Skip to content

Commit

Permalink
xilinx asynchronous bram patch fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
tinebp committed Nov 19, 2024
1 parent 8230b37 commit 320c090
Show file tree
Hide file tree
Showing 9 changed files with 490 additions and 257 deletions.
3 changes: 3 additions & 0 deletions hw/rtl/VX_platform.vh
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ endgenerate
`define USE_BLOCK_BRAM (* ramstyle = "block" *)
`define USE_FAST_BRAM (* ramstyle = "MLAB, no_rw_check" *)
`define NO_RW_RAM_CHECK (* altera_attribute = "-name add_pass_through_logic_to_inferred_rams off" *)
`define RW_RAM_CHECK (* altera_attribute = "-name add_pass_through_logic_to_inferred_rams on" *)
`define DISABLE_BRAM (* ramstyle = "logic" *)
`define PRESERVE_NET (* preserve *)
`define BLACKBOX_CELL (* black_box *)
Expand All @@ -173,6 +174,7 @@ endgenerate
`define USE_BLOCK_BRAM (* ram_style = "block" *)
`define USE_FAST_BRAM (* ram_style = "distributed" *)
`define NO_RW_RAM_CHECK (* rw_addr_collision = "no" *)
`define RW_RAM_CHECK (* rw_addr_collision = "yes" *)
`define DISABLE_BRAM (* ram_style = "registers" *)
`define PRESERVE_NET (* keep = "true" *)
`define BLACKBOX_CELL (* black_box *)
Expand All @@ -183,6 +185,7 @@ endgenerate
`define USE_BLOCK_BRAM
`define USE_FAST_BRAM
`define NO_RW_RAM_CHECK
`define RW_RAM_CHECK
`define DISABLE_BRAM
`define PRESERVE_NET
`define BLACKBOX_CELL
Expand Down
236 changes: 168 additions & 68 deletions hw/rtl/libs/VX_async_ram_patch.sv
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@

`include "VX_platform.vh"

`define RAM_WRITE_WREN for (integer i = 0; i < WRENW; ++i) begin \
if (wren[i]) begin \
ram[waddr][i * WSELW +: WSELW] <= wdata[i * WSELW +: WSELW]; \
end \
end

`define RAM_INITIALIZATION \
if (INIT_ENABLE != 0) begin : g_init \
if (INIT_FILE != "") begin : g_file \
Expand All @@ -32,21 +26,102 @@
end \
end

`define RAM_BYPASS(__d) \
reg [DATAW-1:0] bypass_data_r; \
reg bypass_valid_r; \
`define SYNC_RAM_WF_BLOCK(__d, __re, __we, __ra, __wa) \
`RAM_ATTRIBUTES `RW_RAM_CHECK reg [DATAW-1:0] ram [0:SIZE-1]; \
`RAM_INITIALIZATION \
reg [ADDRW-1:0] raddr_r; \
always @(posedge clk) begin \
if (__re || __we) begin \
if (__we) begin \
ram[__wa] <= wdata; \
end \
raddr_r <= __ra; \
end \
end \
assign __d = ram[raddr_r]

`define SYNC_RAM_WF_WREN_BLOCK(__d, __re, __we, __ra, __wa) \
`RAM_ATTRIBUTES `RW_RAM_CHECK reg [DATAW-1:0] ram [0:SIZE-1]; \
`RAM_INITIALIZATION \
reg [ADDRW-1:0] raddr_r; \
always @(posedge clk) begin \
bypass_valid_r <= read_s && write && (raddr_s == waddr); \
bypass_data_r <= wdata; \
if (__re || __we) begin \
if (__we) begin \
for (integer i = 0; i < WRENW; ++i) begin \
if (wren[i]) begin \
ram[__wa][i * WSELW +: WSELW] <= wdata[i * WSELW +: WSELW]; \
end \
end \
end \
raddr_r <= __ra; \
end \
end \
assign __d = bypass_valid_r ? bypass_data_r : rdata_r
assign __d = ram[raddr_r]

`define SYNC_RAM_RF_BLOCK(__d, __re, __we, __ra, __wa) \
`RAM_ATTRIBUTES reg [DATAW-1:0] ram [0:SIZE-1]; \
`RAM_INITIALIZATION \
reg [DATAW-1:0] rdata_r; \
always @(posedge clk) begin \
if (__re || __we) begin \
if (__we) begin \
ram[__wa] <= wdata; \
end \
rdata_r <= ram[__ra]; \
end \
end \
assign __d = rdata_r

`define SYNC_RAM_RF_WREN_BLOCK(__d, __re, __we, __ra, __wa) \
`RAM_ATTRIBUTES reg [DATAW-1:0] ram [0:SIZE-1]; \
`RAM_INITIALIZATION \
reg [DATAW-1:0] rdata_r; \
always @(posedge clk) begin \
if (__re || __we) begin \
if (__we) begin \
for (integer i = 0; i < WRENW; ++i) begin \
if (wren[i]) begin \
ram[__wa][i * WSELW +: WSELW] <= wdata[i * WSELW +: WSELW]; \
end \
end \
end \
rdata_r <= ram[__ra]; \
end \
end \
assign __d = rdata_r

`define ASYNC_RAM_BLOCK(__d, __we, __ra, __wa) \
`RAM_ATTRIBUTES reg [DATAW-1:0] ram [0:SIZE-1]; \
`RAM_INITIALIZATION \
always @(posedge clk) begin \
if (__we) begin \
ram[__wa] <= wdata; \
end \
end \
assign __d = ram[__ra]

`define ASYNC_RAM_BLOCK_WREN(__d, __we, __ra, __wa) \
`RAM_ATTRIBUTES reg [DATAW-1:0] ram [0:SIZE-1]; \
`RAM_INITIALIZATION \
always @(posedge clk) begin \
if (__we) begin \
for (integer i = 0; i < WRENW; ++i) begin \
if (wren[i]) begin \
ram[__wa][i * WSELW +: WSELW] <= wdata[i * WSELW +: WSELW]; \
end \
end \
end \
end \
assign __d = ram[__ra]

`TRACING_OFF
module VX_async_ram_patch #(
parameter DATAW = 1,
parameter SIZE = 1,
parameter WRENW = 1,
parameter DUAL_PORT = 0,
parameter FORCE_BRAM = 0,
parameter WRITE_FIRST = 0,
parameter INIT_ENABLE = 0,
parameter INIT_FILE = "",
parameter [DATAW-1:0] INIT_VALUE = 0,
Expand Down Expand Up @@ -79,77 +154,102 @@ module VX_async_ram_patch #(
.out ({raddr_s, read_s, is_raddr_reg})
);

// synchroneous ram

wire [DATAW-1:0] rdata_s;
wire [DATAW-1:0] rdata_s, rdata_a;

if (WRENW != 1) begin : g_wren_sync_ram
`USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
reg [DATAW-1:0] rdata_r;
`RAM_INITIALIZATION
always @(posedge clk) begin
if (read_s || write) begin
if (write) begin
`RAM_WRITE_WREN
if (1) begin : g_sync_ram
if (WRENW != 1) begin : g_wren
if (FORCE_BRAM) begin : g_bram
if (WRITE_FIRST) begin : g_write_first
`define RAM_ATTRIBUTES `USE_BLOCK_BRAM
`SYNC_RAM_WF_WREN_BLOCK(rdata_s, read_s, write, raddr_s, waddr);
`undef RAM_ATTRIBUTES
end else begin : g_read_first
`define RAM_ATTRIBUTES `USE_BLOCK_BRAM
`SYNC_RAM_RF_WREN_BLOCK(rdata_s, read_s, write, raddr_s, waddr);
`undef RAM_ATTRIBUTES
end
end else begin : g_lutram
if (WRITE_FIRST) begin : g_write_first
`define RAM_ATTRIBUTES
`SYNC_RAM_WF_WREN_BLOCK(rdata_s, read_s, write, raddr_s, waddr);
`undef RAM_ATTRIBUTES
end else begin : g_read_first
`define RAM_ATTRIBUTES
`SYNC_RAM_RF_WREN_BLOCK(rdata_s, read_s, write, raddr_s, waddr);
`undef RAM_ATTRIBUTES
end
rdata_r <= ram[raddr_s];
end
end
`RAM_BYPASS(rdata_s);
end else begin : g_no_wren_sync_ram
`USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
reg [DATAW-1:0] rdata_r;
`RAM_INITIALIZATION
`UNUSED_VAR (wren)
always @(posedge clk) begin
if (read_s || write) begin
if (write) begin
ram[waddr] <= wdata;
end else begin : g_no_wren
if (FORCE_BRAM) begin : g_bram
if (WRITE_FIRST) begin : g_write_first
`define RAM_ATTRIBUTES `USE_BLOCK_BRAM
`SYNC_RAM_WF_BLOCK(rdata_s, read_s, write, raddr_s, waddr);
`undef RAM_ATTRIBUTES
end else begin : g_read_first
`define RAM_ATTRIBUTES `USE_BLOCK_BRAM
`SYNC_RAM_RF_BLOCK(rdata_s, read_s, write, raddr_s, waddr);
`undef RAM_ATTRIBUTES
end
end else begin : g_lutram
if (WRITE_FIRST) begin : g_write_first
`define RAM_ATTRIBUTES
`SYNC_RAM_WF_BLOCK(rdata_s, read_s, write, raddr_s, waddr);
`undef RAM_ATTRIBUTES
end else begin : g_read_first
`define RAM_ATTRIBUTES
`SYNC_RAM_RF_BLOCK(rdata_s, read_s, write, raddr_s, waddr);
`undef RAM_ATTRIBUTES
end
rdata_r <= ram[raddr_s];
end
end
`RAM_BYPASS(rdata_s);
end

// asynchronous ram (fallback)

wire [DATAW-1:0] rdata_a;

if (DUAL_PORT != 0) begin : g_dp_async_ram
reg [DATAW-1:0] ram [0:SIZE-1];
`RAM_INITIALIZATION
if (WRENW != 1) begin : g_wren
always @(posedge clk) begin
if (write) begin
`RAM_WRITE_WREN
if (1) begin : g_async_ram
if (DUAL_PORT != 0) begin : g_dp
if (WRENW != 1) begin : g_wren
if (WRITE_FIRST) begin : g_write_first
`define RAM_ATTRIBUTES `RW_RAM_CHECK
`ASYNC_RAM_BLOCK_WREN(rdata_a, write, raddr, waddr);
`undef RAM_ATTRIBUTES
end else begin : g_read_first
`define RAM_ATTRIBUTES `NO_RW_RAM_CHECK
`ASYNC_RAM_BLOCK_WREN(rdata_a, write, raddr, waddr);
`undef RAM_ATTRIBUTES
end
end
end else begin : g_no_wren
always @(posedge clk) begin
if (write) begin
ram[waddr] <= wdata;
end else begin : g_no_wren
if (WRITE_FIRST) begin : g_write_first
`define RAM_ATTRIBUTES `RW_RAM_CHECK
`ASYNC_RAM_BLOCK(rdata_a, write, raddr, waddr);
`undef RAM_ATTRIBUTES
end else begin : g_read_first
`define RAM_ATTRIBUTES `NO_RW_RAM_CHECK
`ASYNC_RAM_BLOCK(rdata_a, write, raddr, waddr);
`undef RAM_ATTRIBUTES
end
end
end
assign rdata_a = ram[raddr];
end else begin : g_sp_async_ram
reg [DATAW-1:0] ram [0:SIZE-1];
`RAM_INITIALIZATION
if (WRENW != 1) begin : g_wren
always @(posedge clk) begin
if (write) begin
`RAM_WRITE_WREN
end else begin : g_sp
if (WRENW != 1) begin : g_wren
if (WRITE_FIRST) begin : g_write_first
`define RAM_ATTRIBUTES `RW_RAM_CHECK
`ASYNC_RAM_BLOCK_WREN(rdata_a, write, waddr, waddr);
`undef RAM_ATTRIBUTES
end else begin : g_read_first
`define RAM_ATTRIBUTES `NO_RW_RAM_CHECK
`ASYNC_RAM_BLOCK_WREN(rdata_a, write, waddr, waddr);
`undef RAM_ATTRIBUTES
end
end
end else begin : g_no_wren
always @(posedge clk) begin
if (write) begin
ram[waddr] <= wdata;
end else begin : g_no_wren
if (WRITE_FIRST) begin : g_write_first
`define RAM_ATTRIBUTES `RW_RAM_CHECK
`ASYNC_RAM_BLOCK(rdata_a, write, waddr, waddr);
`undef RAM_ATTRIBUTES
end else begin : g_read_first
`define RAM_ATTRIBUTES `NO_RW_RAM_CHECK
`ASYNC_RAM_BLOCK(rdata_a, write, waddr, waddr);
`undef RAM_ATTRIBUTES
end
end
end
assign rdata_a = ram[waddr];
end

assign rdata = is_raddr_reg ? rdata_s : rdata_a;
Expand Down
Loading

0 comments on commit 320c090

Please sign in to comment.