xilinx: Add block RAM mapping for Virtex 2* and Spartan 3*.
authorMarcin Kościelnicki <mwk@0x04.net>
Tue, 4 Feb 2020 14:35:47 +0000 (15:35 +0100)
committerMarcelina Kościelnicka <mwk@0x04.net>
Fri, 7 Feb 2020 00:00:29 +0000 (01:00 +0100)
techlibs/xilinx/Makefile.inc
techlibs/xilinx/synth_xilinx.cc
techlibs/xilinx/xc2v_brams.txt [new file with mode: 0644]
techlibs/xilinx/xc2v_brams_map.v [new file with mode: 0644]
techlibs/xilinx/xc3sa_brams.txt [new file with mode: 0644]
techlibs/xilinx/xc3sda_brams.txt
techlibs/xilinx/xc6s_brams.txt
techlibs/xilinx/xc6s_brams_map.v
techlibs/xilinx/xc7_brams_map.v
techlibs/xilinx/xc7_xcu_brams.txt
techlibs/xilinx/xcu_brams_map.v

index 60b4ace1c4ad237eb90e019f50f4c394b8386aa9..7785bf81cd12268722f2ef33d419a9115ea5128d 100644 (file)
@@ -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))
index 705591cf7f88f2f526729512c23aa83a38d657d4..a7fa73837bb2e4bfbb0c5ba0abac19a759eefc6f 100644 (file)
@@ -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 (file)
index 0000000..ac8cfb5
--- /dev/null
@@ -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 (file)
index 0000000..dc698f9
--- /dev/null
@@ -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 (file)
index 0000000..22a62bd
--- /dev/null
@@ -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
index fd53a94bf02c76a4245277104a9d6337c0f4ba7f..12c68ffd5f9894bc6573082afb7c04042d1ece44 100644 (file)
@@ -1,3 +1,4 @@
+# Spartan 3A DSP block RAM rules.
 
 bram $__XILINX_RAMB16BWER_TDP
   init 1
index 17cd8e3558f587b7bafbf3cd142c141a5a270fc3..6457097db41bd059a88a8ab61402ace756c500ee 100644 (file)
@@ -1,3 +1,4 @@
+# Spartan 6 block RAM rules.
 
 bram $__XILINX_RAMB8BWER_SDP
   init 1
index 16fd15e743de8ff36bddd6320917569cbb4a560e..9577eebe474589bc0359b7aa07cc15fbc6a7cb84 100644 (file)
@@ -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;
index 7ea49158d27cbf83e99877432eb77539bcc392a4..2b6ad0da60a95a3c8d1c6cce42e37df1e1841150 100644 (file)
@@ -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;
index c63218ae1b500cc7d3a129d38e2ed9e06aa768d8..650367abfd1ec0d55cec86afab5c4bcde4403a18 100644 (file)
@@ -1,3 +1,5 @@
+# Virtex 6, Series 7, Ultrascale, Ultrascale Plus block RAM rules.
+
 bram $__XILINX_RAMB36_SDP
   init 1
   abits 9
index 6e7925b57bf245e6966c803e082cf2bcd5b9203c..b6719b2ddeb7edda8307355c887db751d5a65b30 100644 (file)
@@ -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;