From 30854b9c7f23e2817a445761022668d6b0f7c0ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Tue, 4 Feb 2020 15:35:47 +0100 Subject: xilinx: Add block RAM mapping for Virtex 2* and Spartan 3*. --- techlibs/xilinx/Makefile.inc | 3 + techlibs/xilinx/synth_xilinx.cc | 9 +- techlibs/xilinx/xc2v_brams.txt | 31 +++++ techlibs/xilinx/xc2v_brams_map.v | 266 ++++++++++++++++++++++++++++++++++++++ techlibs/xilinx/xc3sa_brams.txt | 51 ++++++++ techlibs/xilinx/xc3sda_brams.txt | 1 + techlibs/xilinx/xc6s_brams.txt | 1 + techlibs/xilinx/xc6s_brams_map.v | 3 + techlibs/xilinx/xc7_brams_map.v | 2 + techlibs/xilinx/xc7_xcu_brams.txt | 2 + techlibs/xilinx/xcu_brams_map.v | 2 + 11 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 techlibs/xilinx/xc2v_brams.txt create mode 100644 techlibs/xilinx/xc2v_brams_map.v create mode 100644 techlibs/xilinx/xc3sa_brams.txt diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index 60b4ace1c..7785bf81c 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -27,6 +27,9 @@ techlibs/xilinx/brams_init_8.vh: techlibs/xilinx/brams_init.mk $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_sim.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_xtra.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc2v_brams.txt)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc2v_brams_map.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3sa_brams.txt)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3sda_brams.txt)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams.txt)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_map.v)) diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 705591cf7..a7fa73837 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -438,7 +438,14 @@ struct SynthXilinxPass : public ScriptPass run("memory_bram -rules +/xilinx/{family}_brams.txt"); run("techmap -map +/xilinx/{family}_brams_map.v"); } else if (!nobram) { - if (family == "xc3sda") { + if (family == "xc2v" || family == "xc2vp" || family == "xc3s" || family == "xc3se") { + run("memory_bram -rules +/xilinx/xc2v_brams.txt"); + run("techmap -map +/xilinx/xc2v_brams_map.v"); + } else if (family == "xc3sa") { + // Superset of Virtex 2 primitives — uses common map file. + run("memory_bram -rules +/xilinx/xc3sa_brams.txt"); + run("techmap -map +/xilinx/xc2v_brams_map.v"); + } else if (family == "xc3sda") { // Supported block RAMs for Spartan 3A DSP are // a subset of Spartan 6's ones. run("memory_bram -rules +/xilinx/xc3sda_brams.txt"); diff --git a/techlibs/xilinx/xc2v_brams.txt b/techlibs/xilinx/xc2v_brams.txt new file mode 100644 index 000000000..ac8cfb552 --- /dev/null +++ b/techlibs/xilinx/xc2v_brams.txt @@ -0,0 +1,31 @@ +# Virtex 2, Virtex 2 Pro, Spartan 3, Spartan 3E block RAM rules. + +bram $__XILINX_RAMB16 + init 1 + abits 9 @a9d36 + dbits 36 @a9d36 + abits 10 @a10d18 + dbits 18 @a10d18 + abits 11 @a11d9 + dbits 9 @a11d9 + abits 12 @a12d4 + dbits 4 @a12d4 + abits 13 @a13d2 + dbits 2 @a13d2 + abits 14 @a14d1 + dbits 1 @a14d1 + groups 2 + ports 1 1 + wrmode 0 1 + enable 1 1 + transp 0 0 + clocks 2 3 + clkpol 2 3 +endbram + +match $__XILINX_RAMB16 + min bits 4096 + min efficiency 5 + shuffle_enable B + make_transp +endmatch diff --git a/techlibs/xilinx/xc2v_brams_map.v b/techlibs/xilinx/xc2v_brams_map.v new file mode 100644 index 000000000..dc698f956 --- /dev/null +++ b/techlibs/xilinx/xc2v_brams_map.v @@ -0,0 +1,266 @@ +// Virtex 2, Virtex 2 Pro, Spartan 3, Spartan 3E, Spartan 3A block RAM +// mapping (Spartan 3A is a superset of the other four). + +// ------------------------------------------------------------------------ + +module \$__XILINX_RAMB16 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 9; + parameter CFG_DBITS = 36; + parameter CFG_ENABLE_B = 1; + + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + parameter [18431:0] INIT = 18432'bx; + + input CLK2; + input CLK3; + + input [CFG_ABITS-1:0] A1ADDR; + output [CFG_DBITS-1:0] A1DATA; + input A1EN; + + input [CFG_ABITS-1:0] B1ADDR; + input [CFG_DBITS-1:0] B1DATA; + input [CFG_ENABLE_B-1:0] B1EN; + + generate if (CFG_DBITS == 1) begin + wire DOB; + RAMB16_S1_S1 #( + `include "brams_init_16.vh" + .WRITE_MODE_A("READ_FIRST"), + .WRITE_MODE_B("READ_FIRST"), + ) _TECHMAP_REPLACE_ ( + .DIA(1'd0), + .DOA(A1DATA), + .ADDRA(A1ADDR), + .CLKA(CLK2 ^ !CLKPOL2), + .ENA(A1EN), + .SSRA(|0), + .WEA(1'b0), + + .DIB(B1DATA), + .DOB(DOB), + .ADDRB(B1ADDR), + .CLKB(CLK3 ^ !CLKPOL3), + .ENB(|1), + .SSRB(|0), + .WEB(B1EN) + ); + end else if (CFG_DBITS == 2) begin + wire [1:0] DOB; + RAMB16_S2_S2 #( + `include "brams_init_16.vh" + .WRITE_MODE_A("READ_FIRST"), + .WRITE_MODE_B("READ_FIRST"), + ) _TECHMAP_REPLACE_ ( + .DIA(2'd0), + .DOA(A1DATA), + .ADDRA(A1ADDR), + .CLKA(CLK2 ^ !CLKPOL2), + .ENA(A1EN), + .SSRA(|0), + .WEA(1'b0), + + .DIB(B1DATA), + .DOB(DOB), + .ADDRB(B1ADDR), + .CLKB(CLK3 ^ !CLKPOL3), + .ENB(|1), + .SSRB(|0), + .WEB(B1EN) + ); + end else if (CFG_DBITS == 4) begin + wire [3:0] DOB; + RAMB16_S4_S4 #( + `include "brams_init_16.vh" + .WRITE_MODE_A("READ_FIRST"), + .WRITE_MODE_B("READ_FIRST"), + ) _TECHMAP_REPLACE_ ( + .DIA(4'd0), + .DOA(A1DATA), + .ADDRA(A1ADDR), + .CLKA(CLK2 ^ !CLKPOL2), + .ENA(A1EN), + .SSRA(|0), + .WEA(1'b0), + + .DIB(B1DATA), + .DOB(DOB), + .ADDRB(B1ADDR), + .CLKB(CLK3 ^ !CLKPOL3), + .ENB(|1), + .SSRB(|0), + .WEB(B1EN) + ); + end else if (CFG_DBITS == 9) begin + wire [7:0] DOB; + wire DOPB; + RAMB16_S9_S9 #( + `include "brams_init_18.vh" + .WRITE_MODE_A("READ_FIRST"), + .WRITE_MODE_B("READ_FIRST"), + ) _TECHMAP_REPLACE_ ( + .DIA(8'd0), + .DIPA(1'd0), + .DOA(A1DATA[7:0]), + .DOPA(A1DATA[8]), + .ADDRA(A1ADDR), + .CLKA(CLK2 ^ !CLKPOL2), + .ENA(A1EN), + .SSRA(|0), + .WEA(1'b0), + + .DIB(B1DATA[7:0]), + .DIPB(B1DATA[8]), + .DOB(DOB), + .DOPB(DOPB), + .ADDRB(B1ADDR), + .CLKB(CLK3 ^ !CLKPOL3), + .ENB(|1), + .SSRB(|0), + .WEB(B1EN) + ); + end else if (CFG_DBITS == 18) begin + wire [15:0] DOB; + wire [1:0] DOPB; + RAMB16_S18_S18 #( + `include "brams_init_18.vh" + .WRITE_MODE_A("READ_FIRST"), + .WRITE_MODE_B("READ_FIRST"), + ) _TECHMAP_REPLACE_ ( + .DIA(16'd0), + .DIPA(2'd0), + .DOA({A1DATA[16:9], A1DATA[7:0]}), + .DOPA({A1DATA[17], A1DATA[8]}), + .ADDRA(A1ADDR), + .CLKA(CLK2 ^ !CLKPOL2), + .ENA(A1EN), + .SSRA(|0), + .WEA(1'b0), + + .DIB({B1DATA[16:9], B1DATA[7:0]}), + .DIPB({B1DATA[17], B1DATA[8]}), + .DOB(DOB), + .DOPB(DOPB), + .ADDRB(B1ADDR), + .CLKB(CLK3 ^ !CLKPOL3), + .ENB(|1), + .SSRB(|0), + .WEB(B1EN) + ); + end else if (CFG_DBITS == 36) begin + wire [31:0] DOB; + wire [3:0] DOPB; + RAMB16_S36_S36 #( + `include "brams_init_18.vh" + .WRITE_MODE_A("READ_FIRST"), + .WRITE_MODE_B("READ_FIRST"), + ) _TECHMAP_REPLACE_ ( + .DIA(32'd0), + .DIPA(4'd0), + .DOA({A1DATA[34:27], A1DATA[25:18], A1DATA[16:9], A1DATA[7:0]}), + .DOPA({A1DATA[35], A1DATA[26], A1DATA[17], A1DATA[8]}), + .ADDRA(A1ADDR), + .CLKA(CLK2 ^ !CLKPOL2), + .ENA(A1EN), + .SSRA(|0), + .WEA(1'b0), + + .DIB({B1DATA[34:27], B1DATA[25:18], B1DATA[16:9], B1DATA[7:0]}), + .DIPB({B1DATA[35], B1DATA[26], B1DATA[17], B1DATA[8]}), + .DOB(DOB), + .DOPB(DOPB), + .ADDRB(B1ADDR), + .CLKB(CLK3 ^ !CLKPOL3), + .ENB(|1), + .SSRB(|0), + .WEB(B1EN) + ); + end else begin + $error("Strange block RAM data width."); + end endgenerate +endmodule + + +// Version with separate byte enables, only available on Spartan 3A. + +module \$__XILINX_RAMB16BWE (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 9; + parameter CFG_DBITS = 36; + parameter CFG_ENABLE_B = 4; + + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + parameter [18431:0] INIT = 18432'bx; + + input CLK2; + input CLK3; + + input [CFG_ABITS-1:0] A1ADDR; + output [CFG_DBITS-1:0] A1DATA; + input A1EN; + + input [CFG_ABITS-1:0] B1ADDR; + input [CFG_DBITS-1:0] B1DATA; + input [CFG_ENABLE_B-1:0] B1EN; + + generate if (CFG_DBITS == 18) begin + wire [15:0] DOB; + wire [1:0] DOPB; + RAMB16BWE_S18_S18 #( + `include "brams_init_18.vh" + .WRITE_MODE_A("READ_FIRST"), + .WRITE_MODE_B("READ_FIRST"), + ) _TECHMAP_REPLACE_ ( + .DIA(16'd0), + .DIPA(2'd0), + .DOA({A1DATA[16:9], A1DATA[7:0]}), + .DOPA({A1DATA[17], A1DATA[8]}), + .ADDRA(A1ADDR), + .CLKA(CLK2 ^ !CLKPOL2), + .ENA(A1EN), + .SSRA(|0), + .WEA(2'b00), + + .DIB({B1DATA[16:9], B1DATA[7:0]}), + .DIPB({B1DATA[17], B1DATA[8]}), + .DOB(DOB), + .DOPB(DOPB), + .ADDRB(B1ADDR), + .CLKB(CLK3 ^ !CLKPOL3), + .ENB(|1), + .SSRB(|0), + .WEB(B1EN) + ); + end else if (CFG_DBITS == 36) begin + wire [31:0] DOB; + wire [3:0] DOPB; + RAMB16BWE_S36_S36 #( + `include "brams_init_18.vh" + .WRITE_MODE_A("READ_FIRST"), + .WRITE_MODE_B("READ_FIRST"), + ) _TECHMAP_REPLACE_ ( + .DIA(32'd0), + .DIPA(4'd0), + .DOA({A1DATA[34:27], A1DATA[25:18], A1DATA[16:9], A1DATA[7:0]}), + .DOPA({A1DATA[35], A1DATA[26], A1DATA[17], A1DATA[8]}), + .ADDRA(A1ADDR), + .CLKA(CLK2 ^ !CLKPOL2), + .ENA(A1EN), + .SSRA(|0), + .WEA(4'b0000), + + .DIB({B1DATA[34:27], B1DATA[25:18], B1DATA[16:9], B1DATA[7:0]}), + .DIPB({B1DATA[35], B1DATA[26], B1DATA[17], B1DATA[8]}), + .DOB(DOB), + .DOPB(DOPB), + .ADDRB(B1ADDR), + .CLKB(CLK3 ^ !CLKPOL3), + .ENB(|1), + .SSRB(|0), + .WEB(B1EN) + ); + end else begin + $error("Strange block RAM data width."); + end endgenerate +endmodule diff --git a/techlibs/xilinx/xc3sa_brams.txt b/techlibs/xilinx/xc3sa_brams.txt new file mode 100644 index 000000000..22a62bd2c --- /dev/null +++ b/techlibs/xilinx/xc3sa_brams.txt @@ -0,0 +1,51 @@ +# Spartan 3A block RAM rules. + +bram $__XILINX_RAMB16 + init 1 + abits 11 @a11d9 + dbits 9 @a11d9 + abits 12 @a12d4 + dbits 4 @a12d4 + abits 13 @a13d2 + dbits 2 @a13d2 + abits 14 @a14d1 + dbits 1 @a14d1 + groups 2 + ports 1 1 + wrmode 0 1 + enable 1 1 + transp 0 0 + clocks 2 3 + clkpol 2 3 +endbram + +bram $__XILINX_RAMB16BWE + init 1 + abits 9 @a9d36 + dbits 36 @a9d36 + abits 10 @a10d18 + dbits 18 @a10d18 + groups 2 + ports 1 1 + wrmode 0 1 + enable 1 4 @a9d36 + enable 1 2 @a10d18 + transp 0 0 + clocks 2 3 + clkpol 2 3 +endbram + +match $__XILINX_RAMB16 + min bits 4096 + min efficiency 5 + shuffle_enable B + make_transp + or_next_if_better +endmatch + +match $__XILINX_RAMB16BWE + min bits 4096 + min efficiency 5 + shuffle_enable B + make_transp +endmatch diff --git a/techlibs/xilinx/xc3sda_brams.txt b/techlibs/xilinx/xc3sda_brams.txt index fd53a94bf..12c68ffd5 100644 --- a/techlibs/xilinx/xc3sda_brams.txt +++ b/techlibs/xilinx/xc3sda_brams.txt @@ -1,3 +1,4 @@ +# Spartan 3A DSP block RAM rules. bram $__XILINX_RAMB16BWER_TDP init 1 diff --git a/techlibs/xilinx/xc6s_brams.txt b/techlibs/xilinx/xc6s_brams.txt index 17cd8e355..6457097db 100644 --- a/techlibs/xilinx/xc6s_brams.txt +++ b/techlibs/xilinx/xc6s_brams.txt @@ -1,3 +1,4 @@ +# Spartan 6 block RAM rules. bram $__XILINX_RAMB8BWER_SDP init 1 diff --git a/techlibs/xilinx/xc6s_brams_map.v b/techlibs/xilinx/xc6s_brams_map.v index 16fd15e74..9577eebe4 100644 --- a/techlibs/xilinx/xc6s_brams_map.v +++ b/techlibs/xilinx/xc6s_brams_map.v @@ -1,3 +1,6 @@ +// Spartan 3A DSP and Spartan 6 block RAM mapping (Spartan 6 is a superset of +// Spartan 3A DSP). + module \$__XILINX_RAMB8BWER_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CLKPOL2 = 1; parameter CLKPOL3 = 1; diff --git a/techlibs/xilinx/xc7_brams_map.v b/techlibs/xilinx/xc7_brams_map.v index 7ea49158d..2b6ad0da6 100644 --- a/techlibs/xilinx/xc7_brams_map.v +++ b/techlibs/xilinx/xc7_brams_map.v @@ -1,3 +1,5 @@ +// Virtex 6 and Series 7 block RAM mapping. + module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CLKPOL2 = 1; parameter CLKPOL3 = 1; diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt index c63218ae1..650367abf 100644 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ b/techlibs/xilinx/xc7_xcu_brams.txt @@ -1,3 +1,5 @@ +# Virtex 6, Series 7, Ultrascale, Ultrascale Plus block RAM rules. + bram $__XILINX_RAMB36_SDP init 1 abits 9 diff --git a/techlibs/xilinx/xcu_brams_map.v b/techlibs/xilinx/xcu_brams_map.v index 6e7925b57..b6719b2dd 100644 --- a/techlibs/xilinx/xcu_brams_map.v +++ b/techlibs/xilinx/xcu_brams_map.v @@ -1,3 +1,5 @@ +// Ultrascale and Ultrascale Plus block RAM mapping. + module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CLKPOL2 = 1; parameter CLKPOL3 = 1; -- cgit v1.2.3