cpu32.v (5226B)
1 // CPU32 Non-pipelined Core 2 // 3 // Copyright 2012, Brian Swetland. Use at your own risk. 4 5 `timescale 1ns/1ns 6 7 module cpu32 ( 8 input clk, 9 input reset, 10 output [31:0] i_addr, 11 input [31:0] i_data, 12 output [31:0] d_addr, 13 output [31:0] d_data_w, 14 input [31:0] d_data_r, 15 output d_data_we 16 ); 17 18 reg sync_reset; 19 20 always @(posedge clk) 21 if (reset) 22 sync_reset <= 1'b1; 23 else 24 sync_reset <= 1'b0; 25 26 reg [31:0] pc, ir; 27 28 wire [31:0] next_pc, pc_plus_4, next_pc0; 29 30 wire [3:0] opcode, opfunc, opsela, opselb, opseld; 31 wire [15:0] opimm16; 32 33 wire [31:0] adata, bdata, wdata, result; 34 35 assign opcode = ir[31:28]; 36 assign opfunc = ir[27:24]; 37 assign opsela = ir[23:20]; 38 assign opselb = ir[19:16]; 39 assign opseld = ir[15:12]; 40 assign opimm16 = ir[15:0]; 41 42 wire [31:0] opimm16s; 43 assign opimm16s[31:0] = { {16{opimm16[15]}} , opimm16[15:0] }; 44 45 wire ctl_alu_pc; 46 wire ctl_alu_imm; 47 wire ctl_regs_we; 48 wire ctl_ram_we; 49 wire ctl_alu_altdest; 50 wire ctl_wdata_ram; 51 wire ctl_branch_ind; 52 wire ctl_branch_taken; 53 54 control control( 55 .opcode(opcode), 56 .opfunc(opfunc), 57 .ctl_adata_zero(ctl_adata_zero), 58 .hazard(hazard_rrw), 59 60 .ctl_alu_pc(ctl_alu_pc), 61 .ctl_alu_imm(ctl_alu_imm), 62 .ctl_regs_we(ctl_regs_we), 63 .ctl_ram_we(ctl_ram_we), 64 .ctl_alu_altdest(ctl_alu_altdest), 65 .ctl_wdata_ram(ctl_wdata_ram), 66 67 .ctl_branch_ind(ctl_branch_ind), 68 .ctl_branch_taken(ctl_branch_taken) 69 ); 70 71 wire ctl_adata_zero; 72 assign ctl_adata_zero = (adata == 32'h0); 73 74 assign i_addr = next_pc; 75 76 always @(posedge clk) 77 if (sync_reset) begin 78 ir <= 32'hEEEE7777; 79 pc <= 32'h00000000; 80 end else begin 81 if (!hazard_rrw) 82 ir <= i_data; 83 pc <= next_pc; 84 end 85 86 /* these arrive from writeback */ 87 wire [31:0] regs_wdata; 88 wire [3:0] regs_wsel; 89 wire regs_we; 90 91 regfile REGS ( 92 .reset(reset), 93 .clk(clk), 94 .we(regs_we), 95 .wsel(regs_wsel), .wdata(regs_wdata), 96 .asel(opsela), .adata(adata), 97 .bsel(opselb), .bdata(bdata) 98 ); 99 100 // attempt to identify hazards 101 wire hazard1, hazard2, hazard_rrw; 102 assign hazard1 = (((regs_wsel == opsela) | (regs_wsel == opselb)) & regs_we) & (regs_wsel != 4'b1111); 103 assign hazard2 = (((mem_wsel == opsela) | (mem_wsel == opselb)) & mem_we) & (mem_wsel != 4'b1111); 104 assign hazard_rrw = hazard1 | hazard2; 105 106 assign pc_plus_4 = hazard_rrw ? pc : (pc + 32'h4); 107 108 wire [31:0] branch_to; 109 mux2 #(32) mux_branch_to( 110 .sel(ctl_branch_ind), 111 .in0(pc + { opimm16s[29:0], 2'b00 } ), 112 .in1(bdata), 113 .out(branch_to) 114 ); 115 116 mux2 #(32) mux_pc_source( 117 .sel(ctl_branch_taken), 118 .in0(pc_plus_4), 119 .in1(branch_to), 120 .out(next_pc0) 121 ); 122 123 mux2 #(32) mux_next_pc( 124 .sel(sync_reset), 125 .in0(next_pc0), 126 .in1(32'h0), 127 .out(next_pc) 128 ); 129 130 wire [31:0] ainput; 131 wire [31:0] binput; 132 133 mux2 #(32) mux_alu_left( 134 .sel(ctl_alu_pc), 135 .in0(adata), 136 .in1(pc_plus_4), 137 .out(ainput) 138 ); 139 140 mux2 #(32) mux_alu_right( 141 .sel(ctl_alu_imm), 142 .in0(bdata), 143 .in1(opimm16s), 144 .out(binput) 145 ); 146 147 wire [3:0] ctl_wsel; 148 149 mux2 #(4) alu_wsel_mux( 150 .sel(ctl_alu_altdest), 151 .in0(opseld), 152 .in1(opselb), 153 .out(ctl_wsel) 154 ); 155 156 alu alu( 157 .opcode(opfunc), 158 .left(ainput), 159 .right(binput), 160 .out(result) 161 ); 162 163 wire [31:0] mem_data; 164 wire [3:0] mem_wsel; 165 wire mem_we; 166 167 memory mem( 168 .clk(clk), 169 .reset(reset), 170 171 .in_alu_data(result), 172 .in_reg_data(bdata), 173 174 .in_mem_we(ctl_ram_we), 175 .in_regs_we(ctl_regs_we), 176 .in_regs_wsel(ctl_wsel), 177 .in_wdata_ram(ctl_wdata_ram), 178 179 .out_data(mem_data), 180 .out_wsel(mem_wsel), 181 .out_we(mem_we), 182 183 .d_addr(d_addr), 184 .d_data_r(d_data_r), 185 .d_data_w(d_data_w), 186 .d_data_we(d_data_we) 187 ); 188 189 writeback wb( 190 .clk(clk), 191 .reset(reset), 192 193 .in_data(mem_data), 194 .in_wsel(mem_wsel), 195 .in_we(mem_we), 196 197 .out_we(regs_we), 198 .out_wsel(regs_wsel), 199 .out_data(regs_wdata) 200 ); 201 202 endmodule 203 204 205 module memory( 206 input clk, 207 input reset, 208 209 /* interface to sync sram */ 210 output [31:0] d_addr, 211 input [31:0] d_data_r, 212 output [31:0] d_data_w, 213 output d_data_we, 214 215 /* interface to processor core */ 216 input [31:0] in_alu_data, 217 input [31:0] in_reg_data, 218 219 input in_mem_we, 220 input in_regs_we, 221 input [3:0] in_regs_wsel, 222 input in_wdata_ram, 223 224 output [31:0] out_data, 225 output [3:0] out_wsel, 226 output out_we 227 ); 228 229 reg [31:0] alu_data; 230 reg [31:0] reg_data; 231 reg mem_we; 232 reg regs_we; 233 reg [3:0] regs_wsel; 234 reg wdata_ram; 235 236 always @(posedge clk) begin 237 if (reset) begin 238 alu_data <= 32'b0; 239 reg_data <= 32'b0; 240 mem_we <= 1'b0; 241 regs_we <= 1'b0; 242 regs_wsel <= 4'b0; 243 wdata_ram <= 1'b0; 244 end else begin 245 alu_data <= in_alu_data; 246 reg_data <= in_reg_data; 247 mem_we <= in_mem_we; 248 regs_we <= in_regs_we; 249 regs_wsel <= in_regs_wsel; 250 wdata_ram <= in_wdata_ram; 251 end 252 end 253 254 assign d_addr = in_alu_data; 255 assign d_data_w = in_reg_data; 256 assign d_data_we = in_mem_we; 257 258 mux2 #(32) mux_data( 259 .sel(wdata_ram), 260 .in0(alu_data), 261 .in1(d_data_r), 262 .out(out_data) 263 ); 264 265 assign out_wsel = regs_wsel; 266 assign out_we = regs_we; 267 endmodule 268 269 module writeback( 270 input clk, 271 input reset, 272 273 input [31:0] in_data, 274 input [3:0] in_wsel, 275 input in_we, 276 277 output out_we, 278 output [3:0] out_wsel, 279 output [31:0] out_data 280 ); 281 282 reg [31:0] data; 283 reg [3:0] wsel; 284 reg we; 285 286 always @(posedge clk) begin 287 if (reset) begin 288 data <= 32'b0; 289 wsel <= 4'b0; 290 we <= 1'b0; 291 end else begin 292 data <= in_data; 293 wsel <= in_wsel; 294 we <= in_we; 295 end 296 end 297 298 assign out_we = we; 299 assign out_wsel = wsel; 300 assign out_data = data; 301 endmodule 302 303 304