`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