mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-23 21:39:10 -04:00
xilinx asynchronous bram patch fixes
Some checks failed
CI / setup (push) Has been cancelled
CI / build (32) (push) Has been cancelled
CI / build (64) (push) Has been cancelled
CI / tests (cache, 32) (push) Has been cancelled
CI / tests (cache, 64) (push) Has been cancelled
CI / tests (config1, 32) (push) Has been cancelled
CI / tests (config1, 64) (push) Has been cancelled
CI / tests (config2, 32) (push) Has been cancelled
CI / tests (config2, 64) (push) Has been cancelled
CI / tests (debug, 32) (push) Has been cancelled
CI / tests (debug, 64) (push) Has been cancelled
CI / tests (opencl, 32) (push) Has been cancelled
CI / tests (opencl, 64) (push) Has been cancelled
CI / tests (regression, 32) (push) Has been cancelled
CI / tests (regression, 64) (push) Has been cancelled
CI / tests (scope, 32) (push) Has been cancelled
CI / tests (scope, 64) (push) Has been cancelled
CI / tests (stress, 32) (push) Has been cancelled
CI / tests (stress, 64) (push) Has been cancelled
CI / tests (synthesis, 32) (push) Has been cancelled
CI / tests (synthesis, 64) (push) Has been cancelled
CI / tests (vm, 32) (push) Has been cancelled
CI / tests (vm, 64) (push) Has been cancelled
CI / complete (push) Has been cancelled
Some checks failed
CI / setup (push) Has been cancelled
CI / build (32) (push) Has been cancelled
CI / build (64) (push) Has been cancelled
CI / tests (cache, 32) (push) Has been cancelled
CI / tests (cache, 64) (push) Has been cancelled
CI / tests (config1, 32) (push) Has been cancelled
CI / tests (config1, 64) (push) Has been cancelled
CI / tests (config2, 32) (push) Has been cancelled
CI / tests (config2, 64) (push) Has been cancelled
CI / tests (debug, 32) (push) Has been cancelled
CI / tests (debug, 64) (push) Has been cancelled
CI / tests (opencl, 32) (push) Has been cancelled
CI / tests (opencl, 64) (push) Has been cancelled
CI / tests (regression, 32) (push) Has been cancelled
CI / tests (regression, 64) (push) Has been cancelled
CI / tests (scope, 32) (push) Has been cancelled
CI / tests (scope, 64) (push) Has been cancelled
CI / tests (stress, 32) (push) Has been cancelled
CI / tests (stress, 64) (push) Has been cancelled
CI / tests (synthesis, 32) (push) Has been cancelled
CI / tests (synthesis, 64) (push) Has been cancelled
CI / tests (vm, 32) (push) Has been cancelled
CI / tests (vm, 64) (push) Has been cancelled
CI / complete (push) Has been cancelled
This commit is contained in:
parent
8230b37411
commit
320c090613
9 changed files with 529 additions and 296 deletions
|
@ -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 *)
|
||||
|
@ -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 *)
|
||||
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
@ -32,14 +26,93 @@
|
|||
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 \
|
||||
bypass_valid_r <= read_s && write && (raddr_s == waddr); \
|
||||
bypass_data_r <= wdata; \
|
||||
if (__re || __we) begin \
|
||||
if (__we) begin \
|
||||
ram[__wa] <= wdata; \
|
||||
end \
|
||||
raddr_r <= __ra; \
|
||||
end \
|
||||
end \
|
||||
assign __d = bypass_valid_r ? bypass_data_r : rdata_r
|
||||
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 \
|
||||
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 = 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 #(
|
||||
|
@ -47,6 +120,8 @@ module VX_async_ram_patch #(
|
|||
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,
|
||||
|
@ -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, rdata_a;
|
||||
|
||||
wire [DATAW-1:0] rdata_s;
|
||||
|
||||
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
|
||||
end
|
||||
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 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
|
||||
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 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 else begin : g_no_wren
|
||||
always @(posedge clk) begin
|
||||
if (write) begin
|
||||
ram[waddr] <= wdata;
|
||||
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 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[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
|
||||
end
|
||||
end else begin : g_no_wren
|
||||
always @(posedge clk) begin
|
||||
if (write) begin
|
||||
ram[waddr] <= wdata;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign rdata_a = ram[waddr];
|
||||
end
|
||||
|
||||
assign rdata = is_raddr_reg ? rdata_s : rdata_a;
|
||||
|
|
|
@ -80,7 +80,7 @@ module VX_dp_ram #(
|
|||
if (FORCE_BRAM) begin : g_bram
|
||||
if (RDW_MODE == "W") begin : g_write_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
(* rw_addr_collision = "yes" *) `USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
`RW_RAM_CHECK `USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
reg [ADDRW-1:0] raddr_r;
|
||||
always @(posedge clk) begin
|
||||
|
@ -93,7 +93,7 @@ module VX_dp_ram #(
|
|||
end
|
||||
assign rdata = ram[raddr_r];
|
||||
end else begin : g_no_wren
|
||||
(* rw_addr_collision = "yes" *) `USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RW_RAM_CHECK `USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RAM_INITIALIZATION
|
||||
reg [ADDRW-1:0] raddr_r;
|
||||
always @(posedge clk) begin
|
||||
|
@ -166,7 +166,7 @@ module VX_dp_ram #(
|
|||
end else begin : g_auto
|
||||
if (RDW_MODE == "W") begin : g_write_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
(* rw_addr_collision = "yes" *) `RAM_ARRAY_WREN
|
||||
`RW_RAM_CHECK `RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
reg [ADDRW-1:0] raddr_r;
|
||||
always @(posedge clk) begin
|
||||
|
@ -179,7 +179,7 @@ module VX_dp_ram #(
|
|||
end
|
||||
assign rdata = ram[raddr_r];
|
||||
end else begin : g_no_wren
|
||||
(* rw_addr_collision = "yes" *) reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RW_RAM_CHECK reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RAM_INITIALIZATION
|
||||
reg [ADDRW-1:0] raddr_r;
|
||||
always @(posedge clk) begin
|
||||
|
@ -220,7 +220,7 @@ module VX_dp_ram #(
|
|||
end
|
||||
assign rdata = rdata_r;
|
||||
end
|
||||
end else begin
|
||||
end else begin : g_undefined
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
|
@ -253,30 +253,32 @@ module VX_dp_ram #(
|
|||
end else begin : g_async
|
||||
`UNUSED_VAR (read)
|
||||
if (FORCE_BRAM) begin : g_bram
|
||||
`ifdef VIVADO
|
||||
VX_async_ram_patch #(
|
||||
.DATAW (DATAW),
|
||||
.SIZE (SIZE),
|
||||
.WRENW (WRENW),
|
||||
.DUAL_PORT (1),
|
||||
.FORCE_BRAM (FORCE_BRAM),
|
||||
.WRITE_FIRST(RDW_MODE == "W"),
|
||||
.INIT_ENABLE(INIT_ENABLE),
|
||||
.INIT_FILE (INIT_FILE),
|
||||
.INIT_VALUE (INIT_VALUE)
|
||||
) async_ram_patch (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.read (read),
|
||||
.write (write),
|
||||
.wren (wren),
|
||||
.waddr (waddr),
|
||||
.wdata (wdata),
|
||||
.raddr (raddr),
|
||||
.rdata (rdata)
|
||||
);
|
||||
`else
|
||||
if (RDW_MODE == "W") begin : g_write_first
|
||||
`ifdef VIVADO
|
||||
VX_async_ram_patch #(
|
||||
.DATAW (DATAW),
|
||||
.SIZE (SIZE),
|
||||
.WRENW (WRENW),
|
||||
.DUAL_PORT (1),
|
||||
.INIT_ENABLE(INIT_ENABLE),
|
||||
.INIT_FILE (INIT_FILE),
|
||||
.INIT_VALUE (INIT_VALUE)
|
||||
) async_ram_patch (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.read (read),
|
||||
.write (write),
|
||||
.wren (wren),
|
||||
.waddr (waddr),
|
||||
.wdata (wdata),
|
||||
.raddr (raddr),
|
||||
.rdata (rdata)
|
||||
);
|
||||
`else
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
`RW_RAM_CHECK `USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
always @(posedge clk) begin
|
||||
if (write) begin
|
||||
|
@ -285,7 +287,7 @@ module VX_dp_ram #(
|
|||
end
|
||||
assign rdata = ram[raddr];
|
||||
end else begin : g_no_wren
|
||||
`USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RW_RAM_CHECK `USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RAM_INITIALIZATION
|
||||
always @(posedge clk) begin
|
||||
if (write) begin
|
||||
|
@ -294,7 +296,6 @@ module VX_dp_ram #(
|
|||
end
|
||||
assign rdata = ram[raddr];
|
||||
end
|
||||
`endif
|
||||
end else begin : g_read_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`NO_RW_RAM_CHECK `USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
|
@ -316,10 +317,11 @@ module VX_dp_ram #(
|
|||
assign rdata = ram[raddr];
|
||||
end
|
||||
end
|
||||
`endif
|
||||
end else begin : g_auto
|
||||
if (RDW_MODE == "W") begin : g_write_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`RAM_ARRAY_WREN
|
||||
`RW_RAM_CHECK `RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
always @(posedge clk) begin
|
||||
if (write) begin
|
||||
|
@ -328,7 +330,7 @@ module VX_dp_ram #(
|
|||
end
|
||||
assign rdata = ram[raddr];
|
||||
end else begin : g_no_wren
|
||||
reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RW_RAM_CHECK reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RAM_INITIALIZATION
|
||||
always @(posedge clk) begin
|
||||
if (write) begin
|
||||
|
|
|
@ -485,7 +485,7 @@ module VX_rr_arbiter #(
|
|||
.D (NUM_REQS)
|
||||
) grant_decoder (
|
||||
.sel_in (grant_index),
|
||||
.data_in (1'b1),
|
||||
.data_in (grant_valid),
|
||||
.data_out (grant_onehot)
|
||||
);
|
||||
|
||||
|
|
|
@ -77,37 +77,9 @@ module VX_sp_ram #(
|
|||
localparam FORCE_BRAM = !LUTRAM && (SIZE * DATAW >= `MAX_LUTRAM);
|
||||
if (OUT_REG) begin : g_sync
|
||||
if (FORCE_BRAM) begin : g_bram
|
||||
if (RDW_MODE == "R") begin : g_read_first
|
||||
if (RDW_MODE == "W") begin : g_write_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
reg [DATAW-1:0] rdata_r;
|
||||
always @(posedge clk) begin
|
||||
if (read || write) begin
|
||||
if (write) begin
|
||||
`RAM_WRITE_WREN
|
||||
end
|
||||
rdata_r <= ram[addr];
|
||||
end
|
||||
end
|
||||
assign rdata = rdata_r;
|
||||
end else begin : g_no_wren
|
||||
`USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RAM_INITIALIZATION
|
||||
reg [DATAW-1:0] rdata_r;
|
||||
always @(posedge clk) begin
|
||||
if (read || write) begin
|
||||
if (write) begin
|
||||
ram[addr] <= wdata;
|
||||
end
|
||||
rdata_r <= ram[addr];
|
||||
end
|
||||
end
|
||||
assign rdata = rdata_r;
|
||||
end
|
||||
end else if (RDW_MODE == "W") begin : g_write_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
`RW_RAM_CHECK `USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
reg [ADDRW-1:0] addr_r;
|
||||
always @(posedge clk) begin
|
||||
|
@ -135,6 +107,34 @@ module VX_sp_ram #(
|
|||
end
|
||||
assign rdata = rdata_r;
|
||||
end
|
||||
end else if (RDW_MODE == "R") begin : g_read_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
reg [DATAW-1:0] rdata_r;
|
||||
always @(posedge clk) begin
|
||||
if (read || write) begin
|
||||
if (write) begin
|
||||
`RAM_WRITE_WREN
|
||||
end
|
||||
rdata_r <= ram[addr];
|
||||
end
|
||||
end
|
||||
assign rdata = rdata_r;
|
||||
end else begin : g_no_wren
|
||||
`USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RAM_INITIALIZATION
|
||||
reg [DATAW-1:0] rdata_r;
|
||||
always @(posedge clk) begin
|
||||
if (read || write) begin
|
||||
if (write) begin
|
||||
ram[addr] <= wdata;
|
||||
end
|
||||
rdata_r <= ram[addr];
|
||||
end
|
||||
end
|
||||
assign rdata = rdata_r;
|
||||
end
|
||||
end else if (RDW_MODE == "N") begin : g_no_change
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
|
@ -165,7 +165,7 @@ module VX_sp_ram #(
|
|||
end
|
||||
assign rdata = rdata_r;
|
||||
end
|
||||
end else if (RDW_MODE == "U") begin : g_unknown
|
||||
end else if (RDW_MODE == "U") begin : g_undefined
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
|
@ -195,35 +195,7 @@ module VX_sp_ram #(
|
|||
end
|
||||
end
|
||||
end else begin : g_auto
|
||||
if (RDW_MODE == "R") begin : g_read_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
reg [DATAW-1:0] rdata_r;
|
||||
always @(posedge clk) begin
|
||||
if (read || write) begin
|
||||
if (write) begin
|
||||
`RAM_WRITE_WREN
|
||||
end
|
||||
rdata_r <= ram[addr];
|
||||
end
|
||||
end
|
||||
assign rdata = rdata_r;
|
||||
end else begin : g_no_wren
|
||||
reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RAM_INITIALIZATION
|
||||
reg [DATAW-1:0] rdata_r;
|
||||
always @(posedge clk) begin
|
||||
if (read || write) begin
|
||||
if (write) begin
|
||||
ram[addr] <= wdata;
|
||||
end
|
||||
rdata_r <= ram[addr];
|
||||
end
|
||||
end
|
||||
assign rdata = rdata_r;
|
||||
end
|
||||
end else if (RDW_MODE == "W") begin : g_write_first
|
||||
if (RDW_MODE == "W") begin : g_write_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
|
@ -253,6 +225,34 @@ module VX_sp_ram #(
|
|||
end
|
||||
assign rdata = rdata_r;
|
||||
end
|
||||
end else if (RDW_MODE == "R") begin : g_read_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
reg [DATAW-1:0] rdata_r;
|
||||
always @(posedge clk) begin
|
||||
if (read || write) begin
|
||||
if (write) begin
|
||||
`RAM_WRITE_WREN
|
||||
end
|
||||
rdata_r <= ram[addr];
|
||||
end
|
||||
end
|
||||
assign rdata = rdata_r;
|
||||
end else begin : g_no_wren
|
||||
reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RAM_INITIALIZATION
|
||||
reg [DATAW-1:0] rdata_r;
|
||||
always @(posedge clk) begin
|
||||
if (read || write) begin
|
||||
if (write) begin
|
||||
ram[addr] <= wdata;
|
||||
end
|
||||
rdata_r <= ram[addr];
|
||||
end
|
||||
end
|
||||
assign rdata = rdata_r;
|
||||
end
|
||||
end else if (RDW_MODE == "N") begin : g_no_change
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`RAM_ARRAY_WREN
|
||||
|
@ -283,7 +283,7 @@ module VX_sp_ram #(
|
|||
end
|
||||
assign rdata = rdata_r;
|
||||
end
|
||||
end else if (RDW_MODE == "U") begin : g_unknown
|
||||
end else if (RDW_MODE == "U") begin : g_undefined
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
|
@ -316,30 +316,32 @@ module VX_sp_ram #(
|
|||
end else begin : g_async
|
||||
`UNUSED_VAR (read)
|
||||
if (FORCE_BRAM) begin : g_bram
|
||||
`ifdef VIVADO
|
||||
VX_async_ram_patch #(
|
||||
.DATAW (DATAW),
|
||||
.SIZE (SIZE),
|
||||
.WRENW (WRENW),
|
||||
.DUAL_PORT (0),
|
||||
.FORCE_BRAM (FORCE_BRAM),
|
||||
.WRITE_FIRST(RDW_MODE == "W"),
|
||||
.INIT_ENABLE(INIT_ENABLE),
|
||||
.INIT_FILE (INIT_FILE),
|
||||
.INIT_VALUE (INIT_VALUE)
|
||||
) async_ram_patch (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.read (read),
|
||||
.write (write),
|
||||
.wren (wren),
|
||||
.waddr (addr),
|
||||
.wdata (wdata),
|
||||
.raddr (addr),
|
||||
.rdata (rdata)
|
||||
);
|
||||
`else
|
||||
if (RDW_MODE == "W") begin : g_write_first
|
||||
`ifdef VIVADO
|
||||
VX_async_ram_patch #(
|
||||
.DATAW (DATAW),
|
||||
.SIZE (SIZE),
|
||||
.WRENW (WRENW),
|
||||
.DUAL_PORT (0),
|
||||
.INIT_ENABLE(INIT_ENABLE),
|
||||
.INIT_FILE (INIT_FILE),
|
||||
.INIT_VALUE (INIT_VALUE)
|
||||
) async_ram_patch (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.read (read),
|
||||
.write (write),
|
||||
.wren (wren),
|
||||
.waddr (addr),
|
||||
.wdata (wdata),
|
||||
.raddr (addr),
|
||||
.rdata (rdata)
|
||||
);
|
||||
`else
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
`RW_RAM_CHECK `USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
always @(posedge clk) begin
|
||||
if (write) begin
|
||||
|
@ -348,7 +350,7 @@ module VX_sp_ram #(
|
|||
end
|
||||
assign rdata = ram[addr];
|
||||
end else begin : g_no_wren
|
||||
`USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RW_RAM_CHECK `USE_BLOCK_BRAM reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RAM_INITIALIZATION
|
||||
always @(posedge clk) begin
|
||||
if (write) begin
|
||||
|
@ -357,7 +359,6 @@ module VX_sp_ram #(
|
|||
end
|
||||
assign rdata = ram[addr];
|
||||
end
|
||||
`endif
|
||||
end else begin : g_read_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`NO_RW_RAM_CHECK `USE_BLOCK_BRAM `RAM_ARRAY_WREN
|
||||
|
@ -379,10 +380,11 @@ module VX_sp_ram #(
|
|||
assign rdata = ram[addr];
|
||||
end
|
||||
end
|
||||
`endif
|
||||
end else begin : g_auto
|
||||
if (RDW_MODE == "W") begin : g_write_first
|
||||
if (WRENW != 1) begin : g_wren
|
||||
`RAM_ARRAY_WREN
|
||||
`RW_RAM_CHECK `RAM_ARRAY_WREN
|
||||
`RAM_INITIALIZATION
|
||||
always @(posedge clk) begin
|
||||
if (write) begin
|
||||
|
@ -391,7 +393,7 @@ module VX_sp_ram #(
|
|||
end
|
||||
assign rdata = ram[addr];
|
||||
end else begin : g_no_wren
|
||||
reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RW_RAM_CHECK reg [DATAW-1:0] ram [0:SIZE-1];
|
||||
`RAM_INITIALIZATION
|
||||
always @(posedge clk) begin
|
||||
if (write) begin
|
||||
|
@ -443,15 +445,7 @@ module VX_sp_ram #(
|
|||
end
|
||||
|
||||
if (OUT_REG) begin : g_sync
|
||||
if (RDW_MODE == "R") begin : g_read_first
|
||||
reg [DATAW-1:0] rdata_r;
|
||||
always @(posedge clk) begin
|
||||
if (read || write) begin
|
||||
rdata_r <= ram[addr];
|
||||
end
|
||||
end
|
||||
assign rdata = rdata_r;
|
||||
end else if (RDW_MODE == "W") begin : g_write_first
|
||||
if (RDW_MODE == "W") begin : g_write_first
|
||||
reg [ADDRW-1:0] addr_r;
|
||||
always @(posedge clk) begin
|
||||
if (read || write) begin
|
||||
|
@ -459,6 +453,14 @@ module VX_sp_ram #(
|
|||
end
|
||||
end
|
||||
assign rdata = ram[addr_r];
|
||||
end else if (RDW_MODE == "R") begin : g_read_first
|
||||
reg [DATAW-1:0] rdata_r;
|
||||
always @(posedge clk) begin
|
||||
if (read || write) begin
|
||||
rdata_r <= ram[addr];
|
||||
end
|
||||
end
|
||||
assign rdata = rdata_r;
|
||||
end else if (RDW_MODE == "N") begin : g_no_change
|
||||
reg [DATAW-1:0] rdata_r;
|
||||
always @(posedge clk) begin
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
# Copyright © 2019-2023
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
namespace eval vortex {
|
||||
|
||||
variable debug 0
|
||||
|
@ -17,6 +30,25 @@ proc str_replace {str match repl} {
|
|||
return $result
|
||||
}
|
||||
|
||||
proc regex_escape {str} {
|
||||
return [string map {
|
||||
\\ \\\\
|
||||
^ \\^
|
||||
. \\.
|
||||
\[ \\\[
|
||||
\] \\\]
|
||||
\$ \\\$
|
||||
\( \\\(
|
||||
\) \\\)
|
||||
| \\|
|
||||
* \\*
|
||||
+ \\+
|
||||
? \\?
|
||||
\{ \\\{
|
||||
\} \\\}
|
||||
} $str]
|
||||
}
|
||||
|
||||
proc unique_cell_name {name} {
|
||||
if {[get_cells -quiet $name] == {}} { return $name }
|
||||
set index 0
|
||||
|
@ -31,31 +63,60 @@ proc unique_net_name {name} {
|
|||
return ${name}_${index}
|
||||
}
|
||||
|
||||
proc find_nested_cells {parent name_match {should_exist 1}} {
|
||||
proc build_parent_child_map {all_cells} {
|
||||
set parent_child_map {}
|
||||
foreach cell $all_cells {
|
||||
set parent [get_property PARENT $cell]
|
||||
if {$parent ne ""} {
|
||||
if {[dict exists $parent_child_map $parent]} {
|
||||
dict lappend parent_child_map $parent $cell
|
||||
} else {
|
||||
dict set parent_child_map $parent [list $cell]
|
||||
}
|
||||
}
|
||||
}
|
||||
return $parent_child_map
|
||||
}
|
||||
|
||||
proc find_cell_descendants_recursive {parent_cell parent_child_map} {
|
||||
set descendants {}
|
||||
if {[dict exists $parent_child_map $parent_cell]} {
|
||||
set children [dict get $parent_child_map $parent_cell]
|
||||
foreach child $children {
|
||||
# Add the child to the list
|
||||
lappend descendants $child
|
||||
# Recursively add its descendants
|
||||
set sub_descendants [find_cell_descendants_recursive $child $parent_child_map]
|
||||
lappend descendants {*}$sub_descendants
|
||||
}
|
||||
}
|
||||
return $descendants
|
||||
}
|
||||
|
||||
proc find_cell_descendants {parent_cell} {
|
||||
set all_cells [get_cells -hierarchical]
|
||||
set parent_child_map [build_parent_child_map $all_cells]
|
||||
return [find_cell_descendants_recursive $parent_cell $parent_child_map]
|
||||
}
|
||||
|
||||
proc find_nested_cells {parent_cell name_match {should_exist 1}} {
|
||||
set hier_sep [get_hierarchy_separator]
|
||||
set matching_cells {}
|
||||
foreach cell [get_cells -hierarchical -include_replicated_objects -filter "PARENT == $parent"] {
|
||||
set name [get_property NAME $cell]
|
||||
if {[regexp $name_match $name]} {
|
||||
foreach cell [find_cell_descendants $parent_cell] {
|
||||
set parent_name [get_property PARENT $cell]
|
||||
set cell_name [get_property NAME $cell]
|
||||
set name_prefix [regex_escape "${parent_name}${hier_sep}"]
|
||||
set pattern "${name_prefix}${name_match}"
|
||||
if {[regexp $pattern $cell_name]} {
|
||||
lappend matching_cells $cell
|
||||
}
|
||||
}
|
||||
if {[llength $matching_cells] == 0} {
|
||||
print_error "No matching cell found for '$parent' matching '$name_match'." $should_exist
|
||||
print_error "No matching cell found for '$parent_cell' matching '$name_match'." $should_exist
|
||||
}
|
||||
return $matching_cells
|
||||
}
|
||||
|
||||
proc find_nested_cell {parent name_match} {
|
||||
foreach cell [get_cells -hierarchical -filter "PARENT == $parent"] {
|
||||
set name [get_property NAME $cell]
|
||||
if {$name == $name_match} {
|
||||
return $cell
|
||||
}
|
||||
}
|
||||
puts "ERROR: No matching cell found for '$parent' matching '$name_match'."
|
||||
exit -1
|
||||
}
|
||||
|
||||
proc find_cell_nets {cell name_match {should_exist 1}} {
|
||||
set matching_nets {}
|
||||
foreach net [get_nets -hierarchical -filter "PARENT_CELL == $cell"] {
|
||||
|
@ -70,22 +131,23 @@ proc find_cell_nets {cell name_match {should_exist 1}} {
|
|||
return $matching_nets
|
||||
}
|
||||
|
||||
proc get_cell_net {cell name_match} {
|
||||
foreach net [get_nets -hierarchical -filter "PARENT_CELL == $cell"] {
|
||||
set name [get_property NAME $net]
|
||||
if {$name == $name_match} {
|
||||
return $net
|
||||
}
|
||||
proc get_cell_net {cell name} {
|
||||
set net [get_nets -hierarchical -filter "PARENT_CELL == $cell && NAME == $name"]
|
||||
if {[llength $net] == 0} {
|
||||
puts "ERROR: No matching net found for '$cell' matching '$name'."
|
||||
exit -1
|
||||
}
|
||||
puts "ERROR: No matching net found for '$cell' matching '$name_match'."
|
||||
exit -1
|
||||
return $net;
|
||||
}
|
||||
|
||||
proc find_cell_pins {cell name_match {should_exist 1}} {
|
||||
set hier_sep [get_hierarchy_separator]
|
||||
set matching_pins {}
|
||||
foreach pin [get_pins -of_objects $cell] {
|
||||
set name [get_property NAME $pin]
|
||||
if {[regexp $name_match $name]} {
|
||||
set name_prefix [regex_escape "${cell}${hier_sep}"]
|
||||
set pattern "${name_prefix}${name_match}"
|
||||
if {[regexp $pattern $name]} {
|
||||
lappend matching_pins $pin
|
||||
}
|
||||
}
|
||||
|
@ -95,15 +157,31 @@ proc find_cell_pins {cell name_match {should_exist 1}} {
|
|||
return $matching_pins
|
||||
}
|
||||
|
||||
proc get_cell_pin {cell name_match} {
|
||||
foreach pin [get_pins -of_objects $cell] {
|
||||
set name [get_property NAME $pin]
|
||||
if {$name == $name_match} {
|
||||
return $pin
|
||||
}
|
||||
proc get_cell_pin {cell name} {
|
||||
set pin [get_pins -of_objects $cell -filter "NAME == $name"]
|
||||
if {[llength $pin] == 0} {
|
||||
puts "ERROR: No matching pin found for '$cell' matching '$name'."
|
||||
exit -1
|
||||
}
|
||||
puts "ERROR: No matching pin found for '$cell' matching '$name_match'."
|
||||
exit -1
|
||||
return $pin
|
||||
}
|
||||
|
||||
proc remove_cell_from_netlist {cell} {
|
||||
variable debug
|
||||
|
||||
puts "INFO: Removing cell '$cell' from the netlist."
|
||||
|
||||
# Disconnect all pins of the cell
|
||||
#foreach pin [get_pins -quiet -of_objects $cell] {
|
||||
# foreach net [get_nets -quiet -of_objects $pin] {
|
||||
# disconnect_net -net $net -objects $pin
|
||||
# if {$debug} {puts "DEBUG: Disconnected net '$net' from pin '$pin'."}
|
||||
# }
|
||||
#}
|
||||
|
||||
# Remove the cell
|
||||
remove_cell $cell
|
||||
if {$debug} {puts "DEBUG: Cell '$cell' was removed successfully."}
|
||||
}
|
||||
|
||||
proc replace_pin_source {pin source_pin} {
|
||||
|
@ -141,10 +219,42 @@ proc replace_pin_source {pin source_pin} {
|
|||
if {$debug} {puts "DEBUG: Connected net '$source_net' to pin '$pin'."}
|
||||
}
|
||||
|
||||
proc create_register_next {reg_cell prefix_name} {
|
||||
proc find_net_driver {input_net {should_exist 1}} {
|
||||
set driverPins [get_pins -quiet -leaf -of_objects $input_net -filter {DIRECTION == "OUT"}]
|
||||
if {[llength $driverPins] == 0} {
|
||||
set driverPorts [get_ports -quiet -of_objects $input_net -filter {DIRECTION == "IN"}]
|
||||
if {[llength $driverPorts] == 0} {
|
||||
print_error "No driver found for '$input_net'." $should_exist
|
||||
} elseif {[llength $driverPorts] > 1} {
|
||||
puts "WARNING: Multiple driver ports found for '$input_net'."
|
||||
return [lindex $driverPorts 0]
|
||||
}
|
||||
return $driverPorts
|
||||
} elseif {[llength $driverPins] > 1} {
|
||||
puts "WARNING: Multiple driver pins found for '$input_net'."
|
||||
return [lindex $driverPins 0]
|
||||
}
|
||||
return $driverPins
|
||||
}
|
||||
|
||||
proc find_pin_driver {input_pin {should_exist 1}} {
|
||||
set net [get_nets -quiet -of_objects $input_pin]
|
||||
if {[llength $net] == 0} {
|
||||
print_error "No net connected to pin '$input_pin'." $should_exist
|
||||
return ""
|
||||
} elseif {[llength $net] > 1} {
|
||||
puts "ERROR: Multiple nets connected to pin '$input_pin'."
|
||||
exit -1
|
||||
}
|
||||
return [find_net_driver $net]
|
||||
}
|
||||
|
||||
proc create_register_next {parent reg_cell} {
|
||||
variable debug
|
||||
|
||||
set reg_d_pin [get_pins -of_objects $reg_cell -filter {NAME =~ "*/D"}]
|
||||
set hier_sep [get_hierarchy_separator]
|
||||
|
||||
set reg_d_pin [get_pins "${reg_cell}${hier_sep}D"]
|
||||
if {[llength $reg_d_pin] == 0} {
|
||||
puts "ERROR: No D pin found on register cell '$reg_cell'."
|
||||
exit -1
|
||||
|
@ -167,7 +277,7 @@ proc create_register_next {reg_cell prefix_name} {
|
|||
|
||||
set register_type [get_property REF_NAME $reg_cell]
|
||||
if {$register_type == "FDRE"} {
|
||||
set reg_r_pin [get_pins -of_objects $reg_cell -filter {NAME =~ "*/R"}]
|
||||
set reg_r_pin [get_pins "${reg_cell}${hier_sep}R"]
|
||||
if {[llength $reg_r_pin] == 0} {
|
||||
puts "ERROR: No R pin found on FDRE cell '$reg_cell'."
|
||||
exit -1
|
||||
|
@ -184,7 +294,7 @@ proc create_register_next {reg_cell prefix_name} {
|
|||
exit -1
|
||||
}
|
||||
} elseif {$register_type == "FDSE"} {
|
||||
set reg_s_pin [get_pins -of_objects $reg_cell -filter {NAME =~ "*/S"}]
|
||||
set reg_s_pin [get_pins "${reg_cell}${hier_sep}S"]
|
||||
if {[llength $reg_s_pin] == 0} {
|
||||
puts "ERROR: No S pin found on FDSE cell '$reg_cell'."
|
||||
exit -1
|
||||
|
@ -229,7 +339,7 @@ proc create_register_next {reg_cell prefix_name} {
|
|||
# Use a 2x1 LUT to describe the logic:
|
||||
# FDRE: O = I1 ? 0 : I0; where I0=D, I1=R
|
||||
# FDSE: O = I1 ? 1 : I0; where I0=D, I1=S
|
||||
set lut_name [unique_cell_name $prefix_name]
|
||||
set lut_name [unique_cell_name "${parent}${hier_sep}raddr_next"]
|
||||
set lut_cell [create_cell -reference LUT2 $lut_name]
|
||||
puts "INFO: Created lut cell: '$lut_cell'"
|
||||
|
||||
|
@ -242,7 +352,7 @@ proc create_register_next {reg_cell prefix_name} {
|
|||
exit 1
|
||||
}
|
||||
|
||||
set lut_i0_pin [get_pins -of_objects $lut_cell -filter {NAME =~ "*/I0"}]
|
||||
set lut_i0_pin [get_pins "${lut_cell}${hier_sep}I0"]
|
||||
if {[llength $lut_i0_pin] == 0} {
|
||||
puts "ERROR: No I0 pin found on FDSE cell '$lut_cell'."
|
||||
exit -1
|
||||
|
@ -251,7 +361,7 @@ proc create_register_next {reg_cell prefix_name} {
|
|||
exit -1
|
||||
}
|
||||
|
||||
set lut_i1_pin [get_pins -of_objects $lut_cell -filter {NAME =~ "*/I1"}]
|
||||
set lut_i1_pin [get_pins "${lut_cell}${hier_sep}I1"]
|
||||
if {[llength $lut_i1_pin] == 0} {
|
||||
puts "ERROR: No I1 pin found on FDSE cell '$lut_cell'."
|
||||
exit -1
|
||||
|
@ -260,7 +370,7 @@ proc create_register_next {reg_cell prefix_name} {
|
|||
exit -1
|
||||
}
|
||||
|
||||
set lut_o_pin [get_pins -of_objects $lut_cell -filter {NAME =~ "*/O"}]
|
||||
set lut_o_pin [get_pins "${lut_cell}${hier_sep}O"]
|
||||
if {[llength $lut_o_pin] == 0} {
|
||||
puts "ERROR: No O pin found on FDSE cell '$lut_cell'."
|
||||
exit -1
|
||||
|
@ -278,19 +388,22 @@ proc create_register_next {reg_cell prefix_name} {
|
|||
return $lut_o_pin
|
||||
}
|
||||
|
||||
proc getOrCreateVCCPin {prefix_name} {
|
||||
proc getOrCreateVCCPin {parent} {
|
||||
variable debug
|
||||
|
||||
set vcc_cell ""
|
||||
set vcc_cells [get_cells -quiet -filter {REF_NAME == VCC}]
|
||||
if {[llength $vcc_cells] == 0} {
|
||||
set cell_name [unique_cell_name $prefix_name]
|
||||
set hier_sep [get_hierarchy_separator]
|
||||
set cell_name "${parent}${hier_sep}VCC"
|
||||
|
||||
set vcc_cell [get_cells -quiet $cell_name]
|
||||
if {[llength $vcc_cell] == 0} {
|
||||
set vcc_cell [create_cell -reference VCC $cell_name]
|
||||
puts "INFO: Created VCC cell: '$vcc_cell'"
|
||||
} else {
|
||||
set vcc_cell [lindex $vcc_cells 0]
|
||||
} elseif {[llength $vcc_cell] > 1} {
|
||||
puts "ERROR: Multiple VCC cells found with name '$cell_name'."
|
||||
exit -1
|
||||
}
|
||||
set vcc_pin [get_pins -of_objects $vcc_cell -filter {NAME =~ "*/P"}]
|
||||
|
||||
set vcc_pin [get_pins "${vcc_cell}${hier_sep}P"]
|
||||
if {[llength $vcc_pin] == 0} {
|
||||
puts "ERROR: No VCC pin found on VCC cell '$vcc_cell'."
|
||||
exit -1
|
||||
|
@ -298,22 +411,26 @@ proc getOrCreateVCCPin {prefix_name} {
|
|||
puts "ERROR: Multiple VCC pins found on VCC cell '$vcc_cell'."
|
||||
exit -1
|
||||
}
|
||||
|
||||
return $vcc_pin
|
||||
}
|
||||
|
||||
proc getOrCreateGNDPin {prefix_name} {
|
||||
proc getOrCreateGNDPin {parent} {
|
||||
variable debug
|
||||
|
||||
set gnd_cell ""
|
||||
set gnd_cells [get_cells -quiet -filter {REF_NAME == GND}]
|
||||
if {[llength $gnd_cells] == 0} {
|
||||
set cell_name [unique_cell_name $prefix_name]
|
||||
set hier_sep [get_hierarchy_separator]
|
||||
set cell_name "${parent}${hier_sep}GND"
|
||||
|
||||
set gnd_cell [get_cells -quiet $cell_name]
|
||||
if {[llength $gnd_cell] == 0} {
|
||||
set gnd_cell [create_cell -reference GND $cell_name]
|
||||
puts "INFO: Created GND cell: '$gnd_cell'"
|
||||
} else {
|
||||
set gnd_cell [lindex $gnd_cells 0]
|
||||
} elseif {[llength $gnd_cell] > 1} {
|
||||
puts "ERROR: Multiple GND cells found with name '$cell_name'."
|
||||
exit -1
|
||||
}
|
||||
set gnd_pin [get_pins -of_objects $gnd_cell -filter {NAME =~ "*/G"}]
|
||||
|
||||
set gnd_pin [get_pins "${gnd_cell}${hier_sep}G"]
|
||||
if {[llength $gnd_pin] == 0} {
|
||||
puts "ERROR: No GND pin found on GND cell '$gnd_cell'."
|
||||
exit -1
|
||||
|
@ -321,6 +438,7 @@ proc getOrCreateGNDPin {prefix_name} {
|
|||
puts "ERROR: Multiple GND pins found on GND cell '$gnd_cell'."
|
||||
exit -1
|
||||
}
|
||||
|
||||
return $gnd_pin
|
||||
}
|
||||
|
||||
|
@ -338,35 +456,6 @@ proc find_net_sinks {input_net {should_exist 1}} {
|
|||
return $sink_pins
|
||||
}
|
||||
|
||||
proc find_net_driver {input_net {should_exist 1}} {
|
||||
set driverPins [get_pins -quiet -leaf -of_objects $input_net -filter {DIRECTION == "OUT"}]
|
||||
if {[llength $driverPins] == 0} {
|
||||
set driverPorts [get_ports -quiet -of_objects $input_net -filter {DIRECTION == "IN"}]
|
||||
if {[llength $driverPorts] == 0} {
|
||||
print_error "No driver found for '$input_net'." $should_exist
|
||||
} elseif {[llength $driverPorts] > 1} {
|
||||
puts "WARNING: Multiple driver ports found for '$input_net'."
|
||||
return [lindex $driverPorts 0]
|
||||
}
|
||||
return $driverPorts
|
||||
} elseif {[llength $driverPins] > 1} {
|
||||
puts "WARNING: Multiple driver pins found for '$input_net'."
|
||||
return [lindex $driverPins 0]
|
||||
}
|
||||
return $driverPins
|
||||
}
|
||||
|
||||
proc find_pin_driver {input_pin {should_exist 1}} {
|
||||
set net [get_nets -quiet -of_objects $input_pin]
|
||||
if {[llength $net] == 0} {
|
||||
print_error "No net connected to pin '$input_pin'." $should_exist
|
||||
} elseif {[llength $net] > 1} {
|
||||
puts "ERROR: Multiple nets connected to pin '$input_pin'."
|
||||
exit -1
|
||||
}
|
||||
return [find_net_driver $net]
|
||||
}
|
||||
|
||||
proc find_matching_nets {cell nets match repl} {
|
||||
set matching_nets {}
|
||||
foreach net $nets {
|
||||
|
@ -386,6 +475,25 @@ proc find_matching_nets {cell nets match repl} {
|
|||
return $matching_nets
|
||||
}
|
||||
|
||||
proc find_matching_pins {cell pins match repl} {
|
||||
set matching_pins {}
|
||||
foreach pin $pins {
|
||||
set pin_name [str_replace $pin $match $repl]
|
||||
set matching_pin [get_cell_pin $cell $pin_name]
|
||||
if {$matching_pin != ""} {
|
||||
lappend matching_pins $matching_pin
|
||||
}
|
||||
}
|
||||
if {[llength $matching_pins] == 0} {
|
||||
puts "ERROR: No matching pins found for '$pins'."
|
||||
exit -1
|
||||
} elseif {[llength $matching_pins] != [llength $pins]} {
|
||||
puts "ERROR: Mismatch in number of matching pins."
|
||||
exit -1
|
||||
}
|
||||
return $matching_pins
|
||||
}
|
||||
|
||||
proc replace_net_source {net source_pin} {
|
||||
foreach pin [find_net_sinks $net 0] {
|
||||
replace_pin_source $pin $source_pin
|
||||
|
@ -397,6 +505,8 @@ proc resolve_async_bram {inst} {
|
|||
|
||||
puts "INFO: Resolving asynchronous BRAM patch: '$inst'."
|
||||
|
||||
set hier_sep [get_hierarchy_separator]
|
||||
|
||||
set raddr_w_nets [find_cell_nets $inst "raddr_w(\\\[\\d+\\\])?$"]
|
||||
set read_s_net [find_cell_nets $inst "read_s$"]
|
||||
set is_raddr_reg_net [find_cell_nets $inst "is_raddr_reg$"]
|
||||
|
@ -433,7 +543,7 @@ proc resolve_async_bram {inst} {
|
|||
}
|
||||
|
||||
# Create register next cell and return output pin
|
||||
set reg_next_pin [create_register_next $raddr_src_cell "$inst/raddr_next"]
|
||||
set reg_next_pin [create_register_next $inst $raddr_src_cell]
|
||||
if {$reg_next_pin == ""} {
|
||||
puts "ERROR: failed to create register next value for '$raddr_src_cell'."
|
||||
exit -1
|
||||
|
@ -444,7 +554,7 @@ proc resolve_async_bram {inst} {
|
|||
|
||||
# Find the CE pin on raddr_src_cell
|
||||
if {$reg_ce_src_pin == ""} {
|
||||
set reg_ce_pin [get_pins -of_objects $raddr_src_cell -filter {NAME =~ "*/CE"}]
|
||||
set reg_ce_pin [get_pins "${raddr_src_cell}${hier_sep}CE"]
|
||||
if {[llength $reg_ce_pin] == 0} {
|
||||
puts "ERROR: No CE pin found on register cell '$raddr_src_cell'."
|
||||
exit -1
|
||||
|
@ -466,9 +576,10 @@ proc resolve_async_bram {inst} {
|
|||
# do we have a fully registered read address?
|
||||
if {[llength $reg_next_pins] == [llength $raddr_w_nets]} {
|
||||
puts "INFO: Fully registered read address detected."
|
||||
|
||||
# Connect all reg_next_pins to all input pins attached to raddr_s_nets
|
||||
set addr_width [llength $raddr_w_nets]
|
||||
for {set addr_idx 0} {$addr_idx < $addr_width} {incr addr_idx} {
|
||||
set raddr_w_net [lindex $raddr_w_nets $addr_idx]
|
||||
set raddr_s_net [lindex $raddr_s_nets $addr_idx]
|
||||
set reg_next_pin [lindex $reg_next_pins $addr_idx]
|
||||
puts "INFO: Connecting pin '$reg_next_pin' to '$raddr_s_net's pins."
|
||||
|
@ -481,7 +592,7 @@ proc resolve_async_bram {inst} {
|
|||
replace_net_source $read_s_net $reg_ce_src_pin
|
||||
|
||||
# Create Const<1>'s pin
|
||||
set vcc_pin [getOrCreateVCCPin "$inst/VCC"]
|
||||
set vcc_pin [getOrCreateVCCPin $inst]
|
||||
|
||||
# Connect vcc_pin to all input pins attached to is_raddr_reg_net
|
||||
puts "INFO: Connecting pin '$vcc_pin' to '$is_raddr_reg_net's pins."
|
||||
|
@ -490,18 +601,16 @@ proc resolve_async_bram {inst} {
|
|||
puts "WARNING: Not all read addresses are registered!"
|
||||
|
||||
# Create Const<0>'s pin
|
||||
set gnd_pin [getOrCreateGNDPin "$inst/GND"]
|
||||
set gnd_pin [getOrCreateGNDPin $inst]
|
||||
|
||||
# Connect gnd_pin to all input pins attached to is_raddr_reg_net
|
||||
puts "INFO: Connecting pin '$gnd_pin' to '$is_raddr_reg_net's pins."
|
||||
replace_net_source $is_raddr_reg_net $gnd_pin
|
||||
}
|
||||
|
||||
# Remove all placeholder cells
|
||||
foreach cell [find_nested_cells $inst "placeholder$"] {
|
||||
remove_cell $cell
|
||||
if {$debug} {puts "DEBUG: Cell '$cell' was removed successfully."}
|
||||
}
|
||||
# Remove placeholder cell
|
||||
set placeholder [get_cells "${inst}${hier_sep}placeholder"]
|
||||
remove_cell_from_netlist $placeholder
|
||||
}
|
||||
|
||||
proc resolve_async_brams {} {
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
# Copyright © 2019-2023
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Function to export netlist to a Graphviz DOT file
|
||||
proc export_netlist {dot_file_name} {
|
||||
# Open the DOT file for writing
|
||||
|
|
|
@ -47,6 +47,9 @@ TARGET=hw PLATFORM=xilinx_u50_gen3x16_xdma_5_202210_1 make chipscope
|
|||
# analyze build report
|
||||
vitis_analyzer build_xilinx_u50_gen3x16_xdma_5_202210_1_hw_4c/bin/vortex_afu.xclbin.link_summary
|
||||
|
||||
# resuming build for routing
|
||||
TARGET=hw PLATFORM=xilinx_u55c_gen3x16_xdma_3_202210_1 VPP_FLAGS="--from_step vpl.impl.route_design" make > build.log 2>&1 &
|
||||
|
||||
# running test
|
||||
FPGA_BIN_DIR=<bin_dir> TARGET=hw_emu ./ci/blackbox.sh --driver=xrt --app=demo
|
||||
FPGA_BIN_DIR=<bin_dir> TARGET=hw ./ci/blackbox.sh --driver=xrt --app=demo
|
||||
|
|
|
@ -180,6 +180,7 @@ ifeq ($(TARGET), hw)
|
|||
cp $(BUILD_DIR)/_x/logs/link/vivado.log $(BUILD_DIR)/bin
|
||||
cp $(BUILD_DIR)/_x/logs/link/syn/ulp_vortex_afu_1_0_synth_1_runme.log $(BUILD_DIR)/bin
|
||||
cp $(BUILD_DIR)/_x/reports/link/syn/ulp_vortex_afu_1_0_synth_1_ulp_vortex_afu_1_0_utilization_synth.rpt $(BUILD_DIR)/bin
|
||||
cp $(BUILD_DIR)/_x/reports/link/imp/impl_1_hw_bb_locked_utilization_placed.rpt $(BUILD_DIR)/bin
|
||||
cp $(BUILD_DIR)/_x/reports/link/imp/impl_1_hw_bb_locked_timing_summary_routed.rpt $(BUILD_DIR)/bin
|
||||
endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue