serv/rtl/serv_rf_ram.v
Olof Kindgren 8edd456b5d Rewrite serv_rf_ram_if
This adds some optimizations to serv_rf_ram_if. It also adds a read enable
signal and delays writes one cycle which has the added bonus that no reads
or writes happen in the same cycle for RF_WIDTH > 2. This allows SERV to be
used with single-port RAMs in most cases.
2023-06-22 15:48:25 +02:00

45 lines
1.2 KiB
Verilog

module serv_rf_ram
#(parameter width=0,
parameter csr_regs=4,
parameter depth=32*(32+csr_regs)/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,
input wire i_ren,
output wire [width-1:0] o_rdata);
reg [width-1:0] memory [0:depth-1];
reg [width-1:0] rdata ;
always @(posedge i_clk) begin
if (i_wen)
memory[i_waddr] <= i_wdata;
rdata <= i_ren ? memory[i_raddr] : {width{1'bx}};
end
/* Reads from reg x0 needs to return 0
Check that the part of the read address corresponding to the register
is zero and gate the output
width LSB of reg index $clog2(width)
2 4 1
4 3 2
8 2 3
16 1 4
32 0 5
*/
reg regzero;
always @(posedge i_clk)
regzero <= !(|i_raddr[$clog2(depth)-1:5-$clog2(width)]);
assign o_rdata = rdata & ~{width{regzero}};
`ifdef SERV_CLEAR_RAM
integer i;
initial
for (i=0;i<depth;i=i+1)
memory[i] = {width{1'd0}};
`endif
endmodule