diff --git a/rtl/serv_rf_ram.v b/rtl/serv_rf_ram.v index 3cedea6..6c96fa6 100644 --- a/rtl/serv_rf_ram.v +++ b/rtl/serv_rf_ram.v @@ -7,6 +7,7 @@ module serv_rf_ram input wire [width-1:0] i_wdata, input wire i_wen, input wire [$clog2(depth)-1:0] i_raddr, + input wire i_ren, output wire [width-1:0] o_rdata); reg [width-1:0] memory [0:depth-1]; @@ -15,7 +16,7 @@ module serv_rf_ram always @(posedge i_clk) begin if (i_wen) memory[i_waddr] <= i_wdata; - rdata <= memory[i_raddr]; + rdata <= i_ren ? memory[i_raddr] : {width{1'bx}}; end /* Reads from reg x0 needs to return 0 diff --git a/rtl/serv_rf_ram_if.v b/rtl/serv_rf_ram_if.v index 0c69296..39c572d 100644 --- a/rtl/serv_rf_ram_if.v +++ b/rtl/serv_rf_ram_if.v @@ -1,68 +1,81 @@ `default_nettype none module serv_rf_ram_if - #(parameter width=8, + #(//Data width. Adjust to preferred width of SRAM data interface + parameter width=8, + + //Select reset strategy. + // "MINI" for resetting minimally required FFs + // "NONE" for relying on FFs having a defined value on startup parameter reset_strategy="MINI", + + //Number of CSR registers. These are allocated after the normal + // GPR registers in the RAM. parameter csr_regs=4, - parameter depth=32*(32+csr_regs)/width, - parameter l2w = $clog2(width)) + + //Internal parameters calculated from above values. Do not change + parameter raw=$clog2(32+csr_regs), //Register address width + parameter l2w=$clog2(width), //log2 of width + parameter aw=5+raw-l2w) //Address width ( //SERV side - input wire i_clk, - input wire i_rst, - input wire i_wreq, - input wire i_rreq, - output wire o_ready, - input wire [$clog2(32+csr_regs)-1:0] i_wreg0, - input wire [$clog2(32+csr_regs)-1:0] i_wreg1, - input wire i_wen0, - input wire i_wen1, - input wire i_wdata0, - input wire i_wdata1, - input wire [$clog2(32+csr_regs)-1:0] i_rreg0, - input wire [$clog2(32+csr_regs)-1:0] i_rreg1, - output wire o_rdata0, - output wire o_rdata1, + input wire i_clk, + input wire i_rst, + input wire i_wreq, + input wire i_rreq, + output wire o_ready, + input wire [raw-1:0] i_wreg0, + input wire [raw-1:0] i_wreg1, + input wire i_wen0, + input wire i_wen1, + input wire i_wdata0, + input wire i_wdata1, + input wire [raw-1:0] i_rreg0, + input wire [raw-1:0] i_rreg1, + output wire o_rdata0, + output wire o_rdata1, //RAM side - output wire [$clog2(depth)-1:0] o_waddr, - output wire [width-1:0] o_wdata, - output wire o_wen, - output wire [$clog2(depth)-1:0] o_raddr, - input wire [width-1:0] i_rdata); + output wire [aw-1:0] o_waddr, + output wire [width-1:0] o_wdata, + output wire o_wen, + output wire [aw-1:0] o_raddr, + output wire o_ren, + input wire [width-1:0] i_rdata); reg rgnt; assign o_ready = rgnt | i_wreq; reg [4:0] rcnt; + reg rtrig1; /* ********** Write side *********** */ wire [4:0] wcnt; - reg [width-2:0] wdata0_r; - reg [width-1:0] wdata1_r; + reg [width-1:0] wdata0_r; + reg [width-0:0] wdata1_r; reg wen0_r; reg wen1_r; wire wtrig0; wire wtrig1; + assign wtrig0 = rtrig1; + generate if (width == 2) begin - assign wtrig0 = ~wcnt[0]; assign wtrig1 = wcnt[0]; end else begin reg wtrig0_r; always @(posedge i_clk) wtrig0_r <= wtrig0; - assign wtrig0 = (wcnt[l2w-1:0] == {{l2w-1{1'b1}},1'b0}); assign wtrig1 = wtrig0_r; end endgenerate assign o_wdata = wtrig1 ? - wdata1_r : - {i_wdata0, wdata0_r}; + wdata1_r[width-1:0] : + wdata0_r; - wire [$clog2(32+csr_regs)-1:0] wreg = wtrig1 ? i_wreg1 : i_wreg0; + wire [raw-1:0] wreg = wtrig1 ? i_wreg1 : i_wreg0; generate if (width == 32) assign o_waddr = wreg; else @@ -71,19 +84,16 @@ module serv_rf_ram_if assign o_wen = (wtrig0 & wen0_r) | (wtrig1 & wen1_r); - generate if (width > 2) - always @(posedge i_clk) wdata0_r <= {i_wdata0, wdata0_r[width-2:1]}; - else - always @(posedge i_clk) wdata0_r <= i_wdata0; - endgenerate - - assign wcnt = rcnt-3; + assign wcnt = rcnt-4; always @(posedge i_clk) begin - wen0_r <= i_wen0; - wen1_r <= i_wen1; + if (wcnt[0]) begin + wen0_r <= i_wen0; + wen1_r <= i_wen1; + end - wdata1_r <= {i_wdata1,wdata1_r[width-1:1]}; + wdata0_r <= {i_wdata0,wdata0_r[width-1:1]}; + wdata1_r <= {i_wdata1,wdata1_r[width-0:1]}; end @@ -93,9 +103,8 @@ module serv_rf_ram_if wire rtrig0; - reg rtrig1; - wire [$clog2(32+csr_regs)-1:0] rreg = rtrig0 ? i_rreg1 : i_rreg0; + wire [raw-1:0] rreg = rtrig0 ? i_rreg1 : i_rreg0; generate if (width == 32) assign o_raddr = rreg; else @@ -105,11 +114,19 @@ module serv_rf_ram_if reg [width-1:0] rdata0; reg [width-2:0] rdata1; + reg rgate; + assign o_rdata0 = rdata0[0]; assign o_rdata1 = rtrig1 ? i_rdata[0] : rdata1[0]; assign rtrig0 = (rcnt[l2w-1:0] == 1); + generate if (width == 2) + assign o_ren = rgate; + else + assign o_ren = rgate & (rcnt[l2w-1:1] == 0); + endgenerate + reg rreq_r; generate if (width>2) @@ -123,12 +140,13 @@ module serv_rf_ram_if endgenerate always @(posedge i_clk) begin + if (&rcnt | i_rreq) + rgate <= i_rreq; + rtrig1 <= rtrig0; rcnt <= rcnt+5'd1; - if (i_rreq) - rcnt <= 5'd0; - if (i_wreq) - rcnt <= 5'd2; + if (i_rreq | i_wreq) + rcnt <= {3'd0,i_wreq,1'b0}; rreq_r <= i_rreq; rgnt <= rreq_r; @@ -139,8 +157,10 @@ module serv_rf_ram_if if (i_rst) begin if (reset_strategy != "NONE") begin + rgate <= 1'b0; rgnt <= 1'b0; rreq_r <= 1'b0; + rcnt <= 5'd0; end end end diff --git a/rtl/serv_rf_top.v b/rtl/serv_rf_top.v index 9830882..35b7662 100644 --- a/rtl/serv_rf_top.v +++ b/rtl/serv_rf_top.v @@ -98,6 +98,7 @@ module serv_rf_top wire [RF_WIDTH-1:0] wdata; wire wen; wire [RF_L2D-1:0] raddr; + wire ren; wire [RF_WIDTH-1:0] rdata; serv_rf_ram_if @@ -124,6 +125,7 @@ module serv_rf_top .o_wdata (wdata), .o_wen (wen), .o_raddr (raddr), + .o_ren (ren), .i_rdata (rdata)); serv_rf_ram @@ -135,6 +137,7 @@ module serv_rf_top .i_wdata (wdata), .i_wen (wen), .i_raddr (raddr), + .i_ren (ren), .o_rdata (rdata)); serv_top diff --git a/serving/serving.v b/serving/serving.v index 99517fd..67399aa 100644 --- a/serving/serving.v +++ b/serving/serving.v @@ -191,6 +191,7 @@ module serving .o_wdata (wdata), .o_wen (wen), .o_raddr (raddr), + .o_ren (), .i_rdata (rdata)); serv_top