`include "VX_platform.vh" `TRACING_OFF module VX_sp_ram #( parameter DATAW = 1, parameter SIZE = 1, parameter BYTEENW = 1, parameter OUT_REG = 0, parameter NO_RWCHECK = 0, parameter LUTRAM = 0, parameter ADDRW = $clog2(SIZE), parameter INIT_ENABLE = 0, parameter INIT_FILE = "", parameter [DATAW-1:0] INIT_VALUE = 0 ) ( input wire clk, input wire [ADDRW-1:0] addr, input wire [BYTEENW-1:0] wren, input wire [DATAW-1:0] wdata, output wire [DATAW-1:0] rdata ); `STATIC_ASSERT((1 == BYTEENW) || ((BYTEENW > 1) && 0 == (BYTEENW % 4)), ("invalid parameter")) `define RAM_INITIALIZATION \ if (INIT_ENABLE) begin \ if (INIT_FILE != "") begin \ initial $readmemh(INIT_FILE, ram); \ end else begin \ initial \ for (integer i = 0; i < SIZE; ++i)\ ram[i] = INIT_VALUE; \ end \ end `ifdef SYNTHESIS if (LUTRAM) begin if (OUT_REG) begin reg [DATAW-1:0] rdata_r; if (BYTEENW > 1) begin `USE_FAST_BRAM reg [BYTEENW-1:0][7:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin for (integer i = 0; i < BYTEENW; i++) begin if (wren[i]) ram[addr][i] <= wdata[i * 8 +: 8]; end rdata_r <= ram[addr]; end end else begin `USE_FAST_BRAM reg [DATAW-1:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin if (wren) ram[addr] <= wdata; rdata_r <= ram[addr]; end end assign rdata = rdata_r; end else begin if (BYTEENW > 1) begin `USE_FAST_BRAM reg [BYTEENW-1:0][7:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin for (integer i = 0; i < BYTEENW; i++) begin if (wren[i]) ram[addr][i] <= wdata[i * 8 +: 8]; end end assign rdata = ram[addr]; end else begin `USE_FAST_BRAM reg [DATAW-1:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin if (wren) ram[addr] <= wdata; end assign rdata = ram[addr]; end end end else begin if (OUT_REG) begin reg [DATAW-1:0] rdata_r; if (BYTEENW > 1) begin reg [BYTEENW-1:0][7:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin for (integer i = 0; i < BYTEENW; i++) begin if (wren[i]) ram[addr][i] <= wdata[i * 8 +: 8]; end rdata_r <= ram[addr]; end end else begin reg [DATAW-1:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin if (wren) ram[addr] <= wdata; rdata_r <= ram[addr]; end end assign rdata = rdata_r; end else begin if (NO_RWCHECK) begin if (BYTEENW > 1) begin `NO_RW_RAM_CHECK reg [BYTEENW-1:0][7:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin for (integer i = 0; i < BYTEENW; i++) begin if (wren[i]) ram[addr][i] <= wdata[i * 8 +: 8]; end end assign rdata = ram[addr]; end else begin `NO_RW_RAM_CHECK reg [DATAW-1:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin if (wren) ram[addr] <= wdata; end assign rdata = ram[addr]; end end else begin if (BYTEENW > 1) begin reg [BYTEENW-1:0][7:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin for (integer i = 0; i < BYTEENW; i++) begin if (wren[i]) ram[addr][i] <= wdata[i * 8 +: 8]; end end assign rdata = ram[addr]; end else begin reg [DATAW-1:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin if (wren) ram[addr] <= wdata; end assign rdata = ram[addr]; end end end end `else if (OUT_REG) begin reg [DATAW-1:0] rdata_r; if (BYTEENW > 1) begin reg [BYTEENW-1:0][7:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin for (integer i = 0; i < BYTEENW; i++) begin if (wren[i]) ram[addr][i] <= wdata[i * 8 +: 8]; end rdata_r <= ram[addr]; end end else begin reg [DATAW-1:0] ram [SIZE-1:0]; `RAM_INITIALIZATION always @(posedge clk) begin if (wren) ram[addr] <= wdata; rdata_r <= ram[addr]; end end assign rdata = rdata_r; end else begin if (BYTEENW > 1) begin reg [BYTEENW-1:0][7:0] ram [SIZE-1:0]; reg [DATAW-1:0] prev_data; reg [ADDRW-1:0] prev_addr; reg prev_write; `RAM_INITIALIZATION always @(posedge clk) begin for (integer i = 0; i < BYTEENW; i++) begin if (wren[i]) ram[addr][i] <= wdata[i * 8 +: 8]; end prev_write <= (| wren); prev_data <= ram[addr]; prev_addr <= addr; end if (LUTRAM || !NO_RWCHECK) begin `UNUSED_VAR (prev_write) `UNUSED_VAR (prev_data) `UNUSED_VAR (prev_addr) assign rdata = ram[addr]; end else begin assign rdata = (prev_write && (prev_addr == addr)) ? prev_data : ram[addr]; end end else begin reg [DATAW-1:0] ram [SIZE-1:0]; reg [DATAW-1:0] prev_data; reg [ADDRW-1:0] prev_addr; reg prev_write; `RAM_INITIALIZATION always @(posedge clk) begin if (wren) ram[addr] <= wdata; prev_write <= wren; prev_data <= ram[addr]; prev_addr <= addr; end if (LUTRAM || !NO_RWCHECK) begin `UNUSED_VAR (prev_write) `UNUSED_VAR (prev_data) `UNUSED_VAR (prev_addr) assign rdata = ram[addr]; end else begin assign rdata = (prev_write && (prev_addr == addr)) ? prev_data : ram[addr]; end end end `endif endmodule `TRACING_ON