From b2d688dbf93904d55d868fd7a4d86f434f08553e Mon Sep 17 00:00:00 2001 From: nella Date: Wed, 17 Jun 2026 17:36:32 +0200 Subject: [PATCH] Error out on latches. --- .../macro_commands/synth_ice40.ys | 2 +- techlibs/efinix/synth_efinix.cc | 22 ++++++++++++++--- techlibs/fabulous/synth_fabulous.cc | 22 ++++++++++++++--- techlibs/ice40/synth_ice40.cc | 22 ++++++++++++++--- techlibs/lattice/synth_lattice.cc | 24 ++++++++++++++++--- techlibs/nanoxplore/synth_nanoxplore.cc | 23 +++++++++++++++--- techlibs/quicklogic/synth_quicklogic.cc | 24 ++++++++++++++++--- tests/arch/ecp5/latches.ys | 6 ++--- tests/arch/ecp5/latches_abc9.ys | 2 +- tests/arch/efinix/latches.ys | 6 ++--- tests/arch/ice40/latches.ys | 6 ++--- tests/arch/nanoxplore/latches.ys | 6 ++--- tests/arch/quicklogic/pp3/latches.ys | 6 ++--- tests/various/synth_latch_warning.ys | 15 ++++++++++-- 14 files changed, 149 insertions(+), 37 deletions(-) diff --git a/docs/source/code_examples/macro_commands/synth_ice40.ys b/docs/source/code_examples/macro_commands/synth_ice40.ys index a829c197c..b3fca3e78 100644 --- a/docs/source/code_examples/macro_commands/synth_ice40.ys +++ b/docs/source/code_examples/macro_commands/synth_ice40.ys @@ -67,7 +67,7 @@ map_ffs: map_luts: abc ice40_opt - check + select techmap simplemap techmap diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index 788580794..70b05c88d 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -63,13 +63,19 @@ struct SynthEfinixPass : public ScriptPass log(" -nobram\n"); log(" do not use EFX_RAM_5K cells in output netlist\n"); log("\n"); + log(" -latches \n"); + log(" select the behaviour for latches that cannot be mapped to a\n"); + log(" dedicated hardware primitive and are implemented using LUTs\n"); + log(" instead. 'error' (the default) aborts synthesis, 'warn' only\n"); + log(" prints a warning, and 'auto' permits them without complaint.\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } - string top_opt, edif_file, json_file; + string top_opt, edif_file, json_file, latches; bool flatten, retime, nobram; void clear_flags() override @@ -80,6 +86,7 @@ struct SynthEfinixPass : public ScriptPass flatten = true; retime = false; nobram = false; + latches = "error"; } void execute(std::vector args, RTLIL::Design *design) override @@ -122,12 +129,18 @@ struct SynthEfinixPass : public ScriptPass nobram = true; continue; } + if (args[argidx] == "-latches" && argidx+1 < args.size()) { + latches = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); + if (latches != "auto" && latches != "warn" && latches != "error") + log_cmd_error("Invalid value '%s' for -latches (expected auto, warn or error)\n", latches.c_str()); log_header(design, "Executing SYNTH_EFINIX pass.\n"); log_push(); @@ -147,7 +160,7 @@ struct SynthEfinixPass : public ScriptPass if (flatten && check_label("flatten", "(unless -noflatten)")) { - run("proc"); + run("proc -latches " + (latches == "error" ? std::string("auto") : latches)); run("check"); run("flatten"); run("tribuf -logic"); @@ -190,7 +203,10 @@ struct SynthEfinixPass : public ScriptPass if (check_label("map_ffs")) { run("dfflegalize -cell $_DFFE_????_ 0 -cell $_SDFFE_????_ 0 -cell $_SDFFCE_????_ 0 -cell $_DLATCH_?_ x"); - run("check -nolatches"); + if (help_mode) + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*", "(only if -latches error, the default)"); + else if (latches == "error") + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*"); run("techmap -D NO_LUT -map +/efinix/cells_map.v"); run("opt_expr -mux_undef"); run("simplemap"); diff --git a/techlibs/fabulous/synth_fabulous.cc b/techlibs/fabulous/synth_fabulous.cc index 67bf35e14..56505b5f9 100644 --- a/techlibs/fabulous/synth_fabulous.cc +++ b/techlibs/fabulous/synth_fabulous.cc @@ -116,13 +116,19 @@ struct SynthPass : public ScriptPass log(" read/write collision\" (same result as setting the no_rw_check\n"); log(" attribute on all memories).\n"); log("\n"); + log(" -latches \n"); + log(" select the behaviour for latches that cannot be mapped to a\n"); + log(" dedicated hardware primitive and are implemented using LUTs\n"); + log(" instead. 'error' (the default) aborts synthesis, 'warn' only\n"); + log(" prints a warning, and 'auto' permits them without complaint.\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } - string top_module, json_file, blif_file, plib, fsm_opts, memory_opts, carry_mode; + string top_module, json_file, blif_file, plib, fsm_opts, memory_opts, carry_mode, latches; std::vector extra_plib, extra_map; bool autotop, forvpr, noalumacc, nofsm, noshare, noregfile, iopad, complexdff, flatten; @@ -144,6 +150,7 @@ struct SynthPass : public ScriptPass flatten = true; json_file = ""; blif_file = ""; + latches = "error"; } void execute(std::vector args, RTLIL::Design *design) override @@ -243,12 +250,18 @@ struct SynthPass : public ScriptPass flatten = false; continue; } + if (args[argidx] == "-latches" && argidx+1 < args.size()) { + latches = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); + if (latches != "auto" && latches != "warn" && latches != "error") + log_cmd_error("Invalid value '%s' for -latches (expected auto, warn or error)\n", latches.c_str()); log_header(design, "Executing SYNTH_FABULOUS pass.\n"); log_push(); @@ -279,7 +292,7 @@ struct SynthPass : public ScriptPass run("hierarchy -check"); } else run(stringf("hierarchy -check -top %s", top_module)); - run("proc"); + run("proc -latches " + (latches == "error" ? std::string("auto") : latches)); } @@ -359,7 +372,10 @@ struct SynthPass : public ScriptPass } else { run("dfflegalize -cell $_DFF_P_ 0 -cell $_DLATCH_?_ x", "without -complex-dff"); } - run("check -nolatches"); + if (help_mode) + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*", "(only if -latches error, the default)"); + else if (latches == "error") + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*"); run("techmap -map +/fabulous/latches_map.v"); run("techmap -map +/fabulous/ff_map.v"); if (help_mode) { diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 3bdd25746..9993a0d50 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -117,13 +117,19 @@ struct SynthIce40Pass : public ScriptPass log(" read/write collision\" (same result as setting the no_rw_check\n"); log(" attribute on all memories).\n"); log("\n"); + log(" -latches \n"); + log(" select the behaviour for latches that cannot be mapped to a\n"); + log(" dedicated hardware primitive and are implemented using LUTs\n"); + log(" instead. 'error' (the default) aborts synthesis, 'warn' only\n"); + log(" prints a warning, and 'auto' permits them without complaint.\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } - string top_opt, blif_file, edif_file, json_file, device_opt; + string top_opt, blif_file, edif_file, json_file, device_opt, latches; bool nocarry, nodffe, nobram, spram, dsp, flatten, retime, noabc, abc2, vpr, abc9, dff, flowmap, no_rw_check; int min_ce_use; @@ -148,6 +154,7 @@ struct SynthIce40Pass : public ScriptPass flowmap = false; device_opt = "hx"; no_rw_check = false; + latches = "error"; } void execute(std::vector args, RTLIL::Design *design) override @@ -258,6 +265,10 @@ struct SynthIce40Pass : public ScriptPass no_rw_check = true; continue; } + if (args[argidx] == "-latches" && argidx+1 < args.size()) { + latches = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); @@ -266,6 +277,8 @@ struct SynthIce40Pass : public ScriptPass log_cmd_error("This command only operates on fully selected designs!\n"); if (device_opt != "hx" && device_opt != "lp" && device_opt !="u") log_cmd_error("Invalid or no device specified: '%s'\n", device_opt); + if (latches != "auto" && latches != "warn" && latches != "error") + log_cmd_error("Invalid value '%s' for -latches (expected auto, warn or error)\n", latches.c_str()); if (abc9 && retime) log_cmd_error("-retime option not currently compatible with -abc9!\n"); @@ -303,7 +316,7 @@ struct SynthIce40Pass : public ScriptPass { run("read_verilog " + define + " -lib -specify +/ice40/cells_sim.v"); run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt)); - run("proc"); + run("proc -latches " + (latches == "error" ? std::string("auto") : latches)); } if (check_label("flatten", "(unless -noflatten)")) @@ -406,7 +419,10 @@ struct SynthIce40Pass : public ScriptPass run("abc", " (only if -abc2)"); run("ice40_opt", "(only if -abc2)"); } - run("check -nolatches"); + if (help_mode) + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*", "(only if -latches error, the default)"); + else if (latches == "error") + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*"); run("techmap -map +/ice40/latches_map.v"); if (noabc || flowmap || help_mode) { run("simplemap", " (if -noabc or -flowmap)"); diff --git a/techlibs/lattice/synth_lattice.cc b/techlibs/lattice/synth_lattice.cc index e68298f31..56d34d6f4 100644 --- a/techlibs/lattice/synth_lattice.cc +++ b/techlibs/lattice/synth_lattice.cc @@ -156,13 +156,20 @@ struct SynthLatticePass : public ScriptPass log(" implement constant comparisons in soft logic, do not involve\n"); log(" hard carry chains\n"); log("\n"); + log(" -latches \n"); + log(" select the behaviour for latches that cannot be mapped to a\n"); + log(" dedicated hardware primitive and are implemented using LUTs\n"); + log(" instead. 'error' (the default) aborts synthesis, 'warn' only\n"); + log(" prints a warning, and 'auto' permits them without complaint.\n"); + log(" (ignored with -asyncprld, which has a latch primitive)\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } - string top_opt, edif_file, json_file, family; + string top_opt, edif_file, json_file, family, latches; bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, iopad, nodsp, no_rw_check, have_dsp; bool cmp2softlogic; string postfix, arith_map, brams_map, dsp_map, cells_map, map_ram_default, widelut_abc; @@ -189,6 +196,7 @@ struct SynthLatticePass : public ScriptPass iopad = false; nodsp = false; no_rw_check = false; + latches = "error"; postfix = ""; arith_map = ""; brams_map = ""; @@ -318,6 +326,10 @@ struct SynthLatticePass : public ScriptPass cmp2softlogic = true; continue; } + if (args[argidx] == "-latches" && argidx+1 < args.size()) { + latches = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); @@ -325,6 +337,9 @@ struct SynthLatticePass : public ScriptPass if (family.empty()) log_cmd_error("Lattice family parameter must be set.\n"); + if (latches != "auto" && latches != "warn" && latches != "error") + log_cmd_error("Invalid value '%s' for -latches (expected auto, warn or error)\n", latches.c_str()); + if (family == "ecp5") { postfix = "_ecp5"; arith_map = "_ccu2c"; @@ -401,7 +416,7 @@ struct SynthLatticePass : public ScriptPass if (check_label("coarse")) { - run("proc"); + run("proc -latches " + ((asyncprld || latches == "error") ? std::string("auto") : latches)); if (flatten || help_mode) { run("check"); run("flatten"); @@ -532,7 +547,10 @@ struct SynthLatticePass : public ScriptPass if (abc2 || help_mode) run("abc", " (only if -abc2)"); if (!asyncprld || help_mode) { - run("check -nolatches", "(skip if -asyncprld)"); + if (help_mode) + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*", "(skip if -asyncprld; only if -latches error, the default)"); + else if (latches == "error") + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*"); run("techmap -map +/lattice/latches_map.v", "(skip if -asyncprld)"); } diff --git a/techlibs/nanoxplore/synth_nanoxplore.cc b/techlibs/nanoxplore/synth_nanoxplore.cc index 73c9b3876..f42784f54 100644 --- a/techlibs/nanoxplore/synth_nanoxplore.cc +++ b/techlibs/nanoxplore/synth_nanoxplore.cc @@ -97,13 +97,19 @@ struct SynthNanoXplorePass : public ScriptPass log(" read/write collision\" (same result as setting the no_rw_check\n"); log(" attribute on all memories).\n"); log("\n"); + log(" -latches \n"); + log(" select the behaviour for latches that cannot be mapped to a\n"); + log(" dedicated hardware primitive and are implemented using LUTs\n"); + log(" instead. 'error' (the default) aborts synthesis, 'warn' only\n"); + log(" prints a warning, and 'auto' permits them without complaint.\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } - string top_opt, json_file, family; + string top_opt, json_file, family, latches; bool flatten, abc9, nocy, nodffe, norfram, nobram, noiopad, no_rw_check; std::string postfix; int min_ce_use, min_srst_use; @@ -124,6 +130,7 @@ struct SynthNanoXplorePass : public ScriptPass postfix = ""; min_ce_use = 8; min_srst_use = 8; + latches = "error"; } void execute(std::vector args, RTLIL::Design *design) override @@ -202,10 +209,17 @@ struct SynthNanoXplorePass : public ScriptPass no_rw_check = true; continue; } + if (args[argidx] == "-latches" && argidx+1 < args.size()) { + latches = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); + if (latches != "auto" && latches != "warn" && latches != "error") + log_cmd_error("Invalid value '%s' for -latches (expected auto, warn or error)\n", latches.c_str()); + if (family.empty()) { //log_warning("NanoXplore family not set, setting it to NG-ULTRA.\n"); family = "ultra"; @@ -249,7 +263,7 @@ struct SynthNanoXplorePass : public ScriptPass if (check_label("coarse")) { - run("proc"); + run("proc -latches " + (latches == "error" ? std::string("auto") : latches)); if (flatten || help_mode) { run("check"); run("flatten", "(skip if -noflatten)"); @@ -325,7 +339,10 @@ struct SynthNanoXplorePass : public ScriptPass dfflegalize_args += stringf(" -cell $_DLATCH_?_ x -mince %d -minsrst %d", min_ce_use, min_srst_use); run("dfflegalize" + dfflegalize_args,"($_*DFFE_* only if not -nodffe)"); run("opt_merge"); - run("check -nolatches"); + if (help_mode) + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*", "(only if -latches error, the default)"); + else if (latches == "error") + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*"); run("techmap -map +/nanoxplore/latches_map.v"); run("techmap -map +/nanoxplore/cells_map.v"); run("opt_expr -undriven -mux_undef"); diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc index 05396764a..f465d0148 100644 --- a/techlibs/quicklogic/synth_quicklogic.cc +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -72,12 +72,19 @@ struct SynthQuickLogicPass : public ScriptPass { log(" use old ABC flow, which has generally worse mapping results but is less\n"); log(" likely to have bugs.\n"); log("\n"); + log(" -latches \n"); + log(" select the behaviour for latches that cannot be mapped to a\n"); + log(" dedicated hardware primitive and are implemented using LUTs\n"); + log(" instead. 'error' (the default) aborts synthesis, 'warn' only\n"); + log(" prints a warning, and 'auto' permits them without complaint.\n"); + log(" (only applies to the pp3 family)\n"); + log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } - string top_opt, blif_file, edif_file, family, currmodule, verilog_file, lib_path; + string top_opt, blif_file, edif_file, family, currmodule, verilog_file, lib_path, latches; bool abc9, inferAdder, nobram, bramTypes, dsp, ioff, flatten; void clear_flags() override @@ -96,6 +103,7 @@ struct SynthQuickLogicPass : public ScriptPass { dsp = true; ioff = true; flatten = true; + latches = "error"; } void set_scratchpad_defaults(RTLIL::Design *design) { @@ -168,6 +176,10 @@ struct SynthQuickLogicPass : public ScriptPass { flatten = false; continue; } + if (args[argidx] == "-latches" && argidx+1 < args.size()) { + latches = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); @@ -178,6 +190,9 @@ struct SynthQuickLogicPass : public ScriptPass { if (family != "pp3" && family != "qlf_k6n10f") log_cmd_error("Invalid family specified: '%s'\n", family); + if (latches != "auto" && latches != "warn" && latches != "error") + log_cmd_error("Invalid value '%s' for -latches (expected auto, warn or error)\n", latches.c_str()); + if (abc9 && design->scratchpad_get_int("abc9.D", 0) == 0) { log_warning("delay target has not been set via SDC or scratchpad; assuming 12 MHz clock.\n"); design->scratchpad_set_int("abc9.D", 41667); // 12MHz = 83.33.. ns; divided by two to allow for interconnect delay. @@ -211,7 +226,7 @@ struct SynthQuickLogicPass : public ScriptPass { } if (check_label("prepare")) { - run("proc"); + run("proc -latches " + ((family == "pp3" && latches != "error") ? latches : std::string("auto"))); if (flatten) { run("check"); run("flatten", "(unless -noflatten)"); @@ -315,7 +330,10 @@ struct SynthQuickLogicPass : public ScriptPass { } if (check_label("map_luts", "(for pp3)") && (help_mode || family == "pp3")) { - run("check -nolatches"); + if (help_mode) + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*", "(only if -latches error, the default)"); + else if (latches == "error") + run("select -assert-none t:$_DLATCH_* t:$_DLATCHSR_*"); run("techmap -map " + lib_path + family + "/latches_map.v"); if (abc9) { run("read_verilog -lib -specify -icells " + lib_path + family + "/abc9_model.v"); diff --git a/tests/arch/ecp5/latches.ys b/tests/arch/ecp5/latches.ys index 3d011d74f..977769371 100644 --- a/tests/arch/ecp5/latches.ys +++ b/tests/arch/ecp5/latches.ys @@ -4,7 +4,7 @@ design -save read hierarchy -top latchp proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_ecp5 +synth_ecp5 -latches auto cd latchp # Constrain all select calls below inside the top module select -assert-count 1 t:LUT4 @@ -15,7 +15,7 @@ design -load read hierarchy -top latchn proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_ecp5 +synth_ecp5 -latches auto cd latchn # Constrain all select calls below inside the top module select -assert-count 1 t:LUT4 @@ -26,7 +26,7 @@ design -load read hierarchy -top latchsr proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_ecp5 +synth_ecp5 -latches auto cd latchsr # Constrain all select calls below inside the top module select -assert-count 2 t:LUT4 select -assert-count 1 t:PFUMX diff --git a/tests/arch/ecp5/latches_abc9.ys b/tests/arch/ecp5/latches_abc9.ys index 4daf04050..0524113e5 100644 --- a/tests/arch/ecp5/latches_abc9.ys +++ b/tests/arch/ecp5/latches_abc9.ys @@ -8,6 +8,6 @@ assign q = ~l; endmodule EOT # Can't run any sort of equivalence check because latches are blown to LUTs -synth_ecp5 -abc9 +synth_ecp5 -abc9 -latches auto select -assert-count 2 t:LUT4 select -assert-none t:LUT4 %% t:* %D diff --git a/tests/arch/efinix/latches.ys b/tests/arch/efinix/latches.ys index 1b1c00023..4f2ca1b26 100644 --- a/tests/arch/efinix/latches.ys +++ b/tests/arch/efinix/latches.ys @@ -4,7 +4,7 @@ design -save read hierarchy -top latchp proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_efinix +synth_efinix -latches auto cd latchp # Constrain all select calls below inside the top module select -assert-count 1 t:EFX_LUT4 @@ -15,7 +15,7 @@ design -load read hierarchy -top latchn proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_efinix +synth_efinix -latches auto cd latchn # Constrain all select calls below inside the top module select -assert-count 1 t:EFX_LUT4 @@ -26,7 +26,7 @@ design -load read hierarchy -top latchsr proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_efinix +synth_efinix -latches auto cd latchsr # Constrain all select calls below inside the top module select -assert-count 2 t:EFX_LUT4 diff --git a/tests/arch/ice40/latches.ys b/tests/arch/ice40/latches.ys index b06dd630b..36e03710a 100644 --- a/tests/arch/ice40/latches.ys +++ b/tests/arch/ice40/latches.ys @@ -4,7 +4,7 @@ design -save read hierarchy -top latchp proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_ice40 +synth_ice40 -latches auto cd latchp # Constrain all select calls below inside the top module select -assert-count 1 t:SB_LUT4 @@ -15,7 +15,7 @@ design -load read hierarchy -top latchn proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_ice40 +synth_ice40 -latches auto cd latchn # Constrain all select calls below inside the top module select -assert-count 1 t:SB_LUT4 @@ -26,7 +26,7 @@ design -load read hierarchy -top latchsr proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_ice40 +synth_ice40 -latches auto cd latchsr # Constrain all select calls below inside the top module select -assert-count 2 t:SB_LUT4 diff --git a/tests/arch/nanoxplore/latches.ys b/tests/arch/nanoxplore/latches.ys index b2eccfd80..c96f2b3bb 100644 --- a/tests/arch/nanoxplore/latches.ys +++ b/tests/arch/nanoxplore/latches.ys @@ -4,7 +4,7 @@ design -save read hierarchy -top latchp proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_nanoxplore -noiopad +synth_nanoxplore -noiopad -latches auto cd latchp # Constrain all select calls below inside the top module select -assert-count 1 t:NX_LUT @@ -15,7 +15,7 @@ design -load read hierarchy -top latchn proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_nanoxplore -noiopad +synth_nanoxplore -noiopad -latches auto cd latchn # Constrain all select calls below inside the top module select -assert-count 1 t:NX_LUT @@ -26,7 +26,7 @@ design -load read hierarchy -top latchsr proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_nanoxplore -noiopad +synth_nanoxplore -noiopad -latches auto cd latchsr # Constrain all select calls below inside the top module select -assert-count 2 t:NX_LUT diff --git a/tests/arch/quicklogic/pp3/latches.ys b/tests/arch/quicklogic/pp3/latches.ys index 90a4f515b..17c252c69 100644 --- a/tests/arch/quicklogic/pp3/latches.ys +++ b/tests/arch/quicklogic/pp3/latches.ys @@ -4,7 +4,7 @@ design -save read hierarchy -top latchp proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_quicklogic +synth_quicklogic -latches auto cd latchp # Constrain all select calls below inside the top module select -assert-count 1 t:LUT3 select -assert-count 3 t:inpad @@ -17,7 +17,7 @@ design -load read hierarchy -top latchn proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_quicklogic +synth_quicklogic -latches auto cd latchn # Constrain all select calls below inside the top module select -assert-count 1 t:LUT3 select -assert-count 3 t:inpad @@ -30,7 +30,7 @@ design -load read hierarchy -top latchsr proc # Can't run any sort of equivalence check because latches are blown to LUTs -synth_quicklogic +synth_quicklogic -latches auto cd latchsr # Constrain all select calls below inside the top module select -assert-count 1 t:LUT2 select -assert-count 1 t:LUT4 diff --git a/tests/various/synth_latch_warning.ys b/tests/various/synth_latch_warning.ys index f6394abc7..acd49f76d 100644 --- a/tests/various/synth_latch_warning.ys +++ b/tests/various/synth_latch_warning.ys @@ -3,6 +3,17 @@ module top(input d, en, output reg q); always @* if (en) q = d; endmodule EOT -logger -expect warning "is a latch of type" 1 -synth_ice40 +design -save read + +logger -expect warning "Latch inferred for signal" 1 +synth_ice40 -latches warn logger -check-expected +select -assert-count 1 t:SB_LUT4 + +design -load read +synth_ice40 -latches auto +select -assert-count 1 t:SB_LUT4 + +design -load read +logger -expect error "selection is not empty: t:._DLATCH_" 1 +synth_ice40