commit 56f88f259a5816f0990835871442c477c73c251d
parent dc8fcb6a7c3a5c649e07501dfd5b125ad2c301d6
Author: Vineet Kumar <git@vineetk.net>
Date: Tue, 11 Aug 2026 17:10:44 +0530
split memop into loadop and storeop
Recovery-Origin: 7865eed346008c19d94bb6963010a9b24244028d
Recovery-Status: reconstructed history
Reconstructed split load/store control types, memory-stage interface and testbench from intact Aug22 pre-amendment RTL. Intermediate Aug11/Aug18 source is unavailable; exact attribution of individual edits is uncertain.
Diffstat:
5 files changed, 65 insertions(+), 55 deletions(-)
diff --git a/rtl/rv32g_hart.sv b/rtl/rv32g_hart.sv
@@ -41,7 +41,8 @@ module rv32g_hart
logic ex_branch_taken;
// temporary memory signals
- memop_t mem_memop;
+ loadop_t mem_loadop;
+ storeop_t mem_storeop;
logic [31:0] mem_mem_out;
reg_t memwb_value;
@@ -219,7 +220,8 @@ module rv32g_hart
exmem_reg.rd_num <= idex_reg.rd_num;
exmem_reg.branch_taken <= ex_branch_taken;
exmem_reg.branchop <= idex_reg.ctrl.branchop;
- exmem_reg.memop <= idex_reg.ctrl.memop;
+ exmem_reg.loadop <= idex_reg.ctrl.loadop;
+ exmem_reg.storeop <= idex_reg.ctrl.storeop;
exmem_reg.wbsrc <= idex_reg.ctrl.wbsrc;
exmem_reg.pcsrc <= idex_reg.ctrl.pcsrc;
exmem_reg.exception <= idex_reg.ctrl.exception;
@@ -259,13 +261,14 @@ module rv32g_hart
// === MEMORY ===
// ==============
- assign mem_memop = exmem_reg.valid ? exmem_reg.memop : MEM_NONE;
+ assign mem_loadop = memwb_reg.valid ? memwb_reg.loadop : LD_NONE;
+ assign mem_storeop = exmem_reg.valid ? exmem_reg.storeop : ST_NONE;
- stage_memory u_mem(.memop(mem_memop),
+ stage_memory u_mem(.loadop(mem_loadop),
+ .storeop(mem_storeop),
+ .addr(memwb_reg.alu_out),
.alu_out(exmem_reg.alu_out),
.rs2_val(exmem_reg.rs2_val),
- .resp_memop(memwb_reg.memop),
- .resp_addr(memwb_reg.alu_out),
.mem_out(mem_mem_out),
.dmem_addr, .dmem_rdata, .dmem_wdata, .dmem_we, .dmem_be);
// MEM/WB pipeline register
@@ -277,7 +280,8 @@ module rv32g_hart
memwb_reg.alu_out <= exmem_reg.alu_out;
memwb_reg.wb_value <= exmem_reg.wb_value;
memwb_reg.rd_num <= exmem_reg.rd_num;
- memwb_reg.memop <= exmem_reg.memop;
+ memwb_reg.loadop <= exmem_reg.loadop;
+ memwb_reg.storeop <= exmem_reg.storeop;
memwb_reg.wbsrc <= exmem_reg.wbsrc;
memwb_reg.exception <= exmem_reg.exception;
end
diff --git a/rtl/rv32g_pkg.sv b/rtl/rv32g_pkg.sv
@@ -126,24 +126,26 @@ package rv32g_pkg;
ALUOP2_IMM // sign-extended immediate for I-type and JALR
} aluop2src_t;
- typedef enum logic [3:0] {MEM_NONE,
- MEM_LB,
- MEM_LH,
- MEM_LW,
- MEM_LBU,
- MEM_LHU,
- MEM_SB,
- MEM_SH,
- MEM_SW
- } memop_t;
-
- typedef enum logic [2:0] {BRANCH_NONE,
- BRANCH_BEQ,
- BRANCH_BNE,
- BRANCH_BLT,
- BRANCH_BGE,
- BRANCH_BLTU,
- BRANCH_BGEU
+ typedef enum logic [2:0] {LD_LB = 3'b000,
+ LD_LH = 3'b001,
+ LD_LW = 3'b010,
+ LD_LBU = 3'b100,
+ LD_LHU = 3'b101,
+ LD_NONE = 3'b111
+ } loadop_t;
+
+ typedef enum logic [2:0] {ST_SB,
+ ST_SH,
+ ST_SW,
+ ST_NONE} storeop_t;
+
+ typedef enum logic [2:0] {BRANCH_BEQ = 3'b000,
+ BRANCH_BNE = 3'b001,
+ BRANCH_BLT = 3'b100,
+ BRANCH_BGE = 3'b101,
+ BRANCH_BLTU = 3'b110,
+ BRANCH_BGEU = 3'b111,
+ BRANCH_NONE = 3'b011 // this value is unused.
} branchop_t;
typedef enum logic [1:0] {PC_SEQ, // PC = PC + 4 (regular)
@@ -175,7 +177,8 @@ package rv32g_pkg;
aluop_t aluop;
aluop1src_t aluop1src;
aluop2src_t aluop2src;
- memop_t memop;
+ loadop_t loadop;
+ storeop_t storeop;
pcsrc_t pcsrc;
branchop_t branchop;
wbsrc_t wbsrc;
@@ -207,7 +210,8 @@ package rv32g_pkg;
logic [4:0] rd_num;
logic branch_taken;
branchop_t branchop;
- memop_t memop;
+ loadop_t loadop;
+ storeop_t storeop;
wbsrc_t wbsrc;
pcsrc_t pcsrc;
exception_t exception;
@@ -219,7 +223,8 @@ package rv32g_pkg;
reg_t alu_out;
reg_t wb_value;
logic [4:0] rd_num;
- memop_t memop;
+ loadop_t loadop;
+ storeop_t storeop;
wbsrc_t wbsrc;
exception_t exception;
} memwb_reg_t;
diff --git a/rtl/stage_decode.sv b/rtl/stage_decode.sv
@@ -138,7 +138,8 @@ module stage_decode
ctrl = '{aluop: ALU_NONE,
aluop1src: ALUOP1_NONE,
aluop2src: ALUOP2_NONE,
- memop: MEM_NONE,
+ loadop: LD_NONE,
+ storeop: ST_NONE,
pcsrc: PC_SEQ,
branchop: BRANCH_NONE,
wbsrc: WB_NONE,
@@ -208,14 +209,14 @@ module stage_decode
BGE: ctrl.branchop = BRANCH_BGE;
BLTU: ctrl.branchop = BRANCH_BLTU;
BGEU: ctrl.branchop = BRANCH_BGEU;
- LB: ctrl.memop = MEM_LB;
- LH: ctrl.memop = MEM_LH;
- LW: ctrl.memop = MEM_LW;
- LBU: ctrl.memop = MEM_LBU;
- LHU: ctrl.memop = MEM_LHU;
- SB: ctrl.memop = MEM_SB;
- SH: ctrl.memop = MEM_SH;
- SW: ctrl.memop = MEM_SW;
+ LB: ctrl.loadop = LD_LB;
+ LH: ctrl.loadop = LD_LH;
+ LW: ctrl.loadop = LD_LW;
+ LBU: ctrl.loadop = LD_LBU;
+ LHU: ctrl.loadop = LD_LHU;
+ SB: ctrl.storeop = ST_SB;
+ SH: ctrl.storeop = ST_SH;
+ SW: ctrl.storeop = ST_SW;
ADDI: begin
if (rd_num == 0 && rs1_num == 0 && imm == 0) begin // handle nop by doing a nop
ctrl.aluop = ALU_NONE;
diff --git a/rtl/stage_memory.sv b/rtl/stage_memory.sv
@@ -1,12 +1,11 @@
module stage_memory
import rv32g_pkg::*;
- (input memop_t memop,
+ (input loadop_t loadop,
+ input storeop_t storeop,
+ input logic [31:0] addr,
input logic [31:0] alu_out,
input reg_t rs2_val,
- input memop_t resp_memop,
- input logic [31:0] resp_addr,
-
output logic [31:0] dmem_addr,
input logic [31:0] dmem_rdata,
output logic [31:0] dmem_wdata,
@@ -26,29 +25,29 @@ module stage_memory
dmem_be = 0;
mem_out = 0;
- unique case (resp_addr[1:0])
+ unique case (addr[1:0])
2'b00: bdata = dmem_rdata[7:0];
2'b01: bdata = dmem_rdata[15:8];
2'b10: bdata = dmem_rdata[23:16];
2'b11: bdata = dmem_rdata[31:24];
endcase
- unique case (resp_addr[1])
+ unique case (addr[1])
1'b0: hdata = dmem_rdata[15:0];
1'b1: hdata = dmem_rdata[31:16];
endcase
- unique case (resp_memop)
- MEM_LB: mem_out = {{24{bdata[7]}}, bdata};
- MEM_LH: mem_out = {{16{hdata[15]}}, hdata};
- MEM_LW: mem_out = dmem_rdata;
- MEM_LBU: mem_out = {24'b0, bdata};
- MEM_LHU: mem_out = {16'b0, hdata};
+ unique case (loadop)
+ LD_LB: mem_out = {{24{bdata[7]}}, bdata};
+ LD_LH: mem_out = {{16{hdata[15]}}, hdata};
+ LD_LW: mem_out = dmem_rdata;
+ LD_LBU: mem_out = {24'b0, bdata};
+ LD_LHU: mem_out = {16'b0, hdata};
default: mem_out = '0;
endcase
- unique case (memop)
- MEM_SB: begin
+ unique case (storeop)
+ ST_SB: begin
unique case (alu_out[1:0])
2'b00: begin
dmem_be = 4'b0001;
@@ -69,7 +68,7 @@ module stage_memory
endcase
dmem_we = 1;
end
- MEM_SH: begin
+ ST_SH: begin
unique case (alu_out[1])
1'b0: begin
dmem_be = 4'b0011;
@@ -82,7 +81,7 @@ module stage_memory
endcase
dmem_we = 1;
end
- MEM_SW: begin
+ ST_SW: begin
dmem_be = 4'b1111;
dmem_wdata = rs2_val;
dmem_we = 1;
diff --git a/rtl/tb_rv32g.sv b/rtl/tb_rv32g.sv
@@ -92,8 +92,9 @@ module tb_rv32g
dut.idex_reg.ctrl.aluop, dut.idex_reg.ctrl.aluop1src, dut.idex_reg.ctrl.aluop2src,
dut.idex_reg.ctrl.branchop, dut.exmem_reg.alu_out, dut.exmem_reg.branch_taken,
dut.ex_rs1_val, dut.ex_rs2_val);
- $display("MEM: memop: %h, dmem_addr: %h, dmem_rdata: %h, dmem_wdata: %h, dmem_we: %d, dmem_be: %b, mem_out: %h",
- dut.exmem_reg.memop, dut.dmem_addr, dut.dmem_rdata, dut.dmem_wdata, dut.dmem_we, dut.dmem_be, dut.mem_mem_out);
+ $display("MEM: loadop: %h, storeop: %h, dmem_addr: %h, dmem_rdata: %h, dmem_wdata: %h, dmem_we: %d, dmem_be: %b, mem_out: %h",
+ dut.exmem_reg.loadop, dut.exmem_reg.storeop,
+ dut.dmem_addr, dut.dmem_rdata, dut.dmem_wdata, dut.dmem_we, dut.dmem_be, dut.mem_mem_out);
$display("WB: wbsrc: %d, rd_num: %d, wb_value: %h, alu_out: %h, mem_out: %h",
dut.memwb_reg.wbsrc, dut.memwb_reg.rd_num, dut.memwb_reg.wb_value,
dut.memwb_reg.alu_out, dut.mem_mem_out);