aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs')
-rw-r--r--techlibs/anlogic/Makefile.inc3
-rw-r--r--techlibs/anlogic/brams.txt69
-rw-r--r--techlibs/anlogic/brams_map.v474
-rw-r--r--techlibs/anlogic/lutram_init_16x4.vh16
-rw-r--r--techlibs/anlogic/lutrams.txt28
-rw-r--r--techlibs/anlogic/lutrams_map.v40
-rw-r--r--techlibs/anlogic/synth_anlogic.cc24
-rw-r--r--techlibs/common/simlib.v72
-rw-r--r--techlibs/common/synth.cc9
-rw-r--r--techlibs/common/techmap.v39
-rw-r--r--techlibs/ecp5/.gitignore10
-rw-r--r--techlibs/ecp5/Makefile.inc43
-rw-r--r--techlibs/ecp5/brams.txt166
-rwxr-xr-xtechlibs/ecp5/brams_connect.py66
-rwxr-xr-xtechlibs/ecp5/brams_init.py22
-rw-r--r--techlibs/ecp5/brams_map.v636
-rw-r--r--techlibs/ecp5/cells_bb.v2
-rw-r--r--techlibs/ecp5/cells_sim.v46
-rw-r--r--techlibs/ecp5/lutrams.txt38
-rw-r--r--techlibs/ecp5/lutrams_map.v46
-rw-r--r--techlibs/ecp5/synth_ecp5.cc43
-rw-r--r--techlibs/efinix/brams.txt51
-rw-r--r--techlibs/efinix/brams_map.v194
-rw-r--r--techlibs/efinix/synth_efinix.cc8
-rw-r--r--techlibs/gatemate/.gitignore4
-rw-r--r--techlibs/gatemate/Makefile.inc16
-rw-r--r--techlibs/gatemate/brams.txt360
-rw-r--r--techlibs/gatemate/brams_map.v1352
-rw-r--r--techlibs/gatemate/cells_sim.v44
-rw-r--r--techlibs/gatemate/gatemate_foldinv.cc219
-rw-r--r--techlibs/gatemate/inv_map.v4
-rw-r--r--techlibs/gatemate/make_lut_tree_lib.py323
-rw-r--r--techlibs/gatemate/synth_gatemate.cc39
-rw-r--r--techlibs/gowin/.gitignore2
-rw-r--r--techlibs/gowin/Makefile.inc15
-rw-r--r--techlibs/gowin/brams.txt110
-rwxr-xr-xtechlibs/gowin/brams_init.py8
-rw-r--r--techlibs/gowin/brams_init3.vh12
-rw-r--r--techlibs/gowin/brams_map.v550
-rw-r--r--techlibs/gowin/cells_sim.v945
-rw-r--r--techlibs/gowin/lutrams.txt30
-rw-r--r--techlibs/gowin/lutrams_map.v94
-rw-r--r--techlibs/gowin/synth_gowin.cc41
-rw-r--r--techlibs/ice40/.gitignore4
-rw-r--r--techlibs/ice40/Makefile.inc23
-rw-r--r--techlibs/ice40/brams.txt123
-rw-r--r--techlibs/ice40/brams_init.py14
-rw-r--r--techlibs/ice40/brams_map.v524
-rw-r--r--techlibs/ice40/spram.txt12
-rw-r--r--techlibs/ice40/spram_map.v24
-rw-r--r--techlibs/ice40/synth_ice40.cc47
-rw-r--r--techlibs/intel_alm/Makefile.inc1
-rw-r--r--techlibs/intel_alm/common/bram_m10k.txt16
-rw-r--r--techlibs/intel_alm/common/bram_m10k_map.v16
-rw-r--r--techlibs/intel_alm/common/mem_sim.v2
-rw-r--r--techlibs/intel_alm/common/quartus_rename.v9
-rw-r--r--techlibs/intel_alm/synth_intel_alm.cc3
-rw-r--r--techlibs/machxo2/Makefile.inc5
-rw-r--r--techlibs/machxo2/brams.txt50
-rw-r--r--techlibs/machxo2/brams_map.v337
-rw-r--r--techlibs/machxo2/cells_sim.v121
-rw-r--r--techlibs/machxo2/lutrams.txt12
-rw-r--r--techlibs/machxo2/lutrams_map.v23
-rw-r--r--techlibs/machxo2/synth_machxo2.cc31
-rw-r--r--techlibs/nexus/Makefile.inc2
-rw-r--r--techlibs/nexus/arith_map.v2
-rw-r--r--techlibs/nexus/brams.txt108
-rw-r--r--techlibs/nexus/brams_init.vh64
-rw-r--r--techlibs/nexus/brams_map.v493
-rw-r--r--techlibs/nexus/cells_sim.v4
-rw-r--r--techlibs/nexus/lrams.txt43
-rw-r--r--techlibs/nexus/lrams_init.vh128
-rw-r--r--techlibs/nexus/lrams_map.v246
-rw-r--r--techlibs/nexus/lutrams.txt38
-rw-r--r--techlibs/nexus/lutrams_map.v39
-rw-r--r--techlibs/nexus/synth_nexus.cc33
-rw-r--r--techlibs/quicklogic/synth_quicklogic.cc4
-rw-r--r--techlibs/xilinx/.gitignore2
-rw-r--r--techlibs/xilinx/Makefile.inc70
-rw-r--r--techlibs/xilinx/brams_defs.vh561
-rw-r--r--techlibs/xilinx/brams_init.py50
-rw-r--r--techlibs/xilinx/brams_xc2v.txt33
-rw-r--r--techlibs/xilinx/brams_xc2v_map.v532
-rw-r--r--techlibs/xilinx/brams_xc3sda.txt120
-rw-r--r--techlibs/xilinx/brams_xc3sda_map.v224
-rw-r--r--techlibs/xilinx/brams_xc4v.txt169
-rw-r--r--techlibs/xilinx/brams_xc4v_map.v149
-rw-r--r--techlibs/xilinx/brams_xc5v_map.v255
-rw-r--r--techlibs/xilinx/brams_xc6v_map.v284
-rw-r--r--techlibs/xilinx/brams_xcu_map.v225
-rw-r--r--techlibs/xilinx/brams_xcv.txt17
-rw-r--r--techlibs/xilinx/brams_xcv_map.v257
-rw-r--r--techlibs/xilinx/cells_xtra.py21
-rw-r--r--techlibs/xilinx/cells_xtra.v675
-rw-r--r--techlibs/xilinx/lut4_lutrams.txt19
-rw-r--r--techlibs/xilinx/lut6_lutrams.txt143
-rw-r--r--techlibs/xilinx/lutrams_map.v279
-rw-r--r--techlibs/xilinx/lutrams_xc5v.txt100
-rw-r--r--techlibs/xilinx/lutrams_xc5v_map.v901
-rw-r--r--techlibs/xilinx/lutrams_xcu.txt162
-rw-r--r--techlibs/xilinx/lutrams_xcv.txt59
-rw-r--r--techlibs/xilinx/lutrams_xcv_map.v177
-rw-r--r--techlibs/xilinx/synth_xilinx.cc127
-rw-r--r--techlibs/xilinx/urams.txt37
-rw-r--r--techlibs/xilinx/urams_map.v152
-rw-r--r--techlibs/xilinx/xc2v_brams.txt31
-rw-r--r--techlibs/xilinx/xc2v_brams_map.v266
-rw-r--r--techlibs/xilinx/xc3sa_brams.txt51
-rw-r--r--techlibs/xilinx/xc3sda_brams.txt33
-rw-r--r--techlibs/xilinx/xc6s_brams.txt85
-rw-r--r--techlibs/xilinx/xc6s_brams_map.v258
-rw-r--r--techlibs/xilinx/xc7_brams_map.v363
-rw-r--r--techlibs/xilinx/xc7_xcu_brams.txt151
-rw-r--r--techlibs/xilinx/xcu_brams_map.v386
-rw-r--r--techlibs/xilinx/xcup_urams.txt19
-rw-r--r--techlibs/xilinx/xcup_urams_map.v47
116 files changed, 11302 insertions, 5102 deletions
diff --git a/techlibs/anlogic/Makefile.inc b/techlibs/anlogic/Makefile.inc
index 2d8d65e2e..669e8bea5 100644
--- a/techlibs/anlogic/Makefile.inc
+++ b/techlibs/anlogic/Makefile.inc
@@ -9,4 +9,5 @@ $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_sim.v))
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/eagle_bb.v))
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams.txt))
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams_map.v))
-$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutram_init_16x4.vh))
+$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/brams.txt))
+$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/brams_map.v))
diff --git a/techlibs/anlogic/brams.txt b/techlibs/anlogic/brams.txt
new file mode 100644
index 000000000..910cdebe1
--- /dev/null
+++ b/techlibs/anlogic/brams.txt
@@ -0,0 +1,69 @@
+ram block $__ANLOGIC_BRAM_TDP_ {
+ abits 13;
+ widths 1 2 4 9 per_port;
+ cost 64;
+ init no_undef;
+ port srsw "A" "B" {
+ clock anyedge;
+ clken;
+ portoption "WRITEMODE" "NORMAL" {
+ rdwr no_change;
+ }
+ portoption "WRITEMODE" "WRITETHROUGH" {
+ rdwr new;
+ }
+ portoption "WRITEMODE" "READBEFOREWRITE" {
+ rdwr old;
+ }
+ option "RESETMODE" "SYNC" {
+ rdsrst zero ungated block_wr;
+ }
+ option "RESETMODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ }
+}
+
+ram block $__ANLOGIC_BRAM_SDP_ {
+ abits 13;
+ widths 1 2 4 9 18 per_port;
+ byte 9;
+ cost 64;
+ init no_undef;
+ port sr "R" {
+ clock anyedge;
+ clken;
+ option "RESETMODE" "SYNC" {
+ rdsrst zero ungated;
+ }
+ option "RESETMODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ }
+ port sw "W" {
+ clock anyedge;
+ clken;
+ }
+}
+
+ram block $__ANLOGIC_BRAM32K_ {
+ abits 12;
+ widths 8 16 per_port;
+ byte 8;
+ cost 192;
+ init no_undef;
+ port srsw "A" "B" {
+ clock anyedge;
+ clken;
+ portoption "WRITEMODE" "NORMAL" {
+ rdwr no_change;
+ }
+ portoption "WRITEMODE" "WRITETHROUGH" {
+ rdwr new;
+ }
+ # no reset - it doesn't really work without the pipeline
+ # output registers
+ }
+}
diff --git a/techlibs/anlogic/brams_map.v b/techlibs/anlogic/brams_map.v
new file mode 100644
index 000000000..7e2642d65
--- /dev/null
+++ b/techlibs/anlogic/brams_map.v
@@ -0,0 +1,474 @@
+module $__ANLOGIC_BRAM_TDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_RESETMODE = "SYNC";
+
+parameter PORT_A_WIDTH = 9;
+parameter PORT_A_CLK_POL = 1;
+parameter PORT_A_OPTION_WRITEMODE = "NORMAL";
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input PORT_A_WR_EN;
+input PORT_A_RD_SRST;
+input PORT_A_RD_ARST;
+input [12:0] PORT_A_ADDR;
+input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
+output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
+
+parameter PORT_B_WIDTH = 9;
+parameter PORT_B_CLK_POL = 1;
+parameter PORT_B_OPTION_WRITEMODE = "NORMAL";
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input PORT_B_WR_EN;
+input PORT_B_RD_SRST;
+input PORT_B_RD_ARST;
+input [12:0] PORT_B_ADDR;
+input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
+output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
+
+function [255:0] init_slice;
+ input integer idx;
+ integer i;
+ for (i = 0; i < 32; i = i + 1) begin
+ init_slice[i*8+:8] = INIT[(idx * 32 + i) * 9 +: 8];
+ end
+endfunction
+
+function [255:0] initp_slice;
+ input integer idx;
+ integer i;
+ for (i = 0; i < 256; i = i + 1) begin
+ initp_slice[i] = INIT[(idx * 256 + i) * 9 + 8];
+ end
+endfunction
+
+wire [8:0] DOA;
+wire [8:0] DOB;
+// the replication is important — the BRAM behaves in... unexpected ways for
+// width 1 and 2
+wire [8:0] DIA = {9{PORT_A_WR_DATA}};
+wire [8:0] DIB = {9{PORT_B_WR_DATA}};
+
+assign PORT_A_RD_DATA = DOA;
+assign PORT_B_RD_DATA = DOB;
+
+EG_PHY_BRAM #(
+ .INIT_00(init_slice('h00)),
+ .INIT_01(init_slice('h01)),
+ .INIT_02(init_slice('h02)),
+ .INIT_03(init_slice('h03)),
+ .INIT_04(init_slice('h04)),
+ .INIT_05(init_slice('h05)),
+ .INIT_06(init_slice('h06)),
+ .INIT_07(init_slice('h07)),
+ .INIT_08(init_slice('h08)),
+ .INIT_09(init_slice('h09)),
+ .INIT_0A(init_slice('h0a)),
+ .INIT_0B(init_slice('h0b)),
+ .INIT_0C(init_slice('h0c)),
+ .INIT_0D(init_slice('h0d)),
+ .INIT_0E(init_slice('h0e)),
+ .INIT_0F(init_slice('h0f)),
+ .INIT_10(init_slice('h10)),
+ .INIT_11(init_slice('h11)),
+ .INIT_12(init_slice('h12)),
+ .INIT_13(init_slice('h13)),
+ .INIT_14(init_slice('h14)),
+ .INIT_15(init_slice('h15)),
+ .INIT_16(init_slice('h16)),
+ .INIT_17(init_slice('h17)),
+ .INIT_18(init_slice('h18)),
+ .INIT_19(init_slice('h19)),
+ .INIT_1A(init_slice('h1a)),
+ .INIT_1B(init_slice('h1b)),
+ .INIT_1C(init_slice('h1c)),
+ .INIT_1D(init_slice('h1d)),
+ .INIT_1E(init_slice('h1e)),
+ .INIT_1F(init_slice('h1f)),
+ .INITP_00(initp_slice('h00)),
+ .INITP_01(initp_slice('h01)),
+ .INITP_02(initp_slice('h02)),
+ .INITP_03(initp_slice('h03)),
+ .MODE("DP8K"),
+ .DATA_WIDTH_A($sformatf("%d", PORT_A_WIDTH)),
+ .DATA_WIDTH_B($sformatf("%d", PORT_B_WIDTH)),
+ .REGMODE_A("NOREG"),
+ .REGMODE_B("NOREG"),
+ .RESETMODE(OPTION_RESETMODE),
+ .ASYNC_RESET_RELEASE(OPTION_RESETMODE),
+ .CLKAMUX(PORT_A_CLK_POL ? "SIG" : "INV"),
+ .CLKBMUX(PORT_B_CLK_POL ? "SIG" : "INV"),
+ .WRITEMODE_A(PORT_A_OPTION_WRITEMODE),
+ .WRITEMODE_B(PORT_B_OPTION_WRITEMODE),
+) _TECHMAP_REPLACE_ (
+ .clka(PORT_A_CLK),
+ .wea(PORT_A_WR_EN),
+ .cea(PORT_A_CLK_EN),
+ .ocea(1'b1),
+ .rsta(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST),
+ .csa(3'b111),
+ .addra(PORT_A_WIDTH == 9 ? {PORT_A_ADDR[12:1], 1'b1} : PORT_A_ADDR),
+ .dia(DIA),
+ .doa(DOA),
+
+ .clkb(PORT_B_CLK),
+ .web(PORT_B_WR_EN),
+ .ceb(PORT_B_CLK_EN),
+ .oceb(1'b1),
+ .rstb(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST),
+ .csb(3'b111),
+ .addrb(PORT_B_WIDTH == 9 ? {PORT_B_ADDR[12:1], 1'b1} : PORT_B_ADDR),
+ .dib(DIB),
+ .dob(DOB),
+);
+
+endmodule
+
+
+module $__ANLOGIC_BRAM_SDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_RESETMODE = "SYNC";
+
+parameter PORT_R_WIDTH = 18;
+parameter PORT_R_CLK_POL = 1;
+
+input PORT_R_CLK;
+input PORT_R_CLK_EN;
+input PORT_R_RD_SRST;
+input PORT_R_RD_ARST;
+input [12:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+
+parameter PORT_W_WIDTH = 18;
+parameter PORT_W_WR_EN_WIDTH = 2;
+parameter PORT_W_CLK_POL = 1;
+
+input PORT_W_CLK;
+input PORT_W_CLK_EN;
+input [12:0] PORT_W_ADDR;
+input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+
+function [255:0] init_slice;
+ input integer idx;
+ integer i;
+ for (i = 0; i < 32; i = i + 1) begin
+ init_slice[i*8+:8] = INIT[(idx * 32 + i) * 9 +: 8];
+ end
+endfunction
+
+function [255:0] initp_slice;
+ input integer idx;
+ integer i;
+ for (i = 0; i < 256; i = i + 1) begin
+ initp_slice[i] = INIT[(idx * 256 + i) * 9 + 8];
+ end
+endfunction
+
+wire [17:0] DI = {18{PORT_W_WR_DATA}};
+wire [17:0] DO;
+
+assign PORT_R_RD_DATA = PORT_R_WIDTH == 18 ? DO : DO[17:9];
+
+EG_PHY_BRAM #(
+ .INIT_00(init_slice('h00)),
+ .INIT_01(init_slice('h01)),
+ .INIT_02(init_slice('h02)),
+ .INIT_03(init_slice('h03)),
+ .INIT_04(init_slice('h04)),
+ .INIT_05(init_slice('h05)),
+ .INIT_06(init_slice('h06)),
+ .INIT_07(init_slice('h07)),
+ .INIT_08(init_slice('h08)),
+ .INIT_09(init_slice('h09)),
+ .INIT_0A(init_slice('h0a)),
+ .INIT_0B(init_slice('h0b)),
+ .INIT_0C(init_slice('h0c)),
+ .INIT_0D(init_slice('h0d)),
+ .INIT_0E(init_slice('h0e)),
+ .INIT_0F(init_slice('h0f)),
+ .INIT_10(init_slice('h10)),
+ .INIT_11(init_slice('h11)),
+ .INIT_12(init_slice('h12)),
+ .INIT_13(init_slice('h13)),
+ .INIT_14(init_slice('h14)),
+ .INIT_15(init_slice('h15)),
+ .INIT_16(init_slice('h16)),
+ .INIT_17(init_slice('h17)),
+ .INIT_18(init_slice('h18)),
+ .INIT_19(init_slice('h19)),
+ .INIT_1A(init_slice('h1a)),
+ .INIT_1B(init_slice('h1b)),
+ .INIT_1C(init_slice('h1c)),
+ .INIT_1D(init_slice('h1d)),
+ .INIT_1E(init_slice('h1e)),
+ .INIT_1F(init_slice('h1f)),
+ .INITP_00(initp_slice('h00)),
+ .INITP_01(initp_slice('h01)),
+ .INITP_02(initp_slice('h02)),
+ .INITP_03(initp_slice('h03)),
+ .MODE("PDPW8K"),
+ .DATA_WIDTH_A($sformatf("%d", PORT_W_WIDTH)),
+ .DATA_WIDTH_B($sformatf("%d", PORT_R_WIDTH)),
+ .REGMODE_A("NOREG"),
+ .REGMODE_B("NOREG"),
+ .RESETMODE(OPTION_RESETMODE),
+ .ASYNC_RESET_RELEASE(OPTION_RESETMODE),
+ .CLKAMUX(PORT_W_CLK_POL ? "SIG" : "INV"),
+ .CLKBMUX(PORT_R_CLK_POL ? "SIG" : "INV"),
+) _TECHMAP_REPLACE_ (
+ .clka(PORT_W_CLK),
+ .wea(PORT_W_WIDTH >= 9 ? 1'b1 : PORT_W_WR_EN[0]),
+ .cea(PORT_W_CLK_EN),
+ .ocea(1'b1),
+ .rsta(1'b0),
+ .csa(3'b111),
+ .addra(PORT_W_WIDTH == 18 ? {PORT_W_ADDR[12:2], PORT_W_WR_EN[1:0]} : (PORT_W_WIDTH == 9 ? {PORT_W_ADDR[12:1], PORT_W_WR_EN[0]} : PORT_W_ADDR)),
+ .dia(DI[8:0]),
+ .doa(DO[8:0]),
+
+ .clkb(PORT_R_CLK),
+ .web(1'b0),
+ .ceb(PORT_R_CLK_EN),
+ .oceb(1'b1),
+ .rstb(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST),
+ .csb(3'b111),
+ .addrb(PORT_R_ADDR),
+ .dib(DI[17:9]),
+ .dob(DO[17:9]),
+);
+
+endmodule
+
+
+module $__ANLOGIC_BRAM32K_ (...);
+
+parameter INIT = 0;
+
+parameter PORT_A_WIDTH = 16;
+parameter PORT_A_WR_EN_WIDTH = 2;
+parameter PORT_A_CLK_POL = 1;
+parameter PORT_A_OPTION_WRITEMODE = "NORMAL";
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
+input [11:0] PORT_A_ADDR;
+input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
+output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
+
+parameter PORT_B_WIDTH = 16;
+parameter PORT_B_WR_EN_WIDTH = 2;
+parameter PORT_B_CLK_POL = 1;
+parameter PORT_B_OPTION_WRITEMODE = "NORMAL";
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN;
+input [11:0] PORT_B_ADDR;
+input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
+output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
+
+function [255:0] init_slice;
+ input integer idx;
+ init_slice = INIT[256 * idx +: 256];
+endfunction
+
+wire [15:0] DOA;
+wire [15:0] DOB;
+wire [15:0] DIA = PORT_A_WR_DATA;
+wire [15:0] DIB = PORT_B_WR_DATA;
+
+assign PORT_A_RD_DATA = DOA;
+assign PORT_B_RD_DATA = DOB;
+
+wire BYTE_A, BYTEWE_A;
+wire BYTE_B, BYTEWE_B;
+
+generate
+
+if (PORT_A_WIDTH == 8) begin
+ assign BYTE_A = PORT_A_ADDR[0];
+ assign BYTEWE_A = 1;
+end else begin
+ assign BYTE_A = PORT_A_WR_EN == 2;
+ assign BYTEWE_A = ^PORT_A_WR_EN;
+end
+
+if (PORT_B_WIDTH == 8) begin
+ assign BYTE_B = PORT_B_ADDR[0];
+ assign BYTEWE_B = 1;
+end else begin
+ assign BYTE_B = PORT_B_WR_EN == 2;
+ assign BYTEWE_B = ^PORT_B_WR_EN;
+end
+
+endgenerate
+
+EG_PHY_BRAM32K #(
+ .INIT_00(init_slice('h00)),
+ .INIT_01(init_slice('h01)),
+ .INIT_02(init_slice('h02)),
+ .INIT_03(init_slice('h03)),
+ .INIT_04(init_slice('h04)),
+ .INIT_05(init_slice('h05)),
+ .INIT_06(init_slice('h06)),
+ .INIT_07(init_slice('h07)),
+ .INIT_08(init_slice('h08)),
+ .INIT_09(init_slice('h09)),
+ .INIT_0A(init_slice('h0a)),
+ .INIT_0B(init_slice('h0b)),
+ .INIT_0C(init_slice('h0c)),
+ .INIT_0D(init_slice('h0d)),
+ .INIT_0E(init_slice('h0e)),
+ .INIT_0F(init_slice('h0f)),
+ .INIT_10(init_slice('h10)),
+ .INIT_11(init_slice('h11)),
+ .INIT_12(init_slice('h12)),
+ .INIT_13(init_slice('h13)),
+ .INIT_14(init_slice('h14)),
+ .INIT_15(init_slice('h15)),
+ .INIT_16(init_slice('h16)),
+ .INIT_17(init_slice('h17)),
+ .INIT_18(init_slice('h18)),
+ .INIT_19(init_slice('h19)),
+ .INIT_1A(init_slice('h1a)),
+ .INIT_1B(init_slice('h1b)),
+ .INIT_1C(init_slice('h1c)),
+ .INIT_1D(init_slice('h1d)),
+ .INIT_1E(init_slice('h1e)),
+ .INIT_1F(init_slice('h1f)),
+ .INIT_20(init_slice('h20)),
+ .INIT_21(init_slice('h21)),
+ .INIT_22(init_slice('h22)),
+ .INIT_23(init_slice('h23)),
+ .INIT_24(init_slice('h24)),
+ .INIT_25(init_slice('h25)),
+ .INIT_26(init_slice('h26)),
+ .INIT_27(init_slice('h27)),
+ .INIT_28(init_slice('h28)),
+ .INIT_29(init_slice('h29)),
+ .INIT_2A(init_slice('h2a)),
+ .INIT_2B(init_slice('h2b)),
+ .INIT_2C(init_slice('h2c)),
+ .INIT_2D(init_slice('h2d)),
+ .INIT_2E(init_slice('h2e)),
+ .INIT_2F(init_slice('h2f)),
+ .INIT_30(init_slice('h30)),
+ .INIT_31(init_slice('h31)),
+ .INIT_32(init_slice('h32)),
+ .INIT_33(init_slice('h33)),
+ .INIT_34(init_slice('h34)),
+ .INIT_35(init_slice('h35)),
+ .INIT_36(init_slice('h36)),
+ .INIT_37(init_slice('h37)),
+ .INIT_38(init_slice('h38)),
+ .INIT_39(init_slice('h39)),
+ .INIT_3A(init_slice('h3a)),
+ .INIT_3B(init_slice('h3b)),
+ .INIT_3C(init_slice('h3c)),
+ .INIT_3D(init_slice('h3d)),
+ .INIT_3E(init_slice('h3e)),
+ .INIT_3F(init_slice('h3f)),
+ .INIT_40(init_slice('h40)),
+ .INIT_41(init_slice('h41)),
+ .INIT_42(init_slice('h42)),
+ .INIT_43(init_slice('h43)),
+ .INIT_44(init_slice('h44)),
+ .INIT_45(init_slice('h45)),
+ .INIT_46(init_slice('h46)),
+ .INIT_47(init_slice('h47)),
+ .INIT_48(init_slice('h48)),
+ .INIT_49(init_slice('h49)),
+ .INIT_4A(init_slice('h4a)),
+ .INIT_4B(init_slice('h4b)),
+ .INIT_4C(init_slice('h4c)),
+ .INIT_4D(init_slice('h4d)),
+ .INIT_4E(init_slice('h4e)),
+ .INIT_4F(init_slice('h4f)),
+ .INIT_50(init_slice('h50)),
+ .INIT_51(init_slice('h51)),
+ .INIT_52(init_slice('h52)),
+ .INIT_53(init_slice('h53)),
+ .INIT_54(init_slice('h54)),
+ .INIT_55(init_slice('h55)),
+ .INIT_56(init_slice('h56)),
+ .INIT_57(init_slice('h57)),
+ .INIT_58(init_slice('h58)),
+ .INIT_59(init_slice('h59)),
+ .INIT_5A(init_slice('h5a)),
+ .INIT_5B(init_slice('h5b)),
+ .INIT_5C(init_slice('h5c)),
+ .INIT_5D(init_slice('h5d)),
+ .INIT_5E(init_slice('h5e)),
+ .INIT_5F(init_slice('h5f)),
+ .INIT_60(init_slice('h60)),
+ .INIT_61(init_slice('h61)),
+ .INIT_62(init_slice('h62)),
+ .INIT_63(init_slice('h63)),
+ .INIT_64(init_slice('h64)),
+ .INIT_65(init_slice('h65)),
+ .INIT_66(init_slice('h66)),
+ .INIT_67(init_slice('h67)),
+ .INIT_68(init_slice('h68)),
+ .INIT_69(init_slice('h69)),
+ .INIT_6A(init_slice('h6a)),
+ .INIT_6B(init_slice('h6b)),
+ .INIT_6C(init_slice('h6c)),
+ .INIT_6D(init_slice('h6d)),
+ .INIT_6E(init_slice('h6e)),
+ .INIT_6F(init_slice('h6f)),
+ .INIT_70(init_slice('h70)),
+ .INIT_71(init_slice('h71)),
+ .INIT_72(init_slice('h72)),
+ .INIT_73(init_slice('h73)),
+ .INIT_74(init_slice('h74)),
+ .INIT_75(init_slice('h75)),
+ .INIT_76(init_slice('h76)),
+ .INIT_77(init_slice('h77)),
+ .INIT_78(init_slice('h78)),
+ .INIT_79(init_slice('h79)),
+ .INIT_7A(init_slice('h7a)),
+ .INIT_7B(init_slice('h7b)),
+ .INIT_7C(init_slice('h7c)),
+ .INIT_7D(init_slice('h7d)),
+ .INIT_7E(init_slice('h7e)),
+ .INIT_7F(init_slice('h7f)),
+ .MODE("DP16K"),
+ .DATA_WIDTH_A($sformatf("%d", PORT_A_WIDTH)),
+ .DATA_WIDTH_B($sformatf("%d", PORT_B_WIDTH)),
+ .REGMODE_A("NOREG"),
+ .REGMODE_B("NOREG"),
+ .WRITEMODE_A(PORT_A_OPTION_WRITEMODE),
+ .WRITEMODE_B(PORT_B_OPTION_WRITEMODE),
+ .CLKAMUX(PORT_A_CLK_POL ? "SIG" : "INV"),
+ .CLKBMUX(PORT_B_CLK_POL ? "SIG" : "INV"),
+) _TECHMAP_REPLACE_ (
+ .clka(PORT_A_CLK),
+ .csa(PORT_A_CLK_EN),
+ .wea(|PORT_A_WR_EN),
+ .ocea(1'b1),
+ .rsta(1'b0),
+ .addra(PORT_A_ADDR[11:1]),
+ .bytea(BYTE_A),
+ .bytewea(BYTEWE_A),
+ .dia(DIA),
+ .doa(DOA),
+
+ .clkb(PORT_B_CLK),
+ .csb(PORT_B_CLK_EN),
+ .web(|PORT_B_WR_EN),
+ .ocea(1'b1),
+ .rsta(1'b0),
+ .addrb(PORT_B_ADDR[11:1]),
+ .byteb(BYTE_B),
+ .byteweb(BYTEWE_B),
+ .dib(DIB),
+ .dob(DOB),
+);
+
+endmodule
diff --git a/techlibs/anlogic/lutram_init_16x4.vh b/techlibs/anlogic/lutram_init_16x4.vh
deleted file mode 100644
index 32fb1578c..000000000
--- a/techlibs/anlogic/lutram_init_16x4.vh
+++ /dev/null
@@ -1,16 +0,0 @@
-.INIT_D0({INIT[15*4+0], INIT[14*4+0], INIT[13*4+0], INIT[12*4+0],
- INIT[11*4+0], INIT[10*4+0], INIT[9*4+0], INIT[8*4+0],
- INIT[7*4+0], INIT[6*4+0], INIT[5*4+0], INIT[4*4+0],
- INIT[3*4+0], INIT[2*4+0], INIT[1*4+0], INIT[0*4+0]}),
-.INIT_D1({INIT[15*4+1], INIT[14*4+1], INIT[13*4+1], INIT[12*4+1],
- INIT[11*4+1], INIT[10*4+1], INIT[9*4+1], INIT[8*4+1],
- INIT[7*4+1], INIT[6*4+1], INIT[5*4+1], INIT[4*4+1],
- INIT[3*4+1], INIT[2*4+1], INIT[1*4+1], INIT[0*4+1]}),
-.INIT_D2({INIT[15*4+2], INIT[14*4+2], INIT[13*4+2], INIT[12*4+2],
- INIT[11*4+2], INIT[10*4+2], INIT[9*4+2], INIT[8*4+2],
- INIT[7*4+2], INIT[6*4+2], INIT[5*4+2], INIT[4*4+2],
- INIT[3*4+2], INIT[2*4+2], INIT[1*4+2], INIT[0*4+2]}),
-.INIT_D3({INIT[15*4+3], INIT[14*4+3], INIT[13*4+3], INIT[12*4+3],
- INIT[11*4+3], INIT[10*4+3], INIT[9*4+3], INIT[8*4+3],
- INIT[7*4+3], INIT[6*4+3], INIT[5*4+3], INIT[4*4+3],
- INIT[3*4+3], INIT[2*4+3], INIT[1*4+3], INIT[0*4+3]})
diff --git a/techlibs/anlogic/lutrams.txt b/techlibs/anlogic/lutrams.txt
index 4e903c0a2..ef6fec24e 100644
--- a/techlibs/anlogic/lutrams.txt
+++ b/techlibs/anlogic/lutrams.txt
@@ -1,16 +1,12 @@
-bram $__ANLOGIC_DRAM16X4
- init 1
- abits 4
- dbits 4
- groups 2
- ports 1 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 1
-endbram
-
-match $__ANLOGIC_DRAM16X4
- make_outreg
-endmatch
+ram distributed $__ANLOGIC_DRAM16X4_ {
+ abits 4;
+ width 4;
+ cost 4;
+ init no_undef;
+ prune_rom;
+ port sw "W" {
+ clock posedge;
+ }
+ port ar "R" {
+ }
+}
diff --git a/techlibs/anlogic/lutrams_map.v b/techlibs/anlogic/lutrams_map.v
index 5a464cafc..6314da22a 100644
--- a/techlibs/anlogic/lutrams_map.v
+++ b/techlibs/anlogic/lutrams_map.v
@@ -1,22 +1,32 @@
-module \$__ANLOGIC_DRAM16X4 (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
- parameter [63:0]INIT = 64'bx;
- input CLK1;
+module $__ANLOGIC_DRAM16X4_ (...);
+ parameter INIT = 64'b0;
- input [3:0] A1ADDR;
- output [3:0] A1DATA;
+ input PORT_W_CLK;
+ input [3:0] PORT_W_ADDR;
+ input [3:0] PORT_W_WR_DATA;
+ input PORT_W_WR_EN;
- input [3:0] B1ADDR;
- input [3:0] B1DATA;
- input B1EN;
+ input [3:0] PORT_R_ADDR;
+ output [3:0] PORT_R_RD_DATA;
+
+ function [15:0] init_slice;
+ input integer idx;
+ integer i;
+ for (i = 0; i < 16; i = i + 1)
+ init_slice[i] = INIT[i * 4 + idx];
+ endfunction
EG_LOGIC_DRAM16X4 #(
- `include "lutram_init_16x4.vh"
+ .INIT_D0(init_slice(0)),
+ .INIT_D1(init_slice(1)),
+ .INIT_D2(init_slice(2)),
+ .INIT_D3(init_slice(3))
) _TECHMAP_REPLACE_ (
- .di(B1DATA),
- .waddr(B1ADDR),
- .wclk(CLK1),
- .we(B1EN),
- .raddr(A1ADDR),
- .do(A1DATA)
+ .di(PORT_W_WR_DATA),
+ .waddr(PORT_W_ADDR),
+ .wclk(PORT_W_CLK),
+ .we(PORT_W_WR_EN),
+ .raddr(PORT_R_ADDR),
+ .do(PORT_R_RD_DATA)
);
endmodule
diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc
index 039cae00e..a3c1e0434 100644
--- a/techlibs/anlogic/synth_anlogic.cc
+++ b/techlibs/anlogic/synth_anlogic.cc
@@ -63,6 +63,9 @@ struct SynthAnlogicPass : public ScriptPass
log(" -nolutram\n");
log(" do not use EG_LOGIC_DRAM16X4 cells in output netlist\n");
log("\n");
+ log(" -nobram\n");
+ log(" do not use EG_PHY_BRAM or EG_PHY_BRAM32K cells in output netlist\n");
+ log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
@@ -70,7 +73,7 @@ struct SynthAnlogicPass : public ScriptPass
}
string top_opt, edif_file, json_file;
- bool flatten, retime, nolutram;
+ bool flatten, retime, nolutram, nobram;
void clear_flags() override
{
@@ -80,6 +83,7 @@ struct SynthAnlogicPass : public ScriptPass
flatten = true;
retime = false;
nolutram = false;
+ nobram = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
@@ -118,6 +122,10 @@ struct SynthAnlogicPass : public ScriptPass
nolutram = true;
continue;
}
+ if (args[argidx] == "-nobram") {
+ nobram = true;
+ continue;
+ }
if (args[argidx] == "-retime") {
retime = true;
continue;
@@ -158,11 +166,17 @@ struct SynthAnlogicPass : public ScriptPass
run("synth -run coarse");
}
- if (!nolutram && check_label("map_lutram", "(skip if -nolutram)"))
+ if (check_label("map_ram"))
{
- run("memory_bram -rules +/anlogic/lutrams.txt");
- run("techmap -map +/anlogic/lutrams_map.v");
- run("setundef -zero -params t:EG_LOGIC_DRAM16X4");
+ std::string args = "";
+ if (nobram)
+ args += " -no-auto-block";
+ if (nolutram)
+ args += " -no-auto-distributed";
+ if (help_mode)
+ args += " [-no-auto-block] [-no-auto-distributed]";
+ run("memory_libmap -lib +/anlogic/lutrams.txt -lib +/anlogic/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)");
+ run("techmap -map +/anlogic/lutrams_map.v -map +/anlogic/brams_map.v");
}
if (check_label("map_ffram"))
diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v
index e9129f690..b14488ff4 100644
--- a/techlibs/common/simlib.v
+++ b/techlibs/common/simlib.v
@@ -1292,6 +1292,33 @@ endmodule
// --------------------------------------------------------
+module \$bmux (A, S, Y);
+
+parameter WIDTH = 0;
+parameter S_WIDTH = 0;
+
+input [(WIDTH << S_WIDTH)-1:0] A;
+input [S_WIDTH-1:0] S;
+output [WIDTH-1:0] Y;
+
+wire [WIDTH-1:0] bm0_out, bm1_out;
+
+generate
+ if (S_WIDTH > 1) begin:muxlogic
+ \$bmux #(.WIDTH(WIDTH), .S_WIDTH(S_WIDTH-1)) bm0 (.A(A), .S(S[S_WIDTH-2:0]), .Y(bm0_out));
+ \$bmux #(.WIDTH(WIDTH), .S_WIDTH(S_WIDTH-1)) bm1 (.A(A[(WIDTH << S_WIDTH)-1:WIDTH << (S_WIDTH - 1)]), .S(S[S_WIDTH-2:0]), .Y(bm1_out));
+ assign Y = S[S_WIDTH-1] ? bm1_out : bm0_out;
+ end else if (S_WIDTH == 1) begin:simple
+ assign Y = S ? A[1] : A[0];
+ end else begin:passthru
+ assign Y = A;
+ end
+endgenerate
+
+endmodule
+
+// --------------------------------------------------------
+
module \$pmux (A, B, S, Y);
parameter WIDTH = 0;
@@ -1318,6 +1345,26 @@ end
endmodule
// --------------------------------------------------------
+
+module \$demux (A, S, Y);
+
+parameter WIDTH = 1;
+parameter S_WIDTH = 1;
+
+input [WIDTH-1:0] A;
+input [S_WIDTH-1:0] S;
+output [(WIDTH << S_WIDTH)-1:0] Y;
+
+genvar i;
+generate
+ for (i = 0; i < (1 << S_WIDTH); i = i + 1) begin:slices
+ assign Y[i*WIDTH+:WIDTH] = (S == i) ? A : 0;
+ end
+endgenerate
+
+endmodule
+
+// --------------------------------------------------------
`ifndef SIMLIB_NOLUT
module \$lut (A, Y);
@@ -1326,30 +1373,9 @@ parameter WIDTH = 0;
parameter LUT = 0;
input [WIDTH-1:0] A;
-output reg Y;
-
-wire lut0_out, lut1_out;
+output Y;
-generate
- if (WIDTH <= 1) begin:simple
- assign {lut1_out, lut0_out} = LUT;
- end else begin:complex
- \$lut #( .WIDTH(WIDTH-1), .LUT(LUT ) ) lut0 ( .A(A[WIDTH-2:0]), .Y(lut0_out) );
- \$lut #( .WIDTH(WIDTH-1), .LUT(LUT >> (2**(WIDTH-1))) ) lut1 ( .A(A[WIDTH-2:0]), .Y(lut1_out) );
- end
-
- if (WIDTH > 0) begin:lutlogic
- always @* begin
- casez ({A[WIDTH-1], lut0_out, lut1_out})
- 3'b?11: Y = 1'b1;
- 3'b?00: Y = 1'b0;
- 3'b0??: Y = lut0_out;
- 3'b1??: Y = lut1_out;
- default: Y = 1'bx;
- endcase
- end
- end
-endgenerate
+\$bmux #(.WIDTH(1), .S_WIDTH(WIDTH)) mux(.A(LUT), .S(A), .Y(Y));
endmodule
diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc
index 79e5933e0..63395c368 100644
--- a/techlibs/common/synth.cc
+++ b/techlibs/common/synth.cc
@@ -81,6 +81,11 @@ struct SynthPass : public ScriptPass
log(" -flowmap\n");
log(" use FlowMap LUT techmapping instead of ABC\n");
log("\n");
+ log(" -no-rw-check\n");
+ log(" marks all recognized read ports as \"return don't-care value on\n");
+ log(" read/write collision\" (same result as setting the no_rw_check\n");
+ log(" attribute on all memories).\n");
+ log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
@@ -175,6 +180,10 @@ struct SynthPass : public ScriptPass
flowmap = true;
continue;
}
+ if (args[argidx] == "-no-rw-check") {
+ memory_opts += " -no-rw-check";
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v
index 667773e1b..91d385b80 100644
--- a/techlibs/common/techmap.v
+++ b/techlibs/common/techmap.v
@@ -59,7 +59,7 @@ module _90_simplemap_compare_ops;
endmodule
(* techmap_simplemap *)
-(* techmap_celltype = "$pos $slice $concat $mux $tribuf" *)
+(* techmap_celltype = "$pos $slice $concat $mux $tribuf $bmux" *)
module _90_simplemap_various;
endmodule
@@ -597,6 +597,43 @@ module _90_pmux (A, B, S, Y);
assign Y = |S ? Y_B : A;
endmodule
+// --------------------------------------------------------
+// Demultiplexers
+// --------------------------------------------------------
+
+(* techmap_celltype = "$demux" *)
+module _90_demux (A, S, Y);
+ parameter WIDTH = 1;
+ parameter S_WIDTH = 1;
+
+ (* force_downto *)
+ input [WIDTH-1:0] A;
+ (* force_downto *)
+ input [S_WIDTH-1:0] S;
+ (* force_downto *)
+ output [(WIDTH << S_WIDTH)-1:0] Y;
+
+ generate
+ if (S_WIDTH == 0) begin
+ assign Y = A;
+ end else if (S_WIDTH == 1) begin
+ assign Y[0+:WIDTH] = S ? 0 : A;
+ assign Y[WIDTH+:WIDTH] = S ? A : 0;
+ end else begin
+ localparam SPLIT = S_WIDTH / 2;
+ wire [(1 << (S_WIDTH-SPLIT))-1:0] YH;
+ wire [(1 << SPLIT)-1:0] YL;
+ $demux #(.WIDTH(1), .S_WIDTH(SPLIT)) lo (.A(1'b1), .S(S[SPLIT-1:0]), .Y(YL));
+ $demux #(.WIDTH(1), .S_WIDTH(S_WIDTH-SPLIT)) hi (.A(1'b1), .S(S[S_WIDTH-1:SPLIT]), .Y(YH));
+ genvar i;
+ for (i = 0; i < (1 << S_WIDTH); i = i + 1) begin
+ localparam [S_WIDTH-1:0] IDX = i;
+ assign Y[i*WIDTH+:WIDTH] = (YL[IDX[SPLIT-1:0]] & YH[IDX[S_WIDTH-1:SPLIT]]) ? A : 0;
+ end
+ end
+ endgenerate
+endmodule
+
// --------------------------------------------------------
// LUTs
diff --git a/techlibs/ecp5/.gitignore b/techlibs/ecp5/.gitignore
deleted file mode 100644
index 9d4723264..000000000
--- a/techlibs/ecp5/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-bram_init_1_2_4.vh
-bram_init_9_18_36.vh
-brams_init.mk
-bram_conn_1.vh
-bram_conn_2.vh
-bram_conn_4.vh
-bram_conn_9.vh
-bram_conn_18.vh
-bram_conn_36.vh
-brams_connect.mk
diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc
index 4c1bc23b5..f9fa79ab9 100644
--- a/techlibs/ecp5/Makefile.inc
+++ b/techlibs/ecp5/Makefile.inc
@@ -1,15 +1,6 @@
OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_gsr.o
-GENFILES += techlibs/ecp5/bram_init_1_2_4.vh
-GENFILES += techlibs/ecp5/bram_init_9_18_36.vh
-GENFILES += techlibs/ecp5/bram_conn_1.vh
-GENFILES += techlibs/ecp5/bram_conn_2.vh
-GENFILES += techlibs/ecp5/bram_conn_4.vh
-GENFILES += techlibs/ecp5/bram_conn_9.vh
-GENFILES += techlibs/ecp5/bram_conn_18.vh
-GENFILES += techlibs/ecp5/bram_conn_36.vh
-
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_ff.vh))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_io.vh))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v))
@@ -22,37 +13,3 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/brams.txt))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/latches_map.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/dsp_map.v))
-
-EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
-.SECONDARY: techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
-
-techlibs/ecp5/brams_init.mk: techlibs/ecp5/brams_init.py
- $(Q) mkdir -p techlibs/ecp5
- $(P) $(PYTHON_EXECUTABLE) $<
- $(Q) touch $@
-
-techlibs/ecp5/brams_connect.mk: techlibs/ecp5/brams_connect.py
- $(Q) mkdir -p techlibs/ecp5
- $(P) $(PYTHON_EXECUTABLE) $<
- $(Q) touch $@
-
-
-techlibs/ecp5/bram_init_1_2_4.vh: techlibs/ecp5/brams_init.mk
-techlibs/ecp5/bram_init_9_18_36.vh: techlibs/ecp5/brams_init.mk
-
-techlibs/ecp5/bram_conn_1.vh: techlibs/ecp5/brams_connect.mk
-techlibs/ecp5/bram_conn_2.vh: techlibs/ecp5/brams_connect.mk
-techlibs/ecp5/bram_conn_4.vh: techlibs/ecp5/brams_connect.mk
-techlibs/ecp5/bram_conn_9.vh: techlibs/ecp5/brams_connect.mk
-techlibs/ecp5/bram_conn_18.vh: techlibs/ecp5/brams_connect.mk
-techlibs/ecp5/bram_conn_36.vh: techlibs/ecp5/brams_connect.mk
-
-$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_init_1_2_4.vh))
-$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_init_9_18_36.vh))
-
-$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_1.vh))
-$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_2.vh))
-$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_4.vh))
-$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_9.vh))
-$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_18.vh))
-$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_36.vh))
diff --git a/techlibs/ecp5/brams.txt b/techlibs/ecp5/brams.txt
index 615d8b2e5..db28a40d7 100644
--- a/techlibs/ecp5/brams.txt
+++ b/techlibs/ecp5/brams.txt
@@ -1,114 +1,52 @@
-bram $__ECP5_PDPW16KD
- init 1
-
- abits 9
- dbits 36
-
- groups 2
- ports 1 1
- wrmode 1 0
- enable 4 1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-bram $__ECP5_DP16KD
- init 1
-
- 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 1 0
- enable 2 1 @a10d18
- enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
- transp 0 2
- clocks 2 3
- clkpol 2 3
-endbram
-
-# The syn_* attributes are described in:
-# https://www.latticesemi.com/view_document?document_id=51556
-attr_icase 1
-
-match $__ECP5_PDPW16KD
- # implicitly requested RAM or ROM
- attribute !syn_ramstyle syn_ramstyle=auto
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- min bits 2048
- min efficiency 5
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__ECP5_PDPW16KD
- # explicitly requested RAM
- attribute syn_ramstyle=block_ram ram_block
- attribute !syn_romstyle
- attribute !rom_block
- attribute !logic_block
- min wports 1
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__ECP5_PDPW16KD
- # explicitly requested ROM
- attribute syn_romstyle=ebr rom_block
- attribute !syn_ramstyle
- attribute !ram_block
- attribute !logic_block
- max wports 0
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__ECP5_DP16KD
- # implicitly requested RAM or ROM
- attribute !syn_ramstyle syn_ramstyle=auto
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- min bits 2048
- min efficiency 5
- shuffle_enable A
- or_next_if_better
-endmatch
-
-match $__ECP5_DP16KD
- # explicitly requested RAM
- attribute syn_ramstyle=block_ram ram_block
- attribute !syn_romstyle
- attribute !rom_block
- attribute !logic_block
- min wports 1
- shuffle_enable A
- or_next_if_better
-endmatch
-
-match $__ECP5_DP16KD
- # explicitly requested ROM
- attribute syn_romstyle=ebr rom_block
- attribute !syn_ramstyle
- attribute !ram_block
- attribute !logic_block
- max wports 0
- shuffle_enable A
-endmatch
+ram block $__ECP5_DP16KD_ {
+ abits 14;
+ widths 1 2 4 9 18 per_port;
+ byte 9;
+ cost 128;
+ init no_undef;
+ port srsw "A" "B" {
+ clock anyedge;
+ clken;
+ wrbe_separate;
+ portoption "WRITEMODE" "NORMAL" {
+ rdwr no_change;
+ }
+ portoption "WRITEMODE" "WRITETHROUGH" {
+ rdwr new;
+ }
+ portoption "WRITEMODE" "READBEFOREWRITE" {
+ rdwr old;
+ }
+ option "RESETMODE" "SYNC" {
+ rdsrst zero ungated block_wr;
+ }
+ option "RESETMODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ }
+}
+
+ram block $__ECP5_PDPW16KD_ {
+ abits 14;
+ widths 1 2 4 9 18 36 per_port;
+ byte 9;
+ cost 128;
+ init no_undef;
+ port sr "R" {
+ clock anyedge;
+ clken;
+ option "RESETMODE" "SYNC" {
+ rdsrst zero ungated;
+ }
+ option "RESETMODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ }
+ port sw "W" {
+ width 36;
+ clock anyedge;
+ clken;
+ }
+}
diff --git a/techlibs/ecp5/brams_connect.py b/techlibs/ecp5/brams_connect.py
deleted file mode 100755
index 098607c59..000000000
--- a/techlibs/ecp5/brams_connect.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-
-def write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits):
- ada_conn = [".ADA%d(%s)" % (i, ada_bits[i]) for i in range(len(ada_bits))]
- adb_conn = [".ADB%d(%s)" % (i, adb_bits[i]) for i in range(len(adb_bits))]
- dia_conn = [".DIA%d(%s)" % (i, dia_bits[i]) for i in range(len(dia_bits))]
- dob_conn = [".DOB%d(%s)" % (i, dob_bits[i]) for i in range(len(dob_bits))]
- print(" %s," % ", ".join(ada_conn), file=f)
- print(" %s," % ", ".join(adb_conn), file=f)
- print(" %s," % ", ".join(dia_conn), file=f)
- print(" %s," % ", ".join(dob_conn), file=f)
-
-def write_bus_ports_pdp(f, adw_bits, adr_bits, di_bits, do_bits, be_bits):
- adw_conn = [".ADW%d(%s)" % (i, adw_bits[i]) for i in range(len(adw_bits))]
- adr_conn = [".ADR%d(%s)" % (i, adr_bits[i]) for i in range(len(adr_bits))]
- di_conn = [".DI%d(%s)" % (i, di_bits[i]) for i in range(len(di_bits))]
- do_conn = [".DO%d(%s)" % (i, do_bits[i]) for i in range(len(do_bits))]
- be_conn = [".BE%d(%s)" % (i, be_bits[i]) for i in range(len(be_bits))]
- print(" %s," % ", ".join(adw_conn), file=f)
- print(" %s," % ", ".join(adr_conn), file=f)
- print(" %s," % ", ".join(di_conn), file=f)
- print(" %s," % ", ".join(do_conn), file=f)
- print(" %s," % ", ".join(be_conn), file=f)
-
-with open("techlibs/ecp5/bram_conn_1.vh", "w") as f:
- ada_bits = ["A1ADDR[%d]" % i for i in range(14)]
- adb_bits = ["B1ADDR[%d]" % i for i in range(14)]
- dia_bits = ["A1DATA[0]"] + ["1'b0" for i in range(17)]
- dob_bits = ["B1DATA[0]"]
- write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits)
-
-with open("techlibs/ecp5/bram_conn_2.vh", "w") as f:
- ada_bits = ["1'b0"] + ["A1ADDR[%d]" % i for i in range(13)]
- adb_bits = ["1'b0"] + ["B1ADDR[%d]" % i for i in range(13)]
- dia_bits = ["A1DATA[%d]" % i for i in range(2)] + ["1'b0" for i in range(16)]
- dob_bits = ["B1DATA[%d]" % i for i in range(2)]
- write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits)
-
-with open("techlibs/ecp5/bram_conn_4.vh", "w") as f:
- ada_bits = ["1'b0", "1'b0"] + ["A1ADDR[%d]" % i for i in range(12)]
- adb_bits = ["1'b0", "1'b0"] + ["B1ADDR[%d]" % i for i in range(12)]
- dia_bits = ["A1DATA[%d]" % i for i in range(4)] + ["1'b0" for i in range(14)]
- dob_bits = ["B1DATA[%d]" % i for i in range(4)]
- write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits)
-
-with open("techlibs/ecp5/bram_conn_9.vh", "w") as f:
- ada_bits = ["1'b0", "1'b0", "1'b0"] + ["A1ADDR[%d]" % i for i in range(11)]
- adb_bits = ["1'b0", "1'b0", "1'b0"] + ["B1ADDR[%d]" % i for i in range(11)]
- dia_bits = ["A1DATA[%d]" % i for i in range(9)] + ["1'b0" for i in range(9)]
- dob_bits = ["B1DATA[%d]" % i for i in range(9)]
- write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits)
-
-with open("techlibs/ecp5/bram_conn_18.vh", "w") as f:
- ada_bits = ["A1EN[0]", "A1EN[1]", "1'b0", "1'b0"] + ["A1ADDR[%d]" % i for i in range(10)]
- adb_bits = ["1'b0", "1'b0", "1'b0", "1'b0"] + ["B1ADDR[%d]" % i for i in range(10)]
- dia_bits = ["A1DATA[%d]" % i for i in range(18)]
- dob_bits = ["B1DATA[%d]" % i for i in range(18)]
- write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits)
-
-with open("techlibs/ecp5/bram_conn_36.vh", "w") as f:
- adw_bits = ["A1ADDR[%d]" % i for i in range(9)]
- adr_bits = ["1'b0", "1'b0", "1'b0", "1'b0", "1'b0"] + ["B1ADDR[%d]" % i for i in range(9)]
- di_bits = ["A1DATA[%d]" % i for i in range(36)]
- do_bits = ["B1DATA[%d]" % (i + 18) for i in range(18)] + ["B1DATA[%d]" % i for i in range(18)]
- be_bits = ["A1EN[%d]" % i for i in range(4)]
- write_bus_ports_pdp(f, adw_bits, adr_bits, di_bits, do_bits, be_bits)
diff --git a/techlibs/ecp5/brams_init.py b/techlibs/ecp5/brams_init.py
deleted file mode 100755
index 96a47bdcd..000000000
--- a/techlibs/ecp5/brams_init.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python3
-with open("techlibs/ecp5/bram_init_1_2_4.vh", "w") as f:
- for i in range(0, 0x40):
- init_snippets = []
- for j in range(32):
- init_snippets.append("INIT[%4d*8 +: 8]" % (32 * i + j))
- init_snippets.append("3'b000" if (j % 2 == 1) else "1'b0")
- init_snippets = list(reversed(init_snippets))
- for k in range(8, 64, 8):
- init_snippets[k] = "\n " + init_snippets[k]
- print(".INITVAL_%02X({%s})," % (i, ", ".join(init_snippets)), file=f)
-
-with open("techlibs/ecp5/bram_init_9_18_36.vh", "w") as f:
- for i in range(0, 0x40):
- init_snippets = []
- for j in range(16):
- init_snippets.append("INIT[%3d*18 +: 18]" % (16 * i + j))
- init_snippets.append("2'b00")
- init_snippets = list(reversed(init_snippets))
- for k in range(8, 32, 8):
- init_snippets[k] = "\n " + init_snippets[k]
- print(".INITVAL_%02X({%s})," % (i, ", ".join(init_snippets)), file=f)
diff --git a/techlibs/ecp5/brams_map.v b/techlibs/ecp5/brams_map.v
index edda17c02..22e6e068e 100644
--- a/techlibs/ecp5/brams_map.v
+++ b/techlibs/ecp5/brams_map.v
@@ -1,155 +1,489 @@
-module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 10;
- parameter CFG_DBITS = 18;
- parameter CFG_ENABLE_A = 2;
-
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
- parameter [18431:0] INIT = 18432'bx;
- parameter TRANSP2 = 0;
-
- input CLK2;
- input CLK3;
-
- input [CFG_ABITS-1:0] A1ADDR;
- input [CFG_DBITS-1:0] A1DATA;
- input [CFG_ENABLE_A-1:0] A1EN;
-
- input [CFG_ABITS-1:0] B1ADDR;
- output [CFG_DBITS-1:0] B1DATA;
- input B1EN;
-
- localparam CLKAMUX = CLKPOL2 ? "CLKA" : "INV";
- localparam CLKBMUX = CLKPOL3 ? "CLKB" : "INV";
-
- localparam WRITEMODE_A = TRANSP2 ? "WRITETHROUGH" : "READBEFOREWRITE";
-
- generate if (CFG_DBITS == 1) begin
- DP16KD #(
- `include "bram_init_1_2_4.vh"
- .DATA_WIDTH_A(1),
- .DATA_WIDTH_B(1),
- .CLKAMUX(CLKAMUX),
- .CLKBMUX(CLKBMUX),
- .WRITEMODE_A(WRITEMODE_A),
- .WRITEMODE_B("READBEFOREWRITE"),
- .GSR("AUTO")
- ) _TECHMAP_REPLACE_ (
- `include "bram_conn_1.vh"
- .CLKA(CLK2), .CLKB(CLK3),
- .WEA(|A1EN), .CEA(1'b1), .OCEA(1'b1),
- .WEB(1'b0), .CEB(B1EN), .OCEB(1'b1),
- .RSTA(1'b0), .RSTB(1'b0)
- );
- end else if (CFG_DBITS == 2) begin
- DP16KD #(
- `include "bram_init_1_2_4.vh"
- .DATA_WIDTH_A(2),
- .DATA_WIDTH_B(2),
- .CLKAMUX(CLKAMUX),
- .CLKBMUX(CLKBMUX),
- .WRITEMODE_A(WRITEMODE_A),
- .WRITEMODE_B("READBEFOREWRITE"),
- .GSR("AUTO")
- ) _TECHMAP_REPLACE_ (
- `include "bram_conn_2.vh"
- .CLKA(CLK2), .CLKB(CLK3),
- .WEA(|A1EN), .CEA(1'b1), .OCEA(1'b1),
- .WEB(1'b0), .CEB(B1EN), .OCEB(1'b1),
- .RSTA(1'b0), .RSTB(1'b0)
- );
- end else if (CFG_DBITS <= 4) begin
- DP16KD #(
- `include "bram_init_1_2_4.vh"
- .DATA_WIDTH_A(4),
- .DATA_WIDTH_B(4),
- .CLKAMUX(CLKAMUX),
- .CLKBMUX(CLKBMUX),
- .WRITEMODE_A(WRITEMODE_A),
- .WRITEMODE_B("READBEFOREWRITE"),
- .GSR("AUTO")
- ) _TECHMAP_REPLACE_ (
- `include "bram_conn_4.vh"
- .CLKA(CLK2), .CLKB(CLK3),
- .WEA(|A1EN), .CEA(1'b1), .OCEA(1'b1),
- .WEB(1'b0), .CEB(B1EN), .OCEB(1'b1),
- .RSTA(1'b0), .RSTB(1'b0)
- );
- end else if (CFG_DBITS <= 9) begin
- DP16KD #(
- `include "bram_init_9_18_36.vh"
- .DATA_WIDTH_A(9),
- .DATA_WIDTH_B(9),
- .CLKAMUX(CLKAMUX),
- .CLKBMUX(CLKBMUX),
- .WRITEMODE_A(WRITEMODE_A),
- .WRITEMODE_B("READBEFOREWRITE"),
- .GSR("AUTO")
- ) _TECHMAP_REPLACE_ (
- `include "bram_conn_9.vh"
- .CLKA(CLK2), .CLKB(CLK3),
- .WEA(|A1EN), .CEA(1'b1), .OCEA(1'b1),
- .WEB(1'b0), .CEB(B1EN), .OCEB(1'b1),
- .RSTA(1'b0), .RSTB(1'b0)
- );
- end else if (CFG_DBITS <= 18) begin
- DP16KD #(
- `include "bram_init_9_18_36.vh"
- .DATA_WIDTH_A(18),
- .DATA_WIDTH_B(18),
- .CLKAMUX(CLKAMUX),
- .CLKBMUX(CLKBMUX),
- .WRITEMODE_A(WRITEMODE_A),
- .WRITEMODE_B("READBEFOREWRITE"),
- .GSR("AUTO")
- ) _TECHMAP_REPLACE_ (
- `include "bram_conn_18.vh"
- .CLKA(CLK2), .CLKB(CLK3),
- .WEA(|A1EN), .CEA(1'b1), .OCEA(1'b1),
- .WEB(1'b0), .CEB(B1EN), .OCEB(1'b1),
- .RSTA(1'b0), .RSTB(1'b0)
- );
- end else begin
- wire TECHMAP_FAIL = 1'b1;
- end endgenerate
+module $__ECP5_DP16KD_ (...);
+
+parameter INIT = 0;
+parameter OPTION_RESETMODE = "SYNC";
+
+parameter PORT_A_WIDTH = 18;
+parameter PORT_A_WR_BE_WIDTH = 2;
+parameter PORT_A_CLK_POL = 1;
+parameter PORT_A_OPTION_WRITEMODE = "NORMAL";
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input PORT_A_WR_EN;
+input PORT_A_RD_SRST;
+input PORT_A_RD_ARST;
+input [13:0] PORT_A_ADDR;
+input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE;
+input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
+output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
+
+parameter PORT_B_WIDTH = 18;
+parameter PORT_B_WR_BE_WIDTH = 2;
+parameter PORT_B_CLK_POL = 1;
+parameter PORT_B_OPTION_WRITEMODE = "NORMAL";
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input PORT_B_WR_EN;
+input PORT_B_RD_SRST;
+input PORT_B_RD_ARST;
+input [13:0] PORT_B_ADDR;
+input [PORT_B_WR_BE_WIDTH-1:0] PORT_B_WR_BE;
+input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
+output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
+
+function [319:0] init_slice;
+ input integer idx;
+ integer i, j;
+ init_slice = 0;
+ for (i = 0; i < 16; i = i + 1) begin
+ init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18];
+ end
+endfunction
+
+wire [17:0] DOA;
+wire [17:0] DOB;
+wire [17:0] DIA = PORT_A_WR_DATA;
+wire [17:0] DIB = PORT_B_WR_DATA;
+
+assign PORT_A_RD_DATA = DOA;
+assign PORT_B_RD_DATA = DOB;
+
+DP16KD #(
+ .INITVAL_00(init_slice('h00)),
+ .INITVAL_01(init_slice('h01)),
+ .INITVAL_02(init_slice('h02)),
+ .INITVAL_03(init_slice('h03)),
+ .INITVAL_04(init_slice('h04)),
+ .INITVAL_05(init_slice('h05)),
+ .INITVAL_06(init_slice('h06)),
+ .INITVAL_07(init_slice('h07)),
+ .INITVAL_08(init_slice('h08)),
+ .INITVAL_09(init_slice('h09)),
+ .INITVAL_0A(init_slice('h0a)),
+ .INITVAL_0B(init_slice('h0b)),
+ .INITVAL_0C(init_slice('h0c)),
+ .INITVAL_0D(init_slice('h0d)),
+ .INITVAL_0E(init_slice('h0e)),
+ .INITVAL_0F(init_slice('h0f)),
+ .INITVAL_10(init_slice('h10)),
+ .INITVAL_11(init_slice('h11)),
+ .INITVAL_12(init_slice('h12)),
+ .INITVAL_13(init_slice('h13)),
+ .INITVAL_14(init_slice('h14)),
+ .INITVAL_15(init_slice('h15)),
+ .INITVAL_16(init_slice('h16)),
+ .INITVAL_17(init_slice('h17)),
+ .INITVAL_18(init_slice('h18)),
+ .INITVAL_19(init_slice('h19)),
+ .INITVAL_1A(init_slice('h1a)),
+ .INITVAL_1B(init_slice('h1b)),
+ .INITVAL_1C(init_slice('h1c)),
+ .INITVAL_1D(init_slice('h1d)),
+ .INITVAL_1E(init_slice('h1e)),
+ .INITVAL_1F(init_slice('h1f)),
+ .INITVAL_20(init_slice('h20)),
+ .INITVAL_21(init_slice('h21)),
+ .INITVAL_22(init_slice('h22)),
+ .INITVAL_23(init_slice('h23)),
+ .INITVAL_24(init_slice('h24)),
+ .INITVAL_25(init_slice('h25)),
+ .INITVAL_26(init_slice('h26)),
+ .INITVAL_27(init_slice('h27)),
+ .INITVAL_28(init_slice('h28)),
+ .INITVAL_29(init_slice('h29)),
+ .INITVAL_2A(init_slice('h2a)),
+ .INITVAL_2B(init_slice('h2b)),
+ .INITVAL_2C(init_slice('h2c)),
+ .INITVAL_2D(init_slice('h2d)),
+ .INITVAL_2E(init_slice('h2e)),
+ .INITVAL_2F(init_slice('h2f)),
+ .INITVAL_30(init_slice('h30)),
+ .INITVAL_31(init_slice('h31)),
+ .INITVAL_32(init_slice('h32)),
+ .INITVAL_33(init_slice('h33)),
+ .INITVAL_34(init_slice('h34)),
+ .INITVAL_35(init_slice('h35)),
+ .INITVAL_36(init_slice('h36)),
+ .INITVAL_37(init_slice('h37)),
+ .INITVAL_38(init_slice('h38)),
+ .INITVAL_39(init_slice('h39)),
+ .INITVAL_3A(init_slice('h3a)),
+ .INITVAL_3B(init_slice('h3b)),
+ .INITVAL_3C(init_slice('h3c)),
+ .INITVAL_3D(init_slice('h3d)),
+ .INITVAL_3E(init_slice('h3e)),
+ .INITVAL_3F(init_slice('h3f)),
+ .DATA_WIDTH_A(PORT_A_WIDTH),
+ .DATA_WIDTH_B(PORT_B_WIDTH),
+ .REGMODE_A("NOREG"),
+ .REGMODE_B("NOREG"),
+ .RESETMODE(OPTION_RESETMODE),
+ .ASYNC_RESET_RELEASE(OPTION_RESETMODE),
+ .CSDECODE_A("0b000"),
+ .CSDECODE_B("0b000"),
+ .CLKAMUX(PORT_A_CLK_POL ? "CLKA" : "INV"),
+ .CLKBMUX(PORT_B_CLK_POL ? "CLKB" : "INV"),
+ .WRITEMODE_A(PORT_A_OPTION_WRITEMODE),
+ .WRITEMODE_B(PORT_B_OPTION_WRITEMODE),
+ .GSR("AUTO")
+) _TECHMAP_REPLACE_ (
+ .CLKA(PORT_A_CLK),
+ .WEA(PORT_A_WIDTH == 18 ? PORT_A_WR_EN : (PORT_A_WR_EN | PORT_A_WR_BE[0])),
+ .CEA(PORT_A_CLK_EN),
+ .OCEA(1'b1),
+ .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST),
+ .CSA0(1'b0),
+ .CSA1(1'b0),
+ .CSA2(1'b0),
+ .ADA0(PORT_A_WIDTH == 18 ? PORT_A_WR_BE[0] : PORT_A_ADDR[0]),
+ .ADA1(PORT_A_WIDTH == 18 ? PORT_A_WR_BE[1] : PORT_A_ADDR[1]),
+ .ADA2(PORT_A_ADDR[2]),
+ .ADA3(PORT_A_ADDR[3]),
+ .ADA4(PORT_A_ADDR[4]),
+ .ADA5(PORT_A_ADDR[5]),
+ .ADA6(PORT_A_ADDR[6]),
+ .ADA7(PORT_A_ADDR[7]),
+ .ADA8(PORT_A_ADDR[8]),
+ .ADA9(PORT_A_ADDR[9]),
+ .ADA10(PORT_A_ADDR[10]),
+ .ADA11(PORT_A_ADDR[11]),
+ .ADA12(PORT_A_ADDR[12]),
+ .ADA13(PORT_A_ADDR[13]),
+ .DIA0(DIA[0]),
+ .DIA1(DIA[1]),
+ .DIA2(DIA[2]),
+ .DIA3(DIA[3]),
+ .DIA4(DIA[4]),
+ .DIA5(DIA[5]),
+ .DIA6(DIA[6]),
+ .DIA7(DIA[7]),
+ .DIA8(DIA[8]),
+ .DIA9(DIA[9]),
+ .DIA10(DIA[10]),
+ .DIA11(DIA[11]),
+ .DIA12(DIA[12]),
+ .DIA13(DIA[13]),
+ .DIA14(DIA[14]),
+ .DIA15(DIA[15]),
+ .DIA16(DIA[16]),
+ .DIA17(DIA[17]),
+ .DOA0(DOA[0]),
+ .DOA1(DOA[1]),
+ .DOA2(DOA[2]),
+ .DOA3(DOA[3]),
+ .DOA4(DOA[4]),
+ .DOA5(DOA[5]),
+ .DOA6(DOA[6]),
+ .DOA7(DOA[7]),
+ .DOA8(DOA[8]),
+ .DOA9(DOA[9]),
+ .DOA10(DOA[10]),
+ .DOA11(DOA[11]),
+ .DOA12(DOA[12]),
+ .DOA13(DOA[13]),
+ .DOA14(DOA[14]),
+ .DOA15(DOA[15]),
+ .DOA16(DOA[16]),
+ .DOA17(DOA[17]),
+
+ .CLKB(PORT_B_CLK),
+ .WEB(PORT_B_WIDTH == 18 ? PORT_B_WR_EN : (PORT_B_WR_EN | PORT_B_WR_BE[0])),
+ .CEB(PORT_B_CLK_EN),
+ .OCEB(1'b1),
+ .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST),
+ .CSB0(1'b0),
+ .CSB1(1'b0),
+ .CSB2(1'b0),
+ .ADB0(PORT_B_WIDTH == 18 ? PORT_B_WR_BE[0] : PORT_B_ADDR[0]),
+ .ADB1(PORT_B_WIDTH == 18 ? PORT_B_WR_BE[1] : PORT_B_ADDR[1]),
+ .ADB2(PORT_B_ADDR[2]),
+ .ADB3(PORT_B_ADDR[3]),
+ .ADB4(PORT_B_ADDR[4]),
+ .ADB5(PORT_B_ADDR[5]),
+ .ADB6(PORT_B_ADDR[6]),
+ .ADB7(PORT_B_ADDR[7]),
+ .ADB8(PORT_B_ADDR[8]),
+ .ADB9(PORT_B_ADDR[9]),
+ .ADB10(PORT_B_ADDR[10]),
+ .ADB11(PORT_B_ADDR[11]),
+ .ADB12(PORT_B_ADDR[12]),
+ .ADB13(PORT_B_ADDR[13]),
+ .DIB0(DIB[0]),
+ .DIB1(DIB[1]),
+ .DIB2(DIB[2]),
+ .DIB3(DIB[3]),
+ .DIB4(DIB[4]),
+ .DIB5(DIB[5]),
+ .DIB6(DIB[6]),
+ .DIB7(DIB[7]),
+ .DIB8(DIB[8]),
+ .DIB9(DIB[9]),
+ .DIB10(DIB[10]),
+ .DIB11(DIB[11]),
+ .DIB12(DIB[12]),
+ .DIB13(DIB[13]),
+ .DIB14(DIB[14]),
+ .DIB15(DIB[15]),
+ .DIB16(DIB[16]),
+ .DIB17(DIB[17]),
+ .DOB0(DOB[0]),
+ .DOB1(DOB[1]),
+ .DOB2(DOB[2]),
+ .DOB3(DOB[3]),
+ .DOB4(DOB[4]),
+ .DOB5(DOB[5]),
+ .DOB6(DOB[6]),
+ .DOB7(DOB[7]),
+ .DOB8(DOB[8]),
+ .DOB9(DOB[9]),
+ .DOB10(DOB[10]),
+ .DOB11(DOB[11]),
+ .DOB12(DOB[12]),
+ .DOB13(DOB[13]),
+ .DOB14(DOB[14]),
+ .DOB15(DOB[15]),
+ .DOB16(DOB[16]),
+ .DOB17(DOB[17]),
+);
+
endmodule
-module \$__ECP5_PDPW16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 9;
- parameter CFG_DBITS = 36;
- parameter CFG_ENABLE_A = 4;
-
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
- parameter [18431:0] INIT = 18432'bx;
-
- input CLK2;
- input CLK3;
-
- input [CFG_ABITS-1:0] A1ADDR;
- input [CFG_DBITS-1:0] A1DATA;
- input [CFG_ENABLE_A-1:0] A1EN;
-
- input [CFG_ABITS-1:0] B1ADDR;
- output [CFG_DBITS-1:0] B1DATA;
- input B1EN;
-
- localparam CLKWMUX = CLKPOL2 ? "CLKA" : "INV";
- localparam CLKRMUX = CLKPOL3 ? "CLKB" : "INV";
-
- PDPW16KD #(
- `include "bram_init_9_18_36.vh"
- .DATA_WIDTH_W(36),
- .DATA_WIDTH_R(36),
- .CLKWMUX(CLKWMUX),
- .CLKRMUX(CLKRMUX),
- .GSR("AUTO")
- ) _TECHMAP_REPLACE_ (
- `include "bram_conn_36.vh"
- .CLKW(CLK2), .CLKR(CLK3),
- .CEW(1'b1),
- .CER(B1EN), .OCER(1'b1),
- .RST(1'b0)
- );
+
+module $__ECP5_PDPW16KD_ (...);
+
+parameter INIT = 0;
+parameter OPTION_RESETMODE = "SYNC";
+
+parameter PORT_R_WIDTH = 36;
+parameter PORT_R_CLK_POL = 1;
+
+input PORT_R_CLK;
+input PORT_R_CLK_EN;
+input PORT_R_RD_SRST;
+input PORT_R_RD_ARST;
+input [13:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+
+parameter PORT_W_WIDTH = 36;
+parameter PORT_W_WR_EN_WIDTH = 4;
+parameter PORT_W_CLK_POL = 1;
+
+input PORT_W_CLK;
+input PORT_W_CLK_EN;
+input [13:0] PORT_W_ADDR;
+input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+
+function [319:0] init_slice;
+ input integer idx;
+ integer i, j;
+ init_slice = 0;
+ for (i = 0; i < 16; i = i + 1) begin
+ init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18];
+ end
+endfunction
+
+wire [35:0] DI = PORT_W_WR_DATA;
+wire [35:0] DO;
+
+assign PORT_R_RD_DATA = PORT_R_WIDTH == 36 ? DO : DO[35:18];
+
+DP16KD #(
+ .INITVAL_00(init_slice('h00)),
+ .INITVAL_01(init_slice('h01)),
+ .INITVAL_02(init_slice('h02)),
+ .INITVAL_03(init_slice('h03)),
+ .INITVAL_04(init_slice('h04)),
+ .INITVAL_05(init_slice('h05)),
+ .INITVAL_06(init_slice('h06)),
+ .INITVAL_07(init_slice('h07)),
+ .INITVAL_08(init_slice('h08)),
+ .INITVAL_09(init_slice('h09)),
+ .INITVAL_0A(init_slice('h0a)),
+ .INITVAL_0B(init_slice('h0b)),
+ .INITVAL_0C(init_slice('h0c)),
+ .INITVAL_0D(init_slice('h0d)),
+ .INITVAL_0E(init_slice('h0e)),
+ .INITVAL_0F(init_slice('h0f)),
+ .INITVAL_10(init_slice('h10)),
+ .INITVAL_11(init_slice('h11)),
+ .INITVAL_12(init_slice('h12)),
+ .INITVAL_13(init_slice('h13)),
+ .INITVAL_14(init_slice('h14)),
+ .INITVAL_15(init_slice('h15)),
+ .INITVAL_16(init_slice('h16)),
+ .INITVAL_17(init_slice('h17)),
+ .INITVAL_18(init_slice('h18)),
+ .INITVAL_19(init_slice('h19)),
+ .INITVAL_1A(init_slice('h1a)),
+ .INITVAL_1B(init_slice('h1b)),
+ .INITVAL_1C(init_slice('h1c)),
+ .INITVAL_1D(init_slice('h1d)),
+ .INITVAL_1E(init_slice('h1e)),
+ .INITVAL_1F(init_slice('h1f)),
+ .INITVAL_20(init_slice('h20)),
+ .INITVAL_21(init_slice('h21)),
+ .INITVAL_22(init_slice('h22)),
+ .INITVAL_23(init_slice('h23)),
+ .INITVAL_24(init_slice('h24)),
+ .INITVAL_25(init_slice('h25)),
+ .INITVAL_26(init_slice('h26)),
+ .INITVAL_27(init_slice('h27)),
+ .INITVAL_28(init_slice('h28)),
+ .INITVAL_29(init_slice('h29)),
+ .INITVAL_2A(init_slice('h2a)),
+ .INITVAL_2B(init_slice('h2b)),
+ .INITVAL_2C(init_slice('h2c)),
+ .INITVAL_2D(init_slice('h2d)),
+ .INITVAL_2E(init_slice('h2e)),
+ .INITVAL_2F(init_slice('h2f)),
+ .INITVAL_30(init_slice('h30)),
+ .INITVAL_31(init_slice('h31)),
+ .INITVAL_32(init_slice('h32)),
+ .INITVAL_33(init_slice('h33)),
+ .INITVAL_34(init_slice('h34)),
+ .INITVAL_35(init_slice('h35)),
+ .INITVAL_36(init_slice('h36)),
+ .INITVAL_37(init_slice('h37)),
+ .INITVAL_38(init_slice('h38)),
+ .INITVAL_39(init_slice('h39)),
+ .INITVAL_3A(init_slice('h3a)),
+ .INITVAL_3B(init_slice('h3b)),
+ .INITVAL_3C(init_slice('h3c)),
+ .INITVAL_3D(init_slice('h3d)),
+ .INITVAL_3E(init_slice('h3e)),
+ .INITVAL_3F(init_slice('h3f)),
+ .DATA_WIDTH_A(PORT_W_WIDTH),
+ .DATA_WIDTH_B(PORT_R_WIDTH),
+ .REGMODE_A("NOREG"),
+ .REGMODE_B("NOREG"),
+ .RESETMODE(OPTION_RESETMODE),
+ .ASYNC_RESET_RELEASE(OPTION_RESETMODE),
+ .CSDECODE_A("0b000"),
+ .CSDECODE_B("0b000"),
+ .CLKAMUX(PORT_W_CLK_POL ? "CLKA" : "INV"),
+ .CLKBMUX(PORT_R_CLK_POL ? "CLKB" : "INV"),
+ .GSR("AUTO")
+) _TECHMAP_REPLACE_ (
+ .CLKA(PORT_W_CLK),
+ .WEA(PORT_W_WIDTH >= 18 ? 1'b1 : PORT_W_WR_EN[0]),
+ .CEA(PORT_W_CLK_EN),
+ .OCEA(1'b0),
+ .RSTA(1'b0),
+ .CSA0(1'b0),
+ .CSA1(1'b0),
+ .CSA2(1'b0),
+ .ADA0(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[0] : PORT_W_ADDR[0]),
+ .ADA1(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[1] : PORT_W_ADDR[1]),
+ .ADA2(PORT_W_WIDTH >= 36 ? PORT_W_WR_EN[2] : PORT_W_ADDR[2]),
+ .ADA3(PORT_W_WIDTH >= 36 ? PORT_W_WR_EN[3] : PORT_W_ADDR[3]),
+ .ADA4(PORT_W_ADDR[4]),
+ .ADA5(PORT_W_ADDR[5]),
+ .ADA6(PORT_W_ADDR[6]),
+ .ADA7(PORT_W_ADDR[7]),
+ .ADA8(PORT_W_ADDR[8]),
+ .ADA9(PORT_W_ADDR[9]),
+ .ADA10(PORT_W_ADDR[10]),
+ .ADA11(PORT_W_ADDR[11]),
+ .ADA12(PORT_W_ADDR[12]),
+ .ADA13(PORT_W_ADDR[13]),
+ .DIA0(DI[0]),
+ .DIA1(DI[1]),
+ .DIA2(DI[2]),
+ .DIA3(DI[3]),
+ .DIA4(DI[4]),
+ .DIA5(DI[5]),
+ .DIA6(DI[6]),
+ .DIA7(DI[7]),
+ .DIA8(DI[8]),
+ .DIA9(DI[9]),
+ .DIA10(DI[10]),
+ .DIA11(DI[11]),
+ .DIA12(DI[12]),
+ .DIA13(DI[13]),
+ .DIA14(DI[14]),
+ .DIA15(DI[15]),
+ .DIA16(DI[16]),
+ .DIA17(DI[17]),
+ .DIB0(DI[18]),
+ .DIB1(DI[19]),
+ .DIB2(DI[20]),
+ .DIB3(DI[21]),
+ .DIB4(DI[22]),
+ .DIB5(DI[23]),
+ .DIB6(DI[24]),
+ .DIB7(DI[25]),
+ .DIB8(DI[26]),
+ .DIB9(DI[27]),
+ .DIB10(DI[28]),
+ .DIB11(DI[29]),
+ .DIB12(DI[30]),
+ .DIB13(DI[31]),
+ .DIB14(DI[32]),
+ .DIB15(DI[33]),
+ .DIB16(DI[34]),
+ .DIB17(DI[35]),
+
+ .CLKB(PORT_R_CLK),
+ .WEB(1'b0),
+ .CEB(PORT_R_CLK_EN),
+ .OCEB(1'b1),
+ .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST),
+ .CSB0(1'b0),
+ .CSB1(1'b0),
+ .CSB2(1'b0),
+ .ADB0(PORT_R_ADDR[0]),
+ .ADB1(PORT_R_ADDR[1]),
+ .ADB2(PORT_R_ADDR[2]),
+ .ADB3(PORT_R_ADDR[3]),
+ .ADB4(PORT_R_ADDR[4]),
+ .ADB5(PORT_R_ADDR[5]),
+ .ADB6(PORT_R_ADDR[6]),
+ .ADB7(PORT_R_ADDR[7]),
+ .ADB8(PORT_R_ADDR[8]),
+ .ADB9(PORT_R_ADDR[9]),
+ .ADB10(PORT_R_ADDR[10]),
+ .ADB11(PORT_R_ADDR[11]),
+ .ADB12(PORT_R_ADDR[12]),
+ .ADB13(PORT_R_ADDR[13]),
+ .DOA0(DO[0]),
+ .DOA1(DO[1]),
+ .DOA2(DO[2]),
+ .DOA3(DO[3]),
+ .DOA4(DO[4]),
+ .DOA5(DO[5]),
+ .DOA6(DO[6]),
+ .DOA7(DO[7]),
+ .DOA8(DO[8]),
+ .DOA9(DO[9]),
+ .DOA10(DO[10]),
+ .DOA11(DO[11]),
+ .DOA12(DO[12]),
+ .DOA13(DO[13]),
+ .DOA14(DO[14]),
+ .DOA15(DO[15]),
+ .DOA16(DO[16]),
+ .DOA17(DO[17]),
+ .DOB0(DO[18]),
+ .DOB1(DO[19]),
+ .DOB2(DO[20]),
+ .DOB3(DO[21]),
+ .DOB4(DO[22]),
+ .DOB5(DO[23]),
+ .DOB6(DO[24]),
+ .DOB7(DO[25]),
+ .DOB8(DO[26]),
+ .DOB9(DO[27]),
+ .DOB10(DO[28]),
+ .DOB11(DO[29]),
+ .DOB12(DO[30]),
+ .DOB13(DO[31]),
+ .DOB14(DO[32]),
+ .DOB15(DO[33]),
+ .DOB16(DO[34]),
+ .DOB17(DO[35]),
+);
endmodule
diff --git a/techlibs/ecp5/cells_bb.v b/techlibs/ecp5/cells_bb.v
index e616d24d6..fc352a52c 100644
--- a/techlibs/ecp5/cells_bb.v
+++ b/techlibs/ecp5/cells_bb.v
@@ -223,7 +223,7 @@ endmodule
(* blackbox *)
module IDDRX2F(
- input D, SCLK, ECLK, RST,
+ input D, SCLK, ECLK, RST, ALIGNWD,
output Q0, Q1, Q2, Q3
);
parameter GSR = "ENABLED";
diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v
index 357fd9173..f9d503deb 100644
--- a/techlibs/ecp5/cells_sim.v
+++ b/techlibs/ecp5/cells_sim.v
@@ -204,7 +204,7 @@ module TRELLIS_DPR16X4 (
integer i;
initial begin
for (i = 0; i < 16; i = i + 1)
- mem[i] <= {INITVAL[i+3], INITVAL[i+2], INITVAL[i+1], INITVAL[i]};
+ mem[i] <= INITVAL[4*i +: 4];
end
wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK;
@@ -355,37 +355,24 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q);
end
endgenerate
- generate
- // TODO
- if (CLKMUX == "INV")
- specify
- $setup(DI, negedge CLK, 0);
- $setup(CE, negedge CLK, 0);
- $setup(LSR, negedge CLK, 0);
-`ifndef YOSYS
- if (SRMODE == "ASYNC" && muxlsr) (negedge CLK => (Q : srval)) = 0;
-`else
- if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path
- // but for facilitating a bypass box, let's pretend it's
- // a simple path
-`endif
- if (!muxlsr && muxce) (negedge CLK => (Q : DI)) = 0;
- endspecify
- else
- specify
- $setup(DI, posedge CLK, 0);
- $setup(CE, posedge CLK, 0);
- $setup(LSR, posedge CLK, 0);
+ specify
+ $setup(DI, negedge CLK &&& CLKMUX == "INV", 0);
+ $setup(CE, negedge CLK &&& CLKMUX == "INV", 0);
+ $setup(LSR, negedge CLK &&& CLKMUX == "INV", 0);
+ $setup(DI, posedge CLK &&& CLKMUX != "INV", 0);
+ $setup(CE, posedge CLK &&& CLKMUX != "INV", 0);
+ $setup(LSR, posedge CLK &&& CLKMUX != "INV", 0);
`ifndef YOSYS
- if (SRMODE == "ASYNC" && muxlsr) (posedge CLK => (Q : srval)) = 0;
+ if (SRMODE == "ASYNC" && muxlsr && CLKMUX == "INV") (negedge CLK => (Q : srval)) = 0;
+ if (SRMODE == "ASYNC" && muxlsr && CLKMUX != "INV") (posedge CLK => (Q : srval)) = 0;
`else
- if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path
- // but for facilitating a bypass box, let's pretend it's
- // a simple path
+ if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path
+ // but for facilitating a bypass box, let's pretend it's
+ // a simple path
`endif
- if (!muxlsr && muxce) (posedge CLK => (Q : DI)) = 0;
- endspecify
- endgenerate
+ if (!muxlsr && muxce && CLKMUX == "INV") (negedge CLK => (Q : DI)) = 0;
+ if (!muxlsr && muxce && CLKMUX != "INV") (posedge CLK => (Q : DI)) = 0;
+ endspecify
endmodule
// ---------------------------------------
@@ -812,6 +799,7 @@ module DP16KD(
parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_DATA = "STATIC";
endmodule
`ifndef NO_INCLUDES
diff --git a/techlibs/ecp5/lutrams.txt b/techlibs/ecp5/lutrams.txt
index 5370a1ddb..ea42d4fcb 100644
--- a/techlibs/ecp5/lutrams.txt
+++ b/techlibs/ecp5/lutrams.txt
@@ -1,26 +1,12 @@
-bram $__TRELLIS_DPR16X4
- init 1
- abits 4
- dbits 4
- groups 2
- ports 1 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 2
-endbram
-
-# The syn_* attributes are described in:
-# https://www.latticesemi.com/view_document?document_id=51556
-attr_icase 1
-
-match $__TRELLIS_DPR16X4
- attribute !syn_ramstyle syn_ramstyle=auto syn_ramstyle=distributed
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- make_outreg
- min wports 1
-endmatch
+ram distributed $__TRELLIS_DPR16X4_ {
+ abits 4;
+ width 4;
+ cost 4;
+ init any;
+ prune_rom;
+ port sw "W" {
+ clock anyedge;
+ }
+ port ar "R" {
+ }
+}
diff --git a/techlibs/ecp5/lutrams_map.v b/techlibs/ecp5/lutrams_map.v
index 3b3de831f..3cb325f04 100644
--- a/techlibs/ecp5/lutrams_map.v
+++ b/techlibs/ecp5/lutrams_map.v
@@ -1,28 +1,30 @@
-module \$__TRELLIS_DPR16X4 (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
- parameter [63:0] INIT = 64'bx;
- parameter CLKPOL2 = 1;
- input CLK1;
+module $__TRELLIS_DPR16X4_(...);
- input [3:0] A1ADDR;
- output [3:0] A1DATA;
+parameter INIT = 64'bx;
+parameter PORT_W_CLK_POL = 1;
- input [3:0] B1ADDR;
- input [3:0] B1DATA;
- input B1EN;
+input PORT_W_CLK;
+input [3:0] PORT_W_ADDR;
+input [3:0] PORT_W_WR_DATA;
+input PORT_W_WR_EN;
- localparam WCKMUX = CLKPOL2 ? "WCK" : "INV";
+input [3:0] PORT_R_ADDR;
+output [3:0] PORT_R_RD_DATA;
- TRELLIS_DPR16X4 #(
- .INITVAL(INIT),
- .WCKMUX(WCKMUX),
- .WREMUX("WRE")
- ) _TECHMAP_REPLACE_ (
- .RAD(A1ADDR),
- .DO(A1DATA),
+localparam WCKMUX = PORT_W_CLK_POL ? "WCK" : "INV";
+
+TRELLIS_DPR16X4 #(
+ .INITVAL(INIT),
+ .WCKMUX(WCKMUX),
+ .WREMUX("WRE")
+) _TECHMAP_REPLACE_ (
+ .RAD(PORT_R_ADDR),
+ .DO(PORT_R_RD_DATA),
+
+ .WAD(PORT_W_ADDR),
+ .DI(PORT_W_WR_DATA),
+ .WCK(PORT_W_CLK),
+ .WRE(PORT_W_WR_EN)
+);
- .WAD(B1ADDR),
- .DI(B1DATA),
- .WCK(CLK1),
- .WRE(B1EN)
- );
endmodule
diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc
index eb8ba8b9d..f2dc534f9 100644
--- a/techlibs/ecp5/synth_ecp5.cc
+++ b/techlibs/ecp5/synth_ecp5.cc
@@ -103,6 +103,11 @@ struct SynthEcp5Pass : public ScriptPass
log(" -nodsp\n");
log(" do not map multipliers to MULT18X18D\n");
log("\n");
+ log(" -no-rw-check\n");
+ log(" marks all recognized read ports as \"return don't-care value on\n");
+ log(" read/write collision\" (same result as setting the no_rw_check\n");
+ log(" attribute on all memories).\n");
+ log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
@@ -110,7 +115,7 @@ struct SynthEcp5Pass : public ScriptPass
}
string top_opt, blif_file, edif_file, json_file;
- bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, nodsp, vpr;
+ bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, nodsp, vpr, no_rw_check;
void clear_flags() override
{
@@ -131,6 +136,7 @@ struct SynthEcp5Pass : public ScriptPass
vpr = false;
abc9 = false;
nodsp = false;
+ no_rw_check = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
@@ -221,6 +227,10 @@ struct SynthEcp5Pass : public ScriptPass
nodsp = true;
continue;
}
+ if (args[argidx] == "-no-rw-check") {
+ no_rw_check = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -241,6 +251,12 @@ struct SynthEcp5Pass : public ScriptPass
void script() override
{
+ std::string no_rw_check_opt = "";
+ if (no_rw_check)
+ no_rw_check_opt = " -no-rw-check";
+ if (help_mode)
+ no_rw_check_opt = " [-no-rw-check]";
+
if (check_label("begin"))
{
run("read_verilog -lib -specify +/ecp5/cells_sim.v +/ecp5/cells_bb.v");
@@ -273,28 +289,27 @@ struct SynthEcp5Pass : public ScriptPass
}
run("alumacc");
run("opt");
- run("memory -nomap");
+ run("memory -nomap" + no_rw_check_opt);
run("opt_clean");
}
- if (!nobram && check_label("map_bram", "(skip if -nobram)"))
+ if (check_label("map_ram"))
{
- run("memory_bram -rules +/ecp5/brams.txt");
- run("techmap -map +/ecp5/brams_map.v");
- }
-
- if (!nolutram && check_label("map_lutram", "(skip if -nolutram)"))
- {
- run("memory_bram -rules +/ecp5/lutrams.txt");
- run("techmap -map +/ecp5/lutrams_map.v");
+ std::string args = "";
+ if (nobram)
+ args += " -no-auto-block";
+ if (nolutram)
+ args += " -no-auto-distributed";
+ if (help_mode)
+ args += " [-no-auto-block] [-no-auto-distributed]";
+ run("memory_libmap -lib +/ecp5/lutrams.txt -lib +/ecp5/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)");
+ run("techmap -map +/ecp5/lutrams_map.v -map +/ecp5/brams_map.v");
}
if (check_label("map_ffram"))
{
run("opt -fast -mux_undef -undriven -fine");
- run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block "
- "-attr syn_ramstyle=auto -attr syn_ramstyle=registers "
- "-attr syn_romstyle=auto -attr syn_romstyle=logic");
+ run("memory_map");
run("opt -undriven -fine");
}
diff --git a/techlibs/efinix/brams.txt b/techlibs/efinix/brams.txt
index 0b3fd9308..271fc4fc4 100644
--- a/techlibs/efinix/brams.txt
+++ b/techlibs/efinix/brams.txt
@@ -1,32 +1,19 @@
-bram $__EFINIX_5K
- init 1
-
- abits 8 @a8d16
- dbits 16 @a8d16
- abits 9 @a9d8
- dbits 8 @a9d8
- abits 10 @a10d4
- dbits 4 @a10d4
- abits 11 @a11d2
- dbits 2 @a11d2
- abits 12 @a12d1
- dbits 1 @a12d1
- abits 8 @a8d20
- dbits 20 @a8d20
- abits 9 @a9d10
- dbits 10 @a9d10
-
- groups 2
- ports 1 1
- wrmode 1 0
- enable 1 1
- transp 0 2
- clocks 2 3
- clkpol 2 3
-endbram
-
-match $__EFINIX_5K
- min bits 256
- min efficiency 5
- shuffle_enable B
-endmatch
+ram block $__EFINIX_5K_ {
+ abits 12;
+ widths 1 2 5 10 20 per_port;
+ cost 32;
+ init no_undef;
+ port sr "R" {
+ clock anyedge;
+ rden;
+ }
+ port sw "W" {
+ clock anyedge;
+ option "WRITE_MODE" "READ_FIRST" {
+ wrtrans "R" old;
+ }
+ option "WRITE_MODE" "WRITE_FIRST" {
+ wrtrans "R" new;
+ }
+ }
+}
diff --git a/techlibs/efinix/brams_map.v b/techlibs/efinix/brams_map.v
index 6786ae769..752010f45 100644
--- a/techlibs/efinix/brams_map.v
+++ b/techlibs/efinix/brams_map.v
@@ -1,65 +1,149 @@
-module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 8;
- parameter CFG_DBITS = 20;
- parameter CFG_ENABLE_A = 1;
+module $__EFINIX_5K_ (...);
+ parameter INIT = 0;
+ parameter OPTION_WRITE_MODE = "READ_FIRST";
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
- parameter [5119:0] INIT = 5119'bx;
- parameter TRANSP2 = 0;
+ parameter PORT_R_WIDTH = 20;
+ parameter PORT_R_CLK_POL = 1;
+ parameter PORT_W_WIDTH = 20;
+ parameter PORT_W_CLK_POL = 1;
- input CLK2;
- input CLK3;
+ input PORT_R_CLK;
+ input PORT_R_RD_EN;
+ input [11:0] PORT_R_ADDR;
+ output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
- input [CFG_ABITS-1:0] A1ADDR;
- input [CFG_DBITS-1:0] A1DATA;
- input [CFG_ENABLE_A-1:0] A1EN;
+ input PORT_W_CLK;
+ input PORT_W_WR_EN;
+ input [11:0] PORT_W_ADDR;
+ input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
- input [CFG_ABITS-1:0] B1ADDR;
- output [CFG_DBITS-1:0] B1DATA;
- input B1EN;
+ localparam IS_5BIT = PORT_R_WIDTH >= 5 && PORT_W_WIDTH >= 5;
- localparam WRITEMODE_A = TRANSP2 ? "WRITE_FIRST" : "READ_FIRST";
+ localparam RADDR_WIDTH =
+ PORT_R_WIDTH == 1 ? 12 :
+ PORT_R_WIDTH == 2 ? 11 :
+ PORT_R_WIDTH == 5 ? 10 :
+ PORT_R_WIDTH == 10 ? 9 :
+ 8;
+
+ localparam WADDR_WIDTH =
+ PORT_W_WIDTH == 1 ? 12 :
+ PORT_W_WIDTH == 2 ? 11 :
+ PORT_W_WIDTH == 5 ? 10 :
+ PORT_W_WIDTH == 10 ? 9 :
+ 8;
+
+ localparam READ_WIDTH =
+ PORT_R_WIDTH == 1 ? 1 :
+ PORT_R_WIDTH == 2 ? 2 :
+ PORT_R_WIDTH == 5 ? (IS_5BIT ? 5 : 4) :
+ PORT_R_WIDTH == 10 ? (IS_5BIT ? 10 : 8) :
+ (IS_5BIT ? 20 : 16);
+
+ localparam WRITE_WIDTH =
+ PORT_W_WIDTH == 1 ? 1 :
+ PORT_W_WIDTH == 2 ? 2 :
+ PORT_W_WIDTH == 5 ? (IS_5BIT ? 5 : 4) :
+ PORT_W_WIDTH == 10 ? (IS_5BIT ? 10 : 8) :
+ (IS_5BIT ? 20 : 16);
+
+ wire [RADDR_WIDTH-1:0] RADDR = PORT_R_ADDR[11:12-RADDR_WIDTH];
+ wire [WADDR_WIDTH-1:0] WADDR = PORT_W_ADDR[11:12-WADDR_WIDTH];
+
+ wire [WRITE_WIDTH-1:0] WDATA;
+ wire [READ_WIDTH-1:0] RDATA;
+
+ generate
+ case (WRITE_WIDTH)
+ 1: assign WDATA = PORT_W_WR_DATA;
+ 2: assign WDATA = PORT_W_WR_DATA;
+ 4: assign WDATA = PORT_W_WR_DATA[3:0];
+ 5: assign WDATA = PORT_W_WR_DATA;
+ 8: assign WDATA = {
+ PORT_W_WR_DATA[8:5],
+ PORT_W_WR_DATA[3:0]
+ };
+ 10: assign WDATA = PORT_W_WR_DATA;
+ 16: assign WDATA = {
+ PORT_W_WR_DATA[18:15],
+ PORT_W_WR_DATA[13:10],
+ PORT_W_WR_DATA[8:5],
+ PORT_W_WR_DATA[3:0]
+ };
+ 20: assign WDATA = PORT_W_WR_DATA;
+ endcase
+ case (READ_WIDTH)
+ 1: assign PORT_R_RD_DATA = RDATA;
+ 2: assign PORT_R_RD_DATA = RDATA;
+ 4: assign PORT_R_RD_DATA[3:0] = RDATA;
+ 5: assign PORT_R_RD_DATA = RDATA;
+ 8: assign {
+ PORT_R_RD_DATA[8:5],
+ PORT_R_RD_DATA[3:0]
+ } = RDATA;
+ 10: assign PORT_R_RD_DATA = RDATA;
+ 16: assign {
+ PORT_R_RD_DATA[18:15],
+ PORT_R_RD_DATA[13:10],
+ PORT_R_RD_DATA[8:5],
+ PORT_R_RD_DATA[3:0]
+ } = RDATA;
+ 20: assign PORT_R_RD_DATA = RDATA;
+ endcase
+ endgenerate
+
+ function [255:0] init_slice;
+ input integer idx;
+ integer i;
+ if (IS_5BIT)
+ init_slice = INIT[idx * 256 +: 256];
+ else if (idx > 16)
+ init_slice = 0;
+ else
+ for (i = 0; i < 64; i = i + 1)
+ init_slice[i*4+:4] = INIT[(idx * 64 + i) * 5+:4];
+ endfunction
EFX_RAM_5K #(
- .READ_WIDTH(CFG_DBITS),
- .WRITE_WIDTH(CFG_DBITS),
- .OUTPUT_REG(1'b0),
- .RCLK_POLARITY(1'b1),
- .RE_POLARITY(1'b1),
- .WCLK_POLARITY(1'b1),
- .WE_POLARITY(1'b1),
- .WCLKE_POLARITY(1'b1),
- .WRITE_MODE(WRITEMODE_A),
- .INIT_0(INIT[ 0*256 +: 256]),
- .INIT_1(INIT[ 1*256 +: 256]),
- .INIT_2(INIT[ 2*256 +: 256]),
- .INIT_3(INIT[ 3*256 +: 256]),
- .INIT_4(INIT[ 4*256 +: 256]),
- .INIT_5(INIT[ 5*256 +: 256]),
- .INIT_6(INIT[ 6*256 +: 256]),
- .INIT_7(INIT[ 7*256 +: 256]),
- .INIT_8(INIT[ 8*256 +: 256]),
- .INIT_9(INIT[ 9*256 +: 256]),
- .INIT_A(INIT[10*256 +: 256]),
- .INIT_B(INIT[11*256 +: 256]),
- .INIT_C(INIT[12*256 +: 256]),
- .INIT_D(INIT[13*256 +: 256]),
- .INIT_E(INIT[14*256 +: 256]),
- .INIT_F(INIT[15*256 +: 256]),
- .INIT_10(INIT[16*256 +: 256]),
- .INIT_11(INIT[17*256 +: 256]),
- .INIT_12(INIT[18*256 +: 256]),
- .INIT_13(INIT[19*256 +: 256])
+ .READ_WIDTH(READ_WIDTH),
+ .WRITE_WIDTH(WRITE_WIDTH),
+ .OUTPUT_REG(1'b0),
+ .RCLK_POLARITY(PORT_R_CLK_POL),
+ .RE_POLARITY(1'b1),
+ .WCLK_POLARITY(PORT_W_CLK_POL),
+ .WE_POLARITY(1'b1),
+ .WCLKE_POLARITY(1'b1),
+ .WRITE_MODE(OPTION_WRITE_MODE),
+ .INIT_0(init_slice('h00)),
+ .INIT_1(init_slice('h01)),
+ .INIT_2(init_slice('h02)),
+ .INIT_3(init_slice('h03)),
+ .INIT_4(init_slice('h04)),
+ .INIT_5(init_slice('h05)),
+ .INIT_6(init_slice('h06)),
+ .INIT_7(init_slice('h07)),
+ .INIT_8(init_slice('h08)),
+ .INIT_9(init_slice('h09)),
+ .INIT_A(init_slice('h0a)),
+ .INIT_B(init_slice('h0b)),
+ .INIT_C(init_slice('h0c)),
+ .INIT_D(init_slice('h0d)),
+ .INIT_E(init_slice('h0e)),
+ .INIT_F(init_slice('h0f)),
+ .INIT_10(init_slice('h10)),
+ .INIT_11(init_slice('h11)),
+ .INIT_12(init_slice('h12)),
+ .INIT_13(init_slice('h13)),
) _TECHMAP_REPLACE_ (
- .WDATA(A1DATA),
- .WADDR(A1ADDR),
- .WE(A1EN),
- .WCLK(CLK2),
- .WCLKE(1'b1),
- .RDATA(B1DATA),
- .RADDR(B1ADDR),
- .RE(B1EN),
- .RCLK(CLK3)
+ .WDATA(WDATA),
+ .WADDR(WADDR),
+ .WE(PORT_W_WR_EN),
+ .WCLK(PORT_W_CLK),
+ .WCLKE(1'b1),
+ .RDATA(RDATA),
+ .RADDR(RADDR),
+ .RE(PORT_R_RD_EN),
+ .RCLK(PORT_R_CLK)
);
+
endmodule
diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc
index ace56bee9..bbc389444 100644
--- a/techlibs/efinix/synth_efinix.cc
+++ b/techlibs/efinix/synth_efinix.cc
@@ -158,11 +158,13 @@ struct SynthEfinixPass : public ScriptPass
run("synth -run coarse");
}
- if (!nobram || check_label("map_bram", "(skip if -nobram)"))
+ if (check_label("map_ram"))
{
- run("memory_bram -rules +/efinix/brams.txt");
+ std::string args = "";
+ if (nobram)
+ args += " -no-auto-block";
+ run("memory_libmap -lib +/efinix/brams.txt" + args);
run("techmap -map +/efinix/brams_map.v");
- run("setundef -zero -params t:EFX_RAM_5K");
}
if (check_label("map_ffram"))
diff --git a/techlibs/gatemate/.gitignore b/techlibs/gatemate/.gitignore
new file mode 100644
index 000000000..f260d6e9d
--- /dev/null
+++ b/techlibs/gatemate/.gitignore
@@ -0,0 +1,4 @@
+lut_tree_cells.genlib
+lut_tree_map.v
+lut_tree_lib.mk
+
diff --git a/techlibs/gatemate/Makefile.inc b/techlibs/gatemate/Makefile.inc
index d1341d7bb..aeb318cc9 100644
--- a/techlibs/gatemate/Makefile.inc
+++ b/techlibs/gatemate/Makefile.inc
@@ -1,5 +1,6 @@
OBJS += techlibs/gatemate/synth_gatemate.o
+OBJS += techlibs/gatemate/gatemate_foldinv.o
$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/reg_map.v))
$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/mux_map.v))
@@ -12,3 +13,18 @@ $(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams_map.v))
$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams.txt))
$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams_init_20.vh))
$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams_init_40.vh))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/inv_map.v))
+
+EXTRA_OBJS += techlibs/gatemate/lut_tree_lib.mk
+.SECONDARY: techlibs/gatemate/lut_tree_lib.mk
+
+techlibs/gatemate/lut_tree_lib.mk: techlibs/gatemate/make_lut_tree_lib.py
+ $(Q) mkdir -p techlibs/gatemate
+ $(P) $(PYTHON_EXECUTABLE) $<
+ $(Q) touch $@
+
+techlibs/gatemate/lut_tree_cells.genlib: techlibs/gatemate/lut_tree_lib.mk
+techlibs/gatemate/lut_tree_map.v: techlibs/gatemate/lut_tree_lib.mk
+
+$(eval $(call add_gen_share_file,share/gatemate,techlibs/gatemate/lut_tree_cells.genlib))
+$(eval $(call add_gen_share_file,share/gatemate,techlibs/gatemate/lut_tree_map.v))
diff --git a/techlibs/gatemate/brams.txt b/techlibs/gatemate/brams.txt
index 9e0bebba6..be22856ac 100644
--- a/techlibs/gatemate/brams.txt
+++ b/techlibs/gatemate/brams.txt
@@ -1,280 +1,80 @@
-bram $__CC_BRAM_CASCADE
- init 1
- abits 16 @a16d1
- dbits 1 @a16d1
- groups 2
- ports 1 1
- wrmode 1 0
- enable 1 1 @a16d1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-bram $__CC_BRAM_40K_SDP
- init 1
- abits 9 @a9d80
- dbits 80 @a9d80
- groups 2
- ports 1 1
- wrmode 1 0
- enable 80 1 @a9d80
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-bram $__CC_BRAM_20K_SDP
- init 1
- abits 9 @a9d40
- dbits 40 @a9d40
- groups 2
- ports 1 1
- wrmode 1 0
- enable 40 1 @a9d40
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-bram $__CC_BRAM_40K_TDP
- init 1
- abits 10 @a10d40
- dbits 40 @a10d40
- abits 11 @a11d20
- dbits 20 @a11d20
- abits 12 @a12d10
- dbits 10 @a12d10
- abits 13 @a13d5
- dbits 5 @a13d5
- abits 14 @a14d2
- dbits 2 @a14d2
- abits 15 @a15d1
- dbits 1 @a15d1
- groups 2
- ports 1 1
- wrmode 1 0
- enable 40 1 @a10d40
- enable 20 1 @a11d20
- enable 10 1 @a12d10
- enable 5 1 @a13d5
- enable 2 1 @a14d2
- enable 1 1 @a15d1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-bram $__CC_BRAM_20K_TDP
- init 1
- abits 10 @a10d20
- dbits 20 @a10d20
- abits 11 @a11d10
- dbits 10 @a11d10
- abits 12 @a12d5
- dbits 5 @a12d5
- abits 13 @a13d2
- dbits 2 @a13d2
- abits 14 @a14d1
- dbits 1 @a14d1
- groups 2
- ports 1 1
- wrmode 1 0
- enable 20 1 @a10d20
- enable 10 1 @a11d10
- enable 5 1 @a12d5
- enable 2 1 @a13d2
- enable 1 1 @a14d1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-match $__CC_BRAM_CASCADE
- # implicitly requested RAM or ROM
- attribute !syn_ramstyle syn_ramstyle=auto
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- min bits 512
- min efficiency 5
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_CASCADE
- # explicitly requested RAM
- attribute syn_ramstyle=block_ram ram_block
- attribute !syn_romstyle
- attribute !rom_block
- attribute !logic_block
- min wports 1
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_CASCADE
- # explicitly requested ROM
- attribute syn_romstyle=ebr rom_block
- attribute !syn_ramstyle
- attribute !ram_block
- attribute !logic_block
- max wports 0
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_40K_SDP
- # implicitly requested RAM or ROM
- attribute !syn_ramstyle syn_ramstyle=auto
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- min bits 512
- min efficiency 5
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_40K_SDP
- # explicitly requested RAM
- attribute syn_ramstyle=block_ram ram_block
- attribute !syn_romstyle
- attribute !rom_block
- attribute !logic_block
- min wports 1
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_40K_SDP
- # explicitly requested ROM
- attribute syn_romstyle=ebr rom_block
- attribute !syn_ramstyle
- attribute !ram_block
- attribute !logic_block
- max wports 0
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_20K_SDP
- # implicitly requested RAM or ROM
- attribute !syn_ramstyle syn_ramstyle=auto
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- min bits 512
- min efficiency 5
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_20K_SDP
- # explicitly requested RAM
- attribute syn_ramstyle=block_ram ram_block
- attribute !syn_romstyle
- attribute !rom_block
- attribute !logic_block
- min wports 1
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_20K_SDP
- # explicitly requested ROM
- attribute syn_romstyle=ebr rom_block
- attribute !syn_ramstyle
- attribute !ram_block
- attribute !logic_block
- max wports 0
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_40K_TDP
- # implicitly requested RAM or ROM
- attribute !syn_ramstyle syn_ramstyle=auto
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- min bits 512
- min efficiency 5
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_40K_TDP
- # explicitly requested RAM
- attribute syn_ramstyle=block_ram ram_block
- attribute !syn_romstyle
- attribute !rom_block
- attribute !logic_block
- min wports 1
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_40K_TDP
- # explicitly requested ROM
- attribute syn_romstyle=ebr rom_block
- attribute !syn_ramstyle
- attribute !ram_block
- attribute !logic_block
- max wports 0
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_20K_TDP
- # implicitly requested RAM or ROM
- attribute !syn_ramstyle syn_ramstyle=auto
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- min bits 512
- min efficiency 5
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_20K_TDP
- # explicitly requested RAM
- attribute syn_ramstyle=block_ram ram_block
- attribute !syn_romstyle
- attribute !rom_block
- attribute !logic_block
- min wports 1
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__CC_BRAM_20K_TDP
- # explicitly requested ROM
- attribute syn_romstyle=ebr rom_block
- attribute !syn_ramstyle
- attribute !ram_block
- attribute !logic_block
- max wports 0
- shuffle_enable A
- make_transp
-endmatch
+ram block $__CC_BRAM_TDP_ {
+ option "MODE" "20K" {
+ abits 14;
+ widths 1 2 5 10 20 per_port;
+ cost 129;
+ }
+ option "MODE" "40K" {
+ abits 15;
+ widths 1 2 5 10 20 40 per_port;
+ cost 257;
+ }
+ option "MODE" "CASCADE" {
+ abits 16;
+ # hack to enforce same INIT layout as in the other modes
+ widths 1 2 5 per_port;
+ cost 513;
+ }
+ byte 1;
+ init no_undef;
+ port srsw "A" "B" {
+ clock anyedge;
+ clken;
+ option "MODE" "20K" {
+ width mix;
+ }
+ option "MODE" "40K" {
+ width mix;
+ }
+ option "MODE" "CASCADE" {
+ width mix 1;
+ }
+ portoption "WR_MODE" "NO_CHANGE" {
+ rdwr no_change;
+ }
+ portoption "WR_MODE" "WRITE_THROUGH" {
+ rdwr new;
+ wrtrans all new;
+ }
+ wrbe_separate;
+ optional_rw;
+ }
+}
+
+ram block $__CC_BRAM_SDP_ {
+ option "MODE" "20K" {
+ abits 14;
+ widths 1 2 5 10 20 40 per_port;
+ cost 129;
+ }
+ option "MODE" "40K" {
+ abits 15;
+ widths 1 2 5 10 20 40 80 per_port;
+ cost 257;
+ }
+ byte 1;
+ init no_undef;
+ port sr "R" {
+ option "MODE" "20K" {
+ width 40;
+ }
+ option "MODE" "40K" {
+ width 80;
+ }
+ clock anyedge;
+ clken;
+ optional;
+ }
+ port sw "W" {
+ option "MODE" "20K" {
+ width 40;
+ }
+ option "MODE" "40K" {
+ width 80;
+ }
+ clock anyedge;
+ clken;
+ wrbe_separate;
+ optional;
+ }
+}
diff --git a/techlibs/gatemate/brams_map.v b/techlibs/gatemate/brams_map.v
index f36f05212..171825f49 100644
--- a/techlibs/gatemate/brams_map.v
+++ b/techlibs/gatemate/brams_map.v
@@ -1,520 +1,882 @@
-/*
- * yosys -- Yosys Open SYnthesis Suite
- *
- * Copyright (C) 2021 Cologne Chip AG <support@colognechip.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-module \$__CC_BRAM_20K_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
-
- parameter CFG_ABITS = 14;
- parameter CFG_DBITS = 40;
- parameter CFG_ENABLE_A = 1;
- parameter CFG_ENABLE_B = 1;
-
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
-
- // 512 x 40 bit
- parameter [20479:0] INIT = 20480'b0;
-
- input CLK2;
- input CLK3;
-
- // write side of the memory
- input [15:0] A1ADDR;
- input [39:0] A1DATA;
- input [39:0] A1EN;
-
- // read side of the memory
- input [15:0] B1ADDR;
- output [39:0] B1DATA;
- input [0:0] B1EN;
-
- // unconnected signals
- wire ECC_1B_ERR, ECC_2B_ERR;
-
- // internal signals
- wire [15:0] ADDRA = {A1ADDR, 7'b0};
- wire [15:0] ADDRB = {B1ADDR, 7'b0};
-
- localparam INIT_CHUNK_SIZE = 320;
-
- function [319:0] permute_init;
- input [INIT_CHUNK_SIZE-1:0] chunk;
- integer i;
- begin
- permute_init = chunk;
- end
- endfunction
-
- CC_BRAM_20K #(
- `include "brams_init_20.vh"
- .LOC("UNPLACED"),
- .A_RD_WIDTH(0), .B_RD_WIDTH(CFG_DBITS),
- .A_WR_WIDTH(CFG_DBITS), .B_WR_WIDTH(0),
- .RAM_MODE("SDP"),
- .A_WR_MODE("NO_CHANGE"), .B_WR_MODE("NO_CHANGE"),
- .A_CLK_INV(!CLKPOL2), .B_CLK_INV(!CLKPOL3),
- .A_EN_INV(1'b0), .B_EN_INV(1'b0),
- .A_WE_INV(1'b0), .B_WE_INV(1'b0),
- .A_DO_REG(1'b0), .B_DO_REG(1'b0),
- .ECC_EN(1'b0)
- ) _TECHMAP_REPLACE_ (
- .A_DO(B1DATA[19:0]),
- .B_DO(B1DATA[39:20]),
- .ECC_1B_ERR(ECC_1B_ERR),
- .ECC_2B_ERR(ECC_2B_ERR),
- .A_CLK(CLK2),
- .B_CLK(CLK3),
- .A_EN(1'b1),
- .B_EN(B1EN),
- .A_WE(|A1EN),
- .B_WE(1'b0),
- .A_ADDR(ADDRA),
- .B_ADDR(ADDRB),
- .A_DI(A1DATA[19:0]),
- .B_DI(A1DATA[39:20]),
- .A_BM(A1EN[19:0]),
- .B_BM(A1EN[39:20])
- );
-
-endmodule
-
-
-module \$__CC_BRAM_40K_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
-
- parameter CFG_ABITS = 15;
- parameter CFG_DBITS = 80;
- parameter CFG_ENABLE_A = 1;
- parameter CFG_ENABLE_B = 1;
-
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
-
- // 512 x 80 bit
- parameter [40959:0] INIT = 40960'b0;
-
- input CLK2;
- input CLK3;
-
- // write side of the memory
- input [15:0] A1ADDR;
- input [79:0] A1DATA;
- input [79:0] A1EN;
-
- // read side of the memory
- input [15:0] B1ADDR;
- output [79:0] B1DATA;
- input [0:0] B1EN;
-
- // unconnected signals
- wire A_ECC_1B_ERR, B_ECC_1B_ERR, A_ECC_2B_ERR, B_ECC_2B_ERR;
-
- // internal signals
- wire [15:0] ADDRA = {A1ADDR, 7'b0};
- wire [15:0] ADDRB = {B1ADDR, 7'b0};
-
- localparam INIT_CHUNK_SIZE = 320;
-
- function [319:0] permute_init;
- input [INIT_CHUNK_SIZE-1:0] chunk;
- integer i;
- begin
- permute_init = chunk;
- end
- endfunction
-
- CC_BRAM_40K #(
- `define INIT_LOWER
- `include "brams_init_40.vh"
- `undef INIT_LOWER
- .LOC("UNPLACED"),
- .CAS("NONE"),
- .A_RD_WIDTH(0), .B_RD_WIDTH(CFG_DBITS),
- .A_WR_WIDTH(CFG_DBITS), .B_WR_WIDTH(0),
- .RAM_MODE("SDP"),
- .A_WR_MODE("NO_CHANGE"), .B_WR_MODE("NO_CHANGE"),
- .A_CLK_INV(!CLKPOL2), .B_CLK_INV(!CLKPOL3),
- .A_EN_INV(1'b0), .B_EN_INV(1'b0),
- .A_WE_INV(1'b0), .B_WE_INV(1'b0),
- .A_DO_REG(1'b0), .B_DO_REG(1'b0),
- .A_ECC_EN(1'b0), .B_ECC_EN(1'b0)
- ) _TECHMAP_REPLACE_ (
- .A_DO(B1DATA[39:0]),
- .B_DO(B1DATA[79:40]),
- .A_ECC_1B_ERR(A_ECC_1B_ERR),
- .B_ECC_1B_ERR(B_ECC_1B_ERR),
- .A_ECC_2B_ERR(A_ECC_2B_ERR),
- .B_ECC_2B_ERR(B_ECC_2B_ERR),
- .A_CLK(CLK2),
- .B_CLK(CLK3),
- .A_EN(1'b1),
- .B_EN(B1EN),
- .A_WE(|A1EN),
- .B_WE(1'b0),
- .A_ADDR(ADDRA),
- .B_ADDR(ADDRB),
- .A_DI(A1DATA[39:0]),
- .B_DI(A1DATA[79:40]),
- .A_BM(A1EN[39:0]),
- .B_BM(A1EN[79:40])
- );
-
-endmodule
-
-
-module \$__CC_BRAM_20K_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
-
- parameter CFG_ABITS = 14;
- parameter CFG_DBITS = 20;
- parameter CFG_ENABLE_A = 1;
- parameter CFG_ENABLE_B = 1;
-
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
-
- // 512 x 40 bit
- parameter [20479:0] INIT = 20480'b0;
-
- input CLK2;
- input CLK3;
-
- // write side of the memory
- input [15:0] A1ADDR;
- input [19:0] A1DATA;
- input [19:0] A1EN;
-
- // read side of the memory
- input [15:0] B1ADDR;
- output [19:0] B1DATA;
- input [0:0] B1EN;
-
- // unconnected signals
- wire [19:0] A_DO;
- wire ECC_1B_ERR, ECC_2B_ERR;
-
- localparam INIT_CHUNK_SIZE = (CFG_DBITS <= 2) ? 256 : 320;
-
- function [319:0] permute_init;
- input [INIT_CHUNK_SIZE-1:0] chunk;
- integer i;
- begin
- if (CFG_DBITS <= 2) begin
- for (i = 0; i < 64; i = i + 1) begin
- permute_init[i * 5 +: 5] = {1'b0, chunk[i * 4 +: 4]};
- end
- end else begin
- permute_init = chunk;
- end
- end
- endfunction
-
- // internal signals
- generate
- wire [15:0] ADDRA;
- wire [15:0] ADDRB;
-
- if (CFG_DBITS == 1) begin: blk
- assign ADDRA = {A1ADDR[13:5], 1'b0, A1ADDR[4:0], 1'b0};
- assign ADDRB = {B1ADDR[13:5], 1'b0, B1ADDR[4:0], 1'b0};
- end
- else if (CFG_DBITS == 2) begin: blk
- assign ADDRA = {A1ADDR[12:4], 1'b0, A1ADDR[3:0], 2'b0};
- assign ADDRB = {B1ADDR[12:4], 1'b0, B1ADDR[3:0], 2'b0};
- end
- else if (CFG_DBITS == 5) begin: blk
- assign ADDRA = {A1ADDR[11:3], 1'b0, A1ADDR[2:0], 3'b0};
- assign ADDRB = {B1ADDR[11:3], 1'b0, B1ADDR[2:0], 3'b0};
- end
- else if (CFG_DBITS == 10) begin: blk
- assign ADDRA = {A1ADDR[10:2], 1'b0, A1ADDR[1:0], 4'b0};
- assign ADDRB = {B1ADDR[10:2], 1'b0, B1ADDR[1:0], 4'b0};
- end
- else if (CFG_DBITS == 20) begin: blk
- assign ADDRA = {A1ADDR[9:1], 1'b0, A1ADDR[0], 5'b0};
- assign ADDRB = {B1ADDR[9:1], 1'b0, B1ADDR[0], 5'b0};
- end
-
+module $__CC_BRAM_TDP_(...);
+
+parameter INIT = 0;
+parameter OPTION_MODE = "20K";
+
+parameter PORT_A_CLK_POL = 1;
+parameter PORT_A_RD_USED = 1;
+parameter PORT_A_WR_USED = 1;
+parameter PORT_A_RD_WIDTH = 1;
+parameter PORT_A_WR_WIDTH = 1;
+parameter PORT_A_WR_BE_WIDTH = 1;
+parameter PORT_A_OPTION_WR_MODE = "NO_CHANGE";
+
+parameter PORT_B_CLK_POL = 1;
+parameter PORT_B_RD_USED = 1;
+parameter PORT_B_WR_USED = 1;
+parameter PORT_B_RD_WIDTH = 1;
+parameter PORT_B_WR_WIDTH = 1;
+parameter PORT_B_WR_BE_WIDTH = 1;
+parameter PORT_B_OPTION_WR_MODE = "NO_CHANGE";
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input PORT_A_WR_EN;
+input [15:0] PORT_A_ADDR;
+input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE;
+input [PORT_A_WR_WIDTH-1:0] PORT_A_WR_DATA;
+output [PORT_A_RD_WIDTH-1:0] PORT_A_RD_DATA;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input PORT_B_WR_EN;
+input [15:0] PORT_B_ADDR;
+input [PORT_B_WR_BE_WIDTH-1:0] PORT_B_WR_BE;
+input [PORT_B_WR_WIDTH-1:0] PORT_B_WR_DATA;
+output [PORT_B_RD_WIDTH-1:0] PORT_B_RD_DATA;
+
+generate
+ if (OPTION_MODE == "20K") begin
CC_BRAM_20K #(
- `include "brams_init_20.vh"
- .LOC("UNPLACED"),
- .A_RD_WIDTH(0), .B_RD_WIDTH(CFG_DBITS),
- .A_WR_WIDTH(CFG_DBITS), .B_WR_WIDTH(0),
+ .INIT_00(INIT['h00*320+:320]),
+ .INIT_01(INIT['h01*320+:320]),
+ .INIT_02(INIT['h02*320+:320]),
+ .INIT_03(INIT['h03*320+:320]),
+ .INIT_04(INIT['h04*320+:320]),
+ .INIT_05(INIT['h05*320+:320]),
+ .INIT_06(INIT['h06*320+:320]),
+ .INIT_07(INIT['h07*320+:320]),
+ .INIT_08(INIT['h08*320+:320]),
+ .INIT_09(INIT['h09*320+:320]),
+ .INIT_0A(INIT['h0a*320+:320]),
+ .INIT_0B(INIT['h0b*320+:320]),
+ .INIT_0C(INIT['h0c*320+:320]),
+ .INIT_0D(INIT['h0d*320+:320]),
+ .INIT_0E(INIT['h0e*320+:320]),
+ .INIT_0F(INIT['h0f*320+:320]),
+ .INIT_10(INIT['h10*320+:320]),
+ .INIT_11(INIT['h11*320+:320]),
+ .INIT_12(INIT['h12*320+:320]),
+ .INIT_13(INIT['h13*320+:320]),
+ .INIT_14(INIT['h14*320+:320]),
+ .INIT_15(INIT['h15*320+:320]),
+ .INIT_16(INIT['h16*320+:320]),
+ .INIT_17(INIT['h17*320+:320]),
+ .INIT_18(INIT['h18*320+:320]),
+ .INIT_19(INIT['h19*320+:320]),
+ .INIT_1A(INIT['h1a*320+:320]),
+ .INIT_1B(INIT['h1b*320+:320]),
+ .INIT_1C(INIT['h1c*320+:320]),
+ .INIT_1D(INIT['h1d*320+:320]),
+ .INIT_1E(INIT['h1e*320+:320]),
+ .INIT_1F(INIT['h1f*320+:320]),
+ .INIT_20(INIT['h20*320+:320]),
+ .INIT_21(INIT['h21*320+:320]),
+ .INIT_22(INIT['h22*320+:320]),
+ .INIT_23(INIT['h23*320+:320]),
+ .INIT_24(INIT['h24*320+:320]),
+ .INIT_25(INIT['h25*320+:320]),
+ .INIT_26(INIT['h26*320+:320]),
+ .INIT_27(INIT['h27*320+:320]),
+ .INIT_28(INIT['h28*320+:320]),
+ .INIT_29(INIT['h29*320+:320]),
+ .INIT_2A(INIT['h2a*320+:320]),
+ .INIT_2B(INIT['h2b*320+:320]),
+ .INIT_2C(INIT['h2c*320+:320]),
+ .INIT_2D(INIT['h2d*320+:320]),
+ .INIT_2E(INIT['h2e*320+:320]),
+ .INIT_2F(INIT['h2f*320+:320]),
+ .INIT_30(INIT['h30*320+:320]),
+ .INIT_31(INIT['h31*320+:320]),
+ .INIT_32(INIT['h32*320+:320]),
+ .INIT_33(INIT['h33*320+:320]),
+ .INIT_34(INIT['h34*320+:320]),
+ .INIT_35(INIT['h35*320+:320]),
+ .INIT_36(INIT['h36*320+:320]),
+ .INIT_37(INIT['h37*320+:320]),
+ .INIT_38(INIT['h38*320+:320]),
+ .INIT_39(INIT['h39*320+:320]),
+ .INIT_3A(INIT['h3a*320+:320]),
+ .INIT_3B(INIT['h3b*320+:320]),
+ .INIT_3C(INIT['h3c*320+:320]),
+ .INIT_3D(INIT['h3d*320+:320]),
+ .INIT_3E(INIT['h3e*320+:320]),
+ .INIT_3F(INIT['h3f*320+:320]),
+ .A_RD_WIDTH(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0),
+ .A_WR_WIDTH(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0),
+ .B_RD_WIDTH(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0),
+ .B_WR_WIDTH(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0),
.RAM_MODE("TDP"),
- .A_WR_MODE("NO_CHANGE"), .B_WR_MODE("NO_CHANGE"),
- .A_CLK_INV(!CLKPOL2), .B_CLK_INV(!CLKPOL3),
- .A_EN_INV(1'b0), .B_EN_INV(1'b0),
- .A_WE_INV(1'b0), .B_WE_INV(1'b0),
- .A_DO_REG(1'b0), .B_DO_REG(1'b0),
- .ECC_EN(1'b0)
+ .A_WR_MODE(PORT_A_OPTION_WR_MODE),
+ .B_WR_MODE(PORT_B_OPTION_WR_MODE),
+ .A_CLK_INV(!PORT_A_CLK_POL),
+ .B_CLK_INV(!PORT_B_CLK_POL),
) _TECHMAP_REPLACE_ (
- .A_DO(A_DO),
- .B_DO(B1DATA),
- .ECC_1B_ERR(ECC_1B_ERR),
- .ECC_2B_ERR(ECC_2B_ERR),
- .A_CLK(CLK2),
- .B_CLK(CLK3),
- .A_EN(1'b1),
- .B_EN(B1EN),
- .A_WE(|A1EN),
- .B_WE(1'b0),
- .A_ADDR(ADDRA),
- .B_ADDR(ADDRB),
- .A_DI(A1DATA),
- .B_DI(20'b0),
- .A_BM(A1EN),
- .B_BM(20'b0)
+ .A_CLK(PORT_A_CLK),
+ .A_EN(PORT_A_CLK_EN),
+ .A_WE(PORT_A_WR_EN),
+ .A_BM(PORT_A_WR_BE),
+ .A_DI(PORT_A_WR_DATA),
+ .A_ADDR({PORT_A_ADDR[13:5], 1'b0, PORT_A_ADDR[4:0], 1'b0}),
+ .A_DO(PORT_A_RD_DATA),
+ .B_CLK(PORT_B_CLK),
+ .B_EN(PORT_B_CLK_EN),
+ .B_WE(PORT_B_WR_EN),
+ .B_BM(PORT_B_WR_BE),
+ .B_DI(PORT_B_WR_DATA),
+ .B_ADDR({PORT_B_ADDR[13:5], 1'b0, PORT_B_ADDR[4:0], 1'b0}),
+ .B_DO(PORT_B_RD_DATA),
);
- endgenerate
-
-endmodule
-
-
-module \$__CC_BRAM_40K_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
-
- parameter CFG_ABITS = 15;
- parameter CFG_DBITS = 40;
- parameter CFG_ENABLE_A = 1;
- parameter CFG_ENABLE_B = 1;
-
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
-
- // 512 x 80 bit
- parameter [40959:0] INIT = 40960'b0;
-
- input CLK2;
- input CLK3;
-
- // write side of the memory
- input [15:0] A1ADDR;
- input [39:0] A1DATA;
- input [39:0] A1EN;
-
- // read side of the memory
- input [15:0] B1ADDR;
- output [39:0] B1DATA;
- input [0:0] B1EN;
-
- // unconnected signals
- wire [39:0] A_DO;
- wire A_ECC_1B_ERR, B_ECC_1B_ERR, A_ECC_2B_ERR, B_ECC_2B_ERR;
-
- localparam INIT_CHUNK_SIZE = (CFG_DBITS <= 2) ? 256 : 320;
-
- function [319:0] permute_init;
- input [INIT_CHUNK_SIZE-1:0] chunk;
- integer i;
- begin
- if (CFG_DBITS <= 2) begin
- for (i = 0; i < 64; i = i + 1) begin
- permute_init[i * 5 +: 5] = {1'b0, chunk[i * 4 +: 4]};
- end
- end else begin
- permute_init = chunk;
- end
- end
- endfunction
-
- generate
- wire [15:0] ADDRA;
- wire [15:0] ADDRB;
-
- if (CFG_DBITS == 1) begin
- assign ADDRA = {A1ADDR, 1'b0};
- assign ADDRB = {B1ADDR, 1'b0};
- end
- else if (CFG_DBITS == 2) begin
- assign ADDRA = {A1ADDR, 2'b0};
- assign ADDRB = {B1ADDR, 2'b0};
- end
- else if (CFG_DBITS == 5) begin
- assign ADDRA = {A1ADDR, 3'b0};
- assign ADDRB = {B1ADDR, 3'b0};
- end
- else if (CFG_DBITS == 10) begin
- assign ADDRA = {A1ADDR, 4'b0};
- assign ADDRB = {B1ADDR, 4'b0};
- end
- else if (CFG_DBITS == 20) begin
- assign ADDRA = {A1ADDR, 5'b0};
- assign ADDRB = {B1ADDR, 5'b0};
- end
- else if (CFG_DBITS == 40) begin
- assign ADDRA = {A1ADDR, 6'b0};
- assign ADDRB = {B1ADDR, 6'b0};
- end
-
+ end else if (OPTION_MODE == "40K") begin
CC_BRAM_40K #(
- `define INIT_LOWER
- `include "brams_init_40.vh"
- `undef INIT_LOWER
- .LOC("UNPLACED"),
- .CAS("NONE"),
- .A_RD_WIDTH(0), .B_RD_WIDTH(CFG_DBITS),
- .A_WR_WIDTH(CFG_DBITS), .B_WR_WIDTH(0),
+ .INIT_00(INIT['h00*320+:320]),
+ .INIT_01(INIT['h01*320+:320]),
+ .INIT_02(INIT['h02*320+:320]),
+ .INIT_03(INIT['h03*320+:320]),
+ .INIT_04(INIT['h04*320+:320]),
+ .INIT_05(INIT['h05*320+:320]),
+ .INIT_06(INIT['h06*320+:320]),
+ .INIT_07(INIT['h07*320+:320]),
+ .INIT_08(INIT['h08*320+:320]),
+ .INIT_09(INIT['h09*320+:320]),
+ .INIT_0A(INIT['h0a*320+:320]),
+ .INIT_0B(INIT['h0b*320+:320]),
+ .INIT_0C(INIT['h0c*320+:320]),
+ .INIT_0D(INIT['h0d*320+:320]),
+ .INIT_0E(INIT['h0e*320+:320]),
+ .INIT_0F(INIT['h0f*320+:320]),
+ .INIT_10(INIT['h10*320+:320]),
+ .INIT_11(INIT['h11*320+:320]),
+ .INIT_12(INIT['h12*320+:320]),
+ .INIT_13(INIT['h13*320+:320]),
+ .INIT_14(INIT['h14*320+:320]),
+ .INIT_15(INIT['h15*320+:320]),
+ .INIT_16(INIT['h16*320+:320]),
+ .INIT_17(INIT['h17*320+:320]),
+ .INIT_18(INIT['h18*320+:320]),
+ .INIT_19(INIT['h19*320+:320]),
+ .INIT_1A(INIT['h1a*320+:320]),
+ .INIT_1B(INIT['h1b*320+:320]),
+ .INIT_1C(INIT['h1c*320+:320]),
+ .INIT_1D(INIT['h1d*320+:320]),
+ .INIT_1E(INIT['h1e*320+:320]),
+ .INIT_1F(INIT['h1f*320+:320]),
+ .INIT_20(INIT['h20*320+:320]),
+ .INIT_21(INIT['h21*320+:320]),
+ .INIT_22(INIT['h22*320+:320]),
+ .INIT_23(INIT['h23*320+:320]),
+ .INIT_24(INIT['h24*320+:320]),
+ .INIT_25(INIT['h25*320+:320]),
+ .INIT_26(INIT['h26*320+:320]),
+ .INIT_27(INIT['h27*320+:320]),
+ .INIT_28(INIT['h28*320+:320]),
+ .INIT_29(INIT['h29*320+:320]),
+ .INIT_2A(INIT['h2a*320+:320]),
+ .INIT_2B(INIT['h2b*320+:320]),
+ .INIT_2C(INIT['h2c*320+:320]),
+ .INIT_2D(INIT['h2d*320+:320]),
+ .INIT_2E(INIT['h2e*320+:320]),
+ .INIT_2F(INIT['h2f*320+:320]),
+ .INIT_30(INIT['h30*320+:320]),
+ .INIT_31(INIT['h31*320+:320]),
+ .INIT_32(INIT['h32*320+:320]),
+ .INIT_33(INIT['h33*320+:320]),
+ .INIT_34(INIT['h34*320+:320]),
+ .INIT_35(INIT['h35*320+:320]),
+ .INIT_36(INIT['h36*320+:320]),
+ .INIT_37(INIT['h37*320+:320]),
+ .INIT_38(INIT['h38*320+:320]),
+ .INIT_39(INIT['h39*320+:320]),
+ .INIT_3A(INIT['h3a*320+:320]),
+ .INIT_3B(INIT['h3b*320+:320]),
+ .INIT_3C(INIT['h3c*320+:320]),
+ .INIT_3D(INIT['h3d*320+:320]),
+ .INIT_3E(INIT['h3e*320+:320]),
+ .INIT_3F(INIT['h3f*320+:320]),
+ .INIT_40(INIT['h40*320+:320]),
+ .INIT_41(INIT['h41*320+:320]),
+ .INIT_42(INIT['h42*320+:320]),
+ .INIT_43(INIT['h43*320+:320]),
+ .INIT_44(INIT['h44*320+:320]),
+ .INIT_45(INIT['h45*320+:320]),
+ .INIT_46(INIT['h46*320+:320]),
+ .INIT_47(INIT['h47*320+:320]),
+ .INIT_48(INIT['h48*320+:320]),
+ .INIT_49(INIT['h49*320+:320]),
+ .INIT_4A(INIT['h4a*320+:320]),
+ .INIT_4B(INIT['h4b*320+:320]),
+ .INIT_4C(INIT['h4c*320+:320]),
+ .INIT_4D(INIT['h4d*320+:320]),
+ .INIT_4E(INIT['h4e*320+:320]),
+ .INIT_4F(INIT['h4f*320+:320]),
+ .INIT_50(INIT['h50*320+:320]),
+ .INIT_51(INIT['h51*320+:320]),
+ .INIT_52(INIT['h52*320+:320]),
+ .INIT_53(INIT['h53*320+:320]),
+ .INIT_54(INIT['h54*320+:320]),
+ .INIT_55(INIT['h55*320+:320]),
+ .INIT_56(INIT['h56*320+:320]),
+ .INIT_57(INIT['h57*320+:320]),
+ .INIT_58(INIT['h58*320+:320]),
+ .INIT_59(INIT['h59*320+:320]),
+ .INIT_5A(INIT['h5a*320+:320]),
+ .INIT_5B(INIT['h5b*320+:320]),
+ .INIT_5C(INIT['h5c*320+:320]),
+ .INIT_5D(INIT['h5d*320+:320]),
+ .INIT_5E(INIT['h5e*320+:320]),
+ .INIT_5F(INIT['h5f*320+:320]),
+ .INIT_60(INIT['h60*320+:320]),
+ .INIT_61(INIT['h61*320+:320]),
+ .INIT_62(INIT['h62*320+:320]),
+ .INIT_63(INIT['h63*320+:320]),
+ .INIT_64(INIT['h64*320+:320]),
+ .INIT_65(INIT['h65*320+:320]),
+ .INIT_66(INIT['h66*320+:320]),
+ .INIT_67(INIT['h67*320+:320]),
+ .INIT_68(INIT['h68*320+:320]),
+ .INIT_69(INIT['h69*320+:320]),
+ .INIT_6A(INIT['h6a*320+:320]),
+ .INIT_6B(INIT['h6b*320+:320]),
+ .INIT_6C(INIT['h6c*320+:320]),
+ .INIT_6D(INIT['h6d*320+:320]),
+ .INIT_6E(INIT['h6e*320+:320]),
+ .INIT_6F(INIT['h6f*320+:320]),
+ .INIT_70(INIT['h70*320+:320]),
+ .INIT_71(INIT['h71*320+:320]),
+ .INIT_72(INIT['h72*320+:320]),
+ .INIT_73(INIT['h73*320+:320]),
+ .INIT_74(INIT['h74*320+:320]),
+ .INIT_75(INIT['h75*320+:320]),
+ .INIT_76(INIT['h76*320+:320]),
+ .INIT_77(INIT['h77*320+:320]),
+ .INIT_78(INIT['h78*320+:320]),
+ .INIT_79(INIT['h79*320+:320]),
+ .INIT_7A(INIT['h7a*320+:320]),
+ .INIT_7B(INIT['h7b*320+:320]),
+ .INIT_7C(INIT['h7c*320+:320]),
+ .INIT_7D(INIT['h7d*320+:320]),
+ .INIT_7E(INIT['h7e*320+:320]),
+ .INIT_7F(INIT['h7f*320+:320]),
+ .A_RD_WIDTH(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0),
+ .A_WR_WIDTH(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0),
+ .B_RD_WIDTH(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0),
+ .B_WR_WIDTH(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0),
.RAM_MODE("TDP"),
- .A_WR_MODE("NO_CHANGE"), .B_WR_MODE("NO_CHANGE"),
- .A_CLK_INV(!CLKPOL2), .B_CLK_INV(!CLKPOL3),
- .A_EN_INV(1'b0), .B_EN_INV(1'b0),
- .A_WE_INV(1'b0), .B_WE_INV(1'b0),
- .A_DO_REG(1'b0), .B_DO_REG(1'b0),
- .A_ECC_EN(1'b0), .B_ECC_EN(1'b0)
+ .A_WR_MODE(PORT_A_OPTION_WR_MODE),
+ .B_WR_MODE(PORT_B_OPTION_WR_MODE),
+ .A_CLK_INV(!PORT_A_CLK_POL),
+ .B_CLK_INV(!PORT_B_CLK_POL),
) _TECHMAP_REPLACE_ (
- .A_DO(A_DO),
- .B_DO(B1DATA),
- .A_ECC_1B_ERR(A_ECC_1B_ERR),
- .B_ECC_1B_ERR(B_ECC_1B_ERR),
- .A_ECC_2B_ERR(A_ECC_2B_ERR),
- .B_ECC_2B_ERR(B_ECC_2B_ERR),
- .A_CLK(CLK2),
- .B_CLK(CLK3),
- .A_EN(1'b1),
- .B_EN(B1EN),
- .A_WE(|A1EN),
- .B_WE(1'b0),
- .A_ADDR(ADDRA),
- .B_ADDR(ADDRB),
- .A_DI(A1DATA),
- .B_DI(40'b0),
- .A_BM(A1EN),
- .B_BM(40'b0)
+ .A_CLK(PORT_A_CLK),
+ .A_EN(PORT_A_CLK_EN),
+ .A_WE(PORT_A_WR_EN),
+ .A_BM(PORT_A_WR_BE),
+ .A_DI(PORT_A_WR_DATA),
+ .A_ADDR({PORT_A_ADDR[14:0], 1'b0}),
+ .A_DO(PORT_A_RD_DATA),
+ .B_CLK(PORT_B_CLK),
+ .B_EN(PORT_B_CLK_EN),
+ .B_WE(PORT_B_WR_EN),
+ .B_BM(PORT_B_WR_BE),
+ .B_DI(PORT_B_WR_DATA),
+ .B_ADDR({PORT_B_ADDR[14:0], 1'b0}),
+ .B_DO(PORT_B_RD_DATA),
);
- endgenerate
+ end else begin
+ wire CAS_A, CAS_B;
+ CC_BRAM_40K #(
+ .INIT_00(INIT['h00*320+:320]),
+ .INIT_01(INIT['h01*320+:320]),
+ .INIT_02(INIT['h02*320+:320]),
+ .INIT_03(INIT['h03*320+:320]),
+ .INIT_04(INIT['h04*320+:320]),
+ .INIT_05(INIT['h05*320+:320]),
+ .INIT_06(INIT['h06*320+:320]),
+ .INIT_07(INIT['h07*320+:320]),
+ .INIT_08(INIT['h08*320+:320]),
+ .INIT_09(INIT['h09*320+:320]),
+ .INIT_0A(INIT['h0a*320+:320]),
+ .INIT_0B(INIT['h0b*320+:320]),
+ .INIT_0C(INIT['h0c*320+:320]),
+ .INIT_0D(INIT['h0d*320+:320]),
+ .INIT_0E(INIT['h0e*320+:320]),
+ .INIT_0F(INIT['h0f*320+:320]),
+ .INIT_10(INIT['h10*320+:320]),
+ .INIT_11(INIT['h11*320+:320]),
+ .INIT_12(INIT['h12*320+:320]),
+ .INIT_13(INIT['h13*320+:320]),
+ .INIT_14(INIT['h14*320+:320]),
+ .INIT_15(INIT['h15*320+:320]),
+ .INIT_16(INIT['h16*320+:320]),
+ .INIT_17(INIT['h17*320+:320]),
+ .INIT_18(INIT['h18*320+:320]),
+ .INIT_19(INIT['h19*320+:320]),
+ .INIT_1A(INIT['h1a*320+:320]),
+ .INIT_1B(INIT['h1b*320+:320]),
+ .INIT_1C(INIT['h1c*320+:320]),
+ .INIT_1D(INIT['h1d*320+:320]),
+ .INIT_1E(INIT['h1e*320+:320]),
+ .INIT_1F(INIT['h1f*320+:320]),
+ .INIT_20(INIT['h20*320+:320]),
+ .INIT_21(INIT['h21*320+:320]),
+ .INIT_22(INIT['h22*320+:320]),
+ .INIT_23(INIT['h23*320+:320]),
+ .INIT_24(INIT['h24*320+:320]),
+ .INIT_25(INIT['h25*320+:320]),
+ .INIT_26(INIT['h26*320+:320]),
+ .INIT_27(INIT['h27*320+:320]),
+ .INIT_28(INIT['h28*320+:320]),
+ .INIT_29(INIT['h29*320+:320]),
+ .INIT_2A(INIT['h2a*320+:320]),
+ .INIT_2B(INIT['h2b*320+:320]),
+ .INIT_2C(INIT['h2c*320+:320]),
+ .INIT_2D(INIT['h2d*320+:320]),
+ .INIT_2E(INIT['h2e*320+:320]),
+ .INIT_2F(INIT['h2f*320+:320]),
+ .INIT_30(INIT['h30*320+:320]),
+ .INIT_31(INIT['h31*320+:320]),
+ .INIT_32(INIT['h32*320+:320]),
+ .INIT_33(INIT['h33*320+:320]),
+ .INIT_34(INIT['h34*320+:320]),
+ .INIT_35(INIT['h35*320+:320]),
+ .INIT_36(INIT['h36*320+:320]),
+ .INIT_37(INIT['h37*320+:320]),
+ .INIT_38(INIT['h38*320+:320]),
+ .INIT_39(INIT['h39*320+:320]),
+ .INIT_3A(INIT['h3a*320+:320]),
+ .INIT_3B(INIT['h3b*320+:320]),
+ .INIT_3C(INIT['h3c*320+:320]),
+ .INIT_3D(INIT['h3d*320+:320]),
+ .INIT_3E(INIT['h3e*320+:320]),
+ .INIT_3F(INIT['h3f*320+:320]),
+ .INIT_40(INIT['h40*320+:320]),
+ .INIT_41(INIT['h41*320+:320]),
+ .INIT_42(INIT['h42*320+:320]),
+ .INIT_43(INIT['h43*320+:320]),
+ .INIT_44(INIT['h44*320+:320]),
+ .INIT_45(INIT['h45*320+:320]),
+ .INIT_46(INIT['h46*320+:320]),
+ .INIT_47(INIT['h47*320+:320]),
+ .INIT_48(INIT['h48*320+:320]),
+ .INIT_49(INIT['h49*320+:320]),
+ .INIT_4A(INIT['h4a*320+:320]),
+ .INIT_4B(INIT['h4b*320+:320]),
+ .INIT_4C(INIT['h4c*320+:320]),
+ .INIT_4D(INIT['h4d*320+:320]),
+ .INIT_4E(INIT['h4e*320+:320]),
+ .INIT_4F(INIT['h4f*320+:320]),
+ .INIT_50(INIT['h50*320+:320]),
+ .INIT_51(INIT['h51*320+:320]),
+ .INIT_52(INIT['h52*320+:320]),
+ .INIT_53(INIT['h53*320+:320]),
+ .INIT_54(INIT['h54*320+:320]),
+ .INIT_55(INIT['h55*320+:320]),
+ .INIT_56(INIT['h56*320+:320]),
+ .INIT_57(INIT['h57*320+:320]),
+ .INIT_58(INIT['h58*320+:320]),
+ .INIT_59(INIT['h59*320+:320]),
+ .INIT_5A(INIT['h5a*320+:320]),
+ .INIT_5B(INIT['h5b*320+:320]),
+ .INIT_5C(INIT['h5c*320+:320]),
+ .INIT_5D(INIT['h5d*320+:320]),
+ .INIT_5E(INIT['h5e*320+:320]),
+ .INIT_5F(INIT['h5f*320+:320]),
+ .INIT_60(INIT['h60*320+:320]),
+ .INIT_61(INIT['h61*320+:320]),
+ .INIT_62(INIT['h62*320+:320]),
+ .INIT_63(INIT['h63*320+:320]),
+ .INIT_64(INIT['h64*320+:320]),
+ .INIT_65(INIT['h65*320+:320]),
+ .INIT_66(INIT['h66*320+:320]),
+ .INIT_67(INIT['h67*320+:320]),
+ .INIT_68(INIT['h68*320+:320]),
+ .INIT_69(INIT['h69*320+:320]),
+ .INIT_6A(INIT['h6a*320+:320]),
+ .INIT_6B(INIT['h6b*320+:320]),
+ .INIT_6C(INIT['h6c*320+:320]),
+ .INIT_6D(INIT['h6d*320+:320]),
+ .INIT_6E(INIT['h6e*320+:320]),
+ .INIT_6F(INIT['h6f*320+:320]),
+ .INIT_70(INIT['h70*320+:320]),
+ .INIT_71(INIT['h71*320+:320]),
+ .INIT_72(INIT['h72*320+:320]),
+ .INIT_73(INIT['h73*320+:320]),
+ .INIT_74(INIT['h74*320+:320]),
+ .INIT_75(INIT['h75*320+:320]),
+ .INIT_76(INIT['h76*320+:320]),
+ .INIT_77(INIT['h77*320+:320]),
+ .INIT_78(INIT['h78*320+:320]),
+ .INIT_79(INIT['h79*320+:320]),
+ .INIT_7A(INIT['h7a*320+:320]),
+ .INIT_7B(INIT['h7b*320+:320]),
+ .INIT_7C(INIT['h7c*320+:320]),
+ .INIT_7D(INIT['h7d*320+:320]),
+ .INIT_7E(INIT['h7e*320+:320]),
+ .INIT_7F(INIT['h7f*320+:320]),
+ .A_RD_WIDTH(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0),
+ .A_WR_WIDTH(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0),
+ .B_RD_WIDTH(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0),
+ .B_WR_WIDTH(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0),
+ .RAM_MODE("TDP"),
+ .A_WR_MODE(PORT_A_OPTION_WR_MODE),
+ .B_WR_MODE(PORT_B_OPTION_WR_MODE),
+ .A_CLK_INV(!PORT_A_CLK_POL),
+ .B_CLK_INV(!PORT_B_CLK_POL),
+ .CAS("LOWER"),
+ ) lower (
+ .A_CO(CAS_A),
+ .B_CO(CAS_B),
+ .A_CLK(PORT_A_CLK),
+ .A_EN(PORT_A_CLK_EN),
+ .A_WE(PORT_A_WR_EN),
+ .A_BM(PORT_A_WR_BE),
+ .A_DI(PORT_A_WR_DATA),
+ .A_ADDR({PORT_A_ADDR[14:0], PORT_A_ADDR[15]}),
+ .B_CLK(PORT_B_CLK),
+ .B_EN(PORT_B_CLK_EN),
+ .B_WE(PORT_B_WR_EN),
+ .B_BM(PORT_B_WR_BE),
+ .B_DI(PORT_B_WR_DATA),
+ .B_ADDR({PORT_B_ADDR[14:0], PORT_B_ADDR[15]}),
+ );
+ CC_BRAM_40K #(
+ .INIT_00(INIT['h80*320+:320]),
+ .INIT_01(INIT['h81*320+:320]),
+ .INIT_02(INIT['h82*320+:320]),
+ .INIT_03(INIT['h83*320+:320]),
+ .INIT_04(INIT['h84*320+:320]),
+ .INIT_05(INIT['h85*320+:320]),
+ .INIT_06(INIT['h86*320+:320]),
+ .INIT_07(INIT['h87*320+:320]),
+ .INIT_08(INIT['h88*320+:320]),
+ .INIT_09(INIT['h89*320+:320]),
+ .INIT_0A(INIT['h8a*320+:320]),
+ .INIT_0B(INIT['h8b*320+:320]),
+ .INIT_0C(INIT['h8c*320+:320]),
+ .INIT_0D(INIT['h8d*320+:320]),
+ .INIT_0E(INIT['h8e*320+:320]),
+ .INIT_0F(INIT['h8f*320+:320]),
+ .INIT_10(INIT['h90*320+:320]),
+ .INIT_11(INIT['h91*320+:320]),
+ .INIT_12(INIT['h92*320+:320]),
+ .INIT_13(INIT['h93*320+:320]),
+ .INIT_14(INIT['h94*320+:320]),
+ .INIT_15(INIT['h95*320+:320]),
+ .INIT_16(INIT['h96*320+:320]),
+ .INIT_17(INIT['h97*320+:320]),
+ .INIT_18(INIT['h98*320+:320]),
+ .INIT_19(INIT['h99*320+:320]),
+ .INIT_1A(INIT['h9a*320+:320]),
+ .INIT_1B(INIT['h9b*320+:320]),
+ .INIT_1C(INIT['h9c*320+:320]),
+ .INIT_1D(INIT['h9d*320+:320]),
+ .INIT_1E(INIT['h9e*320+:320]),
+ .INIT_1F(INIT['h9f*320+:320]),
+ .INIT_20(INIT['ha0*320+:320]),
+ .INIT_21(INIT['ha1*320+:320]),
+ .INIT_22(INIT['ha2*320+:320]),
+ .INIT_23(INIT['ha3*320+:320]),
+ .INIT_24(INIT['ha4*320+:320]),
+ .INIT_25(INIT['ha5*320+:320]),
+ .INIT_26(INIT['ha6*320+:320]),
+ .INIT_27(INIT['ha7*320+:320]),
+ .INIT_28(INIT['ha8*320+:320]),
+ .INIT_29(INIT['ha9*320+:320]),
+ .INIT_2A(INIT['haa*320+:320]),
+ .INIT_2B(INIT['hab*320+:320]),
+ .INIT_2C(INIT['hac*320+:320]),
+ .INIT_2D(INIT['had*320+:320]),
+ .INIT_2E(INIT['hae*320+:320]),
+ .INIT_2F(INIT['haf*320+:320]),
+ .INIT_30(INIT['hb0*320+:320]),
+ .INIT_31(INIT['hb1*320+:320]),
+ .INIT_32(INIT['hb2*320+:320]),
+ .INIT_33(INIT['hb3*320+:320]),
+ .INIT_34(INIT['hb4*320+:320]),
+ .INIT_35(INIT['hb5*320+:320]),
+ .INIT_36(INIT['hb6*320+:320]),
+ .INIT_37(INIT['hb7*320+:320]),
+ .INIT_38(INIT['hb8*320+:320]),
+ .INIT_39(INIT['hb9*320+:320]),
+ .INIT_3A(INIT['hba*320+:320]),
+ .INIT_3B(INIT['hbb*320+:320]),
+ .INIT_3C(INIT['hbc*320+:320]),
+ .INIT_3D(INIT['hbd*320+:320]),
+ .INIT_3E(INIT['hbe*320+:320]),
+ .INIT_3F(INIT['hbf*320+:320]),
+ .INIT_40(INIT['hc0*320+:320]),
+ .INIT_41(INIT['hc1*320+:320]),
+ .INIT_42(INIT['hc2*320+:320]),
+ .INIT_43(INIT['hc3*320+:320]),
+ .INIT_44(INIT['hc4*320+:320]),
+ .INIT_45(INIT['hc5*320+:320]),
+ .INIT_46(INIT['hc6*320+:320]),
+ .INIT_47(INIT['hc7*320+:320]),
+ .INIT_48(INIT['hc8*320+:320]),
+ .INIT_49(INIT['hc9*320+:320]),
+ .INIT_4A(INIT['hca*320+:320]),
+ .INIT_4B(INIT['hcb*320+:320]),
+ .INIT_4C(INIT['hcc*320+:320]),
+ .INIT_4D(INIT['hcd*320+:320]),
+ .INIT_4E(INIT['hce*320+:320]),
+ .INIT_4F(INIT['hcf*320+:320]),
+ .INIT_50(INIT['hd0*320+:320]),
+ .INIT_51(INIT['hd1*320+:320]),
+ .INIT_52(INIT['hd2*320+:320]),
+ .INIT_53(INIT['hd3*320+:320]),
+ .INIT_54(INIT['hd4*320+:320]),
+ .INIT_55(INIT['hd5*320+:320]),
+ .INIT_56(INIT['hd6*320+:320]),
+ .INIT_57(INIT['hd7*320+:320]),
+ .INIT_58(INIT['hd8*320+:320]),
+ .INIT_59(INIT['hd9*320+:320]),
+ .INIT_5A(INIT['hda*320+:320]),
+ .INIT_5B(INIT['hdb*320+:320]),
+ .INIT_5C(INIT['hdc*320+:320]),
+ .INIT_5D(INIT['hdd*320+:320]),
+ .INIT_5E(INIT['hde*320+:320]),
+ .INIT_5F(INIT['hdf*320+:320]),
+ .INIT_60(INIT['he0*320+:320]),
+ .INIT_61(INIT['he1*320+:320]),
+ .INIT_62(INIT['he2*320+:320]),
+ .INIT_63(INIT['he3*320+:320]),
+ .INIT_64(INIT['he4*320+:320]),
+ .INIT_65(INIT['he5*320+:320]),
+ .INIT_66(INIT['he6*320+:320]),
+ .INIT_67(INIT['he7*320+:320]),
+ .INIT_68(INIT['he8*320+:320]),
+ .INIT_69(INIT['he9*320+:320]),
+ .INIT_6A(INIT['hea*320+:320]),
+ .INIT_6B(INIT['heb*320+:320]),
+ .INIT_6C(INIT['hec*320+:320]),
+ .INIT_6D(INIT['hed*320+:320]),
+ .INIT_6E(INIT['hee*320+:320]),
+ .INIT_6F(INIT['hef*320+:320]),
+ .INIT_70(INIT['hf0*320+:320]),
+ .INIT_71(INIT['hf1*320+:320]),
+ .INIT_72(INIT['hf2*320+:320]),
+ .INIT_73(INIT['hf3*320+:320]),
+ .INIT_74(INIT['hf4*320+:320]),
+ .INIT_75(INIT['hf5*320+:320]),
+ .INIT_76(INIT['hf6*320+:320]),
+ .INIT_77(INIT['hf7*320+:320]),
+ .INIT_78(INIT['hf8*320+:320]),
+ .INIT_79(INIT['hf9*320+:320]),
+ .INIT_7A(INIT['hfa*320+:320]),
+ .INIT_7B(INIT['hfb*320+:320]),
+ .INIT_7C(INIT['hfc*320+:320]),
+ .INIT_7D(INIT['hfd*320+:320]),
+ .INIT_7E(INIT['hfe*320+:320]),
+ .INIT_7F(INIT['hff*320+:320]),
+ .A_RD_WIDTH(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0),
+ .A_WR_WIDTH(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0),
+ .B_RD_WIDTH(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0),
+ .B_WR_WIDTH(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0),
+ .RAM_MODE("TDP"),
+ .A_WR_MODE(PORT_A_OPTION_WR_MODE),
+ .B_WR_MODE(PORT_B_OPTION_WR_MODE),
+ .A_CLK_INV(!PORT_A_CLK_POL),
+ .B_CLK_INV(!PORT_B_CLK_POL),
+ .CAS("UPPER"),
+ ) upper (
+ .A_CI(CAS_A),
+ .B_CI(CAS_B),
+ .A_CLK(PORT_A_CLK),
+ .A_EN(PORT_A_CLK_EN),
+ .A_WE(PORT_A_WR_EN),
+ .A_BM(PORT_A_WR_BE),
+ .A_DI(PORT_A_WR_DATA),
+ .A_DO(PORT_A_RD_DATA),
+ .A_ADDR({PORT_A_ADDR[14:0], PORT_A_ADDR[15]}),
+ .B_CLK(PORT_B_CLK),
+ .B_EN(PORT_B_CLK_EN),
+ .B_WE(PORT_B_WR_EN),
+ .B_BM(PORT_B_WR_BE),
+ .B_DI(PORT_B_WR_DATA),
+ .B_DO(PORT_B_RD_DATA),
+ .B_ADDR({PORT_B_ADDR[14:0], PORT_B_ADDR[15]}),
+ );
+ end
+endgenerate
endmodule
-module \$__CC_BRAM_CASCADE (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
-
- parameter CFG_ABITS = 16;
- parameter CFG_DBITS = 1;
- parameter CFG_ENABLE_A = 1;
- parameter CFG_ENABLE_B = 1;
-
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
-
- // 64K x 1
- parameter [65535:0] INIT = 65535'b0;
-
- input CLK2;
- input CLK3;
+module $__CC_BRAM_SDP_(...);
- // write side of the memory
- input [15:0] A1ADDR;
- input [39:0] A1DATA;
- input [39:0] A1EN;
+parameter INIT = 0;
+parameter OPTION_MODE = "20K";
+parameter OPTION_WR_MODE = "NO_CHANGE";
- // read side of the memory
- input [15:0] B1ADDR;
- output [39:0] B1DATA;
- input [0:0] B1EN;
+parameter PORT_W_CLK_POL = 1;
+parameter PORT_W_USED = 1;
+parameter PORT_W_WIDTH = 40;
+parameter PORT_W_WR_BE_WIDTH = 40;
- // cascade signals
- wire A_CAS, B_CAS;
+parameter PORT_R_CLK_POL = 1;
+parameter PORT_R_USED = 1;
+parameter PORT_R_WIDTH = 40;
- // unconnected signals
- wire [39:0] A_UP_DO;
- wire A_ECC_1B_ERR, B_ECC_1B_ERR, A_ECC_2B_ERR, B_ECC_2B_ERR;
+input PORT_W_CLK;
+input PORT_W_CLK_EN;
+input PORT_W_WR_EN;
+input [15:0] PORT_W_ADDR;
+input [PORT_W_WR_BE_WIDTH-1:0] PORT_W_WR_BE;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
- localparam INIT_CHUNK_SIZE = 256;
+input PORT_R_CLK;
+input PORT_R_CLK_EN;
+input [15:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
- function [319:0] permute_init;
- input [INIT_CHUNK_SIZE-1:0] chunk;
- integer i;
- begin
- for (i = 0; i < 64; i = i + 1) begin
- permute_init[i * 5 +: 5] = {1'b0, chunk[i * 4 +: 4]};
- end
- end
- endfunction
-
- generate
- CC_BRAM_40K #(
- `define INIT_UPPER
- `include "brams_init_40.vh" // INIT_80 .. INIT_FF
- `undef INIT_UPPER
- .LOC("UNPLACED"),
- .CAS("UPPER"),
- .A_RD_WIDTH(0), .B_RD_WIDTH(CFG_DBITS),
- .A_WR_WIDTH(CFG_DBITS), .B_WR_WIDTH(0),
- .RAM_MODE("TDP"),
- .A_WR_MODE("NO_CHANGE"), .B_WR_MODE("NO_CHANGE"),
- .A_CLK_INV(!CLKPOL2), .B_CLK_INV(!CLKPOL3),
- .A_EN_INV(1'b0), .B_EN_INV(1'b0),
- .A_WE_INV(1'b0), .B_WE_INV(1'b0),
- .A_DO_REG(1'b0), .B_DO_REG(1'b0),
- .A_ECC_EN(1'b0), .B_ECC_EN(1'b0)
- ) upper_cell (
- .A_CI(A_CAS),
- .B_CI(B_CAS),
- .A_DO(A_UP_DO),
- .B_DO(B1DATA),
- .A_ECC_1B_ERR(A_ECC_1B_ERR),
- .B_ECC_1B_ERR(B_ECC_1B_ERR),
- .A_ECC_2B_ERR(A_ECC_2B_ERR),
- .B_ECC_2B_ERR(B_ECC_2B_ERR),
- .A_CLK(CLK2),
- .B_CLK(CLK3),
- .A_EN(1'b1),
- .B_EN(B1EN),
- .A_WE(|A1EN),
+generate
+ if (OPTION_MODE == "20K") begin
+ CC_BRAM_20K #(
+ .INIT_00(INIT['h00*320+:320]),
+ .INIT_01(INIT['h01*320+:320]),
+ .INIT_02(INIT['h02*320+:320]),
+ .INIT_03(INIT['h03*320+:320]),
+ .INIT_04(INIT['h04*320+:320]),
+ .INIT_05(INIT['h05*320+:320]),
+ .INIT_06(INIT['h06*320+:320]),
+ .INIT_07(INIT['h07*320+:320]),
+ .INIT_08(INIT['h08*320+:320]),
+ .INIT_09(INIT['h09*320+:320]),
+ .INIT_0A(INIT['h0a*320+:320]),
+ .INIT_0B(INIT['h0b*320+:320]),
+ .INIT_0C(INIT['h0c*320+:320]),
+ .INIT_0D(INIT['h0d*320+:320]),
+ .INIT_0E(INIT['h0e*320+:320]),
+ .INIT_0F(INIT['h0f*320+:320]),
+ .INIT_10(INIT['h10*320+:320]),
+ .INIT_11(INIT['h11*320+:320]),
+ .INIT_12(INIT['h12*320+:320]),
+ .INIT_13(INIT['h13*320+:320]),
+ .INIT_14(INIT['h14*320+:320]),
+ .INIT_15(INIT['h15*320+:320]),
+ .INIT_16(INIT['h16*320+:320]),
+ .INIT_17(INIT['h17*320+:320]),
+ .INIT_18(INIT['h18*320+:320]),
+ .INIT_19(INIT['h19*320+:320]),
+ .INIT_1A(INIT['h1a*320+:320]),
+ .INIT_1B(INIT['h1b*320+:320]),
+ .INIT_1C(INIT['h1c*320+:320]),
+ .INIT_1D(INIT['h1d*320+:320]),
+ .INIT_1E(INIT['h1e*320+:320]),
+ .INIT_1F(INIT['h1f*320+:320]),
+ .INIT_20(INIT['h20*320+:320]),
+ .INIT_21(INIT['h21*320+:320]),
+ .INIT_22(INIT['h22*320+:320]),
+ .INIT_23(INIT['h23*320+:320]),
+ .INIT_24(INIT['h24*320+:320]),
+ .INIT_25(INIT['h25*320+:320]),
+ .INIT_26(INIT['h26*320+:320]),
+ .INIT_27(INIT['h27*320+:320]),
+ .INIT_28(INIT['h28*320+:320]),
+ .INIT_29(INIT['h29*320+:320]),
+ .INIT_2A(INIT['h2a*320+:320]),
+ .INIT_2B(INIT['h2b*320+:320]),
+ .INIT_2C(INIT['h2c*320+:320]),
+ .INIT_2D(INIT['h2d*320+:320]),
+ .INIT_2E(INIT['h2e*320+:320]),
+ .INIT_2F(INIT['h2f*320+:320]),
+ .INIT_30(INIT['h30*320+:320]),
+ .INIT_31(INIT['h31*320+:320]),
+ .INIT_32(INIT['h32*320+:320]),
+ .INIT_33(INIT['h33*320+:320]),
+ .INIT_34(INIT['h34*320+:320]),
+ .INIT_35(INIT['h35*320+:320]),
+ .INIT_36(INIT['h36*320+:320]),
+ .INIT_37(INIT['h37*320+:320]),
+ .INIT_38(INIT['h38*320+:320]),
+ .INIT_39(INIT['h39*320+:320]),
+ .INIT_3A(INIT['h3a*320+:320]),
+ .INIT_3B(INIT['h3b*320+:320]),
+ .INIT_3C(INIT['h3c*320+:320]),
+ .INIT_3D(INIT['h3d*320+:320]),
+ .INIT_3E(INIT['h3e*320+:320]),
+ .INIT_3F(INIT['h3f*320+:320]),
+ .A_RD_WIDTH(0),
+ .A_WR_WIDTH(PORT_W_USED ? PORT_W_WIDTH : 0),
+ .B_RD_WIDTH(PORT_R_USED ? PORT_R_WIDTH : 0),
+ .B_WR_WIDTH(0),
+ .RAM_MODE("SDP"),
+ .A_WR_MODE(OPTION_WR_MODE),
+ .B_WR_MODE(OPTION_WR_MODE),
+ .A_CLK_INV(!PORT_W_CLK_POL),
+ .B_CLK_INV(!PORT_R_CLK_POL),
+ ) _TECHMAP_REPLACE_ (
+ .A_CLK(PORT_W_CLK),
+ .A_EN(PORT_W_CLK_EN),
+ .A_WE(PORT_W_WR_EN),
+ .A_BM(PORT_W_WR_BE[19:0]),
+ .B_BM(PORT_W_WR_BE[39:20]),
+ .A_DI(PORT_W_WR_DATA[19:0]),
+ .B_DI(PORT_W_WR_DATA[39:20]),
+ .A_ADDR({PORT_W_ADDR[13:5], 1'b0, PORT_W_ADDR[4:0], 1'b0}),
+ .B_CLK(PORT_R_CLK),
+ .B_EN(PORT_R_CLK_EN),
.B_WE(1'b0),
- .A_ADDR(A1ADDR),
- .B_ADDR(B1ADDR),
- .A_DI(A1DATA),
- .B_DI(40'b0),
- .A_BM(A1EN),
- .B_BM(40'b0)
+ .B_ADDR({PORT_R_ADDR[13:5], 1'b0, PORT_R_ADDR[4:0], 1'b0}),
+ .A_DO(PORT_R_RD_DATA[19:0]),
+ .B_DO(PORT_R_RD_DATA[39:20]),
);
-
+ end else if (OPTION_MODE == "40K") begin
CC_BRAM_40K #(
- `define INIT_LOWER
- `include "brams_init_40.vh" // INIT_00 .. INIT_7F
- `undef INIT_LOWER
- .LOC("UNPLACED"),
- .CAS("LOWER"),
- .A_RD_WIDTH(0), .B_RD_WIDTH(CFG_DBITS),
- .A_WR_WIDTH(CFG_DBITS), .B_WR_WIDTH(0),
- .RAM_MODE("TDP"),
- .A_WR_MODE("NO_CHANGE"), .B_WR_MODE("NO_CHANGE"),
- .A_CLK_INV(!CLKPOL2), .B_CLK_INV(!CLKPOL3),
- .A_EN_INV(1'b0), .B_EN_INV(1'b0),
- .A_WE_INV(1'b0), .B_WE_INV(1'b0),
- .A_DO_REG(1'b0), .B_DO_REG(1'b0),
- .A_ECC_EN(1'b0), .B_ECC_EN(1'b0)
- ) lower_cell (
- .A_CI(),
- .B_CI(),
- .A_CO(A_CAS),
- .B_CO(B_CAS),
- .A_CLK(CLK2),
- .B_CLK(CLK3),
- .A_EN(1'b1),
- .B_EN(B1EN),
- .A_WE(|A1EN),
+ .INIT_00(INIT['h00*320+:320]),
+ .INIT_01(INIT['h01*320+:320]),
+ .INIT_02(INIT['h02*320+:320]),
+ .INIT_03(INIT['h03*320+:320]),
+ .INIT_04(INIT['h04*320+:320]),
+ .INIT_05(INIT['h05*320+:320]),
+ .INIT_06(INIT['h06*320+:320]),
+ .INIT_07(INIT['h07*320+:320]),
+ .INIT_08(INIT['h08*320+:320]),
+ .INIT_09(INIT['h09*320+:320]),
+ .INIT_0A(INIT['h0a*320+:320]),
+ .INIT_0B(INIT['h0b*320+:320]),
+ .INIT_0C(INIT['h0c*320+:320]),
+ .INIT_0D(INIT['h0d*320+:320]),
+ .INIT_0E(INIT['h0e*320+:320]),
+ .INIT_0F(INIT['h0f*320+:320]),
+ .INIT_10(INIT['h10*320+:320]),
+ .INIT_11(INIT['h11*320+:320]),
+ .INIT_12(INIT['h12*320+:320]),
+ .INIT_13(INIT['h13*320+:320]),
+ .INIT_14(INIT['h14*320+:320]),
+ .INIT_15(INIT['h15*320+:320]),
+ .INIT_16(INIT['h16*320+:320]),
+ .INIT_17(INIT['h17*320+:320]),
+ .INIT_18(INIT['h18*320+:320]),
+ .INIT_19(INIT['h19*320+:320]),
+ .INIT_1A(INIT['h1a*320+:320]),
+ .INIT_1B(INIT['h1b*320+:320]),
+ .INIT_1C(INIT['h1c*320+:320]),
+ .INIT_1D(INIT['h1d*320+:320]),
+ .INIT_1E(INIT['h1e*320+:320]),
+ .INIT_1F(INIT['h1f*320+:320]),
+ .INIT_20(INIT['h20*320+:320]),
+ .INIT_21(INIT['h21*320+:320]),
+ .INIT_22(INIT['h22*320+:320]),
+ .INIT_23(INIT['h23*320+:320]),
+ .INIT_24(INIT['h24*320+:320]),
+ .INIT_25(INIT['h25*320+:320]),
+ .INIT_26(INIT['h26*320+:320]),
+ .INIT_27(INIT['h27*320+:320]),
+ .INIT_28(INIT['h28*320+:320]),
+ .INIT_29(INIT['h29*320+:320]),
+ .INIT_2A(INIT['h2a*320+:320]),
+ .INIT_2B(INIT['h2b*320+:320]),
+ .INIT_2C(INIT['h2c*320+:320]),
+ .INIT_2D(INIT['h2d*320+:320]),
+ .INIT_2E(INIT['h2e*320+:320]),
+ .INIT_2F(INIT['h2f*320+:320]),
+ .INIT_30(INIT['h30*320+:320]),
+ .INIT_31(INIT['h31*320+:320]),
+ .INIT_32(INIT['h32*320+:320]),
+ .INIT_33(INIT['h33*320+:320]),
+ .INIT_34(INIT['h34*320+:320]),
+ .INIT_35(INIT['h35*320+:320]),
+ .INIT_36(INIT['h36*320+:320]),
+ .INIT_37(INIT['h37*320+:320]),
+ .INIT_38(INIT['h38*320+:320]),
+ .INIT_39(INIT['h39*320+:320]),
+ .INIT_3A(INIT['h3a*320+:320]),
+ .INIT_3B(INIT['h3b*320+:320]),
+ .INIT_3C(INIT['h3c*320+:320]),
+ .INIT_3D(INIT['h3d*320+:320]),
+ .INIT_3E(INIT['h3e*320+:320]),
+ .INIT_3F(INIT['h3f*320+:320]),
+ .INIT_40(INIT['h40*320+:320]),
+ .INIT_41(INIT['h41*320+:320]),
+ .INIT_42(INIT['h42*320+:320]),
+ .INIT_43(INIT['h43*320+:320]),
+ .INIT_44(INIT['h44*320+:320]),
+ .INIT_45(INIT['h45*320+:320]),
+ .INIT_46(INIT['h46*320+:320]),
+ .INIT_47(INIT['h47*320+:320]),
+ .INIT_48(INIT['h48*320+:320]),
+ .INIT_49(INIT['h49*320+:320]),
+ .INIT_4A(INIT['h4a*320+:320]),
+ .INIT_4B(INIT['h4b*320+:320]),
+ .INIT_4C(INIT['h4c*320+:320]),
+ .INIT_4D(INIT['h4d*320+:320]),
+ .INIT_4E(INIT['h4e*320+:320]),
+ .INIT_4F(INIT['h4f*320+:320]),
+ .INIT_50(INIT['h50*320+:320]),
+ .INIT_51(INIT['h51*320+:320]),
+ .INIT_52(INIT['h52*320+:320]),
+ .INIT_53(INIT['h53*320+:320]),
+ .INIT_54(INIT['h54*320+:320]),
+ .INIT_55(INIT['h55*320+:320]),
+ .INIT_56(INIT['h56*320+:320]),
+ .INIT_57(INIT['h57*320+:320]),
+ .INIT_58(INIT['h58*320+:320]),
+ .INIT_59(INIT['h59*320+:320]),
+ .INIT_5A(INIT['h5a*320+:320]),
+ .INIT_5B(INIT['h5b*320+:320]),
+ .INIT_5C(INIT['h5c*320+:320]),
+ .INIT_5D(INIT['h5d*320+:320]),
+ .INIT_5E(INIT['h5e*320+:320]),
+ .INIT_5F(INIT['h5f*320+:320]),
+ .INIT_60(INIT['h60*320+:320]),
+ .INIT_61(INIT['h61*320+:320]),
+ .INIT_62(INIT['h62*320+:320]),
+ .INIT_63(INIT['h63*320+:320]),
+ .INIT_64(INIT['h64*320+:320]),
+ .INIT_65(INIT['h65*320+:320]),
+ .INIT_66(INIT['h66*320+:320]),
+ .INIT_67(INIT['h67*320+:320]),
+ .INIT_68(INIT['h68*320+:320]),
+ .INIT_69(INIT['h69*320+:320]),
+ .INIT_6A(INIT['h6a*320+:320]),
+ .INIT_6B(INIT['h6b*320+:320]),
+ .INIT_6C(INIT['h6c*320+:320]),
+ .INIT_6D(INIT['h6d*320+:320]),
+ .INIT_6E(INIT['h6e*320+:320]),
+ .INIT_6F(INIT['h6f*320+:320]),
+ .INIT_70(INIT['h70*320+:320]),
+ .INIT_71(INIT['h71*320+:320]),
+ .INIT_72(INIT['h72*320+:320]),
+ .INIT_73(INIT['h73*320+:320]),
+ .INIT_74(INIT['h74*320+:320]),
+ .INIT_75(INIT['h75*320+:320]),
+ .INIT_76(INIT['h76*320+:320]),
+ .INIT_77(INIT['h77*320+:320]),
+ .INIT_78(INIT['h78*320+:320]),
+ .INIT_79(INIT['h79*320+:320]),
+ .INIT_7A(INIT['h7a*320+:320]),
+ .INIT_7B(INIT['h7b*320+:320]),
+ .INIT_7C(INIT['h7c*320+:320]),
+ .INIT_7D(INIT['h7d*320+:320]),
+ .INIT_7E(INIT['h7e*320+:320]),
+ .INIT_7F(INIT['h7f*320+:320]),
+ .A_RD_WIDTH(0),
+ .A_WR_WIDTH(PORT_W_USED ? PORT_W_WIDTH : 0),
+ .B_RD_WIDTH(PORT_R_USED ? PORT_R_WIDTH : 0),
+ .B_WR_WIDTH(0),
+ .RAM_MODE("SDP"),
+ .A_WR_MODE(OPTION_WR_MODE),
+ .B_WR_MODE(OPTION_WR_MODE),
+ .A_CLK_INV(!PORT_W_CLK_POL),
+ .B_CLK_INV(!PORT_R_CLK_POL),
+ ) _TECHMAP_REPLACE_ (
+ .A_CLK(PORT_W_CLK),
+ .A_EN(PORT_W_CLK_EN),
+ .A_WE(PORT_W_WR_EN),
+ .A_BM(PORT_W_WR_BE[39:0]),
+ .B_BM(PORT_W_WR_BE[79:40]),
+ .A_DI(PORT_W_WR_DATA[39:0]),
+ .B_DI(PORT_W_WR_DATA[79:40]),
+ .A_ADDR({PORT_W_ADDR[14:0], 1'b0}),
+ .B_CLK(PORT_R_CLK),
+ .B_EN(PORT_R_CLK_EN),
.B_WE(1'b0),
- .A_ADDR(A1ADDR),
- .B_ADDR(B1ADDR),
- .A_DI(A1DATA),
- .B_DI(40'b0),
- .A_BM(A1EN),
- .B_BM(40'b0)
+ .B_ADDR({PORT_R_ADDR[14:0], 1'b0}),
+ .A_DO(PORT_R_RD_DATA[39:0]),
+ .B_DO(PORT_R_RD_DATA[79:40]),
);
- endgenerate
+ end
+endgenerate
endmodule
diff --git a/techlibs/gatemate/cells_sim.v b/techlibs/gatemate/cells_sim.v
index 1de3d1c7a..7e88fd7cf 100644
--- a/techlibs/gatemate/cells_sim.v
+++ b/techlibs/gatemate/cells_sim.v
@@ -1409,3 +1409,47 @@ module CC_BRAM_40K (
end
endgenerate
endmodule
+
+// Models of the LUT2 tree primitives
+module CC_L2T4(
+ output O,
+ input I0, I1, I2, I3
+);
+ parameter [3:0] INIT_L00 = 4'b0000;
+ parameter [3:0] INIT_L01 = 4'b0000;
+ parameter [3:0] INIT_L10 = 4'b0000;
+
+ wire [1:0] l00_s1 = I1 ? INIT_L00[3:2] : INIT_L00[1:0];
+ wire l00 = I0 ? l00_s1[1] : l00_s1[0];
+
+ wire [1:0] l01_s1 = I3 ? INIT_L01[3:2] : INIT_L01[1:0];
+ wire l01 = I2 ? l01_s1[1] : l01_s1[0];
+
+ wire [1:0] l10_s1 = l01 ? INIT_L10[3:2] : INIT_L10[1:0];
+ assign O = l00 ? l10_s1[1] : l10_s1[0];
+
+endmodule
+
+
+module CC_L2T5(
+ output O,
+ input I0, I1, I2, I3, I4
+);
+ parameter [3:0] INIT_L02 = 4'b0000;
+ parameter [3:0] INIT_L03 = 4'b0000;
+ parameter [3:0] INIT_L11 = 4'b0000;
+ parameter [3:0] INIT_L20 = 4'b0000;
+
+ wire [1:0] l02_s1 = I1 ? INIT_L02[3:2] : INIT_L02[1:0];
+ wire l02 = I0 ? l02_s1[1] : l02_s1[0];
+
+ wire [1:0] l03_s1 = I3 ? INIT_L03[3:2] : INIT_L03[1:0];
+ wire l03 = I2 ? l03_s1[1] : l03_s1[0];
+
+ wire [1:0] l11_s1 = l03 ? INIT_L11[3:2] : INIT_L11[1:0];
+ wire l11 = l02 ? l11_s1[1] : l11_s1[0];
+
+ wire [1:0] l20_s1 = l11 ? INIT_L20[3:2] : INIT_L20[1:0];
+ assign O = I4 ? l20_s1[1] : l20_s1[0];
+
+endmodule
diff --git a/techlibs/gatemate/gatemate_foldinv.cc b/techlibs/gatemate/gatemate_foldinv.cc
new file mode 100644
index 000000000..752f8aac0
--- /dev/null
+++ b/techlibs/gatemate/gatemate_foldinv.cc
@@ -0,0 +1,219 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2021 gatecat <gatecat@ds0.me>
+ * Copyright (C) 2021 Cologne Chip AG <support@colognechip.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/yosys.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct LUTPin {
+ int input_bit;
+ IdString init_param;
+};
+
+struct LUTType {
+ dict<IdString, LUTPin> inputs;
+ IdString output_param;
+};
+
+struct FoldInvWorker {
+ FoldInvWorker(Module *module) : module(module), sigmap(module) {};
+ Module *module;
+ SigMap sigmap;
+
+ // Mapping from inverter output to inverter input
+ dict<SigBit, SigBit> inverted_bits;
+ // Mapping from inverter input to inverter
+ dict<SigBit, Cell*> inverter_input;
+
+ const dict<IdString, LUTType> lut_types = {
+ {ID(CC_LUT2), {{
+ {ID(I0), {0, ID(INIT)}},
+ {ID(I1), {1, ID(INIT)}},
+ }, ID(INIT)}},
+ {ID(CC_L2T4), {{
+ {ID(I0), {0, ID(INIT_L00)}},
+ {ID(I1), {1, ID(INIT_L00)}},
+ {ID(I2), {0, ID(INIT_L01)}},
+ {ID(I3), {1, ID(INIT_L01)}},
+ }, ID(INIT_L10)}},
+ {ID(CC_L2T5), {{
+ {ID(I0), {0, ID(INIT_L02)}},
+ {ID(I1), {1, ID(INIT_L02)}},
+ {ID(I2), {0, ID(INIT_L03)}},
+ {ID(I3), {1, ID(INIT_L03)}},
+ {ID(I4), {0, ID(INIT_L20)}},
+ }, ID(INIT_L20)}},
+ };
+
+
+ void find_inverted_bits()
+ {
+ for (auto cell : module->selected_cells()) {
+ if (cell->type != ID($__CC_NOT))
+ continue;
+ SigBit a = sigmap(cell->getPort(ID::A)[0]);
+ SigBit y = sigmap(cell->getPort(ID::Y)[0]);
+ inverted_bits[y] = a;
+ inverter_input[a] = cell;
+ }
+ }
+
+ Const invert_lut_input(Const lut, int bit)
+ {
+ Const result(State::S0, GetSize(lut));
+ for (int i = 0; i < GetSize(lut); i++) {
+ int j = i ^ (1 << bit);
+ result[j] = lut[i];
+ }
+ return result;
+ }
+
+ Const invert_lut_output(Const lut)
+ {
+ Const result(State::S0, GetSize(lut));
+ for (int i = 0; i < GetSize(lut); i++)
+ result[i] = (lut[i] == State::S1) ? State::S0 : State::S1;
+ return result;
+ }
+
+ void fold_input_inverters()
+ {
+ for (auto cell : module->selected_cells()) {
+ auto found_type = lut_types.find(cell->type);
+ if (found_type == lut_types.end())
+ continue;
+ const auto &type = found_type->second;
+ for (const auto &ipin : type.inputs) {
+ if (!cell->hasPort(ipin.first))
+ continue;
+ auto sig = cell->getPort(ipin.first);
+ if (GetSize(sig) == 0)
+ continue;
+ SigBit bit = sigmap(sig[0]);
+ auto inv = inverted_bits.find(bit);
+ if (inv == inverted_bits.end())
+ continue; // not the output of an inverter
+ // Rewire to inverter input
+ cell->unsetPort(ipin.first);
+ cell->setPort(ipin.first, inv->second);
+ // Rewrite init
+ cell->setParam(ipin.second.init_param,
+ invert_lut_input(cell->getParam(ipin.second.init_param), ipin.second.input_bit));
+ }
+ }
+ }
+
+ void fold_output_inverters()
+ {
+ pool<SigBit> used_bits;
+ // Find bits that are actually used
+ for (auto cell : module->selected_cells()) {
+ for (auto conn : cell->connections()) {
+ if (cell->output(conn.first))
+ continue;
+ for (auto bit : sigmap(conn.second))
+ used_bits.insert(bit);
+ }
+ }
+ // Find LUTs driving inverters
+ // (create a vector to avoid iterate-and-modify issues)
+ std::vector<std::pair<Cell *, Cell*>> lut_inv;
+ for (auto cell : module->selected_cells()) {
+ auto found_type = lut_types.find(cell->type);
+ if (found_type == lut_types.end())
+ continue;
+ if (!cell->hasPort(ID::O))
+ continue;
+ auto o_sig = cell->getPort(ID::O);
+ if (GetSize(o_sig) == 0)
+ continue;
+ SigBit o = sigmap(o_sig[0]);
+ auto found_inv = inverter_input.find(o);
+ if (found_inv == inverter_input.end())
+ continue; // doesn't drive an inverter
+ lut_inv.emplace_back(cell, found_inv->second);
+ }
+ for (auto pair : lut_inv) {
+ Cell *orig_lut = pair.first;
+ Cell *inv = pair.second;
+ // Find the inverter output
+ SigBit inv_y = sigmap(inv->getPort(ID::Y)[0]);
+ // Inverter output might not actually be used; if all users were folded into inputs already
+ if (!used_bits.count(inv_y))
+ continue;
+ // Create a duplicate of the LUT with an inverted output
+ // (if the uninverted version becomes unused it will be swept away)
+ Cell *dup_lut = module->addCell(NEW_ID, orig_lut->type);
+ inv->unsetPort(ID::Y);
+ dup_lut->setPort(ID::O, inv_y);
+ for (auto conn : orig_lut->connections()) {
+ if (conn.first == ID::O)
+ continue;
+ dup_lut->setPort(conn.first, conn.second);
+ }
+ for (auto param : orig_lut->parameters) {
+ if (param.first == lut_types.at(orig_lut->type).output_param)
+ dup_lut->parameters[param.first] = invert_lut_output(param.second);
+ else
+ dup_lut->parameters[param.first] = param.second;
+ }
+ }
+ }
+
+ void operator()()
+ {
+ find_inverted_bits();
+ fold_input_inverters();
+ fold_output_inverters();
+ }
+};
+
+struct GatemateFoldInvPass : public Pass {
+ GatemateFoldInvPass() : Pass("gatemate_foldinv", "fold inverters into Gatemate LUT trees") { }
+ void help() override
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" gatemate_foldinv [selection]\n");
+ log("\n");
+ log("\n");
+ log("This pass searches for $__CC_NOT cells and folds them into CC_LUT2, CC_L2T4\n");
+ log("and CC_L2T5 cells as created by LUT tree mapping.\n");
+ log("\n");
+ }
+
+ void execute(std::vector<std::string> args, RTLIL::Design *design) override
+ {
+ log_header(design, "Executing GATEMATE_FOLDINV pass (folding LUT tree inverters).\n");
+
+ size_t argidx = 1;
+ extra_args(args, argidx, design);
+
+ for (Module *module : design->selected_modules()) {
+ FoldInvWorker worker(module);
+ worker();
+ }
+ }
+} GatemateFoldInvPass;
+
+PRIVATE_NAMESPACE_END
+
diff --git a/techlibs/gatemate/inv_map.v b/techlibs/gatemate/inv_map.v
new file mode 100644
index 000000000..8a5051747
--- /dev/null
+++ b/techlibs/gatemate/inv_map.v
@@ -0,0 +1,4 @@
+// Any inverters not folded into LUTs are mapped to a LUT of their own
+module \$__CC_NOT (input A, output Y);
+ CC_LUT1 #(.INIT(2'b01)) _TECHMAP_REPLACE_ (.I0(A), .O(Y));
+endmodule
diff --git a/techlibs/gatemate/make_lut_tree_lib.py b/techlibs/gatemate/make_lut_tree_lib.py
new file mode 100644
index 000000000..25ca88882
--- /dev/null
+++ b/techlibs/gatemate/make_lut_tree_lib.py
@@ -0,0 +1,323 @@
+#!/usr/bin/env python3
+
+class FNode:
+ def __init__(self, fun, *args):
+ self.fun = fun
+ self.args = args
+
+ if len(self.args) == 0:
+ assert fun not in ("BUF", "NOT", "AND", "OR", "XOR", "MUX")
+
+ if len(self.args) == 1:
+ assert fun in ("BUF", "NOT")
+
+ if len(self.args) == 2:
+ assert fun in ("AND", "OR", "XOR")
+
+ if len(self.args) == 3:
+ assert fun in ("MUX")
+
+ def __str__(self):
+ if len(self.args) == 0:
+ return self.fun
+ if self.fun == "NOT" and len(self.args[0].args) == 0:
+ return "!" + self.args[0].fun
+ return self.fun + "(" + ",".join([str(a) for a in self.args]) + ")"
+
+ def as_genlib_term(self):
+ if len(self.args) == 0:
+ return self.fun
+ if self.fun == "NOT":
+ assert len(self.args[0].args) == 0
+ return "!" + self.args[0].fun
+ if self.fun == "AND":
+ return "(" + self.args[0].as_genlib_term() + "*" + self.args[1].as_genlib_term() + ")"
+ if self.fun == "OR":
+ return "(" + self.args[0].as_genlib_term() + "+" + self.args[1].as_genlib_term() + ")"
+ assert False
+
+ def mapMux(self):
+ if self.fun == "MUX":
+ A, B, C = self.args
+ return OR(AND(A, NOT(C)), AND(B, C)).mapMux()
+ return FNode(self.fun, *[a.mapMux() for a in self.args])
+
+ def mapXor(self):
+ if self.fun == "XOR":
+ A, B = self.args
+ return OR(AND(A, NOT(B)), AND(NOT(A), B)).mapXor()
+ return FNode(self.fun, *[a.mapXor() for a in self.args])
+
+ def mapNot(self):
+ if self.fun == "BUF":
+ return self.arg1.mapNot()
+ if self.fun == "NOT":
+ if self.args[0].fun == "AND":
+ return OR(NOT(self.args[0].args[0]),NOT(self.args[0].args[1])).mapNot()
+ if self.args[0].fun == "OR":
+ return AND(NOT(self.args[0].args[0]),NOT(self.args[0].args[1])).mapNot()
+ if self.args[0].fun == "NOT":
+ return self.args[0].args[0].mapNot()
+ return FNode(self.fun, *[a.mapNot() for a in self.args])
+
+ def map(self):
+ n = self
+ n = n.mapMux()
+ n = n.mapXor()
+ n = n.mapNot()
+ return n
+
+ def isInv(self):
+ if len(self.args) == 0:
+ return False
+ if self.fun == "XOR":
+ return False
+ if self.fun == "NOT":
+ return self.args[0].isNonInv()
+ for a in self.args:
+ if not a.isInv():
+ return False
+ return True
+
+ def isNonInv(self):
+ if len(self.args) == 0:
+ return True
+ if self.fun == "XOR":
+ return False
+ if self.fun == "NOT":
+ return self.args[0].isInv()
+ for a in self.args:
+ if not a.isNonInv():
+ return False
+ return True
+
+A = FNode("A")
+B = FNode("B")
+C = FNode("C")
+D = FNode("D")
+E = FNode("E")
+
+def BUF(arg): return FNode("BUF", arg)
+def NOT(arg): return FNode("NOT", arg)
+def AND(arg1, arg2): return FNode("AND", arg1, arg2)
+def OR(arg1, arg2): return FNode( "OR", arg1, arg2)
+def XOR(arg1, arg2): return FNode("XOR", arg1, arg2)
+def MUX(arg1, arg2, arg3): return FNode("MUX", arg1, arg2, arg3)
+
+# Genlib Format:
+#
+# GATE <cell-name> <cell-area> <cell-logic-function>
+#
+# PIN <pin-name> <phase> <input-load> <max-load>
+# <rise-block-delay> <rise-fanout-delay>
+# <fall-block-delay> <fall-fanout-delay>
+#
+# phase:
+# INV, NONINV, or UNKNOWN
+#
+# cell-logic-function:
+# <output> = <term with *(AND), +(OR), !(NOT)>
+
+
+cells = [
+ ["$__CC_BUF", 5, A],
+ ["$__CC_NOT", 0, NOT(A)],
+ ["$__CC_MUX", 5, MUX(A, B, C)],
+]
+
+base_cells = [
+ ["$__CC2_A", AND(A, B)],
+ ["$__CC2_O", OR(A, B)],
+ ["$__CC2_X", XOR(A, B)],
+
+ ["$__CC3_AA", AND(AND(A, B), C)],
+ ["$__CC3_OO", OR( OR(A, B), C)],
+ ["$__CC3_XX", XOR(XOR(A, B), C)],
+ ["$__CC3_AO", OR(AND(A, B), C)],
+ ["$__CC3_OA", AND( OR(A, B), C)],
+ ["$__CC3_AX", XOR(AND(A, B), C)],
+ ["$__CC3_XA", AND(XOR(A, B), C)],
+
+# ["$__CC3_AAA", AND(AND(A,B),AND(A,C))],
+# ["$__CC3_AXA", XOR(AND(A,B),AND(A,C))],
+# ["$__CC3_XAX", AND(XOR(A,B),XOR(A,C))],
+# ["$__CC3_AAX", AND(AND(A,B),XOR(A,C))],
+# ["$__CC3_AXX", XOR(AND(A,B),XOR(A,C))],
+# ["$__CC3_XXX", XOR(XOR(A,B),XOR(A,C))],
+# ["$__CC3_AAO", AND(AND(A,B), OR(A,C))],
+# ["$__CC3_AOA", OR(AND(A,B),AND(A,C))],
+# ["$__CC3_AOX", OR(AND(A,B),XOR(A,C))],
+
+# ["$__CC3_AAA_N", AND(AND(A,B),AND(NOT(A),C))],
+# ["$__CC3_AXA_N", XOR(AND(A,B),AND(NOT(A),C))],
+# ["$__CC3_XAX_N", AND(XOR(A,B),XOR(NOT(A),C))],
+# ["$__CC3_AAX_N", AND(AND(A,B),XOR(NOT(A),C))],
+# ["$__CC3_AXX_N", XOR(AND(A,B),XOR(NOT(A),C))],
+# ["$__CC3_XXX_N", XOR(XOR(A,B),XOR(NOT(A),C))],
+# ["$__CC3_AAO_N", AND(AND(A,B), OR(NOT(A),C))],
+# ["$__CC3_AOA_N", OR(AND(A,B),AND(NOT(A),C))],
+# ["$__CC3_AOX_N", OR(AND(A,B),XOR(NOT(A),C))],
+
+ ["$__CC4_AAA", AND(AND(A,B),AND(C,D))],
+ ["$__CC4_AXA", XOR(AND(A,B),AND(C,D))],
+ ["$__CC4_XAX", AND(XOR(A,B),XOR(C,D))],
+ ["$__CC4_AAX", AND(AND(A,B),XOR(C,D))],
+ ["$__CC4_AXX", XOR(AND(A,B),XOR(C,D))],
+ ["$__CC4_XXX", XOR(XOR(A,B),XOR(C,D))],
+ ["$__CC4_AAO", AND(AND(A,B), OR(C,D))],
+ ["$__CC4_AOA", OR(AND(A,B),AND(C,D))],
+ ["$__CC4_AOX", OR(AND(A,B),XOR(C,D))],
+]
+
+for name, expr in base_cells:
+ cells.append([name, 10, expr])
+
+ name = (name
+ .replace("$__CC4_", "$__CC5_")
+ .replace("$__CC3_", "$__CC4_")
+ .replace("$__CC2_", "$__CC3_"))
+
+ # Cells such as $__CC4_AA_A are redundant, as $__CC4_AAA is equivalent
+ if name not in ("$__CC4_AA", "$__CC3_A"):
+ cells.append([name + "_A", 12, AND(E, expr)])
+ if name not in ("$__CC4_OO", "$__CC3_O"):
+ cells.append([name + "_O", 12, OR(E, expr)])
+ if name not in ("$__CC4_XX", "$__CC3_X"):
+ cells.append([name + "_X", 12, XOR(E, expr)])
+
+with open("techlibs/gatemate/lut_tree_cells.genlib", "w") as glf:
+ def mkGate(name, cost, expr, max_load=9999, block_delay = 10, fanout_delay = 5):
+ name = name.replace(" ", "")
+ expr = expr.map()
+
+ phase = "UNKNOWN"
+ if expr.isInv(): phase = "INV"
+ if expr.isNonInv(): phase = "NONINV"
+
+ print("", file=glf)
+ print("GATE %s %d Y=%s;" % (name, cost, expr.as_genlib_term()), file=glf)
+ print("PIN * %s 1 %d %d %d %d %d" % (phase, max_load, block_delay, fanout_delay, block_delay, fanout_delay), file=glf)
+ print("GATE $__ZERO 0 Y=CONST0;", file=glf)
+ print("GATE $__ONE 0 Y=CONST1;", file=glf)
+ for name, cost, expr in cells:
+ mkGate(name, cost, expr)
+
+class LUTTreeNode:
+ def __init__(self, name, width, inputs=None):
+ self.name = name
+ self.width = width
+ self.inputs = inputs
+ def is_input(self):
+ return self.width == 0
+ def map(self, expr, params, ports):
+ if self.is_input():
+ # Input to LUT tree
+ if expr is None:
+ ports[self.name] = "" # disconnected input
+ else:
+ assert(len(expr.args) == 0)
+ ports[self.name] = expr.fun
+ return
+ if expr is None:
+ # Unused part of tree
+ params[self.name] = "4'b0000"
+ for i in self.inputs:
+ i.map(None, params, ports)
+ return
+ elif len(expr.args) == 0:
+ # Input to the expression; but not LUT tree
+ # Insert a route through
+ params[self.name] = "4'b1010"
+ self.inputs[0].map(expr, params, ports)
+ for i in self.inputs[1:]:
+ i.map(None, params, ports)
+ return
+ # Map uphill LUTs; uninverting arguments and keeping track of that if needed
+ arg_inv = []
+ for (i, arg) in zip(self.inputs, expr.args):
+ if arg.fun == "NOT":
+ i.map(arg.args[0], params, ports)
+ arg_inv.append(True)
+ else:
+ i.map(arg, params, ports)
+ arg_inv.append(False)
+ # Determine base init value
+ assert self.width == 2
+ if expr.fun == "AND":
+ init = 0b1000
+ elif expr.fun == "OR":
+ init = 0b1110
+ elif expr.fun == "XOR":
+ init = 0b0110
+ else:
+ assert False, expr.fun
+ # Swap bits if init inverted
+ swapped_init = 0b0000
+ for b in range(4):
+ if ((init >> b) & 0x1) == 0: continue
+ for i in range(2):
+ if arg_inv[i]:
+ b ^= (1 << i)
+ swapped_init |= (1 << b)
+ # Set init param
+ params[self.name] = "4'b{:04b}".format(swapped_init)
+
+def LUT2(name, i0, i1): return LUTTreeNode(name, 2, [i0, i1])
+def I(name): return LUTTreeNode(name, 0)
+
+lut_prims = {
+ "CC_LUT2": LUT2("INIT", I("I0"), I("I1")),
+ "CC_L2T4": LUT2(
+ "INIT_L10",
+ LUT2("INIT_L00", I("I0"), I("I1")),
+ LUT2("INIT_L01", I("I2"), I("I3")),
+ ),
+ "CC_L2T5": LUT2(
+ "INIT_L20", I("I4"), LUT2("INIT_L11",
+ LUT2("INIT_L02", I("I0"), I("I1")),
+ LUT2("INIT_L03", I("I2"), I("I3")),
+ )
+ )
+}
+
+with open("techlibs/gatemate/lut_tree_map.v", "w") as vf:
+ # Non-automatic rules
+ print("""
+module \\$__ZERO (output Y); assign Y = 1'b0; endmodule
+module \\$__ONE (output Y); assign Y = 1'b1; endmodule
+
+module \\$__CC_BUF (input A, output Y); assign Y = A; endmodule
+
+module \\$__CC_MUX (input A, B, C, output Y);
+ CC_MX2 _TECHMAP_REPLACE_ (
+ .D0(A), .D1(B), .S0(C),
+ .Y(Y)
+ );
+endmodule
+""", file=vf)
+ for name, cost, expr in cells:
+ expr = expr.mapMux().mapNot() # Don't map XOR
+ if name in ("$__CC_BUF", "$__CC_NOT", "$__CC_MUX"):
+ # Special cases
+ continue
+ if name.startswith("$__CC2_"):
+ prim = "CC_LUT2"
+ elif name.startswith("$__CC5_") or (name.startswith("$__CC4_") and cost == 12):
+ prim = "CC_L2T5"
+ else:
+ prim = "CC_L2T4"
+ ports = {}
+ params = {}
+ lut_prims[prim].map(expr, params, ports)
+ print("", file=vf)
+ print("module \\%s (input %s, output Y);" % (name,
+ ", ".join(sorted(set(x for x in ports.values() if x)))), file=vf)
+ print(" %s #(" % prim, file=vf)
+ for k, v in sorted(params.items(), key=lambda x: x[0]):
+ print(" .%s(%s)," % (k, v), file=vf)
+ print(" ) _TECHMAP_REPLACE_ (", file=vf)
+ print(" %s," % ", ".join(".%s(%s)" % (k, v) for k, v in sorted(ports.items(), key=lambda x:x[0])),
+ file=vf)
+ print(" .O(Y)", file=vf)
+ print(" );", file=vf)
+ print("endmodule", file=vf)
diff --git a/techlibs/gatemate/synth_gatemate.cc b/techlibs/gatemate/synth_gatemate.cc
index 0131cdcdf..dd4fde643 100644
--- a/techlibs/gatemate/synth_gatemate.cc
+++ b/techlibs/gatemate/synth_gatemate.cc
@@ -67,7 +67,10 @@ struct SynthGateMatePass : public ScriptPass
log("\n");
log(" -nomx8, -nomx4\n");
log(" do not use CC_MX{8,4} multiplexer cells in output netlist.\n");
- log("\n");;
+ log("\n");
+ log(" -luttree\n");
+ log(" use new LUT tree mapping approach (EXPERIMENTAL).\n");
+ log("\n");
log(" -dff\n");
log(" run 'abc' with -dff option\n");
log("\n");
@@ -87,7 +90,7 @@ struct SynthGateMatePass : public ScriptPass
}
string top_opt, vlog_file, json_file;
- bool noflatten, nobram, noaddf, nomult, nomx4, nomx8, dff, retime, noiopad, noclkbuf;
+ bool noflatten, nobram, noaddf, nomult, nomx4, nomx8, luttree, dff, retime, noiopad, noclkbuf;
void clear_flags() override
{
@@ -100,6 +103,7 @@ struct SynthGateMatePass : public ScriptPass
nomult = false;
nomx4 = false;
nomx8 = false;
+ luttree = false;
dff = false;
retime = false;
noiopad = false;
@@ -158,6 +162,10 @@ struct SynthGateMatePass : public ScriptPass
nomx8 = true;
continue;
}
+ if (args[argidx] == "-luttree") {
+ luttree = true;
+ continue;
+ }
if (args[argidx] == "-dff") {
dff = true;
continue;
@@ -237,12 +245,7 @@ struct SynthGateMatePass : public ScriptPass
if (check_label("map_bram", "(skip if '-nobram')") && !nobram)
{
- run("memory_bram -rules +/gatemate/brams.txt");
- run("setundef -zero -params "
- "t:$__CC_BRAM_CASCADE "
- "t:$__CC_BRAM_40K_SDP t:$__CC_BRAM_20K_SDP "
- "t:$__CC_BRAM_20K_TDP t:$__CC_BRAM_40K_TDP "
- );
+ run("memory_libmap -lib +/gatemate/brams.txt");
run("techmap -map +/gatemate/brams_map.v");
}
@@ -303,11 +306,23 @@ struct SynthGateMatePass : public ScriptPass
if (check_label("map_luts"))
{
- std::string abc_args = " -dress -lut 4";
- if (dff) {
- abc_args += " -dff";
+ if (luttree || help_mode) {
+ std::string abc_args = " -genlib +/gatemate/lut_tree_cells.genlib";
+ if (dff) {
+ abc_args += " -dff";
+ }
+ run("abc " + abc_args, "(with -luttree)");
+ run("techmap -map +/gatemate/lut_tree_map.v", "(with -luttree)");
+ run("gatemate_foldinv", "(with -luttree)");
+ run("techmap -map +/gatemate/inv_map.v", "(with -luttree)");
+ }
+ if (!luttree || help_mode) {
+ std::string abc_args = " -dress -lut 4";
+ if (dff) {
+ abc_args += " -dff";
+ }
+ run("abc " + abc_args, "(without -luttree)");
}
- run("abc " + abc_args);
run("clean");
}
diff --git a/techlibs/gowin/.gitignore b/techlibs/gowin/.gitignore
deleted file mode 100644
index d6c48e90d..000000000
--- a/techlibs/gowin/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-brams_init.mk
-bram_init_*.vh
diff --git a/techlibs/gowin/Makefile.inc b/techlibs/gowin/Makefile.inc
index e6a6be970..4f3a33f36 100644
--- a/techlibs/gowin/Makefile.inc
+++ b/techlibs/gowin/Makefile.inc
@@ -1,8 +1,6 @@
OBJS += techlibs/gowin/synth_gowin.o
-GENFILES += techlibs/gowin/bram_init_16.vh
-
$(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_sim.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/arith_map.v))
@@ -10,16 +8,3 @@ $(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams.txt))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams.txt))
-
-$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_init3.vh))
-
-EXTRA_OBJS += techlibs/gowin/brams_init.mk
-.SECONDARY: techlibs/gowin/brams_init.mk
-
-techlibs/gowin/brams_init.mk: techlibs/gowin/brams_init.py
- $(Q) mkdir -p techlibs/gowin
- $(P) python3 $<
- $(Q) touch $@
-
-techlibs/gowin/bram_init_16.vh: techlibs/gowin/brams_init.mk
-$(eval $(call add_gen_share_file,share/gowin,techlibs/gowin/bram_init_16.vh))
diff --git a/techlibs/gowin/brams.txt b/techlibs/gowin/brams.txt
index e406f9c51..0c0d8fa3e 100644
--- a/techlibs/gowin/brams.txt
+++ b/techlibs/gowin/brams.txt
@@ -1,31 +1,81 @@
-bram $__GW1NR_SDP
- init 1
- abits 9 @a9d36
- dbits 32 @a9d36
- abits 10 @a10d18
- dbits 16 @a10d18
- abits 11 @a11d9
- dbits 8 @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 1 0
- enable 4 1 @a9d36
- enable 2 1 @a10d18
- enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
+ram block $__GOWIN_SP_ {
+ abits 14;
+ widths 1 2 4 9 18 36 per_port;
+ byte 9;
+ cost 128;
+ init no_undef;
+ port srsw "A" {
+ clock posedge;
+ clken;
+ wrbe_separate;
+ option "RESET_MODE" "SYNC" {
+ rdsrst zero ungated;
+ }
+ option "RESET_MODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ portoption "WRITE_MODE" 0 {
+ rdwr no_change;
+ }
+ portoption "WRITE_MODE" 1 {
+ rdwr new;
+ }
+ portoption "WRITE_MODE" 2 {
+ rdwr old;
+ }
+ }
+}
-match $__GW1NR_SDP
- min bits 2048
- min efficiency 5
- shuffle_enable A
- make_transp
-endmatch
+ram block $__GOWIN_DP_ {
+ abits 14;
+ widths 1 2 4 9 18 per_port;
+ byte 9;
+ cost 128;
+ init no_undef;
+ port srsw "A" "B" {
+ clock posedge;
+ clken;
+ wrbe_separate;
+ option "RESET_MODE" "SYNC" {
+ rdsrst zero ungated;
+ }
+ option "RESET_MODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ portoption "WRITE_MODE" 0 {
+ rdwr no_change;
+ }
+ portoption "WRITE_MODE" 1 {
+ rdwr new;
+ }
+ portoption "WRITE_MODE" 2 {
+ rdwr old;
+ }
+ }
+}
+
+ram block $__GOWIN_SDP_ {
+ abits 14;
+ widths 1 2 4 9 18 36 per_port;
+ byte 9;
+ cost 128;
+ init no_undef;
+ port sr "R" {
+ clock posedge;
+ clken;
+ option "RESET_MODE" "SYNC" {
+ rdsrst zero ungated;
+ }
+ option "RESET_MODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ }
+ port sw "W" {
+ clock posedge;
+ clken;
+ wrbe_separate;
+ }
+}
diff --git a/techlibs/gowin/brams_init.py b/techlibs/gowin/brams_init.py
deleted file mode 100755
index b78eb8da5..000000000
--- a/techlibs/gowin/brams_init.py
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env python3
-
-with open("techlibs/gowin/bram_init_16.vh", "w") as f:
- for i in range(0, 0x40):
- low = i << 8
- hi = ((i+1) << 8)-1
- snippet = "INIT[%d:%d]" % (hi, low)
- print(".INIT_RAM_%02X({%s})," % (i, snippet), file=f)
diff --git a/techlibs/gowin/brams_init3.vh b/techlibs/gowin/brams_init3.vh
deleted file mode 100644
index 84397fa24..000000000
--- a/techlibs/gowin/brams_init3.vh
+++ /dev/null
@@ -1,12 +0,0 @@
-localparam [15:0] INIT_0 = {
- INIT[ 60], INIT[ 56], INIT[ 52], INIT[ 48], INIT[ 44], INIT[ 40], INIT[ 36], INIT[ 32], INIT[ 28], INIT[ 24], INIT[ 20], INIT[ 16], INIT[ 12], INIT[ 8], INIT[ 4], INIT[ 0]
-};
-localparam [15:0] INIT_1 = {
- INIT[ 61], INIT[ 57], INIT[ 53], INIT[ 49], INIT[ 45], INIT[ 41], INIT[ 37], INIT[ 33], INIT[ 29], INIT[ 25], INIT[ 21], INIT[ 17], INIT[ 13], INIT[ 9], INIT[ 5], INIT[ 1]
-};
-localparam [15:0] INIT_2 = {
- INIT[ 62], INIT[ 58], INIT[ 54], INIT[ 50], INIT[ 46], INIT[ 42], INIT[ 38], INIT[ 34], INIT[ 30], INIT[ 26], INIT[ 22], INIT[ 18], INIT[ 14], INIT[ 10], INIT[ 6], INIT[ 2]
-};
-localparam [15:0] INIT_3 = {
- INIT[ 63], INIT[ 59], INIT[ 55], INIT[ 51], INIT[ 47], INIT[ 43], INIT[ 39], INIT[ 35], INIT[ 31], INIT[ 27], INIT[ 23], INIT[ 19], INIT[ 15], INIT[ 11], INIT[ 7], INIT[ 3]
-};
diff --git a/techlibs/gowin/brams_map.v b/techlibs/gowin/brams_map.v
index fbebc4af8..7ffc91bac 100644
--- a/techlibs/gowin/brams_map.v
+++ b/techlibs/gowin/brams_map.v
@@ -1,142 +1,410 @@
-/* Semi Dual Port (SDP) memory have the following configurations:
- * Memory Config RAM(BIT) Port Mode Memory Depth Data Depth
- * ----------------|---------| ----------|--------------|------------|
- * B-SRAM_16K_SD1 16K 16Kx1 16,384 1
- * B-SRAM_8K_SD2 16K 8Kx2 8,192 2
- * B-SRAM_4K_SD4 16K 4Kx2 4,096 4
- */
-module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 10;
- parameter CFG_DBITS = 16;
- parameter CFG_ENABLE_A = 1;
- parameter [16383:0] INIT = 16384'hx;
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
-
- input CLK2;
- input CLK3;
-
- input [CFG_ABITS-1:0] A1ADDR;
- input [CFG_DBITS-1:0] A1DATA;
- input [CFG_ENABLE_A-1:0] A1EN;
-
- input [CFG_ABITS-1:0] B1ADDR;
- output [CFG_DBITS-1:0] B1DATA;
- input B1EN;
-
- wire [31-CFG_DBITS:0] open;
-
-
- generate if (CFG_DBITS == 1) begin
- SDP #(
- `include "bram_init_16.vh"
- .READ_MODE(0),
- .BIT_WIDTH_0(1),
- .BIT_WIDTH_1(1),
- .BLK_SEL(3'b000),
- .RESET_MODE("SYNC")
- ) _TECHMAP_REPLACE_ (
- .CLKA(CLK2), .CLKB(CLK3),
- .WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
- .WREB(1'b0), .CEB(B1EN),
- .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
- .DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
- .DO({open, B1DATA}),
- .ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
- .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
- );
- end else if (CFG_DBITS == 2) begin
- SDP #(
- `include "bram_init_16.vh"
- .READ_MODE(0),
- .BIT_WIDTH_0(2),
- .BIT_WIDTH_1(2),
- .BLK_SEL(3'b000),
- .RESET_MODE("SYNC")
- ) _TECHMAP_REPLACE_ (
- .CLKA(CLK2), .CLKB(CLK3),
- .WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
- .WREB(1'b0), .CEB(B1EN),
- .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
- .DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
- .DO({open, B1DATA}),
- .ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
- .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
- );
- end else if (CFG_DBITS <= 4) begin
- SDP #(
- `include "bram_init_16.vh"
- .READ_MODE(0),
- .BIT_WIDTH_0(4),
- .BIT_WIDTH_1(4),
- .BLK_SEL(3'b000),
- .RESET_MODE("SYNC")
- ) _TECHMAP_REPLACE_ (
- .CLKA(CLK2), .CLKB(CLK3),
- .WREA(A1EN), .OCE(1'b0),
- .WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
- .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
- .DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
- .DO({open, B1DATA}),
- .ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
- .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
- );
- end else if (CFG_DBITS <= 8) begin
- SDP #(
- `include "bram_init_16.vh"
- .READ_MODE(0),
- .BIT_WIDTH_0(8),
- .BIT_WIDTH_1(8),
- .BLK_SEL(3'b000),
- .RESET_MODE("SYNC")
- ) _TECHMAP_REPLACE_ (
- .CLKA(CLK2), .CLKB(CLK3),
- .WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
- .WREB(1'b0), .CEB(B1EN),
- .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
- .DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
- .DO({open, B1DATA}),
- .ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
- .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
- );
- end else if (CFG_DBITS <= 16) begin
- SDP #(
- `include "bram_init_16.vh"
- .READ_MODE(0),
- .BIT_WIDTH_0(16),
- .BIT_WIDTH_1(16),
- .BLK_SEL(3'b000),
- .RESET_MODE("SYNC")
- ) _TECHMAP_REPLACE_ (
- .CLKA(CLK2), .CLKB(CLK3),
- .WREA(|A1EN), .OCE(1'b0),
- .WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
- .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
- .DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
- .DO({open, B1DATA}),
- .ADA({A1ADDR, {(12-CFG_ABITS){1'b0}}, A1EN}),
- .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
- );
- end else if (CFG_DBITS <= 32) begin
- SDP #(
- `include "bram_init_16.vh"
- .READ_MODE(0),
- .BIT_WIDTH_0(32),
- .BIT_WIDTH_1(32),
- .BLK_SEL(3'b000),
- .RESET_MODE("SYNC")
- ) _TECHMAP_REPLACE_ (
- .CLKA(CLK2), .CLKB(CLK3),
- .WREA(|A1EN), .OCE(1'b0),
- .WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
- .RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
- .DI(A1DATA),
- .DO(B1DATA),
- .ADA({A1ADDR, {(10-CFG_ABITS){1'b0}}, A1EN}),
- .ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
- );
- end else begin
- wire TECHMAP_FAIL = 1'b1;
- end endgenerate
-
+`define DEF_FUNCS \
+ function [255:0] init_slice_x8; \
+ input integer idx; \
+ integer i; \
+ for (i = 0; i < 32; i = i + 1) begin \
+ init_slice_x8[i*8+:8] = INIT[(idx * 32 + i) * 9+:8]; \
+ end \
+ endfunction \
+ function [287:0] init_slice_x9; \
+ input integer idx; \
+ init_slice_x9 = INIT[idx * 288+:288]; \
+ endfunction \
+
+`define x8_width(width) (width / 9 * 8 + width % 9)
+`define x8_rd_data(data) {1'bx, data[31:24], 1'bx, data[23:16], 1'bx, data[15:8], 1'bx, data[7:0]}
+`define x8_wr_data(data) {data[34:27], data[25:18], data[16:9], data[7:0]}
+`define wre(width, wr_en, wr_be) (width < 18 ? wr_en | wr_be[0] : wr_en)
+`define addrbe(width, addr, wr_be) (width < 18 ? addr : {addr[13:4], wr_be})
+
+
+`define INIT(func) \
+ .INIT_RAM_00(func('h00)), \
+ .INIT_RAM_01(func('h01)), \
+ .INIT_RAM_02(func('h02)), \
+ .INIT_RAM_03(func('h03)), \
+ .INIT_RAM_04(func('h04)), \
+ .INIT_RAM_05(func('h05)), \
+ .INIT_RAM_06(func('h06)), \
+ .INIT_RAM_07(func('h07)), \
+ .INIT_RAM_08(func('h08)), \
+ .INIT_RAM_09(func('h09)), \
+ .INIT_RAM_0A(func('h0a)), \
+ .INIT_RAM_0B(func('h0b)), \
+ .INIT_RAM_0C(func('h0c)), \
+ .INIT_RAM_0D(func('h0d)), \
+ .INIT_RAM_0E(func('h0e)), \
+ .INIT_RAM_0F(func('h0f)), \
+ .INIT_RAM_10(func('h10)), \
+ .INIT_RAM_11(func('h11)), \
+ .INIT_RAM_12(func('h12)), \
+ .INIT_RAM_13(func('h13)), \
+ .INIT_RAM_14(func('h14)), \
+ .INIT_RAM_15(func('h15)), \
+ .INIT_RAM_16(func('h16)), \
+ .INIT_RAM_17(func('h17)), \
+ .INIT_RAM_18(func('h18)), \
+ .INIT_RAM_19(func('h19)), \
+ .INIT_RAM_1A(func('h1a)), \
+ .INIT_RAM_1B(func('h1b)), \
+ .INIT_RAM_1C(func('h1c)), \
+ .INIT_RAM_1D(func('h1d)), \
+ .INIT_RAM_1E(func('h1e)), \
+ .INIT_RAM_1F(func('h1f)), \
+ .INIT_RAM_20(func('h20)), \
+ .INIT_RAM_21(func('h21)), \
+ .INIT_RAM_22(func('h22)), \
+ .INIT_RAM_23(func('h23)), \
+ .INIT_RAM_24(func('h24)), \
+ .INIT_RAM_25(func('h25)), \
+ .INIT_RAM_26(func('h26)), \
+ .INIT_RAM_27(func('h27)), \
+ .INIT_RAM_28(func('h28)), \
+ .INIT_RAM_29(func('h29)), \
+ .INIT_RAM_2A(func('h2a)), \
+ .INIT_RAM_2B(func('h2b)), \
+ .INIT_RAM_2C(func('h2c)), \
+ .INIT_RAM_2D(func('h2d)), \
+ .INIT_RAM_2E(func('h2e)), \
+ .INIT_RAM_2F(func('h2f)), \
+ .INIT_RAM_30(func('h30)), \
+ .INIT_RAM_31(func('h31)), \
+ .INIT_RAM_32(func('h32)), \
+ .INIT_RAM_33(func('h33)), \
+ .INIT_RAM_34(func('h34)), \
+ .INIT_RAM_35(func('h35)), \
+ .INIT_RAM_36(func('h36)), \
+ .INIT_RAM_37(func('h37)), \
+ .INIT_RAM_38(func('h38)), \
+ .INIT_RAM_39(func('h39)), \
+ .INIT_RAM_3A(func('h3a)), \
+ .INIT_RAM_3B(func('h3b)), \
+ .INIT_RAM_3C(func('h3c)), \
+ .INIT_RAM_3D(func('h3d)), \
+ .INIT_RAM_3E(func('h3e)), \
+ .INIT_RAM_3F(func('h3f)),
+
+module $__GOWIN_SP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_RESET_MODE = "SYNC";
+
+parameter PORT_A_WIDTH = 36;
+parameter PORT_A_WR_BE_WIDTH = 4;
+parameter PORT_A_OPTION_WRITE_MODE = 0;
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input PORT_A_WR_EN;
+input PORT_A_RD_SRST;
+input PORT_A_RD_ARST;
+input [13:0] PORT_A_ADDR;
+input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE;
+input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
+output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
+
+`DEF_FUNCS
+
+wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST;
+wire WRE = `wre(PORT_A_WIDTH, PORT_A_WR_EN, PORT_A_WR_BE);
+wire [13:0] AD = `addrbe(PORT_A_WIDTH, PORT_A_ADDR, PORT_A_WR_BE);
+
+generate
+
+if (PORT_A_WIDTH < 9) begin
+
+ wire [31:0] DI = `x8_wr_data(PORT_A_WR_DATA);
+ wire [31:0] DO;
+
+ assign PORT_A_RD_DATA = `x8_rd_data(DO);
+
+ SP #(
+ `INIT(init_slice_x8)
+ .READ_MODE(1'b0),
+ .WRITE_MODE(PORT_A_OPTION_WRITE_MODE),
+ .BIT_WIDTH(`x8_width(PORT_A_WIDTH)),
+ .BLK_SEL(3'b000),
+ .RESET_MODE(OPTION_RESET_MODE),
+ ) _TECHMAP_REPLACE_ (
+ .BLKSEL(3'b000),
+ .CLK(PORT_A_CLK),
+ .CE(PORT_A_CLK_EN),
+ .WRE(WRE),
+ .RESET(RST),
+ .OCE(1'b0),
+ .AD(AD),
+ .DI(DI),
+ .DO(DO),
+ );
+
+end else begin
+
+ wire [35:0] DI = PORT_A_WR_DATA;
+ wire [35:0] DO;
+
+ assign PORT_A_RD_DATA = DO;
+
+ SPX9 #(
+ `INIT(init_slice_x9)
+ .READ_MODE(1'b0),
+ .WRITE_MODE(PORT_A_OPTION_WRITE_MODE),
+ .BIT_WIDTH(PORT_A_WIDTH),
+ .BLK_SEL(3'b000),
+ .RESET_MODE(OPTION_RESET_MODE),
+ ) _TECHMAP_REPLACE_ (
+ .BLKSEL(3'b000),
+ .CLK(PORT_A_CLK),
+ .CE(PORT_A_CLK_EN),
+ .WRE(WRE),
+ .RESET(RST),
+ .OCE(1'b0),
+ .AD(AD),
+ .DI(DI),
+ .DO(DO),
+ );
+
+end
+
+endgenerate
+
+endmodule
+
+
+module $__GOWIN_DP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_RESET_MODE = "SYNC";
+
+parameter PORT_A_WIDTH = 18;
+parameter PORT_A_WR_BE_WIDTH = 2;
+parameter PORT_A_OPTION_WRITE_MODE = 0;
+
+parameter PORT_B_WIDTH = 18;
+parameter PORT_B_WR_BE_WIDTH = 2;
+parameter PORT_B_OPTION_WRITE_MODE = 0;
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input PORT_A_WR_EN;
+input PORT_A_RD_SRST;
+input PORT_A_RD_ARST;
+input [13:0] PORT_A_ADDR;
+input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE;
+input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
+output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input PORT_B_WR_EN;
+input PORT_B_RD_SRST;
+input PORT_B_RD_ARST;
+input [13:0] PORT_B_ADDR;
+input [PORT_A_WR_BE_WIDTH-1:0] PORT_B_WR_BE;
+input [PORT_A_WIDTH-1:0] PORT_B_WR_DATA;
+output [PORT_A_WIDTH-1:0] PORT_B_RD_DATA;
+
+`DEF_FUNCS
+
+wire RSTA = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST;
+wire RSTB = OPTION_RESET_MODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST;
+wire WREA = `wre(PORT_A_WIDTH, PORT_A_WR_EN, PORT_A_WR_BE);
+wire WREB = `wre(PORT_B_WIDTH, PORT_B_WR_EN, PORT_B_WR_BE);
+wire [13:0] ADA = `addrbe(PORT_A_WIDTH, PORT_A_ADDR, PORT_A_WR_BE);
+wire [13:0] ADB = `addrbe(PORT_B_WIDTH, PORT_B_ADDR, PORT_B_WR_BE);
+
+generate
+
+if (PORT_A_WIDTH < 9 || PORT_B_WIDTH < 9) begin
+
+ wire [15:0] DIA = `x8_wr_data(PORT_A_WR_DATA);
+ wire [15:0] DIB = `x8_wr_data(PORT_B_WR_DATA);
+ wire [15:0] DOA;
+ wire [15:0] DOB;
+
+ assign PORT_A_RD_DATA = `x8_rd_data(DOA);
+ assign PORT_B_RD_DATA = `x8_rd_data(DOB);
+
+ DP #(
+ `INIT(init_slice_x8)
+ .READ_MODE0(1'b0),
+ .READ_MODE1(1'b0),
+ .WRITE_MODE0(PORT_A_OPTION_WRITE_MODE),
+ .WRITE_MODE1(PORT_B_OPTION_WRITE_MODE),
+ .BIT_WIDTH_0(`x8_width(PORT_A_WIDTH)),
+ .BIT_WIDTH_1(`x8_width(PORT_B_WIDTH)),
+ .BLK_SEL(3'b000),
+ .RESET_MODE(OPTION_RESET_MODE),
+ ) _TECHMAP_REPLACE_ (
+ .BLKSEL(3'b000),
+
+ .CLKA(PORT_A_CLK),
+ .CEA(PORT_A_CLK_EN),
+ .WREA(WREA),
+ .RESETA(RSTA),
+ .OCEA(1'b0),
+ .ADA(ADA),
+ .DIA(DIA),
+ .DOA(DOA),
+
+ .CLKB(PORT_B_CLK),
+ .CEB(PORT_B_CLK_EN),
+ .WREB(WREB),
+ .RESETB(RSTB),
+ .OCEB(1'b0),
+ .ADB(ADB),
+ .DIB(DIB),
+ .DOB(DOB),
+ );
+
+end else begin
+
+ wire [17:0] DIA = PORT_A_WR_DATA;
+ wire [17:0] DIB = PORT_B_WR_DATA;
+ wire [17:0] DOA;
+ wire [17:0] DOB;
+
+ assign PORT_A_RD_DATA = DOA;
+ assign PORT_B_RD_DATA = DOB;
+
+ DPX9 #(
+ `INIT(init_slice_x9)
+ .READ_MODE0(1'b0),
+ .READ_MODE1(1'b0),
+ .WRITE_MODE0(PORT_A_OPTION_WRITE_MODE),
+ .WRITE_MODE1(PORT_B_OPTION_WRITE_MODE),
+ .BIT_WIDTH_0(PORT_A_WIDTH),
+ .BIT_WIDTH_1(PORT_B_WIDTH),
+ .BLK_SEL(3'b000),
+ .RESET_MODE(OPTION_RESET_MODE),
+ ) _TECHMAP_REPLACE_ (
+ .BLKSEL(3'b000),
+
+ .CLKA(PORT_A_CLK),
+ .CEA(PORT_A_CLK_EN),
+ .WREA(WREA),
+ .RESETA(RSTA),
+ .OCEA(1'b0),
+ .ADA(ADA),
+ .DIA(DIA),
+ .DOA(DOA),
+
+ .CLKB(PORT_B_CLK),
+ .CEB(PORT_B_CLK_EN),
+ .WREB(WREB),
+ .RESETB(RSTB),
+ .OCEB(1'b0),
+ .ADB(ADB),
+ .DIB(DIB),
+ .DOB(DOB),
+ );
+
+end
+
+endgenerate
+
+endmodule
+
+
+module $__GOWIN_SDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_RESET_MODE = "SYNC";
+
+parameter PORT_R_WIDTH = 18;
+
+parameter PORT_W_WIDTH = 18;
+parameter PORT_W_WR_BE_WIDTH = 2;
+
+input PORT_R_CLK;
+input PORT_R_CLK_EN;
+input PORT_R_RD_SRST;
+input PORT_R_RD_ARST;
+input [13:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+
+input PORT_W_CLK;
+input PORT_W_CLK_EN;
+input PORT_W_WR_EN;
+input [13:0] PORT_W_ADDR;
+input [PORT_W_WR_BE_WIDTH-1:0] PORT_W_WR_BE;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+
+`DEF_FUNCS
+
+wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST;
+wire WRE = `wre(PORT_W_WIDTH, PORT_W_WR_EN, PORT_W_WR_BE);
+wire [13:0] ADW = `addrbe(PORT_W_WIDTH, PORT_W_ADDR, PORT_W_WR_BE);
+
+generate
+
+if (PORT_W_WIDTH < 9 || PORT_R_WIDTH < 9) begin
+
+ wire [31:0] DI = `x8_wr_data(PORT_W_WR_DATA);
+ wire [31:0] DO;
+
+ assign PORT_R_RD_DATA = `x8_rd_data(DO);
+
+ SDP #(
+ `INIT(init_slice_x8)
+ .READ_MODE(1'b0),
+ .BIT_WIDTH_0(`x8_width(PORT_W_WIDTH)),
+ .BIT_WIDTH_1(`x8_width(PORT_R_WIDTH)),
+ .BLK_SEL(3'b000),
+ .RESET_MODE(OPTION_RESET_MODE),
+ ) _TECHMAP_REPLACE_ (
+ .BLKSEL(3'b000),
+
+ .CLKA(PORT_W_CLK),
+ .CEA(PORT_W_CLK_EN),
+ .WREA(WRE),
+ .RESETA(1'b0),
+ .ADA(ADW),
+ .DI(DI),
+
+ .CLKB(PORT_R_CLK),
+ .CEB(PORT_R_CLK_EN),
+ .WREB(1'b0),
+ .RESETB(RST),
+ .OCE(1'b0),
+ .ADB(PORT_R_ADDR),
+ .DO(DO),
+ );
+
+end else begin
+
+ wire [35:0] DI = PORT_W_WR_DATA;
+ wire [35:0] DO;
+
+ assign PORT_R_RD_DATA = DO;
+
+ SDPX9 #(
+ `INIT(init_slice_x9)
+ .READ_MODE(1'b0),
+ .BIT_WIDTH_0(PORT_W_WIDTH),
+ .BIT_WIDTH_1(PORT_R_WIDTH),
+ .BLK_SEL(3'b000),
+ .RESET_MODE(OPTION_RESET_MODE),
+ ) _TECHMAP_REPLACE_ (
+ .BLKSEL(3'b000),
+
+ .CLKA(PORT_W_CLK),
+ .CEA(PORT_W_CLK_EN),
+ .WREA(WRE),
+ .RESETA(1'b0),
+ .ADA(ADW),
+ .DI(DI),
+
+ .CLKB(PORT_R_CLK),
+ .CEB(PORT_R_CLK_EN),
+ .WREB(1'b0),
+ .RESETB(RST),
+ .OCE(1'b0),
+ .ADB(PORT_R_ADDR),
+ .DO(DO),
+ );
+
+end
+
+endgenerate
+
endmodule
diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v
index 41398409d..736aa0707 100644
--- a/techlibs/gowin/cells_sim.v
+++ b/techlibs/gowin/cells_sim.v
@@ -550,7 +550,6 @@ module GND(output G);
assign G = 0;
endmodule
-(* abc9_box *)
module IBUF(output O, input I);
specify
@@ -560,7 +559,6 @@ module IBUF(output O, input I);
assign O = I;
endmodule
-(* abc9_box *)
module OBUF(output O, input I);
specify
@@ -584,6 +582,39 @@ module IOBUF (O, IO, I, OEN);
assign I = IO;
endmodule
+module TLVDS_OBUF (I, O, OB);
+ input I;
+ output O;
+ output OB;
+ assign O = I;
+ assign OB = ~I;
+endmodule
+
+(* blackbox *)
+module ODDR(D0, D1, TX, CLK, Q0, Q1);
+ input D0;
+ input D1;
+ input TX;
+ input CLK;
+ output Q0;
+ output Q1;
+ parameter TXCLK_POL = 0;
+ parameter INIT = 0;
+endmodule
+
+(* blackbox *)
+module ODDRC(D0, D1, CLEAR, TX, CLK, Q0, Q1);
+ input D0;
+ input D1;
+ input CLEAR;
+ input TX;
+ input CLK;
+ output Q0;
+ output Q1;
+ parameter TXCLK_POL = 0;
+ parameter INIT = 0;
+endmodule
+
module GSR (input GSRI);
wire GSRO = GSRI;
endmodule
@@ -674,134 +705,610 @@ end
endmodule
+
+module RAM16S1 (DO, DI, AD, WRE, CLK);
+
+parameter INIT_0 = 16'h0000;
+
+input [3:0] AD;
+input DI;
+output DO;
+input CLK;
+input WRE;
+
+specify
+ (AD *> DO) = (270, 405);
+ $setup(DI, posedge CLK, 62);
+ $setup(WRE, posedge CLK, 62);
+ $setup(AD, posedge CLK, 62);
+ (posedge CLK => (DO : 1'bx)) = (474, 565);
+endspecify
+
+reg [15:0] mem;
+
+initial begin
+ mem = INIT_0;
+end
+
+assign DO = mem[AD];
+
+always @(posedge CLK) begin
+ if (WRE) begin
+ mem[AD] <= DI;
+ end
+end
+
+endmodule
+
+
+module RAM16S2 (DO, DI, AD, WRE, CLK);
+
+parameter INIT_0 = 16'h0000;
+parameter INIT_1 = 16'h0000;
+
+input [3:0] AD;
+input [1:0] DI;
+output [1:0] DO;
+input CLK;
+input WRE;
+
+specify
+ (AD *> DO) = (270, 405);
+ $setup(DI, posedge CLK, 62);
+ $setup(WRE, posedge CLK, 62);
+ $setup(AD, posedge CLK, 62);
+ (posedge CLK => (DO : 2'bx)) = (474, 565);
+endspecify
+
+reg [15:0] mem0, mem1;
+
+initial begin
+ mem0 = INIT_0;
+ mem1 = INIT_1;
+end
+
+assign DO[0] = mem0[AD];
+assign DO[1] = mem1[AD];
+
+always @(posedge CLK) begin
+ if (WRE) begin
+ mem0[AD] <= DI[0];
+ mem1[AD] <= DI[1];
+ end
+end
+
+endmodule
+
+
module RAM16S4 (DO, DI, AD, WRE, CLK);
- parameter WIDTH = 4;
- parameter INIT_0 = 16'h0000;
- parameter INIT_1 = 16'h0000;
- parameter INIT_2 = 16'h0000;
- parameter INIT_3 = 16'h0000;
-
- input [WIDTH-1:0] AD;
- input [WIDTH-1:0] DI;
- output [WIDTH-1:0] DO;
- input CLK;
- input WRE;
- specify
- (AD => DO) = (270, 405);
+parameter INIT_0 = 16'h0000;
+parameter INIT_1 = 16'h0000;
+parameter INIT_2 = 16'h0000;
+parameter INIT_3 = 16'h0000;
+
+input [3:0] AD;
+input [3:0] DI;
+output [3:0] DO;
+input CLK;
+input WRE;
+
+specify
+ (AD *> DO) = (270, 405);
$setup(DI, posedge CLK, 62);
$setup(WRE, posedge CLK, 62);
$setup(AD, posedge CLK, 62);
- (posedge CLK => (DO : {WIDTH{1'bx}})) = (474, 565);
- endspecify
+ (posedge CLK => (DO : 4'bx)) = (474, 565);
+endspecify
+
+reg [15:0] mem0, mem1, mem2, mem3;
+
+initial begin
+ mem0 = INIT_0;
+ mem1 = INIT_1;
+ mem2 = INIT_2;
+ mem3 = INIT_3;
+end
+
+assign DO[0] = mem0[AD];
+assign DO[1] = mem1[AD];
+assign DO[2] = mem2[AD];
+assign DO[3] = mem3[AD];
+
+always @(posedge CLK) begin
+ if (WRE) begin
+ mem0[AD] <= DI[0];
+ mem1[AD] <= DI[1];
+ mem2[AD] <= DI[2];
+ mem3[AD] <= DI[3];
+ end
+end
+
+endmodule
+
+
+module RAM16SDP1 (DO, DI, WAD, RAD, WRE, CLK);
+
+parameter INIT_0 = 16'h0000;
+
+input [3:0] WAD;
+input [3:0] RAD;
+input DI;
+output DO;
+input CLK;
+input WRE;
+
+specify
+ (RAD *> DO) = (270, 405);
+ $setup(DI, posedge CLK, 62);
+ $setup(WRE, posedge CLK, 62);
+ $setup(WAD, posedge CLK, 62);
+ (posedge CLK => (DO : 1'bx)) = (474, 565);
+endspecify
+
+reg [15:0] mem;
+
+initial begin
+ mem = INIT_0;
+end
+
+assign DO = mem[RAD];
+
+always @(posedge CLK) begin
+ if (WRE) begin
+ mem[WAD] <= DI;
+ end
+end
+
+endmodule
+
+
+module RAM16SDP2 (DO, DI, WAD, RAD, WRE, CLK);
+
+parameter INIT_0 = 16'h0000;
+parameter INIT_1 = 16'h0000;
+
+input [3:0] WAD;
+input [3:0] RAD;
+input [1:0] DI;
+output [1:0] DO;
+input CLK;
+input WRE;
+
+specify
+ (RAD *> DO) = (270, 405);
+ $setup(DI, posedge CLK, 62);
+ $setup(WRE, posedge CLK, 62);
+ $setup(WAD, posedge CLK, 62);
+ (posedge CLK => (DO : 2'bx)) = (474, 565);
+endspecify
+
+reg [15:0] mem0, mem1;
+
+initial begin
+ mem0 = INIT_0;
+ mem1 = INIT_1;
+end
+
+assign DO[0] = mem0[RAD];
+assign DO[1] = mem1[RAD];
+
+always @(posedge CLK) begin
+ if (WRE) begin
+ mem0[WAD] <= DI[0];
+ mem1[WAD] <= DI[1];
+ end
+end
+
+endmodule
+
+
+module RAM16SDP4 (DO, DI, WAD, RAD, WRE, CLK);
+
+parameter INIT_0 = 16'h0000;
+parameter INIT_1 = 16'h0000;
+parameter INIT_2 = 16'h0000;
+parameter INIT_3 = 16'h0000;
+
+input [3:0] WAD;
+input [3:0] RAD;
+input [3:0] DI;
+output [3:0] DO;
+input CLK;
+input WRE;
+
+specify
+ (RAD *> DO) = (270, 405);
+ $setup(DI, posedge CLK, 62);
+ $setup(WRE, posedge CLK, 62);
+ $setup(WAD, posedge CLK, 62);
+ (posedge CLK => (DO : 4'bx)) = (474, 565);
+endspecify
+
+reg [15:0] mem0, mem1, mem2, mem3;
+
+initial begin
+ mem0 = INIT_0;
+ mem1 = INIT_1;
+ mem2 = INIT_2;
+ mem3 = INIT_3;
+end
+
+assign DO[0] = mem0[RAD];
+assign DO[1] = mem1[RAD];
+assign DO[2] = mem2[RAD];
+assign DO[3] = mem3[RAD];
+
+always @(posedge CLK) begin
+ if (WRE) begin
+ mem0[WAD] <= DI[0];
+ mem1[WAD] <= DI[1];
+ mem2[WAD] <= DI[2];
+ mem3[WAD] <= DI[3];
+ end
+end
+
+endmodule
+
+
+(* blackbox *)
+module SP (DO, DI, BLKSEL, AD, WRE, CLK, CE, OCE, RESET);
+
+// 1 Enables output pipeline registers.
+parameter READ_MODE = 1'b0;
+// 0: no read on write, 1: transparent, 2: read-before-write
+parameter WRITE_MODE = 2'b00;
+parameter BIT_WIDTH = 32; // 1, 2, 4, 8, 16, 32
+parameter BLK_SEL = 3'b000;
+parameter RESET_MODE = "SYNC";
+parameter INIT_RAM_00 = 256'h0;
+parameter INIT_RAM_01 = 256'h0;
+parameter INIT_RAM_02 = 256'h0;
+parameter INIT_RAM_03 = 256'h0;
+parameter INIT_RAM_04 = 256'h0;
+parameter INIT_RAM_05 = 256'h0;
+parameter INIT_RAM_06 = 256'h0;
+parameter INIT_RAM_07 = 256'h0;
+parameter INIT_RAM_08 = 256'h0;
+parameter INIT_RAM_09 = 256'h0;
+parameter INIT_RAM_0A = 256'h0;
+parameter INIT_RAM_0B = 256'h0;
+parameter INIT_RAM_0C = 256'h0;
+parameter INIT_RAM_0D = 256'h0;
+parameter INIT_RAM_0E = 256'h0;
+parameter INIT_RAM_0F = 256'h0;
+parameter INIT_RAM_10 = 256'h0;
+parameter INIT_RAM_11 = 256'h0;
+parameter INIT_RAM_12 = 256'h0;
+parameter INIT_RAM_13 = 256'h0;
+parameter INIT_RAM_14 = 256'h0;
+parameter INIT_RAM_15 = 256'h0;
+parameter INIT_RAM_16 = 256'h0;
+parameter INIT_RAM_17 = 256'h0;
+parameter INIT_RAM_18 = 256'h0;
+parameter INIT_RAM_19 = 256'h0;
+parameter INIT_RAM_1A = 256'h0;
+parameter INIT_RAM_1B = 256'h0;
+parameter INIT_RAM_1C = 256'h0;
+parameter INIT_RAM_1D = 256'h0;
+parameter INIT_RAM_1E = 256'h0;
+parameter INIT_RAM_1F = 256'h0;
+parameter INIT_RAM_20 = 256'h0;
+parameter INIT_RAM_21 = 256'h0;
+parameter INIT_RAM_22 = 256'h0;
+parameter INIT_RAM_23 = 256'h0;
+parameter INIT_RAM_24 = 256'h0;
+parameter INIT_RAM_25 = 256'h0;
+parameter INIT_RAM_26 = 256'h0;
+parameter INIT_RAM_27 = 256'h0;
+parameter INIT_RAM_28 = 256'h0;
+parameter INIT_RAM_29 = 256'h0;
+parameter INIT_RAM_2A = 256'h0;
+parameter INIT_RAM_2B = 256'h0;
+parameter INIT_RAM_2C = 256'h0;
+parameter INIT_RAM_2D = 256'h0;
+parameter INIT_RAM_2E = 256'h0;
+parameter INIT_RAM_2F = 256'h0;
+parameter INIT_RAM_30 = 256'h0;
+parameter INIT_RAM_31 = 256'h0;
+parameter INIT_RAM_32 = 256'h0;
+parameter INIT_RAM_33 = 256'h0;
+parameter INIT_RAM_34 = 256'h0;
+parameter INIT_RAM_35 = 256'h0;
+parameter INIT_RAM_36 = 256'h0;
+parameter INIT_RAM_37 = 256'h0;
+parameter INIT_RAM_38 = 256'h0;
+parameter INIT_RAM_39 = 256'h0;
+parameter INIT_RAM_3A = 256'h0;
+parameter INIT_RAM_3B = 256'h0;
+parameter INIT_RAM_3C = 256'h0;
+parameter INIT_RAM_3D = 256'h0;
+parameter INIT_RAM_3E = 256'h0;
+parameter INIT_RAM_3F = 256'h0;
+
+output [31:0] DO;
+input [31:0] DI;
+input [2:0] BLKSEL;
+input [13:0] AD;
+input WRE;
+input CLK;
+input CE;
+input OCE;
+input RESET;
+
+endmodule
+
+(* blackbox *)
+module SPX9 (DO, DI, BLKSEL, AD, WRE, CLK, CE, OCE, RESET);
- reg [15:0] mem0, mem1, mem2, mem3;
-
- initial begin
- mem0 = INIT_0;
- mem1 = INIT_1;
- mem2 = INIT_2;
- mem3 = INIT_3;
- end
-
- assign DO[0] = mem0[AD];
- assign DO[1] = mem1[AD];
- assign DO[2] = mem2[AD];
- assign DO[3] = mem3[AD];
-
- always @(posedge CLK) begin
- if (WRE) begin
- mem0[AD] <= DI[0];
- mem1[AD] <= DI[1];
- mem2[AD] <= DI[2];
- mem3[AD] <= DI[3];
- end
- end
-
-endmodule // RAM16S4
+// 1 Enables output pipeline registers.
+parameter READ_MODE = 1'b0;
+// 0: no read on write, 1: transparent, 2: read-before-write
+parameter WRITE_MODE = 2'b00;
+parameter BIT_WIDTH = 36; // 9, 18, 36
+parameter BLK_SEL = 3'b000;
+parameter RESET_MODE = "SYNC";
+parameter INIT_RAM_00 = 288'h0;
+parameter INIT_RAM_01 = 288'h0;
+parameter INIT_RAM_02 = 288'h0;
+parameter INIT_RAM_03 = 288'h0;
+parameter INIT_RAM_04 = 288'h0;
+parameter INIT_RAM_05 = 288'h0;
+parameter INIT_RAM_06 = 288'h0;
+parameter INIT_RAM_07 = 288'h0;
+parameter INIT_RAM_08 = 288'h0;
+parameter INIT_RAM_09 = 288'h0;
+parameter INIT_RAM_0A = 288'h0;
+parameter INIT_RAM_0B = 288'h0;
+parameter INIT_RAM_0C = 288'h0;
+parameter INIT_RAM_0D = 288'h0;
+parameter INIT_RAM_0E = 288'h0;
+parameter INIT_RAM_0F = 288'h0;
+parameter INIT_RAM_10 = 288'h0;
+parameter INIT_RAM_11 = 288'h0;
+parameter INIT_RAM_12 = 288'h0;
+parameter INIT_RAM_13 = 288'h0;
+parameter INIT_RAM_14 = 288'h0;
+parameter INIT_RAM_15 = 288'h0;
+parameter INIT_RAM_16 = 288'h0;
+parameter INIT_RAM_17 = 288'h0;
+parameter INIT_RAM_18 = 288'h0;
+parameter INIT_RAM_19 = 288'h0;
+parameter INIT_RAM_1A = 288'h0;
+parameter INIT_RAM_1B = 288'h0;
+parameter INIT_RAM_1C = 288'h0;
+parameter INIT_RAM_1D = 288'h0;
+parameter INIT_RAM_1E = 288'h0;
+parameter INIT_RAM_1F = 288'h0;
+parameter INIT_RAM_20 = 288'h0;
+parameter INIT_RAM_21 = 288'h0;
+parameter INIT_RAM_22 = 288'h0;
+parameter INIT_RAM_23 = 288'h0;
+parameter INIT_RAM_24 = 288'h0;
+parameter INIT_RAM_25 = 288'h0;
+parameter INIT_RAM_26 = 288'h0;
+parameter INIT_RAM_27 = 288'h0;
+parameter INIT_RAM_28 = 288'h0;
+parameter INIT_RAM_29 = 288'h0;
+parameter INIT_RAM_2A = 288'h0;
+parameter INIT_RAM_2B = 288'h0;
+parameter INIT_RAM_2C = 288'h0;
+parameter INIT_RAM_2D = 288'h0;
+parameter INIT_RAM_2E = 288'h0;
+parameter INIT_RAM_2F = 288'h0;
+parameter INIT_RAM_30 = 288'h0;
+parameter INIT_RAM_31 = 288'h0;
+parameter INIT_RAM_32 = 288'h0;
+parameter INIT_RAM_33 = 288'h0;
+parameter INIT_RAM_34 = 288'h0;
+parameter INIT_RAM_35 = 288'h0;
+parameter INIT_RAM_36 = 288'h0;
+parameter INIT_RAM_37 = 288'h0;
+parameter INIT_RAM_38 = 288'h0;
+parameter INIT_RAM_39 = 288'h0;
+parameter INIT_RAM_3A = 288'h0;
+parameter INIT_RAM_3B = 288'h0;
+parameter INIT_RAM_3C = 288'h0;
+parameter INIT_RAM_3D = 288'h0;
+parameter INIT_RAM_3E = 288'h0;
+parameter INIT_RAM_3F = 288'h0;
+
+output [35:0] DO;
+input [35:0] DI;
+input [2:0] BLKSEL;
+input [13:0] AD;
+input WRE;
+input CLK;
+input CE;
+input OCE;
+input RESET;
+
+endmodule
(* blackbox *)
module SDP (DO, DI, BLKSEL, ADA, ADB, WREA, WREB, CLKA, CLKB, CEA, CEB, OCE, RESETA, RESETB);
-//1'b0: Bypass mode; 1'b1 Pipeline mode
+
parameter READ_MODE = 1'b0;
parameter BIT_WIDTH_0 = 32; // 1, 2, 4, 8, 16, 32
parameter BIT_WIDTH_1 = 32; // 1, 2, 4, 8, 16, 32
parameter BLK_SEL = 3'b000;
parameter RESET_MODE = "SYNC";
-parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-
-input CLKA, CEA, CLKB, CEB;
-input OCE; // clock enable of memory output register
-input RESETA, RESETB; // resets output registers, not memory contents
-input WREA, WREB; // 1'b0: read enabled; 1'b1: write enabled
-input [13:0] ADA, ADB;
+parameter INIT_RAM_00 = 256'h0;
+parameter INIT_RAM_01 = 256'h0;
+parameter INIT_RAM_02 = 256'h0;
+parameter INIT_RAM_03 = 256'h0;
+parameter INIT_RAM_04 = 256'h0;
+parameter INIT_RAM_05 = 256'h0;
+parameter INIT_RAM_06 = 256'h0;
+parameter INIT_RAM_07 = 256'h0;
+parameter INIT_RAM_08 = 256'h0;
+parameter INIT_RAM_09 = 256'h0;
+parameter INIT_RAM_0A = 256'h0;
+parameter INIT_RAM_0B = 256'h0;
+parameter INIT_RAM_0C = 256'h0;
+parameter INIT_RAM_0D = 256'h0;
+parameter INIT_RAM_0E = 256'h0;
+parameter INIT_RAM_0F = 256'h0;
+parameter INIT_RAM_10 = 256'h0;
+parameter INIT_RAM_11 = 256'h0;
+parameter INIT_RAM_12 = 256'h0;
+parameter INIT_RAM_13 = 256'h0;
+parameter INIT_RAM_14 = 256'h0;
+parameter INIT_RAM_15 = 256'h0;
+parameter INIT_RAM_16 = 256'h0;
+parameter INIT_RAM_17 = 256'h0;
+parameter INIT_RAM_18 = 256'h0;
+parameter INIT_RAM_19 = 256'h0;
+parameter INIT_RAM_1A = 256'h0;
+parameter INIT_RAM_1B = 256'h0;
+parameter INIT_RAM_1C = 256'h0;
+parameter INIT_RAM_1D = 256'h0;
+parameter INIT_RAM_1E = 256'h0;
+parameter INIT_RAM_1F = 256'h0;
+parameter INIT_RAM_20 = 256'h0;
+parameter INIT_RAM_21 = 256'h0;
+parameter INIT_RAM_22 = 256'h0;
+parameter INIT_RAM_23 = 256'h0;
+parameter INIT_RAM_24 = 256'h0;
+parameter INIT_RAM_25 = 256'h0;
+parameter INIT_RAM_26 = 256'h0;
+parameter INIT_RAM_27 = 256'h0;
+parameter INIT_RAM_28 = 256'h0;
+parameter INIT_RAM_29 = 256'h0;
+parameter INIT_RAM_2A = 256'h0;
+parameter INIT_RAM_2B = 256'h0;
+parameter INIT_RAM_2C = 256'h0;
+parameter INIT_RAM_2D = 256'h0;
+parameter INIT_RAM_2E = 256'h0;
+parameter INIT_RAM_2F = 256'h0;
+parameter INIT_RAM_30 = 256'h0;
+parameter INIT_RAM_31 = 256'h0;
+parameter INIT_RAM_32 = 256'h0;
+parameter INIT_RAM_33 = 256'h0;
+parameter INIT_RAM_34 = 256'h0;
+parameter INIT_RAM_35 = 256'h0;
+parameter INIT_RAM_36 = 256'h0;
+parameter INIT_RAM_37 = 256'h0;
+parameter INIT_RAM_38 = 256'h0;
+parameter INIT_RAM_39 = 256'h0;
+parameter INIT_RAM_3A = 256'h0;
+parameter INIT_RAM_3B = 256'h0;
+parameter INIT_RAM_3C = 256'h0;
+parameter INIT_RAM_3D = 256'h0;
+parameter INIT_RAM_3E = 256'h0;
+parameter INIT_RAM_3F = 256'h0;
+
+output [31:0] DO;
input [31:0] DI;
input [2:0] BLKSEL;
-output [31:0] DO;
+input [13:0] ADA, ADB;
+input WREA, WREB;
+input CLKA, CLKB;
+input CEA, CEB;
+input OCE;
+input RESETA, RESETB;
+
+specify
+ (posedge CLKB => (DO : DI)) = (419, 493);
+ $setup(RESETA, posedge CLKA, 62);
+ $setup(RESETB, posedge CLKB, 62);
+ $setup(OCE, posedge CLKB, 62);
+ $setup(CEA, posedge CLKA, 62);
+ $setup(CEB, posedge CLKB, 62);
+ $setup(OCE, posedge CLKB, 62);
+ $setup(WREA, posedge CLKA, 62);
+ $setup(WREB, posedge CLKB, 62);
+ $setup(DI, posedge CLKA, 62);
+ $setup(ADA, posedge CLKA, 62);
+ $setup(ADB, posedge CLKB, 62);
+ $setup(BLKSEL, posedge CLKA, 62);
+endspecify
+
+endmodule
+
+(* blackbox *)
+module SDPX9 (DO, DI, BLKSEL, ADA, ADB, WREA, WREB, CLKA, CLKB, CEA, CEB, OCE, RESETA, RESETB);
+
+parameter READ_MODE = 1'b0;
+parameter BIT_WIDTH_0 = 36; // 9, 18, 36
+parameter BIT_WIDTH_1 = 36; // 9, 18, 36
+parameter BLK_SEL = 3'b000;
+parameter RESET_MODE = "SYNC";
+parameter INIT_RAM_00 = 288'h0;
+parameter INIT_RAM_01 = 288'h0;
+parameter INIT_RAM_02 = 288'h0;
+parameter INIT_RAM_03 = 288'h0;
+parameter INIT_RAM_04 = 288'h0;
+parameter INIT_RAM_05 = 288'h0;
+parameter INIT_RAM_06 = 288'h0;
+parameter INIT_RAM_07 = 288'h0;
+parameter INIT_RAM_08 = 288'h0;
+parameter INIT_RAM_09 = 288'h0;
+parameter INIT_RAM_0A = 288'h0;
+parameter INIT_RAM_0B = 288'h0;
+parameter INIT_RAM_0C = 288'h0;
+parameter INIT_RAM_0D = 288'h0;
+parameter INIT_RAM_0E = 288'h0;
+parameter INIT_RAM_0F = 288'h0;
+parameter INIT_RAM_10 = 288'h0;
+parameter INIT_RAM_11 = 288'h0;
+parameter INIT_RAM_12 = 288'h0;
+parameter INIT_RAM_13 = 288'h0;
+parameter INIT_RAM_14 = 288'h0;
+parameter INIT_RAM_15 = 288'h0;
+parameter INIT_RAM_16 = 288'h0;
+parameter INIT_RAM_17 = 288'h0;
+parameter INIT_RAM_18 = 288'h0;
+parameter INIT_RAM_19 = 288'h0;
+parameter INIT_RAM_1A = 288'h0;
+parameter INIT_RAM_1B = 288'h0;
+parameter INIT_RAM_1C = 288'h0;
+parameter INIT_RAM_1D = 288'h0;
+parameter INIT_RAM_1E = 288'h0;
+parameter INIT_RAM_1F = 288'h0;
+parameter INIT_RAM_20 = 288'h0;
+parameter INIT_RAM_21 = 288'h0;
+parameter INIT_RAM_22 = 288'h0;
+parameter INIT_RAM_23 = 288'h0;
+parameter INIT_RAM_24 = 288'h0;
+parameter INIT_RAM_25 = 288'h0;
+parameter INIT_RAM_26 = 288'h0;
+parameter INIT_RAM_27 = 288'h0;
+parameter INIT_RAM_28 = 288'h0;
+parameter INIT_RAM_29 = 288'h0;
+parameter INIT_RAM_2A = 288'h0;
+parameter INIT_RAM_2B = 288'h0;
+parameter INIT_RAM_2C = 288'h0;
+parameter INIT_RAM_2D = 288'h0;
+parameter INIT_RAM_2E = 288'h0;
+parameter INIT_RAM_2F = 288'h0;
+parameter INIT_RAM_30 = 288'h0;
+parameter INIT_RAM_31 = 288'h0;
+parameter INIT_RAM_32 = 288'h0;
+parameter INIT_RAM_33 = 288'h0;
+parameter INIT_RAM_34 = 288'h0;
+parameter INIT_RAM_35 = 288'h0;
+parameter INIT_RAM_36 = 288'h0;
+parameter INIT_RAM_37 = 288'h0;
+parameter INIT_RAM_38 = 288'h0;
+parameter INIT_RAM_39 = 288'h0;
+parameter INIT_RAM_3A = 288'h0;
+parameter INIT_RAM_3B = 288'h0;
+parameter INIT_RAM_3C = 288'h0;
+parameter INIT_RAM_3D = 288'h0;
+parameter INIT_RAM_3E = 288'h0;
+parameter INIT_RAM_3F = 288'h0;
+
+output [35:0] DO;
+input [35:0] DI;
+input [2:0] BLKSEL;
+input [13:0] ADA, ADB;
+input WREA, WREB;
+input CLKA, CLKB;
+input CEA, CEB;
+input OCE;
+input RESETA, RESETB;
specify
(posedge CLKB => (DO : DI)) = (419, 493);
@@ -821,6 +1328,184 @@ endspecify
endmodule
+
+(* blackbox *)
+module DP (DOA, DOB, DIA, DIB, BLKSEL, ADA, ADB, WREA, WREB, CLKA, CLKB, CEA, CEB, OCEA, OCEB, RESETA, RESETB);
+
+parameter READ_MODE0 = 1'b0;
+parameter READ_MODE1 = 1'b0;
+parameter WRITE_MODE0 = 2'b00;
+parameter WRITE_MODE1 = 2'b00;
+parameter BIT_WIDTH_0 = 16; // 1, 2, 4, 8, 16
+parameter BIT_WIDTH_1 = 16; // 1, 2, 4, 8, 16
+parameter BLK_SEL = 3'b000;
+parameter RESET_MODE = "SYNC";
+parameter INIT_RAM_00 = 256'h0;
+parameter INIT_RAM_01 = 256'h0;
+parameter INIT_RAM_02 = 256'h0;
+parameter INIT_RAM_03 = 256'h0;
+parameter INIT_RAM_04 = 256'h0;
+parameter INIT_RAM_05 = 256'h0;
+parameter INIT_RAM_06 = 256'h0;
+parameter INIT_RAM_07 = 256'h0;
+parameter INIT_RAM_08 = 256'h0;
+parameter INIT_RAM_09 = 256'h0;
+parameter INIT_RAM_0A = 256'h0;
+parameter INIT_RAM_0B = 256'h0;
+parameter INIT_RAM_0C = 256'h0;
+parameter INIT_RAM_0D = 256'h0;
+parameter INIT_RAM_0E = 256'h0;
+parameter INIT_RAM_0F = 256'h0;
+parameter INIT_RAM_10 = 256'h0;
+parameter INIT_RAM_11 = 256'h0;
+parameter INIT_RAM_12 = 256'h0;
+parameter INIT_RAM_13 = 256'h0;
+parameter INIT_RAM_14 = 256'h0;
+parameter INIT_RAM_15 = 256'h0;
+parameter INIT_RAM_16 = 256'h0;
+parameter INIT_RAM_17 = 256'h0;
+parameter INIT_RAM_18 = 256'h0;
+parameter INIT_RAM_19 = 256'h0;
+parameter INIT_RAM_1A = 256'h0;
+parameter INIT_RAM_1B = 256'h0;
+parameter INIT_RAM_1C = 256'h0;
+parameter INIT_RAM_1D = 256'h0;
+parameter INIT_RAM_1E = 256'h0;
+parameter INIT_RAM_1F = 256'h0;
+parameter INIT_RAM_20 = 256'h0;
+parameter INIT_RAM_21 = 256'h0;
+parameter INIT_RAM_22 = 256'h0;
+parameter INIT_RAM_23 = 256'h0;
+parameter INIT_RAM_24 = 256'h0;
+parameter INIT_RAM_25 = 256'h0;
+parameter INIT_RAM_26 = 256'h0;
+parameter INIT_RAM_27 = 256'h0;
+parameter INIT_RAM_28 = 256'h0;
+parameter INIT_RAM_29 = 256'h0;
+parameter INIT_RAM_2A = 256'h0;
+parameter INIT_RAM_2B = 256'h0;
+parameter INIT_RAM_2C = 256'h0;
+parameter INIT_RAM_2D = 256'h0;
+parameter INIT_RAM_2E = 256'h0;
+parameter INIT_RAM_2F = 256'h0;
+parameter INIT_RAM_30 = 256'h0;
+parameter INIT_RAM_31 = 256'h0;
+parameter INIT_RAM_32 = 256'h0;
+parameter INIT_RAM_33 = 256'h0;
+parameter INIT_RAM_34 = 256'h0;
+parameter INIT_RAM_35 = 256'h0;
+parameter INIT_RAM_36 = 256'h0;
+parameter INIT_RAM_37 = 256'h0;
+parameter INIT_RAM_38 = 256'h0;
+parameter INIT_RAM_39 = 256'h0;
+parameter INIT_RAM_3A = 256'h0;
+parameter INIT_RAM_3B = 256'h0;
+parameter INIT_RAM_3C = 256'h0;
+parameter INIT_RAM_3D = 256'h0;
+parameter INIT_RAM_3E = 256'h0;
+parameter INIT_RAM_3F = 256'h0;
+
+output [15:0] DOA, DOB;
+input [15:0] DIA, DIB;
+input [2:0] BLKSEL;
+input [13:0] ADA, ADB;
+input WREA, WREB;
+input CLKA, CLKB;
+input CEA, CEB;
+input OCEA, OCEB;
+input RESETA, RESETB;
+
+endmodule
+
+(* blackbox *)
+module DPX9 (DOA, DOB, DIA, DIB, BLKSEL, ADA, ADB, WREA, WREB, CLKA, CLKB, CEA, CEB, OCEA, OCEB, RESETA, RESETB);
+
+parameter READ_MODE0 = 1'b0;
+parameter READ_MODE1 = 1'b0;
+parameter WRITE_MODE0 = 2'b00;
+parameter WRITE_MODE1 = 2'b00;
+parameter BIT_WIDTH_0 = 18; // 9, 18
+parameter BIT_WIDTH_1 = 18; // 9, 18
+parameter BLK_SEL = 3'b000;
+parameter RESET_MODE = "SYNC";
+parameter INIT_RAM_00 = 288'h0;
+parameter INIT_RAM_01 = 288'h0;
+parameter INIT_RAM_02 = 288'h0;
+parameter INIT_RAM_03 = 288'h0;
+parameter INIT_RAM_04 = 288'h0;
+parameter INIT_RAM_05 = 288'h0;
+parameter INIT_RAM_06 = 288'h0;
+parameter INIT_RAM_07 = 288'h0;
+parameter INIT_RAM_08 = 288'h0;
+parameter INIT_RAM_09 = 288'h0;
+parameter INIT_RAM_0A = 288'h0;
+parameter INIT_RAM_0B = 288'h0;
+parameter INIT_RAM_0C = 288'h0;
+parameter INIT_RAM_0D = 288'h0;
+parameter INIT_RAM_0E = 288'h0;
+parameter INIT_RAM_0F = 288'h0;
+parameter INIT_RAM_10 = 288'h0;
+parameter INIT_RAM_11 = 288'h0;
+parameter INIT_RAM_12 = 288'h0;
+parameter INIT_RAM_13 = 288'h0;
+parameter INIT_RAM_14 = 288'h0;
+parameter INIT_RAM_15 = 288'h0;
+parameter INIT_RAM_16 = 288'h0;
+parameter INIT_RAM_17 = 288'h0;
+parameter INIT_RAM_18 = 288'h0;
+parameter INIT_RAM_19 = 288'h0;
+parameter INIT_RAM_1A = 288'h0;
+parameter INIT_RAM_1B = 288'h0;
+parameter INIT_RAM_1C = 288'h0;
+parameter INIT_RAM_1D = 288'h0;
+parameter INIT_RAM_1E = 288'h0;
+parameter INIT_RAM_1F = 288'h0;
+parameter INIT_RAM_20 = 288'h0;
+parameter INIT_RAM_21 = 288'h0;
+parameter INIT_RAM_22 = 288'h0;
+parameter INIT_RAM_23 = 288'h0;
+parameter INIT_RAM_24 = 288'h0;
+parameter INIT_RAM_25 = 288'h0;
+parameter INIT_RAM_26 = 288'h0;
+parameter INIT_RAM_27 = 288'h0;
+parameter INIT_RAM_28 = 288'h0;
+parameter INIT_RAM_29 = 288'h0;
+parameter INIT_RAM_2A = 288'h0;
+parameter INIT_RAM_2B = 288'h0;
+parameter INIT_RAM_2C = 288'h0;
+parameter INIT_RAM_2D = 288'h0;
+parameter INIT_RAM_2E = 288'h0;
+parameter INIT_RAM_2F = 288'h0;
+parameter INIT_RAM_30 = 288'h0;
+parameter INIT_RAM_31 = 288'h0;
+parameter INIT_RAM_32 = 288'h0;
+parameter INIT_RAM_33 = 288'h0;
+parameter INIT_RAM_34 = 288'h0;
+parameter INIT_RAM_35 = 288'h0;
+parameter INIT_RAM_36 = 288'h0;
+parameter INIT_RAM_37 = 288'h0;
+parameter INIT_RAM_38 = 288'h0;
+parameter INIT_RAM_39 = 288'h0;
+parameter INIT_RAM_3A = 288'h0;
+parameter INIT_RAM_3B = 288'h0;
+parameter INIT_RAM_3C = 288'h0;
+parameter INIT_RAM_3D = 288'h0;
+parameter INIT_RAM_3E = 288'h0;
+parameter INIT_RAM_3F = 288'h0;
+
+output [17:0] DOA, DOB;
+input [17:0] DIA, DIB;
+input [2:0] BLKSEL;
+input [13:0] ADA, ADB;
+input WREA, WREB;
+input CLKA, CLKB;
+input CEA, CEB;
+input OCEA, OCEB;
+input RESETA, RESETB;
+
+endmodule
+
+
(* blackbox *)
module rPLL (CLKOUT, CLKOUTP, CLKOUTD, CLKOUTD3, LOCK, CLKIN, CLKFB, FBDSEL, IDSEL, ODSEL, DUTYDA, PSDA, FDLY, RESET, RESET_P);
input CLKIN;
@@ -866,3 +1551,37 @@ parameter CLKOUTD3_SRC = "CLKOUT"; // CLKOUT, CLKOUTP
parameter DEVICE = "GW1N-1"; // "GW1N-1", "GW1N-4", "GW1N-9", "GW1NR-4", "GW1NR-9", "GW1N-4B", "GW1NR-4B", "GW1NS-2", "GW1NS-2C", "GW1NZ-1", "GW1NSR-2", "GW1NSR-2C", "GW1N-1S", "GW1NSE-2C", "GW1NRF-4B", "GW1N-9C", "GW1NR-9C", "GW1N-4C", "GW1NR-4C"
endmodule
+
+(* blackbox *)
+module OSC(OSCOUT);
+output OSCOUT;
+
+parameter FREQ_DIV = 100;
+parameter DEVICE = "GW1N-4";
+endmodule
+
+(* blackbox *)
+module OSCZ(OSCOUT, OSCEN);
+input OSCEN;
+
+output OSCOUT;
+
+parameter FREQ_DIV = 100;
+endmodule
+
+(* blackbox *)
+module OSCF(OSCOUT, OSCOUT30M, OSCEN);
+input OSCEN;
+
+output OSCOUT;
+output OSCOUT30M;
+
+parameter FREQ_DIV = 100;
+endmodule
+
+(* blackbox *)
+module OSCH(OSCOUT);
+output OSCOUT;
+
+parameter FREQ_DIV = 96;
+endmodule
diff --git a/techlibs/gowin/lutrams.txt b/techlibs/gowin/lutrams.txt
index 9db530251..76c4cd584 100644
--- a/techlibs/gowin/lutrams.txt
+++ b/techlibs/gowin/lutrams.txt
@@ -1,17 +1,13 @@
-bram $__GW1NR_RAM16S4
- init 1
- abits 4
- dbits 4
- groups 2
- ports 1 1
- wrmode 0 1
- enable 0 1
- transp 0 1
- clocks 0 1
- clkpol 0 1
-endbram
-
-match $__GW1NR_RAM16S4
- make_outreg
- min wports 1
-endmatch
+ram distributed $__GOWIN_LUTRAM_ {
+ abits 4;
+ width 4;
+ cost 4;
+ widthscale;
+ init no_undef;
+ prune_rom;
+ port sw "W" {
+ clock posedge;
+ }
+ port ar "R" {
+ }
+}
diff --git a/techlibs/gowin/lutrams_map.v b/techlibs/gowin/lutrams_map.v
index a50ab365a..6396ef7c6 100644
--- a/techlibs/gowin/lutrams_map.v
+++ b/techlibs/gowin/lutrams_map.v
@@ -1,31 +1,65 @@
-module \$__GW1NR_RAM16S4 (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 4;
- parameter CFG_DBITS = 4;
-
- parameter [63:0] INIT = 64'bx;
- input CLK1;
-
- 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 B1EN;
-
- `include "brams_init3.vh"
-
- RAM16S4
- #(.INIT_0(INIT_0),
- .INIT_1(INIT_1),
- .INIT_2(INIT_2),
- .INIT_3(INIT_3))
- _TECHMAP_REPLACE_
- (.AD(B1ADDR),
- .DI(B1DATA),
- .DO(A1DATA),
- .CLK(CLK1),
- .WRE(B1EN));
-
-
+module $__GOWIN_LUTRAM_(...);
+
+parameter INIT = 64'bx;
+parameter BITS_USED = 0;
+
+input PORT_W_CLK;
+input [3:0] PORT_W_ADDR;
+input PORT_W_WR_EN;
+input [3:0] PORT_W_WR_DATA;
+
+input [3:0] PORT_R_ADDR;
+output [3:0] PORT_R_RD_DATA;
+
+function [15:0] init_slice;
+input integer idx;
+integer i;
+for (i = 0; i < 16; i = i + 1)
+ init_slice[i] = INIT[4*i+idx];
+endfunction
+
+generate
+
+casez(BITS_USED)
+4'b000z:
+RAM16SDP1 #(
+ .INIT_0(init_slice(0)),
+) _TECHMAP_REPLACE_ (
+ .WAD(PORT_W_ADDR),
+ .RAD(PORT_R_ADDR),
+ .DI(PORT_W_WR_DATA[0]),
+ .DO(PORT_R_RD_DATA[0]),
+ .CLK(PORT_W_CLK),
+ .WRE(PORT_W_WR_EN)
+);
+4'b00zz:
+RAM16SDP2 #(
+ .INIT_0(init_slice(0)),
+ .INIT_1(init_slice(1)),
+) _TECHMAP_REPLACE_ (
+ .WAD(PORT_W_ADDR),
+ .RAD(PORT_R_ADDR),
+ .DI(PORT_W_WR_DATA[1:0]),
+ .DO(PORT_R_RD_DATA[1:0]),
+ .CLK(PORT_W_CLK),
+ .WRE(PORT_W_WR_EN)
+);
+default:
+RAM16SDP4 #(
+ .INIT_0(init_slice(0)),
+ .INIT_1(init_slice(1)),
+ .INIT_2(init_slice(2)),
+ .INIT_3(init_slice(3)),
+) _TECHMAP_REPLACE_ (
+ .WAD(PORT_W_ADDR),
+ .RAD(PORT_R_ADDR),
+ .DI(PORT_W_WR_DATA),
+ .DO(PORT_R_RD_DATA),
+ .CLK(PORT_W_CLK),
+ .WRE(PORT_W_WR_EN)
+);
+endcase
+
+endgenerate
+
endmodule
diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc
index cfbc9b9a6..0dffdf498 100644
--- a/techlibs/gowin/synth_gowin.cc
+++ b/techlibs/gowin/synth_gowin.cc
@@ -81,6 +81,11 @@ struct SynthGowinPass : public ScriptPass
log(" -abc9\n");
log(" use new ABC9 flow (EXPERIMENTAL)\n");
log("\n");
+ log(" -no-rw-check\n");
+ log(" marks all recognized read ports as \"return don't-care value on\n");
+ log(" read/write collision\" (same result as setting the no_rw_check\n");
+ log(" attribute on all memories).\n");
+ log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
@@ -88,7 +93,7 @@ struct SynthGowinPass : public ScriptPass
}
string top_opt, vout_file, json_file;
- bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads, noalu;
+ bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads, noalu, no_rw_check;
void clear_flags() override
{
@@ -104,6 +109,7 @@ struct SynthGowinPass : public ScriptPass
abc9 = false;
noiopads = false;
noalu = false;
+ no_rw_check = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
@@ -125,7 +131,6 @@ struct SynthGowinPass : public ScriptPass
if (args[argidx] == "-json" && argidx+1 < args.size()) {
json_file = args[++argidx];
nobram = true;
- nolutram = true;
continue;
}
if (args[argidx] == "-run" && argidx+1 < args.size()) {
@@ -172,6 +177,10 @@ struct SynthGowinPass : public ScriptPass
noiopads = true;
continue;
}
+ if (args[argidx] == "-no-rw-check") {
+ no_rw_check = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -189,6 +198,12 @@ struct SynthGowinPass : public ScriptPass
void script() override
{
+ std::string no_rw_check_opt = "";
+ if (no_rw_check)
+ no_rw_check_opt = " -no-rw-check";
+ if (help_mode)
+ no_rw_check_opt = " [-no-rw-check]";
+
if (check_label("begin"))
{
run("read_verilog -specify -lib +/gowin/cells_sim.v");
@@ -205,20 +220,20 @@ struct SynthGowinPass : public ScriptPass
if (check_label("coarse"))
{
- run("synth -run coarse");
- }
-
- if (!nobram && check_label("map_bram", "(skip if -nobram)"))
- {
- run("memory_bram -rules +/gowin/brams.txt");
- run("techmap -map +/gowin/brams_map.v");
+ run("synth -run coarse" + no_rw_check_opt);
}
- if (!nolutram && check_label("map_lutram", "(skip if -nolutram)"))
+ if (check_label("map_ram"))
{
- run("memory_bram -rules +/gowin/lutrams.txt");
- run("techmap -map +/gowin/lutrams_map.v");
- run("setundef -params -zero t:RAM16S4");
+ std::string args = "";
+ if (nobram)
+ args += " -no-auto-block";
+ if (nolutram)
+ args += " -no-auto-distributed";
+ if (help_mode)
+ args += " [-no-auto-block] [-no-auto-distributed]";
+ run("memory_libmap -lib +/gowin/lutrams.txt -lib +/gowin/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)");
+ run("techmap -map +/gowin/lutrams_map.v -map +/gowin/brams_map.v");
}
if (check_label("map_ffram"))
diff --git a/techlibs/ice40/.gitignore b/techlibs/ice40/.gitignore
deleted file mode 100644
index 6bf3b6717..000000000
--- a/techlibs/ice40/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-brams_init.mk
-brams_init1.vh
-brams_init2.vh
-brams_init3.vh
diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc
index 8ce3cb024..4bf8e4e86 100644
--- a/techlibs/ice40/Makefile.inc
+++ b/techlibs/ice40/Makefile.inc
@@ -3,22 +3,6 @@ OBJS += techlibs/ice40/synth_ice40.o
OBJS += techlibs/ice40/ice40_braminit.o
OBJS += techlibs/ice40/ice40_opt.o
-GENFILES += techlibs/ice40/brams_init1.vh
-GENFILES += techlibs/ice40/brams_init2.vh
-GENFILES += techlibs/ice40/brams_init3.vh
-
-EXTRA_OBJS += techlibs/ice40/brams_init.mk
-.SECONDARY: techlibs/ice40/brams_init.mk
-
-techlibs/ice40/brams_init.mk: techlibs/ice40/brams_init.py
- $(Q) mkdir -p techlibs/ice40
- $(P) $(PYTHON_EXECUTABLE) $<
- $(Q) touch techlibs/ice40/brams_init.mk
-
-techlibs/ice40/brams_init1.vh: techlibs/ice40/brams_init.mk
-techlibs/ice40/brams_init2.vh: techlibs/ice40/brams_init.mk
-techlibs/ice40/brams_init3.vh: techlibs/ice40/brams_init.mk
-
$(eval $(call add_share_file,share/ice40,techlibs/ice40/arith_map.v))
$(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_map.v))
$(eval $(call add_share_file,share/ice40,techlibs/ice40/ff_map.v))
@@ -26,10 +10,7 @@ $(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_sim.v))
$(eval $(call add_share_file,share/ice40,techlibs/ice40/latches_map.v))
$(eval $(call add_share_file,share/ice40,techlibs/ice40/brams.txt))
$(eval $(call add_share_file,share/ice40,techlibs/ice40/brams_map.v))
+$(eval $(call add_share_file,share/ice40,techlibs/ice40/spram.txt))
+$(eval $(call add_share_file,share/ice40,techlibs/ice40/spram_map.v))
$(eval $(call add_share_file,share/ice40,techlibs/ice40/dsp_map.v))
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_model.v))
-
-$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init1.vh))
-$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init2.vh))
-$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init3.vh))
-
diff --git a/techlibs/ice40/brams.txt b/techlibs/ice40/brams.txt
index 36dfddab2..518972c2a 100644
--- a/techlibs/ice40/brams.txt
+++ b/techlibs/ice40/brams.txt
@@ -1,100 +1,23 @@
-bram $__ICE40_RAM4K_M0
- init 1
- abits 8
- dbits 16
- groups 2
- ports 1 1
- wrmode 0 1
- enable 1 16
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-bram $__ICE40_RAM4K_M123
- init 1
- abits 9 @M1
- dbits 8 @M1
- abits 10 @M2
- dbits 4 @M2
- abits 11 @M3
- dbits 2 @M3
- groups 2
- ports 1 1
- wrmode 0 1
- enable 1 1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-# The syn_* attributes are described in:
-# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx
-attr_icase 1
-
-match $__ICE40_RAM4K_M0
- # implicitly requested RAM or ROM
- attribute !syn_ramstyle syn_ramstyle=auto
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- min efficiency 2
- make_transp
- or_next_if_better
-endmatch
-
-match $__ICE40_RAM4K_M0
- # explicitly requested RAM
- attribute syn_ramstyle=block_ram ram_block
- attribute !syn_romstyle
- attribute !rom_block
- attribute !logic_block
- min wports 1
- make_transp
- or_next_if_better
-endmatch
-
-match $__ICE40_RAM4K_M0
- # explicitly requested ROM
- attribute syn_romstyle=ebr rom_block
- attribute !syn_ramstyle
- attribute !ram_block
- attribute !logic_block
- max wports 0
- make_transp
- or_next_if_better
-endmatch
-
-match $__ICE40_RAM4K_M123
- # implicitly requested RAM or ROM
- attribute !syn_ramstyle syn_ramstyle=auto
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- min efficiency 2
- make_transp
- or_next_if_better
-endmatch
-
-match $__ICE40_RAM4K_M123
- # explicitly requested RAM
- attribute syn_ramstyle=block_ram ram_block
- attribute !syn_romstyle
- attribute !rom_block
- attribute !logic_block
- min wports 1
- make_transp
- or_next_if_better
-endmatch
-
-match $__ICE40_RAM4K_M123
- # explicitly requested ROM
- attribute syn_romstyle=ebr rom_block
- attribute !syn_ramstyle
- attribute !ram_block
- attribute !logic_block
- max wports 0
- make_transp
-endmatch
+ram block $__ICE40_RAM4K_ {
+ abits 11;
+ widths 2 4 8 16 per_port;
+ cost 64;
+ option "HAS_BE" 1 {
+ byte 1;
+ }
+ init any;
+ port sw "W" {
+ option "HAS_BE" 0 {
+ width 2 4 8;
+ }
+ option "HAS_BE" 1 {
+ width 16;
+ wrbe_separate;
+ }
+ clock anyedge;
+ }
+ port sr "R" {
+ clock anyedge;
+ rden;
+ }
+}
diff --git a/techlibs/ice40/brams_init.py b/techlibs/ice40/brams_init.py
deleted file mode 100644
index 4a1485110..000000000
--- a/techlibs/ice40/brams_init.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env python3
-
-def write_init_vh(filename, initbits):
- with open(filename, "w") as f:
- for i in range(16):
- print("localparam [255:0] INIT_%X = {" % i, file=f)
- for k in range(32):
- print(" %s%s" % (", ".join(["INIT[%4d]" % initbits[i*256 + 255 - k*8 - l] for l in range(8)]), "," if k != 31 else ""), file=f)
- print("};", file=f);
-
-write_init_vh("techlibs/ice40/brams_init1.vh", [i//2 + 2048*(i%2) for i in range(4096)])
-write_init_vh("techlibs/ice40/brams_init2.vh", [i//4 + 1024*(i%4) for i in range(4096)])
-write_init_vh("techlibs/ice40/brams_init3.vh", [i//8 + 512*(i%8) for i in range(4096)])
-
diff --git a/techlibs/ice40/brams_map.v b/techlibs/ice40/brams_map.v
index db9f5d8ce..9d7b793e1 100644
--- a/techlibs/ice40/brams_map.v
+++ b/techlibs/ice40/brams_map.v
@@ -1,318 +1,218 @@
-
-module \$__ICE40_RAM4K (
- output [15:0] RDATA,
- input RCLK, RCLKE, RE,
- input [10:0] RADDR,
- input WCLK, WCLKE, WE,
- input [10:0] WADDR,
- input [15:0] MASK, WDATA
-);
- parameter [1:0] READ_MODE = 0;
- parameter [1:0] WRITE_MODE = 0;
- parameter [0:0] NEGCLK_R = 0;
- parameter [0:0] NEGCLK_W = 0;
-
- parameter [255:0] INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter [255:0] INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-
- generate
- case ({NEGCLK_R, NEGCLK_W})
- 2'b00:
- SB_RAM40_4K #(
- .READ_MODE(READ_MODE),
- .WRITE_MODE(WRITE_MODE),
- .INIT_0(INIT_0),
- .INIT_1(INIT_1),
- .INIT_2(INIT_2),
- .INIT_3(INIT_3),
- .INIT_4(INIT_4),
- .INIT_5(INIT_5),
- .INIT_6(INIT_6),
- .INIT_7(INIT_7),
- .INIT_8(INIT_8),
- .INIT_9(INIT_9),
- .INIT_A(INIT_A),
- .INIT_B(INIT_B),
- .INIT_C(INIT_C),
- .INIT_D(INIT_D),
- .INIT_E(INIT_E),
- .INIT_F(INIT_F)
- ) _TECHMAP_REPLACE_ (
- .RDATA(RDATA),
- .RCLK (RCLK ),
- .RCLKE(RCLKE),
- .RE (RE ),
- .RADDR(RADDR),
- .WCLK (WCLK ),
- .WCLKE(WCLKE),
- .WE (WE ),
- .WADDR(WADDR),
- .MASK (MASK ),
- .WDATA(WDATA)
- );
- 2'b01:
- SB_RAM40_4KNW #(
- .READ_MODE(READ_MODE),
- .WRITE_MODE(WRITE_MODE),
- .INIT_0(INIT_0),
- .INIT_1(INIT_1),
- .INIT_2(INIT_2),
- .INIT_3(INIT_3),
- .INIT_4(INIT_4),
- .INIT_5(INIT_5),
- .INIT_6(INIT_6),
- .INIT_7(INIT_7),
- .INIT_8(INIT_8),
- .INIT_9(INIT_9),
- .INIT_A(INIT_A),
- .INIT_B(INIT_B),
- .INIT_C(INIT_C),
- .INIT_D(INIT_D),
- .INIT_E(INIT_E),
- .INIT_F(INIT_F)
- ) _TECHMAP_REPLACE_ (
- .RDATA(RDATA),
- .RCLK (RCLK ),
- .RCLKE(RCLKE),
- .RE (RE ),
- .RADDR(RADDR),
- .WCLKN(WCLK ),
- .WCLKE(WCLKE),
- .WE (WE ),
- .WADDR(WADDR),
- .MASK (MASK ),
- .WDATA(WDATA)
- );
- 2'b10:
- SB_RAM40_4KNR #(
- .READ_MODE(READ_MODE),
- .WRITE_MODE(WRITE_MODE),
- .INIT_0(INIT_0),
- .INIT_1(INIT_1),
- .INIT_2(INIT_2),
- .INIT_3(INIT_3),
- .INIT_4(INIT_4),
- .INIT_5(INIT_5),
- .INIT_6(INIT_6),
- .INIT_7(INIT_7),
- .INIT_8(INIT_8),
- .INIT_9(INIT_9),
- .INIT_A(INIT_A),
- .INIT_B(INIT_B),
- .INIT_C(INIT_C),
- .INIT_D(INIT_D),
- .INIT_E(INIT_E),
- .INIT_F(INIT_F)
- ) _TECHMAP_REPLACE_ (
- .RDATA(RDATA),
- .RCLKN(RCLK ),
- .RCLKE(RCLKE),
- .RE (RE ),
- .RADDR(RADDR),
- .WCLK (WCLK ),
- .WCLKE(WCLKE),
- .WE (WE ),
- .WADDR(WADDR),
- .MASK (MASK ),
- .WDATA(WDATA)
- );
- 2'b11:
- SB_RAM40_4KNRNW #(
- .READ_MODE(READ_MODE),
- .WRITE_MODE(WRITE_MODE),
- .INIT_0(INIT_0),
- .INIT_1(INIT_1),
- .INIT_2(INIT_2),
- .INIT_3(INIT_3),
- .INIT_4(INIT_4),
- .INIT_5(INIT_5),
- .INIT_6(INIT_6),
- .INIT_7(INIT_7),
- .INIT_8(INIT_8),
- .INIT_9(INIT_9),
- .INIT_A(INIT_A),
- .INIT_B(INIT_B),
- .INIT_C(INIT_C),
- .INIT_D(INIT_D),
- .INIT_E(INIT_E),
- .INIT_F(INIT_F)
- ) _TECHMAP_REPLACE_ (
- .RDATA(RDATA),
- .RCLKN(RCLK ),
- .RCLKE(RCLKE),
- .RE (RE ),
- .RADDR(RADDR),
- .WCLKN(WCLK ),
- .WCLKE(WCLKE),
- .WE (WE ),
- .WADDR(WADDR),
- .MASK (MASK ),
- .WDATA(WDATA)
- );
- endcase
- endgenerate
-endmodule
-
-
-module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter [0:0] CLKPOL2 = 1;
- parameter [0:0] CLKPOL3 = 1;
-
- parameter [4095:0] INIT = 4096'bx;
-
- input CLK2;
- input CLK3;
-
- input [7:0] A1ADDR;
- output [15:0] A1DATA;
- input A1EN;
-
- input [7:0] B1ADDR;
- input [15:0] B1DATA;
- input [15:0] B1EN;
-
- wire [10:0] A1ADDR_11 = A1ADDR;
- wire [10:0] B1ADDR_11 = B1ADDR;
-
- \$__ICE40_RAM4K #(
- .READ_MODE(0),
- .WRITE_MODE(0),
- .NEGCLK_R(!CLKPOL2),
- .NEGCLK_W(!CLKPOL3),
- .INIT_0(INIT[ 0*256 +: 256]),
- .INIT_1(INIT[ 1*256 +: 256]),
- .INIT_2(INIT[ 2*256 +: 256]),
- .INIT_3(INIT[ 3*256 +: 256]),
- .INIT_4(INIT[ 4*256 +: 256]),
- .INIT_5(INIT[ 5*256 +: 256]),
- .INIT_6(INIT[ 6*256 +: 256]),
- .INIT_7(INIT[ 7*256 +: 256]),
- .INIT_8(INIT[ 8*256 +: 256]),
- .INIT_9(INIT[ 9*256 +: 256]),
- .INIT_A(INIT[10*256 +: 256]),
- .INIT_B(INIT[11*256 +: 256]),
- .INIT_C(INIT[12*256 +: 256]),
- .INIT_D(INIT[13*256 +: 256]),
- .INIT_E(INIT[14*256 +: 256]),
- .INIT_F(INIT[15*256 +: 256])
- ) _TECHMAP_REPLACE_ (
- .RDATA(A1DATA),
- .RADDR(A1ADDR_11),
- .RCLK(CLK2),
- .RCLKE(A1EN),
- .RE(1'b1),
- .WDATA(B1DATA),
- .WADDR(B1ADDR_11),
- .MASK(~B1EN),
- .WCLK(CLK3),
- .WCLKE(|B1EN),
- .WE(1'b1)
- );
-endmodule
-
-module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 9;
- parameter CFG_DBITS = 8;
-
- parameter [0:0] CLKPOL2 = 1;
- parameter [0:0] CLKPOL3 = 1;
-
- parameter [4095:0] INIT = 4096'bx;
-
- localparam MODE =
- CFG_ABITS == 9 ? 1 :
- CFG_ABITS == 10 ? 2 :
- CFG_ABITS == 11 ? 3 : '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 B1EN;
-
- wire [10:0] A1ADDR_11 = A1ADDR;
- wire [10:0] B1ADDR_11 = B1ADDR;
-
- wire [15:0] A1DATA_16, B1DATA_16;
-
-`define INSTANCE \
- \$__ICE40_RAM4K #( \
- .READ_MODE(MODE), \
- .WRITE_MODE(MODE), \
- .NEGCLK_R(!CLKPOL2), \
- .NEGCLK_W(!CLKPOL3), \
- .INIT_0(INIT_0), \
- .INIT_1(INIT_1), \
- .INIT_2(INIT_2), \
- .INIT_3(INIT_3), \
- .INIT_4(INIT_4), \
- .INIT_5(INIT_5), \
- .INIT_6(INIT_6), \
- .INIT_7(INIT_7), \
- .INIT_8(INIT_8), \
- .INIT_9(INIT_9), \
- .INIT_A(INIT_A), \
- .INIT_B(INIT_B), \
- .INIT_C(INIT_C), \
- .INIT_D(INIT_D), \
- .INIT_E(INIT_E), \
- .INIT_F(INIT_F) \
+module $__ICE40_RAM4K_ (...);
+
+parameter INIT = 0;
+parameter OPTION_HAS_BE = 1;
+parameter PORT_R_WIDTH = 16;
+parameter PORT_W_WIDTH = 16;
+parameter PORT_W_WR_BE_WIDTH = 16;
+parameter PORT_R_CLK_POL = 1;
+parameter PORT_W_CLK_POL = 1;
+
+input PORT_R_CLK;
+input PORT_R_RD_EN;
+input [10:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+
+input PORT_W_CLK;
+input PORT_W_WR_EN;
+input [15:0] PORT_W_WR_BE;
+input [10:0] PORT_W_ADDR;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+
+wire [15:0] RDATA;
+wire [15:0] WDATA;
+wire [15:0] MASK;
+wire [10:0] RADDR = {PORT_R_ADDR[0], PORT_R_ADDR[1], PORT_R_ADDR[2], PORT_R_ADDR[10:3]};
+wire [10:0] WADDR = {PORT_W_ADDR[0], PORT_W_ADDR[1], PORT_W_ADDR[2], PORT_W_ADDR[10:3]};
+
+function [1:0] mode;
+ input integer width;
+ case (width)
+ 16: mode = 0;
+ 8: mode = 1;
+ 4: mode = 2;
+ 2: mode = 3;
+ endcase
+endfunction
+
+function [255:0] slice_init;
+ input [3:0] idx;
+ integer i;
+ reg [7:0] ri;
+ reg [11:0] a;
+ for (i = 0; i < 256; i = i + 1) begin
+ ri = i;
+ a = {idx, ri[7:4], ri[0], ri[1], ri[2], ri[3]};
+ slice_init[i] = INIT[a];
+ end
+endfunction
+
+`define INSTANCE(type, rclk, wclk) \
+ type #( \
+ .INIT_0(slice_init(0)), \
+ .INIT_1(slice_init(1)), \
+ .INIT_2(slice_init(2)), \
+ .INIT_3(slice_init(3)), \
+ .INIT_4(slice_init(4)), \
+ .INIT_5(slice_init(5)), \
+ .INIT_6(slice_init(6)), \
+ .INIT_7(slice_init(7)), \
+ .INIT_8(slice_init(8)), \
+ .INIT_9(slice_init(9)), \
+ .INIT_A(slice_init(10)), \
+ .INIT_B(slice_init(11)), \
+ .INIT_C(slice_init(12)), \
+ .INIT_D(slice_init(13)), \
+ .INIT_E(slice_init(14)), \
+ .INIT_F(slice_init(15)), \
+ .READ_MODE(mode(PORT_R_WIDTH)), \
+ .WRITE_MODE(mode(PORT_W_WIDTH)) \
) _TECHMAP_REPLACE_ ( \
- .RDATA(A1DATA_16), \
- .RADDR(A1ADDR_11), \
- .RCLK(CLK2), \
- .RCLKE(A1EN), \
+ .RDATA(RDATA), \
+ .rclk(PORT_R_CLK), \
+ .RCLKE(PORT_R_RD_EN), \
.RE(1'b1), \
- .WDATA(B1DATA_16), \
- .WADDR(B1ADDR_11), \
- .WCLK(CLK3), \
- .WCLKE(|B1EN), \
- .WE(1'b1) \
+ .RADDR(RADDR), \
+ .WDATA(WDATA), \
+ .wclk(PORT_W_CLK), \
+ .WCLKE(PORT_W_WR_EN), \
+ .WE(1'b1), \
+ .WADDR(WADDR), \
+ .MASK(MASK), \
);
- generate
- if (MODE == 1) begin
- assign A1DATA = {A1DATA_16[14], A1DATA_16[12], A1DATA_16[10], A1DATA_16[ 8],
- A1DATA_16[ 6], A1DATA_16[ 4], A1DATA_16[ 2], A1DATA_16[ 0]};
- assign {B1DATA_16[14], B1DATA_16[12], B1DATA_16[10], B1DATA_16[ 8],
- B1DATA_16[ 6], B1DATA_16[ 4], B1DATA_16[ 2], B1DATA_16[ 0]} = B1DATA;
- `include "brams_init1.vh"
- `INSTANCE
- end
- if (MODE == 2) begin
- assign A1DATA = {A1DATA_16[13], A1DATA_16[9], A1DATA_16[5], A1DATA_16[1]};
- assign {B1DATA_16[13], B1DATA_16[9], B1DATA_16[5], B1DATA_16[1]} = B1DATA;
- `include "brams_init2.vh"
- `INSTANCE
- end
- if (MODE == 3) begin
- assign A1DATA = {A1DATA_16[11], A1DATA_16[3]};
- assign {B1DATA_16[11], B1DATA_16[3]} = B1DATA;
- `include "brams_init3.vh"
- `INSTANCE
- end
- endgenerate
-
-`undef INSTANCE
+generate
+
+case(PORT_R_WIDTH)
+ 2: begin
+ assign PORT_R_RD_DATA = {
+ RDATA[11],
+ RDATA[3]
+ };
+ end
+ 4: begin
+ assign PORT_R_RD_DATA = {
+ RDATA[13],
+ RDATA[5],
+ RDATA[9],
+ RDATA[1]
+ };
+ end
+ 8: begin
+ assign PORT_R_RD_DATA = {
+ RDATA[14],
+ RDATA[6],
+ RDATA[10],
+ RDATA[2],
+ RDATA[12],
+ RDATA[4],
+ RDATA[8],
+ RDATA[0]
+ };
+ end
+ 16: begin
+ assign PORT_R_RD_DATA = {
+ RDATA[15],
+ RDATA[7],
+ RDATA[11],
+ RDATA[3],
+ RDATA[13],
+ RDATA[5],
+ RDATA[9],
+ RDATA[1],
+ RDATA[14],
+ RDATA[6],
+ RDATA[10],
+ RDATA[2],
+ RDATA[12],
+ RDATA[4],
+ RDATA[8],
+ RDATA[0]
+ };
+ end
+endcase
+
+case(PORT_W_WIDTH)
+ 2: begin
+ assign {
+ WDATA[11],
+ WDATA[3]
+ } = PORT_W_WR_DATA;
+ end
+ 4: begin
+ assign {
+ WDATA[13],
+ WDATA[5],
+ WDATA[9],
+ WDATA[1]
+ } = PORT_W_WR_DATA;
+ end
+ 8: begin
+ assign {
+ WDATA[14],
+ WDATA[6],
+ WDATA[10],
+ WDATA[2],
+ WDATA[12],
+ WDATA[4],
+ WDATA[8],
+ WDATA[0]
+ } = PORT_W_WR_DATA;
+ end
+ 16: begin
+ assign WDATA = {
+ PORT_W_WR_DATA[15],
+ PORT_W_WR_DATA[7],
+ PORT_W_WR_DATA[11],
+ PORT_W_WR_DATA[3],
+ PORT_W_WR_DATA[13],
+ PORT_W_WR_DATA[5],
+ PORT_W_WR_DATA[9],
+ PORT_W_WR_DATA[1],
+ PORT_W_WR_DATA[14],
+ PORT_W_WR_DATA[6],
+ PORT_W_WR_DATA[10],
+ PORT_W_WR_DATA[2],
+ PORT_W_WR_DATA[12],
+ PORT_W_WR_DATA[4],
+ PORT_W_WR_DATA[8],
+ PORT_W_WR_DATA[0]
+ };
+ assign MASK = ~{
+ PORT_W_WR_BE[15],
+ PORT_W_WR_BE[7],
+ PORT_W_WR_BE[11],
+ PORT_W_WR_BE[3],
+ PORT_W_WR_BE[13],
+ PORT_W_WR_BE[5],
+ PORT_W_WR_BE[9],
+ PORT_W_WR_BE[1],
+ PORT_W_WR_BE[14],
+ PORT_W_WR_BE[6],
+ PORT_W_WR_BE[10],
+ PORT_W_WR_BE[2],
+ PORT_W_WR_BE[12],
+ PORT_W_WR_BE[4],
+ PORT_W_WR_BE[8],
+ PORT_W_WR_BE[0]
+ };
+ end
+endcase
+
+if (PORT_R_CLK_POL) begin
+ if (PORT_W_CLK_POL) begin
+ `INSTANCE(SB_RAM40_4K, RCLK, WCLK)
+ end else begin
+ `INSTANCE(SB_RAM40_4KNW, RCLK, WCLKN)
+ end
+end else begin
+ if (PORT_W_CLK_POL) begin
+ `INSTANCE(SB_RAM40_4KNR, RCLKN, WCLK)
+ end else begin
+ `INSTANCE(SB_RAM40_4KNRNW, RCLKN, WCLKN)
+ end
+end
+
+endgenerate
endmodule
-
diff --git a/techlibs/ice40/spram.txt b/techlibs/ice40/spram.txt
new file mode 100644
index 000000000..ed0699f7d
--- /dev/null
+++ b/techlibs/ice40/spram.txt
@@ -0,0 +1,12 @@
+ram huge $__ICE40_SPRAM_ {
+ abits 14;
+ width 16;
+ cost 2048;
+ byte 4;
+ port srsw "A" {
+ clock posedge;
+ clken;
+ wrbe_separate;
+ rdwr no_change;
+ }
+}
diff --git a/techlibs/ice40/spram_map.v b/techlibs/ice40/spram_map.v
new file mode 100644
index 000000000..ae8919505
--- /dev/null
+++ b/techlibs/ice40/spram_map.v
@@ -0,0 +1,24 @@
+module $__ICE40_SPRAM_ (...);
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input PORT_A_WR_EN;
+input [3:0] PORT_A_WR_BE;
+input [13:0] PORT_A_ADDR;
+input [15:0] PORT_A_WR_DATA;
+output [15:0] PORT_A_RD_DATA;
+
+SB_SPRAM256KA _TECHMAP_REPLACE_ (
+ .ADDRESS(PORT_A_ADDR),
+ .DATAIN(PORT_A_WR_DATA),
+ .MASKWREN(PORT_A_WR_BE),
+ .WREN(PORT_A_WR_EN),
+ .CHIPSELECT(PORT_A_CLK_EN),
+ .CLOCK(PORT_A_CLK),
+ .STANDBY(1'b0),
+ .SLEEP(1'b0),
+ .POWEROFF(1'b1),
+ .DATAOUT(PORT_A_RD_DATA),
+);
+
+endmodule
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index 421ec3b4e..1174f6e04 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -90,6 +90,9 @@ struct SynthIce40Pass : public ScriptPass
log(" -nobram\n");
log(" do not use SB_RAM40_4K* cells in output netlist\n");
log("\n");
+ log(" -spram\n");
+ log(" enable automatic inference of SB_SPRAM256KA\n");
+ log("\n");
log(" -dsp\n");
log(" use iCE40 UltraPlus DSP cells for large arithmetic\n");
log("\n");
@@ -109,6 +112,11 @@ struct SynthIce40Pass : public ScriptPass
log(" -flowmap\n");
log(" use FlowMap LUT techmapping instead of abc (EXPERIMENTAL)\n");
log("\n");
+ log(" -no-rw-check\n");
+ log(" marks all recognized read ports as \"return don't-care value on\n");
+ log(" read/write collision\" (same result as setting the no_rw_check\n");
+ log(" attribute on all memories).\n");
+ log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
@@ -116,7 +124,7 @@ struct SynthIce40Pass : public ScriptPass
}
string top_opt, blif_file, edif_file, json_file, device_opt;
- bool nocarry, nodffe, nobram, dsp, flatten, retime, noabc, abc2, vpr, abc9, dff, flowmap;
+ bool nocarry, nodffe, nobram, spram, dsp, flatten, retime, noabc, abc2, vpr, abc9, dff, flowmap, no_rw_check;
int min_ce_use;
void clear_flags() override
@@ -129,6 +137,7 @@ struct SynthIce40Pass : public ScriptPass
nodffe = false;
min_ce_use = -1;
nobram = false;
+ spram = false;
dsp = false;
flatten = true;
retime = false;
@@ -138,6 +147,7 @@ struct SynthIce40Pass : public ScriptPass
abc9 = false;
flowmap = false;
device_opt = "hx";
+ no_rw_check = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
@@ -204,6 +214,10 @@ struct SynthIce40Pass : public ScriptPass
nobram = true;
continue;
}
+ if (args[argidx] == "-spram") {
+ spram = true;
+ continue;
+ }
if (args[argidx] == "-dsp") {
dsp = true;
continue;
@@ -236,6 +250,10 @@ struct SynthIce40Pass : public ScriptPass
flowmap = true;
continue;
}
+ if (args[argidx] == "-no-rw-check") {
+ no_rw_check = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -271,6 +289,12 @@ struct SynthIce40Pass : public ScriptPass
define = "-D ICE40_U";
else
define = "-D ICE40_HX";
+ std::string no_rw_check_opt = "";
+ if (no_rw_check)
+ no_rw_check_opt = " -no-rw-check";
+ if (help_mode)
+ no_rw_check_opt = " [-no-rw-check]";
+
if (check_label("begin"))
{
run("read_verilog " + define + " -lib -specify +/ice40/cells_sim.v");
@@ -303,7 +327,7 @@ struct SynthIce40Pass : public ScriptPass
run("opt_expr");
run("opt_clean");
if (help_mode || dsp) {
- run("memory_dff"); // ice40_dsp will merge registers, reserve memory port registers first
+ run("memory_dff" + no_rw_check_opt); // ice40_dsp will merge registers, reserve memory port registers first
run("wreduce t:$mul");
run("techmap -map +/mul2dsp.v -map +/ice40/dsp_map.v -D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=16 "
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_Y_MINWIDTH=11 "
@@ -318,23 +342,28 @@ struct SynthIce40Pass : public ScriptPass
}
run("alumacc");
run("opt");
- run("memory -nomap");
+ run("memory -nomap" + no_rw_check_opt);
run("opt_clean");
}
- if (!nobram && check_label("map_bram", "(skip if -nobram)"))
+ if (check_label("map_ram"))
{
- run("memory_bram -rules +/ice40/brams.txt");
- run("techmap -map +/ice40/brams_map.v");
+ std::string args = "";
+ if (!spram)
+ args += " -no-auto-huge";
+ if (nobram)
+ args += " -no-auto-block";
+ if (help_mode)
+ args += " [-no-auto-huge] [-no-auto-block]";
+ run("memory_libmap -lib +/ice40/brams.txt -lib +/ice40/spram.txt" + args, "(-no-auto-huge unless -spram, -no-auto-block if -nobram)");
+ run("techmap -map +/ice40/brams_map.v -map +/ice40/spram_map.v");
run("ice40_braminit");
}
if (check_label("map_ffram"))
{
run("opt -fast -mux_undef -undriven -fine");
- run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block "
- "-attr syn_ramstyle=auto -attr syn_ramstyle=registers "
- "-attr syn_romstyle=auto -attr syn_romstyle=logic");
+ run("memory_map");
run("opt -undriven -fine");
}
diff --git a/techlibs/intel_alm/Makefile.inc b/techlibs/intel_alm/Makefile.inc
index 614d5802c..b5f279a92 100644
--- a/techlibs/intel_alm/Makefile.inc
+++ b/techlibs/intel_alm/Makefile.inc
@@ -19,6 +19,7 @@ $(eval $(call add_share_file,share/intel_alm/cyclonev,techlibs/intel_alm/cyclone
# RAM
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m10k.txt))
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m10k_map.v))
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m20k.txt))
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m20k_map.v))
$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/lutram_mlab.txt))
diff --git a/techlibs/intel_alm/common/bram_m10k.txt b/techlibs/intel_alm/common/bram_m10k.txt
index e9355fe2c..560711b65 100644
--- a/techlibs/intel_alm/common/bram_m10k.txt
+++ b/techlibs/intel_alm/common/bram_m10k.txt
@@ -1,21 +1,15 @@
-bram MISTRAL_M10K
+bram $__MISTRAL_M10K
init 0 # TODO: Re-enable when I figure out how BRAM init works
abits 13 @D8192x1
dbits 1 @D8192x1
abits 12 @D4096x2
dbits 2 @D4096x2
- abits 11 @D2048x4 @D2048x5
- dbits 4 @D2048x4
+ abits 11 @D2048x5
dbits 5 @D2048x5
- abits 10 @D1024x8 @D1024x10
- dbits 8 @D1024x8
+ abits 10 @D1024x10
dbits 10 @D1024x10
- abits 9 @D512x16 @D512x20
- dbits 16 @D512x16
+ abits 9 @D512x20
dbits 20 @D512x20
- abits 8 @D256x32 @D256x40
- dbits 32 @D256x32
- dbits 40 @D256x40
groups 2
ports 1 1
wrmode 1 0
@@ -27,7 +21,7 @@ bram MISTRAL_M10K
endbram
-match MISTRAL_M10K
+match $__MISTRAL_M10K
min efficiency 5
make_transp
endmatch
diff --git a/techlibs/intel_alm/common/bram_m10k_map.v b/techlibs/intel_alm/common/bram_m10k_map.v
new file mode 100644
index 000000000..8f9d4a3b3
--- /dev/null
+++ b/techlibs/intel_alm/common/bram_m10k_map.v
@@ -0,0 +1,16 @@
+// Stub to invert M10K write-enable.
+
+module \$__MISTRAL_M10K (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+
+parameter CFG_ABITS = 10;
+parameter CFG_DBITS = 10;
+
+input CLK1;
+input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
+input [CFG_DBITS-1:0] A1DATA;
+input A1EN, B1EN;
+output reg [CFG_DBITS-1:0] B1DATA;
+
+MISTRAL_M10K #(.CFG_ABITS(CFG_ABITS), .CFG_DBITS(CFG_DBITS)) _TECHMAP_REPLACE_ (.CLK1(CLK1), .A1ADDR(A1ADDR), .A1DATA(A1DATA), .A1EN(!A1EN), .B1ADDR(B1ADDR), .B1DATA(B1DATA), .B1EN(B1EN));
+
+endmodule \ No newline at end of file
diff --git a/techlibs/intel_alm/common/mem_sim.v b/techlibs/intel_alm/common/mem_sim.v
index 370e17f27..c9ba8c7f1 100644
--- a/techlibs/intel_alm/common/mem_sim.v
+++ b/techlibs/intel_alm/common/mem_sim.v
@@ -145,7 +145,7 @@ endspecify
`endif
always @(posedge CLK1) begin
- if (A1EN)
+ if (!A1EN)
mem[(A1ADDR + 1) * CFG_DBITS - 1 : A1ADDR * CFG_DBITS] <= A1DATA;
if (B1EN)
diff --git a/techlibs/intel_alm/common/quartus_rename.v b/techlibs/intel_alm/common/quartus_rename.v
index 5850f6907..217dc5de9 100644
--- a/techlibs/intel_alm/common/quartus_rename.v
+++ b/techlibs/intel_alm/common/quartus_rename.v
@@ -157,6 +157,11 @@ output [CFG_DBITS-1:0] B1DATA;
// Much like the MLAB, the M10K has mem_init[01234] parameters which would let
// you initialise the RAM cell via hex literals. If they were implemented.
+// Since the MISTRAL_M10K block has an inverted write-enable (like the real hardware)
+// but the Quartus primitive expects a normal write-enable, we add an inverter.
+wire A1EN_N;
+NOT wren_inv (.IN(A1EN), .OUT(A1EN_N));
+
`RAM_BLOCK #(
.operation_mode("dual_port"),
.logical_ram_name(_TECHMAP_CELLNAME_),
@@ -176,10 +181,10 @@ output [CFG_DBITS-1:0] B1DATA;
.port_b_first_bit_number(0),
.port_b_address_clock("clock0"),
.port_b_read_enable_clock("clock0")
-) _TECHMAP_REPLACE_ (
+) ram_block (
.portaaddr(A1ADDR),
.portadatain(A1DATA),
- .portawe(A1EN),
+ .portawe(A1EN_N),
.portbaddr(B1ADDR),
.portbdataout(B1DATA),
.portbre(B1EN),
diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc
index 34a5ffa5d..43d3592d5 100644
--- a/techlibs/intel_alm/synth_intel_alm.cc
+++ b/techlibs/intel_alm/synth_intel_alm.cc
@@ -262,8 +262,7 @@ struct SynthIntelALMPass : public ScriptPass {
if (!nobram && check_label("map_bram", "(skip if -nobram)")) {
run(stringf("memory_bram -rules +/intel_alm/common/bram_%s.txt", bram_type.c_str()));
- if (help_mode || bram_type != "m10k")
- run(stringf("techmap -map +/intel_alm/common/bram_%s_map.v", bram_type.c_str()));
+ run(stringf("techmap -map +/intel_alm/common/bram_%s_map.v", bram_type.c_str()));
}
if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) {
diff --git a/techlibs/machxo2/Makefile.inc b/techlibs/machxo2/Makefile.inc
index 6f6f6ce94..f6aafbd2b 100644
--- a/techlibs/machxo2/Makefile.inc
+++ b/techlibs/machxo2/Makefile.inc
@@ -3,3 +3,8 @@ OBJS += techlibs/machxo2/synth_machxo2.o
$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_map.v))
$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_sim.v))
+
+$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/lutrams.txt))
+$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/lutrams_map.v))
+$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams.txt))
+$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams_map.v))
diff --git a/techlibs/machxo2/brams.txt b/techlibs/machxo2/brams.txt
new file mode 100644
index 000000000..3afbeda07
--- /dev/null
+++ b/techlibs/machxo2/brams.txt
@@ -0,0 +1,50 @@
+ram block $__DP8KC_ {
+ abits 13;
+ widths 1 2 4 9 per_port;
+ cost 64;
+ init no_undef;
+ port srsw "A" "B" {
+ clock posedge;
+ clken;
+ portoption "WRITEMODE" "NORMAL" {
+ rdwr no_change;
+ }
+ portoption "WRITEMODE" "WRITETHROUGH" {
+ rdwr new;
+ }
+ portoption "WRITEMODE" "READBEFOREWRITE" {
+ rdwr old;
+ }
+ option "RESETMODE" "SYNC" {
+ rdsrst zero ungated block_wr;
+ }
+ option "RESETMODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ }
+}
+
+ram block $__PDPW8KC_ {
+ abits 13;
+ widths 1 2 4 9 18 per_port;
+ byte 9;
+ cost 64;
+ init no_undef;
+ port sr "R" {
+ clock posedge;
+ clken;
+ option "RESETMODE" "SYNC" {
+ rdsrst zero ungated;
+ }
+ option "RESETMODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ }
+ port sw "W" {
+ width 18;
+ clock posedge;
+ clken;
+ }
+}
diff --git a/techlibs/machxo2/brams_map.v b/techlibs/machxo2/brams_map.v
new file mode 100644
index 000000000..05a8e8a9b
--- /dev/null
+++ b/techlibs/machxo2/brams_map.v
@@ -0,0 +1,337 @@
+module $__DP8KC_ (...);
+
+parameter INIT = 0;
+parameter OPTION_RESETMODE = "SYNC";
+
+parameter PORT_A_WIDTH = 18;
+parameter PORT_A_OPTION_WRITEMODE = "NORMAL";
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input PORT_A_WR_EN;
+input PORT_A_RD_SRST;
+input PORT_A_RD_ARST;
+input [12:0] PORT_A_ADDR;
+input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
+output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
+
+parameter PORT_B_WIDTH = 18;
+parameter PORT_B_OPTION_WRITEMODE = "NORMAL";
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input PORT_B_WR_EN;
+input PORT_B_RD_SRST;
+input PORT_B_RD_ARST;
+input [12:0] PORT_B_ADDR;
+input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
+output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
+
+function [319:0] init_slice;
+ input integer idx;
+ integer i, j;
+ init_slice = 0;
+ for (i = 0; i < 16; i = i + 1) begin
+ init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18];
+ end
+endfunction
+
+wire [8:0] DOA;
+wire [8:0] DOB;
+wire [8:0] DIA = PORT_A_WR_DATA;
+wire [8:0] DIB = PORT_B_WR_DATA;
+
+assign PORT_A_RD_DATA = DOA;
+assign PORT_B_RD_DATA = DOB;
+
+DP8KC #(
+ .INITVAL_00($sformatf("0x%080x", init_slice('h00))),
+ .INITVAL_01($sformatf("0x%080x", init_slice('h01))),
+ .INITVAL_02($sformatf("0x%080x", init_slice('h02))),
+ .INITVAL_03($sformatf("0x%080x", init_slice('h03))),
+ .INITVAL_04($sformatf("0x%080x", init_slice('h04))),
+ .INITVAL_05($sformatf("0x%080x", init_slice('h05))),
+ .INITVAL_06($sformatf("0x%080x", init_slice('h06))),
+ .INITVAL_07($sformatf("0x%080x", init_slice('h07))),
+ .INITVAL_08($sformatf("0x%080x", init_slice('h08))),
+ .INITVAL_09($sformatf("0x%080x", init_slice('h09))),
+ .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))),
+ .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))),
+ .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))),
+ .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))),
+ .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))),
+ .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))),
+ .INITVAL_10($sformatf("0x%080x", init_slice('h10))),
+ .INITVAL_11($sformatf("0x%080x", init_slice('h11))),
+ .INITVAL_12($sformatf("0x%080x", init_slice('h12))),
+ .INITVAL_13($sformatf("0x%080x", init_slice('h13))),
+ .INITVAL_14($sformatf("0x%080x", init_slice('h14))),
+ .INITVAL_15($sformatf("0x%080x", init_slice('h15))),
+ .INITVAL_16($sformatf("0x%080x", init_slice('h16))),
+ .INITVAL_17($sformatf("0x%080x", init_slice('h17))),
+ .INITVAL_18($sformatf("0x%080x", init_slice('h18))),
+ .INITVAL_19($sformatf("0x%080x", init_slice('h19))),
+ .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))),
+ .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))),
+ .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))),
+ .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))),
+ .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))),
+ .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))),
+ .DATA_WIDTH_A(PORT_A_WIDTH),
+ .DATA_WIDTH_B(PORT_B_WIDTH),
+ .REGMODE_A("NOREG"),
+ .REGMODE_B("NOREG"),
+ .RESETMODE(OPTION_RESETMODE),
+ .ASYNC_RESET_RELEASE(OPTION_RESETMODE),
+ .CSDECODE_A("0b000"),
+ .CSDECODE_B("0b000"),
+ .WRITEMODE_A(PORT_A_OPTION_WRITEMODE),
+ .WRITEMODE_B(PORT_B_OPTION_WRITEMODE),
+ .GSR("AUTO")
+) _TECHMAP_REPLACE_ (
+ .CLKA(PORT_A_CLK),
+ .WEA(PORT_A_WR_EN),
+ .CEA(PORT_A_CLK_EN),
+ .OCEA(1'b1),
+ .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST),
+ .CSA0(1'b0),
+ .CSA1(1'b0),
+ .CSA2(1'b0),
+ .ADA0(PORT_A_WIDTH == 9 ? 1'b1 : PORT_A_ADDR[0]),
+ .ADA1(PORT_A_ADDR[1]),
+ .ADA2(PORT_A_ADDR[2]),
+ .ADA3(PORT_A_ADDR[3]),
+ .ADA4(PORT_A_ADDR[4]),
+ .ADA5(PORT_A_ADDR[5]),
+ .ADA6(PORT_A_ADDR[6]),
+ .ADA7(PORT_A_ADDR[7]),
+ .ADA8(PORT_A_ADDR[8]),
+ .ADA9(PORT_A_ADDR[9]),
+ .ADA10(PORT_A_ADDR[10]),
+ .ADA11(PORT_A_ADDR[11]),
+ .ADA12(PORT_A_ADDR[12]),
+ .DIA0(DIA[0]),
+ .DIA1(DIA[1]),
+ .DIA2(DIA[2]),
+ .DIA3(DIA[3]),
+ .DIA4(DIA[4]),
+ .DIA5(DIA[5]),
+ .DIA6(DIA[6]),
+ .DIA7(DIA[7]),
+ .DIA8(DIA[8]),
+ .DOA0(DOA[0]),
+ .DOA1(DOA[1]),
+ .DOA2(DOA[2]),
+ .DOA3(DOA[3]),
+ .DOA4(DOA[4]),
+ .DOA5(DOA[5]),
+ .DOA6(DOA[6]),
+ .DOA7(DOA[7]),
+ .DOA8(DOA[8]),
+
+ .CLKB(PORT_B_CLK),
+ .WEB(PORT_B_WR_EN),
+ .CEB(PORT_B_CLK_EN),
+ .OCEB(1'b1),
+ .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST),
+ .CSB0(1'b0),
+ .CSB1(1'b0),
+ .CSB2(1'b0),
+ .ADB0(PORT_B_WIDTH == 9 ? 1'b1 : PORT_B_ADDR[0]),
+ .ADB1(PORT_B_ADDR[1]),
+ .ADB2(PORT_B_ADDR[2]),
+ .ADB3(PORT_B_ADDR[3]),
+ .ADB4(PORT_B_ADDR[4]),
+ .ADB5(PORT_B_ADDR[5]),
+ .ADB6(PORT_B_ADDR[6]),
+ .ADB7(PORT_B_ADDR[7]),
+ .ADB8(PORT_B_ADDR[8]),
+ .ADB9(PORT_B_ADDR[9]),
+ .ADB10(PORT_B_ADDR[10]),
+ .ADB11(PORT_B_ADDR[11]),
+ .ADB12(PORT_B_ADDR[12]),
+ .DIB0(DIB[0]),
+ .DIB1(DIB[1]),
+ .DIB2(DIB[2]),
+ .DIB3(DIB[3]),
+ .DIB4(DIB[4]),
+ .DIB5(DIB[5]),
+ .DIB6(DIB[6]),
+ .DIB7(DIB[7]),
+ .DIB8(DIB[8]),
+ .DOB0(DOB[0]),
+ .DOB1(DOB[1]),
+ .DOB2(DOB[2]),
+ .DOB3(DOB[3]),
+ .DOB4(DOB[4]),
+ .DOB5(DOB[5]),
+ .DOB6(DOB[6]),
+ .DOB7(DOB[7]),
+ .DOB8(DOB[8]),
+);
+
+endmodule
+
+
+module $__PDPW8KC_ (...);
+
+parameter INIT = 0;
+parameter OPTION_RESETMODE = "SYNC";
+
+parameter PORT_R_WIDTH = 18;
+
+input PORT_R_CLK;
+input PORT_R_CLK_EN;
+input PORT_R_RD_SRST;
+input PORT_R_RD_ARST;
+input [12:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+
+parameter PORT_W_WIDTH = 18;
+parameter PORT_W_WR_EN_WIDTH = 2;
+
+input PORT_W_CLK;
+input PORT_W_CLK_EN;
+input [12:0] PORT_W_ADDR;
+input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+
+function [319:0] init_slice;
+ input integer idx;
+ integer i, j;
+ init_slice = 0;
+ for (i = 0; i < 16; i = i + 1) begin
+ init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18];
+ end
+endfunction
+
+wire [17:0] DI = PORT_W_WR_DATA;
+wire [17:0] DO;
+
+assign PORT_R_RD_DATA = PORT_R_WIDTH == 18 ? DO : DO[17:9];
+
+DP8KC #(
+ .INITVAL_00($sformatf("0x%080x", init_slice('h00))),
+ .INITVAL_01($sformatf("0x%080x", init_slice('h01))),
+ .INITVAL_02($sformatf("0x%080x", init_slice('h02))),
+ .INITVAL_03($sformatf("0x%080x", init_slice('h03))),
+ .INITVAL_04($sformatf("0x%080x", init_slice('h04))),
+ .INITVAL_05($sformatf("0x%080x", init_slice('h05))),
+ .INITVAL_06($sformatf("0x%080x", init_slice('h06))),
+ .INITVAL_07($sformatf("0x%080x", init_slice('h07))),
+ .INITVAL_08($sformatf("0x%080x", init_slice('h08))),
+ .INITVAL_09($sformatf("0x%080x", init_slice('h09))),
+ .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))),
+ .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))),
+ .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))),
+ .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))),
+ .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))),
+ .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))),
+ .INITVAL_10($sformatf("0x%080x", init_slice('h10))),
+ .INITVAL_11($sformatf("0x%080x", init_slice('h11))),
+ .INITVAL_12($sformatf("0x%080x", init_slice('h12))),
+ .INITVAL_13($sformatf("0x%080x", init_slice('h13))),
+ .INITVAL_14($sformatf("0x%080x", init_slice('h14))),
+ .INITVAL_15($sformatf("0x%080x", init_slice('h15))),
+ .INITVAL_16($sformatf("0x%080x", init_slice('h16))),
+ .INITVAL_17($sformatf("0x%080x", init_slice('h17))),
+ .INITVAL_18($sformatf("0x%080x", init_slice('h18))),
+ .INITVAL_19($sformatf("0x%080x", init_slice('h19))),
+ .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))),
+ .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))),
+ .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))),
+ .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))),
+ .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))),
+ .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))),
+ .DATA_WIDTH_A(PORT_W_WIDTH),
+ .DATA_WIDTH_B(PORT_R_WIDTH),
+ .REGMODE_A("NOREG"),
+ .REGMODE_B("NOREG"),
+ .RESETMODE(OPTION_RESETMODE),
+ .ASYNC_RESET_RELEASE(OPTION_RESETMODE),
+ .CSDECODE_A("0b000"),
+ .CSDECODE_B("0b000"),
+ .GSR("AUTO")
+) _TECHMAP_REPLACE_ (
+ .CLKA(PORT_W_CLK),
+ .WEA(PORT_W_WIDTH >= 9 ? 1'b1 : PORT_W_WR_EN[0]),
+ .CEA(PORT_W_CLK_EN),
+ .OCEA(1'b0),
+ .RSTA(1'b0),
+ .CSA0(1'b0),
+ .CSA1(1'b0),
+ .CSA2(1'b0),
+ .ADA0(PORT_W_WIDTH >= 9 ? PORT_W_WR_EN[0] : PORT_W_ADDR[0]),
+ .ADA1(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[1] : PORT_W_ADDR[1]),
+ .ADA2(PORT_W_ADDR[2]),
+ .ADA3(PORT_W_ADDR[3]),
+ .ADA4(PORT_W_ADDR[4]),
+ .ADA5(PORT_W_ADDR[5]),
+ .ADA6(PORT_W_ADDR[6]),
+ .ADA7(PORT_W_ADDR[7]),
+ .ADA8(PORT_W_ADDR[8]),
+ .ADA9(PORT_W_ADDR[9]),
+ .ADA10(PORT_W_ADDR[10]),
+ .ADA11(PORT_W_ADDR[11]),
+ .ADA12(PORT_W_ADDR[12]),
+ .DIA0(DI[0]),
+ .DIA1(DI[1]),
+ .DIA2(DI[2]),
+ .DIA3(DI[3]),
+ .DIA4(DI[4]),
+ .DIA5(DI[5]),
+ .DIA6(DI[6]),
+ .DIA7(DI[7]),
+ .DIA8(DI[8]),
+ .DIB0(DI[9]),
+ .DIB1(DI[10]),
+ .DIB2(DI[11]),
+ .DIB3(DI[12]),
+ .DIB4(DI[13]),
+ .DIB5(DI[14]),
+ .DIB6(DI[15]),
+ .DIB7(DI[16]),
+ .DIB8(DI[17]),
+
+ .CLKB(PORT_R_CLK),
+ .WEB(1'b0),
+ .CEB(PORT_R_CLK_EN),
+ .OCEB(1'b1),
+ .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST),
+ .CSB0(1'b0),
+ .CSB1(1'b0),
+ .CSB2(1'b0),
+ .ADB0(PORT_R_ADDR[0]),
+ .ADB1(PORT_R_ADDR[1]),
+ .ADB2(PORT_R_ADDR[2]),
+ .ADB3(PORT_R_ADDR[3]),
+ .ADB4(PORT_R_ADDR[4]),
+ .ADB5(PORT_R_ADDR[5]),
+ .ADB6(PORT_R_ADDR[6]),
+ .ADB7(PORT_R_ADDR[7]),
+ .ADB8(PORT_R_ADDR[8]),
+ .ADB9(PORT_R_ADDR[9]),
+ .ADB10(PORT_R_ADDR[10]),
+ .ADB11(PORT_R_ADDR[11]),
+ .ADB12(PORT_R_ADDR[12]),
+ .DOA0(DO[0]),
+ .DOA1(DO[1]),
+ .DOA2(DO[2]),
+ .DOA3(DO[3]),
+ .DOA4(DO[4]),
+ .DOA5(DO[5]),
+ .DOA6(DO[6]),
+ .DOA7(DO[7]),
+ .DOA8(DO[8]),
+ .DOB0(DO[9]),
+ .DOB1(DO[10]),
+ .DOB2(DO[11]),
+ .DOB3(DO[12]),
+ .DOB4(DO[13]),
+ .DOB5(DO[14]),
+ .DOB6(DO[15]),
+ .DOB7(DO[16]),
+ .DOB8(DO[17]),
+);
+
+endmodule
diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v
index dc68a3127..82c9d8c4b 100644
--- a/techlibs/machxo2/cells_sim.v
+++ b/techlibs/machxo2/cells_sim.v
@@ -199,6 +199,127 @@ module DCMA (
);
endmodule
+(* abc9_box, lib_whitebox *)
+module DPR16X4C (
+ input [3:0] DI,
+ input WCK, WRE,
+ input [3:0] RAD,
+ input [3:0] WAD,
+ output [3:0] DO
+);
+ parameter INITVAL = "0x0000000000000000";
+
+ function [63:0] convert_initval;
+ input [143:0] hex_initval;
+ reg done;
+ reg [63:0] temp;
+ reg [7:0] char;
+ integer i;
+ begin
+ done = 1'b0;
+ temp = 0;
+ for (i = 0; i < 16; i = i + 1) begin
+ if (!done) begin
+ char = hex_initval[8*i +: 8];
+ if (char == "x") begin
+ done = 1'b1;
+ end else begin
+ if (char >= "0" && char <= "9")
+ temp[4*i +: 4] = char - "0";
+ else if (char >= "A" && char <= "F")
+ temp[4*i +: 4] = 10 + char - "A";
+ else if (char >= "a" && char <= "f")
+ temp[4*i +: 4] = 10 + char - "a";
+ end
+ end
+ end
+ convert_initval = temp;
+ end
+ endfunction
+
+ localparam conv_initval = convert_initval(INITVAL);
+
+ reg [3:0] ram[0:15];
+ integer i;
+ initial begin
+ for (i = 0; i < 15; i = i + 1) begin
+ ram[i] <= conv_initval[4*i +: 4];
+ end
+ end
+
+ always @(posedge WCK)
+ if (WRE)
+ ram[WAD] <= DI;
+
+ assign DO = ram[RAD];
+endmodule
+
+(* blackbox *)
+module DP8KC(
+ input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0,
+ input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0,
+ input CEA, OCEA, CLKA, WEA, RSTA,
+ input CSA2, CSA1, CSA0,
+ output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0,
+
+ input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0,
+ input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0,
+ input CEB, OCEB, CLKB, WEB, RSTB,
+ input CSB2, CSB1, CSB0,
+ output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0
+);
+ parameter DATA_WIDTH_A = 9;
+ parameter DATA_WIDTH_B = 9;
+
+ parameter REGMODE_A = "NOREG";
+ parameter REGMODE_B = "NOREG";
+
+ parameter RESETMODE = "SYNC";
+ parameter ASYNC_RESET_RELEASE = "SYNC";
+
+ parameter CSDECODE_A = "0b000";
+ parameter CSDECODE_B = "0b000";
+
+ parameter WRITEMODE_A = "NORMAL";
+ parameter WRITEMODE_B = "NORMAL";
+
+ parameter GSR = "ENABLED";
+ parameter INIT_DATA = "STATIC";
+
+ parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+ parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000";
+endmodule
+
// IO- "$__" cells for the iopadmap pass. These are temporary cells not meant
// to be instantiated by the end user. They are required in this file for
// attrmvcp to work.
diff --git a/techlibs/machxo2/lutrams.txt b/techlibs/machxo2/lutrams.txt
new file mode 100644
index 000000000..c6b0b6c45
--- /dev/null
+++ b/techlibs/machxo2/lutrams.txt
@@ -0,0 +1,12 @@
+ram distributed $__DPR16X4C_ {
+ abits 4;
+ width 4;
+ cost 4;
+ init no_undef;
+ prune_rom;
+ port sw "W" {
+ clock posedge;
+ }
+ port ar "R" {
+ }
+}
diff --git a/techlibs/machxo2/lutrams_map.v b/techlibs/machxo2/lutrams_map.v
new file mode 100644
index 000000000..b55253fb8
--- /dev/null
+++ b/techlibs/machxo2/lutrams_map.v
@@ -0,0 +1,23 @@
+module $__DPR16X4C_ (...);
+ parameter INIT = 64'b0;
+
+ input PORT_W_CLK;
+ input [3:0] PORT_W_ADDR;
+ input [3:0] PORT_W_WR_DATA;
+ input PORT_W_WR_EN;
+
+ input [3:0] PORT_R_ADDR;
+ output [3:0] PORT_R_RD_DATA;
+
+ DPR16X4C #(
+ .INITVAL($sformatf("0x%08x", INIT))
+ ) _TECHMAP_REPLACE_ (
+ .RAD(PORT_R_ADDR),
+ .DO(PORT_R_RD_DATA),
+
+ .WAD(PORT_W_ADDR),
+ .DI(PORT_W_WR_DATA),
+ .WCK(PORT_W_CLK),
+ .WRE(PORT_W_WR_EN)
+ );
+endmodule
diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc
index e86ec5aaf..dbd01bbfd 100644
--- a/techlibs/machxo2/synth_machxo2.cc
+++ b/techlibs/machxo2/synth_machxo2.cc
@@ -57,6 +57,12 @@ struct SynthMachXO2Pass : public ScriptPass
log(" from label is synonymous to 'begin', and empty to label is\n");
log(" synonymous to the end of the command list.\n");
log("\n");
+ log(" -nobram\n");
+ log(" do not use block RAM cells in output netlist\n");
+ log("\n");
+ log(" -nolutram\n");
+ log(" do not use LUT RAM cells in output netlist\n");
+ log("\n");
log(" -noflatten\n");
log(" do not flatten design before synthesis\n");
log("\n");
@@ -74,7 +80,7 @@ struct SynthMachXO2Pass : public ScriptPass
}
string top_opt, blif_file, edif_file, json_file;
- bool flatten, vpr, noiopad;
+ bool nobram, nolutram, flatten, vpr, noiopad;
void clear_flags() override
{
@@ -82,6 +88,8 @@ struct SynthMachXO2Pass : public ScriptPass
blif_file = "";
edif_file = "";
json_file = "";
+ nobram = false;
+ nolutram = false;
flatten = true;
vpr = false;
noiopad = false;
@@ -127,6 +135,14 @@ struct SynthMachXO2Pass : public ScriptPass
flatten = false;
continue;
}
+ if (args[argidx] == "-nobram") {
+ nobram = true;
+ continue;
+ }
+ if (args[argidx] == "-nolutram") {
+ nolutram = true;
+ continue;
+ }
if (args[argidx] == "-noiopad") {
noiopad = true;
continue;
@@ -173,6 +189,19 @@ struct SynthMachXO2Pass : public ScriptPass
run("synth -run coarse");
}
+ if (check_label("map_ram"))
+ {
+ std::string args = "";
+ if (nobram)
+ args += " -no-auto-block";
+ if (nolutram)
+ args += " -no-auto-distributed";
+ if (help_mode)
+ args += " [-no-auto-block] [-no-auto-distributed]";
+ run("memory_libmap -lib +/machxo2/lutrams.txt -lib +/machxo2/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)");
+ run("techmap -map +/machxo2/lutrams_map.v -map +/machxo2/brams_map.v");
+ }
+
if (check_label("fine"))
{
run("memory_map");
diff --git a/techlibs/nexus/Makefile.inc b/techlibs/nexus/Makefile.inc
index 9828d32c1..8121d1d8a 100644
--- a/techlibs/nexus/Makefile.inc
+++ b/techlibs/nexus/Makefile.inc
@@ -6,10 +6,8 @@ $(eval $(call add_share_file,share/nexus,techlibs/nexus/parse_init.vh))
$(eval $(call add_share_file,share/nexus,techlibs/nexus/cells_xtra.v))
$(eval $(call add_share_file,share/nexus,techlibs/nexus/lutrams_map.v))
$(eval $(call add_share_file,share/nexus,techlibs/nexus/lutrams.txt))
-$(eval $(call add_share_file,share/nexus,techlibs/nexus/brams_init.vh))
$(eval $(call add_share_file,share/nexus,techlibs/nexus/brams_map.v))
$(eval $(call add_share_file,share/nexus,techlibs/nexus/brams.txt))
-$(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams_init.vh))
$(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams_map.v))
$(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams.txt))
$(eval $(call add_share_file,share/nexus,techlibs/nexus/arith_map.v))
diff --git a/techlibs/nexus/arith_map.v b/techlibs/nexus/arith_map.v
index 9a1fedfc8..81ab7ba54 100644
--- a/techlibs/nexus/arith_map.v
+++ b/techlibs/nexus/arith_map.v
@@ -90,7 +90,7 @@ module _80_nexus_alu (A, B, CI, BI, X, Y, CO);
assign CO[i] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i]));
if (i+1 < Y_WIDTH) begin
- assign CO[i + 1] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i]));
+ assign CO[i + 1] = (AA[i + 1] && BB[i + 1]) || ((Y[i + 1] ^ AA[i + 1] ^ BB[i + 1]) && (AA[i + 1] || BB[i + 1]));
assign Y[i+1] = Y1[i];
end
end endgenerate
diff --git a/techlibs/nexus/brams.txt b/techlibs/nexus/brams.txt
index 086afe8bf..975a8d227 100644
--- a/techlibs/nexus/brams.txt
+++ b/techlibs/nexus/brams.txt
@@ -1,63 +1,47 @@
-bram $__NX_PDP16K
- init 1
+ram block $__NX_DP16K_ {
+ abits 14;
+ widths 1 2 4 9 18 per_port;
+ byte 9;
+ cost 129;
+ init no_undef;
+ port srsw "A" "B" {
+ clock posedge;
+ clken;
+ wrbe_separate;
+ rdwr no_change;
+ portoption "RESETMODE" "SYNC" {
+ rdsrst zero gated_clken;
+ }
+ portoption "RESETMODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ }
+}
- 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 1 0
- enable 4 1 @a9d36
- enable 2 1 @a10d18
- enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-match $__NX_PDP16K
- # implicitly requested RAM or ROM
- attribute !syn_ramstyle syn_ramstyle=auto
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- min bits 2048
- min efficiency 5
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__NX_PDP16K
- # explicitly requested RAM
- attribute syn_ramstyle=block_ram ram_block
- attribute !syn_romstyle
- attribute !rom_block
- attribute !logic_block
- min wports 1
- shuffle_enable A
- make_transp
- or_next_if_better
-endmatch
-
-match $__NX_PDP16K
- # explicitly requested ROM
- attribute syn_romstyle=ebr rom_block
- attribute !syn_ramstyle
- attribute !ram_block
- attribute !logic_block
- max wports 0
- make_transp
- shuffle_enable A
-endmatch
+ram block $__NX_PDP16K_ {
+ abits 14;
+ widths 1 2 4 9 18 36 per_port;
+ byte 9;
+ option "SAME_CLOCK" 1 cost 128;
+ option "SAME_CLOCK" 0 cost 129;
+ init no_undef;
+ port sr "R" {
+ option "SAME_CLOCK" 1 clock posedge "C";
+ option "SAME_CLOCK" 0 clock posedge;
+ clken;
+ portoption "RESETMODE" "SYNC" {
+ rdsrst zero gated_clken;
+ }
+ portoption "RESETMODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ }
+ port sw "W" {
+ option "SAME_CLOCK" 1 clock posedge "C";
+ option "SAME_CLOCK" 0 clock posedge;
+ clken;
+ option "SAME_CLOCK" 1 wrtrans all old;
+ }
+}
diff --git a/techlibs/nexus/brams_init.vh b/techlibs/nexus/brams_init.vh
deleted file mode 100644
index 5b1d0188a..000000000
--- a/techlibs/nexus/brams_init.vh
+++ /dev/null
@@ -1,64 +0,0 @@
-.INITVAL_00($sformatf("0x%080x", permute_init(INIT[0 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_01($sformatf("0x%080x", permute_init(INIT[1 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_02($sformatf("0x%080x", permute_init(INIT[2 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_03($sformatf("0x%080x", permute_init(INIT[3 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_04($sformatf("0x%080x", permute_init(INIT[4 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_05($sformatf("0x%080x", permute_init(INIT[5 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_06($sformatf("0x%080x", permute_init(INIT[6 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_07($sformatf("0x%080x", permute_init(INIT[7 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_08($sformatf("0x%080x", permute_init(INIT[8 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_09($sformatf("0x%080x", permute_init(INIT[9 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0A($sformatf("0x%080x", permute_init(INIT[10 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0B($sformatf("0x%080x", permute_init(INIT[11 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0C($sformatf("0x%080x", permute_init(INIT[12 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0D($sformatf("0x%080x", permute_init(INIT[13 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0E($sformatf("0x%080x", permute_init(INIT[14 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0F($sformatf("0x%080x", permute_init(INIT[15 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_10($sformatf("0x%080x", permute_init(INIT[16 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_11($sformatf("0x%080x", permute_init(INIT[17 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_12($sformatf("0x%080x", permute_init(INIT[18 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_13($sformatf("0x%080x", permute_init(INIT[19 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_14($sformatf("0x%080x", permute_init(INIT[20 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_15($sformatf("0x%080x", permute_init(INIT[21 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_16($sformatf("0x%080x", permute_init(INIT[22 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_17($sformatf("0x%080x", permute_init(INIT[23 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_18($sformatf("0x%080x", permute_init(INIT[24 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_19($sformatf("0x%080x", permute_init(INIT[25 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1A($sformatf("0x%080x", permute_init(INIT[26 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1B($sformatf("0x%080x", permute_init(INIT[27 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1C($sformatf("0x%080x", permute_init(INIT[28 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1D($sformatf("0x%080x", permute_init(INIT[29 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1E($sformatf("0x%080x", permute_init(INIT[30 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1F($sformatf("0x%080x", permute_init(INIT[31 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_20($sformatf("0x%080x", permute_init(INIT[32 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_21($sformatf("0x%080x", permute_init(INIT[33 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_22($sformatf("0x%080x", permute_init(INIT[34 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_23($sformatf("0x%080x", permute_init(INIT[35 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_24($sformatf("0x%080x", permute_init(INIT[36 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_25($sformatf("0x%080x", permute_init(INIT[37 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_26($sformatf("0x%080x", permute_init(INIT[38 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_27($sformatf("0x%080x", permute_init(INIT[39 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_28($sformatf("0x%080x", permute_init(INIT[40 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_29($sformatf("0x%080x", permute_init(INIT[41 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2A($sformatf("0x%080x", permute_init(INIT[42 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2B($sformatf("0x%080x", permute_init(INIT[43 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2C($sformatf("0x%080x", permute_init(INIT[44 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2D($sformatf("0x%080x", permute_init(INIT[45 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2E($sformatf("0x%080x", permute_init(INIT[46 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2F($sformatf("0x%080x", permute_init(INIT[47 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_30($sformatf("0x%080x", permute_init(INIT[48 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_31($sformatf("0x%080x", permute_init(INIT[49 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_32($sformatf("0x%080x", permute_init(INIT[50 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_33($sformatf("0x%080x", permute_init(INIT[51 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_34($sformatf("0x%080x", permute_init(INIT[52 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_35($sformatf("0x%080x", permute_init(INIT[53 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_36($sformatf("0x%080x", permute_init(INIT[54 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_37($sformatf("0x%080x", permute_init(INIT[55 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_38($sformatf("0x%080x", permute_init(INIT[56 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_39($sformatf("0x%080x", permute_init(INIT[57 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3A($sformatf("0x%080x", permute_init(INIT[58 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3B($sformatf("0x%080x", permute_init(INIT[59 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3C($sformatf("0x%080x", permute_init(INIT[60 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3D($sformatf("0x%080x", permute_init(INIT[61 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3E($sformatf("0x%080x", permute_init(INIT[62 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3F($sformatf("0x%080x", permute_init(INIT[63 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])))
diff --git a/techlibs/nexus/brams_map.v b/techlibs/nexus/brams_map.v
index 214da4326..3cada2414 100644
--- a/techlibs/nexus/brams_map.v
+++ b/techlibs/nexus/brams_map.v
@@ -1,115 +1,382 @@
-module \$__NX_PDP16K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 9;
- parameter CFG_DBITS = 36;
- parameter CFG_ENABLE_A = 4;
-
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
- parameter [18431:0] INIT = 18432'b0;
-
- parameter _TECHMAP_BITS_CONNMAP_ = 8;
- parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_CLK2_ = 0;
- parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_CLK3_ = 0;
-
- input CLK2;
- input CLK3;
-
- input [CFG_ABITS-1:0] A1ADDR;
- input [CFG_DBITS-1:0] A1DATA;
- input [CFG_ENABLE_A-1:0] A1EN;
-
- input [CFG_ABITS-1:0] B1ADDR;
- output [CFG_DBITS-1:0] B1DATA;
- input B1EN;
-
- // Address is left justified, in x18 and above lower bits are byte enables
- localparam A_SHIFT =
- (CFG_DBITS == 36) ? 5 :
- (CFG_DBITS == 18) ? 4 :
- (CFG_DBITS == 9) ? 3 :
- (CFG_DBITS == 4) ? 2 :
- (CFG_DBITS == 2) ? 1 :
- 0;
-
- // Different primitives needed for single vs dual clock case
- localparam SINGLE_CLOCK = (_TECHMAP_CONNMAP_CLK2_ == _TECHMAP_CONNMAP_CLK3_);
-
- localparam WIDTH = $sformatf("X%d", CFG_DBITS);
-
- wire [13:0] ra, wa;
- wire [35:0] rd, wd;
-
- assign ra = {B1ADDR, {A_SHIFT{1'b1}}};
-
- generate
- if (CFG_ENABLE_A > 1)
- assign wa = {A1ADDR, {(A_SHIFT-CFG_ENABLE_A){1'b1}}, A1EN};
- else
- assign wa = {A1ADDR, {A_SHIFT{1'b1}}};
- endgenerate
-
- assign wd = A1DATA;
- assign B1DATA = rd[CFG_DBITS-1:0];
-
- wire wck, rck;
-
- generate
- if (CLKPOL2)
- assign wck = CLK2;
- else
- INV wck_inv_i (.A(CLK2), .Z(wck));
- if (CLKPOL3)
- assign rck = CLK3;
- else
- INV wck_inv_i (.A(CLK3), .Z(rck));
- endgenerate
-
- wire we = |A1EN;
-
- localparam INIT_CHUNK_SIZE = (CFG_DBITS <= 4) ? 256 : 288;
-
- function [319:0] permute_init;
- input [INIT_CHUNK_SIZE-1:0] chunk;
- integer i;
- begin
- if (CFG_DBITS <= 4) begin
- for (i = 0; i < 32; i = i + 1'b1)
- permute_init[i * 10 +: 10] = {2'b00, chunk[i * 8 +: 8]};
- end else begin
- for (i = 0; i < 32; i = i + 1'b1)
- permute_init[i * 10 +: 10] = {1'b0, chunk[i * 9 +: 9]};
- end
- end
- endfunction
-
- generate
- if (SINGLE_CLOCK) begin
- PDPSC16K #(
- .DATA_WIDTH_W(WIDTH),
- .DATA_WIDTH_R(WIDTH),
- .OUTREG("BYPASSED"),
- .ECC("DISABLED"),
- .GSR("DISABLED"),
-`include "brams_init.vh"
- ) _TECHMAP_REPLACE_ (
- .CLK(wck), .RST(1'b0),
- .DI(wd), .ADW(wa), .CEW(we), .CSW(3'b111),
- .ADR(ra), .DO(rd), .CER(B1EN), .CSR(3'b111)
- );
- end else begin
- PDP16K #(
- .DATA_WIDTH_W(WIDTH),
- .DATA_WIDTH_R(WIDTH),
- .OUTREG("BYPASSED"),
- .ECC("DISABLED"),
- .GSR("DISABLED"),
-`include "brams_init.vh"
- ) _TECHMAP_REPLACE_ (
- .CLKW(wck), .CLKR(rck), .RST(1'b0),
- .DI(wd), .ADW(wa), .CEW(we), .CSW(3'b111),
- .ADR(ra), .DO(rd), .CER(B1EN), .CSR(3'b111)
- );
- end
- endgenerate
+module $__NX_DP16K_ (...);
+
+parameter INIT = 0;
+
+parameter PORT_A_OPTION_RESETMODE = "SYNC";
+parameter PORT_A_WIDTH = 18;
+parameter PORT_A_WR_BE_WIDTH = 2;
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input PORT_A_WR_EN;
+input PORT_A_RD_SRST;
+input PORT_A_RD_ARST;
+input [13:0] PORT_A_ADDR;
+input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE;
+input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
+output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
+
+parameter PORT_B_OPTION_RESETMODE = "SYNC";
+parameter PORT_B_WIDTH = 18;
+parameter PORT_B_WR_BE_WIDTH = 2;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input PORT_B_WR_EN;
+input PORT_B_RD_SRST;
+input PORT_B_RD_ARST;
+input [13:0] PORT_B_ADDR;
+input [PORT_B_WR_BE_WIDTH-1:0] PORT_B_WR_BE;
+input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
+output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
+
+function [319:0] init_slice;
+ input integer idx;
+ integer i, j;
+ init_slice = 0;
+ for (i = 0; i < 16; i = i + 1) begin
+ init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18];
+ end
+endfunction
+
+wire [17:0] DOA;
+wire [17:0] DOB;
+wire [17:0] DIA = PORT_A_WR_DATA;
+wire [17:0] DIB = PORT_B_WR_DATA;
+wire [13:0] ADA = PORT_A_WIDTH == 18 ? {PORT_A_ADDR[13:2], PORT_A_WR_BE} : PORT_A_ADDR;
+wire [13:0] ADB = PORT_B_WIDTH == 18 ? {PORT_B_ADDR[13:2], PORT_B_WR_BE} : PORT_B_ADDR;
+
+assign PORT_A_RD_DATA = DOA;
+assign PORT_B_RD_DATA = DOB;
+
+DP16K #(
+ .INITVAL_00($sformatf("0x%080x", init_slice('h00))),
+ .INITVAL_01($sformatf("0x%080x", init_slice('h01))),
+ .INITVAL_02($sformatf("0x%080x", init_slice('h02))),
+ .INITVAL_03($sformatf("0x%080x", init_slice('h03))),
+ .INITVAL_04($sformatf("0x%080x", init_slice('h04))),
+ .INITVAL_05($sformatf("0x%080x", init_slice('h05))),
+ .INITVAL_06($sformatf("0x%080x", init_slice('h06))),
+ .INITVAL_07($sformatf("0x%080x", init_slice('h07))),
+ .INITVAL_08($sformatf("0x%080x", init_slice('h08))),
+ .INITVAL_09($sformatf("0x%080x", init_slice('h09))),
+ .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))),
+ .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))),
+ .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))),
+ .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))),
+ .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))),
+ .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))),
+ .INITVAL_10($sformatf("0x%080x", init_slice('h10))),
+ .INITVAL_11($sformatf("0x%080x", init_slice('h11))),
+ .INITVAL_12($sformatf("0x%080x", init_slice('h12))),
+ .INITVAL_13($sformatf("0x%080x", init_slice('h13))),
+ .INITVAL_14($sformatf("0x%080x", init_slice('h14))),
+ .INITVAL_15($sformatf("0x%080x", init_slice('h15))),
+ .INITVAL_16($sformatf("0x%080x", init_slice('h16))),
+ .INITVAL_17($sformatf("0x%080x", init_slice('h17))),
+ .INITVAL_18($sformatf("0x%080x", init_slice('h18))),
+ .INITVAL_19($sformatf("0x%080x", init_slice('h19))),
+ .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))),
+ .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))),
+ .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))),
+ .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))),
+ .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))),
+ .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))),
+ .INITVAL_20($sformatf("0x%080x", init_slice('h20))),
+ .INITVAL_21($sformatf("0x%080x", init_slice('h21))),
+ .INITVAL_22($sformatf("0x%080x", init_slice('h22))),
+ .INITVAL_23($sformatf("0x%080x", init_slice('h23))),
+ .INITVAL_24($sformatf("0x%080x", init_slice('h24))),
+ .INITVAL_25($sformatf("0x%080x", init_slice('h25))),
+ .INITVAL_26($sformatf("0x%080x", init_slice('h26))),
+ .INITVAL_27($sformatf("0x%080x", init_slice('h27))),
+ .INITVAL_28($sformatf("0x%080x", init_slice('h28))),
+ .INITVAL_29($sformatf("0x%080x", init_slice('h29))),
+ .INITVAL_2A($sformatf("0x%080x", init_slice('h2a))),
+ .INITVAL_2B($sformatf("0x%080x", init_slice('h2b))),
+ .INITVAL_2C($sformatf("0x%080x", init_slice('h2c))),
+ .INITVAL_2D($sformatf("0x%080x", init_slice('h2d))),
+ .INITVAL_2E($sformatf("0x%080x", init_slice('h2e))),
+ .INITVAL_2F($sformatf("0x%080x", init_slice('h2f))),
+ .INITVAL_30($sformatf("0x%080x", init_slice('h30))),
+ .INITVAL_31($sformatf("0x%080x", init_slice('h31))),
+ .INITVAL_32($sformatf("0x%080x", init_slice('h32))),
+ .INITVAL_33($sformatf("0x%080x", init_slice('h33))),
+ .INITVAL_34($sformatf("0x%080x", init_slice('h34))),
+ .INITVAL_35($sformatf("0x%080x", init_slice('h35))),
+ .INITVAL_36($sformatf("0x%080x", init_slice('h36))),
+ .INITVAL_37($sformatf("0x%080x", init_slice('h37))),
+ .INITVAL_38($sformatf("0x%080x", init_slice('h38))),
+ .INITVAL_39($sformatf("0x%080x", init_slice('h39))),
+ .INITVAL_3A($sformatf("0x%080x", init_slice('h3a))),
+ .INITVAL_3B($sformatf("0x%080x", init_slice('h3b))),
+ .INITVAL_3C($sformatf("0x%080x", init_slice('h3c))),
+ .INITVAL_3D($sformatf("0x%080x", init_slice('h3d))),
+ .INITVAL_3E($sformatf("0x%080x", init_slice('h3e))),
+ .INITVAL_3F($sformatf("0x%080x", init_slice('h3f))),
+ .DATA_WIDTH_A($sformatf("X%d", PORT_A_WIDTH)),
+ .DATA_WIDTH_B($sformatf("X%d", PORT_B_WIDTH)),
+ .OUTREG_A("BYPASSED"),
+ .OUTREG_B("BYPASSED"),
+ .RESETMODE_A(PORT_A_OPTION_RESETMODE),
+ .RESETMODE_B(PORT_B_OPTION_RESETMODE),
+ .ASYNC_RST_RELEASE_A(PORT_A_OPTION_RESETMODE),
+ .ASYNC_RST_RELEASE_B(PORT_B_OPTION_RESETMODE),
+ .CSDECODE_A("000"),
+ .CSDECODE_B("000"),
+ .GSR("DISABLED"),
+) _TECHMAP_REPLACE_ (
+ .CLKA(PORT_A_CLK),
+ .WEA(PORT_A_WIDTH == 18 ? PORT_A_WR_EN : (PORT_A_WR_EN | PORT_A_WR_BE[0])),
+ .CEA(PORT_A_CLK_EN),
+ .RSTA(PORT_A_OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST),
+ .CSA(3'b111),
+ .DIA(DIA),
+ .DOA(DOA),
+ .ADA(ADA),
+
+ .CLKB(PORT_B_CLK),
+ .WEB(PORT_B_WIDTH == 18 ? PORT_B_WR_EN : (PORT_B_WR_EN | PORT_B_WR_BE[0])),
+ .CEB(PORT_B_CLK_EN),
+ .RSTB(PORT_B_OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST),
+ .CSB(3'b111),
+ .ADB(ADB),
+ .DIB(DIB),
+ .DOB(DOB),
+);
+
+endmodule
+
+
+module $__NX_PDP16K_ (...);
+
+parameter INIT = 0;
+parameter OPTION_SAME_CLOCK = 1;
+
+parameter PORT_R_WIDTH = 36;
+parameter PORT_R_OPTION_RESETMODE = "SYNC";
+
+input CLK_C;
+
+input PORT_R_CLK;
+input PORT_R_CLK_EN;
+input PORT_R_RD_SRST;
+input PORT_R_RD_ARST;
+input [13:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+
+parameter PORT_W_WIDTH = 36;
+parameter PORT_W_WR_EN_WIDTH = 4;
+
+input PORT_W_CLK;
+input PORT_W_CLK_EN;
+input [13:0] PORT_W_ADDR;
+input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+
+function [319:0] init_slice;
+ input integer idx;
+ integer i, j;
+ init_slice = 0;
+ for (i = 0; i < 16; i = i + 1) begin
+ init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18];
+ end
+endfunction
+
+wire [35:0] DI = PORT_W_WR_DATA;
+wire [35:0] DO;
+
+assign PORT_R_RD_DATA = DO;
+
+wire [13:0] ADW = PORT_W_WIDTH == 36 ? {PORT_W_ADDR[13:4], PORT_W_WR_EN} :
+ (PORT_W_WIDTH == 18 ? {PORT_W_ADDR[13:2], PORT_W_WR_EN} : PORT_W_ADDR);
+
+generate
+
+if (OPTION_SAME_CLOCK) begin
+
+PDPSC16K #(
+ .INITVAL_00($sformatf("0x%080x", init_slice('h00))),
+ .INITVAL_01($sformatf("0x%080x", init_slice('h01))),
+ .INITVAL_02($sformatf("0x%080x", init_slice('h02))),
+ .INITVAL_03($sformatf("0x%080x", init_slice('h03))),
+ .INITVAL_04($sformatf("0x%080x", init_slice('h04))),
+ .INITVAL_05($sformatf("0x%080x", init_slice('h05))),
+ .INITVAL_06($sformatf("0x%080x", init_slice('h06))),
+ .INITVAL_07($sformatf("0x%080x", init_slice('h07))),
+ .INITVAL_08($sformatf("0x%080x", init_slice('h08))),
+ .INITVAL_09($sformatf("0x%080x", init_slice('h09))),
+ .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))),
+ .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))),
+ .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))),
+ .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))),
+ .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))),
+ .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))),
+ .INITVAL_10($sformatf("0x%080x", init_slice('h10))),
+ .INITVAL_11($sformatf("0x%080x", init_slice('h11))),
+ .INITVAL_12($sformatf("0x%080x", init_slice('h12))),
+ .INITVAL_13($sformatf("0x%080x", init_slice('h13))),
+ .INITVAL_14($sformatf("0x%080x", init_slice('h14))),
+ .INITVAL_15($sformatf("0x%080x", init_slice('h15))),
+ .INITVAL_16($sformatf("0x%080x", init_slice('h16))),
+ .INITVAL_17($sformatf("0x%080x", init_slice('h17))),
+ .INITVAL_18($sformatf("0x%080x", init_slice('h18))),
+ .INITVAL_19($sformatf("0x%080x", init_slice('h19))),
+ .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))),
+ .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))),
+ .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))),
+ .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))),
+ .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))),
+ .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))),
+ .INITVAL_20($sformatf("0x%080x", init_slice('h20))),
+ .INITVAL_21($sformatf("0x%080x", init_slice('h21))),
+ .INITVAL_22($sformatf("0x%080x", init_slice('h22))),
+ .INITVAL_23($sformatf("0x%080x", init_slice('h23))),
+ .INITVAL_24($sformatf("0x%080x", init_slice('h24))),
+ .INITVAL_25($sformatf("0x%080x", init_slice('h25))),
+ .INITVAL_26($sformatf("0x%080x", init_slice('h26))),
+ .INITVAL_27($sformatf("0x%080x", init_slice('h27))),
+ .INITVAL_28($sformatf("0x%080x", init_slice('h28))),
+ .INITVAL_29($sformatf("0x%080x", init_slice('h29))),
+ .INITVAL_2A($sformatf("0x%080x", init_slice('h2a))),
+ .INITVAL_2B($sformatf("0x%080x", init_slice('h2b))),
+ .INITVAL_2C($sformatf("0x%080x", init_slice('h2c))),
+ .INITVAL_2D($sformatf("0x%080x", init_slice('h2d))),
+ .INITVAL_2E($sformatf("0x%080x", init_slice('h2e))),
+ .INITVAL_2F($sformatf("0x%080x", init_slice('h2f))),
+ .INITVAL_30($sformatf("0x%080x", init_slice('h30))),
+ .INITVAL_31($sformatf("0x%080x", init_slice('h31))),
+ .INITVAL_32($sformatf("0x%080x", init_slice('h32))),
+ .INITVAL_33($sformatf("0x%080x", init_slice('h33))),
+ .INITVAL_34($sformatf("0x%080x", init_slice('h34))),
+ .INITVAL_35($sformatf("0x%080x", init_slice('h35))),
+ .INITVAL_36($sformatf("0x%080x", init_slice('h36))),
+ .INITVAL_37($sformatf("0x%080x", init_slice('h37))),
+ .INITVAL_38($sformatf("0x%080x", init_slice('h38))),
+ .INITVAL_39($sformatf("0x%080x", init_slice('h39))),
+ .INITVAL_3A($sformatf("0x%080x", init_slice('h3a))),
+ .INITVAL_3B($sformatf("0x%080x", init_slice('h3b))),
+ .INITVAL_3C($sformatf("0x%080x", init_slice('h3c))),
+ .INITVAL_3D($sformatf("0x%080x", init_slice('h3d))),
+ .INITVAL_3E($sformatf("0x%080x", init_slice('h3e))),
+ .INITVAL_3F($sformatf("0x%080x", init_slice('h3f))),
+ .DATA_WIDTH_W($sformatf("X%d", PORT_W_WIDTH)),
+ .DATA_WIDTH_R($sformatf("X%d", PORT_R_WIDTH)),
+ .OUTREG("BYPASSED"),
+ .RESETMODE(PORT_R_OPTION_RESETMODE),
+ .ASYNC_RST_RELEASE(PORT_R_OPTION_RESETMODE),
+ .CSDECODE_W("000"),
+ .CSDECODE_R("000"),
+ .ECC("DISABLED"),
+ .GSR("DISABLED"),
+) _TECHMAP_REPLACE_ (
+ .CLK(CLK_C),
+
+ .CEW(PORT_W_CLK_EN),
+ .CSW(3'b111),
+ .ADW(ADW),
+ .DI(DI),
+
+ .CER(PORT_R_CLK_EN),
+ .RST(PORT_R_OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST),
+ .CSR(3'b111),
+ .ADR(PORT_R_ADDR),
+ .DO(DO),
+);
+
+end else begin
+
+PDP16K #(
+ .INITVAL_00($sformatf("0x%080x", init_slice('h00))),
+ .INITVAL_01($sformatf("0x%080x", init_slice('h01))),
+ .INITVAL_02($sformatf("0x%080x", init_slice('h02))),
+ .INITVAL_03($sformatf("0x%080x", init_slice('h03))),
+ .INITVAL_04($sformatf("0x%080x", init_slice('h04))),
+ .INITVAL_05($sformatf("0x%080x", init_slice('h05))),
+ .INITVAL_06($sformatf("0x%080x", init_slice('h06))),
+ .INITVAL_07($sformatf("0x%080x", init_slice('h07))),
+ .INITVAL_08($sformatf("0x%080x", init_slice('h08))),
+ .INITVAL_09($sformatf("0x%080x", init_slice('h09))),
+ .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))),
+ .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))),
+ .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))),
+ .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))),
+ .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))),
+ .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))),
+ .INITVAL_10($sformatf("0x%080x", init_slice('h10))),
+ .INITVAL_11($sformatf("0x%080x", init_slice('h11))),
+ .INITVAL_12($sformatf("0x%080x", init_slice('h12))),
+ .INITVAL_13($sformatf("0x%080x", init_slice('h13))),
+ .INITVAL_14($sformatf("0x%080x", init_slice('h14))),
+ .INITVAL_15($sformatf("0x%080x", init_slice('h15))),
+ .INITVAL_16($sformatf("0x%080x", init_slice('h16))),
+ .INITVAL_17($sformatf("0x%080x", init_slice('h17))),
+ .INITVAL_18($sformatf("0x%080x", init_slice('h18))),
+ .INITVAL_19($sformatf("0x%080x", init_slice('h19))),
+ .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))),
+ .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))),
+ .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))),
+ .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))),
+ .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))),
+ .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))),
+ .INITVAL_20($sformatf("0x%080x", init_slice('h20))),
+ .INITVAL_21($sformatf("0x%080x", init_slice('h21))),
+ .INITVAL_22($sformatf("0x%080x", init_slice('h22))),
+ .INITVAL_23($sformatf("0x%080x", init_slice('h23))),
+ .INITVAL_24($sformatf("0x%080x", init_slice('h24))),
+ .INITVAL_25($sformatf("0x%080x", init_slice('h25))),
+ .INITVAL_26($sformatf("0x%080x", init_slice('h26))),
+ .INITVAL_27($sformatf("0x%080x", init_slice('h27))),
+ .INITVAL_28($sformatf("0x%080x", init_slice('h28))),
+ .INITVAL_29($sformatf("0x%080x", init_slice('h29))),
+ .INITVAL_2A($sformatf("0x%080x", init_slice('h2a))),
+ .INITVAL_2B($sformatf("0x%080x", init_slice('h2b))),
+ .INITVAL_2C($sformatf("0x%080x", init_slice('h2c))),
+ .INITVAL_2D($sformatf("0x%080x", init_slice('h2d))),
+ .INITVAL_2E($sformatf("0x%080x", init_slice('h2e))),
+ .INITVAL_2F($sformatf("0x%080x", init_slice('h2f))),
+ .INITVAL_30($sformatf("0x%080x", init_slice('h30))),
+ .INITVAL_31($sformatf("0x%080x", init_slice('h31))),
+ .INITVAL_32($sformatf("0x%080x", init_slice('h32))),
+ .INITVAL_33($sformatf("0x%080x", init_slice('h33))),
+ .INITVAL_34($sformatf("0x%080x", init_slice('h34))),
+ .INITVAL_35($sformatf("0x%080x", init_slice('h35))),
+ .INITVAL_36($sformatf("0x%080x", init_slice('h36))),
+ .INITVAL_37($sformatf("0x%080x", init_slice('h37))),
+ .INITVAL_38($sformatf("0x%080x", init_slice('h38))),
+ .INITVAL_39($sformatf("0x%080x", init_slice('h39))),
+ .INITVAL_3A($sformatf("0x%080x", init_slice('h3a))),
+ .INITVAL_3B($sformatf("0x%080x", init_slice('h3b))),
+ .INITVAL_3C($sformatf("0x%080x", init_slice('h3c))),
+ .INITVAL_3D($sformatf("0x%080x", init_slice('h3d))),
+ .INITVAL_3E($sformatf("0x%080x", init_slice('h3e))),
+ .INITVAL_3F($sformatf("0x%080x", init_slice('h3f))),
+ .DATA_WIDTH_W($sformatf("X%d", PORT_W_WIDTH)),
+ .DATA_WIDTH_R($sformatf("X%d", PORT_R_WIDTH)),
+ .OUTREG("BYPASSED"),
+ .RESETMODE(PORT_R_OPTION_RESETMODE),
+ .ASYNC_RST_RELEASE(PORT_R_OPTION_RESETMODE),
+ .CSDECODE_W("000"),
+ .CSDECODE_R("000"),
+ .ECC("DISABLED"),
+ .GSR("DISABLED"),
+) _TECHMAP_REPLACE_ (
+ .CLKW(PORT_W_CLK),
+ .CEW(PORT_W_CLK_EN),
+ .CSW(3'b111),
+ .ADW(ADW),
+ .DI(DI),
+
+ .CLKR(PORT_R_CLK),
+ .CER(PORT_R_CLK_EN),
+ .RST(PORT_R_OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST),
+ .CSR(3'b111),
+ .ADR(PORT_R_ADDR),
+ .DO(DO),
+);
+
+end
+
+endgenerate
endmodule
diff --git a/techlibs/nexus/cells_sim.v b/techlibs/nexus/cells_sim.v
index 1e876a210..d1c8bf0d7 100644
--- a/techlibs/nexus/cells_sim.v
+++ b/techlibs/nexus/cells_sim.v
@@ -54,8 +54,8 @@ endmodule
// Bidirectional IO buffer
module BB(input T, I, output O,
(* iopad_external_pin *) inout B);
- assign B = T ? 1'bz : O;
- assign I = B;
+ assign B = T ? 1'bz : I;
+ assign O = B;
endmodule
// Input buffer
diff --git a/techlibs/nexus/lrams.txt b/techlibs/nexus/lrams.txt
index 481629b98..ad2845783 100644
--- a/techlibs/nexus/lrams.txt
+++ b/techlibs/nexus/lrams.txt
@@ -1,22 +1,21 @@
-bram $__NX_PDPSC512K
- init 1
-
- abits 14
- dbits 32
-
- groups 2
- ports 1 1
- wrmode 1 0
- enable 4 1
- transp 0 0
- clocks 2 2
- clkpol 2 2
-endbram
-
-match $__NX_PDPSC512K
- # explicitly requested LRAM only, due to limited availability and
- # slower Fmax
- attribute lram
- shuffle_enable A
- make_transp
-endmatch
+ram huge $__NX_DPSC512K_ {
+ abits 14;
+ width 32;
+ byte 8;
+ cost 2048;
+ init no_undef;
+ port srsw "A" "B" {
+ clock posedge "C";
+ clken;
+ wrbe_separate;
+ rdwr no_change;
+ option "RESETMODE" "SYNC" {
+ rdsrst zero gated_clken;
+ }
+ option "RESETMODE" "ASYNC" {
+ rdarst zero;
+ }
+ rdinit zero;
+ wrtrans all old;
+ }
+}
diff --git a/techlibs/nexus/lrams_init.vh b/techlibs/nexus/lrams_init.vh
deleted file mode 100644
index 31a7ba4a8..000000000
--- a/techlibs/nexus/lrams_init.vh
+++ /dev/null
@@ -1,128 +0,0 @@
-.INITVAL_00($sformatf("0x%05120x", permute_init(INIT[0 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_01($sformatf("0x%05120x", permute_init(INIT[1 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_02($sformatf("0x%05120x", permute_init(INIT[2 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_03($sformatf("0x%05120x", permute_init(INIT[3 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_04($sformatf("0x%05120x", permute_init(INIT[4 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_05($sformatf("0x%05120x", permute_init(INIT[5 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_06($sformatf("0x%05120x", permute_init(INIT[6 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_07($sformatf("0x%05120x", permute_init(INIT[7 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_08($sformatf("0x%05120x", permute_init(INIT[8 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_09($sformatf("0x%05120x", permute_init(INIT[9 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0A($sformatf("0x%05120x", permute_init(INIT[10 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0B($sformatf("0x%05120x", permute_init(INIT[11 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0C($sformatf("0x%05120x", permute_init(INIT[12 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0D($sformatf("0x%05120x", permute_init(INIT[13 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0E($sformatf("0x%05120x", permute_init(INIT[14 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_0F($sformatf("0x%05120x", permute_init(INIT[15 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_10($sformatf("0x%05120x", permute_init(INIT[16 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_11($sformatf("0x%05120x", permute_init(INIT[17 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_12($sformatf("0x%05120x", permute_init(INIT[18 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_13($sformatf("0x%05120x", permute_init(INIT[19 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_14($sformatf("0x%05120x", permute_init(INIT[20 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_15($sformatf("0x%05120x", permute_init(INIT[21 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_16($sformatf("0x%05120x", permute_init(INIT[22 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_17($sformatf("0x%05120x", permute_init(INIT[23 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_18($sformatf("0x%05120x", permute_init(INIT[24 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_19($sformatf("0x%05120x", permute_init(INIT[25 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1A($sformatf("0x%05120x", permute_init(INIT[26 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1B($sformatf("0x%05120x", permute_init(INIT[27 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1C($sformatf("0x%05120x", permute_init(INIT[28 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1D($sformatf("0x%05120x", permute_init(INIT[29 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1E($sformatf("0x%05120x", permute_init(INIT[30 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_1F($sformatf("0x%05120x", permute_init(INIT[31 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_20($sformatf("0x%05120x", permute_init(INIT[32 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_21($sformatf("0x%05120x", permute_init(INIT[33 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_22($sformatf("0x%05120x", permute_init(INIT[34 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_23($sformatf("0x%05120x", permute_init(INIT[35 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_24($sformatf("0x%05120x", permute_init(INIT[36 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_25($sformatf("0x%05120x", permute_init(INIT[37 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_26($sformatf("0x%05120x", permute_init(INIT[38 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_27($sformatf("0x%05120x", permute_init(INIT[39 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_28($sformatf("0x%05120x", permute_init(INIT[40 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_29($sformatf("0x%05120x", permute_init(INIT[41 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2A($sformatf("0x%05120x", permute_init(INIT[42 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2B($sformatf("0x%05120x", permute_init(INIT[43 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2C($sformatf("0x%05120x", permute_init(INIT[44 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2D($sformatf("0x%05120x", permute_init(INIT[45 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2E($sformatf("0x%05120x", permute_init(INIT[46 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_2F($sformatf("0x%05120x", permute_init(INIT[47 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_30($sformatf("0x%05120x", permute_init(INIT[48 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_31($sformatf("0x%05120x", permute_init(INIT[49 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_32($sformatf("0x%05120x", permute_init(INIT[50 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_33($sformatf("0x%05120x", permute_init(INIT[51 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_34($sformatf("0x%05120x", permute_init(INIT[52 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_35($sformatf("0x%05120x", permute_init(INIT[53 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_36($sformatf("0x%05120x", permute_init(INIT[54 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_37($sformatf("0x%05120x", permute_init(INIT[55 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_38($sformatf("0x%05120x", permute_init(INIT[56 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_39($sformatf("0x%05120x", permute_init(INIT[57 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3A($sformatf("0x%05120x", permute_init(INIT[58 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3B($sformatf("0x%05120x", permute_init(INIT[59 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3C($sformatf("0x%05120x", permute_init(INIT[60 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3D($sformatf("0x%05120x", permute_init(INIT[61 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3E($sformatf("0x%05120x", permute_init(INIT[62 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_3F($sformatf("0x%05120x", permute_init(INIT[63 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_40($sformatf("0x%05120x", permute_init(INIT[64 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_41($sformatf("0x%05120x", permute_init(INIT[65 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_42($sformatf("0x%05120x", permute_init(INIT[66 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_43($sformatf("0x%05120x", permute_init(INIT[67 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_44($sformatf("0x%05120x", permute_init(INIT[68 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_45($sformatf("0x%05120x", permute_init(INIT[69 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_46($sformatf("0x%05120x", permute_init(INIT[70 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_47($sformatf("0x%05120x", permute_init(INIT[71 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_48($sformatf("0x%05120x", permute_init(INIT[72 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_49($sformatf("0x%05120x", permute_init(INIT[73 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_4A($sformatf("0x%05120x", permute_init(INIT[74 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_4B($sformatf("0x%05120x", permute_init(INIT[75 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_4C($sformatf("0x%05120x", permute_init(INIT[76 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_4D($sformatf("0x%05120x", permute_init(INIT[77 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_4E($sformatf("0x%05120x", permute_init(INIT[78 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_4F($sformatf("0x%05120x", permute_init(INIT[79 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_50($sformatf("0x%05120x", permute_init(INIT[80 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_51($sformatf("0x%05120x", permute_init(INIT[81 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_52($sformatf("0x%05120x", permute_init(INIT[82 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_53($sformatf("0x%05120x", permute_init(INIT[83 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_54($sformatf("0x%05120x", permute_init(INIT[84 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_55($sformatf("0x%05120x", permute_init(INIT[85 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_56($sformatf("0x%05120x", permute_init(INIT[86 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_57($sformatf("0x%05120x", permute_init(INIT[87 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_58($sformatf("0x%05120x", permute_init(INIT[88 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_59($sformatf("0x%05120x", permute_init(INIT[89 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_5A($sformatf("0x%05120x", permute_init(INIT[90 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_5B($sformatf("0x%05120x", permute_init(INIT[91 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_5C($sformatf("0x%05120x", permute_init(INIT[92 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_5D($sformatf("0x%05120x", permute_init(INIT[93 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_5E($sformatf("0x%05120x", permute_init(INIT[94 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_5F($sformatf("0x%05120x", permute_init(INIT[95 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_60($sformatf("0x%05120x", permute_init(INIT[96 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_61($sformatf("0x%05120x", permute_init(INIT[97 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_62($sformatf("0x%05120x", permute_init(INIT[98 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_63($sformatf("0x%05120x", permute_init(INIT[99 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_64($sformatf("0x%05120x", permute_init(INIT[100 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_65($sformatf("0x%05120x", permute_init(INIT[101 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_66($sformatf("0x%05120x", permute_init(INIT[102 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_67($sformatf("0x%05120x", permute_init(INIT[103 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_68($sformatf("0x%05120x", permute_init(INIT[104 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_69($sformatf("0x%05120x", permute_init(INIT[105 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_6A($sformatf("0x%05120x", permute_init(INIT[106 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_6B($sformatf("0x%05120x", permute_init(INIT[107 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_6C($sformatf("0x%05120x", permute_init(INIT[108 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_6D($sformatf("0x%05120x", permute_init(INIT[109 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_6E($sformatf("0x%05120x", permute_init(INIT[110 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_6F($sformatf("0x%05120x", permute_init(INIT[111 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_70($sformatf("0x%05120x", permute_init(INIT[112 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_71($sformatf("0x%05120x", permute_init(INIT[113 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_72($sformatf("0x%05120x", permute_init(INIT[114 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_73($sformatf("0x%05120x", permute_init(INIT[115 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_74($sformatf("0x%05120x", permute_init(INIT[116 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_75($sformatf("0x%05120x", permute_init(INIT[117 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_76($sformatf("0x%05120x", permute_init(INIT[118 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_77($sformatf("0x%05120x", permute_init(INIT[119 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_78($sformatf("0x%05120x", permute_init(INIT[120 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_79($sformatf("0x%05120x", permute_init(INIT[121 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_7A($sformatf("0x%05120x", permute_init(INIT[122 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_7B($sformatf("0x%05120x", permute_init(INIT[123 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_7C($sformatf("0x%05120x", permute_init(INIT[124 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_7D($sformatf("0x%05120x", permute_init(INIT[125 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_7E($sformatf("0x%05120x", permute_init(INIT[126 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
-.INITVAL_7F($sformatf("0x%05120x", permute_init(INIT[127 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))),
diff --git a/techlibs/nexus/lrams_map.v b/techlibs/nexus/lrams_map.v
index 938a0e843..5db5ae8bf 100644
--- a/techlibs/nexus/lrams_map.v
+++ b/techlibs/nexus/lrams_map.v
@@ -1,56 +1,194 @@
-module \$__NX_PDPSC512K (CLK2, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 14;
- parameter CFG_DBITS = 32;
- parameter CFG_ENABLE_A = 4;
-
- parameter CLKPOL2 = 1;
- parameter [524287:0] INIT = 524287'b0;
-
- input CLK2;
-
- input [CFG_ABITS-1:0] A1ADDR;
- input [CFG_DBITS-1:0] A1DATA;
- input [CFG_ENABLE_A-1:0] A1EN;
-
- input [CFG_ABITS-1:0] B1ADDR;
- output [CFG_DBITS-1:0] B1DATA;
- input B1EN;
-
- wire clk;
- wire [31:0] rd;
- assign B1DATA = rd[CFG_DBITS-1:0];
-
- generate
- if (CLKPOL2)
- assign clk = CLK2;
- else
- INV clk_inv_i (.A(CLK2), .Z(clk));
- endgenerate
-
- wire we = |A1EN;
-
- localparam INIT_CHUNK_SIZE = 4096;
-
- function [5119:0] permute_init;
- input [INIT_CHUNK_SIZE-1:0] chunk;
- integer i;
- begin
- for (i = 0; i < 128; i = i + 1'b1)
- permute_init[i * 40 +: 40] = {8'b0, chunk[i * 32 +: 32]};
- end
- endfunction
-
- generate
- PDPSC512K #(
- .OUTREG("NO_REG"),
- .ECC_BYTE_SEL("BYTE_EN"),
-`include "lrams_init.vh"
- .GSR("DISABLED")
- ) _TECHMAP_REPLACE_ (
- .CLK(clk), .RSTR(1'b0),
- .DI(A1DATA), .ADW(A1ADDR), .CEW(we), .WE(we), .CSW(1'b1),
- .ADR(B1ADDR), .DO(rd), .CER(B1EN), .CSR(1'b1),
- );
- endgenerate
+module $__NX_DPSC512K_ (...);
+
+parameter INIT = 0;
+parameter OPTION_RESETMODE = "SYNC";
+
+input CLK_C;
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input PORT_A_WR_EN;
+input PORT_A_RD_SRST;
+input PORT_A_RD_ARST;
+input [13:0] PORT_A_ADDR;
+input [3:0] PORT_A_WR_BE;
+input [31:0] PORT_A_WR_DATA;
+output [31:0] PORT_A_RD_DATA;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input PORT_B_WR_EN;
+input PORT_B_RD_SRST;
+input PORT_B_RD_ARST;
+input [13:0] PORT_B_ADDR;
+input [3:0] PORT_B_WR_BE;
+input [31:0] PORT_B_WR_DATA;
+output [31:0] PORT_B_RD_DATA;
+
+function [5119:0] init_slice;
+ input integer idx;
+ integer i, j;
+ init_slice = 0;
+ for (i = 0; i < 128; i = i + 1) begin
+ init_slice[i*40+:32] = INIT[(idx * 128 + i) * 32+:32];
+ end
+endfunction
+
+DPSC512K #(
+ .INITVAL_00($sformatf("0x%01280x", init_slice('h00))),
+ .INITVAL_01($sformatf("0x%01280x", init_slice('h01))),
+ .INITVAL_02($sformatf("0x%01280x", init_slice('h02))),
+ .INITVAL_03($sformatf("0x%01280x", init_slice('h03))),
+ .INITVAL_04($sformatf("0x%01280x", init_slice('h04))),
+ .INITVAL_05($sformatf("0x%01280x", init_slice('h05))),
+ .INITVAL_06($sformatf("0x%01280x", init_slice('h06))),
+ .INITVAL_07($sformatf("0x%01280x", init_slice('h07))),
+ .INITVAL_08($sformatf("0x%01280x", init_slice('h08))),
+ .INITVAL_09($sformatf("0x%01280x", init_slice('h09))),
+ .INITVAL_0A($sformatf("0x%01280x", init_slice('h0a))),
+ .INITVAL_0B($sformatf("0x%01280x", init_slice('h0b))),
+ .INITVAL_0C($sformatf("0x%01280x", init_slice('h0c))),
+ .INITVAL_0D($sformatf("0x%01280x", init_slice('h0d))),
+ .INITVAL_0E($sformatf("0x%01280x", init_slice('h0e))),
+ .INITVAL_0F($sformatf("0x%01280x", init_slice('h0f))),
+ .INITVAL_10($sformatf("0x%01280x", init_slice('h10))),
+ .INITVAL_11($sformatf("0x%01280x", init_slice('h11))),
+ .INITVAL_12($sformatf("0x%01280x", init_slice('h12))),
+ .INITVAL_13($sformatf("0x%01280x", init_slice('h13))),
+ .INITVAL_14($sformatf("0x%01280x", init_slice('h14))),
+ .INITVAL_15($sformatf("0x%01280x", init_slice('h15))),
+ .INITVAL_16($sformatf("0x%01280x", init_slice('h16))),
+ .INITVAL_17($sformatf("0x%01280x", init_slice('h17))),
+ .INITVAL_18($sformatf("0x%01280x", init_slice('h18))),
+ .INITVAL_19($sformatf("0x%01280x", init_slice('h19))),
+ .INITVAL_1A($sformatf("0x%01280x", init_slice('h1a))),
+ .INITVAL_1B($sformatf("0x%01280x", init_slice('h1b))),
+ .INITVAL_1C($sformatf("0x%01280x", init_slice('h1c))),
+ .INITVAL_1D($sformatf("0x%01280x", init_slice('h1d))),
+ .INITVAL_1E($sformatf("0x%01280x", init_slice('h1e))),
+ .INITVAL_1F($sformatf("0x%01280x", init_slice('h1f))),
+ .INITVAL_20($sformatf("0x%01280x", init_slice('h20))),
+ .INITVAL_21($sformatf("0x%01280x", init_slice('h21))),
+ .INITVAL_22($sformatf("0x%01280x", init_slice('h22))),
+ .INITVAL_23($sformatf("0x%01280x", init_slice('h23))),
+ .INITVAL_24($sformatf("0x%01280x", init_slice('h24))),
+ .INITVAL_25($sformatf("0x%01280x", init_slice('h25))),
+ .INITVAL_26($sformatf("0x%01280x", init_slice('h26))),
+ .INITVAL_27($sformatf("0x%01280x", init_slice('h27))),
+ .INITVAL_28($sformatf("0x%01280x", init_slice('h28))),
+ .INITVAL_29($sformatf("0x%01280x", init_slice('h29))),
+ .INITVAL_2A($sformatf("0x%01280x", init_slice('h2a))),
+ .INITVAL_2B($sformatf("0x%01280x", init_slice('h2b))),
+ .INITVAL_2C($sformatf("0x%01280x", init_slice('h2c))),
+ .INITVAL_2D($sformatf("0x%01280x", init_slice('h2d))),
+ .INITVAL_2E($sformatf("0x%01280x", init_slice('h2e))),
+ .INITVAL_2F($sformatf("0x%01280x", init_slice('h2f))),
+ .INITVAL_30($sformatf("0x%01280x", init_slice('h30))),
+ .INITVAL_31($sformatf("0x%01280x", init_slice('h31))),
+ .INITVAL_32($sformatf("0x%01280x", init_slice('h32))),
+ .INITVAL_33($sformatf("0x%01280x", init_slice('h33))),
+ .INITVAL_34($sformatf("0x%01280x", init_slice('h34))),
+ .INITVAL_35($sformatf("0x%01280x", init_slice('h35))),
+ .INITVAL_36($sformatf("0x%01280x", init_slice('h36))),
+ .INITVAL_37($sformatf("0x%01280x", init_slice('h37))),
+ .INITVAL_38($sformatf("0x%01280x", init_slice('h38))),
+ .INITVAL_39($sformatf("0x%01280x", init_slice('h39))),
+ .INITVAL_3A($sformatf("0x%01280x", init_slice('h3a))),
+ .INITVAL_3B($sformatf("0x%01280x", init_slice('h3b))),
+ .INITVAL_3C($sformatf("0x%01280x", init_slice('h3c))),
+ .INITVAL_3D($sformatf("0x%01280x", init_slice('h3d))),
+ .INITVAL_3E($sformatf("0x%01280x", init_slice('h3e))),
+ .INITVAL_3F($sformatf("0x%01280x", init_slice('h3f))),
+ .INITVAL_40($sformatf("0x%01280x", init_slice('h40))),
+ .INITVAL_41($sformatf("0x%01280x", init_slice('h41))),
+ .INITVAL_42($sformatf("0x%01280x", init_slice('h42))),
+ .INITVAL_43($sformatf("0x%01280x", init_slice('h43))),
+ .INITVAL_44($sformatf("0x%01280x", init_slice('h44))),
+ .INITVAL_45($sformatf("0x%01280x", init_slice('h45))),
+ .INITVAL_46($sformatf("0x%01280x", init_slice('h46))),
+ .INITVAL_47($sformatf("0x%01280x", init_slice('h47))),
+ .INITVAL_48($sformatf("0x%01280x", init_slice('h48))),
+ .INITVAL_49($sformatf("0x%01280x", init_slice('h49))),
+ .INITVAL_4A($sformatf("0x%01280x", init_slice('h4a))),
+ .INITVAL_4B($sformatf("0x%01280x", init_slice('h4b))),
+ .INITVAL_4C($sformatf("0x%01280x", init_slice('h4c))),
+ .INITVAL_4D($sformatf("0x%01280x", init_slice('h4d))),
+ .INITVAL_4E($sformatf("0x%01280x", init_slice('h4e))),
+ .INITVAL_4F($sformatf("0x%01280x", init_slice('h4f))),
+ .INITVAL_50($sformatf("0x%01280x", init_slice('h50))),
+ .INITVAL_51($sformatf("0x%01280x", init_slice('h51))),
+ .INITVAL_52($sformatf("0x%01280x", init_slice('h52))),
+ .INITVAL_53($sformatf("0x%01280x", init_slice('h53))),
+ .INITVAL_54($sformatf("0x%01280x", init_slice('h54))),
+ .INITVAL_55($sformatf("0x%01280x", init_slice('h55))),
+ .INITVAL_56($sformatf("0x%01280x", init_slice('h56))),
+ .INITVAL_57($sformatf("0x%01280x", init_slice('h57))),
+ .INITVAL_58($sformatf("0x%01280x", init_slice('h58))),
+ .INITVAL_59($sformatf("0x%01280x", init_slice('h59))),
+ .INITVAL_5A($sformatf("0x%01280x", init_slice('h5a))),
+ .INITVAL_5B($sformatf("0x%01280x", init_slice('h5b))),
+ .INITVAL_5C($sformatf("0x%01280x", init_slice('h5c))),
+ .INITVAL_5D($sformatf("0x%01280x", init_slice('h5d))),
+ .INITVAL_5E($sformatf("0x%01280x", init_slice('h5e))),
+ .INITVAL_5F($sformatf("0x%01280x", init_slice('h5f))),
+ .INITVAL_60($sformatf("0x%01280x", init_slice('h60))),
+ .INITVAL_61($sformatf("0x%01280x", init_slice('h61))),
+ .INITVAL_62($sformatf("0x%01280x", init_slice('h62))),
+ .INITVAL_63($sformatf("0x%01280x", init_slice('h63))),
+ .INITVAL_64($sformatf("0x%01280x", init_slice('h64))),
+ .INITVAL_65($sformatf("0x%01280x", init_slice('h65))),
+ .INITVAL_66($sformatf("0x%01280x", init_slice('h66))),
+ .INITVAL_67($sformatf("0x%01280x", init_slice('h67))),
+ .INITVAL_68($sformatf("0x%01280x", init_slice('h68))),
+ .INITVAL_69($sformatf("0x%01280x", init_slice('h69))),
+ .INITVAL_6A($sformatf("0x%01280x", init_slice('h6a))),
+ .INITVAL_6B($sformatf("0x%01280x", init_slice('h6b))),
+ .INITVAL_6C($sformatf("0x%01280x", init_slice('h6c))),
+ .INITVAL_6D($sformatf("0x%01280x", init_slice('h6d))),
+ .INITVAL_6E($sformatf("0x%01280x", init_slice('h6e))),
+ .INITVAL_6F($sformatf("0x%01280x", init_slice('h6f))),
+ .INITVAL_70($sformatf("0x%01280x", init_slice('h70))),
+ .INITVAL_71($sformatf("0x%01280x", init_slice('h71))),
+ .INITVAL_72($sformatf("0x%01280x", init_slice('h72))),
+ .INITVAL_73($sformatf("0x%01280x", init_slice('h73))),
+ .INITVAL_74($sformatf("0x%01280x", init_slice('h74))),
+ .INITVAL_75($sformatf("0x%01280x", init_slice('h75))),
+ .INITVAL_76($sformatf("0x%01280x", init_slice('h76))),
+ .INITVAL_77($sformatf("0x%01280x", init_slice('h77))),
+ .INITVAL_78($sformatf("0x%01280x", init_slice('h78))),
+ .INITVAL_79($sformatf("0x%01280x", init_slice('h79))),
+ .INITVAL_7A($sformatf("0x%01280x", init_slice('h7a))),
+ .INITVAL_7B($sformatf("0x%01280x", init_slice('h7b))),
+ .INITVAL_7C($sformatf("0x%01280x", init_slice('h7c))),
+ .INITVAL_7D($sformatf("0x%01280x", init_slice('h7d))),
+ .INITVAL_7E($sformatf("0x%01280x", init_slice('h7e))),
+ .INITVAL_7F($sformatf("0x%01280x", init_slice('h7f))),
+ .OUTREG_A("NO_REG"),
+ .OUTREG_B("NO_REG"),
+ .ECC_BYTE_SEL("BYTE_EN"),
+ .GSR("DISABLED"),
+ .RESETMODE(OPTION_RESETMODE),
+ .ASYNC_RESET_RELEASE(OPTION_RESETMODE),
+) _TECHMAP_REPLACE_ (
+ .CLK(CLK_C),
+
+ .WEA(PORT_A_WR_EN),
+ .CEA(PORT_A_CLK_EN),
+ .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST),
+ .CSA(1'b1),
+ .ADA(PORT_A_ADDR),
+ .BENA_N(~PORT_A_WR_BE),
+ .DIA(PORT_A_WR_DATA),
+ .DOA(PORT_A_RD_DATA),
+
+ .WEB(PORT_B_WR_EN),
+ .CEB(PORT_B_CLK_EN),
+ .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST),
+ .CSB(1'b1),
+ .BENB_N(~PORT_B_WR_BE),
+ .ADB(PORT_B_ADDR),
+ .DIB(PORT_B_WR_DATA),
+ .DOB(PORT_B_RD_DATA),
+);
endmodule
diff --git a/techlibs/nexus/lutrams.txt b/techlibs/nexus/lutrams.txt
index 2568b9998..90e1e7bfd 100644
--- a/techlibs/nexus/lutrams.txt
+++ b/techlibs/nexus/lutrams.txt
@@ -1,26 +1,12 @@
-bram $__NEXUS_DPR16X4
- init 1
- abits 4
- dbits 4
- groups 2
- ports 1 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 2
-endbram
-
-# The syn_* attributes are described in:
-# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx
-attr_icase 1
-
-match $__NEXUS_DPR16X4
- attribute !syn_ramstyle syn_ramstyle=auto syn_ramstyle=distributed
- attribute !syn_romstyle syn_romstyle=auto
- attribute !ram_block
- attribute !rom_block
- attribute !logic_block
- make_outreg
- min wports 1
-endmatch
+ram distributed $__NEXUS_DPR16X4_ {
+ abits 4;
+ width 4;
+ cost 4;
+ init no_undef;
+ prune_rom;
+ port sw "W" {
+ clock posedge;
+ }
+ port ar "R" {
+ }
+}
diff --git a/techlibs/nexus/lutrams_map.v b/techlibs/nexus/lutrams_map.v
index 0910664ce..d12b49060 100644
--- a/techlibs/nexus/lutrams_map.v
+++ b/techlibs/nexus/lutrams_map.v
@@ -1,34 +1,23 @@
-module \$__NEXUS_DPR16X4 (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
- parameter [63:0] INIT = 64'b0;
- parameter CLKPOL2 = 1;
- input CLK1;
+module $__NEXUS_DPR16X4_ (...);
+ parameter INIT = 64'b0;
- input [3:0] A1ADDR;
- output [3:0] A1DATA;
+ input PORT_W_CLK;
+ input [3:0] PORT_W_ADDR;
+ input [3:0] PORT_W_WR_DATA;
+ input PORT_W_WR_EN;
- input [3:0] B1ADDR;
- input [3:0] B1DATA;
- input B1EN;
-
-
- wire wck;
-
- generate
- if (CLKPOL2)
- assign wck = CLK1;
- else
- INV wck_inv_i (.A(CLK1), .Z(wck));
- endgenerate
+ input [3:0] PORT_R_ADDR;
+ output [3:0] PORT_R_RD_DATA;
DPR16X4 #(
.INITVAL($sformatf("0x%08x", INIT))
) _TECHMAP_REPLACE_ (
- .RAD(A1ADDR),
- .DO(A1DATA),
+ .RAD(PORT_R_ADDR),
+ .DO(PORT_R_RD_DATA),
- .WAD(B1ADDR),
- .DI(B1DATA),
- .WCK(CLK1),
- .WRE(B1EN)
+ .WAD(PORT_W_ADDR),
+ .DI(PORT_W_WR_DATA),
+ .WCK(PORT_W_CLK),
+ .WRE(PORT_W_WR_EN)
);
endmodule
diff --git a/techlibs/nexus/synth_nexus.cc b/techlibs/nexus/synth_nexus.cc
index 03bff0649..6fd15ba55 100644
--- a/techlibs/nexus/synth_nexus.cc
+++ b/techlibs/nexus/synth_nexus.cc
@@ -296,33 +296,24 @@ struct SynthNexusPass : public ScriptPass
run("opt_clean");
}
- if (!nolram && check_label("map_lram", "(skip if -nolram)"))
+ if (check_label("map_ram"))
{
- run("memory_bram -rules +/nexus/lrams.txt");
- run("setundef -zero -params t:$__NX_PDPSC512K");
- run("techmap -map +/nexus/lrams_map.v");
- }
-
- if (!nobram && check_label("map_bram", "(skip if -nobram)"))
- {
- run("memory_bram -rules +/nexus/brams.txt");
- run("setundef -zero -params t:$__NX_PDP16K");
- run("techmap -map +/nexus/brams_map.v");
- }
-
- if (!nolutram && check_label("map_lutram", "(skip if -nolutram)"))
- {
- run("memory_bram -rules +/nexus/lutrams.txt");
- run("setundef -zero -params t:$__NEXUS_DPR16X4");
- run("techmap -map +/nexus/lutrams_map.v");
+ std::string args = "";
+ args += " -no-auto-huge";
+ if (nobram)
+ args += " -no-auto-block";
+ if (nolutram)
+ args += " -no-auto-distributed";
+ if (help_mode)
+ args += " [-no-auto-block] [-no-auto-distributed]";
+ run("memory_libmap -lib +/nexus/lutrams.txt -lib +/nexus/brams.txt -lib +/nexus/lrams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)");
+ run("techmap -map +/nexus/lutrams_map.v -map +/nexus/brams_map.v -map +/nexus/lrams_map.v");
}
if (check_label("map_ffram"))
{
run("opt -fast -mux_undef -undriven -fine");
- run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block "
- "-attr syn_ramstyle=auto -attr syn_ramstyle=registers "
- "-attr syn_romstyle=auto -attr syn_romstyle=logic");
+ run("memory_map");
run("opt -undriven -fine");
}
diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc
index a67b167b8..754de2de6 100644
--- a/techlibs/quicklogic/synth_quicklogic.cc
+++ b/techlibs/quicklogic/synth_quicklogic.cc
@@ -225,8 +225,8 @@ struct SynthQuickLogicPass : public ScriptPass {
}
if (check_label("verilog")) {
- if (!verilog_file.empty()) {
- run("write_verilog -noattr -nohex " + verilog_file);
+ if (!verilog_file.empty() || help_mode) {
+ run(stringf("write_verilog -noattr -nohex %s", help_mode ? "<file-name>" : verilog_file.c_str()));
}
}
}
diff --git a/techlibs/xilinx/.gitignore b/techlibs/xilinx/.gitignore
deleted file mode 100644
index d127107db..000000000
--- a/techlibs/xilinx/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-brams_init.mk
-brams_init_*.vh
diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc
index ba87278de..2d3d0f63c 100644
--- a/techlibs/xilinx/Makefile.inc
+++ b/techlibs/xilinx/Makefile.inc
@@ -2,45 +2,37 @@
OBJS += techlibs/xilinx/synth_xilinx.o
OBJS += techlibs/xilinx/xilinx_dffopt.o
-GENFILES += techlibs/xilinx/brams_init_36.vh
-GENFILES += techlibs/xilinx/brams_init_32.vh
-GENFILES += techlibs/xilinx/brams_init_18.vh
-GENFILES += techlibs/xilinx/brams_init_16.vh
-GENFILES += techlibs/xilinx/brams_init_9.vh
-GENFILES += techlibs/xilinx/brams_init_8.vh
+$(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))
-EXTRA_OBJS += techlibs/xilinx/brams_init.mk
-.SECONDARY: techlibs/xilinx/brams_init.mk
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_xcv.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_xcv_map.v))
-techlibs/xilinx/brams_init.mk: techlibs/xilinx/brams_init.py
- $(Q) mkdir -p techlibs/xilinx
- $(P) $(PYTHON_EXECUTABLE) $<
- $(Q) touch $@
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_xc5v.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_xcu.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_xc5v_map.v))
-techlibs/xilinx/brams_init_36.vh: techlibs/xilinx/brams_init.mk
-techlibs/xilinx/brams_init_32.vh: techlibs/xilinx/brams_init.mk
-techlibs/xilinx/brams_init_18.vh: techlibs/xilinx/brams_init.mk
-techlibs/xilinx/brams_init_16.vh: techlibs/xilinx/brams_init.mk
-techlibs/xilinx/brams_init_9.vh: techlibs/xilinx/brams_init.mk
-techlibs/xilinx/brams_init_8.vh: techlibs/xilinx/brams_init.mk
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xcv.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xcv_map.v))
+
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_defs.vh))
+
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc2v.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc2v_map.v))
+
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc3sda.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc3sda_map.v))
+
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc4v.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc4v_map.v))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc5v_map.v))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xc6v_map.v))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_xcu_map.v))
+
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/urams.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/urams_map.v))
-$(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))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_xcu_brams.txt))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_map.v))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_brams_map.v))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams.txt))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams_map.v))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut4_lutrams.txt))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut6_lutrams.txt))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v))
@@ -54,11 +46,3 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_dsp_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_dsp_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_model.v))
-
-$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_36.vh))
-$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_32.vh))
-$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_18.vh))
-$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_16.vh))
-$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_9.vh))
-$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_8.vh))
-
diff --git a/techlibs/xilinx/brams_defs.vh b/techlibs/xilinx/brams_defs.vh
new file mode 100644
index 000000000..69fe5d716
--- /dev/null
+++ b/techlibs/xilinx/brams_defs.vh
@@ -0,0 +1,561 @@
+`define PARAMS_INIT_9 \
+ .INIT_00(slice_init('h00)), \
+ .INIT_01(slice_init('h01)), \
+ .INIT_02(slice_init('h02)), \
+ .INIT_03(slice_init('h03)), \
+ .INIT_04(slice_init('h04)), \
+ .INIT_05(slice_init('h05)), \
+ .INIT_06(slice_init('h06)), \
+ .INIT_07(slice_init('h07)), \
+ .INIT_08(slice_init('h08)), \
+ .INIT_09(slice_init('h09)), \
+ .INIT_0A(slice_init('h0a)), \
+ .INIT_0B(slice_init('h0b)), \
+ .INIT_0C(slice_init('h0c)), \
+ .INIT_0D(slice_init('h0d)), \
+ .INIT_0E(slice_init('h0e)), \
+ .INIT_0F(slice_init('h0f)), \
+ .INIT_10(slice_init('h10)), \
+ .INIT_11(slice_init('h11)), \
+ .INIT_12(slice_init('h12)), \
+ .INIT_13(slice_init('h13)), \
+ .INIT_14(slice_init('h14)), \
+ .INIT_15(slice_init('h15)), \
+ .INIT_16(slice_init('h16)), \
+ .INIT_17(slice_init('h17)), \
+ .INIT_18(slice_init('h18)), \
+ .INIT_19(slice_init('h19)), \
+ .INIT_1A(slice_init('h1a)), \
+ .INIT_1B(slice_init('h1b)), \
+ .INIT_1C(slice_init('h1c)), \
+ .INIT_1D(slice_init('h1d)), \
+ .INIT_1E(slice_init('h1e)), \
+ .INIT_1F(slice_init('h1f)),
+
+`define PARAMS_INITP_9 \
+ .INITP_00(slice_initp('h00)), \
+ .INITP_01(slice_initp('h01)), \
+ .INITP_02(slice_initp('h02)), \
+ .INITP_03(slice_initp('h03)),
+
+`define PARAMS_INIT_18 \
+ .INIT_00(slice_init('h00)), \
+ .INIT_01(slice_init('h01)), \
+ .INIT_02(slice_init('h02)), \
+ .INIT_03(slice_init('h03)), \
+ .INIT_04(slice_init('h04)), \
+ .INIT_05(slice_init('h05)), \
+ .INIT_06(slice_init('h06)), \
+ .INIT_07(slice_init('h07)), \
+ .INIT_08(slice_init('h08)), \
+ .INIT_09(slice_init('h09)), \
+ .INIT_0A(slice_init('h0a)), \
+ .INIT_0B(slice_init('h0b)), \
+ .INIT_0C(slice_init('h0c)), \
+ .INIT_0D(slice_init('h0d)), \
+ .INIT_0E(slice_init('h0e)), \
+ .INIT_0F(slice_init('h0f)), \
+ .INIT_10(slice_init('h10)), \
+ .INIT_11(slice_init('h11)), \
+ .INIT_12(slice_init('h12)), \
+ .INIT_13(slice_init('h13)), \
+ .INIT_14(slice_init('h14)), \
+ .INIT_15(slice_init('h15)), \
+ .INIT_16(slice_init('h16)), \
+ .INIT_17(slice_init('h17)), \
+ .INIT_18(slice_init('h18)), \
+ .INIT_19(slice_init('h19)), \
+ .INIT_1A(slice_init('h1a)), \
+ .INIT_1B(slice_init('h1b)), \
+ .INIT_1C(slice_init('h1c)), \
+ .INIT_1D(slice_init('h1d)), \
+ .INIT_1E(slice_init('h1e)), \
+ .INIT_1F(slice_init('h1f)), \
+ .INIT_20(slice_init('h20)), \
+ .INIT_21(slice_init('h21)), \
+ .INIT_22(slice_init('h22)), \
+ .INIT_23(slice_init('h23)), \
+ .INIT_24(slice_init('h24)), \
+ .INIT_25(slice_init('h25)), \
+ .INIT_26(slice_init('h26)), \
+ .INIT_27(slice_init('h27)), \
+ .INIT_28(slice_init('h28)), \
+ .INIT_29(slice_init('h29)), \
+ .INIT_2A(slice_init('h2a)), \
+ .INIT_2B(slice_init('h2b)), \
+ .INIT_2C(slice_init('h2c)), \
+ .INIT_2D(slice_init('h2d)), \
+ .INIT_2E(slice_init('h2e)), \
+ .INIT_2F(slice_init('h2f)), \
+ .INIT_30(slice_init('h30)), \
+ .INIT_31(slice_init('h31)), \
+ .INIT_32(slice_init('h32)), \
+ .INIT_33(slice_init('h33)), \
+ .INIT_34(slice_init('h34)), \
+ .INIT_35(slice_init('h35)), \
+ .INIT_36(slice_init('h36)), \
+ .INIT_37(slice_init('h37)), \
+ .INIT_38(slice_init('h38)), \
+ .INIT_39(slice_init('h39)), \
+ .INIT_3A(slice_init('h3a)), \
+ .INIT_3B(slice_init('h3b)), \
+ .INIT_3C(slice_init('h3c)), \
+ .INIT_3D(slice_init('h3d)), \
+ .INIT_3E(slice_init('h3e)), \
+ .INIT_3F(slice_init('h3f)),
+
+`define PARAMS_INIT_18_U \
+ .INIT_00(slice_init('h40)), \
+ .INIT_01(slice_init('h41)), \
+ .INIT_02(slice_init('h42)), \
+ .INIT_03(slice_init('h43)), \
+ .INIT_04(slice_init('h44)), \
+ .INIT_05(slice_init('h45)), \
+ .INIT_06(slice_init('h46)), \
+ .INIT_07(slice_init('h47)), \
+ .INIT_08(slice_init('h48)), \
+ .INIT_09(slice_init('h49)), \
+ .INIT_0A(slice_init('h4a)), \
+ .INIT_0B(slice_init('h4b)), \
+ .INIT_0C(slice_init('h4c)), \
+ .INIT_0D(slice_init('h4d)), \
+ .INIT_0E(slice_init('h4e)), \
+ .INIT_0F(slice_init('h4f)), \
+ .INIT_10(slice_init('h50)), \
+ .INIT_11(slice_init('h51)), \
+ .INIT_12(slice_init('h52)), \
+ .INIT_13(slice_init('h53)), \
+ .INIT_14(slice_init('h54)), \
+ .INIT_15(slice_init('h55)), \
+ .INIT_16(slice_init('h56)), \
+ .INIT_17(slice_init('h57)), \
+ .INIT_18(slice_init('h58)), \
+ .INIT_19(slice_init('h59)), \
+ .INIT_1A(slice_init('h5a)), \
+ .INIT_1B(slice_init('h5b)), \
+ .INIT_1C(slice_init('h5c)), \
+ .INIT_1D(slice_init('h5d)), \
+ .INIT_1E(slice_init('h5e)), \
+ .INIT_1F(slice_init('h5f)), \
+ .INIT_20(slice_init('h60)), \
+ .INIT_21(slice_init('h61)), \
+ .INIT_22(slice_init('h62)), \
+ .INIT_23(slice_init('h63)), \
+ .INIT_24(slice_init('h64)), \
+ .INIT_25(slice_init('h65)), \
+ .INIT_26(slice_init('h66)), \
+ .INIT_27(slice_init('h67)), \
+ .INIT_28(slice_init('h68)), \
+ .INIT_29(slice_init('h69)), \
+ .INIT_2A(slice_init('h6a)), \
+ .INIT_2B(slice_init('h6b)), \
+ .INIT_2C(slice_init('h6c)), \
+ .INIT_2D(slice_init('h6d)), \
+ .INIT_2E(slice_init('h6e)), \
+ .INIT_2F(slice_init('h6f)), \
+ .INIT_30(slice_init('h70)), \
+ .INIT_31(slice_init('h71)), \
+ .INIT_32(slice_init('h72)), \
+ .INIT_33(slice_init('h73)), \
+ .INIT_34(slice_init('h74)), \
+ .INIT_35(slice_init('h75)), \
+ .INIT_36(slice_init('h76)), \
+ .INIT_37(slice_init('h77)), \
+ .INIT_38(slice_init('h78)), \
+ .INIT_39(slice_init('h79)), \
+ .INIT_3A(slice_init('h7a)), \
+ .INIT_3B(slice_init('h7b)), \
+ .INIT_3C(slice_init('h7c)), \
+ .INIT_3D(slice_init('h7d)), \
+ .INIT_3E(slice_init('h7e)), \
+ .INIT_3F(slice_init('h7f)),
+
+`define PARAMS_INITP_18 \
+ .INITP_00(slice_initp('h00)), \
+ .INITP_01(slice_initp('h01)), \
+ .INITP_02(slice_initp('h02)), \
+ .INITP_03(slice_initp('h03)), \
+ .INITP_04(slice_initp('h04)), \
+ .INITP_05(slice_initp('h05)), \
+ .INITP_06(slice_initp('h06)), \
+ .INITP_07(slice_initp('h07)),
+
+`define PARAMS_INIT_36 \
+ .INIT_00(slice_init('h00)), \
+ .INIT_01(slice_init('h01)), \
+ .INIT_02(slice_init('h02)), \
+ .INIT_03(slice_init('h03)), \
+ .INIT_04(slice_init('h04)), \
+ .INIT_05(slice_init('h05)), \
+ .INIT_06(slice_init('h06)), \
+ .INIT_07(slice_init('h07)), \
+ .INIT_08(slice_init('h08)), \
+ .INIT_09(slice_init('h09)), \
+ .INIT_0A(slice_init('h0a)), \
+ .INIT_0B(slice_init('h0b)), \
+ .INIT_0C(slice_init('h0c)), \
+ .INIT_0D(slice_init('h0d)), \
+ .INIT_0E(slice_init('h0e)), \
+ .INIT_0F(slice_init('h0f)), \
+ .INIT_10(slice_init('h10)), \
+ .INIT_11(slice_init('h11)), \
+ .INIT_12(slice_init('h12)), \
+ .INIT_13(slice_init('h13)), \
+ .INIT_14(slice_init('h14)), \
+ .INIT_15(slice_init('h15)), \
+ .INIT_16(slice_init('h16)), \
+ .INIT_17(slice_init('h17)), \
+ .INIT_18(slice_init('h18)), \
+ .INIT_19(slice_init('h19)), \
+ .INIT_1A(slice_init('h1a)), \
+ .INIT_1B(slice_init('h1b)), \
+ .INIT_1C(slice_init('h1c)), \
+ .INIT_1D(slice_init('h1d)), \
+ .INIT_1E(slice_init('h1e)), \
+ .INIT_1F(slice_init('h1f)), \
+ .INIT_20(slice_init('h20)), \
+ .INIT_21(slice_init('h21)), \
+ .INIT_22(slice_init('h22)), \
+ .INIT_23(slice_init('h23)), \
+ .INIT_24(slice_init('h24)), \
+ .INIT_25(slice_init('h25)), \
+ .INIT_26(slice_init('h26)), \
+ .INIT_27(slice_init('h27)), \
+ .INIT_28(slice_init('h28)), \
+ .INIT_29(slice_init('h29)), \
+ .INIT_2A(slice_init('h2a)), \
+ .INIT_2B(slice_init('h2b)), \
+ .INIT_2C(slice_init('h2c)), \
+ .INIT_2D(slice_init('h2d)), \
+ .INIT_2E(slice_init('h2e)), \
+ .INIT_2F(slice_init('h2f)), \
+ .INIT_30(slice_init('h30)), \
+ .INIT_31(slice_init('h31)), \
+ .INIT_32(slice_init('h32)), \
+ .INIT_33(slice_init('h33)), \
+ .INIT_34(slice_init('h34)), \
+ .INIT_35(slice_init('h35)), \
+ .INIT_36(slice_init('h36)), \
+ .INIT_37(slice_init('h37)), \
+ .INIT_38(slice_init('h38)), \
+ .INIT_39(slice_init('h39)), \
+ .INIT_3A(slice_init('h3a)), \
+ .INIT_3B(slice_init('h3b)), \
+ .INIT_3C(slice_init('h3c)), \
+ .INIT_3D(slice_init('h3d)), \
+ .INIT_3E(slice_init('h3e)), \
+ .INIT_3F(slice_init('h3f)), \
+ .INIT_40(slice_init('h40)), \
+ .INIT_41(slice_init('h41)), \
+ .INIT_42(slice_init('h42)), \
+ .INIT_43(slice_init('h43)), \
+ .INIT_44(slice_init('h44)), \
+ .INIT_45(slice_init('h45)), \
+ .INIT_46(slice_init('h46)), \
+ .INIT_47(slice_init('h47)), \
+ .INIT_48(slice_init('h48)), \
+ .INIT_49(slice_init('h49)), \
+ .INIT_4A(slice_init('h4a)), \
+ .INIT_4B(slice_init('h4b)), \
+ .INIT_4C(slice_init('h4c)), \
+ .INIT_4D(slice_init('h4d)), \
+ .INIT_4E(slice_init('h4e)), \
+ .INIT_4F(slice_init('h4f)), \
+ .INIT_50(slice_init('h50)), \
+ .INIT_51(slice_init('h51)), \
+ .INIT_52(slice_init('h52)), \
+ .INIT_53(slice_init('h53)), \
+ .INIT_54(slice_init('h54)), \
+ .INIT_55(slice_init('h55)), \
+ .INIT_56(slice_init('h56)), \
+ .INIT_57(slice_init('h57)), \
+ .INIT_58(slice_init('h58)), \
+ .INIT_59(slice_init('h59)), \
+ .INIT_5A(slice_init('h5a)), \
+ .INIT_5B(slice_init('h5b)), \
+ .INIT_5C(slice_init('h5c)), \
+ .INIT_5D(slice_init('h5d)), \
+ .INIT_5E(slice_init('h5e)), \
+ .INIT_5F(slice_init('h5f)), \
+ .INIT_60(slice_init('h60)), \
+ .INIT_61(slice_init('h61)), \
+ .INIT_62(slice_init('h62)), \
+ .INIT_63(slice_init('h63)), \
+ .INIT_64(slice_init('h64)), \
+ .INIT_65(slice_init('h65)), \
+ .INIT_66(slice_init('h66)), \
+ .INIT_67(slice_init('h67)), \
+ .INIT_68(slice_init('h68)), \
+ .INIT_69(slice_init('h69)), \
+ .INIT_6A(slice_init('h6a)), \
+ .INIT_6B(slice_init('h6b)), \
+ .INIT_6C(slice_init('h6c)), \
+ .INIT_6D(slice_init('h6d)), \
+ .INIT_6E(slice_init('h6e)), \
+ .INIT_6F(slice_init('h6f)), \
+ .INIT_70(slice_init('h70)), \
+ .INIT_71(slice_init('h71)), \
+ .INIT_72(slice_init('h72)), \
+ .INIT_73(slice_init('h73)), \
+ .INIT_74(slice_init('h74)), \
+ .INIT_75(slice_init('h75)), \
+ .INIT_76(slice_init('h76)), \
+ .INIT_77(slice_init('h77)), \
+ .INIT_78(slice_init('h78)), \
+ .INIT_79(slice_init('h79)), \
+ .INIT_7A(slice_init('h7a)), \
+ .INIT_7B(slice_init('h7b)), \
+ .INIT_7C(slice_init('h7c)), \
+ .INIT_7D(slice_init('h7d)), \
+ .INIT_7E(slice_init('h7e)), \
+ .INIT_7F(slice_init('h7f)),
+
+`define PARAMS_INIT_36_U \
+ .INIT_00(slice_init('h80)), \
+ .INIT_01(slice_init('h81)), \
+ .INIT_02(slice_init('h82)), \
+ .INIT_03(slice_init('h83)), \
+ .INIT_04(slice_init('h84)), \
+ .INIT_05(slice_init('h85)), \
+ .INIT_06(slice_init('h86)), \
+ .INIT_07(slice_init('h87)), \
+ .INIT_08(slice_init('h88)), \
+ .INIT_09(slice_init('h89)), \
+ .INIT_0A(slice_init('h8a)), \
+ .INIT_0B(slice_init('h8b)), \
+ .INIT_0C(slice_init('h8c)), \
+ .INIT_0D(slice_init('h8d)), \
+ .INIT_0E(slice_init('h8e)), \
+ .INIT_0F(slice_init('h8f)), \
+ .INIT_10(slice_init('h90)), \
+ .INIT_11(slice_init('h91)), \
+ .INIT_12(slice_init('h92)), \
+ .INIT_13(slice_init('h93)), \
+ .INIT_14(slice_init('h94)), \
+ .INIT_15(slice_init('h95)), \
+ .INIT_16(slice_init('h96)), \
+ .INIT_17(slice_init('h97)), \
+ .INIT_18(slice_init('h98)), \
+ .INIT_19(slice_init('h99)), \
+ .INIT_1A(slice_init('h9a)), \
+ .INIT_1B(slice_init('h9b)), \
+ .INIT_1C(slice_init('h9c)), \
+ .INIT_1D(slice_init('h9d)), \
+ .INIT_1E(slice_init('h9e)), \
+ .INIT_1F(slice_init('h9f)), \
+ .INIT_20(slice_init('ha0)), \
+ .INIT_21(slice_init('ha1)), \
+ .INIT_22(slice_init('ha2)), \
+ .INIT_23(slice_init('ha3)), \
+ .INIT_24(slice_init('ha4)), \
+ .INIT_25(slice_init('ha5)), \
+ .INIT_26(slice_init('ha6)), \
+ .INIT_27(slice_init('ha7)), \
+ .INIT_28(slice_init('ha8)), \
+ .INIT_29(slice_init('ha9)), \
+ .INIT_2A(slice_init('haa)), \
+ .INIT_2B(slice_init('hab)), \
+ .INIT_2C(slice_init('hac)), \
+ .INIT_2D(slice_init('had)), \
+ .INIT_2E(slice_init('hae)), \
+ .INIT_2F(slice_init('haf)), \
+ .INIT_30(slice_init('hb0)), \
+ .INIT_31(slice_init('hb1)), \
+ .INIT_32(slice_init('hb2)), \
+ .INIT_33(slice_init('hb3)), \
+ .INIT_34(slice_init('hb4)), \
+ .INIT_35(slice_init('hb5)), \
+ .INIT_36(slice_init('hb6)), \
+ .INIT_37(slice_init('hb7)), \
+ .INIT_38(slice_init('hb8)), \
+ .INIT_39(slice_init('hb9)), \
+ .INIT_3A(slice_init('hba)), \
+ .INIT_3B(slice_init('hbb)), \
+ .INIT_3C(slice_init('hbc)), \
+ .INIT_3D(slice_init('hbd)), \
+ .INIT_3E(slice_init('hbe)), \
+ .INIT_3F(slice_init('hbf)), \
+ .INIT_40(slice_init('hc0)), \
+ .INIT_41(slice_init('hc1)), \
+ .INIT_42(slice_init('hc2)), \
+ .INIT_43(slice_init('hc3)), \
+ .INIT_44(slice_init('hc4)), \
+ .INIT_45(slice_init('hc5)), \
+ .INIT_46(slice_init('hc6)), \
+ .INIT_47(slice_init('hc7)), \
+ .INIT_48(slice_init('hc8)), \
+ .INIT_49(slice_init('hc9)), \
+ .INIT_4A(slice_init('hca)), \
+ .INIT_4B(slice_init('hcb)), \
+ .INIT_4C(slice_init('hcc)), \
+ .INIT_4D(slice_init('hcd)), \
+ .INIT_4E(slice_init('hce)), \
+ .INIT_4F(slice_init('hcf)), \
+ .INIT_50(slice_init('hd0)), \
+ .INIT_51(slice_init('hd1)), \
+ .INIT_52(slice_init('hd2)), \
+ .INIT_53(slice_init('hd3)), \
+ .INIT_54(slice_init('hd4)), \
+ .INIT_55(slice_init('hd5)), \
+ .INIT_56(slice_init('hd6)), \
+ .INIT_57(slice_init('hd7)), \
+ .INIT_58(slice_init('hd8)), \
+ .INIT_59(slice_init('hd9)), \
+ .INIT_5A(slice_init('hda)), \
+ .INIT_5B(slice_init('hdb)), \
+ .INIT_5C(slice_init('hdc)), \
+ .INIT_5D(slice_init('hdd)), \
+ .INIT_5E(slice_init('hde)), \
+ .INIT_5F(slice_init('hdf)), \
+ .INIT_60(slice_init('he0)), \
+ .INIT_61(slice_init('he1)), \
+ .INIT_62(slice_init('he2)), \
+ .INIT_63(slice_init('he3)), \
+ .INIT_64(slice_init('he4)), \
+ .INIT_65(slice_init('he5)), \
+ .INIT_66(slice_init('he6)), \
+ .INIT_67(slice_init('he7)), \
+ .INIT_68(slice_init('he8)), \
+ .INIT_69(slice_init('he9)), \
+ .INIT_6A(slice_init('hea)), \
+ .INIT_6B(slice_init('heb)), \
+ .INIT_6C(slice_init('hec)), \
+ .INIT_6D(slice_init('hed)), \
+ .INIT_6E(slice_init('hee)), \
+ .INIT_6F(slice_init('hef)), \
+ .INIT_70(slice_init('hf0)), \
+ .INIT_71(slice_init('hf1)), \
+ .INIT_72(slice_init('hf2)), \
+ .INIT_73(slice_init('hf3)), \
+ .INIT_74(slice_init('hf4)), \
+ .INIT_75(slice_init('hf5)), \
+ .INIT_76(slice_init('hf6)), \
+ .INIT_77(slice_init('hf7)), \
+ .INIT_78(slice_init('hf8)), \
+ .INIT_79(slice_init('hf9)), \
+ .INIT_7A(slice_init('hfa)), \
+ .INIT_7B(slice_init('hfb)), \
+ .INIT_7C(slice_init('hfc)), \
+ .INIT_7D(slice_init('hfd)), \
+ .INIT_7E(slice_init('hfe)), \
+ .INIT_7F(slice_init('hff)),
+
+`define PARAMS_INITP_36 \
+ .INITP_00(slice_initp('h00)), \
+ .INITP_01(slice_initp('h01)), \
+ .INITP_02(slice_initp('h02)), \
+ .INITP_03(slice_initp('h03)), \
+ .INITP_04(slice_initp('h04)), \
+ .INITP_05(slice_initp('h05)), \
+ .INITP_06(slice_initp('h06)), \
+ .INITP_07(slice_initp('h07)), \
+ .INITP_08(slice_initp('h08)), \
+ .INITP_09(slice_initp('h09)), \
+ .INITP_0A(slice_initp('h0a)), \
+ .INITP_0B(slice_initp('h0b)), \
+ .INITP_0C(slice_initp('h0c)), \
+ .INITP_0D(slice_initp('h0d)), \
+ .INITP_0E(slice_initp('h0e)), \
+ .INITP_0F(slice_initp('h0f)),
+
+`define MAKE_DO(do, dop, rdata) \
+ wire [63:0] do; \
+ wire [7:0] dop; \
+ assign rdata = { \
+ dop[7], \
+ do[63:56], \
+ dop[6], \
+ do[55:48], \
+ dop[5], \
+ do[47:40], \
+ dop[4], \
+ do[39:32], \
+ dop[3], \
+ do[31:24], \
+ dop[2], \
+ do[23:16], \
+ dop[1], \
+ do[15:8], \
+ dop[0], \
+ do[7:0] \
+ };
+
+`define MAKE_DI(di, dip, wdata) \
+ wire [63:0] di; \
+ wire [7:0] dip; \
+ assign { \
+ dip[7], \
+ di[63:56], \
+ dip[6], \
+ di[55:48], \
+ dip[5], \
+ di[47:40], \
+ dip[4], \
+ di[39:32], \
+ dip[3], \
+ di[31:24], \
+ dip[2], \
+ di[23:16], \
+ dip[1], \
+ di[15:8], \
+ dip[0], \
+ di[7:0] \
+ } = wdata;
+
+function [71:0] ival;
+ input integer width;
+ input [71:0] val;
+ if (width == 72)
+ ival = {
+ val[71],
+ val[62],
+ val[53],
+ val[44],
+ val[35],
+ val[26],
+ val[17],
+ val[8],
+ val[70:63],
+ val[61:54],
+ val[52:45],
+ val[43:36],
+ val[34:27],
+ val[25:18],
+ val[16:9],
+ val[7:0]
+ };
+ else if (width == 36)
+ ival = {
+ val[35],
+ val[26],
+ val[17],
+ val[8],
+ val[34:27],
+ val[25:18],
+ val[16:9],
+ val[7:0]
+ };
+ else if (width == 18)
+ ival = {
+ val[17],
+ val[8],
+ val[16:9],
+ val[7:0]
+ };
+ else
+ ival = val;
+endfunction
+
+function [255:0] slice_init;
+ input integer idx;
+ integer i;
+ for (i = 0; i < 32; i = i + 1)
+ slice_init[i*8+:8] = INIT[(idx * 32 + i)*9+:8];
+endfunction
+
+function [255:0] slice_initp;
+ input integer idx;
+ integer i;
+ for (i = 0; i < 256; i = i + 1)
+ slice_initp[i] = INIT[(idx * 256 + i)*9+8];
+endfunction
diff --git a/techlibs/xilinx/brams_init.py b/techlibs/xilinx/brams_init.py
deleted file mode 100644
index 10057a0cb..000000000
--- a/techlibs/xilinx/brams_init.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python3
-
-with open("techlibs/xilinx/brams_init_9.vh", "w") as f:
- for i in range(4):
- init_snippets = [" INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)]
- for k in range(4, 256, 4):
- init_snippets[k] = "\n " + init_snippets[k]
- print(".INITP_%02X({%s})," % (i, ",".join(init_snippets)), file=f)
- for i in range(32):
- init_snippets = [" INIT[%3d*9 +: 8]" % (k+32*i,) for k in range(31, -1, -1)]
- for k in range(4, 32, 4):
- init_snippets[k] = "\n " + init_snippets[k]
- print(".INIT_%02X({%s})," % (i, ",".join(init_snippets)), file=f)
-
-with open("techlibs/xilinx/brams_init_18.vh", "w") as f:
- for i in range(8):
- init_snippets = [" INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)]
- for k in range(4, 256, 4):
- init_snippets[k] = "\n " + init_snippets[k]
- print(".INITP_%02X({%s})," % (i, ",".join(init_snippets)), file=f)
- for i in range(64):
- init_snippets = [" INIT[%3d*9 +: 8]" % (k+32*i,) for k in range(31, -1, -1)]
- for k in range(4, 32, 4):
- init_snippets[k] = "\n " + init_snippets[k]
- print(".INIT_%02X({%s})," % (i, ",".join(init_snippets)), file=f)
-
-with open("techlibs/xilinx/brams_init_36.vh", "w") as f:
- for i in range(16):
- init_snippets = [" INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)]
- for k in range(4, 256, 4):
- init_snippets[k] = "\n " + init_snippets[k]
- print(".INITP_%02X({%s})," % (i, ",".join(init_snippets)), file=f)
- for i in range(128):
- init_snippets = [" INIT[%3d*9 +: 8]" % (k+32*i,) for k in range(31, -1, -1)]
- for k in range(4, 32, 4):
- init_snippets[k] = "\n " + init_snippets[k]
- print(".INIT_%02X({%s})," % (i, ",".join(init_snippets)), file=f)
-
-with open("techlibs/xilinx/brams_init_8.vh", "w") as f:
- for i in range(32):
- print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f)
-
-with open("techlibs/xilinx/brams_init_16.vh", "w") as f:
- for i in range(64):
- print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f)
-
-with open("techlibs/xilinx/brams_init_32.vh", "w") as f:
- for i in range(128):
- print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f)
-
diff --git a/techlibs/xilinx/brams_xc2v.txt b/techlibs/xilinx/brams_xc2v.txt
new file mode 100644
index 000000000..562148c21
--- /dev/null
+++ b/techlibs/xilinx/brams_xc2v.txt
@@ -0,0 +1,33 @@
+# Block RAMs for Virtex 2, Spartan 3, Spartan 3E, Spartan 3A(N)
+# The corresponding mapping file is brams_xc2v_map.v
+
+ram block $__XILINX_BLOCKRAM_ {
+ abits 14;
+ widths 1 2 4 9 18 36 per_port;
+ ifdef HAS_BE {
+ option "USE_BE" 1 byte 9;
+ }
+ cost 129;
+ init any;
+ port srsw "A" "B" {
+ option "USE_BE" 0 width tied;
+ ifdef HAS_BE {
+ option "USE_BE" 1 width tied 9 18 36;
+ }
+ clock posedge;
+ clken;
+ rdsrst any gated_clken;
+ rdinit any;
+ portoption "WRITE_MODE" "NO_CHANGE" {
+ rdwr no_change;
+ }
+ portoption "WRITE_MODE" "WRITE_FIRST" {
+ rdwr new_only;
+ }
+ portoption "WRITE_MODE" "READ_FIRST" {
+ rdwr old;
+ wrtrans all old;
+ }
+ optional;
+ }
+}
diff --git a/techlibs/xilinx/brams_xc2v_map.v b/techlibs/xilinx/brams_xc2v_map.v
new file mode 100644
index 000000000..a82feff60
--- /dev/null
+++ b/techlibs/xilinx/brams_xc2v_map.v
@@ -0,0 +1,532 @@
+module $__XILINX_BLOCKRAM_ (...);
+
+parameter INIT = 0;
+parameter OPTION_USE_BE = 0;
+
+parameter PORT_A_WIDTH = 1;
+parameter PORT_A_WR_EN_WIDTH = 1;
+parameter PORT_A_USED = 1;
+parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_A_RD_INIT_VALUE = 0;
+parameter PORT_A_RD_SRST_VALUE = 0;
+
+parameter PORT_B_WIDTH = 1;
+parameter PORT_B_WR_EN_WIDTH = 1;
+parameter PORT_B_USED = 0;
+parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_B_RD_INIT_VALUE = 0;
+parameter PORT_B_RD_SRST_VALUE = 0;
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input [13:0] PORT_A_ADDR;
+input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
+input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
+output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
+input PORT_A_RD_SRST;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input [13:0] PORT_B_ADDR;
+input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
+input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN;
+output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
+input PORT_B_RD_SRST;
+
+`include "brams_defs.vh"
+
+`define PARAMS_DP \
+ `PARAMS_INIT_18 \
+ .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \
+ .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \
+ .SRVAL_A(SRVAL_A), \
+ .SRVAL_B(SRVAL_B), \
+ .INIT_A(INIT_A), \
+ .INIT_B(INIT_B),
+
+`define PARAMS_DP_SWAP \
+ `PARAMS_INIT_18 \
+ .WRITE_MODE_A(PORT_B_OPTION_WRITE_MODE), \
+ .WRITE_MODE_B(PORT_A_OPTION_WRITE_MODE), \
+ .SRVAL_A(SRVAL_B), \
+ .SRVAL_B(SRVAL_A), \
+ .INIT_A(INIT_B), \
+ .INIT_B(INIT_A),
+
+`define PARAMS_SP \
+ `PARAMS_INIT_18 \
+ .WRITE_MODE(PORT_A_OPTION_WRITE_MODE), \
+ .SRVAL(SRVAL_A), \
+ .INIT(INIT_A),
+
+`define PORTS_DP(addr_slice_a, addr_slice_b) \
+ .CLKA(PORT_A_CLK), \
+ .ENA(PORT_A_CLK_EN), \
+ .WEA(PORT_A_WR_EN), \
+ .SSRA(PORT_A_RD_SRST), \
+ .ADDRA(PORT_A_ADDR addr_slice_a), \
+ .DOA(DO_A), \
+ .DIA(DI_A), \
+ .CLKB(PORT_B_CLK), \
+ .ENB(PORT_B_CLK_EN), \
+ .WEB(PORT_B_WR_EN), \
+ .SSRB(PORT_B_RD_SRST), \
+ .ADDRB(PORT_B_ADDR addr_slice_b), \
+ .DOB(DO_B), \
+ .DIB(DI_B),
+
+`define PORTS_DP_SWAP(addr_slice_a, addr_slice_b) \
+ .CLKB(PORT_A_CLK), \
+ .ENB(PORT_A_CLK_EN), \
+ .WEB(PORT_A_WR_EN), \
+ .SSRB(PORT_A_RD_SRST), \
+ .ADDRB(PORT_A_ADDR addr_slice_a), \
+ .DOB(DO_A), \
+ .DIB(DI_A), \
+ .CLKA(PORT_B_CLK), \
+ .ENA(PORT_B_CLK_EN), \
+ .WEA(PORT_B_WR_EN), \
+ .SSRA(PORT_B_RD_SRST), \
+ .ADDRA(PORT_B_ADDR addr_slice_b), \
+ .DOA(DO_B), \
+ .DIA(DI_B),
+
+`define PORTS_SP(addr_slice) \
+ .CLK(PORT_A_CLK), \
+ .EN(PORT_A_CLK_EN), \
+ .WE(PORT_A_WR_EN), \
+ .SSR(PORT_A_RD_SRST), \
+ .ADDR(PORT_A_ADDR addr_slice), \
+ .DO(DO_A), \
+ .DI(DI_A),
+
+localparam [PORT_A_WIDTH-1:0] SRVAL_A = ival(PORT_A_WIDTH, PORT_A_RD_SRST_VALUE);
+localparam [PORT_B_WIDTH-1:0] SRVAL_B = ival(PORT_B_WIDTH, PORT_B_RD_SRST_VALUE);
+localparam [PORT_A_WIDTH-1:0] INIT_A = ival(PORT_A_WIDTH, PORT_A_RD_INIT_VALUE);
+localparam [PORT_B_WIDTH-1:0] INIT_B = ival(PORT_B_WIDTH, PORT_B_RD_INIT_VALUE);
+
+`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA)
+`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA)
+`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA)
+`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA)
+
+generate
+
+if (OPTION_USE_BE) begin
+ if (!PORT_B_USED) begin
+ case (PORT_A_WIDTH)
+ 9: RAMB16_S9 #(
+ `PARAMS_SP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([13:3])
+ .DIP(DIP_A),
+ .DOP(DOP_A),
+ );
+ 18: RAMB16BWE_S18 #(
+ `PARAMS_SP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([13:4])
+ .DIP(DIP_A),
+ .DOP(DOP_A),
+ );
+ 36: RAMB16BWE_S36 #(
+ `PARAMS_SP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([13:5])
+ .DIP(DIP_A),
+ .DOP(DOP_A),
+ );
+ endcase
+ end else begin
+ case (PORT_A_WIDTH)
+ 9: case(PORT_B_WIDTH)
+ 9: RAMB16_S9_S9 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:3], [13:3])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 18: RAMB16BWE_S9_S18 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:3], [13:4])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 36: RAMB16BWE_S9_S36 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:3], [13:5])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ endcase
+ 18: case(PORT_B_WIDTH)
+ 9: RAMB16BWE_S9_S18 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:4], [13:3])
+ .DIPA(DIP_B), .DOPA(DOP_B),
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 18: RAMB16BWE_S18_S18 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:4], [13:4])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 36: RAMB16BWE_S18_S36 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:4], [13:5])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ endcase
+ 36: case(PORT_B_WIDTH)
+ 9: RAMB16BWE_S9_S36 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:5], [13:3])
+ .DIPA(DIP_B), .DOPA(DOP_B),
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 18: RAMB16BWE_S18_S36 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:5], [13:4])
+ .DIPA(DIP_B), .DOPA(DOP_B),
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 36: RAMB16BWE_S36_S36 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:5], [13:5])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ endcase
+ endcase
+ end
+end else begin
+ if (!PORT_B_USED) begin
+ case (PORT_A_WIDTH)
+ 1: RAMB16_S1 #(
+ `PARAMS_SP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([13:0])
+ );
+ 2: RAMB16_S2 #(
+ `PARAMS_SP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([13:1])
+ );
+ 4: RAMB16_S4 #(
+ `PARAMS_SP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([13:2])
+ );
+ 9: RAMB16_S9 #(
+ `PARAMS_SP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([13:3])
+ .DIP(DIP_A),
+ .DOP(DOP_A),
+ );
+ 18: RAMB16_S18 #(
+ `PARAMS_SP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([13:4])
+ .DIP(DIP_A),
+ .DOP(DOP_A),
+ );
+ 36: RAMB16_S36 #(
+ `PARAMS_SP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([13:5])
+ .DIP(DIP_A),
+ .DOP(DOP_A),
+ );
+ endcase
+ end else begin
+ case (PORT_A_WIDTH)
+ 1: case(PORT_B_WIDTH)
+ 1: RAMB16_S1_S1 #(
+ `PARAMS_DP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:0], [13:0])
+ );
+ 2: RAMB16_S1_S2 #(
+ `PARAMS_DP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:0], [13:1])
+ );
+ 4: RAMB16_S1_S4 #(
+ `PARAMS_DP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:0], [13:2])
+ );
+ 9: RAMB16_S1_S9 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:0], [13:3])
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 18: RAMB16_S1_S18 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:0], [13:4])
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 36: RAMB16_S1_S36 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:0], [13:5])
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ endcase
+ 2: case(PORT_B_WIDTH)
+ 1: RAMB16_S1_S2 #(
+ `PARAMS_DP_SWAP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:1], [13:0])
+ );
+ 2: RAMB16_S2_S2 #(
+ `PARAMS_DP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:1], [13:1])
+ );
+ 4: RAMB16_S2_S4 #(
+ `PARAMS_DP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:1], [13:2])
+ );
+ 9: RAMB16_S2_S9 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:1], [13:3])
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 18: RAMB16_S2_S18 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:1], [13:4])
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 36: RAMB16_S2_S36 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:1], [13:5])
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ endcase
+ 4: case(PORT_B_WIDTH)
+ 1: RAMB16_S1_S4 #(
+ `PARAMS_DP_SWAP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:2], [13:0])
+ );
+ 2: RAMB16_S2_S4 #(
+ `PARAMS_DP_SWAP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:2], [13:1])
+ );
+ 4: RAMB16_S4_S4 #(
+ `PARAMS_DP
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:2], [13:2])
+ );
+ 9: RAMB16_S4_S9 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:2], [13:3])
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 18: RAMB16_S4_S18 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:2], [13:4])
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 36: RAMB16_S4_S36 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:2], [13:5])
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ endcase
+ 9: case(PORT_B_WIDTH)
+ 1: RAMB16_S1_S9 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:3], [13:0])
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 2: RAMB16_S2_S9 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:3], [13:1])
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 4: RAMB16_S4_S9 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:3], [13:2])
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 9: RAMB16_S9_S9 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:3], [13:3])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 18: RAMB16_S9_S18 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:3], [13:4])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 36: RAMB16_S9_S36 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:3], [13:5])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ endcase
+ 18: case(PORT_B_WIDTH)
+ 1: RAMB16_S1_S18 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:4], [13:0])
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 2: RAMB16_S2_S18 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:4], [13:1])
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 4: RAMB16_S4_S18 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:4], [13:2])
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 9: RAMB16_S9_S18 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:4], [13:3])
+ .DIPA(DIP_B), .DOPA(DOP_B),
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 18: RAMB16_S18_S18 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:4], [13:4])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ 36: RAMB16_S18_S36 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:4], [13:5])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ endcase
+ 36: case(PORT_B_WIDTH)
+ 1: RAMB16_S1_S36 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:5], [13:0])
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 2: RAMB16_S2_S36 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:5], [13:1])
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 4: RAMB16_S4_S36 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:5], [13:2])
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 9: RAMB16_S9_S36 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:5], [13:3])
+ .DIPA(DIP_B), .DOPA(DOP_B),
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 18: RAMB16_S18_S36 #(
+ `PARAMS_DP_SWAP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([13:5], [13:4])
+ .DIPA(DIP_B), .DOPA(DOP_B),
+ .DIPB(DIP_A), .DOPB(DOP_A),
+ );
+ 36: RAMB16_S36_S36 #(
+ `PARAMS_DP
+ `PARAMS_INITP_18
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([13:5], [13:5])
+ .DIPA(DIP_A), .DOPA(DOP_A),
+ .DIPB(DIP_B), .DOPB(DOP_B),
+ );
+ endcase
+ endcase
+ end
+end
+
+endgenerate
+
+
+endmodule
diff --git a/techlibs/xilinx/brams_xc3sda.txt b/techlibs/xilinx/brams_xc3sda.txt
new file mode 100644
index 000000000..451999150
--- /dev/null
+++ b/techlibs/xilinx/brams_xc3sda.txt
@@ -0,0 +1,120 @@
+# Block RAMs for Spartan 3A DSP and Spartan 6.
+# The corresponding mapping file is brams_xc3sda_map.v
+
+ram block $__XILINX_BLOCKRAM_TDP_ {
+ byte 9;
+ ifdef IS_SPARTAN6 {
+ option "MODE" "HALF" {
+ abits 13;
+ widths 1 2 4 9 18 per_port;
+ cost 65;
+ }
+ }
+ option "MODE" "FULL" {
+ abits 14;
+ widths 1 2 4 9 18 36 per_port;
+ cost 129;
+ }
+ init any;
+ port srsw "A" "B" {
+ # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks.
+ ifdef IS_SPARTAN6 {
+ option "HAS_RDFIRST" 1 {
+ clock posedge "C";
+ }
+ option "HAS_RDFIRST" 0 {
+ clock posedge;
+ }
+ } else {
+ clock posedge;
+ }
+ clken;
+ option "RSTTYPE" "SYNC" {
+ portoption "RST_PRIORITY" "CE" {
+ rdsrst any gated_clken;
+ }
+ ifdef IS_SPARTAN6 {
+ portoption "RST_PRIORITY" "SR" {
+ rdsrst any ungated;
+ }
+ }
+ }
+ ifdef IS_SPARTAN6 {
+ option "RSTTYPE" "ASYNC" {
+ portoption "RST_PRIORITY" "SR" {
+ rdarst any;
+ }
+ }
+ }
+ rdinit any;
+ portoption "WRITE_MODE" "NO_CHANGE" {
+ rdwr no_change;
+ }
+ portoption "WRITE_MODE" "WRITE_FIRST" {
+ rdwr new;
+ }
+ ifdef IS_SPARTAN6 {
+ option "HAS_RDFIRST" 1 {
+ portoption "WRITE_MODE" "READ_FIRST" {
+ rdwr old;
+ wrtrans all old;
+ }
+ }
+ } else {
+ portoption "WRITE_MODE" "READ_FIRST" {
+ rdwr old;
+ wrtrans all old;
+ }
+ }
+ optional;
+ }
+}
+
+ifdef IS_SPARTAN6 {
+ ram block $__XILINX_BLOCKRAM_SDP_ {
+ byte 9;
+ abits 13;
+ widths 1 2 4 9 18 36 per_port;
+ cost 65;
+ init any;
+ port sw "W" {
+ width 36;
+ # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks.
+ option "WRITE_MODE" "READ_FIRST" {
+ clock posedge "C";
+ wrtrans all old;
+ }
+ option "WRITE_MODE" "WRITE_FIRST" {
+ clock posedge;
+ }
+ clken;
+ optional;
+ }
+ port sr "R" {
+ width 36;
+ # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks.
+ option "WRITE_MODE" "READ_FIRST" {
+ clock posedge "C";
+ }
+ option "WRITE_MODE" "WRITE_FIRST" {
+ clock posedge;
+ }
+ clken;
+ option "RSTTYPE" "SYNC" {
+ portoption "RST_PRIORITY" "CE" {
+ rdsrst any gated_clken;
+ }
+ portoption "RST_PRIORITY" "SR" {
+ rdsrst any ungated;
+ }
+ }
+ option "RSTTYPE" "ASYNC" {
+ portoption "RST_PRIORITY" "SR" {
+ rdarst any;
+ }
+ }
+ rdinit any;
+ optional;
+ }
+ }
+}
diff --git a/techlibs/xilinx/brams_xc3sda_map.v b/techlibs/xilinx/brams_xc3sda_map.v
new file mode 100644
index 000000000..f5f0e5aa1
--- /dev/null
+++ b/techlibs/xilinx/brams_xc3sda_map.v
@@ -0,0 +1,224 @@
+module $__XILINX_BLOCKRAM_TDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_MODE = "FULL";
+parameter OPTION_RSTTYPE = "SYNC";
+parameter OPTION_HAS_RDFIRST = 0;
+
+parameter PORT_A_WIDTH = 1;
+parameter PORT_A_WR_EN_WIDTH = 1;
+parameter PORT_A_USED = 1;
+parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_A_RD_INIT_VALUE = 0;
+parameter PORT_A_RD_SRST_VALUE = 0;
+parameter PORT_A_RD_ARST_VALUE = 0;
+parameter PORT_A_OPTION_RST_PRIORITY = "CE";
+
+parameter PORT_B_WIDTH = 1;
+parameter PORT_B_WR_EN_WIDTH = 1;
+parameter PORT_B_USED = 0;
+parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_B_RD_INIT_VALUE = 0;
+parameter PORT_B_RD_SRST_VALUE = 0;
+parameter PORT_B_RD_ARST_VALUE = 0;
+parameter PORT_B_OPTION_RST_PRIORITY = "CE";
+
+input CLK_C;
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input [13:0] PORT_A_ADDR;
+input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
+input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
+output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
+input PORT_A_RD_SRST;
+input PORT_A_RD_ARST;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input [13:0] PORT_B_ADDR;
+input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
+input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN;
+output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
+input PORT_B_RD_SRST;
+input PORT_B_RD_ARST;
+
+`include "brams_defs.vh"
+
+`define PARAMS_COMMON \
+ .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \
+ .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \
+ .DATA_WIDTH_A(PORT_A_USED ? PORT_A_WIDTH : 0), \
+ .DATA_WIDTH_B(PORT_B_USED ? PORT_B_WIDTH : 0), \
+ .EN_RSTRAM_A("TRUE"), \
+ .EN_RSTRAM_B("TRUE"), \
+ .DOA_REG(0), \
+ .DOB_REG(0), \
+ .RST_PRIORITY_A(PORT_A_OPTION_RST_PRIORITY), \
+ .RST_PRIORITY_B(PORT_B_OPTION_RST_PRIORITY), \
+ .RSTTYPE(OPTION_RSTTYPE), \
+ .INIT_A(ival(PORT_A_WIDTH, PORT_A_RD_INIT_VALUE)), \
+ .INIT_B(ival(PORT_B_WIDTH, PORT_B_RD_INIT_VALUE)), \
+ .SRVAL_A(ival(PORT_A_WIDTH, OPTION_RSTTYPE == "SYNC" ? PORT_A_RD_SRST_VALUE : PORT_A_RD_ARST_VALUE)), \
+ .SRVAL_B(ival(PORT_B_WIDTH, OPTION_RSTTYPE == "SYNC" ? PORT_B_RD_SRST_VALUE : PORT_B_RD_ARST_VALUE)),
+
+wire RST_A = OPTION_RSTTYPE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST;
+wire RST_B = OPTION_RSTTYPE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST;
+
+`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA)
+`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA)
+`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA)
+`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA)
+
+generate
+
+if (OPTION_MODE == "FULL") begin
+ wire [3:0] WE_A = {4{PORT_A_WR_EN}};
+ wire [3:0] WE_B = {4{PORT_B_WR_EN}};
+ RAMB16BWER #(
+ `PARAMS_INIT_18
+ `PARAMS_INITP_18
+ `PARAMS_COMMON
+ ) _TECHMAP_REPLACE_ (
+ .DOA(DO_A),
+ .DOPA(DOP_A),
+ .DIA(DI_A),
+ .DIPA(DIP_A),
+ .DOB(DO_B),
+ .DOPB(DOP_B),
+ .DIB(DI_B),
+ .DIPB(DIP_B),
+ .ADDRA(PORT_A_ADDR),
+ .ADDRB(PORT_B_ADDR),
+ .CLKA(PORT_A_CLK),
+ .CLKB(PORT_B_CLK),
+ .ENA(PORT_A_CLK_EN),
+ .ENB(PORT_B_CLK_EN),
+ .REGCEA(1'b0),
+ .REGCEB(1'b0),
+ .RSTA(RST_A),
+ .RSTB(RST_B),
+ .WEA(WE_A),
+ .WEB(WE_B),
+ );
+end else begin
+ wire [1:0] WE_A = {2{PORT_A_WR_EN}};
+ wire [1:0] WE_B = {2{PORT_B_WR_EN}};
+ RAMB8BWER #(
+ `PARAMS_INIT_9
+ `PARAMS_INITP_9
+ `PARAMS_COMMON
+ .RAM_MODE("TDP"),
+ ) _TECHMAP_REPLACE_ (
+ .DOADO(DO_A),
+ .DOPADOP(DOP_A),
+ .DIADI(DI_A),
+ .DIPADIP(DIP_A),
+ .DOBDO(DO_B),
+ .DOPBDOP(DOP_B),
+ .DIBDI(DI_B),
+ .DIPBDIP(DIP_B),
+ .ADDRAWRADDR(PORT_A_ADDR),
+ .ADDRBRDADDR(PORT_B_ADDR),
+ .CLKAWRCLK(PORT_A_CLK),
+ .CLKBRDCLK(PORT_B_CLK),
+ .ENAWREN(PORT_A_CLK_EN),
+ .ENBRDEN(PORT_B_CLK_EN),
+ .REGCEA(1'b0),
+ .REGCEBREGCE(1'b0),
+ .RSTA(RST_A),
+ .RSTBRST(RST_B),
+ .WEAWEL(WE_A),
+ .WEBWEU(WE_B),
+ );
+end
+
+endgenerate
+
+endmodule
+
+
+module $__XILINX_BLOCKRAM_SDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_RSTTYPE = "SYNC";
+parameter OPTION_WRITE_MODE = "READ_FIRST";
+
+parameter PORT_W_WIDTH = 1;
+parameter PORT_W_WR_EN_WIDTH = 1;
+parameter PORT_W_USED = 1;
+
+parameter PORT_R_WIDTH = 1;
+parameter PORT_R_USED = 0;
+parameter PORT_R_RD_INIT_VALUE = 0;
+parameter PORT_R_RD_SRST_VALUE = 0;
+parameter PORT_R_RD_ARST_VALUE = 0;
+parameter PORT_R_OPTION_RST_PRIORITY = "CE";
+
+input CLK_C;
+
+input PORT_W_CLK;
+input PORT_W_CLK_EN;
+input [13:0] PORT_W_ADDR;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN;
+
+input PORT_R_CLK;
+input PORT_R_CLK_EN;
+input [13:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+input PORT_R_RD_SRST;
+input PORT_R_RD_ARST;
+
+`include "brams_defs.vh"
+
+wire RST = OPTION_RSTTYPE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST;
+
+`MAKE_DI(DI, DIP, PORT_W_WR_DATA)
+`MAKE_DO(DO, DOP, PORT_R_RD_DATA)
+
+localparam [35:0] RST_VALUE = OPTION_RSTTYPE == "SYNC" ? PORT_R_RD_SRST_VALUE : PORT_R_RD_ARST_VALUE;
+
+RAMB8BWER #(
+ `PARAMS_INIT_9
+ `PARAMS_INITP_9
+ .WRITE_MODE_A(OPTION_WRITE_MODE),
+ .WRITE_MODE_B(OPTION_WRITE_MODE),
+ .DATA_WIDTH_A(PORT_W_USED ? PORT_W_WIDTH : 0),
+ .DATA_WIDTH_B(PORT_R_USED ? PORT_R_WIDTH : 0),
+ .EN_RSTRAM_A("TRUE"),
+ .EN_RSTRAM_B("TRUE"),
+ .DOA_REG(0),
+ .DOB_REG(0),
+ .RST_PRIORITY_A("CE"),
+ .RST_PRIORITY_B(PORT_R_OPTION_RST_PRIORITY),
+ .RSTTYPE(OPTION_RSTTYPE),
+ .INIT_A(ival(18, PORT_R_RD_INIT_VALUE[17:0])),
+ .INIT_B(ival(18, PORT_R_RD_INIT_VALUE[35:18])),
+ .SRVAL_A(ival(18, RST_VALUE[17:0])),
+ .SRVAL_B(ival(18, RST_VALUE[35:18])),
+ .RAM_MODE("SDP"),
+) _TECHMAP_REPLACE_ (
+ .DOADO(DO[15:0]),
+ .DOPADOP(DOP[1:0]),
+ .DIADI(DI[15:0]),
+ .DIPADIP(DIP[1:0]),
+ .DOBDO(DO[31:16]),
+ .DOPBDOP(DOP[3:2]),
+ .DIBDI(DI[31:16]),
+ .DIPBDIP(DIP[3:2]),
+ .ADDRAWRADDR(PORT_W_ADDR),
+ .ADDRBRDADDR(PORT_R_ADDR),
+ .CLKAWRCLK(PORT_W_CLK),
+ .CLKBRDCLK(PORT_R_CLK),
+ .ENAWREN(PORT_W_CLK_EN),
+ .ENBRDEN(PORT_R_CLK_EN),
+ .REGCEA(1'b0),
+ .REGCEBREGCE(1'b0),
+ .RSTA(1'b0),
+ .RSTBRST(RST),
+ .WEAWEL(PORT_W_WR_EN[1:0]),
+ .WEBWEU(PORT_W_WR_EN[3:2]),
+);
+
+endmodule
diff --git a/techlibs/xilinx/brams_xc4v.txt b/techlibs/xilinx/brams_xc4v.txt
new file mode 100644
index 000000000..2301835ea
--- /dev/null
+++ b/techlibs/xilinx/brams_xc4v.txt
@@ -0,0 +1,169 @@
+# Block RAMs for Virtex 4+.
+# The corresponding mapping files are:
+# - brams_xc3sda_map.v: Spartan 3A DSP, Spartan 6
+# - brams_xc4v_map.v: Virtex 4
+# - brams_xc5v_map.v: Virtex 5
+# - brams_xc6v_map.v: Virtex 6, Series 7
+# - brams_xcu_map.v: Ultrascale
+
+ram block $__XILINX_BLOCKRAM_TDP_ {
+ byte 9;
+ ifdef HAS_SIZE_36 {
+ option "MODE" "HALF" {
+ abits 14;
+ widths 1 2 4 9 18 per_port;
+ cost 129;
+ }
+ option "MODE" "FULL" {
+ abits 15;
+ widths 1 2 4 9 18 36 per_port;
+ cost 257;
+ }
+ ifdef HAS_CASCADE {
+ option "MODE" "CASCADE" {
+ abits 16;
+ # hack to enforce same INIT layout as in the other modes
+ widths 1 2 4 9 per_port;
+ cost 513;
+ }
+ }
+ } else {
+ option "MODE" "FULL" {
+ abits 14;
+ widths 1 2 4 9 18 36 per_port;
+ cost 129;
+ }
+ ifdef HAS_CASCADE {
+ option "MODE" "CASCADE" {
+ abits 15;
+ widths 1 2 4 9 per_port;
+ cost 257;
+ }
+ }
+ }
+ init any;
+ port srsw "A" "B" {
+ option "MODE" "HALF" {
+ width mix;
+ }
+ option "MODE" "FULL" {
+ width mix;
+ }
+ option "MODE" "CASCADE" {
+ width mix 1;
+ }
+ ifdef HAS_ADDRCE {
+ # TODO
+ # addrce;
+ }
+ # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks.
+ ifdef HAS_CONFLICT_BUG {
+ option "HAS_RDFIRST" 1 {
+ clock posedge "C";
+ }
+ option "HAS_RDFIRST" 0 {
+ clock posedge;
+ }
+ } else {
+ clock posedge;
+ }
+ clken;
+ rdsrst any gated_clken;
+ rdinit any;
+ portoption "WRITE_MODE" "NO_CHANGE" {
+ rdwr no_change;
+ option "MODE" "CASCADE" {
+ forbid;
+ }
+ }
+ portoption "WRITE_MODE" "WRITE_FIRST" {
+ ifdef HAS_SIZE_36 {
+ rdwr new;
+ } else {
+ rdwr new_only;
+ }
+ }
+ ifdef HAS_CONFLICT_BUG {
+ option "HAS_RDFIRST" 1 {
+ portoption "WRITE_MODE" "READ_FIRST" {
+ rdwr old;
+ wrtrans all old;
+ }
+ }
+ } else {
+ portoption "WRITE_MODE" "READ_FIRST" {
+ rdwr old;
+ wrtrans all old;
+ }
+ }
+ optional_rw;
+ }
+}
+
+ifdef HAS_SIZE_36 {
+ ram block $__XILINX_BLOCKRAM_SDP_ {
+ byte 9;
+ option "MODE" "HALF" {
+ abits 14;
+ widths 1 2 4 9 18 36 per_port;
+ cost 129;
+ }
+ option "MODE" "FULL" {
+ abits 15;
+ widths 1 2 4 9 18 36 72 per_port;
+ cost 257;
+ }
+ init any;
+ port sw "W" {
+ ifndef HAS_MIXWIDTH_SDP {
+ option "MODE" "HALF" width 36;
+ option "MODE" "FULL" width 72;
+ }
+ ifdef HAS_ADDRCE {
+ # TODO
+ # addrce;
+ }
+ # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks.
+ ifdef HAS_CONFLICT_BUG {
+ option "WRITE_MODE" "READ_FIRST" {
+ clock posedge "C";
+ }
+ option "WRITE_MODE" "WRITE_FIRST" {
+ clock posedge;
+ }
+ } else {
+ clock posedge;
+ }
+ clken;
+ option "WRITE_MODE" "READ_FIRST" {
+ wrtrans all old;
+ }
+ optional;
+ }
+ port sr "R" {
+ ifndef HAS_MIXWIDTH_SDP {
+ option "MODE" "HALF" width 36;
+ option "MODE" "FULL" width 72;
+ }
+ ifdef HAS_ADDRCE {
+ # TODO
+ # addrce;
+ }
+ # Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks.
+ ifdef HAS_CONFLICT_BUG {
+ option "WRITE_MODE" "READ_FIRST" {
+ clock posedge "C";
+ }
+ option "WRITE_MODE" "WRITE_FIRST" {
+ clock posedge;
+ }
+ } else {
+ clock posedge;
+ }
+ clken;
+ rdsrst any gated_clken;
+ rdinit any;
+ optional;
+ }
+ }
+}
diff --git a/techlibs/xilinx/brams_xc4v_map.v b/techlibs/xilinx/brams_xc4v_map.v
new file mode 100644
index 000000000..a1747d40a
--- /dev/null
+++ b/techlibs/xilinx/brams_xc4v_map.v
@@ -0,0 +1,149 @@
+module $__XILINX_BLOCKRAM_TDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_MODE = "FULL";
+
+parameter PORT_A_RD_WIDTH = 1;
+parameter PORT_A_WR_WIDTH = 1;
+parameter PORT_A_WR_EN_WIDTH = 1;
+parameter PORT_A_RD_USED = 1;
+parameter PORT_A_WR_USED = 1;
+parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_A_RD_INIT_VALUE = 0;
+parameter PORT_A_RD_SRST_VALUE = 0;
+
+parameter PORT_B_RD_WIDTH = 1;
+parameter PORT_B_WR_WIDTH = 1;
+parameter PORT_B_WR_EN_WIDTH = 1;
+parameter PORT_B_RD_USED = 0;
+parameter PORT_B_WR_USED = 0;
+parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_B_RD_INIT_VALUE = 0;
+parameter PORT_B_RD_SRST_VALUE = 0;
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input [14:0] PORT_A_ADDR;
+input [PORT_A_WR_WIDTH-1:0] PORT_A_WR_DATA;
+input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
+output [PORT_A_RD_WIDTH-1:0] PORT_A_RD_DATA;
+input PORT_A_RD_SRST;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input [14:0] PORT_B_ADDR;
+input [PORT_B_WR_WIDTH-1:0] PORT_B_WR_DATA;
+input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN;
+output [PORT_B_RD_WIDTH-1:0] PORT_B_RD_DATA;
+input PORT_B_RD_SRST;
+
+`include "brams_defs.vh"
+
+`define PARAMS_COMMON \
+ .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \
+ .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \
+ .READ_WIDTH_A(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0), \
+ .READ_WIDTH_B(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0), \
+ .WRITE_WIDTH_A(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0), \
+ .WRITE_WIDTH_B(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0), \
+ .DOA_REG(0), \
+ .DOB_REG(0), \
+ .INIT_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_INIT_VALUE)), \
+ .INIT_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_INIT_VALUE)), \
+ .SRVAL_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_SRST_VALUE)), \
+ .SRVAL_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_SRST_VALUE)),
+
+`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA)
+`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA)
+`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA)
+`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA)
+
+wire [3:0] WE_A = {4{PORT_A_WR_EN}};
+wire [3:0] WE_B = {4{PORT_B_WR_EN}};
+
+generate
+
+if (OPTION_MODE == "FULL") begin
+ RAMB16 #(
+ `PARAMS_INIT_18
+ `PARAMS_INITP_18
+ `PARAMS_COMMON
+ .RAM_EXTENSION_A("NONE"),
+ .RAM_EXTENSION_B("NONE"),
+ ) _TECHMAP_REPLACE_ (
+ .DOA(DO_A),
+ .DOPA(DOP_A),
+ .DIA(DI_A),
+ .DIPA(DIP_A),
+ .DOB(DO_B),
+ .DOPB(DOP_B),
+ .DIB(DI_B),
+ .DIPB(DIP_B),
+ .ADDRA({1'b1, PORT_A_ADDR[13:0]}),
+ .ADDRB({1'b1, PORT_B_ADDR[13:0]}),
+ .CLKA(PORT_A_CLK),
+ .CLKB(PORT_B_CLK),
+ .ENA(PORT_A_CLK_EN),
+ .ENB(PORT_B_CLK_EN),
+ .REGCEA(1'b0),
+ .REGCEB(1'b0),
+ .SSRA(PORT_A_RD_SRST),
+ .SSRB(PORT_B_RD_SRST),
+ .WEA(WE_A),
+ .WEB(WE_B),
+ );
+end else begin
+ wire CAS_A, CAS_B;
+ RAMB16 #(
+ `PARAMS_INIT_18
+ `PARAMS_COMMON
+ .RAM_EXTENSION_A("LOWER"),
+ .RAM_EXTENSION_B("LOWER"),
+ ) lower (
+ .DIA(DI_A),
+ .DIB(DI_B),
+ .ADDRA(PORT_A_ADDR),
+ .ADDRB(PORT_B_ADDR),
+ .CLKA(PORT_A_CLK),
+ .CLKB(PORT_B_CLK),
+ .ENA(PORT_A_CLK_EN),
+ .ENB(PORT_B_CLK_EN),
+ .REGCEA(1'b0),
+ .REGCEB(1'b0),
+ .SSRA(PORT_A_RD_SRST),
+ .SSRB(PORT_B_RD_SRST),
+ .WEA(WE_A),
+ .WEB(WE_B),
+ .CASCADEOUTA(CAS_A),
+ .CASCADEOUTB(CAS_B),
+ );
+ RAMB16 #(
+ `PARAMS_INIT_18_U
+ `PARAMS_COMMON
+ .RAM_EXTENSION_A("UPPER"),
+ .RAM_EXTENSION_B("UPPER"),
+ ) upper (
+ .DOA(DO_A),
+ .DIA(DI_A),
+ .DOB(DO_B),
+ .DIB(DI_B),
+ .ADDRA(PORT_A_ADDR),
+ .ADDRB(PORT_B_ADDR),
+ .CLKA(PORT_A_CLK),
+ .CLKB(PORT_B_CLK),
+ .ENA(PORT_A_CLK_EN),
+ .ENB(PORT_B_CLK_EN),
+ .REGCEA(1'b0),
+ .REGCEB(1'b0),
+ .SSRA(PORT_A_RD_SRST),
+ .SSRB(PORT_B_RD_SRST),
+ .WEA(WE_A),
+ .WEB(WE_B),
+ .CASCADEINA(CAS_A),
+ .CASCADEINB(CAS_B),
+ );
+end
+
+endgenerate
+
+endmodule
diff --git a/techlibs/xilinx/brams_xc5v_map.v b/techlibs/xilinx/brams_xc5v_map.v
new file mode 100644
index 000000000..6349af359
--- /dev/null
+++ b/techlibs/xilinx/brams_xc5v_map.v
@@ -0,0 +1,255 @@
+module $__XILINX_BLOCKRAM_TDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_MODE = "FULL";
+
+parameter PORT_A_RD_WIDTH = 1;
+parameter PORT_A_WR_WIDTH = 1;
+parameter PORT_A_WR_EN_WIDTH = 1;
+parameter PORT_A_RD_USED = 1;
+parameter PORT_A_WR_USED = 1;
+parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_A_RD_INIT_VALUE = 0;
+parameter PORT_A_RD_SRST_VALUE = 0;
+
+parameter PORT_B_RD_WIDTH = 1;
+parameter PORT_B_WR_WIDTH = 1;
+parameter PORT_B_WR_EN_WIDTH = 1;
+parameter PORT_B_RD_USED = 0;
+parameter PORT_B_WR_USED = 0;
+parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_B_RD_INIT_VALUE = 0;
+parameter PORT_B_RD_SRST_VALUE = 0;
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input [15:0] PORT_A_ADDR;
+input [PORT_A_WR_WIDTH-1:0] PORT_A_WR_DATA;
+input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
+output [PORT_A_RD_WIDTH-1:0] PORT_A_RD_DATA;
+input PORT_A_RD_SRST;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input [15:0] PORT_B_ADDR;
+input [PORT_B_WR_WIDTH-1:0] PORT_B_WR_DATA;
+input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN;
+output [PORT_B_RD_WIDTH-1:0] PORT_B_RD_DATA;
+input PORT_B_RD_SRST;
+
+`include "brams_defs.vh"
+
+`define PARAMS_COMMON \
+ .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \
+ .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \
+ .READ_WIDTH_A(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0), \
+ .READ_WIDTH_B(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0), \
+ .WRITE_WIDTH_A(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0), \
+ .WRITE_WIDTH_B(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0), \
+ .DOA_REG(0), \
+ .DOB_REG(0), \
+ .INIT_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_INIT_VALUE)), \
+ .INIT_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_INIT_VALUE)), \
+ .SRVAL_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_SRST_VALUE)), \
+ .SRVAL_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_SRST_VALUE)),
+
+`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA)
+`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA)
+`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA)
+`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA)
+
+wire [3:0] WE_A = {4{PORT_A_WR_EN}};
+wire [3:0] WE_B = {4{PORT_B_WR_EN}};
+
+generate
+
+if (OPTION_MODE == "HALF") begin
+ RAMB18 #(
+ `PARAMS_INIT_18
+ `PARAMS_INITP_18
+ `PARAMS_COMMON
+ ) _TECHMAP_REPLACE_ (
+ .DOA(DO_A),
+ .DOPA(DOP_A),
+ .DIA(DI_A),
+ .DIPA(DIP_A),
+ .DOB(DO_B),
+ .DOPB(DOP_B),
+ .DIB(DI_B),
+ .DIPB(DIP_B),
+ .ADDRA(PORT_A_ADDR[13:0]),
+ .ADDRB(PORT_B_ADDR[13:0]),
+ .CLKA(PORT_A_CLK),
+ .CLKB(PORT_B_CLK),
+ .ENA(PORT_A_CLK_EN),
+ .ENB(PORT_B_CLK_EN),
+ .REGCEA(1'b0),
+ .REGCEB(1'b0),
+ .SSRA(PORT_A_RD_SRST),
+ .SSRB(PORT_B_RD_SRST),
+ .WEA(WE_A),
+ .WEB(WE_B),
+ );
+end else if (OPTION_MODE == "FULL") begin
+ RAMB36 #(
+ `PARAMS_INIT_36
+ `PARAMS_INITP_36
+ `PARAMS_COMMON
+ .RAM_EXTENSION_A("NONE"),
+ .RAM_EXTENSION_B("NONE"),
+ ) _TECHMAP_REPLACE_ (
+ .DOA(DO_A),
+ .DOPA(DOP_A),
+ .DIA(DI_A),
+ .DIPA(DIP_A),
+ .DOB(DO_B),
+ .DOPB(DOP_B),
+ .DIB(DI_B),
+ .DIPB(DIP_B),
+ .ADDRA({1'b1, PORT_A_ADDR[14:0]}),
+ .ADDRB({1'b1, PORT_B_ADDR[14:0]}),
+ .CLKA(PORT_A_CLK),
+ .CLKB(PORT_B_CLK),
+ .ENA(PORT_A_CLK_EN),
+ .ENB(PORT_B_CLK_EN),
+ .REGCEA(1'b0),
+ .REGCEB(1'b0),
+ .SSRA(PORT_A_RD_SRST),
+ .SSRB(PORT_B_RD_SRST),
+ .WEA(WE_A),
+ .WEB(WE_B),
+ );
+end else begin
+ wire CAS_A, CAS_B;
+ RAMB36 #(
+ `PARAMS_INIT_36
+ `PARAMS_COMMON
+ .RAM_EXTENSION_A("LOWER"),
+ .RAM_EXTENSION_B("LOWER"),
+ ) lower (
+ .DIA(DI_A),
+ .DIB(DI_B),
+ .ADDRA(PORT_A_ADDR),
+ .ADDRB(PORT_B_ADDR),
+ .CLKA(PORT_A_CLK),
+ .CLKB(PORT_B_CLK),
+ .ENA(PORT_A_CLK_EN),
+ .ENB(PORT_B_CLK_EN),
+ .REGCEA(1'b0),
+ .REGCEB(1'b0),
+ .SSRA(PORT_A_RD_SRST),
+ .SSRB(PORT_B_RD_SRST),
+ .WEA(WE_A),
+ .WEB(WE_B),
+ .CASCADEOUTLATA(CAS_A),
+ .CASCADEOUTLATB(CAS_B),
+ );
+ RAMB36 #(
+ `PARAMS_INIT_36_U
+ `PARAMS_COMMON
+ .RAM_EXTENSION_A("UPPER"),
+ .RAM_EXTENSION_B("UPPER"),
+ ) upper (
+ .DOA(DO_A),
+ .DIA(DI_A),
+ .DOB(DO_B),
+ .DIB(DI_B),
+ .ADDRA(PORT_A_ADDR),
+ .ADDRB(PORT_B_ADDR),
+ .CLKA(PORT_A_CLK),
+ .CLKB(PORT_B_CLK),
+ .ENA(PORT_A_CLK_EN),
+ .ENB(PORT_B_CLK_EN),
+ .REGCEA(1'b0),
+ .REGCEB(1'b0),
+ .SSRA(PORT_A_RD_SRST),
+ .SSRB(PORT_B_RD_SRST),
+ .WEA(WE_A),
+ .WEB(WE_B),
+ .CASCADEINLATA(CAS_A),
+ .CASCADEINLATB(CAS_B),
+ );
+end
+
+endgenerate
+
+endmodule
+
+
+module $__XILINX_BLOCKRAM_SDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_MODE = "FULL";
+parameter OPTION_WRITE_MODE = "READ_FIRST";
+
+parameter PORT_W_WIDTH = 1;
+parameter PORT_W_WR_EN_WIDTH = 1;
+parameter PORT_W_USED = 1;
+
+parameter PORT_R_WIDTH = 1;
+parameter PORT_R_USED = 0;
+parameter PORT_R_RD_INIT_VALUE = 0;
+parameter PORT_R_RD_SRST_VALUE = 0;
+
+input PORT_W_CLK;
+input PORT_W_CLK_EN;
+input [15:0] PORT_W_ADDR;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN;
+
+input PORT_R_CLK;
+input PORT_R_CLK_EN;
+input [15:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+input PORT_R_RD_SRST;
+
+`include "brams_defs.vh"
+
+`define PARAMS_COMMON \
+ .DO_REG(0), \
+ .INIT(ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)), \
+ .SRVAL(ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)),
+
+`define PORTS_COMMON \
+ .DO(DO), \
+ .DOP(DOP), \
+ .DI(DI), \
+ .DIP(DIP), \
+ .WRCLK(PORT_W_CLK), \
+ .RDCLK(PORT_R_CLK), \
+ .WREN(PORT_W_CLK_EN), \
+ .RDEN(PORT_R_CLK_EN), \
+ .REGCE(1'b0), \
+ .SSR(PORT_R_RD_SRST), \
+ .WE(PORT_W_WR_EN),
+
+`MAKE_DI(DI, DIP, PORT_W_WR_DATA)
+`MAKE_DO(DO, DOP, PORT_R_RD_DATA)
+
+generate
+
+if (OPTION_MODE == "HALF") begin
+ RAMB18SDP #(
+ `PARAMS_INIT_18
+ `PARAMS_INITP_18
+ `PARAMS_COMMON
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_COMMON
+ .WRADDR(PORT_W_ADDR[13:5]),
+ .RDADDR(PORT_R_ADDR[13:5]),
+ );
+end else if (OPTION_MODE == "FULL") begin
+ RAMB36SDP #(
+ `PARAMS_INIT_36
+ `PARAMS_INITP_36
+ `PARAMS_COMMON
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_COMMON
+ .WRADDR(PORT_W_ADDR[14:6]),
+ .RDADDR(PORT_R_ADDR[14:6]),
+ );
+end
+
+endgenerate
+
+endmodule
diff --git a/techlibs/xilinx/brams_xc6v_map.v b/techlibs/xilinx/brams_xc6v_map.v
new file mode 100644
index 000000000..b2698a3aa
--- /dev/null
+++ b/techlibs/xilinx/brams_xc6v_map.v
@@ -0,0 +1,284 @@
+module $__XILINX_BLOCKRAM_TDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_MODE = "FULL";
+parameter OPTION_HAS_RDFIRST = 0;
+
+parameter PORT_A_RD_WIDTH = 1;
+parameter PORT_A_WR_WIDTH = 1;
+parameter PORT_A_WR_EN_WIDTH = 1;
+parameter PORT_A_RD_USED = 1;
+parameter PORT_A_WR_USED = 1;
+parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_A_RD_INIT_VALUE = 0;
+parameter PORT_A_RD_SRST_VALUE = 1;
+
+parameter PORT_B_RD_WIDTH = 1;
+parameter PORT_B_WR_WIDTH = 1;
+parameter PORT_B_WR_EN_WIDTH = 1;
+parameter PORT_B_RD_USED = 0;
+parameter PORT_B_WR_USED = 0;
+parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_B_RD_INIT_VALUE = 0;
+parameter PORT_B_RD_SRST_VALUE = 0;
+
+input CLK_C;
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input [15:0] PORT_A_ADDR;
+input [PORT_A_WR_WIDTH-1:0] PORT_A_WR_DATA;
+input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
+output [PORT_A_RD_WIDTH-1:0] PORT_A_RD_DATA;
+input PORT_A_RD_SRST;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input [15:0] PORT_B_ADDR;
+input [PORT_B_WR_WIDTH-1:0] PORT_B_WR_DATA;
+input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN;
+output [PORT_B_RD_WIDTH-1:0] PORT_B_RD_DATA;
+input PORT_B_RD_SRST;
+
+`include "brams_defs.vh"
+
+`define PARAMS_COMMON \
+ .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \
+ .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \
+ .READ_WIDTH_A(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0), \
+ .READ_WIDTH_B(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0), \
+ .WRITE_WIDTH_A(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0), \
+ .WRITE_WIDTH_B(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0), \
+ .DOA_REG(0), \
+ .DOB_REG(0), \
+ .INIT_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_INIT_VALUE)), \
+ .INIT_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_INIT_VALUE)), \
+ .SRVAL_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_SRST_VALUE)), \
+ .SRVAL_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_SRST_VALUE)), \
+ .RAM_MODE("TDP"),
+
+`define PORTS_COMMON \
+ .DOADO(DO_A), \
+ .DOPADOP(DOP_A), \
+ .DIADI(DI_A), \
+ .DIPADIP(DIP_A), \
+ .DOBDO(DO_B), \
+ .DOPBDOP(DOP_B), \
+ .DIBDI(DI_B), \
+ .DIPBDIP(DIP_B), \
+ .CLKARDCLK(PORT_A_CLK), \
+ .CLKBWRCLK(PORT_B_CLK), \
+ .ENARDEN(PORT_A_CLK_EN), \
+ .ENBWREN(PORT_B_CLK_EN), \
+ .REGCEAREGCE(1'b0), \
+ .REGCEB(1'b0), \
+ .RSTRAMARSTRAM(PORT_A_RD_SRST), \
+ .RSTRAMB(PORT_B_RD_SRST), \
+ .RSTREGARSTREG(1'b0), \
+ .RSTREGB(1'b0), \
+ .WEA(WE_A), \
+ .WEBWE(WE_B),
+
+`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA)
+`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA)
+`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA)
+`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA)
+
+wire [3:0] WE_A = {4{PORT_A_WR_EN}};
+wire [3:0] WE_B = {4{PORT_B_WR_EN}};
+
+generate
+
+if (OPTION_MODE == "HALF") begin
+ RAMB18E1 #(
+ `PARAMS_INIT_18
+ `PARAMS_INITP_18
+ `PARAMS_COMMON
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_COMMON
+ .ADDRARDADDR(PORT_A_ADDR[13:0]),
+ .ADDRBWRADDR(PORT_B_ADDR[13:0]),
+ );
+end else if (OPTION_MODE == "FULL") begin
+ RAMB36E1 #(
+ `PARAMS_INIT_36
+ `PARAMS_INITP_36
+ `PARAMS_COMMON
+ .RAM_EXTENSION_A("NONE"),
+ .RAM_EXTENSION_B("NONE"),
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_COMMON
+ .ADDRARDADDR({1'b1, PORT_A_ADDR[14:0]}),
+ .ADDRBWRADDR({1'b1, PORT_B_ADDR[14:0]}),
+ );
+end else begin
+ wire CAS_A, CAS_B;
+ RAMB36E1 #(
+ `PARAMS_INIT_36
+ `PARAMS_COMMON
+ .RAM_EXTENSION_A("LOWER"),
+ .RAM_EXTENSION_B("LOWER"),
+ ) lower (
+ .DIADI(DI_A),
+ .DIBDI(DI_B),
+ .CLKARDCLK(PORT_A_CLK),
+ .CLKBWRCLK(PORT_B_CLK),
+ .ENARDEN(PORT_A_CLK_EN),
+ .ENBWREN(PORT_B_CLK_EN),
+ .REGCEAREGCE(1'b0),
+ .REGCEB(1'b0),
+ .RSTRAMARSTRAM(PORT_A_RD_SRST),
+ .RSTRAMB(PORT_B_RD_SRST),
+ .RSTREGARSTREG(1'b0),
+ .RSTREGB(1'b0),
+ .WEA(WE_A),
+ .WEBWE(WE_B),
+ .ADDRARDADDR(PORT_A_ADDR),
+ .ADDRBWRADDR(PORT_B_ADDR),
+ .CASCADEOUTA(CAS_A),
+ .CASCADEOUTB(CAS_B),
+ );
+ RAMB36E1 #(
+ `PARAMS_INIT_36_U
+ `PARAMS_COMMON
+ .RAM_EXTENSION_A("UPPER"),
+ .RAM_EXTENSION_B("UPPER"),
+ ) upper (
+ .DOADO(DO_A),
+ .DIADI(DI_A),
+ .DOBDO(DO_B),
+ .DIBDI(DI_B),
+ .CLKARDCLK(PORT_A_CLK),
+ .CLKBWRCLK(PORT_B_CLK),
+ .ENARDEN(PORT_A_CLK_EN),
+ .ENBWREN(PORT_B_CLK_EN),
+ .REGCEAREGCE(1'b0),
+ .REGCEB(1'b0),
+ .RSTRAMARSTRAM(PORT_A_RD_SRST),
+ .RSTRAMB(PORT_B_RD_SRST),
+ .RSTREGARSTREG(1'b0),
+ .RSTREGB(1'b0),
+ .WEA(WE_A),
+ .WEBWE(WE_B),
+ .ADDRARDADDR(PORT_A_ADDR),
+ .ADDRBWRADDR(PORT_B_ADDR),
+ .CASCADEINA(CAS_A),
+ .CASCADEINB(CAS_B),
+ );
+end
+
+endgenerate
+
+endmodule
+
+
+module $__XILINX_BLOCKRAM_SDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_MODE = "FULL";
+parameter OPTION_WRITE_MODE = "READ_FIRST";
+
+parameter PORT_W_WIDTH = 1;
+parameter PORT_W_WR_EN_WIDTH = 1;
+parameter PORT_W_USED = 1;
+
+parameter PORT_R_WIDTH = 1;
+parameter PORT_R_USED = 0;
+parameter PORT_R_RD_INIT_VALUE = 0;
+parameter PORT_R_RD_SRST_VALUE = 0;
+
+input CLK_C;
+
+input PORT_W_CLK;
+input PORT_W_CLK_EN;
+input [15:0] PORT_W_ADDR;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN;
+
+input PORT_R_CLK;
+input PORT_R_CLK_EN;
+input [15:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+input PORT_R_RD_SRST;
+
+`include "brams_defs.vh"
+
+`define PARAMS_COMMON \
+ .WRITE_MODE_A(OPTION_WRITE_MODE), \
+ .WRITE_MODE_B(OPTION_WRITE_MODE), \
+ .READ_WIDTH_A(PORT_R_USED ? PORT_R_WIDTH : 0), \
+ .READ_WIDTH_B(0), \
+ .WRITE_WIDTH_A(0), \
+ .WRITE_WIDTH_B(PORT_W_USED ? PORT_W_WIDTH : 0), \
+ .DOA_REG(0), \
+ .DOB_REG(0), \
+ .RAM_MODE("SDP"),
+
+`define PORTS_COMMON \
+ .CLKBWRCLK(PORT_W_CLK), \
+ .CLKARDCLK(PORT_R_CLK), \
+ .ENBWREN(PORT_W_CLK_EN), \
+ .ENARDEN(PORT_R_CLK_EN), \
+ .REGCEAREGCE(1'b0), \
+ .REGCEB(1'b0), \
+ .RSTRAMARSTRAM(PORT_R_RD_SRST), \
+ .RSTRAMB(1'b0), \
+ .RSTREGARSTREG(1'b0), \
+ .RSTREGB(1'b0), \
+ .WEA(0), \
+ .WEBWE(PORT_W_WR_EN),
+
+`MAKE_DI(DI, DIP, PORT_W_WR_DATA)
+`MAKE_DO(DO, DOP, PORT_R_RD_DATA)
+
+generate
+
+if (OPTION_MODE == "HALF") begin
+ RAMB18E1 #(
+ `PARAMS_INIT_18
+ `PARAMS_INITP_18
+ `PARAMS_COMMON
+ .INIT_A(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_INIT_VALUE[17:0]) : ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)),
+ .INIT_B(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_INIT_VALUE[35:18]) : 0),
+ .SRVAL_A(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_SRST_VALUE[17:0]) : ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)),
+ .SRVAL_B(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_SRST_VALUE[35:18]) : 0),
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_COMMON
+ .ADDRARDADDR(PORT_R_ADDR[13:0]),
+ .ADDRBWRADDR(PORT_W_ADDR[13:0]),
+ .DOADO(DO[15:0]),
+ .DOBDO(DO[31:16]),
+ .DOPADOP(DOP[1:0]),
+ .DOPBDOP(DOP[3:2]),
+ .DIADI(DI[15:0]),
+ .DIBDI(PORT_W_WIDTH == 36 ? DI[31:16] : DI[15:0]),
+ .DIPADIP(DIP[1:0]),
+ .DIPBDIP(PORT_W_WIDTH == 36 ? DIP[3:2] : DIP[1:0]),
+ );
+end else if (OPTION_MODE == "FULL") begin
+ RAMB36E1 #(
+ `PARAMS_INIT_36
+ `PARAMS_INITP_36
+ `PARAMS_COMMON
+ .INIT_A(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_INIT_VALUE[35:0]) : ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)),
+ .INIT_B(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_INIT_VALUE[71:36]) : 0),
+ .SRVAL_A(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_SRST_VALUE[35:0]) : ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)),
+ .SRVAL_B(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_SRST_VALUE[71:36]) : 0),
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_COMMON
+ .ADDRARDADDR({1'b1, PORT_R_ADDR}),
+ .ADDRBWRADDR({1'b1, PORT_W_ADDR}),
+ .DOADO(DO[31:0]),
+ .DOBDO(DO[63:32]),
+ .DOPADOP(DOP[3:0]),
+ .DOPBDOP(DOP[7:4]),
+ .DIADI(DI[31:0]),
+ .DIBDI(PORT_W_WIDTH == 72 ? DI[63:32] : DI[31:0]),
+ .DIPADIP(DIP[3:0]),
+ .DIPBDIP(PORT_W_WIDTH == 71 ? DIP[7:4] : DIP[3:0]),
+ );
+end
+
+endgenerate
+
+endmodule
diff --git a/techlibs/xilinx/brams_xcu_map.v b/techlibs/xilinx/brams_xcu_map.v
new file mode 100644
index 000000000..d48c21a59
--- /dev/null
+++ b/techlibs/xilinx/brams_xcu_map.v
@@ -0,0 +1,225 @@
+module $__XILINX_BLOCKRAM_TDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_MODE = "FULL";
+parameter OPTION_HAS_RDFIRST = 0;
+
+parameter PORT_A_RD_WIDTH = 1;
+parameter PORT_A_WR_WIDTH = 1;
+parameter PORT_A_WR_EN_WIDTH = 1;
+parameter PORT_A_RD_USED = 1;
+parameter PORT_A_WR_USED = 1;
+parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_A_RD_INIT_VALUE = 0;
+parameter PORT_A_RD_SRST_VALUE = 1;
+
+parameter PORT_B_RD_WIDTH = 1;
+parameter PORT_B_WR_WIDTH = 1;
+parameter PORT_B_WR_EN_WIDTH = 1;
+parameter PORT_B_RD_USED = 0;
+parameter PORT_B_WR_USED = 0;
+parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE";
+parameter PORT_B_RD_INIT_VALUE = 0;
+parameter PORT_B_RD_SRST_VALUE = 0;
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input [15:0] PORT_A_ADDR;
+input [PORT_A_WR_WIDTH-1:0] PORT_A_WR_DATA;
+input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
+output [PORT_A_RD_WIDTH-1:0] PORT_A_RD_DATA;
+input PORT_A_RD_SRST;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input [15:0] PORT_B_ADDR;
+input [PORT_B_WR_WIDTH-1:0] PORT_B_WR_DATA;
+input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN;
+output [PORT_B_RD_WIDTH-1:0] PORT_B_RD_DATA;
+input PORT_B_RD_SRST;
+
+`include "brams_defs.vh"
+
+`define PARAMS_COMMON \
+ .WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \
+ .WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \
+ .READ_WIDTH_A(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0), \
+ .READ_WIDTH_B(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0), \
+ .WRITE_WIDTH_A(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0), \
+ .WRITE_WIDTH_B(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0), \
+ .DOA_REG(0), \
+ .DOB_REG(0), \
+ .INIT_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_INIT_VALUE)), \
+ .INIT_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_INIT_VALUE)), \
+ .SRVAL_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_SRST_VALUE)), \
+ .SRVAL_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_SRST_VALUE)),
+
+`define PORTS_COMMON \
+ .DOUTADOUT(DO_A), \
+ .DOUTPADOUTP(DOP_A), \
+ .DINADIN(DI_A), \
+ .DINPADINP(DIP_A), \
+ .DOUTBDOUT(DO_B), \
+ .DOUTPBDOUTP(DOP_B), \
+ .DINBDIN(DI_B), \
+ .DINPBDINP(DIP_B), \
+ .CLKARDCLK(PORT_A_CLK), \
+ .CLKBWRCLK(PORT_B_CLK), \
+ .ENARDEN(PORT_A_CLK_EN), \
+ .ENBWREN(PORT_B_CLK_EN), \
+ .REGCEAREGCE(1'b0), \
+ .REGCEB(1'b0), \
+ .ADDRENA(1'b1), \
+ .ADDRENB(1'b1), \
+ .RSTRAMARSTRAM(PORT_A_RD_SRST), \
+ .RSTRAMB(PORT_B_RD_SRST), \
+ .RSTREGARSTREG(1'b0), \
+ .RSTREGB(1'b0), \
+ .WEA(WE_A), \
+ .WEBWE(WE_B), \
+ .ADDRARDADDR(PORT_A_ADDR), \
+ .ADDRBWRADDR(PORT_B_ADDR), \
+ .SLEEP(1'b0),
+
+`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA)
+`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA)
+`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA)
+`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA)
+
+wire [3:0] WE_A = {4{PORT_A_WR_EN}};
+wire [3:0] WE_B = {4{PORT_B_WR_EN}};
+
+generate
+
+if (OPTION_MODE == "HALF") begin
+ RAMB18E2 #(
+ `PARAMS_INIT_18
+ `PARAMS_INITP_18
+ `PARAMS_COMMON
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_COMMON
+ );
+end else if (OPTION_MODE == "FULL") begin
+ RAMB36E2 #(
+ `PARAMS_INIT_36
+ `PARAMS_INITP_36
+ `PARAMS_COMMON
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_COMMON
+ );
+end
+
+endgenerate
+
+endmodule
+
+
+module $__XILINX_BLOCKRAM_SDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_MODE = "FULL";
+parameter OPTION_WRITE_MODE = "READ_FIRST";
+
+parameter PORT_W_WIDTH = 1;
+parameter PORT_W_WR_EN_WIDTH = 1;
+parameter PORT_W_USED = 1;
+
+parameter PORT_R_WIDTH = 1;
+parameter PORT_R_USED = 0;
+parameter PORT_R_RD_INIT_VALUE = 0;
+parameter PORT_R_RD_SRST_VALUE = 0;
+
+input PORT_W_CLK;
+input PORT_W_CLK_EN;
+input [15:0] PORT_W_ADDR;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN;
+
+input PORT_R_CLK;
+input PORT_R_CLK_EN;
+input [15:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+input PORT_R_RD_SRST;
+
+`include "brams_defs.vh"
+
+`define PARAMS_COMMON \
+ .WRITE_MODE_A(OPTION_WRITE_MODE), \
+ .WRITE_MODE_B(OPTION_WRITE_MODE), \
+ .READ_WIDTH_A(PORT_R_USED ? PORT_R_WIDTH : 0), \
+ .READ_WIDTH_B(0), \
+ .WRITE_WIDTH_A(0), \
+ .WRITE_WIDTH_B(PORT_W_USED ? PORT_W_WIDTH : 0), \
+ .DOA_REG(0), \
+ .DOB_REG(0),
+
+`define PORTS_COMMON \
+ .CLKBWRCLK(PORT_W_CLK), \
+ .CLKARDCLK(PORT_R_CLK), \
+ .ENBWREN(PORT_W_CLK_EN), \
+ .ENARDEN(PORT_R_CLK_EN), \
+ .REGCEAREGCE(1'b0), \
+ .REGCEB(1'b0), \
+ .ADDRENA(1'b1), \
+ .ADDRENB(1'b1), \
+ .RSTRAMARSTRAM(PORT_R_RD_SRST), \
+ .RSTRAMB(1'b0), \
+ .RSTREGARSTREG(1'b0), \
+ .RSTREGB(1'b0), \
+ .WEA(0), \
+ .WEBWE(PORT_W_WR_EN), \
+ .ADDRARDADDR(PORT_R_ADDR), \
+ .ADDRBWRADDR(PORT_W_ADDR), \
+ .SLEEP(1'b0),
+
+`MAKE_DI(DI, DIP, PORT_W_WR_DATA)
+`MAKE_DO(DO, DOP, PORT_R_RD_DATA)
+
+generate
+
+if (OPTION_MODE == "HALF") begin
+ RAMB18E2 #(
+ `PARAMS_INIT_18
+ `PARAMS_INITP_18
+ `PARAMS_COMMON
+ .INIT_A(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_INIT_VALUE[17:0]) : ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)),
+ .INIT_B(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_INIT_VALUE[35:18]) : 0),
+ .SRVAL_A(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_SRST_VALUE[17:0]) : ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)),
+ .SRVAL_B(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_SRST_VALUE[35:18]) : 0),
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_COMMON
+ .DOUTADOUT(DO[15:0]),
+ .DOUTBDOUT(DO[31:16]),
+ .DOUTPADOUTP(DOP[1:0]),
+ .DOUTPBDOUTP(DOP[3:2]),
+ .DINADIN(DI[15:0]),
+ .DINBDIN(PORT_W_WIDTH == 36 ? DI[31:16] : DI[15:0]),
+ .DINPADINP(DIP[1:0]),
+ .DINPBDINP(PORT_W_WIDTH == 36 ? DIP[3:2] : DIP[1:0]),
+ );
+end else if (OPTION_MODE == "FULL") begin
+ RAMB36E2 #(
+ `PARAMS_INIT_36
+ `PARAMS_INITP_36
+ `PARAMS_COMMON
+ .INIT_A(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_INIT_VALUE[35:0]) : ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)),
+ .INIT_B(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_INIT_VALUE[71:36]) : 0),
+ .SRVAL_A(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_SRST_VALUE[35:0]) : ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)),
+ .SRVAL_B(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_SRST_VALUE[71:36]) : 0),
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_COMMON
+ .DOUTADOUT(DO[31:0]),
+ .DOUTBDOUT(DO[63:32]),
+ .DOUTPADOUTP(DOP[3:0]),
+ .DOUTPBDOUTP(DOP[7:4]),
+ .DINADIN(DI[31:0]),
+ .DINBDIN(PORT_W_WIDTH == 72 ? DI[63:32] : DI[31:0]),
+ .DINPADINP(DIP[3:0]),
+ .DINPBDINP(PORT_W_WIDTH == 71 ? DIP[7:4] : DIP[3:0]),
+ );
+end
+
+endgenerate
+
+endmodule
+
diff --git a/techlibs/xilinx/brams_xcv.txt b/techlibs/xilinx/brams_xcv.txt
new file mode 100644
index 000000000..294e9036b
--- /dev/null
+++ b/techlibs/xilinx/brams_xcv.txt
@@ -0,0 +1,17 @@
+# Block RAMs for the original Virtex.
+# The corresponding mapping file is brams_xcv_map.v
+
+ram block $__XILINX_BLOCKRAM_ {
+ abits 12;
+ widths 1 2 4 8 16 per_port;
+ cost 32;
+ init any;
+ port srsw "A" "B" {
+ clock posedge;
+ clken;
+ rdwr new;
+ rdinit zero;
+ rdsrst zero gated_clken;
+ optional;
+ }
+}
diff --git a/techlibs/xilinx/brams_xcv_map.v b/techlibs/xilinx/brams_xcv_map.v
new file mode 100644
index 000000000..408cc6795
--- /dev/null
+++ b/techlibs/xilinx/brams_xcv_map.v
@@ -0,0 +1,257 @@
+module $__XILINX_BLOCKRAM_ (...);
+
+parameter INIT = 0;
+
+parameter PORT_A_WIDTH = 1;
+parameter PORT_B_WIDTH = 1;
+parameter PORT_A_USED = 1;
+parameter PORT_B_USED = 0;
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input [11:0] PORT_A_ADDR;
+input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
+input PORT_A_WR_EN;
+output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
+input PORT_A_RD_SRST;
+
+input PORT_B_CLK;
+input PORT_B_CLK_EN;
+input [11:0] PORT_B_ADDR;
+input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
+input PORT_B_WR_EN;
+output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
+input PORT_B_RD_SRST;
+
+`define PARAMS_INIT \
+ .INIT_00(INIT[0*256+:256]), \
+ .INIT_01(INIT[1*256+:256]), \
+ .INIT_02(INIT[2*256+:256]), \
+ .INIT_03(INIT[3*256+:256]), \
+ .INIT_04(INIT[4*256+:256]), \
+ .INIT_05(INIT[5*256+:256]), \
+ .INIT_06(INIT[6*256+:256]), \
+ .INIT_07(INIT[7*256+:256]), \
+ .INIT_08(INIT[8*256+:256]), \
+ .INIT_09(INIT[9*256+:256]), \
+ .INIT_0A(INIT[10*256+:256]), \
+ .INIT_0B(INIT[11*256+:256]), \
+ .INIT_0C(INIT[12*256+:256]), \
+ .INIT_0D(INIT[13*256+:256]), \
+ .INIT_0E(INIT[14*256+:256]), \
+ .INIT_0F(INIT[15*256+:256]),
+
+`define PORTS_DP(addr_slice_a, addr_slice_b) \
+ .CLKA(PORT_A_CLK), \
+ .ENA(PORT_A_CLK_EN), \
+ .WEA(PORT_A_WR_EN), \
+ .RSTA(PORT_A_RD_SRST), \
+ .ADDRA(PORT_A_ADDR addr_slice_a), \
+ .DOA(PORT_A_RD_DATA), \
+ .DIA(PORT_A_WR_DATA), \
+ .CLKB(PORT_B_CLK), \
+ .ENB(PORT_B_CLK_EN), \
+ .WEB(PORT_B_WR_EN), \
+ .RSTB(PORT_B_RD_SRST), \
+ .ADDRB(PORT_B_ADDR addr_slice_b), \
+ .DOB(PORT_B_RD_DATA), \
+ .DIB(PORT_B_WR_DATA),
+
+`define PORTS_DP_SWAP(addr_slice_a, addr_slice_b) \
+ .CLKB(PORT_A_CLK), \
+ .ENB(PORT_A_CLK_EN), \
+ .WEB(PORT_A_WR_EN), \
+ .RSTB(PORT_A_RD_SRST), \
+ .ADDRB(PORT_A_ADDR addr_slice_a), \
+ .DOB(PORT_A_RD_DATA), \
+ .DIB(PORT_A_WR_DATA), \
+ .CLKA(PORT_B_CLK), \
+ .ENA(PORT_B_CLK_EN), \
+ .WEA(PORT_B_WR_EN), \
+ .RSTA(PORT_B_RD_SRST), \
+ .ADDRA(PORT_B_ADDR addr_slice_b), \
+ .DOA(PORT_B_RD_DATA), \
+ .DIA(PORT_B_WR_DATA),
+
+`define PORTS_SP(addr_slice) \
+ .CLK(PORT_A_CLK), \
+ .EN(PORT_A_CLK_EN), \
+ .WE(PORT_A_WR_EN), \
+ .RST(PORT_A_RD_SRST), \
+ .ADDR(PORT_A_ADDR addr_slice), \
+ .DO(PORT_A_RD_DATA), \
+ .DI(PORT_A_WR_DATA),
+
+generate
+
+if (!PORT_B_USED) begin
+ case (PORT_A_WIDTH)
+ 1: RAMB4_S1 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([11:0])
+ );
+ 2: RAMB4_S2 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([11:1])
+ );
+ 4: RAMB4_S4 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([11:2])
+ );
+ 8: RAMB4_S8 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([11:3])
+ );
+ 16: RAMB4_S16 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_SP([11:4])
+ );
+ endcase
+end else begin
+ case (PORT_A_WIDTH)
+ 1: case(PORT_B_WIDTH)
+ 1: RAMB4_S1_S1 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:0], [11:0])
+ );
+ 2: RAMB4_S1_S2 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:0], [11:1])
+ );
+ 4: RAMB4_S1_S4 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:0], [11:2])
+ );
+ 8: RAMB4_S1_S8 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:0], [11:3])
+ );
+ 16: RAMB4_S1_S16 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:0], [11:4])
+ );
+ endcase
+ 2: case(PORT_B_WIDTH)
+ 1: RAMB4_S1_S2 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([11:1], [11:0])
+ );
+ 2: RAMB4_S2_S2 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:1], [11:1])
+ );
+ 4: RAMB4_S2_S4 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:1], [11:2])
+ );
+ 8: RAMB4_S2_S8 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:1], [11:3])
+ );
+ 16: RAMB4_S2_S16 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:1], [11:4])
+ );
+ endcase
+ 4: case(PORT_B_WIDTH)
+ 1: RAMB4_S1_S4 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([11:2], [11:0])
+ );
+ 2: RAMB4_S2_S4 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([11:2], [11:1])
+ );
+ 4: RAMB4_S4_S4 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:2], [11:2])
+ );
+ 8: RAMB4_S4_S8 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:2], [11:3])
+ );
+ 16: RAMB4_S4_S16 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:2], [11:4])
+ );
+ endcase
+ 8: case(PORT_B_WIDTH)
+ 1: RAMB4_S1_S8 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([11:3], [11:0])
+ );
+ 2: RAMB4_S2_S8 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([11:3], [11:1])
+ );
+ 4: RAMB4_S4_S8 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([11:3], [11:2])
+ );
+ 8: RAMB4_S8_S8 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:3], [11:3])
+ );
+ 16: RAMB4_S8_S16 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:3], [11:4])
+ );
+ endcase
+ 16: case(PORT_B_WIDTH)
+ 1: RAMB4_S1_S16 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([11:4], [11:0])
+ );
+ 2: RAMB4_S2_S16 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([11:4], [11:1])
+ );
+ 4: RAMB4_S4_S16 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([11:4], [11:2])
+ );
+ 8: RAMB4_S8_S16 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP_SWAP([11:4], [11:3])
+ );
+ 16: RAMB4_S16_S16 #(
+ `PARAMS_INIT
+ ) _TECHMAP_REPLACE_ (
+ `PORTS_DP([11:4], [11:4])
+ );
+ endcase
+ endcase
+end
+
+endgenerate
+
+endmodule
diff --git a/techlibs/xilinx/cells_xtra.py b/techlibs/xilinx/cells_xtra.py
index cb23b9787..2630c7a0f 100644
--- a/techlibs/xilinx/cells_xtra.py
+++ b/techlibs/xilinx/cells_xtra.py
@@ -108,7 +108,26 @@ CELLS = [
# Block RAM.
# Virtex.
- # TODO: RAMB4_*
+ Cell('RAMB4_S1', port_attrs={'CLK': ['clkbuf_sink']}),
+ Cell('RAMB4_S2', port_attrs={'CLK': ['clkbuf_sink']}),
+ Cell('RAMB4_S4', port_attrs={'CLK': ['clkbuf_sink']}),
+ Cell('RAMB4_S8', port_attrs={'CLK': ['clkbuf_sink']}),
+ Cell('RAMB4_S16', port_attrs={'CLK': ['clkbuf_sink']}),
+ Cell('RAMB4_S1_S1', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S1_S2', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S1_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S1_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S1_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S2_S2', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S2_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S2_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S2_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S4_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S4_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S4_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S8_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S8_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
+ Cell('RAMB4_S16_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
# Virtex 2, Spartan 3.
Cell('RAMB16_S1', port_attrs={'CLK': ['clkbuf_sink']}),
Cell('RAMB16_S2', port_attrs={'CLK': ['clkbuf_sink']}),
diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v
index 1187101fd..aae0d3ee5 100644
--- a/techlibs/xilinx/cells_xtra.v
+++ b/techlibs/xilinx/cells_xtra.v
@@ -1,5 +1,680 @@
// Created by cells_xtra.py from Xilinx models
+module RAMB4_S1 (...);
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [0:0] DO;
+ input [11:0] ADDR;
+ input [0:0] DI;
+ input EN;
+ (* clkbuf_sink *)
+ input CLK;
+ input WE;
+ input RST;
+endmodule
+
+module RAMB4_S2 (...);
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [1:0] DO;
+ input [10:0] ADDR;
+ input [1:0] DI;
+ input EN;
+ (* clkbuf_sink *)
+ input CLK;
+ input WE;
+ input RST;
+endmodule
+
+module RAMB4_S4 (...);
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [3:0] DO;
+ input [9:0] ADDR;
+ input [3:0] DI;
+ input EN;
+ (* clkbuf_sink *)
+ input CLK;
+ input WE;
+ input RST;
+endmodule
+
+module RAMB4_S8 (...);
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [7:0] DO;
+ input [8:0] ADDR;
+ input [7:0] DI;
+ input EN;
+ (* clkbuf_sink *)
+ input CLK;
+ input WE;
+ input RST;
+endmodule
+
+module RAMB4_S16 (...);
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [15:0] DO;
+ input [7:0] ADDR;
+ input [15:0] DI;
+ input EN;
+ (* clkbuf_sink *)
+ input CLK;
+ input WE;
+ input RST;
+endmodule
+
+module RAMB4_S1_S1 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [0:0] DOA;
+ input [11:0] ADDRA;
+ input [0:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [0:0] DOB;
+ input [11:0] ADDRB;
+ input [0:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S1_S2 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [0:0] DOA;
+ input [11:0] ADDRA;
+ input [0:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [1:0] DOB;
+ input [10:0] ADDRB;
+ input [1:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S1_S4 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [0:0] DOA;
+ input [11:0] ADDRA;
+ input [0:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [3:0] DOB;
+ input [9:0] ADDRB;
+ input [3:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S1_S8 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [0:0] DOA;
+ input [11:0] ADDRA;
+ input [0:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [7:0] DOB;
+ input [8:0] ADDRB;
+ input [7:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S1_S16 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [0:0] DOA;
+ input [11:0] ADDRA;
+ input [0:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [15:0] DOB;
+ input [7:0] ADDRB;
+ input [15:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S2_S2 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [1:0] DOA;
+ input [10:0] ADDRA;
+ input [1:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [1:0] DOB;
+ input [10:0] ADDRB;
+ input [1:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S2_S4 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [1:0] DOA;
+ input [10:0] ADDRA;
+ input [1:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [3:0] DOB;
+ input [9:0] ADDRB;
+ input [3:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S2_S8 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [1:0] DOA;
+ input [10:0] ADDRA;
+ input [1:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [7:0] DOB;
+ input [8:0] ADDRB;
+ input [7:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S2_S16 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [1:0] DOA;
+ input [10:0] ADDRA;
+ input [1:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [15:0] DOB;
+ input [7:0] ADDRB;
+ input [15:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S4_S4 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [3:0] DOA;
+ input [9:0] ADDRA;
+ input [3:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [3:0] DOB;
+ input [9:0] ADDRB;
+ input [3:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S4_S8 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [3:0] DOA;
+ input [9:0] ADDRA;
+ input [3:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [7:0] DOB;
+ input [8:0] ADDRB;
+ input [7:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S4_S16 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [3:0] DOA;
+ input [9:0] ADDRA;
+ input [3:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [15:0] DOB;
+ input [7:0] ADDRB;
+ input [15:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S8_S8 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [7:0] DOA;
+ input [8:0] ADDRA;
+ input [7:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [7:0] DOB;
+ input [8:0] ADDRB;
+ input [7:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S8_S16 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [7:0] DOA;
+ input [8:0] ADDRA;
+ input [7:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [15:0] DOB;
+ input [7:0] ADDRB;
+ input [15:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
+module RAMB4_S16_S16 (...);
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ output [15:0] DOA;
+ input [7:0] ADDRA;
+ input [15:0] DIA;
+ input ENA;
+ (* clkbuf_sink *)
+ input CLKA;
+ input WEA;
+ input RSTA;
+ output [15:0] DOB;
+ input [7:0] ADDRB;
+ input [15:0] DIB;
+ input ENB;
+ (* clkbuf_sink *)
+ input CLKB;
+ input WEB;
+ input RSTB;
+endmodule
+
module RAMB16_S1 (...);
parameter [0:0] INIT = 1'h0;
parameter [0:0] SRVAL = 1'h0;
diff --git a/techlibs/xilinx/lut4_lutrams.txt b/techlibs/xilinx/lut4_lutrams.txt
deleted file mode 100644
index 2b344a9ee..000000000
--- a/techlibs/xilinx/lut4_lutrams.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-bram $__XILINX_RAM16X1D
- init 1
- abits 4
- dbits 1
- groups 2
- ports 1 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 2
-endbram
-
-
-match $__XILINX_RAM16X1D
- min bits 2
- min wports 1
- make_outreg
-endmatch
diff --git a/techlibs/xilinx/lut6_lutrams.txt b/techlibs/xilinx/lut6_lutrams.txt
deleted file mode 100644
index 3b3cb81e1..000000000
--- a/techlibs/xilinx/lut6_lutrams.txt
+++ /dev/null
@@ -1,143 +0,0 @@
-bram $__XILINX_RAM32X1D
- init 1
- abits 5
- dbits 1
- groups 2
- ports 1 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 2
-endbram
-
-bram $__XILINX_RAM64X1D
- init 1
- abits 6
- dbits 1
- groups 2
- ports 1 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 2
-endbram
-
-bram $__XILINX_RAM128X1D
- init 1
- abits 7
- dbits 1
- groups 2
- ports 1 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 2
-endbram
-
-
-bram $__XILINX_RAM32X6SDP
- init 1
- abits 5
- dbits 6
- groups 2
- ports 1 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 2
-endbram
-
-bram $__XILINX_RAM64X3SDP
- init 1
- abits 6
- dbits 3
- groups 2
- ports 1 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 2
-endbram
-
-bram $__XILINX_RAM32X2Q
- init 1
- abits 5
- dbits 2
- groups 2
- ports 3 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 2
-endbram
-
-bram $__XILINX_RAM64X1Q
- init 1
- abits 6
- dbits 1
- groups 2
- ports 3 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 2
-endbram
-
-
-match $__XILINX_RAM32X1D
- min bits 3
- min wports 1
- make_outreg
- or_next_if_better
-endmatch
-
-match $__XILINX_RAM64X1D
- min bits 5
- min wports 1
- make_outreg
- or_next_if_better
-endmatch
-
-match $__XILINX_RAM128X1D
- min bits 9
- min wports 1
- make_outreg
- or_next_if_better
-endmatch
-
-
-match $__XILINX_RAM32X6SDP
- min bits 5
- min wports 1
- make_outreg
- or_next_if_better
-endmatch
-
-match $__XILINX_RAM64X3SDP
- min bits 6
- min wports 1
- make_outreg
- or_next_if_better
-endmatch
-
-match $__XILINX_RAM32X2Q
- min bits 5
- min rports 2
- min wports 1
- make_outreg
- or_next_if_better
-endmatch
-
-match $__XILINX_RAM64X1Q
- min bits 5
- min rports 2
- min wports 1
- make_outreg
-endmatch
diff --git a/techlibs/xilinx/lutrams_map.v b/techlibs/xilinx/lutrams_map.v
deleted file mode 100644
index 3ac1143bb..000000000
--- a/techlibs/xilinx/lutrams_map.v
+++ /dev/null
@@ -1,279 +0,0 @@
-
-module \$__XILINX_RAM16X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
- parameter [15:0] INIT = 16'bx;
- parameter CLKPOL2 = 1;
- input CLK1;
-
- input [3:0] A1ADDR;
- output A1DATA;
-
- input [3:0] B1ADDR;
- input B1DATA;
- input B1EN;
-
- RAM16X1D #(
- .INIT(INIT),
- .IS_WCLK_INVERTED(!CLKPOL2)
- ) _TECHMAP_REPLACE_ (
- .DPRA0(A1ADDR[0]),
- .DPRA1(A1ADDR[1]),
- .DPRA2(A1ADDR[2]),
- .DPRA3(A1ADDR[3]),
- .DPO(A1DATA),
-
- .A0(B1ADDR[0]),
- .A1(B1ADDR[1]),
- .A2(B1ADDR[2]),
- .A3(B1ADDR[3]),
- .D(B1DATA),
- .WCLK(CLK1),
- .WE(B1EN)
- );
-endmodule
-
-module \$__XILINX_RAM32X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
- parameter [31:0] INIT = 32'bx;
- parameter CLKPOL2 = 1;
- input CLK1;
-
- input [4:0] A1ADDR;
- output A1DATA;
-
- input [4:0] B1ADDR;
- input B1DATA;
- input B1EN;
-
- RAM32X1D #(
- .INIT(INIT),
- .IS_WCLK_INVERTED(!CLKPOL2)
- ) _TECHMAP_REPLACE_ (
- .DPRA0(A1ADDR[0]),
- .DPRA1(A1ADDR[1]),
- .DPRA2(A1ADDR[2]),
- .DPRA3(A1ADDR[3]),
- .DPRA4(A1ADDR[4]),
- .DPO(A1DATA),
-
- .A0(B1ADDR[0]),
- .A1(B1ADDR[1]),
- .A2(B1ADDR[2]),
- .A3(B1ADDR[3]),
- .A4(B1ADDR[4]),
- .D(B1DATA),
- .WCLK(CLK1),
- .WE(B1EN)
- );
-endmodule
-
-module \$__XILINX_RAM64X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
- parameter [63:0] INIT = 64'bx;
- parameter CLKPOL2 = 1;
- input CLK1;
-
- input [5:0] A1ADDR;
- output A1DATA;
-
- input [5:0] B1ADDR;
- input B1DATA;
- input B1EN;
-
- RAM64X1D #(
- .INIT(INIT),
- .IS_WCLK_INVERTED(!CLKPOL2)
- ) _TECHMAP_REPLACE_ (
- .DPRA0(A1ADDR[0]),
- .DPRA1(A1ADDR[1]),
- .DPRA2(A1ADDR[2]),
- .DPRA3(A1ADDR[3]),
- .DPRA4(A1ADDR[4]),
- .DPRA5(A1ADDR[5]),
- .DPO(A1DATA),
-
- .A0(B1ADDR[0]),
- .A1(B1ADDR[1]),
- .A2(B1ADDR[2]),
- .A3(B1ADDR[3]),
- .A4(B1ADDR[4]),
- .A5(B1ADDR[5]),
- .D(B1DATA),
- .WCLK(CLK1),
- .WE(B1EN)
- );
-endmodule
-
-module \$__XILINX_RAM128X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
- parameter [127:0] INIT = 128'bx;
- parameter CLKPOL2 = 1;
- input CLK1;
-
- input [6:0] A1ADDR;
- output A1DATA;
-
- input [6:0] B1ADDR;
- input B1DATA;
- input B1EN;
-
- RAM128X1D #(
- .INIT(INIT),
- .IS_WCLK_INVERTED(!CLKPOL2)
- ) _TECHMAP_REPLACE_ (
- .DPRA(A1ADDR),
- .DPO(A1DATA),
-
- .A(B1ADDR),
- .D(B1DATA),
- .WCLK(CLK1),
- .WE(B1EN)
- );
-endmodule
-
-
-module \$__XILINX_RAM32X6SDP (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
- parameter [32*6-1:0] INIT = {32*6{1'bx}};
- parameter CLKPOL2 = 1;
- input CLK1;
-
- input [4:0] A1ADDR;
- output [5:0] A1DATA;
-
- input [4:0] B1ADDR;
- input [5:0] B1DATA;
- input B1EN;
-
- wire [1:0] DOD_unused;
-
- RAM32M #(
- .INIT_A({INIT[187:186], INIT[181:180], INIT[175:174], INIT[169:168], INIT[163:162], INIT[157:156], INIT[151:150], INIT[145:144], INIT[139:138], INIT[133:132], INIT[127:126], INIT[121:120], INIT[115:114], INIT[109:108], INIT[103:102], INIT[ 97: 96], INIT[ 91: 90], INIT[ 85: 84], INIT[ 79: 78], INIT[ 73: 72], INIT[ 67: 66], INIT[ 61: 60], INIT[ 55: 54], INIT[ 49: 48], INIT[ 43: 42], INIT[ 37: 36], INIT[ 31: 30], INIT[ 25: 24], INIT[ 19: 18], INIT[ 13: 12], INIT[ 7: 6], INIT[ 1: 0]}),
- .INIT_B({INIT[189:188], INIT[183:182], INIT[177:176], INIT[171:170], INIT[165:164], INIT[159:158], INIT[153:152], INIT[147:146], INIT[141:140], INIT[135:134], INIT[129:128], INIT[123:122], INIT[117:116], INIT[111:110], INIT[105:104], INIT[ 99: 98], INIT[ 93: 92], INIT[ 87: 86], INIT[ 81: 80], INIT[ 75: 74], INIT[ 69: 68], INIT[ 63: 62], INIT[ 57: 56], INIT[ 51: 50], INIT[ 45: 44], INIT[ 39: 38], INIT[ 33: 32], INIT[ 27: 26], INIT[ 21: 20], INIT[ 15: 14], INIT[ 9: 8], INIT[ 3: 2]}),
- .INIT_C({INIT[191:190], INIT[185:184], INIT[179:178], INIT[173:172], INIT[167:166], INIT[161:160], INIT[155:154], INIT[149:148], INIT[143:142], INIT[137:136], INIT[131:130], INIT[125:124], INIT[119:118], INIT[113:112], INIT[107:106], INIT[101:100], INIT[ 95: 94], INIT[ 89: 88], INIT[ 83: 82], INIT[ 77: 76], INIT[ 71: 70], INIT[ 65: 64], INIT[ 59: 58], INIT[ 53: 52], INIT[ 47: 46], INIT[ 41: 40], INIT[ 35: 34], INIT[ 29: 28], INIT[ 23: 22], INIT[ 17: 16], INIT[ 11: 10], INIT[ 5: 4]}),
- .INIT_D(64'bx),
- .IS_WCLK_INVERTED(!CLKPOL2)
- ) _TECHMAP_REPLACE_ (
- .ADDRA(A1ADDR),
- .ADDRB(A1ADDR),
- .ADDRC(A1ADDR),
- .DOA(A1DATA[1:0]),
- .DOB(A1DATA[3:2]),
- .DOC(A1DATA[5:4]),
- .DOD(DOD_unused),
-
- .ADDRD(B1ADDR),
- .DIA(B1DATA[1:0]),
- .DIB(B1DATA[3:2]),
- .DIC(B1DATA[5:4]),
- .DID(2'b00),
- .WCLK(CLK1),
- .WE(B1EN)
- );
-endmodule
-
-module \$__XILINX_RAM64X3SDP (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
- parameter [64*3-1:0] INIT = {64*3{1'bx}};
- parameter CLKPOL2 = 1;
- input CLK1;
-
- input [5:0] A1ADDR;
- output [2:0] A1DATA;
-
- input [5:0] B1ADDR;
- input [2:0] B1DATA;
- input B1EN;
-
- wire DOD_unused;
-
- RAM64M #(
- .INIT_A({INIT[189], INIT[186], INIT[183], INIT[180], INIT[177], INIT[174], INIT[171], INIT[168], INIT[165], INIT[162], INIT[159], INIT[156], INIT[153], INIT[150], INIT[147], INIT[144], INIT[141], INIT[138], INIT[135], INIT[132], INIT[129], INIT[126], INIT[123], INIT[120], INIT[117], INIT[114], INIT[111], INIT[108], INIT[105], INIT[102], INIT[ 99], INIT[ 96], INIT[ 93], INIT[ 90], INIT[ 87], INIT[ 84], INIT[ 81], INIT[ 78], INIT[ 75], INIT[ 72], INIT[ 69], INIT[ 66], INIT[ 63], INIT[ 60], INIT[ 57], INIT[ 54], INIT[ 51], INIT[ 48], INIT[ 45], INIT[ 42], INIT[ 39], INIT[ 36], INIT[ 33], INIT[ 30], INIT[ 27], INIT[ 24], INIT[ 21], INIT[ 18], INIT[ 15], INIT[ 12], INIT[ 9], INIT[ 6], INIT[ 3], INIT[ 0]}),
- .INIT_B({INIT[190], INIT[187], INIT[184], INIT[181], INIT[178], INIT[175], INIT[172], INIT[169], INIT[166], INIT[163], INIT[160], INIT[157], INIT[154], INIT[151], INIT[148], INIT[145], INIT[142], INIT[139], INIT[136], INIT[133], INIT[130], INIT[127], INIT[124], INIT[121], INIT[118], INIT[115], INIT[112], INIT[109], INIT[106], INIT[103], INIT[100], INIT[ 97], INIT[ 94], INIT[ 91], INIT[ 88], INIT[ 85], INIT[ 82], INIT[ 79], INIT[ 76], INIT[ 73], INIT[ 70], INIT[ 67], INIT[ 64], INIT[ 61], INIT[ 58], INIT[ 55], INIT[ 52], INIT[ 49], INIT[ 46], INIT[ 43], INIT[ 40], INIT[ 37], INIT[ 34], INIT[ 31], INIT[ 28], INIT[ 25], INIT[ 22], INIT[ 19], INIT[ 16], INIT[ 13], INIT[ 10], INIT[ 7], INIT[ 4], INIT[ 1]}),
- .INIT_C({INIT[191], INIT[188], INIT[185], INIT[182], INIT[179], INIT[176], INIT[173], INIT[170], INIT[167], INIT[164], INIT[161], INIT[158], INIT[155], INIT[152], INIT[149], INIT[146], INIT[143], INIT[140], INIT[137], INIT[134], INIT[131], INIT[128], INIT[125], INIT[122], INIT[119], INIT[116], INIT[113], INIT[110], INIT[107], INIT[104], INIT[101], INIT[ 98], INIT[ 95], INIT[ 92], INIT[ 89], INIT[ 86], INIT[ 83], INIT[ 80], INIT[ 77], INIT[ 74], INIT[ 71], INIT[ 68], INIT[ 65], INIT[ 62], INIT[ 59], INIT[ 56], INIT[ 53], INIT[ 50], INIT[ 47], INIT[ 44], INIT[ 41], INIT[ 38], INIT[ 35], INIT[ 32], INIT[ 29], INIT[ 26], INIT[ 23], INIT[ 20], INIT[ 17], INIT[ 14], INIT[ 11], INIT[ 8], INIT[ 5], INIT[ 2]}),
- .INIT_D(64'bx),
- .IS_WCLK_INVERTED(!CLKPOL2)
- ) _TECHMAP_REPLACE_ (
- .ADDRA(A1ADDR),
- .ADDRB(A1ADDR),
- .ADDRC(A1ADDR),
- .DOA(A1DATA[0]),
- .DOB(A1DATA[1]),
- .DOC(A1DATA[2]),
- .DOD(DOD_unused),
-
- .ADDRD(B1ADDR),
- .DIA(B1DATA[0]),
- .DIB(B1DATA[1]),
- .DIC(B1DATA[2]),
- .DID(1'b0),
- .WCLK(CLK1),
- .WE(B1EN)
- );
-endmodule
-
-module \$__XILINX_RAM32X2Q (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN);
- parameter [63:0] INIT = 64'bx;
- parameter CLKPOL2 = 1;
- input CLK1;
-
- input [4:0] A1ADDR, A2ADDR, A3ADDR;
- output [1:0] A1DATA, A2DATA, A3DATA;
-
- input [4:0] B1ADDR;
- input [1:0] B1DATA;
- input B1EN;
-
- RAM32M #(
- .INIT_A(INIT),
- .INIT_B(INIT),
- .INIT_C(INIT),
- .INIT_D(INIT),
- .IS_WCLK_INVERTED(!CLKPOL2)
- ) _TECHMAP_REPLACE_ (
- .ADDRA(A1ADDR),
- .ADDRB(A2ADDR),
- .ADDRC(A3ADDR),
- .DOA(A1DATA),
- .DOB(A2DATA),
- .DOC(A3DATA),
-
- .ADDRD(B1ADDR),
- .DIA(B1DATA),
- .DIB(B1DATA),
- .DIC(B1DATA),
- .DID(B1DATA),
- .WCLK(CLK1),
- .WE(B1EN)
- );
-endmodule
-
-module \$__XILINX_RAM64X1Q (CLK1, A1ADDR, A1DATA, A2ADDR, A2DATA, A3ADDR, A3DATA, B1ADDR, B1DATA, B1EN);
- parameter [63:0] INIT = 64'bx;
- parameter CLKPOL2 = 1;
- input CLK1;
-
- input [5:0] A1ADDR, A2ADDR, A3ADDR;
- output A1DATA, A2DATA, A3DATA;
-
- input [5:0] B1ADDR;
- input B1DATA;
- input B1EN;
-
- RAM64M #(
- .INIT_A(INIT),
- .INIT_B(INIT),
- .INIT_C(INIT),
- .INIT_D(INIT),
- .IS_WCLK_INVERTED(!CLKPOL2)
- ) _TECHMAP_REPLACE_ (
- .ADDRA(A1ADDR),
- .ADDRB(A2ADDR),
- .ADDRC(A3ADDR),
- .DOA(A1DATA),
- .DOB(A2DATA),
- .DOC(A3DATA),
-
- .ADDRD(B1ADDR),
- .DIA(B1DATA),
- .DIB(B1DATA),
- .DIC(B1DATA),
- .DID(B1DATA),
- .WCLK(CLK1),
- .WE(B1EN)
- );
-endmodule
diff --git a/techlibs/xilinx/lutrams_xc5v.txt b/techlibs/xilinx/lutrams_xc5v.txt
new file mode 100644
index 000000000..8ab8076b4
--- /dev/null
+++ b/techlibs/xilinx/lutrams_xc5v.txt
@@ -0,0 +1,100 @@
+# LUT RAMs for Virtex 5, Virtex 6, Spartan 6, Series 7.
+# The corresponding mapping file is lutrams_xc5v_map.v
+
+# Single-port RAMs.
+
+ram distributed $__XILINX_LUTRAM_SP_ {
+ cost 8;
+ widthscale;
+ option "ABITS" 5 {
+ abits 5;
+ widths 8 global;
+ }
+ option "ABITS" 6 {
+ abits 6;
+ widths 4 global;
+ }
+ option "ABITS" 7 {
+ abits 7;
+ widths 2 global;
+ }
+ option "ABITS" 8 {
+ abits 8;
+ widths 1 global;
+ }
+ init no_undef;
+ prune_rom;
+ port arsw "RW" {
+ clock posedge;
+ }
+}
+
+# Dual-port RAMs.
+
+ram distributed $__XILINX_LUTRAM_DP_ {
+ cost 8;
+ widthscale;
+ option "ABITS" 5 {
+ abits 5;
+ widths 4 global;
+ }
+ option "ABITS" 6 {
+ abits 6;
+ widths 2 global;
+ }
+ option "ABITS" 7 {
+ abits 7;
+ widths 1 global;
+ }
+ init no_undef;
+ prune_rom;
+ port arsw "RW" {
+ clock posedge;
+ }
+ port ar "R" {
+ }
+}
+
+# Quad-port RAMs.
+
+ram distributed $__XILINX_LUTRAM_QP_ {
+ cost 7;
+ widthscale;
+ option "ABITS" 5 {
+ abits 5;
+ widths 2 global;
+ }
+ option "ABITS" 6 {
+ abits 6;
+ widths 1 global;
+ }
+ init no_undef;
+ prune_rom;
+ port arsw "RW" {
+ clock posedge;
+ }
+ port ar "R0" "R1" "R2" {
+ }
+}
+
+# Simple dual port RAMs.
+
+ram distributed $__XILINX_LUTRAM_SDP_ {
+ cost 8;
+ widthscale 7;
+ option "ABITS" 5 {
+ abits 5;
+ widths 6 global;
+ }
+ option "ABITS" 6 {
+ abits 6;
+ widths 3 global;
+ }
+ init no_undef;
+ prune_rom;
+ port sw "W" {
+ clock posedge;
+ }
+ port ar "R" {
+ }
+}
diff --git a/techlibs/xilinx/lutrams_xc5v_map.v b/techlibs/xilinx/lutrams_xc5v_map.v
new file mode 100644
index 000000000..18ce3a575
--- /dev/null
+++ b/techlibs/xilinx/lutrams_xc5v_map.v
@@ -0,0 +1,901 @@
+// LUT RAMs for Virtex 5, Virtex 6, Spartan 6, Series 7, Ultrascale.
+// The definitions are in lutrams_xc5v.txt (everything but Ultrascale)
+// and lutrams_xcu.txt (Ultrascale).
+
+
+module $__XILINX_LUTRAM_SP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_ABITS = 5;
+parameter WIDTH = 8;
+parameter BITS_USED = 0;
+
+output [WIDTH-1:0] PORT_RW_RD_DATA;
+input [WIDTH-1:0] PORT_RW_WR_DATA;
+input [OPTION_ABITS-1:0] PORT_RW_ADDR;
+input PORT_RW_WR_EN;
+input PORT_RW_CLK;
+
+function [(1 << OPTION_ABITS)-1:0] init_slice;
+ input integer idx;
+ integer i;
+ for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
+ init_slice[i] = INIT[i * WIDTH + idx];
+endfunction
+
+function [(2 << OPTION_ABITS)-1:0] init_slice2;
+ input integer idx;
+ integer i;
+ for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
+ init_slice2[2 * i +: 2] = INIT[i * WIDTH + idx * 2 +: 2];
+endfunction
+
+generate
+case(OPTION_ABITS)
+5: if (WIDTH == 8)
+ RAM32M
+ #(
+ .INIT_D(init_slice2(0)),
+ .INIT_C(init_slice2(1)),
+ .INIT_B(init_slice2(2)),
+ .INIT_A(init_slice2(3)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_RW_RD_DATA[7:6]),
+ .DOB(PORT_RW_RD_DATA[5:4]),
+ .DOC(PORT_RW_RD_DATA[3:2]),
+ .DOD(PORT_RW_RD_DATA[1:0]),
+ .DIA(PORT_RW_WR_DATA[7:6]),
+ .DIB(PORT_RW_WR_DATA[5:4]),
+ .DIC(PORT_RW_WR_DATA[3:2]),
+ .DID(PORT_RW_WR_DATA[1:0]),
+ .ADDRA(PORT_RW_ADDR),
+ .ADDRB(PORT_RW_ADDR),
+ .ADDRC(PORT_RW_ADDR),
+ .ADDRD(PORT_RW_ADDR),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+else
+ RAM32M16
+ #(
+ .INIT_H(init_slice2(0)),
+ .INIT_G(init_slice2(1)),
+ .INIT_F(init_slice2(2)),
+ .INIT_E(init_slice2(3)),
+ .INIT_D(init_slice2(4)),
+ .INIT_C(init_slice2(5)),
+ .INIT_B(init_slice2(6)),
+ .INIT_A(init_slice2(7)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_RW_RD_DATA[15:14]),
+ .DOB(PORT_RW_RD_DATA[13:12]),
+ .DOC(PORT_RW_RD_DATA[11:10]),
+ .DOD(PORT_RW_RD_DATA[9:8]),
+ .DOE(PORT_RW_RD_DATA[7:6]),
+ .DOF(PORT_RW_RD_DATA[5:4]),
+ .DOG(PORT_RW_RD_DATA[3:2]),
+ .DOH(PORT_RW_RD_DATA[1:0]),
+ .DIA(PORT_RW_WR_DATA[15:14]),
+ .DIB(PORT_RW_WR_DATA[13:12]),
+ .DIC(PORT_RW_WR_DATA[11:10]),
+ .DID(PORT_RW_WR_DATA[9:8]),
+ .DIE(PORT_RW_WR_DATA[7:6]),
+ .DIF(PORT_RW_WR_DATA[5:4]),
+ .DIG(PORT_RW_WR_DATA[3:2]),
+ .DIH(PORT_RW_WR_DATA[1:0]),
+ .ADDRA(PORT_RW_ADDR),
+ .ADDRB(PORT_RW_ADDR),
+ .ADDRC(PORT_RW_ADDR),
+ .ADDRD(PORT_RW_ADDR),
+ .ADDRE(PORT_RW_ADDR),
+ .ADDRF(PORT_RW_ADDR),
+ .ADDRG(PORT_RW_ADDR),
+ .ADDRH(PORT_RW_ADDR),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+6: begin
+ genvar i;
+ for (i = 0; i < WIDTH; i = i + 1)
+ if (BITS_USED[i])
+ RAM64X1S
+ #(
+ .INIT(init_slice(i)),
+ )
+ slice
+ (
+ .A0(PORT_RW_ADDR[0]),
+ .A1(PORT_RW_ADDR[1]),
+ .A2(PORT_RW_ADDR[2]),
+ .A3(PORT_RW_ADDR[3]),
+ .A4(PORT_RW_ADDR[4]),
+ .A5(PORT_RW_ADDR[5]),
+ .D(PORT_RW_WR_DATA[i]),
+ .O(PORT_RW_RD_DATA[i]),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+end
+7: begin
+ genvar i;
+ for (i = 0; i < WIDTH; i = i + 1)
+ if (BITS_USED[i])
+ RAM128X1S
+ #(
+ .INIT(init_slice(i)),
+ )
+ slice
+ (
+ .A0(PORT_RW_ADDR[0]),
+ .A1(PORT_RW_ADDR[1]),
+ .A2(PORT_RW_ADDR[2]),
+ .A3(PORT_RW_ADDR[3]),
+ .A4(PORT_RW_ADDR[4]),
+ .A5(PORT_RW_ADDR[5]),
+ .A6(PORT_RW_ADDR[6]),
+ .D(PORT_RW_WR_DATA[i]),
+ .O(PORT_RW_RD_DATA[i]),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+end
+8: begin
+ genvar i;
+ for (i = 0; i < WIDTH; i = i + 1)
+ if (BITS_USED[i])
+ RAM256X1S
+ #(
+ .INIT(init_slice(i)),
+ )
+ slice
+ (
+ .A(PORT_RW_ADDR),
+ .D(PORT_RW_WR_DATA[i]),
+ .O(PORT_RW_RD_DATA[i]),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+end
+9: begin
+ genvar i;
+ for (i = 0; i < WIDTH; i = i + 1)
+ if (BITS_USED[i])
+ RAM512X1S
+ #(
+ .INIT(init_slice(i)),
+ )
+ slice
+ (
+ .A(PORT_RW_ADDR),
+ .D(PORT_RW_WR_DATA[i]),
+ .O(PORT_RW_RD_DATA[i]),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+end
+default:
+ $error("invalid OPTION_ABITS/WIDTH combination");
+endcase
+endgenerate
+
+endmodule
+
+
+module $__XILINX_LUTRAM_DP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_ABITS = 5;
+parameter WIDTH = 4;
+parameter BITS_USED = 0;
+
+output [WIDTH-1:0] PORT_RW_RD_DATA;
+input [WIDTH-1:0] PORT_RW_WR_DATA;
+input [OPTION_ABITS-1:0] PORT_RW_ADDR;
+input PORT_RW_WR_EN;
+input PORT_RW_CLK;
+
+output [WIDTH-1:0] PORT_R_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R_ADDR;
+
+function [(1 << OPTION_ABITS)-1:0] init_slice;
+ input integer idx;
+ integer i;
+ for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
+ init_slice[i] = INIT[i * WIDTH + idx];
+endfunction
+
+function [(2 << OPTION_ABITS)-1:0] init_slice2;
+ input integer idx;
+ integer i;
+ for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
+ init_slice2[2 * i +: 2] = INIT[i * WIDTH + idx * 2 +: 2];
+endfunction
+
+generate
+case (OPTION_ABITS)
+5: if (WIDTH == 4)
+ RAM32M
+ #(
+ .INIT_D(init_slice2(0)),
+ .INIT_C(init_slice2(0)),
+ .INIT_B(init_slice2(1)),
+ .INIT_A(init_slice2(1)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R_RD_DATA[3:2]),
+ .DOB(PORT_RW_RD_DATA[3:2]),
+ .DOC(PORT_R_RD_DATA[1:0]),
+ .DOD(PORT_RW_RD_DATA[1:0]),
+ .DIA(PORT_RW_WR_DATA[3:2]),
+ .DIB(PORT_RW_WR_DATA[3:2]),
+ .DIC(PORT_RW_WR_DATA[1:0]),
+ .DID(PORT_RW_WR_DATA[1:0]),
+ .ADDRA(PORT_R_ADDR),
+ .ADDRB(PORT_RW_ADDR),
+ .ADDRC(PORT_R_ADDR),
+ .ADDRD(PORT_RW_ADDR),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+else
+ RAM32M16
+ #(
+ .INIT_H(init_slice2(0)),
+ .INIT_G(init_slice2(0)),
+ .INIT_F(init_slice2(1)),
+ .INIT_E(init_slice2(1)),
+ .INIT_D(init_slice2(2)),
+ .INIT_C(init_slice2(2)),
+ .INIT_B(init_slice2(3)),
+ .INIT_A(init_slice2(3)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R_RD_DATA[7:6]),
+ .DOB(PORT_RW_RD_DATA[7:6]),
+ .DOC(PORT_R_RD_DATA[5:4]),
+ .DOD(PORT_RW_RD_DATA[5:4]),
+ .DOE(PORT_R_RD_DATA[3:2]),
+ .DOF(PORT_RW_RD_DATA[3:2]),
+ .DOG(PORT_R_RD_DATA[1:0]),
+ .DOH(PORT_RW_RD_DATA[1:0]),
+ .DIA(PORT_RW_WR_DATA[7:6]),
+ .DIB(PORT_RW_WR_DATA[7:6]),
+ .DIC(PORT_RW_WR_DATA[5:4]),
+ .DID(PORT_RW_WR_DATA[5:4]),
+ .DIE(PORT_RW_WR_DATA[3:2]),
+ .DIF(PORT_RW_WR_DATA[3:2]),
+ .DIG(PORT_RW_WR_DATA[1:0]),
+ .DIH(PORT_RW_WR_DATA[1:0]),
+ .ADDRA(PORT_R_ADDR),
+ .ADDRB(PORT_RW_ADDR),
+ .ADDRC(PORT_R_ADDR),
+ .ADDRD(PORT_RW_ADDR),
+ .ADDRE(PORT_R_ADDR),
+ .ADDRF(PORT_RW_ADDR),
+ .ADDRG(PORT_R_ADDR),
+ .ADDRH(PORT_RW_ADDR),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+6: begin
+ genvar i;
+ for (i = 0; i < WIDTH; i = i + 1)
+ if (BITS_USED[i])
+ RAM64X1D
+ #(
+ .INIT(init_slice(i)),
+ )
+ slice
+ (
+ .A0(PORT_RW_ADDR[0]),
+ .A1(PORT_RW_ADDR[1]),
+ .A2(PORT_RW_ADDR[2]),
+ .A3(PORT_RW_ADDR[3]),
+ .A4(PORT_RW_ADDR[4]),
+ .A5(PORT_RW_ADDR[5]),
+ .D(PORT_RW_WR_DATA[i]),
+ .SPO(PORT_RW_RD_DATA[i]),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ .DPRA0(PORT_R_ADDR[0]),
+ .DPRA1(PORT_R_ADDR[1]),
+ .DPRA2(PORT_R_ADDR[2]),
+ .DPRA3(PORT_R_ADDR[3]),
+ .DPRA4(PORT_R_ADDR[4]),
+ .DPRA5(PORT_R_ADDR[5]),
+ .DPO(PORT_R_RD_DATA[i]),
+ );
+end
+7: begin
+ genvar i;
+ for (i = 0; i < WIDTH; i = i + 1)
+ if (BITS_USED[i])
+ RAM128X1D
+ #(
+ .INIT(init_slice(i)),
+ )
+ slice
+ (
+ .A(PORT_RW_ADDR),
+ .D(PORT_RW_WR_DATA[i]),
+ .SPO(PORT_RW_RD_DATA[i]),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ .DPRA(PORT_R_ADDR),
+ .DPO(PORT_R_RD_DATA[i]),
+ );
+end
+8: begin
+ genvar i;
+ for (i = 0; i < WIDTH; i = i + 1)
+ if (BITS_USED[i])
+ RAM256X1D
+ #(
+ .INIT(init_slice(i)),
+ )
+ slice
+ (
+ .A(PORT_RW_ADDR),
+ .D(PORT_RW_WR_DATA[i]),
+ .SPO(PORT_RW_RD_DATA[i]),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ .DPRA(PORT_R_ADDR),
+ .DPO(PORT_R_RD_DATA[i]),
+ );
+end
+default:
+ $error("invalid OPTION_ABITS/WIDTH combination");
+endcase
+endgenerate
+
+endmodule
+
+
+module $__XILINX_LUTRAM_QP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_ABITS = 5;
+parameter WIDTH = 2;
+parameter BITS_USED = 0;
+
+output [WIDTH-1:0] PORT_RW_RD_DATA;
+input [WIDTH-1:0] PORT_RW_WR_DATA;
+input [OPTION_ABITS-1:0] PORT_RW_ADDR;
+input PORT_RW_WR_EN;
+input PORT_RW_CLK;
+
+output [WIDTH-1:0] PORT_R0_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R0_ADDR;
+output [WIDTH-1:0] PORT_R1_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R1_ADDR;
+output [WIDTH-1:0] PORT_R2_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R2_ADDR;
+
+function [(1 << OPTION_ABITS)-1:0] init_slice;
+ input integer idx;
+ integer i;
+ for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
+ init_slice[i] = INIT[i * WIDTH + idx];
+endfunction
+
+function [(2 << OPTION_ABITS)-1:0] init_slice2;
+ input integer idx;
+ integer i;
+ for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
+ init_slice2[2 * i +: 2] = INIT[i * WIDTH + idx * 2 +: 2];
+endfunction
+
+generate
+case (OPTION_ABITS)
+5: if (WIDTH == 2)
+ RAM32M
+ #(
+ .INIT_D(init_slice2(0)),
+ .INIT_C(init_slice2(0)),
+ .INIT_B(init_slice2(0)),
+ .INIT_A(init_slice2(0)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R2_RD_DATA[1:0]),
+ .DOB(PORT_R1_RD_DATA[1:0]),
+ .DOC(PORT_R0_RD_DATA[1:0]),
+ .DOD(PORT_RW_RD_DATA[1:0]),
+ .DIA(PORT_RW_WR_DATA[1:0]),
+ .DIB(PORT_RW_WR_DATA[1:0]),
+ .DIC(PORT_RW_WR_DATA[1:0]),
+ .DID(PORT_RW_WR_DATA[1:0]),
+ .ADDRA(PORT_R2_ADDR),
+ .ADDRB(PORT_R1_ADDR),
+ .ADDRC(PORT_R0_ADDR),
+ .ADDRD(PORT_RW_ADDR),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+else
+ RAM32M16
+ #(
+ .INIT_H(init_slice2(0)),
+ .INIT_G(init_slice2(0)),
+ .INIT_F(init_slice2(0)),
+ .INIT_E(init_slice2(0)),
+ .INIT_D(init_slice2(1)),
+ .INIT_C(init_slice2(1)),
+ .INIT_B(init_slice2(1)),
+ .INIT_A(init_slice2(1)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R2_RD_DATA[3:2]),
+ .DOB(PORT_R1_RD_DATA[3:2]),
+ .DOC(PORT_R0_RD_DATA[3:2]),
+ .DOD(PORT_RW_RD_DATA[3:2]),
+ .DOE(PORT_R2_RD_DATA[1:0]),
+ .DOF(PORT_R1_RD_DATA[1:0]),
+ .DOG(PORT_R0_RD_DATA[1:0]),
+ .DOH(PORT_RW_RD_DATA[1:0]),
+ .DIA(PORT_RW_WR_DATA[3:2]),
+ .DIB(PORT_RW_WR_DATA[3:2]),
+ .DIC(PORT_RW_WR_DATA[3:2]),
+ .DID(PORT_RW_WR_DATA[3:2]),
+ .DIE(PORT_RW_WR_DATA[1:0]),
+ .DIF(PORT_RW_WR_DATA[1:0]),
+ .DIG(PORT_RW_WR_DATA[1:0]),
+ .DIH(PORT_RW_WR_DATA[1:0]),
+ .ADDRA(PORT_R2_ADDR),
+ .ADDRB(PORT_R1_ADDR),
+ .ADDRC(PORT_R0_ADDR),
+ .ADDRD(PORT_RW_ADDR),
+ .ADDRE(PORT_R2_ADDR),
+ .ADDRF(PORT_R1_ADDR),
+ .ADDRG(PORT_R0_ADDR),
+ .ADDRH(PORT_RW_ADDR),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+6: if (WIDTH == 1)
+ RAM64M
+ #(
+ .INIT_D(init_slice(0)),
+ .INIT_C(init_slice(0)),
+ .INIT_B(init_slice(0)),
+ .INIT_A(init_slice(0)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R2_RD_DATA[0]),
+ .DOB(PORT_R1_RD_DATA[0]),
+ .DOC(PORT_R0_RD_DATA[0]),
+ .DOD(PORT_RW_RD_DATA[0]),
+ .DIA(PORT_RW_WR_DATA[0]),
+ .DIB(PORT_RW_WR_DATA[0]),
+ .DIC(PORT_RW_WR_DATA[0]),
+ .DID(PORT_RW_WR_DATA[0]),
+ .ADDRA(PORT_R2_ADDR),
+ .ADDRB(PORT_R1_ADDR),
+ .ADDRC(PORT_R0_ADDR),
+ .ADDRD(PORT_RW_ADDR),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+else
+ RAM64M8
+ #(
+ .INIT_H(init_slice(0)),
+ .INIT_G(init_slice(0)),
+ .INIT_F(init_slice(0)),
+ .INIT_E(init_slice(0)),
+ .INIT_D(init_slice(1)),
+ .INIT_C(init_slice(1)),
+ .INIT_B(init_slice(1)),
+ .INIT_A(init_slice(1)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R2_RD_DATA[1]),
+ .DOB(PORT_R1_RD_DATA[1]),
+ .DOC(PORT_R0_RD_DATA[1]),
+ .DOD(PORT_RW_RD_DATA[1]),
+ .DOE(PORT_R2_RD_DATA[0]),
+ .DOF(PORT_R1_RD_DATA[0]),
+ .DOG(PORT_R0_RD_DATA[0]),
+ .DOH(PORT_RW_RD_DATA[0]),
+ .DIA(PORT_RW_WR_DATA[1]),
+ .DIB(PORT_RW_WR_DATA[1]),
+ .DIC(PORT_RW_WR_DATA[1]),
+ .DID(PORT_RW_WR_DATA[1]),
+ .DIE(PORT_RW_WR_DATA[0]),
+ .DIF(PORT_RW_WR_DATA[0]),
+ .DIG(PORT_RW_WR_DATA[0]),
+ .DIH(PORT_RW_WR_DATA[0]),
+ .ADDRA(PORT_R2_ADDR),
+ .ADDRB(PORT_R1_ADDR),
+ .ADDRC(PORT_R0_ADDR),
+ .ADDRD(PORT_RW_ADDR),
+ .ADDRE(PORT_R2_ADDR),
+ .ADDRF(PORT_R1_ADDR),
+ .ADDRG(PORT_R0_ADDR),
+ .ADDRH(PORT_RW_ADDR),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+default:
+ $error("invalid OPTION_ABITS/WIDTH combination");
+endcase
+endgenerate
+
+endmodule
+
+
+module $__XILINX_LUTRAM_OP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_ABITS = 5;
+parameter WIDTH = 2;
+parameter BITS_USED = 0;
+
+output [WIDTH-1:0] PORT_RW_RD_DATA;
+input [WIDTH-1:0] PORT_RW_WR_DATA;
+input [OPTION_ABITS-1:0] PORT_RW_ADDR;
+input PORT_RW_WR_EN;
+input PORT_RW_CLK;
+
+output [WIDTH-1:0] PORT_R0_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R0_ADDR;
+output [WIDTH-1:0] PORT_R1_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R1_ADDR;
+output [WIDTH-1:0] PORT_R2_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R2_ADDR;
+output [WIDTH-1:0] PORT_R3_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R3_ADDR;
+output [WIDTH-1:0] PORT_R4_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R4_ADDR;
+output [WIDTH-1:0] PORT_R5_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R5_ADDR;
+output [WIDTH-1:0] PORT_R6_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R6_ADDR;
+
+generate
+case (OPTION_ABITS)
+5: RAM32M16
+ #(
+ .INIT_H(INIT),
+ .INIT_G(INIT),
+ .INIT_F(INIT),
+ .INIT_E(INIT),
+ .INIT_D(INIT),
+ .INIT_C(INIT),
+ .INIT_B(INIT),
+ .INIT_A(INIT),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R6_RD_DATA),
+ .DOB(PORT_R5_RD_DATA),
+ .DOC(PORT_R4_RD_DATA),
+ .DOD(PORT_R3_RD_DATA),
+ .DOE(PORT_R2_RD_DATA),
+ .DOF(PORT_R1_RD_DATA),
+ .DOG(PORT_R0_RD_DATA),
+ .DOH(PORT_RW_RD_DATA),
+ .DIA(PORT_RW_WR_DATA),
+ .DIB(PORT_RW_WR_DATA),
+ .DIC(PORT_RW_WR_DATA),
+ .DID(PORT_RW_WR_DATA),
+ .DIE(PORT_RW_WR_DATA),
+ .DIF(PORT_RW_WR_DATA),
+ .DIG(PORT_RW_WR_DATA),
+ .DIH(PORT_RW_WR_DATA),
+ .ADDRA(PORT_R6_ADDR),
+ .ADDRB(PORT_R5_ADDR),
+ .ADDRC(PORT_R4_ADDR),
+ .ADDRD(PORT_R3_ADDR),
+ .ADDRE(PORT_R2_ADDR),
+ .ADDRF(PORT_R1_ADDR),
+ .ADDRG(PORT_R0_ADDR),
+ .ADDRH(PORT_RW_ADDR),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+6: RAM64M8
+ #(
+ .INIT_H(INIT),
+ .INIT_G(INIT),
+ .INIT_F(INIT),
+ .INIT_E(INIT),
+ .INIT_D(INIT),
+ .INIT_C(INIT),
+ .INIT_B(INIT),
+ .INIT_A(INIT),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R6_RD_DATA),
+ .DOB(PORT_R5_RD_DATA),
+ .DOC(PORT_R4_RD_DATA),
+ .DOD(PORT_R3_RD_DATA),
+ .DOE(PORT_R2_RD_DATA),
+ .DOF(PORT_R1_RD_DATA),
+ .DOG(PORT_R0_RD_DATA),
+ .DOH(PORT_RW_RD_DATA),
+ .DIA(PORT_RW_WR_DATA),
+ .DIB(PORT_RW_WR_DATA),
+ .DIC(PORT_RW_WR_DATA),
+ .DID(PORT_RW_WR_DATA),
+ .DIE(PORT_RW_WR_DATA),
+ .DIF(PORT_RW_WR_DATA),
+ .DIG(PORT_RW_WR_DATA),
+ .DIH(PORT_RW_WR_DATA),
+ .ADDRA(PORT_R6_ADDR),
+ .ADDRB(PORT_R5_ADDR),
+ .ADDRC(PORT_R4_ADDR),
+ .ADDRD(PORT_R3_ADDR),
+ .ADDRE(PORT_R2_ADDR),
+ .ADDRF(PORT_R1_ADDR),
+ .ADDRG(PORT_R0_ADDR),
+ .ADDRH(PORT_RW_ADDR),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+default:
+ $error("invalid OPTION_ABITS/WIDTH combination");
+endcase
+endgenerate
+
+endmodule
+
+
+module $__XILINX_LUTRAM_SDP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_ABITS = 5;
+parameter WIDTH = 6;
+parameter BITS_USED = 0;
+
+input [WIDTH-1:0] PORT_W_WR_DATA;
+input [OPTION_ABITS-1:0] PORT_W_ADDR;
+input PORT_W_WR_EN;
+input PORT_W_CLK;
+
+output [WIDTH-1:0] PORT_R_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R_ADDR;
+
+function [(1 << OPTION_ABITS)-1:0] init_slice;
+ input integer idx;
+ integer i;
+ for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
+ init_slice[i] = INIT[i * WIDTH + idx];
+endfunction
+
+function [(2 << OPTION_ABITS)-1:0] init_slice2;
+ input integer idx;
+ integer i;
+ for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
+ init_slice2[2 * i +: 2] = INIT[i * WIDTH + idx * 2 +: 2];
+endfunction
+
+generate
+case (OPTION_ABITS)
+5: if (WIDTH == 6)
+ RAM32M
+ #(
+ .INIT_C(init_slice2(0)),
+ .INIT_B(init_slice2(1)),
+ .INIT_A(init_slice2(2)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R_RD_DATA[5:4]),
+ .DOB(PORT_R_RD_DATA[3:2]),
+ .DOC(PORT_R_RD_DATA[1:0]),
+ .DIA(PORT_W_WR_DATA[5:4]),
+ .DIB(PORT_W_WR_DATA[3:2]),
+ .DIC(PORT_W_WR_DATA[1:0]),
+ .ADDRA(PORT_R_ADDR),
+ .ADDRB(PORT_R_ADDR),
+ .ADDRC(PORT_R_ADDR),
+ .ADDRD(PORT_W_ADDR),
+ .WE(PORT_W_WR_EN),
+ .WCLK(PORT_W_CLK),
+ );
+else
+ RAM32M16
+ #(
+ .INIT_G(init_slice2(0)),
+ .INIT_F(init_slice2(1)),
+ .INIT_E(init_slice2(2)),
+ .INIT_D(init_slice2(3)),
+ .INIT_C(init_slice2(4)),
+ .INIT_B(init_slice2(5)),
+ .INIT_A(init_slice2(6)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R_RD_DATA[13:12]),
+ .DOB(PORT_R_RD_DATA[11:10]),
+ .DOC(PORT_R_RD_DATA[9:8]),
+ .DOD(PORT_R_RD_DATA[7:6]),
+ .DOE(PORT_R_RD_DATA[5:4]),
+ .DOF(PORT_R_RD_DATA[3:2]),
+ .DOG(PORT_R_RD_DATA[1:0]),
+ .DIA(PORT_W_WR_DATA[13:12]),
+ .DIB(PORT_W_WR_DATA[11:10]),
+ .DIC(PORT_W_WR_DATA[9:8]),
+ .DID(PORT_W_WR_DATA[7:6]),
+ .DIE(PORT_W_WR_DATA[5:4]),
+ .DIF(PORT_W_WR_DATA[3:2]),
+ .DIG(PORT_W_WR_DATA[1:0]),
+ .ADDRA(PORT_R_ADDR),
+ .ADDRB(PORT_R_ADDR),
+ .ADDRC(PORT_R_ADDR),
+ .ADDRD(PORT_R_ADDR),
+ .ADDRE(PORT_R_ADDR),
+ .ADDRF(PORT_R_ADDR),
+ .ADDRG(PORT_R_ADDR),
+ .ADDRH(PORT_W_ADDR),
+ .WE(PORT_W_WR_EN),
+ .WCLK(PORT_W_CLK),
+ );
+6: if (WIDTH == 3)
+ RAM64M
+ #(
+ .INIT_C(init_slice(0)),
+ .INIT_B(init_slice(1)),
+ .INIT_A(init_slice(2)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R_RD_DATA[2]),
+ .DOB(PORT_R_RD_DATA[1]),
+ .DOC(PORT_R_RD_DATA[0]),
+ .DIA(PORT_W_WR_DATA[2]),
+ .DIB(PORT_W_WR_DATA[1]),
+ .DIC(PORT_W_WR_DATA[0]),
+ .ADDRA(PORT_R_ADDR),
+ .ADDRB(PORT_R_ADDR),
+ .ADDRC(PORT_R_ADDR),
+ .ADDRD(PORT_W_ADDR),
+ .WE(PORT_W_WR_EN),
+ .WCLK(PORT_W_CLK),
+ );
+else
+ RAM64M8
+ #(
+ .INIT_G(init_slice(0)),
+ .INIT_F(init_slice(1)),
+ .INIT_E(init_slice(2)),
+ .INIT_D(init_slice(3)),
+ .INIT_C(init_slice(4)),
+ .INIT_B(init_slice(5)),
+ .INIT_A(init_slice(6)),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .DOA(PORT_R_RD_DATA[6]),
+ .DOB(PORT_R_RD_DATA[5]),
+ .DOC(PORT_R_RD_DATA[4]),
+ .DOD(PORT_R_RD_DATA[3]),
+ .DOE(PORT_R_RD_DATA[2]),
+ .DOF(PORT_R_RD_DATA[1]),
+ .DOG(PORT_R_RD_DATA[0]),
+ .DIA(PORT_W_WR_DATA[6]),
+ .DIB(PORT_W_WR_DATA[5]),
+ .DIC(PORT_W_WR_DATA[4]),
+ .DID(PORT_W_WR_DATA[3]),
+ .DIE(PORT_W_WR_DATA[2]),
+ .DIF(PORT_W_WR_DATA[1]),
+ .DIG(PORT_W_WR_DATA[0]),
+ .ADDRA(PORT_R_ADDR),
+ .ADDRB(PORT_R_ADDR),
+ .ADDRC(PORT_R_ADDR),
+ .ADDRD(PORT_R_ADDR),
+ .ADDRE(PORT_R_ADDR),
+ .ADDRF(PORT_R_ADDR),
+ .ADDRG(PORT_R_ADDR),
+ .ADDRH(PORT_W_ADDR),
+ .WE(PORT_W_WR_EN),
+ .WCLK(PORT_W_CLK),
+ );
+default:
+ $error("invalid OPTION_ABITS/WIDTH combination");
+endcase
+endgenerate
+
+endmodule
+
+
+module $__XILINX_LUTRAM_64X8SW_ (...);
+
+parameter INIT = 0;
+parameter OPTION_ABITS = 9;
+parameter PORT_RW_WR_WIDTH = 1;
+parameter PORT_RW_RD_WIDTH = 8;
+
+output [PORT_RW_RD_WIDTH-1:0] PORT_RW_RD_DATA;
+input [PORT_RW_WR_WIDTH-1:0] PORT_RW_WR_DATA;
+input [OPTION_ABITS-1:0] PORT_RW_ADDR;
+input PORT_RW_WR_EN;
+input PORT_RW_CLK;
+
+function [63:0] init_slice;
+ input integer idx;
+ integer i;
+ for (i = 0; i < 64; i = i + 1)
+ init_slice[i] = INIT[i * 8 + idx];
+endfunction
+
+RAM64X8SW
+#(
+ .INIT_A(init_slice(7)),
+ .INIT_B(init_slice(6)),
+ .INIT_C(init_slice(5)),
+ .INIT_D(init_slice(4)),
+ .INIT_E(init_slice(3)),
+ .INIT_F(init_slice(2)),
+ .INIT_G(init_slice(1)),
+ .INIT_H(init_slice(0)),
+)
+_TECHMAP_REPLACE_
+(
+ .A(PORT_RW_ADDR[8:3]),
+ .WSEL(PORT_RW_ADDR[2:0]),
+ .D(PORT_RW_WR_DATA),
+ .O(PORT_RW_RD_DATA),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+);
+
+endmodule
+
+
+module $__XILINX_LUTRAM_32X16DR8_ (...);
+
+parameter OPTION_ABITS = 6;
+parameter BITS_USED = 0;
+parameter PORT_W_WIDTH = 14;
+parameter PORT_R_WIDTH = 7;
+
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+input [OPTION_ABITS-1:0] PORT_W_ADDR;
+input PORT_W_WR_EN;
+input PORT_W_CLK;
+
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R_ADDR;
+
+RAM32X16DR8 _TECHMAP_REPLACE_
+(
+ .DOA(PORT_R_RD_DATA[6]),
+ .DOB(PORT_R_RD_DATA[5]),
+ .DOC(PORT_R_RD_DATA[4]),
+ .DOD(PORT_R_RD_DATA[3]),
+ .DOE(PORT_R_RD_DATA[2]),
+ .DOF(PORT_R_RD_DATA[1]),
+ .DOG(PORT_R_RD_DATA[0]),
+ .DIA({PORT_W_WR_DATA[13], PORT_W_WR_DATA[6]}),
+ .DIB({PORT_W_WR_DATA[12], PORT_W_WR_DATA[5]}),
+ .DIC({PORT_W_WR_DATA[11], PORT_W_WR_DATA[4]}),
+ .DID({PORT_W_WR_DATA[10], PORT_W_WR_DATA[3]}),
+ .DIE({PORT_W_WR_DATA[9], PORT_W_WR_DATA[2]}),
+ .DIF({PORT_W_WR_DATA[8], PORT_W_WR_DATA[1]}),
+ .DIG({PORT_W_WR_DATA[7], PORT_W_WR_DATA[0]}),
+ .ADDRA(PORT_R_ADDR),
+ .ADDRB(PORT_R_ADDR),
+ .ADDRC(PORT_R_ADDR),
+ .ADDRD(PORT_R_ADDR),
+ .ADDRE(PORT_R_ADDR),
+ .ADDRF(PORT_R_ADDR),
+ .ADDRG(PORT_R_ADDR),
+ .ADDRH(PORT_W_ADDR[5:1]),
+ .WE(PORT_W_WR_EN),
+ .WCLK(PORT_W_CLK),
+);
+
+endmodule
diff --git a/techlibs/xilinx/lutrams_xcu.txt b/techlibs/xilinx/lutrams_xcu.txt
new file mode 100644
index 000000000..8062250bf
--- /dev/null
+++ b/techlibs/xilinx/lutrams_xcu.txt
@@ -0,0 +1,162 @@
+# LUT RAMs for Ultrascale.
+# The corresponding mapping file is lutrams_xc5v_map.v
+
+# Single-port RAMs.
+
+ram distributed $__XILINX_LUTRAM_SP_ {
+ cost 16;
+ widthscale;
+ option "ABITS" 5 {
+ abits 5;
+ widths 16 global;
+ }
+ option "ABITS" 6 {
+ abits 6;
+ widths 8 global;
+ }
+ option "ABITS" 7 {
+ abits 7;
+ widths 4 global;
+ }
+ option "ABITS" 8 {
+ abits 8;
+ widths 2 global;
+ }
+ option "ABITS" 16 {
+ abits 16;
+ widths 1 global;
+ }
+ init any;
+ prune_rom;
+ port arsw "RW" {
+ clock posedge;
+ }
+}
+
+# Dual-port RAMs.
+
+ram distributed $__XILINX_LUTRAM_DP_ {
+ cost 16;
+ widthscale;
+ option "ABITS" 5 {
+ abits 5;
+ widths 8 global;
+ }
+ option "ABITS" 6 {
+ abits 6;
+ widths 4 global;
+ }
+ option "ABITS" 7 {
+ abits 7;
+ widths 2 global;
+ }
+ option "ABITS" 8 {
+ abits 8;
+ widths 1 global;
+ }
+ init any;
+ prune_rom;
+ port arsw "RW" {
+ clock posedge;
+ }
+ port ar "R" {
+ }
+}
+
+# Quad-port RAMs.
+
+ram distributed $__XILINX_LUTRAM_QP_ {
+ cost 16;
+ widthscale;
+ option "ABITS" 5 {
+ abits 5;
+ widths 4 global;
+ }
+ option "ABITS" 6 {
+ abits 6;
+ widths 2 global;
+ }
+ init any;
+ prune_rom;
+ port arsw "RW" {
+ clock posedge;
+ }
+ port ar "R0" "R1" "R2" {
+ }
+}
+
+# Octal-port RAMs.
+
+ram distributed $__XILINX_LUTRAM_OP_ {
+ cost 16;
+ widthscale;
+ option "ABITS" 5 {
+ abits 5;
+ widths 2 global;
+ }
+ option "ABITS" 6 {
+ abits 6;
+ widths 1 global;
+ }
+ init any;
+ prune_rom;
+ port arsw "RW" {
+ clock posedge;
+ }
+ port ar "R0" "R1" "R2" "R3" "R4" "R5" "R6" {
+ }
+}
+
+# Simple dual port RAMs.
+
+ram distributed $__XILINX_LUTRAM_SDP_ {
+ cost 16;
+ widthscale;
+ option "ABITS" 5 {
+ abits 5;
+ widths 14 global;
+ }
+ option "ABITS" 6 {
+ abits 6;
+ widths 7 global;
+ }
+ init any;
+ prune_rom;
+ port sw "W" {
+ clock posedge;
+ }
+ port ar "R" {
+ }
+}
+
+# Wide-read RAM.
+
+ram distributed $__XILINX_LUTRAM_64X8SW_ {
+ cost 16;
+ abits 9;
+ widths 1 2 4 8 per_port;
+ init any;
+ prune_rom;
+ port arsw "RW" {
+ width rd 8 wr 1;
+ clock posedge;
+ }
+}
+
+# Wide-write RAM.
+
+ram distributed $__XILINX_LUTRAM_32X16DR8_ {
+ cost 16;
+ widthscale;
+ abits 6;
+ widths 7 14 per_port;
+ # Yes, no initialization capability.
+ prune_rom;
+ port sw "W" {
+ width 14;
+ clock posedge;
+ }
+ port ar "R" {
+ width 7;
+ }
+}
diff --git a/techlibs/xilinx/lutrams_xcv.txt b/techlibs/xilinx/lutrams_xcv.txt
new file mode 100644
index 000000000..0bf17ae35
--- /dev/null
+++ b/techlibs/xilinx/lutrams_xcv.txt
@@ -0,0 +1,59 @@
+# LUT RAMs for Virtex, Virtex 2, Spartan 3, Virtex 4.
+# The corresponding mapping file is lutrams_xcv_map.v
+
+ram distributed $__XILINX_LUTRAM_SP_ {
+ width 1;
+ option "ABITS" 4 {
+ abits 4;
+ cost 3;
+ }
+ option "ABITS" 5 {
+ abits 5;
+ cost 5;
+ }
+ ifndef IS_VIRTEX {
+ option "ABITS" 6 {
+ abits 6;
+ cost 9;
+ }
+ }
+ ifdef IS_VIRTEX2 {
+ # RAM128X1S
+ option "ABITS" 7 {
+ abits 7;
+ cost 17;
+ }
+ }
+ init no_undef;
+ prune_rom;
+ port arsw "RW" {
+ clock posedge;
+ }
+}
+
+ram distributed $__XILINX_LUTRAM_DP_ {
+ width 1;
+ option "ABITS" 4 {
+ abits 4;
+ cost 5;
+ }
+ ifdef IS_VIRTEX2 {
+ # RAM32X1D
+ option "ABITS" 5 {
+ abits 5;
+ cost 9;
+ }
+ # RAM64X1D
+ option "ABITS" 6 {
+ abits 6;
+ cost 17;
+ }
+ }
+ init no_undef;
+ prune_rom;
+ port arsw "RW" {
+ clock posedge;
+ }
+ port ar "R" {
+ }
+}
diff --git a/techlibs/xilinx/lutrams_xcv_map.v b/techlibs/xilinx/lutrams_xcv_map.v
new file mode 100644
index 000000000..91a96942a
--- /dev/null
+++ b/techlibs/xilinx/lutrams_xcv_map.v
@@ -0,0 +1,177 @@
+// LUT RAMs for Virtex, Virtex 2, Spartan 3, Virtex 4.
+// The corresponding definition file is lutrams_xcv.txt
+
+module $__XILINX_LUTRAM_SP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_ABITS = 4;
+
+output PORT_RW_RD_DATA;
+input PORT_RW_WR_DATA;
+input [OPTION_ABITS-1:0] PORT_RW_ADDR;
+input PORT_RW_WR_EN;
+input PORT_RW_CLK;
+
+generate
+case(OPTION_ABITS)
+4: RAM16X1S
+ #(
+ .INIT(INIT),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .A0(PORT_RW_ADDR[0]),
+ .A1(PORT_RW_ADDR[1]),
+ .A2(PORT_RW_ADDR[2]),
+ .A3(PORT_RW_ADDR[3]),
+ .D(PORT_RW_WR_DATA),
+ .O(PORT_RW_RD_DATA),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+5: RAM32X1S
+ #(
+ .INIT(INIT),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .A0(PORT_RW_ADDR[0]),
+ .A1(PORT_RW_ADDR[1]),
+ .A2(PORT_RW_ADDR[2]),
+ .A3(PORT_RW_ADDR[3]),
+ .A4(PORT_RW_ADDR[4]),
+ .D(PORT_RW_WR_DATA),
+ .O(PORT_RW_RD_DATA),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+6: RAM64X1S
+ #(
+ .INIT(INIT),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .A0(PORT_RW_ADDR[0]),
+ .A1(PORT_RW_ADDR[1]),
+ .A2(PORT_RW_ADDR[2]),
+ .A3(PORT_RW_ADDR[3]),
+ .A4(PORT_RW_ADDR[4]),
+ .A5(PORT_RW_ADDR[5]),
+ .D(PORT_RW_WR_DATA),
+ .O(PORT_RW_RD_DATA),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+7: RAM128X1S
+ #(
+ .INIT(INIT),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .A0(PORT_RW_ADDR[0]),
+ .A1(PORT_RW_ADDR[1]),
+ .A2(PORT_RW_ADDR[2]),
+ .A3(PORT_RW_ADDR[3]),
+ .A4(PORT_RW_ADDR[4]),
+ .A5(PORT_RW_ADDR[5]),
+ .A6(PORT_RW_ADDR[6]),
+ .D(PORT_RW_WR_DATA),
+ .O(PORT_RW_RD_DATA),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ );
+default:
+ $error("invalid OPTION_ABITS");
+endcase
+endgenerate
+
+endmodule
+
+module $__XILINX_LUTRAM_DP_ (...);
+
+parameter INIT = 0;
+parameter OPTION_ABITS = 4;
+
+output PORT_RW_RD_DATA;
+input PORT_RW_WR_DATA;
+input [OPTION_ABITS-1:0] PORT_RW_ADDR;
+input PORT_RW_WR_EN;
+input PORT_RW_CLK;
+
+output PORT_R_RD_DATA;
+input [OPTION_ABITS-1:0] PORT_R_ADDR;
+
+generate
+case (OPTION_ABITS)
+4: RAM16X1D
+ #(
+ .INIT(INIT),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .A0(PORT_RW_ADDR[0]),
+ .A1(PORT_RW_ADDR[1]),
+ .A2(PORT_RW_ADDR[2]),
+ .A3(PORT_RW_ADDR[3]),
+ .D(PORT_RW_WR_DATA),
+ .SPO(PORT_RW_RD_DATA),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ .DPRA0(PORT_R_ADDR[0]),
+ .DPRA1(PORT_R_ADDR[1]),
+ .DPRA2(PORT_R_ADDR[2]),
+ .DPRA3(PORT_R_ADDR[3]),
+ .DPO(PORT_R_RD_DATA),
+ );
+5: RAM32X1D
+ #(
+ .INIT(INIT),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .A0(PORT_RW_ADDR[0]),
+ .A1(PORT_RW_ADDR[1]),
+ .A2(PORT_RW_ADDR[2]),
+ .A3(PORT_RW_ADDR[3]),
+ .A4(PORT_RW_ADDR[4]),
+ .D(PORT_RW_WR_DATA),
+ .SPO(PORT_RW_RD_DATA),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ .DPRA0(PORT_R_ADDR[0]),
+ .DPRA1(PORT_R_ADDR[1]),
+ .DPRA2(PORT_R_ADDR[2]),
+ .DPRA3(PORT_R_ADDR[3]),
+ .DPRA4(PORT_R_ADDR[4]),
+ .DPO(PORT_R_RD_DATA),
+ );
+6: RAM64X1D
+ #(
+ .INIT(INIT),
+ )
+ _TECHMAP_REPLACE_
+ (
+ .A0(PORT_RW_ADDR[0]),
+ .A1(PORT_RW_ADDR[1]),
+ .A2(PORT_RW_ADDR[2]),
+ .A3(PORT_RW_ADDR[3]),
+ .A4(PORT_RW_ADDR[4]),
+ .A5(PORT_RW_ADDR[5]),
+ .D(PORT_RW_WR_DATA),
+ .SPO(PORT_RW_RD_DATA),
+ .WE(PORT_RW_WR_EN),
+ .WCLK(PORT_RW_CLK),
+ .DPRA0(PORT_R_ADDR[0]),
+ .DPRA1(PORT_R_ADDR[1]),
+ .DPRA2(PORT_R_ADDR[2]),
+ .DPRA3(PORT_R_ADDR[3]),
+ .DPRA4(PORT_R_ADDR[4]),
+ .DPRA5(PORT_R_ADDR[5]),
+ .DPO(PORT_R_RD_DATA),
+ );
+default:
+ $error("invalid OPTION_ABITS");
+endcase
+endgenerate
+
+endmodule
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index 6a060c8fe..6214e1411 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -450,56 +450,97 @@ struct SynthXilinxPass : public ScriptPass
run("opt_clean");
}
- if (check_label("map_uram", "(only if '-uram')")) {
+ if (check_label("map_memory")) {
+ std::string params = "";
+ std::string lutrams_map = "+/xilinx/lutrams_<family>_map.v";
+ std::string brams_map = "+/xilinx/brams_<family>_map.v";
if (help_mode) {
- run("memory_bram -rules +/xilinx/{family}_urams.txt");
- run("techmap -map +/xilinx/{family}_urams_map.v");
- } else if (uram) {
- if (family == "xcup") {
- run("memory_bram -rules +/xilinx/xcup_urams.txt");
- run("techmap -map +/xilinx/xcup_urams_map.v");
- } else {
- log_warning("UltraRAM inference not supported for family %s.\n", family.c_str());
- }
- }
- }
-
- if (check_label("map_bram", "(skip if '-nobram')")) {
- if (help_mode) {
- run("memory_bram -rules +/xilinx/{family}_brams.txt");
- run("techmap -map +/xilinx/{family}_brams_map.v");
- } else if (!nobram) {
- 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");
+ params = " [...]";
+ } else {
+ if (family == "xcv" || family == "xcve") {
+ params += " -lib +/xilinx/lutrams_xcv.txt";
+ params += " -D IS_VIRTEX";
+ lutrams_map = "+/xilinx/lutrams_xcv_map.v";
+ params += " -lib +/xilinx/brams_xcv.txt";
+ brams_map = "+/xilinx/brams_xcv_map.v";
+ } else if (family == "xc2v" || family == "xc2vp") {
+ params += " -lib +/xilinx/lutrams_xcv.txt";
+ params += " -D IS_VIRTEX2";
+ lutrams_map = "+/xilinx/lutrams_xcv_map.v";
+ params += " -lib +/xilinx/brams_xc2v.txt";
+ brams_map = "+/xilinx/brams_xc2v_map.v";
+ } else if (family == "xc3s" || family == "xc3se") {
+ params += " -lib +/xilinx/lutrams_xcv.txt";
+ lutrams_map = "+/xilinx/lutrams_xcv_map.v";
+ params += " -lib +/xilinx/brams_xc2v.txt";
+ brams_map = "+/xilinx/brams_xc2v_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");
+ params += " -lib +/xilinx/lutrams_xcv.txt";
+ lutrams_map = "+/xilinx/lutrams_xcv_map.v";
+ params += " -lib +/xilinx/brams_xc2v.txt";
+ params += " -D HAS_BE";
+ brams_map = "+/xilinx/brams_xc2v_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");
- run("techmap -map +/xilinx/xc6s_brams_map.v");
+ params += " -lib +/xilinx/lutrams_xcv.txt";
+ lutrams_map = "+/xilinx/lutrams_xcv_map.v";
+ params += " -lib +/xilinx/brams_xc3sda.txt";
+ brams_map = "+/xilinx/brams_xc3sda_map.v";
} else if (family == "xc6s") {
- run("memory_bram -rules +/xilinx/xc6s_brams.txt");
- run("techmap -map +/xilinx/xc6s_brams_map.v");
+ params += " -logic-cost-rom 0.015625";
+ params += " -lib +/xilinx/lutrams_xc5v.txt";
+ lutrams_map = "+/xilinx/lutrams_xc5v_map.v";
+ params += " -lib +/xilinx/brams_xc3sda.txt";
+ params += " -D IS_SPARTAN6";
+ brams_map = "+/xilinx/brams_xc3sda_map.v";
+ } else if (family == "xc4v") {
+ params += " -lib +/xilinx/lutrams_xcv.txt";
+ lutrams_map = "+/xilinx/lutrams_xcv_map.v";
+ params += " -lib +/xilinx/brams_xc4v.txt";
+ params += " -D HAS_CASCADE";
+ brams_map = "+/xilinx/brams_xc4v_map.v";
+ } else if (family == "xc5v") {
+ params += " -logic-cost-rom 0.015625";
+ params += " -lib +/xilinx/lutrams_xc5v.txt";
+ lutrams_map = "+/xilinx/lutrams_xc5v_map.v";
+ params += " -lib +/xilinx/brams_xc4v.txt";
+ params += " -D HAS_SIZE_36";
+ params += " -D HAS_CASCADE";
+ brams_map = "+/xilinx/brams_xc5v_map.v";
} else if (family == "xc6v" || family == "xc7") {
- run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt");
- run("techmap -map +/xilinx/xc7_brams_map.v");
+ params += " -logic-cost-rom 0.015625";
+ params += " -lib +/xilinx/lutrams_xc5v.txt";
+ lutrams_map = "+/xilinx/lutrams_xc5v_map.v";
+ params += " -lib +/xilinx/brams_xc4v.txt";
+ params += " -D HAS_SIZE_36";
+ params += " -D HAS_CASCADE";
+ params += " -D HAS_CONFLICT_BUG";
+ params += " -D HAS_MIXWIDTH_SDP";
+ brams_map = "+/xilinx/brams_xc6v_map.v";
} else if (family == "xcu" || family == "xcup") {
- run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt");
- run("techmap -map +/xilinx/xcu_brams_map.v");
- } else {
- log_warning("Block RAM inference not yet supported for family %s.\n", family.c_str());
+ params += " -logic-cost-rom 0.015625";
+ params += " -lib +/xilinx/lutrams_xcu.txt";
+ lutrams_map = "+/xilinx/lutrams_xc5v_map.v";
+ params += " -lib +/xilinx/brams_xc4v.txt";
+ params += " -D HAS_SIZE_36";
+ params += " -D HAS_MIXWIDTH_SDP";
+ params += " -D HAS_ADDRCE";
+ brams_map = "+/xilinx/brams_xcu_map.v";
+ if (family == "xcup") {
+ params += " -lib +/xilinx/urams.txt";
+ }
}
- }
- }
-
- if (check_label("map_lutram", "(skip if '-nolutram')")) {
- if (!nolutram || help_mode) {
- run("memory_bram -rules +/xilinx/lut" + lut_size_s + "_lutrams.txt");
- run("techmap -map +/xilinx/lutrams_map.v");
+ if (nolutram)
+ params += " -no-auto-distributed";
+ if (nobram)
+ params += " -no-auto-block";
+ if (!uram)
+ params += " -no-auto-huge";
+ }
+ run("memory_libmap" + params);
+ run("techmap -map " + lutrams_map);
+ run("techmap -map " + brams_map);
+ if (family == "xcup") {
+ run("techmap -map +/xilinx/urams_map.v");
}
}
diff --git a/techlibs/xilinx/urams.txt b/techlibs/xilinx/urams.txt
new file mode 100644
index 000000000..6a5920468
--- /dev/null
+++ b/techlibs/xilinx/urams.txt
@@ -0,0 +1,37 @@
+ram huge $__XILINX_URAM_ {
+ abits 12;
+ width 72;
+ cost 1024;
+ option "BYTEWIDTH" 8 byte 8;
+ option "BYTEWIDTH" 9 byte 9;
+ init zero;
+ port srsw "A" {
+ clock anyedge "C";
+ clken;
+ rdwr no_change;
+ rdinit zero;
+ portoption "RST_MODE" "SYNC" {
+ rdsrst zero ungated;
+ }
+ portoption "RST_MODE" "ASYNC" {
+ rdarst zero;
+ }
+ wrtrans all new;
+ wrbe_separate;
+ }
+ port srsw "B" {
+ clock anyedge "C";
+ clken;
+ rdwr no_change;
+ rdinit zero;
+ portoption "RST_MODE" "SYNC" {
+ rdsrst zero ungated;
+ }
+ portoption "RST_MODE" "ASYNC" {
+ rdarst zero;
+ }
+ wrtrans all old;
+ wrprio "A";
+ wrbe_separate;
+ }
+}
diff --git a/techlibs/xilinx/urams_map.v b/techlibs/xilinx/urams_map.v
new file mode 100644
index 000000000..3ecbe704e
--- /dev/null
+++ b/techlibs/xilinx/urams_map.v
@@ -0,0 +1,152 @@
+module $__XILINX_URAM_ (...);
+ parameter OPTION_BYTEWIDTH = 8;
+ localparam WR_BE_WIDTH = 72 / OPTION_BYTEWIDTH;
+
+ parameter CLK_C_POL = 1;
+ parameter PORT_A_CLK_POL = 1;
+ parameter PORT_A_OPTION_RST_MODE = "SYNC";
+ parameter PORT_B_CLK_POL = 1;
+ parameter PORT_B_OPTION_RST_MODE = "SYNC";
+
+ input CLK_C;
+
+ input PORT_A_CLK;
+ input PORT_A_CLK_EN;
+ input PORT_A_RD_SRST;
+ input PORT_A_RD_ARST;
+ input PORT_A_WR_EN;
+ input [WR_BE_WIDTH-1:0] PORT_A_WR_BE;
+ input [11:0] PORT_A_ADDR;
+ input [71:0] PORT_A_WR_DATA;
+ output [71:0] PORT_A_RD_DATA;
+
+ input PORT_B_CLK;
+ input PORT_B_CLK_EN;
+ input PORT_B_RD_SRST;
+ input PORT_B_RD_ARST;
+ input PORT_B_WR_EN;
+ input [WR_BE_WIDTH-1:0] PORT_B_WR_BE;
+ input [11:0] PORT_B_ADDR;
+ input [71:0] PORT_B_WR_DATA;
+ output [71:0] PORT_B_RD_DATA;
+
+ wire [71:0] DIN_A, DIN_B, DOUT_A, DOUT_B;
+
+ generate
+ if (OPTION_BYTEWIDTH == 8) begin
+ assign DIN_A = PORT_A_WR_DATA;
+ assign DIN_B = PORT_B_WR_DATA;
+ assign PORT_A_RD_DATA = DOUT_A;
+ assign PORT_B_RD_DATA = DOUT_B;
+ end else begin
+ assign DIN_A = {
+ PORT_A_WR_DATA[71],
+ PORT_A_WR_DATA[62],
+ PORT_A_WR_DATA[53],
+ PORT_A_WR_DATA[44],
+ PORT_A_WR_DATA[35],
+ PORT_A_WR_DATA[26],
+ PORT_A_WR_DATA[17],
+ PORT_A_WR_DATA[8],
+ PORT_A_WR_DATA[70:63],
+ PORT_A_WR_DATA[61:54],
+ PORT_A_WR_DATA[52:45],
+ PORT_A_WR_DATA[43:36],
+ PORT_A_WR_DATA[34:27],
+ PORT_A_WR_DATA[25:18],
+ PORT_A_WR_DATA[16:9],
+ PORT_A_WR_DATA[7:0]
+ };
+ assign DIN_B = {
+ PORT_B_WR_DATA[71],
+ PORT_B_WR_DATA[62],
+ PORT_B_WR_DATA[53],
+ PORT_B_WR_DATA[44],
+ PORT_B_WR_DATA[35],
+ PORT_B_WR_DATA[26],
+ PORT_B_WR_DATA[17],
+ PORT_B_WR_DATA[8],
+ PORT_B_WR_DATA[70:63],
+ PORT_B_WR_DATA[61:54],
+ PORT_B_WR_DATA[52:45],
+ PORT_B_WR_DATA[43:36],
+ PORT_B_WR_DATA[34:27],
+ PORT_B_WR_DATA[25:18],
+ PORT_B_WR_DATA[16:9],
+ PORT_B_WR_DATA[7:0]
+ };
+ assign PORT_A_RD_DATA = {
+ DOUT_A[71],
+ DOUT_A[63:56],
+ DOUT_A[70],
+ DOUT_A[55:48],
+ DOUT_A[69],
+ DOUT_A[47:40],
+ DOUT_A[68],
+ DOUT_A[39:32],
+ DOUT_A[67],
+ DOUT_A[31:24],
+ DOUT_A[66],
+ DOUT_A[23:16],
+ DOUT_A[65],
+ DOUT_A[15:8],
+ DOUT_A[64],
+ DOUT_A[7:0]
+ };
+ assign PORT_B_RD_DATA = {
+ DOUT_B[71],
+ DOUT_B[63:56],
+ DOUT_B[70],
+ DOUT_B[55:48],
+ DOUT_B[69],
+ DOUT_B[47:40],
+ DOUT_B[68],
+ DOUT_B[39:32],
+ DOUT_B[67],
+ DOUT_B[31:24],
+ DOUT_B[66],
+ DOUT_B[23:16],
+ DOUT_B[65],
+ DOUT_B[15:8],
+ DOUT_B[64],
+ DOUT_B[7:0]
+ };
+ end
+ endgenerate
+
+ URAM288 #(
+ .BWE_MODE_A(OPTION_BYTEWIDTH == 8 ? "PARITY_INDEPENDENT" : "PARITY_INTERLEAVED"),
+ .BWE_MODE_B(OPTION_BYTEWIDTH == 8 ? "PARITY_INDEPENDENT" : "PARITY_INTERLEAVED"),
+ .EN_AUTO_SLEEP_MODE("FALSE"),
+ .IREG_PRE_A("FALSE"),
+ .IREG_PRE_B("FALSE"),
+ .IS_CLK_INVERTED(!CLK_C_POL),
+ .OREG_A("FALSE"),
+ .OREG_B("FALSE"),
+ .RST_MODE_A(PORT_A_OPTION_RST_MODE),
+ .RST_MODE_B(PORT_B_OPTION_RST_MODE),
+ ) _TECHMAP_REPLACE_ (
+ .ADDR_A({11'b0, PORT_A_ADDR}),
+ .BWE_A(PORT_A_WR_BE),
+ .EN_A(PORT_A_CLK_EN),
+ .RDB_WR_A(PORT_A_WR_EN),
+ .INJECT_DBITERR_A(1'b0),
+ .INJECT_SBITERR_A(1'b0),
+ .RST_A(PORT_A_OPTION_RST_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST),
+ .DIN_A(DIN_A),
+ .DOUT_A(DOUT_A),
+
+ .ADDR_B({11'b0, PORT_B_ADDR}),
+ .BWE_B(PORT_B_WR_BE),
+ .EN_B(PORT_B_CLK_EN),
+ .RDB_WR_B(PORT_B_WR_EN),
+ .INJECT_DBITERR_B(1'b0),
+ .INJECT_SBITERR_B(1'b0),
+ .RST_B(PORT_B_OPTION_RST_MODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST),
+ .DIN_B(DIN_B),
+ .DOUT_B(DOUT_B),
+
+ .CLK(CLK_C),
+ .SLEEP(1'b0)
+ );
+endmodule
diff --git a/techlibs/xilinx/xc2v_brams.txt b/techlibs/xilinx/xc2v_brams.txt
deleted file mode 100644
index ac8cfb552..000000000
--- a/techlibs/xilinx/xc2v_brams.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-# 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
deleted file mode 100644
index dc698f956..000000000
--- a/techlibs/xilinx/xc2v_brams_map.v
+++ /dev/null
@@ -1,266 +0,0 @@
-// 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
deleted file mode 100644
index 22a62bd2c..000000000
--- a/techlibs/xilinx/xc3sa_brams.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-# 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
deleted file mode 100644
index 12c68ffd5..000000000
--- a/techlibs/xilinx/xc3sda_brams.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-# Spartan 3A DSP block RAM rules.
-
-bram $__XILINX_RAMB16BWER_TDP
- 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 4 @a9d36
- enable 1 2 @a10d18
- enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-match $__XILINX_RAMB16BWER_TDP
- min bits 4096
- min efficiency 5
- shuffle_enable B
- make_transp
-endmatch
diff --git a/techlibs/xilinx/xc6s_brams.txt b/techlibs/xilinx/xc6s_brams.txt
deleted file mode 100644
index 6457097db..000000000
--- a/techlibs/xilinx/xc6s_brams.txt
+++ /dev/null
@@ -1,85 +0,0 @@
-# Spartan 6 block RAM rules.
-
-bram $__XILINX_RAMB8BWER_SDP
- init 1
- abits 8
- dbits 36
- groups 2
- ports 1 1
- wrmode 0 1
- enable 1 4
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-bram $__XILINX_RAMB16BWER_TDP
- 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 4 @a9d36
- enable 1 2 @a10d18
- enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-bram $__XILINX_RAMB8BWER_TDP
- init 1
- abits 9 @a9d18
- dbits 18 @a9d18
- abits 10 @a10d9
- dbits 9 @a10d9
- abits 11 @a11d4
- dbits 4 @a11d4
- abits 12 @a12d2
- dbits 2 @a12d2
- abits 13 @a13d1
- dbits 1 @a13d1
- groups 2
- ports 1 1
- wrmode 0 1
- enable 1 2 @a9d18
- enable 1 1 @a10d9 @a11d4 @a12d2 @a13d1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-match $__XILINX_RAMB8BWER_SDP
- min bits 4096
- min efficiency 5
- shuffle_enable B
- make_transp
- or_next_if_better
-endmatch
-
-match $__XILINX_RAMB16BWER_TDP
- min bits 4096
- min efficiency 5
- shuffle_enable B
- make_transp
- or_next_if_better
-endmatch
-
-match $__XILINX_RAMB8BWER_TDP
- min bits 4096
- min efficiency 5
- shuffle_enable B
- make_transp
-endmatch
-
diff --git a/techlibs/xilinx/xc6s_brams_map.v b/techlibs/xilinx/xc6s_brams_map.v
deleted file mode 100644
index 9577eebe4..000000000
--- a/techlibs/xilinx/xc6s_brams_map.v
+++ /dev/null
@@ -1,258 +0,0 @@
-// 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;
- parameter [9215:0] INIT = 9216'bx;
-
- input CLK2;
- input CLK3;
-
- input [7:0] A1ADDR;
- output [35:0] A1DATA;
- input A1EN;
-
- input [7:0] B1ADDR;
- input [35:0] B1DATA;
- input [3:0] B1EN;
-
- wire [12:0] A1ADDR_13 = {A1ADDR, 5'b0};
- wire [12:0] B1ADDR_13 = {B1ADDR, 5'b0};
-
- wire [3:0] DIP, DOP;
- wire [31:0] DI, DO;
-
- assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
- assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
-
- RAMB8BWER #(
- .RAM_MODE("SDP"),
- .DATA_WIDTH_A(36),
- .DATA_WIDTH_B(36),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- `include "brams_init_9.vh"
- ) _TECHMAP_REPLACE_ (
- .DOBDO(DO[31:16]),
- .DOADO(DO[15:0]),
- .DOPBDOP(DOP[3:2]),
- .DOPADOP(DOP[1:0]),
- .DIBDI(DI[31:16]),
- .DIADI(DI[15:0]),
- .DIPBDIP(DIP[3:2]),
- .DIPADIP(DIP[1:0]),
- .WEBWEU(B1EN[3:2]),
- .WEAWEL(B1EN[1:0]),
-
- .ADDRAWRADDR(B1ADDR_13),
- .CLKAWRCLK(CLK3 ^ !CLKPOL3),
- .ENAWREN(|1),
- .REGCEA(|0),
- .RSTA(|0),
-
- .ADDRBRDADDR(A1ADDR_13),
- .CLKBRDCLK(CLK2 ^ !CLKPOL2),
- .ENBRDEN(A1EN),
- .REGCEBREGCE(|1),
- .RSTBRST(|0)
- );
-endmodule
-
-// ------------------------------------------------------------------------
-
-module \$__XILINX_RAMB16BWER_TDP (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;
-
- wire [13:0] A1ADDR_14 = A1ADDR << (14 - CFG_ABITS);
- wire [13:0] B1ADDR_14 = B1ADDR << (14 - CFG_ABITS);
- wire [3:0] B1EN_4 = {4{B1EN}};
-
- wire [3:0] DIP, DOP;
- wire [31:0] DI, DO;
-
- wire [31:0] DOB;
- wire [3:0] DOPB;
-
- assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
- assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
-
- generate if (CFG_DBITS > 8) begin
- RAMB16BWER #(
- .DATA_WIDTH_A(CFG_DBITS),
- .DATA_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- `include "brams_init_18.vh"
- ) _TECHMAP_REPLACE_ (
- .DIA(32'd0),
- .DIPA(4'd0),
- .DOA(DO[31:0]),
- .DOPA(DOP[3:0]),
- .ADDRA(A1ADDR_14),
- .CLKA(CLK2 ^ !CLKPOL2),
- .ENA(A1EN),
- .REGCEA(|1),
- .RSTA(|0),
- .WEA(4'b0),
-
- .DIB(DI),
- .DIPB(DIP),
- .DOB(DOB),
- .DOPB(DOPB),
- .ADDRB(B1ADDR_14),
- .CLKB(CLK3 ^ !CLKPOL3),
- .ENB(|1),
- .REGCEB(|0),
- .RSTB(|0),
- .WEB(B1EN_4)
- );
- end else begin
- RAMB16BWER #(
- .DATA_WIDTH_A(CFG_DBITS),
- .DATA_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- `include "brams_init_16.vh"
- ) _TECHMAP_REPLACE_ (
- .DIA(32'd0),
- .DIPA(4'd0),
- .DOA(DO[31:0]),
- .DOPA(DOP[3:0]),
- .ADDRA(A1ADDR_14),
- .CLKA(CLK2 ^ !CLKPOL2),
- .ENA(A1EN),
- .REGCEA(|1),
- .RSTA(|0),
- .WEA(4'b0),
-
- .DIB(DI),
- .DIPB(DIP),
- .DOB(DOB),
- .DOPB(DOPB),
- .ADDRB(B1ADDR_14),
- .CLKB(CLK3 ^ !CLKPOL3),
- .ENB(|1),
- .REGCEB(|0),
- .RSTB(|0),
- .WEB(B1EN_4)
- );
- end endgenerate
-endmodule
-
-// ------------------------------------------------------------------------
-
-module \$__XILINX_RAMB8BWER_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 9;
- parameter CFG_DBITS = 18;
- parameter CFG_ENABLE_B = 2;
-
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
- parameter [9215:0] INIT = 9216'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;
-
- wire [12:0] A1ADDR_13 = A1ADDR << (13 - CFG_ABITS);
- wire [12:0] B1ADDR_13 = B1ADDR << (13 - CFG_ABITS);
- wire [1:0] B1EN_2 = {2{B1EN}};
-
- wire [1:0] DIP, DOP;
- wire [15:0] DI, DO;
-
- wire [15:0] DOBDO;
- wire [1:0] DOPBDOP;
-
- assign A1DATA = { DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
- assign { DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
-
- generate if (CFG_DBITS > 8) begin
- RAMB8BWER #(
- .RAM_MODE("TDP"),
- .DATA_WIDTH_A(CFG_DBITS),
- .DATA_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- `include "brams_init_9.vh"
- ) _TECHMAP_REPLACE_ (
- .DIADI(16'b0),
- .DIPADIP(2'b0),
- .DOADO(DO),
- .DOPADOP(DOP),
- .ADDRAWRADDR(A1ADDR_13),
- .CLKAWRCLK(CLK2 ^ !CLKPOL2),
- .ENAWREN(A1EN),
- .REGCEA(|1),
- .RSTA(|0),
- .WEAWEL(2'b0),
-
- .DIBDI(DI),
- .DIPBDIP(DIP),
- .DOBDO(DOBDO),
- .DOPBDOP(DOPBDOP),
- .ADDRBRDADDR(B1ADDR_13),
- .CLKBRDCLK(CLK3 ^ !CLKPOL3),
- .ENBRDEN(|1),
- .REGCEBREGCE(|0),
- .RSTBRST(|0),
- .WEBWEU(B1EN_2)
- );
- end else begin
- RAMB8BWER #(
- .RAM_MODE("TDP"),
- .DATA_WIDTH_A(CFG_DBITS),
- .DATA_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- `include "brams_init_8.vh"
- ) _TECHMAP_REPLACE_ (
- .DIADI(16'b0),
- .DIPADIP(2'b0),
- .DOADO(DO),
- .DOPADOP(DOP),
- .ADDRAWRADDR(A1ADDR_13),
- .CLKAWRCLK(CLK2 ^ !CLKPOL2),
- .ENAWREN(A1EN),
- .REGCEA(|1),
- .RSTA(|0),
- .WEAWEL(2'b0),
-
- .DIBDI(DI),
- .DIPBDIP(DIP),
- .DOBDO(DOBDO),
- .DOPBDOP(DOPBDOP),
- .ADDRBRDADDR(B1ADDR_13),
- .CLKBRDCLK(CLK3 ^ !CLKPOL3),
- .ENBRDEN(|1),
- .REGCEBREGCE(|0),
- .RSTBRST(|0),
- .WEBWEU(B1EN_2)
- );
- end endgenerate
-endmodule
diff --git a/techlibs/xilinx/xc7_brams_map.v b/techlibs/xilinx/xc7_brams_map.v
deleted file mode 100644
index 982a5a07e..000000000
--- a/techlibs/xilinx/xc7_brams_map.v
+++ /dev/null
@@ -1,363 +0,0 @@
-// 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;
- parameter [36863:0] INIT = 36864'bx;
-
- input CLK2;
- input CLK3;
-
- input [8:0] A1ADDR;
- output [71:0] A1DATA;
- input A1EN;
-
- input [8:0] B1ADDR;
- input [71:0] B1DATA;
- input [7:0] B1EN;
-
- // Set highest address bit to 1, as stated in UG473 (v1.14) July 3, 2019
- wire [15:0] A1ADDR_16 = {1'b1, A1ADDR, 6'b0};
- wire [15:0] B1ADDR_16 = {1'b1, B1ADDR, 6'b0};
-
- wire [7:0] DIP, DOP;
- wire [63:0] DI, DO;
-
- assign A1DATA = { DOP[7], DO[63:56], DOP[6], DO[55:48], DOP[5], DO[47:40], DOP[4], DO[39:32],
- DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
-
- assign { DIP[7], DI[63:56], DIP[6], DI[55:48], DIP[5], DI[47:40], DIP[4], DI[39:32],
- DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
-
- RAMB36E1 #(
- .RAM_MODE("SDP"),
- .READ_WIDTH_A(72),
- .WRITE_WIDTH_B(72),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_36.vh"
- .SIM_DEVICE("7SERIES")
- ) _TECHMAP_REPLACE_ (
- .DOBDO(DO[63:32]),
- .DOADO(DO[31:0]),
- .DOPBDOP(DOP[7:4]),
- .DOPADOP(DOP[3:0]),
- .DIBDI(DI[63:32]),
- .DIADI(DI[31:0]),
- .DIPBDIP(DIP[7:4]),
- .DIPADIP(DIP[3:0]),
-
- .ADDRARDADDR(A1ADDR_16),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(4'b0),
-
- .ADDRBWRADDR(B1ADDR_16),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN)
- );
-endmodule
-
-// ------------------------------------------------------------------------
-
-module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
- parameter [18431:0] INIT = 18432'bx;
-
- input CLK2;
- input CLK3;
-
- input [8:0] A1ADDR;
- output [35:0] A1DATA;
- input A1EN;
-
- input [8:0] B1ADDR;
- input [35:0] B1DATA;
- input [3:0] B1EN;
-
- wire [13:0] A1ADDR_14 = {A1ADDR, 5'b0};
- wire [13:0] B1ADDR_14 = {B1ADDR, 5'b0};
-
- wire [3:0] DIP, DOP;
- wire [31:0] DI, DO;
-
- assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
- assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
-
- RAMB18E1 #(
- .RAM_MODE("SDP"),
- .READ_WIDTH_A(36),
- .WRITE_WIDTH_B(36),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_18.vh"
- .SIM_DEVICE("7SERIES")
- ) _TECHMAP_REPLACE_ (
- .DOBDO(DO[31:16]),
- .DOADO(DO[15:0]),
- .DOPBDOP(DOP[3:2]),
- .DOPADOP(DOP[1:0]),
- .DIBDI(DI[31:16]),
- .DIADI(DI[15:0]),
- .DIPBDIP(DIP[3:2]),
- .DIPADIP(DIP[1:0]),
-
- .ADDRARDADDR(A1ADDR_14),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(2'b0),
-
- .ADDRBWRADDR(B1ADDR_14),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN)
- );
-endmodule
-
-// ------------------------------------------------------------------------
-
-module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 10;
- parameter CFG_DBITS = 36;
- parameter CFG_ENABLE_B = 4;
-
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
- parameter [36863:0] INIT = 36864'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;
-
- // Set highest address bit to 1, as stated in UG473 (v1.14) July 3, 2019
- wire [15:0] A1ADDR_16 = {1'b1, A1ADDR} << (15 - CFG_ABITS);
- wire [15:0] B1ADDR_16 = {1'b1, B1ADDR} << (15 - CFG_ABITS);
- wire [7:0] B1EN_8 = B1EN;
-
- wire [3:0] DIP, DOP;
- wire [31:0] DI, DO;
-
- wire [31:0] DOBDO;
- wire [3:0] DOPBDOP;
-
- assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
- assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
-
- generate if (CFG_DBITS > 8) begin
- RAMB36E1 #(
- .RAM_MODE("TDP"),
- .READ_WIDTH_A(CFG_DBITS),
- .READ_WIDTH_B(CFG_DBITS),
- .WRITE_WIDTH_A(CFG_DBITS),
- .WRITE_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_36.vh"
- .SIM_DEVICE("7SERIES")
- ) _TECHMAP_REPLACE_ (
- .DIADI(32'd0),
- .DIPADIP(4'd0),
- .DOADO(DO[31:0]),
- .DOPADOP(DOP[3:0]),
- .ADDRARDADDR(A1ADDR_16),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(4'b0),
-
- .DIBDI(DI),
- .DIPBDIP(DIP),
- .DOBDO(DOBDO),
- .DOPBDOP(DOPBDOP),
- .ADDRBWRADDR(B1ADDR_16),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN_8)
- );
- end else begin
- RAMB36E1 #(
- .RAM_MODE("TDP"),
- .READ_WIDTH_A(CFG_DBITS),
- .READ_WIDTH_B(CFG_DBITS),
- .WRITE_WIDTH_A(CFG_DBITS),
- .WRITE_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_32.vh"
- .SIM_DEVICE("7SERIES")
- ) _TECHMAP_REPLACE_ (
- .DIADI(32'd0),
- .DIPADIP(4'd0),
- .DOADO(DO[31:0]),
- .DOPADOP(DOP[3:0]),
- .ADDRARDADDR(A1ADDR_16),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(4'b0),
-
- .DIBDI(DI),
- .DIPBDIP(DIP),
- .DOBDO(DOBDO),
- .DOPBDOP(DOPBDOP),
- .ADDRBWRADDR(B1ADDR_16),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN_8)
- );
- end endgenerate
-endmodule
-
-// ------------------------------------------------------------------------
-
-module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 10;
- parameter CFG_DBITS = 18;
- parameter CFG_ENABLE_B = 2;
-
- 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;
-
- wire [13:0] A1ADDR_14 = A1ADDR << (14 - CFG_ABITS);
- wire [13:0] B1ADDR_14 = B1ADDR << (14 - CFG_ABITS);
- wire [3:0] B1EN_4 = B1EN;
-
- wire [1:0] DIP, DOP;
- wire [15:0] DI, DO;
-
- wire [15:0] DOBDO;
- wire [1:0] DOPBDOP;
-
- assign A1DATA = { DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
- assign { DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
-
- generate if (CFG_DBITS > 8) begin
- RAMB18E1 #(
- .RAM_MODE("TDP"),
- .READ_WIDTH_A(CFG_DBITS),
- .READ_WIDTH_B(CFG_DBITS),
- .WRITE_WIDTH_A(CFG_DBITS),
- .WRITE_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_18.vh"
- .SIM_DEVICE("7SERIES")
- ) _TECHMAP_REPLACE_ (
- .DIADI(16'b0),
- .DIPADIP(2'b0),
- .DOADO(DO),
- .DOPADOP(DOP),
- .ADDRARDADDR(A1ADDR_14),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(2'b0),
-
- .DIBDI(DI),
- .DIPBDIP(DIP),
- .DOBDO(DOBDO),
- .DOPBDOP(DOPBDOP),
- .ADDRBWRADDR(B1ADDR_14),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN_4)
- );
- end else begin
- RAMB18E1 #(
- .RAM_MODE("TDP"),
- .READ_WIDTH_A(CFG_DBITS),
- .READ_WIDTH_B(CFG_DBITS),
- .WRITE_WIDTH_A(CFG_DBITS),
- .WRITE_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_16.vh"
- .SIM_DEVICE("7SERIES")
- ) _TECHMAP_REPLACE_ (
- .DIADI(16'b0),
- .DIPADIP(2'b0),
- .DOADO(DO),
- .DOPADOP(DOP),
- .ADDRARDADDR(A1ADDR_14),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(2'b0),
-
- .DIBDI(DI),
- .DIPBDIP(DIP),
- .DOBDO(DOBDO),
- .DOPBDOP(DOPBDOP),
- .ADDRBWRADDR(B1ADDR_14),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN_4)
- );
- end endgenerate
-endmodule
-
diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt
deleted file mode 100644
index 650367abf..000000000
--- a/techlibs/xilinx/xc7_xcu_brams.txt
+++ /dev/null
@@ -1,151 +0,0 @@
-# Virtex 6, Series 7, Ultrascale, Ultrascale Plus block RAM rules.
-
-bram $__XILINX_RAMB36_SDP
- init 1
- abits 9
- dbits 72
- groups 2
- ports 1 1
- wrmode 0 1
- enable 1 8
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-bram $__XILINX_RAMB18_SDP
- init 1
- abits 9
- dbits 36
- groups 2
- ports 1 1
- wrmode 0 1
- enable 1 4
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-bram $__XILINX_RAMB36_TDP
- init 1
- abits 10 @a10d36
- dbits 36 @a10d36
- abits 11 @a11d18
- dbits 18 @a11d18
- abits 12 @a12d9
- dbits 9 @a12d9
- abits 13 @a13d4
- dbits 4 @a13d4
- abits 14 @a14d2
- dbits 2 @a14d2
- abits 15 @a15d1
- dbits 1 @a15d1
- groups 2
- ports 1 1
- wrmode 0 1
- enable 1 4 @a10d36
- enable 1 2 @a11d18
- enable 1 1 @a12d9 @a13d4 @a14d2 @a15d1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-bram $__XILINX_RAMB18_TDP
- init 1
- 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 2 @a10d18
- enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
- transp 0 0
- clocks 2 3
- clkpol 2 3
-endbram
-
-# The "min bits" value were taken from:
-# [[CITE]] 7 Series FPGAs Memory Resources User Guide (UG473),
-# v1.14 ed., p 29-30, July, 2019.
-# https://www.xilinx.com/support/documentation/user_guides/ug473_7Series_Memory_Resources.pdf
-
-match $__XILINX_RAMB36_SDP
- attribute !ram_style
- attribute !logic_block
- min bits 1024
- min efficiency 5
- shuffle_enable B
- make_transp
- or_next_if_better
-endmatch
-
-match $__XILINX_RAMB36_SDP
- attribute ram_style=block ram_block
- attribute !logic_block
- shuffle_enable B
- make_transp
- or_next_if_better
-endmatch
-
-match $__XILINX_RAMB18_SDP
- attribute !ram_style
- attribute !logic_block
- min bits 1024
- min efficiency 5
- shuffle_enable B
- make_transp
- or_next_if_better
-endmatch
-
-match $__XILINX_RAMB18_SDP
- attribute ram_style=block ram_block
- attribute !logic_block
- shuffle_enable B
- make_transp
- or_next_if_better
-endmatch
-
-match $__XILINX_RAMB36_TDP
- attribute !ram_style
- attribute !logic_block
- min bits 1024
- min efficiency 5
- shuffle_enable B
- make_transp
- or_next_if_better
-endmatch
-
-match $__XILINX_RAMB36_TDP
- attribute ram_style=block ram_block
- attribute !logic_block
- shuffle_enable B
- make_transp
- or_next_if_better
-endmatch
-
-match $__XILINX_RAMB18_TDP
- attribute !ram_style
- attribute !logic_block
- min bits 1024
- min efficiency 5
- shuffle_enable B
- make_transp
- or_next_if_better
-endmatch
-
-match $__XILINX_RAMB18_TDP
- attribute ram_style=block ram_block
- attribute !logic_block
- shuffle_enable B
- make_transp
-endmatch
-
diff --git a/techlibs/xilinx/xcu_brams_map.v b/techlibs/xilinx/xcu_brams_map.v
deleted file mode 100644
index b6719b2dd..000000000
--- a/techlibs/xilinx/xcu_brams_map.v
+++ /dev/null
@@ -1,386 +0,0 @@
-// 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;
- parameter [36863:0] INIT = 36864'bx;
-
- input CLK2;
- input CLK3;
-
- input [8:0] A1ADDR;
- output [71:0] A1DATA;
- input A1EN;
-
- input [8:0] B1ADDR;
- input [71:0] B1DATA;
- input [7:0] B1EN;
-
- wire [15:0] A1ADDR_16 = {A1ADDR, 6'b0};
- wire [15:0] B1ADDR_16 = {B1ADDR, 6'b0};
-
- wire [7:0] DIP, DOP;
- wire [63:0] DI, DO;
-
- assign A1DATA = { DOP[7], DO[63:56], DOP[6], DO[55:48], DOP[5], DO[47:40], DOP[4], DO[39:32],
- DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
-
- assign { DIP[7], DI[63:56], DIP[6], DI[55:48], DIP[5], DI[47:40], DIP[4], DI[39:32],
- DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
-
- RAMB36E2 #(
- .READ_WIDTH_A(72),
- .WRITE_WIDTH_B(72),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .DOA_REG(0),
- .DOB_REG(0),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_36.vh"
- ) _TECHMAP_REPLACE_ (
- .DOUTBDOUT(DO[63:32]),
- .DOUTADOUT(DO[31:0]),
- .DOUTPBDOUTP(DOP[7:4]),
- .DOUTPADOUTP(DOP[3:0]),
- .DINBDIN(DI[63:32]),
- .DINADIN(DI[31:0]),
- .DINPBDINP(DIP[7:4]),
- .DINPADINP(DIP[3:0]),
-
- .ADDRARDADDR(A1ADDR_16),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .ADDRENA(|1),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(4'b0),
-
- .ADDRBWRADDR(B1ADDR_16),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .ADDRENB(|1),
- .REGCEB(|1),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN),
-
- .SLEEP(|0)
- );
-endmodule
-
-// ------------------------------------------------------------------------
-
-module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
- parameter [18431:0] INIT = 18432'bx;
-
- input CLK2;
- input CLK3;
-
- input [8:0] A1ADDR;
- output [35:0] A1DATA;
- input A1EN;
-
- input [8:0] B1ADDR;
- input [35:0] B1DATA;
- input [3:0] B1EN;
-
- wire [13:0] A1ADDR_14 = {A1ADDR, 5'b0};
- wire [13:0] B1ADDR_14 = {B1ADDR, 5'b0};
-
- wire [3:0] DIP, DOP;
- wire [31:0] DI, DO;
-
- assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
- assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
-
- RAMB18E2 #(
- .READ_WIDTH_A(36),
- .WRITE_WIDTH_B(36),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .DOA_REG(0),
- .DOB_REG(0),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_18.vh"
- ) _TECHMAP_REPLACE_ (
- .DOUTBDOUT(DO[31:16]),
- .DOUTADOUT(DO[15:0]),
- .DOUTPBDOUTP(DOP[3:2]),
- .DOUTPADOUTP(DOP[1:0]),
- .DINBDIN(DI[31:16]),
- .DINADIN(DI[15:0]),
- .DINPBDINP(DIP[3:2]),
- .DINPADINP(DIP[1:0]),
-
- .ADDRARDADDR(A1ADDR_14),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .ADDRENA(|1),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(2'b0),
-
- .ADDRBWRADDR(B1ADDR_14),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .ADDRENB(|1),
- .REGCEB(|1),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN),
-
- .SLEEP(|0)
- );
-endmodule
-
-// ------------------------------------------------------------------------
-
-module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 10;
- parameter CFG_DBITS = 36;
- parameter CFG_ENABLE_B = 4;
-
- parameter CLKPOL2 = 1;
- parameter CLKPOL3 = 1;
- parameter [36863:0] INIT = 36864'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;
-
- wire [15:0] A1ADDR_16 = A1ADDR << (15 - CFG_ABITS);
- wire [15:0] B1ADDR_16 = B1ADDR << (15 - CFG_ABITS);
- wire [7:0] B1EN_8 = B1EN;
-
- wire [3:0] DIP, DOP;
- wire [31:0] DI, DO;
-
- wire [31:0] DOBDO;
- wire [3:0] DOPBDOP;
-
- assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
- assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
-
- generate if (CFG_DBITS > 8) begin
- RAMB36E2 #(
- .READ_WIDTH_A(CFG_DBITS),
- .READ_WIDTH_B(CFG_DBITS),
- .WRITE_WIDTH_A(CFG_DBITS),
- .WRITE_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .DOA_REG(0),
- .DOB_REG(0),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_36.vh"
- ) _TECHMAP_REPLACE_ (
- .DINADIN(32'hFFFFFFFF),
- .DINPADINP(4'hF),
- .DOUTADOUT(DO[31:0]),
- .DOUTPADOUTP(DOP[3:0]),
- .ADDRARDADDR(A1ADDR_16),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .ADDRENA(|1),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(4'b0),
-
- .DINBDIN(DI),
- .DINPBDINP(DIP),
- .DOUTBDOUT(DOBDO),
- .DOUTPBDOUTP(DOPBDOP),
- .ADDRBWRADDR(B1ADDR_16),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .ADDRENB(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN_8),
-
- .SLEEP(|0)
- );
- end else begin
- RAMB36E2 #(
- .READ_WIDTH_A(CFG_DBITS),
- .READ_WIDTH_B(CFG_DBITS),
- .WRITE_WIDTH_A(CFG_DBITS),
- .WRITE_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .DOA_REG(0),
- .DOB_REG(0),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_32.vh"
- ) _TECHMAP_REPLACE_ (
- .DINADIN(32'hFFFFFFFF),
- .DINPADINP(4'hF),
- .DOUTADOUT(DO[31:0]),
- .DOUTPADOUTP(DOP[3:0]),
- .ADDRARDADDR(A1ADDR_16),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .ADDRENA(|1),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(4'b0),
-
- .DINBDIN(DI),
- .DINPBDINP(DIP),
- .DOUTBDOUT(DOBDO),
- .DOUTPBDOUTP(DOPBDOP),
- .ADDRBWRADDR(B1ADDR_16),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .ADDRENB(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN_8),
-
- .SLEEP(|0)
- );
- end endgenerate
-endmodule
-
-// ------------------------------------------------------------------------
-
-module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CFG_ABITS = 10;
- parameter CFG_DBITS = 18;
- parameter CFG_ENABLE_B = 2;
-
- 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;
-
- wire [13:0] A1ADDR_14 = A1ADDR << (14 - CFG_ABITS);
- wire [13:0] B1ADDR_14 = B1ADDR << (14 - CFG_ABITS);
- wire [3:0] B1EN_4 = B1EN;
-
- wire [1:0] DIP, DOP;
- wire [15:0] DI, DO;
-
- wire [15:0] DOBDO;
- wire [1:0] DOPBDOP;
-
- assign A1DATA = { DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
- assign { DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
-
- generate if (CFG_DBITS > 8) begin
- RAMB18E2 #(
- .READ_WIDTH_A(CFG_DBITS),
- .READ_WIDTH_B(CFG_DBITS),
- .WRITE_WIDTH_A(CFG_DBITS),
- .WRITE_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .DOA_REG(0),
- .DOB_REG(0),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_18.vh"
- ) _TECHMAP_REPLACE_ (
- .DINADIN(16'hFFFF),
- .DINPADINP(2'b11),
- .DOUTADOUT(DO),
- .DOUTPADOUTP(DOP),
- .ADDRARDADDR(A1ADDR_14),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .ADDRENA(|1),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(2'b0),
-
- .DINBDIN(DI),
- .DINPBDINP(DIP),
- .DOUTBDOUT(DOBDO),
- .DOUTPBDOUTP(DOPBDOP),
- .ADDRBWRADDR(B1ADDR_14),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .ADDRENB(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN_4),
-
- .SLEEP(|0)
- );
- end else begin
- RAMB18E2 #(
- //.RAM_MODE("TDP"),
- .READ_WIDTH_A(CFG_DBITS),
- .READ_WIDTH_B(CFG_DBITS),
- .WRITE_WIDTH_A(CFG_DBITS),
- .WRITE_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .DOA_REG(0),
- .DOB_REG(0),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- `include "brams_init_16.vh"
- ) _TECHMAP_REPLACE_ (
- .DINADIN(16'hFFFF),
- .DINPADINP(2'b11),
- .DOUTADOUT(DO),
- .DOUTPADOUTP(DOP),
- .ADDRARDADDR(A1ADDR_14),
- .CLKARDCLK(CLK2),
- .ENARDEN(A1EN),
- .ADDRENA(|1),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(2'b0),
-
- .DINBDIN(DI),
- .DINPBDINP(DIP),
- .DOUTBDOUT(DOBDO),
- .DOUTPBDOUTP(DOPBDOP),
- .ADDRBWRADDR(B1ADDR_14),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .ADDRENB(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN_4),
-
- .SLEEP(|0)
- );
- end endgenerate
-endmodule
-
diff --git a/techlibs/xilinx/xcup_urams.txt b/techlibs/xilinx/xcup_urams.txt
deleted file mode 100644
index 40c474239..000000000
--- a/techlibs/xilinx/xcup_urams.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-bram $__XILINX_URAM288
- init 0
- abits 12
- dbits 72
- groups 2
- ports 1 1
- wrmode 0 1
- enable 1 9
- transp 0 0
- clocks 2 2
- clkpol 2 2
-endbram
-
-match $__XILINX_URAM288
- min bits 131072
- min efficiency 15
- shuffle_enable B
- make_transp
-endmatch
diff --git a/techlibs/xilinx/xcup_urams_map.v b/techlibs/xilinx/xcup_urams_map.v
deleted file mode 100644
index f15211ba3..000000000
--- a/techlibs/xilinx/xcup_urams_map.v
+++ /dev/null
@@ -1,47 +0,0 @@
-module \$__XILINX_URAM288 (CLK2, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
- parameter CLKPOL2 = 1;
-
- input CLK2;
-
- input [11:0] A1ADDR;
- output [71:0] A1DATA;
- input A1EN;
-
- input [11:0] B1ADDR;
- input [71:0] B1DATA;
- input [8:0] B1EN;
-
-
- URAM288 #(
- .BWE_MODE_A("PARITY_INDEPENDENT"),
- .BWE_MODE_B("PARITY_INDEPENDENT"),
- .EN_AUTO_SLEEP_MODE("FALSE"),
- .IREG_PRE_A("FALSE"),
- .IREG_PRE_B("FALSE"),
- .IS_CLK_INVERTED(!CLKPOL2),
- .OREG_A("FALSE"),
- .OREG_B("FALSE")
- ) _TECHMAP_REPLACE_ (
- .ADDR_A({11'b0, A1ADDR}),
- .BWE_A(9'b0),
- .DIN_A(72'b0),
- .EN_A(A1EN),
- .RDB_WR_A(1'b0),
- .INJECT_DBITERR_A(1'b0),
- .INJECT_SBITERR_A(1'b0),
- .RST_A(1'b0),
- .DOUT_A(A1DATA),
-
- .ADDR_B({11'b0, B1ADDR}),
- .BWE_B(B1EN),
- .DIN_B(B1DATA),
- .EN_B(|B1EN),
- .RDB_WR_B(1'b1),
- .INJECT_DBITERR_B(1'b0),
- .INJECT_SBITERR_B(1'b0),
- .RST_B(1'b0),
-
- .CLK(CLK2),
- .SLEEP(1'b0)
- );
-endmodule