diff options
Diffstat (limited to 'techlibs/gatemate')
-rw-r--r-- | techlibs/gatemate/Makefile.inc | 14 | ||||
-rw-r--r-- | techlibs/gatemate/arith_map.v | 69 | ||||
-rw-r--r-- | techlibs/gatemate/brams.txt | 280 | ||||
-rw-r--r-- | techlibs/gatemate/brams_init_20.vh | 64 | ||||
-rw-r--r-- | techlibs/gatemate/brams_init_40.vh | 260 | ||||
-rw-r--r-- | techlibs/gatemate/brams_map.v | 520 | ||||
-rw-r--r-- | techlibs/gatemate/cells_bb.v | 191 | ||||
-rw-r--r-- | techlibs/gatemate/cells_sim.v | 1411 | ||||
-rw-r--r-- | techlibs/gatemate/lut_map.v | 45 | ||||
-rw-r--r-- | techlibs/gatemate/mul_map.v | 77 | ||||
-rw-r--r-- | techlibs/gatemate/mux_map.v | 56 | ||||
-rw-r--r-- | techlibs/gatemate/reg_map.v | 45 | ||||
-rw-r--r-- | techlibs/gatemate/synth_gatemate.cc | 351 |
13 files changed, 3383 insertions, 0 deletions
diff --git a/techlibs/gatemate/Makefile.inc b/techlibs/gatemate/Makefile.inc new file mode 100644 index 000000000..d1341d7bb --- /dev/null +++ b/techlibs/gatemate/Makefile.inc @@ -0,0 +1,14 @@ +
+OBJS += techlibs/gatemate/synth_gatemate.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))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/lut_map.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/mul_map.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/arith_map.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/cells_sim.v))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/cells_bb.v))
+$(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))
diff --git a/techlibs/gatemate/arith_map.v b/techlibs/gatemate/arith_map.v new file mode 100644 index 000000000..a3ab9c186 --- /dev/null +++ b/techlibs/gatemate/arith_map.v @@ -0,0 +1,69 @@ +/*
+ * 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.
+ *
+ */
+
+(* techmap_celltype = "$alu" *)
+module _80_gatemate_alu(A, B, CI, BI, X, Y, CO);
+ parameter A_SIGNED = 0;
+ parameter B_SIGNED = 0;
+ parameter A_WIDTH = 1;
+ parameter B_WIDTH = 1;
+ parameter Y_WIDTH = 1;
+
+ (* force_downto *)
+ input [A_WIDTH-1:0] A;
+ (* force_downto *)
+ input [B_WIDTH-1:0] B;
+ (* force_downto *)
+ output [Y_WIDTH-1:0] X, Y;
+
+ input CI, BI;
+ (* force_downto *)
+ output [Y_WIDTH-1:0] CO;
+
+ wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
+
+ (* force_downto *)
+ wire [Y_WIDTH-1:0] A_buf, B_buf;
+ \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+ \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+ (* force_downto *)
+ wire [Y_WIDTH-1:0] AA = A_buf;
+ (* force_downto *)
+ wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+ (* force_downto *)
+ wire [Y_WIDTH-1:0] C = {CO, CI};
+
+ genvar i;
+ generate
+ for (i = 0; i < Y_WIDTH; i = i + 1)
+ begin: slice
+ CC_ADDF addf_i (
+ .A(AA[i]),
+ .B(BB[i]),
+ .CI(C[i]),
+ .CO(CO[i]),
+ .S(Y[i])
+ );
+ end
+ endgenerate
+
+ assign X = AA ^ BB;
+
+endmodule
diff --git a/techlibs/gatemate/brams.txt b/techlibs/gatemate/brams.txt new file mode 100644 index 000000000..9e0bebba6 --- /dev/null +++ b/techlibs/gatemate/brams.txt @@ -0,0 +1,280 @@ +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 diff --git a/techlibs/gatemate/brams_init_20.vh b/techlibs/gatemate/brams_init_20.vh new file mode 100644 index 000000000..d0764ed2a --- /dev/null +++ b/techlibs/gatemate/brams_init_20.vh @@ -0,0 +1,64 @@ +.INIT_00(permute_init(INIT[ 0*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_01(permute_init(INIT[ 1*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_02(permute_init(INIT[ 2*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_03(permute_init(INIT[ 3*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_04(permute_init(INIT[ 4*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_05(permute_init(INIT[ 5*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_06(permute_init(INIT[ 6*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_07(permute_init(INIT[ 7*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_08(permute_init(INIT[ 8*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_09(permute_init(INIT[ 9*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0A(permute_init(INIT[ 10*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0B(permute_init(INIT[ 11*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0C(permute_init(INIT[ 12*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0D(permute_init(INIT[ 13*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0E(permute_init(INIT[ 14*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0F(permute_init(INIT[ 15*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_10(permute_init(INIT[ 16*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_11(permute_init(INIT[ 17*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_12(permute_init(INIT[ 18*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_13(permute_init(INIT[ 19*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_14(permute_init(INIT[ 20*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_15(permute_init(INIT[ 21*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_16(permute_init(INIT[ 22*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_17(permute_init(INIT[ 23*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_18(permute_init(INIT[ 24*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_19(permute_init(INIT[ 25*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1A(permute_init(INIT[ 26*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1B(permute_init(INIT[ 27*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1C(permute_init(INIT[ 28*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1D(permute_init(INIT[ 29*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1E(permute_init(INIT[ 30*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1F(permute_init(INIT[ 31*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_20(permute_init(INIT[ 32*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_21(permute_init(INIT[ 33*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_22(permute_init(INIT[ 34*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_23(permute_init(INIT[ 35*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_24(permute_init(INIT[ 36*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_25(permute_init(INIT[ 37*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_26(permute_init(INIT[ 38*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_27(permute_init(INIT[ 39*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_28(permute_init(INIT[ 40*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_29(permute_init(INIT[ 41*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2A(permute_init(INIT[ 42*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2B(permute_init(INIT[ 43*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2C(permute_init(INIT[ 44*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2D(permute_init(INIT[ 45*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2E(permute_init(INIT[ 46*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2F(permute_init(INIT[ 47*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_30(permute_init(INIT[ 48*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_31(permute_init(INIT[ 49*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_32(permute_init(INIT[ 50*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_33(permute_init(INIT[ 51*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_34(permute_init(INIT[ 52*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_35(permute_init(INIT[ 53*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_36(permute_init(INIT[ 54*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_37(permute_init(INIT[ 55*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_38(permute_init(INIT[ 56*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_39(permute_init(INIT[ 57*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3A(permute_init(INIT[ 58*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3B(permute_init(INIT[ 59*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3C(permute_init(INIT[ 60*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3D(permute_init(INIT[ 61*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3E(permute_init(INIT[ 62*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3F(permute_init(INIT[ 63*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), diff --git a/techlibs/gatemate/brams_init_40.vh b/techlibs/gatemate/brams_init_40.vh new file mode 100644 index 000000000..649342560 --- /dev/null +++ b/techlibs/gatemate/brams_init_40.vh @@ -0,0 +1,260 @@ +`ifdef INIT_LOWER +.INIT_00(permute_init(INIT[ 0*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_01(permute_init(INIT[ 1*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_02(permute_init(INIT[ 2*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_03(permute_init(INIT[ 3*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_04(permute_init(INIT[ 4*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_05(permute_init(INIT[ 5*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_06(permute_init(INIT[ 6*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_07(permute_init(INIT[ 7*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_08(permute_init(INIT[ 8*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_09(permute_init(INIT[ 9*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0A(permute_init(INIT[ 10*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0B(permute_init(INIT[ 11*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0C(permute_init(INIT[ 12*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0D(permute_init(INIT[ 13*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0E(permute_init(INIT[ 14*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0F(permute_init(INIT[ 15*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_10(permute_init(INIT[ 16*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_11(permute_init(INIT[ 17*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_12(permute_init(INIT[ 18*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_13(permute_init(INIT[ 19*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_14(permute_init(INIT[ 20*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_15(permute_init(INIT[ 21*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_16(permute_init(INIT[ 22*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_17(permute_init(INIT[ 23*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_18(permute_init(INIT[ 24*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_19(permute_init(INIT[ 25*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1A(permute_init(INIT[ 26*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1B(permute_init(INIT[ 27*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1C(permute_init(INIT[ 28*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1D(permute_init(INIT[ 29*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1E(permute_init(INIT[ 30*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1F(permute_init(INIT[ 31*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_20(permute_init(INIT[ 32*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_21(permute_init(INIT[ 33*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_22(permute_init(INIT[ 34*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_23(permute_init(INIT[ 35*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_24(permute_init(INIT[ 36*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_25(permute_init(INIT[ 37*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_26(permute_init(INIT[ 38*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_27(permute_init(INIT[ 39*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_28(permute_init(INIT[ 40*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_29(permute_init(INIT[ 41*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2A(permute_init(INIT[ 42*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2B(permute_init(INIT[ 43*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2C(permute_init(INIT[ 44*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2D(permute_init(INIT[ 45*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2E(permute_init(INIT[ 46*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2F(permute_init(INIT[ 47*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_30(permute_init(INIT[ 48*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_31(permute_init(INIT[ 49*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_32(permute_init(INIT[ 50*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_33(permute_init(INIT[ 51*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_34(permute_init(INIT[ 52*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_35(permute_init(INIT[ 53*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_36(permute_init(INIT[ 54*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_37(permute_init(INIT[ 55*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_38(permute_init(INIT[ 56*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_39(permute_init(INIT[ 57*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3A(permute_init(INIT[ 58*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3B(permute_init(INIT[ 59*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3C(permute_init(INIT[ 60*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3D(permute_init(INIT[ 61*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3E(permute_init(INIT[ 62*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3F(permute_init(INIT[ 63*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_40(permute_init(INIT[ 64*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_41(permute_init(INIT[ 65*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_42(permute_init(INIT[ 66*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_43(permute_init(INIT[ 67*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_44(permute_init(INIT[ 68*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_45(permute_init(INIT[ 69*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_46(permute_init(INIT[ 70*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_47(permute_init(INIT[ 71*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_48(permute_init(INIT[ 72*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_49(permute_init(INIT[ 73*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4A(permute_init(INIT[ 74*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4B(permute_init(INIT[ 75*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4C(permute_init(INIT[ 76*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4D(permute_init(INIT[ 77*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4E(permute_init(INIT[ 78*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4F(permute_init(INIT[ 79*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_50(permute_init(INIT[ 80*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_51(permute_init(INIT[ 81*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_52(permute_init(INIT[ 82*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_53(permute_init(INIT[ 83*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_54(permute_init(INIT[ 84*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_55(permute_init(INIT[ 85*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_56(permute_init(INIT[ 86*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_57(permute_init(INIT[ 87*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_58(permute_init(INIT[ 88*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_59(permute_init(INIT[ 89*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5A(permute_init(INIT[ 90*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5B(permute_init(INIT[ 91*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5C(permute_init(INIT[ 92*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5D(permute_init(INIT[ 93*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5E(permute_init(INIT[ 94*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5F(permute_init(INIT[ 95*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_60(permute_init(INIT[ 96*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_61(permute_init(INIT[ 97*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_62(permute_init(INIT[ 98*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_63(permute_init(INIT[ 99*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_64(permute_init(INIT[100*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_65(permute_init(INIT[101*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_66(permute_init(INIT[102*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_67(permute_init(INIT[103*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_68(permute_init(INIT[104*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_69(permute_init(INIT[105*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6A(permute_init(INIT[106*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6B(permute_init(INIT[107*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6C(permute_init(INIT[108*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6D(permute_init(INIT[109*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6E(permute_init(INIT[110*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6F(permute_init(INIT[111*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_70(permute_init(INIT[112*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_71(permute_init(INIT[113*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_72(permute_init(INIT[114*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_73(permute_init(INIT[115*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_74(permute_init(INIT[116*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_75(permute_init(INIT[117*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_76(permute_init(INIT[118*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_77(permute_init(INIT[119*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_78(permute_init(INIT[120*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_79(permute_init(INIT[121*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7A(permute_init(INIT[122*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7B(permute_init(INIT[123*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7C(permute_init(INIT[124*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7D(permute_init(INIT[125*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7E(permute_init(INIT[126*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7F(permute_init(INIT[127*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +`endif +`ifdef INIT_UPPER +.INIT_00(permute_init(INIT[128*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_01(permute_init(INIT[129*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_02(permute_init(INIT[130*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_03(permute_init(INIT[131*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_04(permute_init(INIT[132*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_05(permute_init(INIT[133*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_06(permute_init(INIT[134*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_07(permute_init(INIT[135*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_08(permute_init(INIT[136*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_09(permute_init(INIT[137*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0A(permute_init(INIT[138*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0B(permute_init(INIT[139*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0C(permute_init(INIT[140*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0D(permute_init(INIT[141*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0E(permute_init(INIT[142*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_0F(permute_init(INIT[143*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_10(permute_init(INIT[144*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_11(permute_init(INIT[145*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_12(permute_init(INIT[146*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_13(permute_init(INIT[147*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_14(permute_init(INIT[148*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_15(permute_init(INIT[149*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_16(permute_init(INIT[150*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_17(permute_init(INIT[151*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_18(permute_init(INIT[152*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_19(permute_init(INIT[153*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1A(permute_init(INIT[154*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1B(permute_init(INIT[155*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1C(permute_init(INIT[156*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1D(permute_init(INIT[157*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1E(permute_init(INIT[158*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_1F(permute_init(INIT[159*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_20(permute_init(INIT[160*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_21(permute_init(INIT[161*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_22(permute_init(INIT[162*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_23(permute_init(INIT[163*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_24(permute_init(INIT[164*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_25(permute_init(INIT[165*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_26(permute_init(INIT[166*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_27(permute_init(INIT[167*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_28(permute_init(INIT[168*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_29(permute_init(INIT[169*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2A(permute_init(INIT[170*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2B(permute_init(INIT[171*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2C(permute_init(INIT[172*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2D(permute_init(INIT[173*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2E(permute_init(INIT[174*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_2F(permute_init(INIT[175*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_30(permute_init(INIT[176*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_31(permute_init(INIT[177*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_32(permute_init(INIT[178*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_33(permute_init(INIT[179*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_34(permute_init(INIT[180*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_35(permute_init(INIT[181*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_36(permute_init(INIT[182*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_37(permute_init(INIT[183*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_38(permute_init(INIT[184*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_39(permute_init(INIT[185*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3A(permute_init(INIT[186*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3B(permute_init(INIT[187*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3C(permute_init(INIT[188*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3D(permute_init(INIT[189*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3E(permute_init(INIT[190*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_3F(permute_init(INIT[191*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_40(permute_init(INIT[192*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_41(permute_init(INIT[193*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_42(permute_init(INIT[194*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_43(permute_init(INIT[195*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_44(permute_init(INIT[196*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_45(permute_init(INIT[197*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_46(permute_init(INIT[198*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_47(permute_init(INIT[199*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_48(permute_init(INIT[200*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_49(permute_init(INIT[201*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4A(permute_init(INIT[202*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4B(permute_init(INIT[203*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4C(permute_init(INIT[204*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4D(permute_init(INIT[205*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4E(permute_init(INIT[206*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_4F(permute_init(INIT[207*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_50(permute_init(INIT[208*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_51(permute_init(INIT[209*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_52(permute_init(INIT[210*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_53(permute_init(INIT[211*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_54(permute_init(INIT[212*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_55(permute_init(INIT[213*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_56(permute_init(INIT[214*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_57(permute_init(INIT[215*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_58(permute_init(INIT[216*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_59(permute_init(INIT[217*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5A(permute_init(INIT[218*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5B(permute_init(INIT[219*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5C(permute_init(INIT[220*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5D(permute_init(INIT[221*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5E(permute_init(INIT[222*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_5F(permute_init(INIT[223*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_60(permute_init(INIT[224*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_61(permute_init(INIT[225*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_62(permute_init(INIT[226*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_63(permute_init(INIT[227*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_64(permute_init(INIT[228*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_65(permute_init(INIT[229*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_66(permute_init(INIT[230*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_67(permute_init(INIT[231*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_68(permute_init(INIT[232*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_69(permute_init(INIT[233*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6A(permute_init(INIT[234*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6B(permute_init(INIT[235*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6C(permute_init(INIT[236*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6D(permute_init(INIT[237*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6E(permute_init(INIT[238*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_6F(permute_init(INIT[239*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_70(permute_init(INIT[240*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_71(permute_init(INIT[241*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_72(permute_init(INIT[242*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_73(permute_init(INIT[243*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_74(permute_init(INIT[244*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_75(permute_init(INIT[245*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_76(permute_init(INIT[246*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_77(permute_init(INIT[247*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_78(permute_init(INIT[248*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_79(permute_init(INIT[249*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7A(permute_init(INIT[250*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7B(permute_init(INIT[251*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7C(permute_init(INIT[252*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7D(permute_init(INIT[253*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7E(permute_init(INIT[254*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +.INIT_7F(permute_init(INIT[255*INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE])), +`endif diff --git a/techlibs/gatemate/brams_map.v b/techlibs/gatemate/brams_map.v new file mode 100644 index 000000000..f36f05212 --- /dev/null +++ b/techlibs/gatemate/brams_map.v @@ -0,0 +1,520 @@ +/*
+ * 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
+
+ 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("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)
+ ) _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)
+ );
+ 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
+
+ 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("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)
+ ) _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)
+ );
+ 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;
+
+ // 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;
+
+ // cascade signals
+ wire A_CAS, B_CAS;
+
+ // 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;
+
+ localparam INIT_CHUNK_SIZE = 256;
+
+ 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),
+ .B_WE(1'b0),
+ .A_ADDR(A1ADDR),
+ .B_ADDR(B1ADDR),
+ .A_DI(A1DATA),
+ .B_DI(40'b0),
+ .A_BM(A1EN),
+ .B_BM(40'b0)
+ );
+
+ 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),
+ .B_WE(1'b0),
+ .A_ADDR(A1ADDR),
+ .B_ADDR(B1ADDR),
+ .A_DI(A1DATA),
+ .B_DI(40'b0),
+ .A_BM(A1EN),
+ .B_BM(40'b0)
+ );
+ endgenerate
+
+endmodule
diff --git a/techlibs/gatemate/cells_bb.v b/techlibs/gatemate/cells_bb.v new file mode 100644 index 000000000..f6fe6a3e1 --- /dev/null +++ b/techlibs/gatemate/cells_bb.v @@ -0,0 +1,191 @@ +/*
+ * 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.
+ *
+ */
+
+(* blackbox *)
+module CC_PLL #(
+ parameter REF_CLK = "", // e.g. "10.0"
+ parameter OUT_CLK = "", // e.g. "50.0"
+ parameter PERF_MD = "", // LOWPOWER, ECONOMY, SPEED
+ parameter LOW_JITTER = 1,
+ parameter CI_FILTER_CONST = 2,
+ parameter CP_FILTER_CONST = 4
+)(
+ input CLK_REF, CLK_FEEDBACK, USR_CLK_REF,
+ input USR_LOCKED_STDY_RST,
+ output USR_PLL_LOCKED_STDY, USR_PLL_LOCKED,
+ output CLK270, CLK180, CLK90, CLK0, CLK_REF_OUT
+);
+endmodule
+
+(* blackbox *)
+module CC_PLL_ADV #(
+ parameter [95:0] PLL_CFG_A = 96'bx,
+ parameter [95:0] PLL_CFG_B = 96'bx
+)(
+ input CLK_REF, CLK_FEEDBACK, USR_CLK_REF,
+ input USR_LOCKED_STDY_RST, USR_SEL_A_B,
+ output USR_PLL_LOCKED_STDY, USR_PLL_LOCKED,
+ output CLK270, CLK180, CLK90, CLK0, CLK_REF_OUT
+);
+endmodule
+
+(* blackbox *) (* keep *)
+module CC_SERDES #(
+ parameter SERDES_CFG = ""
+)(
+ input [63:0] TX_DATA_I,
+ input TX_RESET_I,
+ input TX_PCS_RESET_I,
+ input TX_PMA_RESET_I,
+ input PLL_RESET_I,
+ input TX_POWERDOWN_N_I,
+ input TX_POLARITY_I,
+ input [2:0] TX_PRBS_SEL_I,
+ input TX_PRBS_FORCE_ERR_I,
+ input TX_8B10B_EN_I,
+ input [7:0] TX_8B10B_BYPASS_I,
+ input [7:0] TX_CHAR_IS_K_I,
+ input [7:0] TX_CHAR_DISPMODE_I,
+ input [7:0] TX_CHAR_DISPVAL_I,
+ input TX_ELEC_IDLE_I,
+ input TX_DETECT_RX_I,
+ input [2:0] LOOPBACK_I,
+ input CLK_CORE_TX_I,
+ input CLK_CORE_RX_I,
+ input RX_RESET_I,
+ input RX_PMA_RESET_I,
+ input RX_EQA_RESET_I,
+ input RX_CDR_RESET_I,
+ input RX_PCS_RESET_I,
+ input RX_BUF_RESET_I,
+ input RX_POWERDOWN_N_I,
+ input RX_POLARITY_I,
+ input [2:0] RX_PRBS_SEL_I,
+ input RX_PRBS_CNT_RESET_I,
+ input RX_8B10B_EN_I,
+ input [7:0] RX_8B10B_BYPASS_I,
+ input RX_EN_EI_DETECTOR_I,
+ input RX_COMMA_DETECT_EN_I,
+ input RX_SLIDE_I,
+ input RX_MCOMMA_ALIGN_I,
+ input RX_PCOMMA_ALIGN_I,
+ input CLK_REG_I,
+ input REGFILE_WE_I,
+ input REGFILE_EN_I,
+ input [7:0] REGFILE_ADDR_I,
+ input [15:0] REGFILE_DI_I,
+ input [15:0] REGFILE_MASK_I,
+ output [63:0] RX_DATA_O,
+ output [7:0] RX_NOT_IN_TABLE_O,
+ output [7:0] RX_CHAR_IS_COMMA_O,
+ output [7:0] RX_CHAR_IS_K_O,
+ output [7:0] RX_DISP_ERR_O,
+ output RX_DETECT_DONE_O,
+ output RX_PRESENT_O,
+ output TX_BUF_ERR_O,
+ output TX_RESETDONE_O,
+ output RX_PRBS_ERR_O,
+ output RX_BUF_ERR_O,
+ output RX_BYTE_IS_ALIGNED_O,
+ output RX_BYTE_REALIGN_O,
+ output RX_RESETDONE_O,
+ output RX_EI_EN_O,
+ output CLK_CORE_RX_O,
+ output CLK_CORE_PLL_O,
+ output [15:0] REGFILE_DO_O,
+ output REGFILE_RDY_O
+);
+endmodule
+
+(* blackbox *) (* keep *)
+module CC_CFG_CTRL(
+ input [7:0] DATA,
+ input CLK,
+ input EN,
+ input RECFG,
+ input VALID
+);
+endmodule
+
+(* blackbox *)
+module CC_FIFO_40K (
+ output A_ECC_1B_ERR,
+ output B_ECC_1B_ERR,
+ output A_ECC_2B_ERR,
+ output B_ECC_2B_ERR,
+ // FIFO pop port
+ output [39:0] A_DO,
+ output [39:0] B_DO,
+ (* clkbuf_sink *)
+ input A_CLK,
+ input A_EN,
+ // FIFO push port
+ input [39:0] A_DI,
+ input [39:0] B_DI,
+ input [39:0] A_BM,
+ input [39:0] B_BM,
+ (* clkbuf_sink *)
+ input B_CLK,
+ input B_EN,
+ input B_WE,
+ // FIFO control
+ input F_RST_N,
+ input [12:0] F_ALMOST_FULL_OFFSET,
+ input [12:0] F_ALMOST_EMPTY_OFFSET,
+ // FIFO status signals
+ output F_FULL,
+ output F_EMPTY,
+ output F_ALMOST_FULL,
+ output F_ALMOST_EMPTY,
+ output F_RD_ERROR,
+ output F_WR_ERROR,
+ output [15:0] F_RD_PTR,
+ output [15:0] F_WR_PTR
+);
+ // Location format: D(0..N-1)X(0..3)Y(0..7) or UNPLACED
+ parameter LOC = "UNPLACED";
+
+ // Offset configuration
+ parameter [12:0] ALMOST_FULL_OFFSET = 12'b0;
+ parameter [12:0] ALMOST_EMPTY_OFFSET = 12'b0;
+
+ // Port Widths
+ parameter A_WIDTH = 0;
+ parameter B_WIDTH = 0;
+
+ // RAM and Write Modes
+ parameter RAM_MODE = "SDP"; // "TPD" or "SDP"
+ parameter FIFO_MODE = "SYNC"; // "ASYNC" or "SYNC"
+
+ // Inverting Control Pins
+ parameter A_CLK_INV = 1'b0;
+ parameter B_CLK_INV = 1'b0;
+ parameter A_EN_INV = 1'b0;
+ parameter B_EN_INV = 1'b0;
+ parameter A_WE_INV = 1'b0;
+ parameter B_WE_INV = 1'b0;
+
+ // Output Register
+ parameter A_DO_REG = 1'b0;
+ parameter B_DO_REG = 1'b0;
+
+ // Error Checking and Correction
+ parameter A_ECC_EN = 1'b0;
+ parameter B_ECC_EN = 1'b0;
+endmodule
diff --git a/techlibs/gatemate/cells_sim.v b/techlibs/gatemate/cells_sim.v new file mode 100644 index 000000000..1de3d1c7a --- /dev/null +++ b/techlibs/gatemate/cells_sim.v @@ -0,0 +1,1411 @@ +/*
+ * 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.
+ *
+ */
+
+`timescale 1ps/1ps
+
+module CC_IBUF #(
+ parameter PIN_NAME = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter [0:0] PULLUP = 1'bx,
+ parameter [0:0] PULLDOWN = 1'bx,
+ parameter [0:0] KEEPER = 1'bx,
+ parameter [0:0] SCHMITT_TRIGGER = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_IBF = 1'bx,
+ parameter [0:0] FF_IBF = 1'bx
+)(
+ (* iopad_external_pin *)
+ input I,
+ output Y
+);
+ assign Y = I;
+
+endmodule
+
+
+module CC_OBUF #(
+ parameter PIN_NAME = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter DRIVE = "UNDEFINED",
+ parameter SLEW = "UNDEFINED",
+ // IOSEL
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A,
+ (* iopad_external_pin *)
+ output O
+);
+ assign O = A;
+
+endmodule
+
+
+module CC_TOBUF #(
+ parameter PIN_NAME = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter DRIVE = "UNDEFINED",
+ parameter SLEW = "UNDEFINED",
+ parameter [0:0] PULLUP = 1'bx,
+ parameter [0:0] PULLDOWN = 1'bx,
+ parameter [0:0] KEEPER = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A, T,
+ (* iopad_external_pin *)
+ output O
+);
+ assign O = T ? 1'bz : A;
+
+endmodule
+
+
+module CC_IOBUF #(
+ parameter PIN_NAME = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter DRIVE = "UNDEFINED",
+ parameter SLEW = "UNDEFINED",
+ parameter [0:0] PULLUP = 1'bx,
+ parameter [0:0] PULLDOWN = 1'bx,
+ parameter [0:0] KEEPER = 1'bx,
+ parameter [0:0] SCHMITT_TRIGGER = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_IBF = 1'bx,
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_IBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A, T,
+ output Y,
+ (* iopad_external_pin *)
+ inout IO
+);
+ assign IO = T ? 1'bz : A;
+ assign Y = IO;
+
+endmodule
+
+
+module CC_LVDS_IBUF #(
+ parameter PIN_NAME_P = "UNPLACED",
+ parameter PIN_NAME_N = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter [0:0] LVDS_RTERM = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_IBF = 1'bx,
+ parameter [0:0] FF_IBF = 1'bx
+)(
+ (* iopad_external_pin *)
+ input IP, IN,
+ output Y
+);
+ assign Y = IP;
+
+endmodule
+
+
+module CC_LVDS_OBUF #(
+ parameter PIN_NAME_P = "UNPLACED",
+ parameter PIN_NAME_N = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter [0:0] LVDS_BOOST = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A,
+ (* iopad_external_pin *)
+ output OP, ON
+);
+ assign OP = A;
+ assign ON = ~A;
+
+endmodule
+
+
+module CC_LVDS_TOBUF #(
+ parameter PIN_NAME_P = "UNPLACED",
+ parameter PIN_NAME_N = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter [0:0] LVDS_BOOST = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A, T,
+ (* iopad_external_pin *)
+ output OP, ON
+);
+ assign OP = T ? 1'bz : A;
+ assign ON = T ? 1'bz : ~A;
+
+endmodule
+
+
+module CC_LVDS_IOBUF #(
+ parameter PIN_NAME_P = "UNPLACED",
+ parameter PIN_NAME_N = "UNPLACED",
+ parameter V_IO = "UNDEFINED",
+ parameter [0:0] LVDS_RTERM = 1'bx,
+ parameter [0:0] LVDS_BOOST = 1'bx,
+ // IOSEL
+ parameter [3:0] DELAY_IBF = 1'bx,
+ parameter [3:0] DELAY_OBF = 1'bx,
+ parameter [0:0] FF_IBF = 1'bx,
+ parameter [0:0] FF_OBF = 1'bx
+)(
+ input A, T,
+ (* iopad_external_pin *)
+ inout IOP, ION,
+ output Y
+);
+ assign IOP = T ? 1'bz : A;
+ assign ION = T ? 1'bz : ~A;
+ assign Y = IOP;
+
+endmodule
+
+
+module CC_IDDR #(
+ parameter [0:0] CLK_INV = 1'b0
+)(
+ input D,
+ (* clkbuf_sink *)
+ input CLK,
+ output reg Q0, Q1
+);
+ wire clk;
+ assign clk = (CLK_INV) ? ~CLK : CLK;
+
+ always @(posedge clk)
+ begin
+ Q0 <= D;
+ end
+
+ always @(negedge clk)
+ begin
+ Q1 <= D;
+ end
+
+endmodule
+
+
+module CC_ODDR #(
+ parameter [0:0] CLK_INV = 1'b0
+)(
+ input D0,
+ input D1,
+ (* clkbuf_sink *)
+ input CLK,
+ (* clkbuf_sink *)
+ input DDR,
+ output Q
+);
+ wire clk;
+ assign clk = (CLK_INV) ? ~CLK : CLK;
+
+ reg q0, q1;
+ assign Q = (DDR) ? q0 : q1;
+
+ always @(posedge clk)
+ begin
+ q0 <= D0;
+ end
+
+ always @(negedge clk)
+ begin
+ q1 <= D1;
+ end
+
+endmodule
+
+
+module CC_DFF #(
+ parameter [0:0] CLK_INV = 1'b0,
+ parameter [0:0] EN_INV = 1'b0,
+ parameter [0:0] SR_INV = 1'b0,
+ parameter [0:0] SR_VAL = 1'b0
+)(
+ input D,
+ (* clkbuf_sink *)
+ input CLK,
+ input EN,
+ input SR,
+ output reg Q
+);
+ wire clk, en, sr;
+ assign clk = (CLK_INV) ? ~CLK : CLK;
+ assign en = (EN_INV) ? ~EN : EN;
+ assign sr = (SR_INV) ? ~SR : SR;
+
+ initial Q = 1'bX;
+
+ always @(posedge clk or posedge sr)
+ begin
+ if (sr) begin
+ Q <= SR_VAL;
+ end
+ else if (en) begin
+ Q <= D;
+ end
+ end
+
+endmodule
+
+
+module CC_DLT #(
+ parameter [0:0] G_INV = 1'b0,
+ parameter [0:0] SR_INV = 1'b0,
+ parameter [0:0] SR_VAL = 1'b0
+)(
+ input D,
+ input G,
+ input SR,
+ output reg Q
+);
+ wire en, sr;
+ assign en = (G_INV) ? ~G : G;
+ assign sr = (SR_INV) ? ~SR : SR;
+
+ initial Q = 1'bX;
+
+ always @(*)
+ begin
+ if (sr) begin
+ Q <= SR_VAL;
+ end
+ else if (en) begin
+ Q <= D;
+ end
+ end
+
+endmodule
+
+
+module CC_LUT1 (
+ output O,
+ input I0
+);
+ parameter [1:0] INIT = 0;
+
+ assign O = I0 ? INIT[1] : INIT[0];
+
+endmodule
+
+
+module CC_LUT2 (
+ output O,
+ input I0, I1
+);
+ parameter [3:0] INIT = 0;
+
+ wire [1:0] s1 = I1 ? INIT[3:2] : INIT[1:0];
+ assign O = I0 ? s1[1] : s1[0];
+
+endmodule
+
+
+module CC_LUT3 (
+ output O,
+ input I0, I1, I2
+);
+ parameter [7:0] INIT = 0;
+
+ wire [3:0] s2 = I2 ? INIT[7:4] : INIT[3:0];
+ wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0];
+ assign O = I0 ? s1[1] : s1[0];
+
+endmodule
+
+
+module CC_LUT4 (
+ output O,
+ input I0, I1, I2, I3
+);
+ parameter [15:0] INIT = 0;
+
+ wire [7:0] s3 = I3 ? INIT[15:8] : INIT[7:0];
+ wire [3:0] s2 = I2 ? s3[7:4] : s3[3:0];
+ wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0];
+ assign O = I0 ? s1[1] : s1[0];
+
+endmodule
+
+
+module CC_MX2 (
+ input D0, D1,
+ input S0,
+ output Y
+);
+ assign Y = S0 ? D1 : D0;
+
+endmodule
+
+
+module CC_MX4 (
+ input D0, D1, D2, D3,
+ input S0, S1,
+ output Y
+);
+ assign Y = S1 ? (S0 ? D3 : D2) :
+ (S0 ? D1 : D0);
+
+endmodule
+
+
+module CC_MX8 (
+ input D0, D1, D2, D3,
+ input D4, D5, D6, D7,
+ input S0, S1, S2,
+ output Y
+);
+ assign Y = S2 ? (S1 ? (S0 ? D7 : D6) :
+ (S0 ? D5 : D4)) :
+ (S1 ? (S0 ? D3 : D2) :
+ (S0 ? D1 : D0));
+
+endmodule
+
+
+module CC_ADDF (
+ input A, B, CI,
+ output CO, S
+);
+ assign {CO, S} = A + B + CI;
+
+endmodule
+
+
+module CC_MULT #(
+ parameter A_WIDTH = 0,
+ parameter B_WIDTH = 0,
+ parameter P_WIDTH = 0
+)(
+ input signed [A_WIDTH-1:0] A,
+ input signed [B_WIDTH-1:0] B,
+ output reg signed [P_WIDTH-1:0] P
+);
+ always @(*)
+ begin
+ P <= A * B;
+ end
+endmodule
+
+
+module CC_BUFG (
+ input I,
+ (* clkbuf_driver *)
+ output O
+);
+ assign O = I;
+
+endmodule
+
+
+module CC_BRAM_20K (
+ output [19:0] A_DO,
+ output [19:0] B_DO,
+ output ECC_1B_ERR,
+ output ECC_2B_ERR,
+ (* clkbuf_sink *)
+ input A_CLK,
+ (* clkbuf_sink *)
+ input B_CLK,
+ input A_EN,
+ input B_EN,
+ input A_WE,
+ input B_WE,
+ input [15:0] A_ADDR,
+ input [15:0] B_ADDR,
+ input [19:0] A_DI,
+ input [19:0] B_DI,
+ input [19:0] A_BM,
+ input [19:0] B_BM
+);
+ // Location format: D(0..N-1)(0..N-1)X(0..3)Y(0..7)Z(0..1) or UNPLACED
+ parameter LOC = "UNPLACED";
+
+ // Port Widths
+ parameter A_RD_WIDTH = 0;
+ parameter B_RD_WIDTH = 0;
+ parameter A_WR_WIDTH = 0;
+ parameter B_WR_WIDTH = 0;
+
+ // RAM and Write Modes
+ parameter RAM_MODE = "SDP";
+ parameter A_WR_MODE = "NO_CHANGE";
+ parameter B_WR_MODE = "NO_CHANGE";
+
+ // Inverting Control Pins
+ parameter A_CLK_INV = 1'b0;
+ parameter B_CLK_INV = 1'b0;
+ parameter A_EN_INV = 1'b0;
+ parameter B_EN_INV = 1'b0;
+ parameter A_WE_INV = 1'b0;
+ parameter B_WE_INV = 1'b0;
+
+ // Output Register
+ parameter A_DO_REG = 1'b0;
+ parameter B_DO_REG = 1'b0;
+
+ // Error Checking and Correction
+ parameter ECC_EN = 1'b0;
+
+ // RAM Contents
+ parameter INIT_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+
+ localparam WIDTH_MODE_A = (A_RD_WIDTH > A_WR_WIDTH) ? A_RD_WIDTH : A_WR_WIDTH;
+ localparam WIDTH_MODE_B = (B_RD_WIDTH > B_WR_WIDTH) ? B_RD_WIDTH : B_WR_WIDTH;
+
+ integer i, k;
+
+ // 512 x 40 bit
+ reg [20479:0] memory = 20480'b0;
+
+ initial begin
+ // Check parameters
+ if ((RAM_MODE != "SDP") && (RAM_MODE != "TDP")) begin
+ $display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
+ $finish();
+ end
+ if ((A_WR_MODE != "WRITE_THROUGH") && (A_WR_MODE != "NO_CHANGE")) begin
+ $display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
+ $finish();
+ end
+ if ((RAM_MODE == "SDP") && (A_WR_MODE == "WRITE_THROUGH")) begin
+ $display("ERROR: %s is not supported in %s mode.", A_WR_MODE, RAM_MODE);
+ $finish();
+ end
+ if (ECC_EN != 1'b0) begin
+ $display("WARNING: ECC feature not supported in simulation.");
+ end
+ if ((ECC_EN == 1'b1) && (RAM_MODE != "SDP") && (WIDTH_MODE_A != 40)) begin
+ $display("ERROR: Illegal ECC Port configuration. Must be SDP 40 bit, but is %s %d.", RAM_MODE, WIDTH_MODE_A);
+ $finish();
+ end
+ if ((WIDTH_MODE_A == 40) && (RAM_MODE == "TDP")) begin
+ $display("ERROR: Port A width of 40 bits is only supported in SDP mode.");
+ $finish();
+ end
+ if ((WIDTH_MODE_B == 40) && (RAM_MODE == "TDP")) begin
+ $display("ERROR: Port B width of 40 bits is only supported in SDP mode.");
+ $finish();
+ end
+ if ((WIDTH_MODE_A != 40) && (WIDTH_MODE_A != 20) && (WIDTH_MODE_A != 10) &&
+ (WIDTH_MODE_A != 5) && (WIDTH_MODE_A != 2) && (WIDTH_MODE_A != 1) && (WIDTH_MODE_A != 0)) begin
+ $display("ERROR: Illegal %s Port A width configuration %d.", RAM_MODE, WIDTH_MODE_A);
+ $finish();
+ end
+ if ((WIDTH_MODE_B != 40) && (WIDTH_MODE_B != 20) && (WIDTH_MODE_B != 10) &&
+ (WIDTH_MODE_B != 5) && (WIDTH_MODE_B != 2) && (WIDTH_MODE_B != 1) && (WIDTH_MODE_B != 0)) begin
+ $display("ERROR: Illegal %s Port B width configuration %d.", RAM_MODE, WIDTH_MODE_B);
+ $finish();
+ end
+ // RAM initialization
+ memory[320*0+319:320*0] = INIT_00;
+ memory[320*1+319:320*1] = INIT_01;
+ memory[320*2+319:320*2] = INIT_02;
+ memory[320*3+319:320*3] = INIT_03;
+ memory[320*4+319:320*4] = INIT_04;
+ memory[320*5+319:320*5] = INIT_05;
+ memory[320*6+319:320*6] = INIT_06;
+ memory[320*7+319:320*7] = INIT_07;
+ memory[320*8+319:320*8] = INIT_08;
+ memory[320*9+319:320*9] = INIT_09;
+ memory[320*10+319:320*10] = INIT_0A;
+ memory[320*11+319:320*11] = INIT_0B;
+ memory[320*12+319:320*12] = INIT_0C;
+ memory[320*13+319:320*13] = INIT_0D;
+ memory[320*14+319:320*14] = INIT_0E;
+ memory[320*15+319:320*15] = INIT_0F;
+ memory[320*16+319:320*16] = INIT_10;
+ memory[320*17+319:320*17] = INIT_11;
+ memory[320*18+319:320*18] = INIT_12;
+ memory[320*19+319:320*19] = INIT_13;
+ memory[320*20+319:320*20] = INIT_14;
+ memory[320*21+319:320*21] = INIT_15;
+ memory[320*22+319:320*22] = INIT_16;
+ memory[320*23+319:320*23] = INIT_17;
+ memory[320*24+319:320*24] = INIT_18;
+ memory[320*25+319:320*25] = INIT_19;
+ memory[320*26+319:320*26] = INIT_1A;
+ memory[320*27+319:320*27] = INIT_1B;
+ memory[320*28+319:320*28] = INIT_1C;
+ memory[320*29+319:320*29] = INIT_1D;
+ memory[320*30+319:320*30] = INIT_1E;
+ memory[320*31+319:320*31] = INIT_1F;
+ memory[320*32+319:320*32] = INIT_20;
+ memory[320*33+319:320*33] = INIT_21;
+ memory[320*34+319:320*34] = INIT_22;
+ memory[320*35+319:320*35] = INIT_23;
+ memory[320*36+319:320*36] = INIT_24;
+ memory[320*37+319:320*37] = INIT_25;
+ memory[320*38+319:320*38] = INIT_26;
+ memory[320*39+319:320*39] = INIT_27;
+ memory[320*40+319:320*40] = INIT_28;
+ memory[320*41+319:320*41] = INIT_29;
+ memory[320*42+319:320*42] = INIT_2A;
+ memory[320*43+319:320*43] = INIT_2B;
+ memory[320*44+319:320*44] = INIT_2C;
+ memory[320*45+319:320*45] = INIT_2D;
+ memory[320*46+319:320*46] = INIT_2E;
+ memory[320*47+319:320*47] = INIT_2F;
+ memory[320*48+319:320*48] = INIT_30;
+ memory[320*49+319:320*49] = INIT_31;
+ memory[320*50+319:320*50] = INIT_32;
+ memory[320*51+319:320*51] = INIT_33;
+ memory[320*52+319:320*52] = INIT_34;
+ memory[320*53+319:320*53] = INIT_35;
+ memory[320*54+319:320*54] = INIT_36;
+ memory[320*55+319:320*55] = INIT_37;
+ memory[320*56+319:320*56] = INIT_38;
+ memory[320*57+319:320*57] = INIT_39;
+ memory[320*58+319:320*58] = INIT_3A;
+ memory[320*59+319:320*59] = INIT_3B;
+ memory[320*60+319:320*60] = INIT_3C;
+ memory[320*61+319:320*61] = INIT_3D;
+ memory[320*62+319:320*62] = INIT_3E;
+ memory[320*63+319:320*63] = INIT_3F;
+ end
+
+ // Signal inversion
+ wire clka = A_CLK_INV ^ A_CLK;
+ wire clkb = B_CLK_INV ^ B_CLK;
+ wire ena = A_EN_INV ^ A_EN;
+ wire enb = B_EN_INV ^ B_EN;
+ wire wea = A_WE_INV ^ A_WE;
+ wire web = B_WE_INV ^ B_WE;
+
+ // Internal signals
+ wire [15:0] addra;
+ wire [15:0] addrb;
+ reg [19:0] A_DO_out = 0, A_DO_reg = 0;
+ reg [19:0] B_DO_out = 0, B_DO_reg = 0;
+
+ generate
+ if (RAM_MODE == "SDP") begin
+ // Port A (write)
+ if (A_WR_WIDTH == 40) begin
+ assign addra = A_ADDR[15:7]*40;
+ end
+ // Port B (read)
+ if (B_RD_WIDTH == 40) begin
+ assign addrb = B_ADDR[15:7]*40;
+ end
+ end
+ else if (RAM_MODE == "TDP") begin
+ // Port A
+ if (WIDTH_MODE_A <= 1) begin
+ wire [15:0] tmpa = {2'b0, A_ADDR[15:7], A_ADDR[5:1]};
+ assign addra = tmpa + (tmpa/4);
+ end
+ else if (WIDTH_MODE_A <= 2) begin
+ wire [15:0] tmpa = {3'b0, A_ADDR[15:7], A_ADDR[5:2]};
+ assign addra = tmpa*2 + (tmpa/2);
+ end
+ else if (WIDTH_MODE_A <= 5) begin
+ assign addra = {4'b0, A_ADDR[15:7], A_ADDR[5:3]}*5;
+ end
+ else if (WIDTH_MODE_A <= 10) begin
+ assign addra = {5'b0, A_ADDR[15:7], A_ADDR[5:4]}*10;
+ end
+ else if (WIDTH_MODE_A <= 20) begin
+ assign addra = {6'b0, A_ADDR[15:7], A_ADDR[5]}*20;
+ end
+ // Port B
+ if (WIDTH_MODE_B <= 1) begin
+ wire [15:0] tmpb = {2'b0, B_ADDR[15:7], B_ADDR[5:1]};
+ assign addrb = tmpb + (tmpb/4);
+ end
+ else if (WIDTH_MODE_B <= 2) begin
+ wire [15:0] tmpb = {3'b0, B_ADDR[15:7], B_ADDR[5:2]};
+ assign addrb = tmpb*2 + (tmpb/2);
+ end
+ else if (WIDTH_MODE_B <= 5) begin
+ assign addrb = {4'b0, B_ADDR[15:7], B_ADDR[5:3]}*5;
+ end
+ else if (WIDTH_MODE_B <= 10) begin
+ assign addrb = {5'b0, B_ADDR[15:7], B_ADDR[5:4]}*10;
+ end
+ else if (WIDTH_MODE_B <= 20) begin
+ assign addrb = {6'b0, B_ADDR[15:7], B_ADDR[5]}*20;
+ end
+ end
+ endgenerate
+
+ generate
+ if (RAM_MODE == "SDP") begin
+ // SDP write port
+ always @(posedge clka)
+ begin
+ for (k=0; k < A_WR_WIDTH; k=k+1) begin
+ if (k < 20) begin
+ if (ena && wea && A_BM[k]) memory[addra+k] <= A_DI[k];
+ end
+ else begin // use both ports
+ if (ena && wea && B_BM[k-20]) memory[addra+k] <= B_DI[k-20];
+ end
+ end
+ end
+ // SDP read port
+ always @(posedge clkb)
+ begin
+ // "NO_CHANGE" only
+ for (k=0; k < B_RD_WIDTH; k=k+1) begin
+ if (k < 20) begin
+ if (enb && !wea) A_DO_out[k] <= memory[addrb+k];
+ end
+ else begin // use both ports
+ if (enb && !wea) B_DO_out[k-20] <= memory[addrb+k];
+ end
+ end
+ end
+ end
+ else if (RAM_MODE == "TDP") begin
+ // TDP port A
+ always @(posedge clka)
+ begin
+ for (i=0; i < WIDTH_MODE_A; i=i+1) begin
+ if (ena && wea && A_BM[i]) memory[addra+i] <= A_DI[i];
+
+ if (A_WR_MODE == "NO_CHANGE") begin
+ if (ena && !wea) A_DO_out[i] <= memory[addra+i];
+ end
+ else if (A_WR_MODE == "WRITE_THROUGH") begin
+ if (ena) begin
+ if (wea && A_BM[i]) begin
+ A_DO_out[i] <= A_DI[i];
+ end
+ else begin
+ A_DO_out[i] <= memory[addra+i];
+ end
+ end
+ end
+ end
+ end
+ // TDP port B
+ always @(posedge clkb)
+ begin
+ for (i=0; i < WIDTH_MODE_B; i=i+1) begin
+ if (enb && web && B_BM[i]) memory[addrb+i] <= B_DI[i];
+
+ if (B_WR_MODE == "NO_CHANGE") begin
+ if (enb && !web) B_DO_out[i] <= memory[addrb+i];
+ end
+ else if (B_WR_MODE == "WRITE_THROUGH") begin
+ if (enb) begin
+ if (web && B_BM[i]) begin
+ B_DO_out[i] <= B_DI[i];
+ end
+ else begin
+ B_DO_out[i] <= memory[addrb+i];
+ end
+ end
+ end
+ end
+ end
+ end
+ endgenerate
+
+ // Optional output register
+ generate
+ if (A_DO_REG) begin
+ always @(posedge clka) begin
+ A_DO_reg <= A_DO_out;
+ end
+ assign A_DO = A_DO_reg;
+ end
+ else begin
+ assign A_DO = A_DO_out;
+ end
+ if (B_DO_REG) begin
+ always @(posedge clkb) begin
+ B_DO_reg <= B_DO_out;
+ end
+ assign B_DO = B_DO_reg;
+ end
+ else begin
+ assign B_DO = B_DO_out;
+ end
+ endgenerate
+endmodule
+
+
+module CC_BRAM_40K (
+ output [39:0] A_DO,
+ output [39:0] B_DO,
+ output A_ECC_1B_ERR,
+ output B_ECC_1B_ERR,
+ output A_ECC_2B_ERR,
+ output B_ECC_2B_ERR,
+ output reg A_CO = 0,
+ output reg B_CO = 0,
+ (* clkbuf_sink *)
+ input A_CLK,
+ (* clkbuf_sink *)
+ input B_CLK,
+ input A_EN,
+ input B_EN,
+ input A_WE,
+ input B_WE,
+ input [15:0] A_ADDR,
+ input [15:0] B_ADDR,
+ input [39:0] A_DI,
+ input [39:0] B_DI,
+ input [39:0] A_BM,
+ input [39:0] B_BM,
+ input A_CI,
+ input B_CI
+);
+ // Location format: D(0..N-1)X(0..3)Y(0..7) or UNPLACED
+ parameter LOC = "UNPLACED";
+ parameter CAS = "NONE"; // NONE, UPPER, LOWER
+
+ // Port Widths
+ parameter A_RD_WIDTH = 0;
+ parameter B_RD_WIDTH = 0;
+ parameter A_WR_WIDTH = 0;
+ parameter B_WR_WIDTH = 0;
+
+ // RAM and Write Modes
+ parameter RAM_MODE = "SDP";
+ parameter A_WR_MODE = "NO_CHANGE";
+ parameter B_WR_MODE = "NO_CHANGE";
+
+ // Inverting Control Pins
+ parameter A_CLK_INV = 1'b0;
+ parameter B_CLK_INV = 1'b0;
+ parameter A_EN_INV = 1'b0;
+ parameter B_EN_INV = 1'b0;
+ parameter A_WE_INV = 1'b0;
+ parameter B_WE_INV = 1'b0;
+
+ // Output Register
+ parameter A_DO_REG = 1'b0;
+ parameter B_DO_REG = 1'b0;
+
+ // Error Checking and Correction
+ parameter A_ECC_EN = 1'b0;
+ parameter B_ECC_EN = 1'b0;
+
+ parameter INIT_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_40 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_41 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_42 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_43 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_44 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_45 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_46 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_47 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_48 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_49 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_50 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_51 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_52 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_53 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_54 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_55 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_56 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_57 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_58 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_59 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_60 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_61 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_62 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_63 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_64 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_65 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_66 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_67 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_68 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_69 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_70 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_71 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_72 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_73 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_74 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_75 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_76 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_77 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_78 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_79 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+
+ localparam WIDTH_MODE_A = (A_RD_WIDTH > A_WR_WIDTH) ? A_RD_WIDTH : A_WR_WIDTH;
+ localparam WIDTH_MODE_B = (B_RD_WIDTH > B_WR_WIDTH) ? B_RD_WIDTH : B_WR_WIDTH;
+
+ integer i, k;
+
+ // 512 x 80 bit
+ reg [40959:0] memory = 40960'b0;
+
+ initial begin
+ // Check parameters
+ if ((RAM_MODE != "SDP") && (RAM_MODE != "TDP")) begin
+ $display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
+ $finish();
+ end
+ if ((A_WR_MODE != "WRITE_THROUGH") && (A_WR_MODE != "NO_CHANGE")) begin
+ $display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
+ $finish();
+ end
+ if ((RAM_MODE == "SDP") && (A_WR_MODE == "WRITE_THROUGH")) begin
+ $display("ERROR: %s is not supported in %s mode.", A_WR_MODE, RAM_MODE);
+ $finish();
+ end
+ if ((A_ECC_EN != 1'b0) || (B_ECC_EN != 1'b0)) begin
+ $display("WARNING: ECC feature not supported in simulation.");
+ end
+ if ((A_ECC_EN == 1'b1) && (RAM_MODE != "SDP") && (WIDTH_MODE_A != 40)) begin
+ $display("ERROR: Illegal ECC Port A configuration. Must be SDP 40 bit, but is %s %d.", RAM_MODE, WIDTH_MODE_A);
+ $finish();
+ end
+ if ((WIDTH_MODE_A == 80) && (RAM_MODE == "TDP")) begin
+ $display("ERROR: Port A width of 80 bits is only supported in SDP mode.");
+ $finish();
+ end
+ if ((WIDTH_MODE_B == 80) && (RAM_MODE == "TDP")) begin
+ $display("ERROR: Port B width of 80 bits is only supported in SDP mode.");
+ $finish();
+ end
+ if ((WIDTH_MODE_A != 80) && (WIDTH_MODE_A != 40) && (WIDTH_MODE_A != 20) && (WIDTH_MODE_A != 10) &&
+ (WIDTH_MODE_A != 5) && (WIDTH_MODE_A != 2) && (WIDTH_MODE_A != 1) && (WIDTH_MODE_A != 0)) begin
+ $display("ERROR: Illegal %s Port A width configuration %d.", RAM_MODE, WIDTH_MODE_A);
+ $finish();
+ end
+ if ((WIDTH_MODE_B != 80) && (WIDTH_MODE_B != 40) && (WIDTH_MODE_B != 20) && (WIDTH_MODE_B != 10) &&
+ (WIDTH_MODE_B != 5) && (WIDTH_MODE_B != 2) && (WIDTH_MODE_B != 1) && (WIDTH_MODE_B != 0)) begin
+ $display("ERROR: Illegal %s Port B width configuration %d.", RAM_MODE, WIDTH_MODE_B);
+ $finish();
+ end
+ if ((CAS != "NONE") && ((WIDTH_MODE_A > 1) || (WIDTH_MODE_B > 1))) begin
+ $display("ERROR: Cascade feature only supported in 1 bit data width mode.");
+ $finish();
+ end
+ if ((CAS != "NONE") && (RAM_MODE != "TDP")) begin
+ $display("ERROR: Cascade feature only supported in TDP mode.");
+ $finish();
+ end
+ // RAM initialization
+ memory[320*0+319:320*0] = INIT_00;
+ memory[320*1+319:320*1] = INIT_01;
+ memory[320*2+319:320*2] = INIT_02;
+ memory[320*3+319:320*3] = INIT_03;
+ memory[320*4+319:320*4] = INIT_04;
+ memory[320*5+319:320*5] = INIT_05;
+ memory[320*6+319:320*6] = INIT_06;
+ memory[320*7+319:320*7] = INIT_07;
+ memory[320*8+319:320*8] = INIT_08;
+ memory[320*9+319:320*9] = INIT_09;
+ memory[320*10+319:320*10] = INIT_0A;
+ memory[320*11+319:320*11] = INIT_0B;
+ memory[320*12+319:320*12] = INIT_0C;
+ memory[320*13+319:320*13] = INIT_0D;
+ memory[320*14+319:320*14] = INIT_0E;
+ memory[320*15+319:320*15] = INIT_0F;
+ memory[320*16+319:320*16] = INIT_10;
+ memory[320*17+319:320*17] = INIT_11;
+ memory[320*18+319:320*18] = INIT_12;
+ memory[320*19+319:320*19] = INIT_13;
+ memory[320*20+319:320*20] = INIT_14;
+ memory[320*21+319:320*21] = INIT_15;
+ memory[320*22+319:320*22] = INIT_16;
+ memory[320*23+319:320*23] = INIT_17;
+ memory[320*24+319:320*24] = INIT_18;
+ memory[320*25+319:320*25] = INIT_19;
+ memory[320*26+319:320*26] = INIT_1A;
+ memory[320*27+319:320*27] = INIT_1B;
+ memory[320*28+319:320*28] = INIT_1C;
+ memory[320*29+319:320*29] = INIT_1D;
+ memory[320*30+319:320*30] = INIT_1E;
+ memory[320*31+319:320*31] = INIT_1F;
+ memory[320*32+319:320*32] = INIT_20;
+ memory[320*33+319:320*33] = INIT_21;
+ memory[320*34+319:320*34] = INIT_22;
+ memory[320*35+319:320*35] = INIT_23;
+ memory[320*36+319:320*36] = INIT_24;
+ memory[320*37+319:320*37] = INIT_25;
+ memory[320*38+319:320*38] = INIT_26;
+ memory[320*39+319:320*39] = INIT_27;
+ memory[320*40+319:320*40] = INIT_28;
+ memory[320*41+319:320*41] = INIT_29;
+ memory[320*42+319:320*42] = INIT_2A;
+ memory[320*43+319:320*43] = INIT_2B;
+ memory[320*44+319:320*44] = INIT_2C;
+ memory[320*45+319:320*45] = INIT_2D;
+ memory[320*46+319:320*46] = INIT_2E;
+ memory[320*47+319:320*47] = INIT_2F;
+ memory[320*48+319:320*48] = INIT_30;
+ memory[320*49+319:320*49] = INIT_31;
+ memory[320*50+319:320*50] = INIT_32;
+ memory[320*51+319:320*51] = INIT_33;
+ memory[320*52+319:320*52] = INIT_34;
+ memory[320*53+319:320*53] = INIT_35;
+ memory[320*54+319:320*54] = INIT_36;
+ memory[320*55+319:320*55] = INIT_37;
+ memory[320*56+319:320*56] = INIT_38;
+ memory[320*57+319:320*57] = INIT_39;
+ memory[320*58+319:320*58] = INIT_3A;
+ memory[320*59+319:320*59] = INIT_3B;
+ memory[320*60+319:320*60] = INIT_3C;
+ memory[320*61+319:320*61] = INIT_3D;
+ memory[320*62+319:320*62] = INIT_3E;
+ memory[320*63+319:320*63] = INIT_3F;
+ memory[320*64+319:320*64] = INIT_40;
+ memory[320*65+319:320*65] = INIT_41;
+ memory[320*66+319:320*66] = INIT_42;
+ memory[320*67+319:320*67] = INIT_43;
+ memory[320*68+319:320*68] = INIT_44;
+ memory[320*69+319:320*69] = INIT_45;
+ memory[320*70+319:320*70] = INIT_46;
+ memory[320*71+319:320*71] = INIT_47;
+ memory[320*72+319:320*72] = INIT_48;
+ memory[320*73+319:320*73] = INIT_49;
+ memory[320*74+319:320*74] = INIT_4A;
+ memory[320*75+319:320*75] = INIT_4B;
+ memory[320*76+319:320*76] = INIT_4C;
+ memory[320*77+319:320*77] = INIT_4D;
+ memory[320*78+319:320*78] = INIT_4E;
+ memory[320*79+319:320*79] = INIT_4F;
+ memory[320*80+319:320*80] = INIT_50;
+ memory[320*81+319:320*81] = INIT_51;
+ memory[320*82+319:320*82] = INIT_52;
+ memory[320*83+319:320*83] = INIT_53;
+ memory[320*84+319:320*84] = INIT_54;
+ memory[320*85+319:320*85] = INIT_55;
+ memory[320*86+319:320*86] = INIT_56;
+ memory[320*87+319:320*87] = INIT_57;
+ memory[320*88+319:320*88] = INIT_58;
+ memory[320*89+319:320*89] = INIT_59;
+ memory[320*90+319:320*90] = INIT_5A;
+ memory[320*91+319:320*91] = INIT_5B;
+ memory[320*92+319:320*92] = INIT_5C;
+ memory[320*93+319:320*93] = INIT_5D;
+ memory[320*94+319:320*94] = INIT_5E;
+ memory[320*95+319:320*95] = INIT_5F;
+ memory[320*96+319:320*96] = INIT_60;
+ memory[320*97+319:320*97] = INIT_61;
+ memory[320*98+319:320*98] = INIT_62;
+ memory[320*99+319:320*99] = INIT_63;
+ memory[320*100+319:320*100] = INIT_64;
+ memory[320*101+319:320*101] = INIT_65;
+ memory[320*102+319:320*102] = INIT_66;
+ memory[320*103+319:320*103] = INIT_67;
+ memory[320*104+319:320*104] = INIT_68;
+ memory[320*105+319:320*105] = INIT_69;
+ memory[320*106+319:320*106] = INIT_6A;
+ memory[320*107+319:320*107] = INIT_6B;
+ memory[320*108+319:320*108] = INIT_6C;
+ memory[320*109+319:320*109] = INIT_6D;
+ memory[320*110+319:320*110] = INIT_6E;
+ memory[320*111+319:320*111] = INIT_6F;
+ memory[320*112+319:320*112] = INIT_70;
+ memory[320*113+319:320*113] = INIT_71;
+ memory[320*114+319:320*114] = INIT_72;
+ memory[320*115+319:320*115] = INIT_73;
+ memory[320*116+319:320*116] = INIT_74;
+ memory[320*117+319:320*117] = INIT_75;
+ memory[320*118+319:320*118] = INIT_76;
+ memory[320*119+319:320*119] = INIT_77;
+ memory[320*120+319:320*120] = INIT_78;
+ memory[320*121+319:320*121] = INIT_79;
+ memory[320*122+319:320*122] = INIT_7A;
+ memory[320*123+319:320*123] = INIT_7B;
+ memory[320*124+319:320*124] = INIT_7C;
+ memory[320*125+319:320*125] = INIT_7D;
+ memory[320*126+319:320*126] = INIT_7E;
+ memory[320*127+319:320*127] = INIT_7F;
+ end
+
+ // Signal inversion
+ wire clka = A_CLK_INV ^ A_CLK;
+ wire clkb = B_CLK_INV ^ B_CLK;
+ wire ena = A_EN_INV ^ A_EN;
+ wire enb = B_EN_INV ^ B_EN;
+ wire wea = A_WE_INV ^ A_WE;
+ wire web = B_WE_INV ^ B_WE;
+
+ // Internal signals
+ wire [15:0] addra;
+ wire [15:0] addrb;
+ reg [39:0] A_DO_out = 0, A_DO_reg = 0;
+ reg [39:0] B_DO_out = 0, B_DO_reg = 0;
+
+ generate
+ if (RAM_MODE == "SDP") begin
+ // Port A (write)
+ if (A_WR_WIDTH == 80) begin
+ assign addra = A_ADDR[15:7]*80;
+ end
+ // Port B (read)
+ if (B_RD_WIDTH == 80) begin
+ assign addrb = B_ADDR[15:7]*80;
+ end
+ end
+ else if (RAM_MODE == "TDP") begin
+ // Port A
+ if (WIDTH_MODE_A <= 1) begin
+ wire [15:0] tmpa = {1'b0, A_ADDR[15:1]};
+ assign addra = tmpa + (tmpa/4);
+ end
+ else if (WIDTH_MODE_A <= 2) begin
+ wire [15:0] tmpa = {2'b0, A_ADDR[15:2]};
+ assign addra = tmpa*2 + (tmpa/2);
+ end
+ else if (WIDTH_MODE_A <= 5) begin
+ assign addra = {3'b0, A_ADDR[15:3]}*5;
+ end
+ else if (WIDTH_MODE_A <= 10) begin
+ assign addra = {4'b0, A_ADDR[15:4]}*10;
+ end
+ else if (WIDTH_MODE_A <= 20) begin
+ assign addra = {5'b0, A_ADDR[15:5]}*20;
+ end
+ else if (WIDTH_MODE_A <= 40) begin
+ assign addra = {6'b0, A_ADDR[15:6]}*40;
+ end
+ // Port B
+ if (WIDTH_MODE_B <= 1) begin
+ wire [15:0] tmpb = {1'b0, B_ADDR[15:1]};
+ assign addrb = tmpb + (tmpb/4);
+ end
+ else if (WIDTH_MODE_B <= 2) begin
+ wire [15:0] tmpb = {2'b0, B_ADDR[15:2]};
+ assign addrb = tmpb*2 + (tmpb/2);
+ end
+ else if (WIDTH_MODE_B <= 5) begin
+ assign addrb = {3'b0, B_ADDR[15:3]}*5;
+ end
+ else if (WIDTH_MODE_B <= 10) begin
+ assign addrb = {4'b0, B_ADDR[15:4]}*10;
+ end
+ else if (WIDTH_MODE_B <= 20) begin
+ assign addrb = {5'b0, B_ADDR[15:5]}*20;
+ end
+ else if (WIDTH_MODE_B <= 40) begin
+ assign addrb = {6'b0, B_ADDR[15:6]}*40;
+ end
+ end
+ endgenerate
+
+ generate
+ if (RAM_MODE == "SDP") begin
+ // SDP write port
+ always @(posedge clka)
+ begin
+ for (k=0; k < A_WR_WIDTH; k=k+1) begin
+ if (k < 40) begin
+ if (ena && wea && A_BM[k]) memory[addra+k] <= A_DI[k];
+ end
+ else begin // use both ports
+ if (ena && wea && B_BM[k-40]) memory[addra+k] <= B_DI[k-40];
+ end
+ end
+ end
+ // SDP read port
+ always @(posedge clkb)
+ begin
+ // "NO_CHANGE" only
+ for (k=0; k < B_RD_WIDTH; k=k+1) begin
+ if (k < 40) begin
+ if (enb && !wea) A_DO_out[k] <= memory[addrb+k];
+ end
+ else begin // use both ports
+ if (enb && !wea) B_DO_out[k-40] <= memory[addrb+k];
+ end
+ end
+ end
+ end
+ else if (RAM_MODE == "TDP") begin
+ // {A,B}_ADDR[0]=0 selects lower, {A,B}_ADDR[0]=1 selects upper cascade memory
+ wire upper_sel_a = ((CAS == "UPPER") && (A_ADDR[0] == 1));
+ wire lower_sel_a = ((CAS == "LOWER") && (A_ADDR[0] == 0));
+ wire upper_sel_b = ((CAS == "UPPER") && (B_ADDR[0] == 1));
+ wire lower_sel_b = ((CAS == "LOWER") && (B_ADDR[0] == 0));
+
+ reg dumm;
+
+ // Cascade output port A
+ always @(*)
+ begin
+ if ((A_WR_MODE == "NO_CHANGE") && lower_sel_a) begin
+ A_CO = memory[addra];
+ end
+ else if ((A_WR_MODE == "WRITE_THROUGH") && lower_sel_a) begin
+ A_CO = ((wea && A_BM[0]) ? (A_DI[0]) : (memory[addra]));
+ end
+ end
+
+ // Cascade output port B
+ always @(*)
+ begin
+ if ((B_WR_MODE == "NO_CHANGE") && lower_sel_b) begin
+ B_CO = memory[addrb];
+ end
+ else if ((B_WR_MODE == "WRITE_THROUGH") && lower_sel_b) begin
+ B_CO = ((web && B_BM[0]) ? (B_DI[0]) : (memory[addrb]));
+ end
+ end
+
+ // TDP port A
+ always @(posedge clka)
+ begin
+ for (i=0; i < WIDTH_MODE_A; i=i+1) begin
+ if (upper_sel_a || lower_sel_a || (CAS == "NONE")) begin
+ if (ena && wea && A_BM[i])
+ memory[addra+i] <= A_DI[i];
+ end
+
+ if (A_WR_MODE == "NO_CHANGE") begin
+ if (ena && !wea) begin
+ if (CAS == "UPPER") begin
+ A_DO_out[i] <= ((A_ADDR[0] == 1) ? (memory[addra+i]) : (A_CI));
+ end
+ else if (CAS == "NONE") begin
+ A_DO_out[i] <= memory[addra+i];
+ end
+ end
+ end
+ else if (A_WR_MODE == "WRITE_THROUGH") begin
+ if (ena) begin
+ if (CAS == "UPPER") begin
+ if (A_ADDR[0] == 1) begin
+ A_DO_out[i] <= ((wea && A_BM[i]) ? (A_DI[i]) : (memory[addra+i]));
+ end else begin
+ A_DO_out[i] <= A_CI;
+ end
+ end
+ else if (CAS == "NONE") begin
+ A_DO_out[i] <= ((wea && A_BM[i]) ? (A_DI[i]) : (memory[addra+i]));
+ end
+ end
+ end
+ end
+ end
+ // TDP port B
+ always @(posedge clkb)
+ begin
+ for (i=0; i < WIDTH_MODE_B; i=i+1) begin
+ if (upper_sel_b || lower_sel_b || (CAS == "NONE")) begin
+ if (enb && web && B_BM[i])
+ memory[addrb+i] <= B_DI[i];
+ end
+
+ if (B_WR_MODE == "NO_CHANGE") begin
+ if (enb && !web) begin
+ if (CAS == "UPPER") begin
+ B_DO_out[i] <= ((B_ADDR[0] == 1) ? (memory[addrb+i]) : (B_CI));
+ end
+ else if (CAS == "NONE") begin
+ B_DO_out[i] <= memory[addrb+i];
+ end
+ end
+ end
+ else if (B_WR_MODE == "WRITE_THROUGH") begin
+ if (enb) begin
+ if (CAS == "UPPER") begin
+ if (B_ADDR[0] == 1) begin
+ B_DO_out[i] <= ((web && B_BM[i]) ? (B_DI[i]) : (memory[addrb+i]));
+ end else begin
+ B_DO_out[i] <= B_CI;
+ end
+ end
+ else if (CAS == "NONE") begin
+ B_DO_out[i] <= ((web && B_BM[i]) ? (B_DI[i]) : (memory[addrb+i]));
+ end
+ end
+ end
+ end
+ end
+ end
+ endgenerate
+
+ // Optional output register
+ generate
+ if (A_DO_REG) begin
+ always @(posedge clka) begin
+ A_DO_reg <= A_DO_out;
+ end
+ assign A_DO = A_DO_reg;
+ end
+ else begin
+ assign A_DO = A_DO_out;
+ end
+ if (B_DO_REG) begin
+ always @(posedge clkb) begin
+ B_DO_reg <= B_DO_out;
+ end
+ assign B_DO = B_DO_reg;
+ end
+ else begin
+ assign B_DO = B_DO_out;
+ end
+ endgenerate
+endmodule
diff --git a/techlibs/gatemate/lut_map.v b/techlibs/gatemate/lut_map.v new file mode 100644 index 000000000..1e5d49725 --- /dev/null +++ b/techlibs/gatemate/lut_map.v @@ -0,0 +1,45 @@ +/*
+ * 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 \$lut (A, Y);
+ parameter WIDTH = 0;
+ parameter LUT = 0;
+
+ (* force_downto *)
+ input [WIDTH-1:0] A;
+ output Y;
+
+ generate
+ if (WIDTH == 1) begin
+ CC_LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]));
+ end
+ else if (WIDTH == 2) begin
+ CC_LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]));
+ end
+ else if (WIDTH == 3) begin
+ CC_LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]));
+ end
+ else if (WIDTH == 4) begin
+ CC_LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3]));
+ end
+ else begin
+ wire _TECHMAP_FAIL_ = 1;
+ end
+ endgenerate
+endmodule
diff --git a/techlibs/gatemate/mul_map.v b/techlibs/gatemate/mul_map.v new file mode 100644 index 000000000..c2dd0a9b4 --- /dev/null +++ b/techlibs/gatemate/mul_map.v @@ -0,0 +1,77 @@ +/* + * 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. + * + */ + +(* techmap_celltype = "$mul $__mul" *) +module \$__MULMXN (A, B, Y); + + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] Y; + + localparam A_ADJWIDTH = A_WIDTH + (A_SIGNED ? 0 : 1); + localparam B_ADJWIDTH = B_WIDTH + (B_SIGNED ? 0 : 1); + + generate + if (A_SIGNED) begin: blkA + wire signed [A_ADJWIDTH-1:0] Aext = $signed(A); + end + else begin: blkA + wire [A_ADJWIDTH-1:0] Aext = A; + end + if (B_SIGNED) begin: blkB + wire signed [B_ADJWIDTH-1:0] Bext = $signed(B); + end + else begin: blkB + wire [B_ADJWIDTH-1:0] Bext = B; + end + + if (A_WIDTH >= B_WIDTH) begin + CC_MULT #( + .A_WIDTH(A_ADJWIDTH), + .B_WIDTH(B_ADJWIDTH), + .P_WIDTH(Y_WIDTH), + ) _TECHMAP_REPLACE_ ( + .A(blkA.Aext), + .B(blkB.Bext), + .P(Y) + ); + end + else begin // swap A,B + CC_MULT #( + .A_WIDTH(B_ADJWIDTH), + .B_WIDTH(A_ADJWIDTH), + .P_WIDTH(Y_WIDTH), + ) _TECHMAP_REPLACE_ ( + .A(blkB.Bext), + .B(blkA.Aext), + .P(Y) + ); + end + endgenerate + +endmodule diff --git a/techlibs/gatemate/mux_map.v b/techlibs/gatemate/mux_map.v new file mode 100644 index 000000000..13c1972e3 --- /dev/null +++ b/techlibs/gatemate/mux_map.v @@ -0,0 +1,56 @@ +/*
+ * 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 \$_MUX8_ (A, B, C, D, E, F, G, H, S, T, U, Y);
+ input A, B, C, D, E, F, G, H, S, T, U;
+ output Y;
+
+ CC_MX8 _TECHMAP_REPLACE_ (
+ .D0(A), .D1(B), .D2(C), .D3(D),
+ .D4(E), .D5(F), .D6(G), .D7(H),
+ .S0(S), .S1(T), .S2(U),
+ .Y(Y)
+ );
+
+endmodule
+
+module \$_MUX4_ (A, B, C, D, S, T, Y);
+ input A, B, C, D, S, T;
+ output Y;
+
+ CC_MX4 _TECHMAP_REPLACE_ (
+ .D0(A), .D1(B), .D2(C), .D3(D),
+ .S0(S), .S1(T),
+ .Y(Y)
+ );
+
+endmodule
+
+/*
+module \$_MUX_ (A, B, S, Y);
+ input A, B, S;
+ output Y;
+
+ CC_MX2 _TECHMAP_REPLACE_ (
+ .D0(A), .D1(B), .S0(S),
+ .Y(Y)
+ );
+
+endmodule
+*/
diff --git a/techlibs/gatemate/reg_map.v b/techlibs/gatemate/reg_map.v new file mode 100644 index 000000000..6a2c7fb91 --- /dev/null +++ b/techlibs/gatemate/reg_map.v @@ -0,0 +1,45 @@ +/*
+ * 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.
+ *
+ */
+
+(* techmap_celltype = "$_DFFE_[NP][NP][01][NP]_" *)
+module \$_DFFE_xxxx_ (input D, C, R, E, output Q);
+
+ parameter _TECHMAP_CELLTYPE_ = "";
+
+ CC_DFF #(
+ .CLK_INV(_TECHMAP_CELLTYPE_[39:32] == "N"),
+ .EN_INV(_TECHMAP_CELLTYPE_[15:8] == "N"),
+ .SR_INV(_TECHMAP_CELLTYPE_[31:24] == "N"),
+ .SR_VAL(_TECHMAP_CELLTYPE_[23:16] == "1")
+ ) _TECHMAP_REPLACE_ (.D(D), .EN(E), .CLK(C), .SR(R), .Q(Q));
+
+endmodule
+
+(* techmap_celltype = "$_DLATCH_[NP][NP][01]_" *)
+module \$_DLATCH_xxx_ (input E, R, D, output Q);
+
+ parameter _TECHMAP_CELLTYPE_ = "";
+
+ CC_DLT #(
+ .G_INV(_TECHMAP_CELLTYPE_[31:24] == "N"),
+ .SR_INV(_TECHMAP_CELLTYPE_[23:16] == "N"),
+ .SR_VAL(_TECHMAP_CELLTYPE_[15:8] == "1")
+ ) _TECHMAP_REPLACE_ (.D(D), .G(E), .SR(R), .Q(Q));
+
+endmodule
diff --git a/techlibs/gatemate/synth_gatemate.cc b/techlibs/gatemate/synth_gatemate.cc new file mode 100644 index 000000000..0131cdcdf --- /dev/null +++ b/techlibs/gatemate/synth_gatemate.cc @@ -0,0 +1,351 @@ +/*
+ * 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.
+ *
+ */
+
+#include "kernel/register.h"
+#include "kernel/celltypes.h"
+#include "kernel/rtlil.h"
+#include "kernel/log.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct SynthGateMatePass : public ScriptPass
+{
+ SynthGateMatePass() : ScriptPass("synth_gatemate", "synthesis for Cologne Chip GateMate FPGAs") { }
+
+ void help() override
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" synth_gatemate [options]\n");
+ log("\n");
+ log("This command runs synthesis for Cologne Chip AG GateMate FPGAs.\n");
+ log("\n");
+ log(" -top <module>\n");
+ log(" use the specified module as top module.\n");
+ log("\n");
+ log(" -vlog <file>\n");
+ log(" write the design to the specified verilog file. Writing of an output\n");
+ log(" file is omitted if this parameter is not specified.\n");
+ log("\n");
+ log(" -json <file>\n");
+ log(" write the design to the specified JSON file. Writing of an output file\n");
+ log(" is omitted if this parameter is not specified.\n");
+ log("\n");
+ log(" -run <from_label>:<to_label>\n");
+ log(" only run the commands between the labels (see below). An empty\n");
+ 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(" -noflatten\n");
+ log(" do not flatten design before synthesis.\n");
+ log("\n");
+ log(" -nobram\n");
+ log(" do not use CC_BRAM_20K or CC_BRAM_40K cells in output netlist.\n");
+ log("\n");
+ log(" -noaddf\n");
+ log(" do not use CC_ADDF full adder cells in output netlist.\n");
+ log("\n");
+ log(" -nomult\n");
+ log(" do not use CC_MULT multiplier cells in output netlist.\n");
+ log("\n");
+ log(" -nomx8, -nomx4\n");
+ log(" do not use CC_MX{8,4} multiplexer cells in output netlist.\n");
+ log("\n");;
+ log(" -dff\n");
+ log(" run 'abc' with -dff option\n");
+ log("\n");
+ log(" -retime\n");
+ log(" run 'abc' with '-dff -D 1' options\n");
+ log("\n");
+ log(" -noiopad\n");
+ log(" disable I/O buffer insertion (useful for hierarchical or \n");
+ log(" out-of-context flows).\n");
+ log("\n");
+ log(" -noclkbuf\n");
+ log(" disable automatic clock buffer insertion.\n");
+ log("\n");
+ log("The following commands are executed by this synthesis command:\n");
+ help_script();
+ log("\n");
+ }
+
+ string top_opt, vlog_file, json_file;
+ bool noflatten, nobram, noaddf, nomult, nomx4, nomx8, dff, retime, noiopad, noclkbuf;
+
+ void clear_flags() override
+ {
+ top_opt = "-auto-top";
+ vlog_file = "";
+ json_file = "";
+ noflatten = false;
+ nobram = false;
+ noaddf = false;
+ nomult = false;
+ nomx4 = false;
+ nomx8 = false;
+ dff = false;
+ retime = false;
+ noiopad = false;
+ noclkbuf = false;
+ }
+
+ void execute(std::vector<std::string> args, RTLIL::Design *design) override
+ {
+ string run_from, run_to;
+ clear_flags();
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+ if (args[argidx] == "-top" && argidx+1 < args.size()) {
+ top_opt = "-top " + args[++argidx];
+ continue;
+ }
+ if (args[argidx] == "-vlog" && argidx+1 < args.size()) {
+ vlog_file = args[++argidx];
+ continue;
+ }
+ if (args[argidx] == "-json" && argidx+1 < args.size()) {
+ json_file = args[++argidx];
+ continue;
+ }
+ if (args[argidx] == "-run" && argidx+1 < args.size()) {
+ size_t pos = args[argidx+1].find(':');
+ if (pos == std::string::npos)
+ break;
+ run_from = args[++argidx].substr(0, pos);
+ run_to = args[argidx].substr(pos+1);
+ continue;
+ }
+ if (args[argidx] == "-noflatten") {
+ noflatten = true;
+ continue;
+ }
+ if (args[argidx] == "-nobram") {
+ nobram = true;
+ continue;
+ }
+ if (args[argidx] == "-noaddf") {
+ noaddf = true;
+ continue;
+ }
+ if (args[argidx] == "-nomult") {
+ nomult = true;
+ continue;
+ }
+ if (args[argidx] == "-nomx4") {
+ nomx4 = true;
+ continue;
+ }
+ if (args[argidx] == "-nomx8") {
+ nomx8 = true;
+ continue;
+ }
+ if (args[argidx] == "-dff") {
+ dff = true;
+ continue;
+ }
+ if (args[argidx] == "-retime") {
+ retime = true;
+ continue;
+ }
+ if (args[argidx] == "-noiopad") {
+ noiopad = true;
+ continue;
+ }
+ if (args[argidx] == "-noclkbuf") {
+ noclkbuf = true;
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ if (!design->full_selection()) {
+ log_cmd_error("This command only operates on fully selected designs!\n");
+ }
+
+ log_header(design, "Executing SYNTH_GATEMATE pass.\n");
+ log_push();
+
+ run_script(design, run_from, run_to);
+
+ log_pop();
+ }
+
+ void script() override
+ {
+ if (check_label("begin"))
+ {
+ run("read_verilog -lib -specify +/gatemate/cells_sim.v +/gatemate/cells_bb.v");
+ run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
+ }
+
+ if (check_label("prepare"))
+ {
+ run("proc");
+ if (!noflatten) {
+ run("flatten");
+ }
+ run("tribuf -logic");
+ run("deminout");
+ run("opt_expr");
+ run("opt_clean");
+ run("check");
+ run("opt -nodffe -nosdff");
+ run("fsm");
+ run("opt");
+ run("wreduce");
+ run("peepopt");
+ run("opt_clean");
+ run("muxpack");
+ run("share");
+ run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
+ run("opt_expr");
+ run("opt_clean");
+ }
+
+ if (check_label("map_mult", "(skip if '-nomult')") && !nomult)
+ {
+ run("techmap -map +/gatemate/mul_map.v");
+ }
+
+ if (check_label("coarse"))
+ {
+ run("alumacc");
+ run("opt");
+ run("memory -nomap");
+ run("opt_clean");
+ }
+
+ 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("techmap -map +/gatemate/brams_map.v");
+ }
+
+ if (check_label("map_ffram"))
+ {
+ run("opt -fast -mux_undef -undriven -fine");
+ run("memory_map");
+ run("opt -undriven -fine");
+ }
+
+ if (check_label("map_gates"))
+ {
+ std::string techmap_args = "";
+ if (!noaddf) {
+ techmap_args += " -map +/gatemate/arith_map.v";
+ }
+ run("techmap -map +/techmap.v " + techmap_args);
+ run("opt -fast");
+ if (retime) {
+ run("abc -dff -D 1", "(only if -retime)");
+ }
+ }
+
+ if (check_label("map_io", "(skip if '-noiopad')") && !noiopad)
+ {
+ run("iopadmap -bits "
+ "-inpad CC_IBUF Y:I "
+ "-outpad CC_OBUF A:O "
+ "-toutpad CC_TOBUF ~T:A:O "
+ "-tinoutpad CC_IOBUF ~T:Y:A:IO"
+ );
+ run("clean");
+ }
+
+ if (check_label("map_regs"))
+ {
+ run("opt_clean");
+ run("dfflegalize -cell $_DFFE_????_ x -cell $_DLATCH_???_ x");
+ run("techmap -map +/gatemate/reg_map.v");
+ run("opt_expr -mux_undef");
+ run("simplemap");
+ run("opt_clean");
+ }
+
+ if (check_label("map_muxs"))
+ {
+ std::string muxcover_args;
+ if (!nomx4) {
+ muxcover_args += stringf(" -mux4");
+ }
+ if (!nomx8) {
+ muxcover_args += stringf(" -mux8");
+ }
+ run("muxcover " + muxcover_args);
+ run("opt -full");
+ run("techmap -map +/gatemate/mux_map.v");
+ }
+
+ if (check_label("map_luts"))
+ {
+ std::string abc_args = " -dress -lut 4";
+ if (dff) {
+ abc_args += " -dff";
+ }
+ run("abc " + abc_args);
+ run("clean");
+ }
+
+ if (check_label("map_cells"))
+ {
+ run("techmap -map +/gatemate/lut_map.v");
+ run("clean");
+ }
+
+ if (check_label("map_bufg", "(skip if '-noclkbuf')") && !noclkbuf)
+ {
+ run("clkbufmap -buf CC_BUFG O:I");
+ run("clean");
+ }
+
+ if (check_label("check"))
+ {
+ run("hierarchy -check");
+ run("stat -width");
+ run("check -noinit");
+ run("blackbox =A:whitebox");
+ }
+
+ if (check_label("vlog"))
+ {
+ run("opt_clean -purge");
+ if (!vlog_file.empty() || help_mode) {
+ run(stringf("write_verilog -noattr %s", help_mode ? "<file-name>" : vlog_file.c_str()));
+ }
+ }
+
+ if (check_label("json"))
+ {
+ if (!json_file.empty() || help_mode) {
+ run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
+ }
+ }
+ }
+} SynthGateMatePass;
+
+PRIVATE_NAMESPACE_END
|