rtl: Adjust rf_ram_if for single port memory Bump up macro serv_0 size to assist with routing
diff --git a/openlane/serv_0/config.tcl b/openlane/serv_0/config.tcl index 51eb956..9ac7dc4 100644 --- a/openlane/serv_0/config.tcl +++ b/openlane/serv_0/config.tcl
@@ -36,7 +36,7 @@ ## Floorplan set ::env(FP_SIZING) absolute -set ::env(DIE_AREA) "0 0 700 600" +set ::env(DIE_AREA) "0 0 1000 600" ## Placement set ::env(PL_BASIC_PLACEMENT) 0 @@ -71,13 +71,13 @@ $::env(DESIGN_DIR)/rtl/defines.v \ $::env(DESIGN_DIR)/rtl/serv_0.v \ $::env(DESIGN_DIR)/rtl/serv_rf_ram_gf180.v \ + $::env(DESIGN_DIR)/rtl/serv_rf_spram_if.v \ $::env(DESIGN_DIR)/rtl/scanchain_gf180.v \ $::env(DESIGN_DIR)/blocks/serv/rtl/serv_top.v \ $::env(DESIGN_DIR)/blocks/serv/rtl/serv_synth_wrapper.v \ $::env(DESIGN_DIR)/blocks/serv/rtl/serv_mem_if.v \ $::env(DESIGN_DIR)/blocks/serv/rtl/serv_rf_if.v \ $::env(DESIGN_DIR)/blocks/serv/rtl/serv_rf_top.v \ - $::env(DESIGN_DIR)/blocks/serv/rtl/serv_rf_ram_if.v \ $::env(DESIGN_DIR)/blocks/serv/rtl/serv_alu.v \ $::env(DESIGN_DIR)/blocks/serv/rtl/serv_ctrl.v \ $::env(DESIGN_DIR)/blocks/serv/rtl/serv_bufreg2.v \
diff --git a/verilog/rtl/serv_rf_ram_gf180.v b/verilog/rtl/serv_rf_ram_gf180.v index af0a910..cbac50a 100644 --- a/verilog/rtl/serv_rf_ram_gf180.v +++ b/verilog/rtl/serv_rf_ram_gf180.v
@@ -9,8 +9,7 @@ input wire [$clog2(depth)-1:0] i_raddr, output wire [width-1:0] o_rdata); - wire [width-1:0] data ; - reg [width-1:0] rdata ; + wire [width-1:0] rdata ; wire [$clog2(depth)-1:0] addr; assign addr = i_wen ? i_waddr : i_raddr; @@ -22,9 +21,9 @@ .WEN({8{~i_wen}}), // Active LOW .A(addr), .D(i_wdata), - .Q(data), - .VDD(), - .VSS() + .Q(rdata), + .VDD(1'b1), + .VSS(1'b0) ); /* Reads from reg x0 needs to return 0 @@ -42,10 +41,6 @@ always @(posedge i_clk) regzero <= !(|i_raddr[$clog2(depth)-1:5-$clog2(width)]); - always @(posedge i_clk) - if(~i_wen) - rdata <= data; - - assign o_rdata = (i_wen ? rdata : data) & ~{width{regzero}}; + assign o_rdata = rdata & ~{width{regzero}}; endmodule
diff --git a/verilog/rtl/serv_rf_spram_if.v b/verilog/rtl/serv_rf_spram_if.v new file mode 100644 index 0000000..a23805e --- /dev/null +++ b/verilog/rtl/serv_rf_spram_if.v
@@ -0,0 +1,166 @@ +`default_nettype none +module serv_rf_ram_if + #(parameter width=8, + parameter reset_strategy="MINI", + parameter csr_regs=4, + parameter depth=32*(32+csr_regs)/width, + parameter l2w = $clog2(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, + //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); + + reg rgnt; + assign o_ready = rgnt | i_wreq; + reg [4:0] rcnt; + + /* + ********** Write side *********** + */ + + wire [4:0] wcnt; + + reg [width-2:0] wdata0_r; + reg [width-1:0] wdata1_r; + + reg wen0_r; + reg wen1_r; + wire wtrig0; + wire wtrig1; + + 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 + + wire [$clog2(32+csr_regs)-1:0] wreg = wtrig1 ? i_wreg1 : i_wreg0; + + wire [$clog2(depth)-1:0]o_waddr0; + generate if (width == 32) + assign o_waddr0 = wreg; + else + assign o_waddr0 = {wreg, wcnt[4:l2w]}; + endgenerate + + reg o_wen_req; + reg [width-1:0] o_wen_dat; + reg [$clog2(depth)-1:0] o_wen_adr; + always @(posedge i_clk) begin + if((wtrig0 & wen0_r) | (wtrig1 & wen1_r)) begin + o_wen_req <= 1; + o_wen_dat <= wtrig1 ? wdata1_r : {i_wdata0, wdata0_r}; + o_wen_adr <= o_waddr0; + end + else if(o_wen) begin + o_wen_req <= 0; + end + end + + assign o_wen = o_wen_req & !(rtrig0 | rtrig1); + assign o_wdata = o_wen_dat; + assign o_waddr = o_wen_adr; + + 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; + + always @(posedge i_clk) begin + wen0_r <= i_wen0; + wen1_r <= i_wen1; + + wdata1_r <= {i_wdata1,wdata1_r[width-1:1]}; + + end + + /* + ********** Read side *********** + */ + + + wire rtrig0; + reg rtrig1; + + wire [$clog2(32+csr_regs)-1:0] rreg = rtrig0 ? i_rreg1 : i_rreg0; + generate if (width == 32) + assign o_raddr = rreg; + else + assign o_raddr = {rreg, rcnt[4:l2w]}; + endgenerate + + reg [width-1:0] rdata0; + reg [width-2:0] rdata1; + + assign o_rdata0 = rdata0[0]; + assign o_rdata1 = rtrig1 ? i_rdata[0] : rdata1[0]; + + assign rtrig0 = (rcnt[l2w-1:0] == 1); + + reg rreq_r; + reg rreq_rr; + reg rreq_rrr; + + generate if (width>2) + always @(posedge i_clk) begin + rdata1 <= {1'b0,rdata1[width-2:1]}; //Optimize? + if (rtrig1) + rdata1[width-2:0] <= i_rdata[width-1:1]; + end + else + always @(posedge i_clk) if (rtrig1) rdata1 <= i_rdata[1]; + endgenerate + + always @(posedge i_clk) begin + rtrig1 <= rtrig0; + rcnt <= rcnt+5'd1; + if (i_rreq) + rcnt <= 5'd0; + if (i_wreq) + rcnt <= 5'd2; + + rreq_r <= i_rreq; + rgnt <= rreq_r; + + rdata0 <= {1'b0,rdata0[width-1:1]}; + if (rtrig0) + rdata0 <= i_rdata; + + if (i_rst) begin + if (reset_strategy != "NONE") begin + rgnt <= 1'b0; + rreq_r <= 1'b0; + end + end + end + + + +endmodule