xilinx: Add URAM288 mapping for xcup
authorDavid Shah <dave@ds0.me>
Fri, 18 Oct 2019 13:02:57 +0000 (14:02 +0100)
committerDavid Shah <dave@ds0.me>
Wed, 23 Oct 2019 10:47:44 +0000 (11:47 +0100)
Signed-off-by: David Shah <dave@ds0.me>
techlibs/xilinx/Makefile.inc
techlibs/xilinx/synth_xilinx.cc
techlibs/xilinx/xcu_brams_bb.v
techlibs/xilinx/xcup_urams.txt [new file with mode: 0644]
techlibs/xilinx/xcup_urams_map.v [new file with mode: 0644]

index 6fc41f591a1f4b97fd3badd8cf827703477cb311..debe8a6a093256c1b388a039ecae2962cad53bb3 100644 (file)
@@ -37,6 +37,8 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_map.v))
 $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_bb.v))
 $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_brams_map.v))
 $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_brams_bb.v))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams_map.v))
 $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams.txt))
 $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v))
 $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
index 825addf84f651d40de30e0b65a70432d067c3d58..69b071d34dc35cba179eea37928131c7820cc992 100644 (file)
@@ -93,6 +93,9 @@ struct SynthXilinxPass : public ScriptPass
                log("    -noclkbuf\n");
                log("        disable automatic clock buffer insertion\n");
                log("\n");
+               log("    -uram\n");
+               log("        infer URAM288s for large memories (xcup only)\n");
+               log("\n");
                log("    -widemux <int>\n");
                log("        enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n");
                log("        above this number of inputs (minimum value 2, recommended value >= 5).\n");
@@ -119,7 +122,7 @@ struct SynthXilinxPass : public ScriptPass
        }
 
        std::string top_opt, edif_file, blif_file, family;
-       bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, abc9;
+       bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, uram, abc9;
        bool flatten_before_abc;
        int widemux;
 
@@ -143,6 +146,7 @@ struct SynthXilinxPass : public ScriptPass
                nocarry = false;
                nowidelut = false;
                nodsp = false;
+               uram = false;
                abc9 = false;
                flatten_before_abc = false;
                widemux = 0;
@@ -248,6 +252,10 @@ struct SynthXilinxPass : public ScriptPass
                                nodsp = true;
                                continue;
                        }
+                       if (args[argidx] == "-uram") {
+                               uram = true;
+                               continue;
+                       }
                        break;
                }
                extra_args(args, argidx, design);
@@ -410,6 +418,20 @@ struct SynthXilinxPass : public ScriptPass
                        run("opt_clean");
                }
 
+               if (check_label("map_uram", "(only if '-uram')")) {
+                       if (help_mode) {
+                               run("memory_bram -rules +/xilinx/{family}_urams.txt");
+                               run("techmap -map +/xilinx/{family}_urams_map.v");
+                       } else if (uram) {
+                               if (family == "xcup") {
+                                       run("memory_bram -rules +/xilinx/xcup_urams.txt");
+                                       run("techmap -map +/xilinx/xcup_urams_map.v");
+                               } else {
+                                       log_warning("UltraRAM inference not supported for family %s.\n", family.c_str());
+                               }
+                       }
+               }
+
                if (check_label("map_bram", "(skip if '-nobram')")) {
                        if (help_mode) {
                                run("memory_bram -rules +/xilinx/{family}_brams.txt");
index f3e43d0d6e52c039e093316055cf09c5ea90029d..cc70ce371ff3672e4d8854247982330243881ac4 100644 (file)
@@ -402,4 +402,4 @@ module RAMB36E2 (...);
     input SLEEP;
     input [3:0] WEA;
     input [7:0] WEBWE;
-endmodule
\ No newline at end of file
+endmodule
diff --git a/techlibs/xilinx/xcup_urams.txt b/techlibs/xilinx/xcup_urams.txt
new file mode 100644 (file)
index 0000000..40c4742
--- /dev/null
@@ -0,0 +1,19 @@
+bram $__XILINX_URAM288
+  init 0
+  abits 12
+  dbits 72
+  groups 2
+  ports  1 1
+  wrmode 0 1
+  enable 1 9
+  transp 0 0
+  clocks 2 2
+  clkpol 2 2
+endbram
+
+match $__XILINX_URAM288
+  min bits 131072
+  min efficiency 15
+  shuffle_enable B
+  make_transp
+endmatch
diff --git a/techlibs/xilinx/xcup_urams_map.v b/techlibs/xilinx/xcup_urams_map.v
new file mode 100644 (file)
index 0000000..f15211b
--- /dev/null
@@ -0,0 +1,47 @@
+module \$__XILINX_URAM288 (CLK2, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+       parameter CLKPOL2 = 1;
+
+       input CLK2;
+
+       input [11:0] A1ADDR;
+       output [71:0] A1DATA;
+       input A1EN;
+
+       input [11:0] B1ADDR;
+       input [71:0] B1DATA;
+       input [8:0] B1EN;
+
+
+       URAM288 #(
+               .BWE_MODE_A("PARITY_INDEPENDENT"),
+               .BWE_MODE_B("PARITY_INDEPENDENT"),
+               .EN_AUTO_SLEEP_MODE("FALSE"),
+               .IREG_PRE_A("FALSE"),
+               .IREG_PRE_B("FALSE"),
+               .IS_CLK_INVERTED(!CLKPOL2),
+               .OREG_A("FALSE"),
+               .OREG_B("FALSE")
+       ) _TECHMAP_REPLACE_ (
+               .ADDR_A({11'b0, A1ADDR}),
+               .BWE_A(9'b0),
+               .DIN_A(72'b0),
+               .EN_A(A1EN),
+               .RDB_WR_A(1'b0),
+               .INJECT_DBITERR_A(1'b0),
+               .INJECT_SBITERR_A(1'b0),
+               .RST_A(1'b0),
+               .DOUT_A(A1DATA),
+
+               .ADDR_B({11'b0, B1ADDR}),
+               .BWE_B(B1EN),
+               .DIN_B(B1DATA),
+               .EN_B(|B1EN),
+               .RDB_WR_B(1'b1),
+               .INJECT_DBITERR_B(1'b0),
+               .INJECT_SBITERR_B(1'b0),
+               .RST_B(1'b0),
+
+               .CLK(CLK2),
+               .SLEEP(1'b0)
+       );
+endmodule