Day 84: ChipX core: single-cycle RV32I in RTL (part 1 — datapath)
ChipX core: single-cycle datapath (part 1)
Now assemble the core. Build the single-cycle RV32I first — one instruction per (long) clock — because it's the paper design from Stage 1 with no pipeline hazards to worry about, so any bug is a datapath bug, not a timing one. Wire up PC, instruction memory, the register file and imm-gen (Days 63–64), the ALU, data memory, and the writeback mux — the Day-42 drawing, in Verilog.
module core_sc (input clk, rst_n, /* imem/dmem ports */);
reg [31:0] pc;
wire [31:0] instr, imm, rd1, rd2, alu_a, alu_b, alu_y, mem_rdata, wb_data;
// fetch
imem u_imem (.addr(pc), .data(instr));
// decode
regfile u_rf (.clk(clk), .ra1(instr[19:15]), .ra2(instr[24:20]),
.wa(instr[11:7]), .wd(wb_data), .we(reg_write),
.rd1(rd1), .rd2(rd2));
immgen u_ig (.instr(instr), .imm(imm));
// execute
assign alu_a = rd1;
assign alu_b = alu_src ? imm : rd2;
alu u_alu (.a(alu_a), .b(alu_b), .op(alu_op), .y(alu_y), .zero(zero));
// memory + writeback
dmem u_dm (.clk(clk), .addr(alu_y), .wdata(rd2), .we(mem_write), .rdata(mem_rdata));
assign wb_data = mem_to_reg ? mem_rdata : alu_y;
// next PC
always @(posedge clk or negedge rst_n)
if (!rst_n) pc <= 0;
else pc <= take_branch ? (pc + imm) : (pc + 4);
endmoduleReuse everything you built
The ALU, register file, and imm-gen are the exact building blocks from Days 63–64 — nothing new to write, just wire them per the Day-42 drawing. That reuse is the whole point of building blocks first: the core is *integration*, and each sub-block already has a passing self-check, so failures localize to the wiring.
Progress for Day 84
Why build the single-cycle core before the pipelined one?