diff --git a/rtl/serv_regfile.v b/rtl/serv_regfile.v deleted file mode 100644 index 13c68d3..0000000 --- a/rtl/serv_regfile.v +++ /dev/null @@ -1,87 +0,0 @@ -`default_nettype none -module serv_regfile - ( - input wire i_clk, - input wire i_rst, - input wire i_go, - output reg o_ready, - input wire i_rd_en, - input wire [4:0] i_rd_addr, - input wire i_rd, - input wire [4:0] i_rs1_addr, - input wire [4:0] i_rs2_addr, - output wire o_rs1, - output wire o_rs2); - - reg t; - always @(posedge i_clk) begin - o_ready <= t; - t <= i_go; - if (i_rst) begin - o_ready <= 1'b0; - t <= 1'b0; - end - end - - reg rd_r; - - reg [1:0] rdata; - reg [4:0] rcnt; - reg [4:0] wcnt; - reg rs1; - reg rs2; - reg rs1_r; - - wire rs1_en = rcnt[0]; - wire rs1_tmp = (rs1_en ? rdata[0] : rs1); - - wire [1:0] wdata = {i_rd, rd_r}; - always @(posedge i_clk) begin - rd_r <= i_rd; - if (i_rd_en) - wcnt <= wcnt + 5'd1; - - if (i_go) - rcnt <= 5'd0; - else - rcnt <= rcnt + 4'd1; - if (rs1_en) begin - rs1 <= rdata[1]; - end else begin - rs2 <= rdata[1]; - end - rs1_r <= rs1_tmp; - if (i_rst) begin - wcnt <= 5'd0; - end - end - - - assign o_rs1 = rs1_r; - assign o_rs2 = (rs1_en ? rs2 : rdata[0]); - - wire [8:0] waddr = {i_rd_addr, wcnt[4:1]}; - wire wr_en = wcnt[0] & i_rd_en & (|i_rd_addr); - - wire [8:0] raddr = {!rs1_en ? i_rs1_addr : i_rs2_addr, rcnt[4:1]}; - - reg [1:0] memory [0:511]; - - always @(posedge i_clk) begin - if (wr_en) - memory[waddr] <= wdata; - rdata <= memory[raddr]; - end - -`ifdef RISCV_FORMAL - `define SERV_CLEAR_RAM -`endif - -`ifdef SERV_CLEAR_RAM - integer i; - initial - for (i=0;i<512;i=i+1) - memory[i] = 2'd0; -`endif - -endmodule diff --git a/rtl/serv_rf_2bit.v b/rtl/serv_rf_2bit.v deleted file mode 100644 index 36a7a50..0000000 --- a/rtl/serv_rf_2bit.v +++ /dev/null @@ -1,133 +0,0 @@ -`default_nettype none -module serv_rf_2bit - ( - input wire i_clk, - input wire i_rst, - input wire i_wreq, - input wire i_rreq, - output reg o_rgnt, - input wire [5:0] i_wreg0, - input wire [5:0] i_wreg1, - input wire i_wen0, - input wire i_wen1, - input wire i_wdata0, - input wire i_wdata1, - input wire [5:0] i_rreg0, - input wire [5:0] i_rreg1, - output wire o_rdata0, - output wire o_rdata1); - - - /* - ********** Write side *********** - */ - - reg [4:0] wcnt; - reg wgo; - - wire [3:0] wslot = wcnt[4:1]; - wire wport = wcnt[0]; - - reg wdata0_r; - reg wdata1_r; - reg wdata1_2r; - wire [1:0] wdata = !wport ? - {i_wdata0, wdata0_r} : - {wdata1_r, wdata1_2r}; - - wire [5:0] wreg = wport ? i_wreg1 : i_wreg0; - wire [9:0] waddr = {wreg, wslot}; - - wire wen = wgo & (wport ? wen1_r : wen0_r); - - reg wreq_r; - - reg wen0_r; - reg wen1_r; - - always @(posedge i_clk) begin - wen0_r <= i_wen0; - wen1_r <= i_wen1; - wreq_r <= i_wreq; - wdata0_r <= i_wdata0; - wdata1_r <= i_wdata1; - wdata1_2r <= wdata1_r; - - if (wgo) - wcnt <= wcnt+5'd1; - - if (wreq_r) - wgo <= 1'b1; - if (wcnt == 5'b11111) - wgo <= 1'b0; - - if (i_rst) begin - wcnt <= 5'd0; - end - end - - /* - ********** Read side *********** - */ - - - reg [4:0] rcnt; - wire [3:0] rslot = rcnt[4:1]; - wire rport = rcnt[0]; - - wire [5:0] rreg = rport ? i_rreg1 : i_rreg0; - wire [9:0] raddr = {rreg, rslot}; - - reg [1:0] rdata; - reg [1:0] rdata0; - reg rdata1; - - - assign o_rdata0 = !rport ? rdata0[0] : rdata0[1]; - assign o_rdata1 = rport ? rdata1 : rdata[0]; - - reg rreq_r; - - always @(posedge i_clk) begin - rcnt <= rcnt+5'd1; - if (i_rreq) - rcnt <= 5'd0; - - rreq_r <= i_rreq; - o_rgnt <= rreq_r; - - if (rport) - rdata0 <= rdata; - if (!rport) - rdata1 <= rdata[1]; - - if (i_rst) begin - o_rgnt <= 1'b0; - rreq_r <= 1'b0; - end - end - - - reg [1:0] memory [0:575]; - - always @(posedge i_clk) begin - if (wen) -`ifdef RISCV_FORMAL - if (!i_rst) -`endif - memory[waddr] <= wdata; - rdata <= memory[raddr]; - end - -`ifdef RISCV_FORMAL - `define SERV_CLEAR_RAM -`endif - -`ifdef SERV_CLEAR_RAM - integer i; - initial - for (i=0;i<512;i=i+1) - memory[i] = 2'd0; -`endif - -endmodule diff --git a/rtl/serv_rf_ram.v b/rtl/serv_rf_ram.v new file mode 100644 index 0000000..cf346c6 --- /dev/null +++ b/rtl/serv_rf_ram.v @@ -0,0 +1,25 @@ +module serv_rf_ram + #(parameter width=0, + parameter depth=32*36/width) + (input wire i_clk, + input wire [$clog2(depth)-1:0] i_waddr, + input wire [width-1:0] i_wdata, + input wire i_wen, + input wire [$clog2(depth)-1:0] i_raddr, + output reg [width-1:0] o_rdata); + + reg [width-1:0] memory [0:depth-1]; + + always @(posedge i_clk) begin + if (i_wen) + memory[i_waddr] <= i_wdata; + o_rdata <= memory[i_raddr]; + end + +`ifdef SERV_CLEAR_RAM + integer i; + initial + for (i=0;i 2) + always @(posedge i_clk) wdata0_r <= {i_wdata0, wdata0_r[width-2:1]}; + else + always @(posedge i_clk) wdata0_r <= i_wdata0; + endgenerate + + always @(posedge i_clk) begin + wen0_r <= i_wen0; + wen1_r <= i_wen1; + wreq_r <= i_wreq; + wreq_edge <= i_wreq & !wreq_r; + + wdata1_r <= {i_wdata1,wdata1_r[width-1:1]}; + + if (wgo) + wcnt <= wcnt+5'd1; + + if (wreq_r) begin + wgo <= 1'b1; + end + + if (wcnt == 5'b11111) + wgo <= 1'b0; + + if (i_rst) begin + wcnt <= 5'd0; + end + end + + /* + ********** Read side *********** + */ + + reg [4:0] rcnt; + + wire rtrig0; + reg rtrig1; + + wire [5: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; + + 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; + + rreq_r <= i_rreq; + o_rgnt <= rreq_r; + + rdata0 <= {1'b0,rdata0[width-1:1]}; + if (rtrig0) + rdata0 <= i_rdata; + + if (i_rst) begin + o_rgnt <= 1'b0; + rreq_r <= 1'b0; + end + end + + + +endmodule diff --git a/rtl/serv_rf_top.v b/rtl/serv_rf_top.v index cd6db34..47c4898 100644 --- a/rtl/serv_rf_top.v +++ b/rtl/serv_rf_top.v @@ -41,6 +41,8 @@ module serv_rf_top input wire i_dbus_ack); parameter RESET_PC = 32'd0; + parameter RF_WIDTH = 2; + localparam RF_L2W = $clog2(RF_WIDTH); wire rf_wreq; wire rf_rreq; @@ -56,7 +58,13 @@ module serv_rf_top wire rdata0; wire rdata1; - serv_rf_2bit rf + wire [10-RF_L2W:0] waddr; + wire [RF_WIDTH-1:0] wdata; + wire wen; + wire [10-RF_L2W:0] raddr; + wire [RF_WIDTH-1:0] rdata; + + serv_rf_ram_if #(.width (RF_WIDTH)) rf_ram_if (.i_clk (clk), .i_rst (i_rst), .i_wreq (rf_wreq), @@ -71,7 +79,20 @@ module serv_rf_top .i_rreg0 (rreg0), .i_rreg1 (rreg1), .o_rdata0 (rdata0), - .o_rdata1 (rdata1)); + .o_rdata1 (rdata1), + .o_waddr (waddr), + .o_wdata (wdata), + .o_wen (wen), + .o_raddr (raddr), + .i_rdata (rdata)); + + serv_rf_ram #(.width (RF_WIDTH)) rf_ram + (.i_clk (clk), + .i_waddr (waddr), + .i_wdata (wdata), + .i_wen (wen), + .i_raddr (raddr), + .o_rdata (rdata)); serv_top #(.RESET_PC (RESET_PC)) diff --git a/serv.core b/serv.core index 9fcb717..1a68988 100644 --- a/serv.core +++ b/serv.core @@ -17,7 +17,8 @@ filesets: - rtl/serv_decode.v - rtl/serv_mem_if.v - rtl/serv_rf_if.v - - rtl/serv_rf_2bit.v + - rtl/serv_rf_ram_if.v + - rtl/serv_rf_ram.v - rtl/serv_state.v - rtl/serv_top.v - rtl/serv_rf_top.v