diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v index 6550b75cf..d0ddfd02e 100644 --- a/techlibs/ice40/cells_map.v +++ b/techlibs/ice40/cells_map.v @@ -27,7 +27,7 @@ module \$__DFFE_NP1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ ( module \$__DFFE_PP0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule module \$__DFFE_PP1 (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule -`ifndef NO_SB_LUT4 +`ifndef NO_LUT module \$lut (A, Y); parameter WIDTH = 0; parameter LUT = 0; diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 42873305e..177581d53 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -219,7 +219,7 @@ struct SynthIce40Pass : public ScriptPass run("dffsr2dff"); if (!nodffe) run("dff2dffe -direct-match $_DFF_*"); - run("techmap -D NO_SB_LUT4 -map +/ice40/cells_map.v"); + run("techmap -D NO_LUT -map +/ice40/cells_map.v"); run("opt_expr -mux_undef"); run("simplemap"); run("ice40_ffinit"); @@ -241,9 +241,9 @@ struct SynthIce40Pass : public ScriptPass if (check_label("map_cells")) { if (vpr) - run("techmap -D NO_SB_LUT4 -map +/ice40/cells_map.v"); + run("techmap -D NO_LUT -map +/ice40/cells_map.v"); else - run("techmap -map +/ice40/cells_map.v", "(with -D NO_SB_LUT4 in vpr mode)"); + run("techmap -map +/ice40/cells_map.v", "(with -D NO_LUT in vpr mode)"); run("clean"); } @@ -260,13 +260,17 @@ struct SynthIce40Pass : public ScriptPass if (!blif_file.empty() || help_mode) { if (vpr || help_mode) { run(stringf("opt_clean -purge"), - " (vpr mode)"); - run(stringf("write_blif %s", help_mode ? "" : blif_file.c_str()), - " (vpr mode)"); + " " + " (vpr mode)"); + run(stringf("write_blif -attr -cname -conn -param %s", + help_mode ? "" : blif_file.c_str()), + " (vpr mode)"); } if (!vpr) run(stringf("write_blif -gates -attr -param %s", - help_mode ? "" : blif_file.c_str()), "(non-vpr mode)"); + help_mode ? "" : blif_file.c_str()), + " " + " (non-vpr mode)"); } } diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 8e5a83ce5..0771be0b9 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -15,6 +15,7 @@ module \$_DFF_NP1_ (input D, C, R, output Q); FDPE #(.INIT(|0), .IS_C_INVERTED( module \$_DFF_PN1_ (input D, C, R, output Q); FDPE #(.INIT(|0), .IS_C_INVERTED(|0), .IS_D_INVERTED(|0), .IS_PRE_INVERTED(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(R)); endmodule module \$_DFF_PP1_ (input D, C, R, output Q); FDPE #(.INIT(|0), .IS_C_INVERTED(|0), .IS_D_INVERTED(|0), .IS_PRE_INVERTED(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(R)); endmodule +`ifndef NO_LUT module \$lut (A, Y); parameter WIDTH = 0; parameter LUT = 0; @@ -82,3 +83,4 @@ module \$lut (A, Y); end endgenerate endmodule +`endif diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index b60295ac0..1bc61daef 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -34,8 +34,10 @@ bool check_label(bool &active, std::string run_from, std::string run_to, std::st return active; } -struct SynthXilinxPass : public Pass { +struct SynthXilinxPass : public Pass +{ SynthXilinxPass() : Pass("synth_xilinx", "synthesis for Xilinx FPGAs") { } + virtual void help() { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -53,6 +55,14 @@ struct SynthXilinxPass : public Pass { log(" write the design to the specified edif file. writing of an output file\n"); log(" is omitted if this parameter is not specified.\n"); log("\n"); + log(" -blif \n"); + log(" write the design to the specified BLIF file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -vpr\n"); + log(" generate an output netlist (and BLIF file) suitable for VPR\n"); + log(" (this feature is experimental and incomplete)\n"); + log("\n"); log(" -run :\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"); @@ -102,7 +112,7 @@ struct SynthXilinxPass : public Pass { log(" clean\n"); log("\n"); log(" map_cells:\n"); - log(" techmap -map +/xilinx/cells_map.v\n"); + log(" techmap -map +/xilinx/cells_map.v (with -D NO_LUT in vpr mode)\n"); log(" dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT\n"); log(" clean\n"); log("\n"); @@ -114,14 +124,19 @@ struct SynthXilinxPass : public Pass { log(" edif: (only if -edif)\n"); log(" write_edif \n"); log("\n"); + log(" blif: (only if -blif)\n"); + log(" write_blif \n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { std::string top_opt = "-auto-top"; std::string edif_file; + std::string blif_file; std::string run_from, run_to; bool flatten = false; bool retime = false; + bool vpr = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -134,6 +149,10 @@ struct SynthXilinxPass : public Pass { edif_file = args[++argidx]; continue; } + if (args[argidx] == "-blif" && argidx+1 < args.size()) { + blif_file = args[++argidx]; + continue; + } if (args[argidx] == "-run" && argidx+1 < args.size()) { size_t pos = args[argidx+1].find(':'); if (pos == std::string::npos) @@ -150,6 +169,10 @@ struct SynthXilinxPass : public Pass { retime = true; continue; } + if (args[argidx] == "-vpr") { + vpr = true; + continue; + } break; } extra_args(args, argidx, design); @@ -212,7 +235,10 @@ struct SynthXilinxPass : public Pass { if (check_label(active, run_from, run_to, "map_cells")) { - Pass::call(design, "techmap -map +/xilinx/cells_map.v"); + if (vpr) + Pass::call(design, "techmap -D NO_LUT -map +/xilinx/cells_map.v"); + else + Pass::call(design, "techmap -map +/xilinx/cells_map.v"); Pass::call(design, "dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT"); Pass::call(design, "clean"); } @@ -229,6 +255,11 @@ struct SynthXilinxPass : public Pass { if (!edif_file.empty()) Pass::call(design, stringf("write_edif %s", edif_file.c_str())); } + if (check_label(active, run_from, run_to, "blif")) + { + if (!blif_file.empty()) + Pass::call(design, stringf("write_blif %s", edif_file.c_str())); + } log_pop(); }