diff options
27 files changed, 1635 insertions, 87 deletions
@@ -2,9 +2,28 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.18 .. Yosys 0.18-dev +Yosys 0.19 .. Yosys 0.19-dev -------------------------- +Yosys 0.18 .. Yosys 0.19 +-------------------------- + * New commands and options + - Added option "-rom-only" to "memory_libmap" pass + - Added option "-smtcheck" to "hierarchy" pass + - Added option "-keepdc" to "memory_libmap" pass + - Added option "-suffix" to "rename" pass + - Added "gatemate_foldinv" pass + + * Formal Verification + - Added support for $pos cell in btor backend + - Added the "smtlib2_module" and "smtlib2_comb_expr" attributes + + * GateMate support + - Added LUT tree mapping + + * Verific support + - Added option "-pp" to "verific -import" + Yosys 0.17 .. Yosys 0.18 -------------------------- * Various @@ -129,7 +129,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.18+29 +YOSYS_VER := 0.19+14 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -145,7 +145,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 19ce3b4.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline a45c131.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # @@ -153,10 +153,10 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 09a7e6d +ABCREV = 5f40c47 ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc -ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 VERBOSE=$(Q) +ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) # set ABCEXTERNAL = <abc-command> to use an external ABC instance # Note: The in-tree ABC (yosys-abc) will not be installed when ABCEXTERNAL is set. @@ -201,7 +201,7 @@ ifeq ($(CONFIG),clang) CXX = clang LD = clang++ CXXFLAGS += -std=$(CXXSTD) -Os -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H" +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -Wno-c++11-narrowing" ifneq ($(SANITIZER),) $(info [Clang Sanitizer] $(SANITIZER)) @@ -260,7 +260,7 @@ else ifeq ($(CONFIG),emcc) CXX = emcc LD = emcc CXXFLAGS := -std=$(CXXSTD) $(filter-out -fPIC -ggdb,$(CXXFLAGS)) -ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8" +ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8 -Wno-c++11-narrowing" EMCC_CXXFLAGS := -Os -Wno-warn-absolute-paths EMCC_LDFLAGS := --memory-init-file 0 --embed-file share EMCC_LDFLAGS += -s NO_EXIT_RUNTIME=1 @@ -314,7 +314,7 @@ CXXFLAGS := $(WASIFLAGS) -std=$(CXXSTD) -Os $(filter-out -fPIC,$(CXXFLAGS)) LDFLAGS := $(WASIFLAGS) -Wl,-z,stack-size=1048576 $(filter-out -rdynamic,$(LDFLAGS)) LDLIBS := $(filter-out -lrt,$(LDLIBS)) ABCMKARGS += AR="$(AR)" RANLIB="$(RANLIB)" -ABCMKARGS += ARCHFLAGS="$(WASIFLAGS) -DABC_USE_STDINT_H -DABC_NO_DYNAMIC_LINKING" +ABCMKARGS += ARCHFLAGS="$(WASIFLAGS) -DABC_USE_STDINT_H -DABC_NO_DYNAMIC_LINKING -Wno-c++11-narrowing" ABCMKARGS += OPTFLAGS="-Os" EXE = .wasm @@ -505,6 +505,18 @@ Verilog Attributes and non-standard features module. Modules with such cells will be reprocessed during the ``hierarchy`` pass once the referenced module definition(s) become available. +- The ``smtlib2_module`` attribute can be set on a blackbox module to specify a + formal model directly using SMT-LIB 2. For such a module, the + ``smtlib2_comb_expr`` attribute can be used on output ports to define their + value using an SMT-LIB 2 expression. For example: + + (* blackbox *) + (* smtlib2_module *) + module submod(a, b); + input [7:0] a; + (* smtlib2_comb_expr = "(bvnot a)" *) + output [7:0] b; + endmodule Non-standard or SystemVerilog features for formal verification ============================================================== diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 7dec70545..831a3ada2 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -1405,7 +1405,6 @@ struct BtorBackend : public Backend { log_header(design, "Executing BTOR backend.\n"); log_push(); - Pass::call(design, "memory_map -rom-only"); Pass::call(design, "bmuxmap"); Pass::call(design, "demuxmap"); log_pop(); diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index b4ffa87cd..073921cc4 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -1575,6 +1575,27 @@ value<BitsY> mod_ss(const value<BitsA> &a, const value<BitsB> &b) { return divmod_ss<BitsY>(a, b).second; } +template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE +value<BitsY> modfloor_uu(const value<BitsA> &a, const value<BitsB> &b) { + return divmod_uu<BitsY>(a, b).second; +} + +// GHDL Modfloor operator. Returns r=a mod b, such that r has the same sign as b and +// a=b*N+r where N is some integer +// In practical terms, when a and b have different signs and the remainder returned by divmod_ss is not 0 +// then return the remainder + b +template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE +value<BitsY> modfloor_ss(const value<BitsA> &a, const value<BitsB> &b) { + value<BitsY> r; + r = divmod_ss<BitsY>(a, b).second; + if((b.is_neg() != a.is_neg()) && !r.is_zero()) + return add_ss<BitsY>(b, r); + return r; +} + + // Memory helper struct memory_index { bool valid; diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 404755b1e..62768bd33 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -185,7 +185,7 @@ bool is_binary_cell(RTLIL::IdString type) ID($and), ID($or), ID($xor), ID($xnor), ID($logic_and), ID($logic_or), ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx), ID($eq), ID($ne), ID($eqx), ID($nex), ID($gt), ID($ge), ID($lt), ID($le), - ID($add), ID($sub), ID($mul), ID($div), ID($mod)); + ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($modfloor)); } bool is_extending_cell(RTLIL::IdString type) diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 6e70f9043..7481e0510 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -1609,7 +1609,6 @@ struct Smt2Backend : public Backend { log_header(design, "Executing SMT2 backend.\n"); log_push(); - Pass::call(design, "memory_map -rom-only"); Pass::call(design, "bmuxmap"); Pass::call(design, "demuxmap"); log_pop(); diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index bbf860c96..fd6208e86 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -57,7 +57,7 @@ USING_YOSYS_NAMESPACE #include "FileSystem.h" #ifdef YOSYSHQ_VERIFIC_EXTENSIONS -#include "InitialAssertions.h" +#include "VerificExtensions.h" #endif #ifndef YOSYSHQ_VERIFIC_API_VERSION @@ -2246,7 +2246,7 @@ void verific_import(Design *design, const std::map<std::string,std::string> &par verific_params.Insert(i.first.c_str(), i.second.c_str()); #ifdef YOSYSHQ_VERIFIC_EXTENSIONS - InitialAssertions::Rewrite("work", &verific_params); + VerificExtensions::ElaborateAndRewrite("work", &verific_params); #endif if (top.empty()) { @@ -2312,6 +2312,9 @@ void verific_import(Design *design, const std::map<std::string,std::string> &par nl_todo.erase(it); } +#ifdef YOSYSHQ_VERIFIC_EXTENSIONS + VerificExtensions::Reset(); +#endif hier_tree::DeleteHierarchicalTree(); veri_file::Reset(); #ifdef VERIFIC_VHDL_SUPPORT @@ -2494,6 +2497,9 @@ struct VerificPass : public Pass { log(" -v, -vv\n"); log(" Verbose log messages. (-vv is even more verbose than -v.)\n"); log("\n"); + log(" -pp <filename>\n"); + log(" Pretty print design after elaboration to specified file.\n"); + log("\n"); log("The following additional import options are useful for debugging the Verific\n"); log("bindings (for Yosys and/or Verific developers):\n"); log("\n"); @@ -2539,6 +2545,9 @@ struct VerificPass : public Pass { log("Get/set Verific runtime flags.\n"); log("\n"); log("\n"); +#if defined(YOSYS_ENABLE_VERIFIC) and defined(YOSYSHQ_VERIFIC_EXTENSIONS) + VerificExtensions::Help(); +#endif log("Use YosysHQ Tabby CAD Suite if you need Yosys+Verific.\n"); log("https://www.yosyshq.com/\n"); log("\n"); @@ -2922,6 +2931,7 @@ struct VerificPass : public Pass { bool mode_autocover = false, mode_fullinit = false; bool flatten = false, extnets = false; string dumpfile; + string ppfile; Map parameters(STRING_HASH); for (argidx++; argidx < GetSize(args); argidx++) { @@ -2990,6 +3000,10 @@ struct VerificPass : public Pass { dumpfile = args[++argidx]; continue; } + if (args[argidx] == "-pp" && argidx+1 < GetSize(args)) { + ppfile = args[++argidx]; + continue; + } break; } @@ -2999,8 +3013,11 @@ struct VerificPass : public Pass { std::set<std::string> top_mod_names; #ifdef YOSYSHQ_VERIFIC_EXTENSIONS - InitialAssertions::Rewrite(work, ¶meters); + VerificExtensions::ElaborateAndRewrite(work, ¶meters); #endif + if (!ppfile.empty()) + veri_file::PrettyPrint(ppfile.c_str(), nullptr, work.c_str()); + if (mode_all) { log("Running hier_tree::ElaborateAll().\n"); @@ -3113,6 +3130,9 @@ struct VerificPass : public Pass { nl_todo.erase(it); } +#ifdef YOSYSHQ_VERIFIC_EXTENSIONS + VerificExtensions::Reset(); +#endif hier_tree::DeleteHierarchicalTree(); veri_file::Reset(); #ifdef VERIFIC_VHDL_SUPPORT @@ -3187,6 +3207,13 @@ struct VerificPass : public Pass { } } } +#ifdef YOSYSHQ_VERIFIC_EXTENSIONS + if (VerificExtensions::Execute(args, argidx, work, + [this](const std::vector<std::string> &args, size_t argidx, std::string msg) + { cmd_error(args, argidx, msg); } )) { + goto check_error; + } +#endif cmd_error(args, argidx, "Missing or unsupported mode parameter.\n"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7a0b6b9c7..ee918441e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -168,7 +168,7 @@ namespace RTLIL log_assert(p[1] != 0); for (const char *c = p; *c; c++) if ((unsigned)*c <= (unsigned)' ') - log_error("Found control character or space (0x%02hhx) in string '%s' which is not allowed in RTLIL identifiers\n", *c, p); + log_error("Found control character or space (0x%02x) in string '%s' which is not allowed in RTLIL identifiers\n", *c, p); #ifndef YOSYS_NO_IDS_REFCNT if (global_free_idx_list_.empty()) { diff --git a/manual/command-reference-manual.tex b/manual/command-reference-manual.tex index edc8af6e6..28b99f3a6 100644 --- a/manual/command-reference-manual.tex +++ b/manual/command-reference-manual.tex @@ -2256,6 +2256,16 @@ and simulus signal from FST file number of clock cycles to simulate (default: 20) \end{lstlisting} +\section{gatemate\_foldinv -- fold inverters into Gatemate LUT trees} +\label{cmd:gatemate_foldinv} +\begin{lstlisting}[numbers=left,frame=single] + gatemate_foldinv [selection] + + +This pass searches for $__CC_NOT cells and folds them into CC_LUT2, CC_L2T4 +and CC_L2T5 cells as created by LUT tree mapping. +\end{lstlisting} + \section{glift -- create GLIFT models and optimization problems} \label{cmd:glift} \begin{lstlisting}[numbers=left,frame=single] @@ -2379,6 +2389,9 @@ resolves positional module parameters, unrolls array instances, and more. like -check, but also throw an error if blackbox modules are instantiated, and throw an error if the design has no top module. + -smtcheck + like -simcheck, but allow smtlib2_module modules. + -purge_lib by default the hierarchy command will not remove library (blackbox) modules. use this option to also remove unused blackbox modules. @@ -2947,6 +2960,12 @@ pass to word-wide DFFs and address decoders. -iattr for -attr, ignore case of <value>. + + -rom-only + only perform conversion for ROMs (memories with no write ports). + + -keepdc + when mapping ROMs, keep x-bits shared across read ports. \end{lstlisting} \section{memory\_memx -- emulate vlog sim behavior for mem ports} @@ -4223,10 +4242,12 @@ Assign names auto-generated from the src attribute to all selected wires and cells with private names. - rename -wire [selection] + rename -wire [selection] [-suffix <suffix>] Assign auto-generated names based on the wires they drive to all selected cells with private names. Ignores cells driving privatly named wires. +By default, the cell is named after the wire with the cell type as suffix. +The -suffix option can be used to set the suffix to the given string instead. rename -enumerate [-pattern <pattern>] [selection] @@ -5985,6 +6006,9 @@ This command runs synthesis for Cologne Chip AG GateMate FPGAs. -nomx8, -nomx4 do not use CC_MX{8,4} multiplexer cells in output netlist. + -luttree + use new LUT tree mapping approach (EXPERIMENTAL). + -dff run 'abc' with -dff option @@ -6064,7 +6088,11 @@ The following commands are executed by this synthesis command: techmap -map +/gatemate/mux_map.v map_luts: - abc -dress -lut 4 + abc -genlib +/gatemate/lut_tree_cells.genlib (with -luttree) + techmap -map +/gatemate/lut_tree_map.v (with -luttree) + gatemate_foldinv (with -luttree) + techmap -map +/gatemate/inv_map.v (with -luttree) + abc -dress -lut 4 (without -luttree) clean map_cells: @@ -7898,6 +7926,9 @@ Import options: -v, -vv Verbose log messages. (-vv is even more verbose than -v.) + -pp <filename> + Pretty print design after elaboration to specified file. + The following additional import options are useful for debugging the Verific bindings (for Yosys and/or Verific developers): @@ -7938,50 +7969,6 @@ Pretty print options: Save output for VHDL design units. - verific -app <application>.. - -Execute YosysHQ formal application on loaded Verilog files. - -Application options: - - -module <module> - Run formal application only on specified module. - - -blacklist <filename[:lineno]> - Do not run application on modules from files that match the filename - or filename and line number if provided in such format. - Parameter can also contain comma separated list of file locations. - - -blfile <file> - Do not run application on locations specified in file, they can - represent filename or filename and location in file. - -Applications: - - WARNING: Applications only available in commercial build. - - - verific -template <name> <top_module>.. - -Generate template for specified top module of loaded design. - -Template options: - - -out - Specifies output file for generated template, by default output is stdout - - -chparam name value - Generate template using this parameter value. Otherwise default parameter - values will be used for templat generate functionality. This option - can be specified multiple times to override multiple parameters. - String values must be passed in double quotes ("). - -Templates: - - WARNING: Templates only available in commercial build. - - - verific -cfg [<name> [<value>]] Get/set Verific runtime flags. diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index d40d6e59f..d27fddf1c 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -439,7 +439,8 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI } } -bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, std::vector<std::string> &libdirs) +bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, bool flag_smtcheck, + std::vector<std::string> &libdirs) { bool did_something = false; std::map<RTLIL::Cell*, std::pair<int, int>> array_cells; @@ -477,7 +478,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check RTLIL::Module *mod = design->module(cell->type); if (!mod) { - mod = get_module(*design, *cell, *module, flag_check || flag_simcheck, libdirs); + mod = get_module(*design, *cell, *module, flag_check || flag_simcheck || flag_smtcheck, libdirs); // If we still don't have a module, treat the cell as a black box and skip // it. Otherwise, we either loaded or derived something so should set the @@ -495,11 +496,11 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check // interfaces. if_expander.visit_connections(*cell, *mod); - if (flag_check || flag_simcheck) + if (flag_check || flag_simcheck || flag_smtcheck) check_cell_connections(*module, *cell, *mod); if (mod->get_blackbox_attribute()) { - if (flag_simcheck) + if (flag_simcheck || (flag_smtcheck && !mod->get_bool_attribute(ID::smtlib2_module))) log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox/whitebox module.\n", cell->type.c_str(), module->name.c_str(), cell->name.c_str()); continue; @@ -737,6 +738,9 @@ struct HierarchyPass : public Pass { log(" like -check, but also throw an error if blackbox modules are\n"); log(" instantiated, and throw an error if the design has no top module.\n"); log("\n"); + log(" -smtcheck\n"); + log(" like -simcheck, but allow smtlib2_module modules.\n"); + log("\n"); log(" -purge_lib\n"); log(" by default the hierarchy command will not remove library (blackbox)\n"); log(" modules. use this option to also remove unused blackbox modules.\n"); @@ -803,6 +807,7 @@ struct HierarchyPass : public Pass { bool flag_check = false; bool flag_simcheck = false; + bool flag_smtcheck = false; bool purge_lib = false; RTLIL::Module *top_mod = NULL; std::string load_top_mod; @@ -821,7 +826,7 @@ struct HierarchyPass : public Pass { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-generate" && !flag_check && !flag_simcheck && !top_mod) { + if (args[argidx] == "-generate" && !flag_check && !flag_simcheck && !flag_smtcheck && !top_mod) { generate_mode = true; log("Entering generate mode.\n"); while (++argidx < args.size()) { @@ -868,6 +873,10 @@ struct HierarchyPass : public Pass { flag_simcheck = true; continue; } + if (args[argidx] == "-smtcheck") { + flag_smtcheck = true; + continue; + } if (args[argidx] == "-purge_lib") { purge_lib = true; continue; @@ -1013,7 +1022,7 @@ struct HierarchyPass : public Pass { } } - if (flag_simcheck && top_mod == nullptr) + if ((flag_simcheck || flag_smtcheck) && top_mod == nullptr) log_error("Design has no top module.\n"); if (top_mod != NULL) { @@ -1039,7 +1048,7 @@ struct HierarchyPass : public Pass { } for (auto module : used_modules) { - if (expand_module(design, module, flag_check, flag_simcheck, libdirs)) + if (expand_module(design, module, flag_check, flag_simcheck, flag_smtcheck, libdirs)) did_something = true; } diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index ccfb8c94f..fd5b1f1ad 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -31,6 +31,7 @@ struct MemoryMapWorker { bool attr_icase = false; bool rom_only = false; + bool keepdc = false; dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes; RTLIL::Design *design; @@ -190,14 +191,15 @@ struct MemoryMapWorker { int addr = i + mem.start_offset; int idx = addr & ((1 << abits) - 1); + SigSpec w_init = init_data.extract(i*mem.width, mem.width); if (static_cells_map.count(addr) > 0) { data_reg_out[idx] = static_cells_map[addr]; count_static++; } - else if (mem.wr_ports.empty()) + else if (mem.wr_ports.empty() && (!keepdc || w_init.is_fully_def())) { - data_reg_out[idx] = init_data.extract(i*mem.width, mem.width); + data_reg_out[idx] = w_init; } else { @@ -220,13 +222,15 @@ struct MemoryMapWorker w_out_name = genid(mem.memid, "", addr, "$q"); RTLIL::Wire *w_out = module->addWire(w_out_name, mem.width); - SigSpec w_init = init_data.extract(i*mem.width, mem.width); if (!w_init.is_fully_undef()) w_out->attributes[ID::init] = w_init.as_const(); data_reg_out[idx] = w_out; c->setPort(ID::Q, w_out); + + if (mem.wr_ports.empty()) + module->connect(RTLIL::SigSig(w_in, w_out)); } } @@ -380,11 +384,15 @@ struct MemoryMapPass : public Pass { log(" -rom-only\n"); log(" only perform conversion for ROMs (memories with no write ports).\n"); log("\n"); + log(" -keepdc\n"); + log(" when mapping ROMs, keep x-bits shared across read ports.\n"); + log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool attr_icase = false; bool rom_only = false; + bool keepdc = false; dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes; log_header(design, "Executing MEMORY_MAP pass (converting memories to logic and flip-flops).\n"); @@ -426,6 +434,11 @@ struct MemoryMapPass : public Pass { rom_only = true; continue; } + if (args[argidx] == "-keepdc") + { + keepdc = true; + continue; + } break; } extra_args(args, argidx, design); @@ -435,6 +448,7 @@ struct MemoryMapPass : public Pass { worker.attr_icase = attr_icase; worker.attributes = attributes; worker.rom_only = rom_only; + worker.keepdc = keepdc; worker.run(); } } diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index 0ad4acec2..6ff2d1b4b 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -491,12 +491,17 @@ struct OptDffWorker ff.has_srst = false; ff.sig_d = ff.val_srst; changed = true; - } else { + } else if (!opt.keepdc || ff.val_init.is_fully_def()) { log("Handling never-active EN on %s (%s) from module %s (removing D path).\n", log_id(cell), log_id(cell->type), log_id(module)); // The D input path is effectively useless, so remove it (this will be a D latch, SR latch, or a const driver). ff.has_ce = ff.has_clk = ff.has_srst = false; changed = true; + } else { + // We need to keep the undefined initival around as such + ff.sig_d = ff.sig_q; + ff.has_ce = ff.has_srst = false; + changed = true; } } else if (ff.sig_ce == (ff.pol_ce ? State::S1 : State::S0)) { // Always-active enable. Just remove it. @@ -508,13 +513,20 @@ struct OptDffWorker } } - if (ff.has_clk) { - if (ff.sig_clk.is_fully_const()) { + if (ff.has_clk && ff.sig_clk.is_fully_const()) { + if (!opt.keepdc || ff.val_init.is_fully_def()) { // Const clock — the D input path is effectively useless, so remove it (this will be a D latch, SR latch, or a const driver). log("Handling const CLK on %s (%s) from module %s (removing D path).\n", log_id(cell), log_id(cell->type), log_id(module)); ff.has_ce = ff.has_clk = ff.has_srst = false; changed = true; + } else { + // Const clock, but we need to keep the undefined initval around as such + if (ff.has_ce || ff.has_srst || ff.sig_d != ff.sig_q) { + ff.sig_d = ff.sig_q; + ff.has_ce = ff.has_srst = false; + changed = true; + } } } @@ -550,7 +562,7 @@ struct OptDffWorker ff.has_srst = false; ff.sig_d = ff.val_srst; changed = true; - } else { + } else if (!opt.keepdc || ff.val_init.is_fully_def()) { // The D input path is effectively useless, so remove it (this will be a const-input D latch, SR latch, or a const driver). log("Handling D = Q on %s (%s) from module %s (removing D path).\n", log_id(cell), log_id(cell->type), log_id(module)); @@ -567,7 +579,7 @@ struct OptDffWorker } // The cell has been simplified as much as possible already. Now try to spice it up with enables / sync resets. - if (ff.has_clk) { + if (ff.has_clk && ff.sig_d != ff.sig_q) { if (!ff.has_arst && !ff.has_sr && (!ff.has_srst || !ff.has_ce || ff.ce_over_srst) && !opt.nosdff) { // Try to merge sync resets. std::map<ctrls_t, std::vector<int>> groups; diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index 46c76eba9..6fdf470b1 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -75,6 +75,9 @@ struct Async2syncPass : public Pass { if (ff.has_gclk) continue; + if (ff.has_clk && ff.sig_clk.is_fully_const()) + ff.has_ce = ff.has_clk = ff.has_srst = false; + if (ff.has_clk) { if (ff.has_sr) { diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 61ee99ee7..0b9c327c0 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -65,7 +65,9 @@ #include "frontends/blif/blifparse.h" #ifdef YOSYS_LINK_ABC -extern "C" int Abc_RealMain(int argc, char *argv[]); +namespace abc { + int Abc_RealMain(int argc, char *argv[]); +} #endif USING_YOSYS_NAMESPACE @@ -1098,7 +1100,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin abc_argv[2] = strdup("-f"); abc_argv[3] = strdup(tmp_script_name.c_str()); abc_argv[4] = 0; - int ret = Abc_RealMain(4, abc_argv); + int ret = abc::Abc_RealMain(4, abc_argv); free(abc_argv[0]); free(abc_argv[1]); free(abc_argv[2]); diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc index a66e95e21..7dc0a364b 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -31,7 +31,9 @@ #endif #ifdef YOSYS_LINK_ABC -extern "C" int Abc_RealMain(int argc, char *argv[]); +namespace abc { + int Abc_RealMain(int argc, char *argv[]); +} #endif std::string fold_abc9_cmd(std::string str) @@ -277,7 +279,7 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe abc9_argv[2] = strdup("-f"); abc9_argv[3] = strdup(tmp_script_name.c_str()); abc9_argv[4] = 0; - int ret = Abc_RealMain(4, abc9_argv); + int ret = abc::Abc_RealMain(4, abc9_argv); free(abc9_argv[0]); free(abc9_argv[1]); free(abc9_argv[2]); diff --git a/techlibs/gatemate/.gitignore b/techlibs/gatemate/.gitignore new file mode 100644 index 000000000..f260d6e9d --- /dev/null +++ b/techlibs/gatemate/.gitignore @@ -0,0 +1,4 @@ +lut_tree_cells.genlib +lut_tree_map.v +lut_tree_lib.mk + diff --git a/techlibs/gatemate/Makefile.inc b/techlibs/gatemate/Makefile.inc index d1341d7bb..aeb318cc9 100644 --- a/techlibs/gatemate/Makefile.inc +++ b/techlibs/gatemate/Makefile.inc @@ -1,5 +1,6 @@ OBJS += techlibs/gatemate/synth_gatemate.o
+OBJS += techlibs/gatemate/gatemate_foldinv.o
$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/reg_map.v))
$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/mux_map.v))
@@ -12,3 +13,18 @@ $(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams_map.v)) $(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams.txt))
$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams_init_20.vh))
$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/brams_init_40.vh))
+$(eval $(call add_share_file,share/gatemate,techlibs/gatemate/inv_map.v))
+
+EXTRA_OBJS += techlibs/gatemate/lut_tree_lib.mk
+.SECONDARY: techlibs/gatemate/lut_tree_lib.mk
+
+techlibs/gatemate/lut_tree_lib.mk: techlibs/gatemate/make_lut_tree_lib.py
+ $(Q) mkdir -p techlibs/gatemate
+ $(P) $(PYTHON_EXECUTABLE) $<
+ $(Q) touch $@
+
+techlibs/gatemate/lut_tree_cells.genlib: techlibs/gatemate/lut_tree_lib.mk
+techlibs/gatemate/lut_tree_map.v: techlibs/gatemate/lut_tree_lib.mk
+
+$(eval $(call add_gen_share_file,share/gatemate,techlibs/gatemate/lut_tree_cells.genlib))
+$(eval $(call add_gen_share_file,share/gatemate,techlibs/gatemate/lut_tree_map.v))
diff --git a/techlibs/gatemate/cells_sim.v b/techlibs/gatemate/cells_sim.v index 1de3d1c7a..7e88fd7cf 100644 --- a/techlibs/gatemate/cells_sim.v +++ b/techlibs/gatemate/cells_sim.v @@ -1409,3 +1409,47 @@ module CC_BRAM_40K ( end
endgenerate
endmodule
+
+// Models of the LUT2 tree primitives
+module CC_L2T4(
+ output O,
+ input I0, I1, I2, I3
+);
+ parameter [3:0] INIT_L00 = 4'b0000;
+ parameter [3:0] INIT_L01 = 4'b0000;
+ parameter [3:0] INIT_L10 = 4'b0000;
+
+ wire [1:0] l00_s1 = I1 ? INIT_L00[3:2] : INIT_L00[1:0];
+ wire l00 = I0 ? l00_s1[1] : l00_s1[0];
+
+ wire [1:0] l01_s1 = I3 ? INIT_L01[3:2] : INIT_L01[1:0];
+ wire l01 = I2 ? l01_s1[1] : l01_s1[0];
+
+ wire [1:0] l10_s1 = l01 ? INIT_L10[3:2] : INIT_L10[1:0];
+ assign O = l00 ? l10_s1[1] : l10_s1[0];
+
+endmodule
+
+
+module CC_L2T5(
+ output O,
+ input I0, I1, I2, I3, I4
+);
+ parameter [3:0] INIT_L02 = 4'b0000;
+ parameter [3:0] INIT_L03 = 4'b0000;
+ parameter [3:0] INIT_L11 = 4'b0000;
+ parameter [3:0] INIT_L20 = 4'b0000;
+
+ wire [1:0] l02_s1 = I1 ? INIT_L02[3:2] : INIT_L02[1:0];
+ wire l02 = I0 ? l02_s1[1] : l02_s1[0];
+
+ wire [1:0] l03_s1 = I3 ? INIT_L03[3:2] : INIT_L03[1:0];
+ wire l03 = I2 ? l03_s1[1] : l03_s1[0];
+
+ wire [1:0] l11_s1 = l03 ? INIT_L11[3:2] : INIT_L11[1:0];
+ wire l11 = l02 ? l11_s1[1] : l11_s1[0];
+
+ wire [1:0] l20_s1 = l11 ? INIT_L20[3:2] : INIT_L20[1:0];
+ assign O = I4 ? l20_s1[1] : l20_s1[0];
+
+endmodule
diff --git a/techlibs/gatemate/gatemate_foldinv.cc b/techlibs/gatemate/gatemate_foldinv.cc new file mode 100644 index 000000000..752f8aac0 --- /dev/null +++ b/techlibs/gatemate/gatemate_foldinv.cc @@ -0,0 +1,219 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 gatecat <gatecat@ds0.me> + * Copyright (C) 2021 Cologne Chip AG <support@colognechip.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/yosys.h" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct LUTPin { + int input_bit; + IdString init_param; +}; + +struct LUTType { + dict<IdString, LUTPin> inputs; + IdString output_param; +}; + +struct FoldInvWorker { + FoldInvWorker(Module *module) : module(module), sigmap(module) {}; + Module *module; + SigMap sigmap; + + // Mapping from inverter output to inverter input + dict<SigBit, SigBit> inverted_bits; + // Mapping from inverter input to inverter + dict<SigBit, Cell*> inverter_input; + + const dict<IdString, LUTType> lut_types = { + {ID(CC_LUT2), {{ + {ID(I0), {0, ID(INIT)}}, + {ID(I1), {1, ID(INIT)}}, + }, ID(INIT)}}, + {ID(CC_L2T4), {{ + {ID(I0), {0, ID(INIT_L00)}}, + {ID(I1), {1, ID(INIT_L00)}}, + {ID(I2), {0, ID(INIT_L01)}}, + {ID(I3), {1, ID(INIT_L01)}}, + }, ID(INIT_L10)}}, + {ID(CC_L2T5), {{ + {ID(I0), {0, ID(INIT_L02)}}, + {ID(I1), {1, ID(INIT_L02)}}, + {ID(I2), {0, ID(INIT_L03)}}, + {ID(I3), {1, ID(INIT_L03)}}, + {ID(I4), {0, ID(INIT_L20)}}, + }, ID(INIT_L20)}}, + }; + + + void find_inverted_bits() + { + for (auto cell : module->selected_cells()) { + if (cell->type != ID($__CC_NOT)) + continue; + SigBit a = sigmap(cell->getPort(ID::A)[0]); + SigBit y = sigmap(cell->getPort(ID::Y)[0]); + inverted_bits[y] = a; + inverter_input[a] = cell; + } + } + + Const invert_lut_input(Const lut, int bit) + { + Const result(State::S0, GetSize(lut)); + for (int i = 0; i < GetSize(lut); i++) { + int j = i ^ (1 << bit); + result[j] = lut[i]; + } + return result; + } + + Const invert_lut_output(Const lut) + { + Const result(State::S0, GetSize(lut)); + for (int i = 0; i < GetSize(lut); i++) + result[i] = (lut[i] == State::S1) ? State::S0 : State::S1; + return result; + } + + void fold_input_inverters() + { + for (auto cell : module->selected_cells()) { + auto found_type = lut_types.find(cell->type); + if (found_type == lut_types.end()) + continue; + const auto &type = found_type->second; + for (const auto &ipin : type.inputs) { + if (!cell->hasPort(ipin.first)) + continue; + auto sig = cell->getPort(ipin.first); + if (GetSize(sig) == 0) + continue; + SigBit bit = sigmap(sig[0]); + auto inv = inverted_bits.find(bit); + if (inv == inverted_bits.end()) + continue; // not the output of an inverter + // Rewire to inverter input + cell->unsetPort(ipin.first); + cell->setPort(ipin.first, inv->second); + // Rewrite init + cell->setParam(ipin.second.init_param, + invert_lut_input(cell->getParam(ipin.second.init_param), ipin.second.input_bit)); + } + } + } + + void fold_output_inverters() + { + pool<SigBit> used_bits; + // Find bits that are actually used + for (auto cell : module->selected_cells()) { + for (auto conn : cell->connections()) { + if (cell->output(conn.first)) + continue; + for (auto bit : sigmap(conn.second)) + used_bits.insert(bit); + } + } + // Find LUTs driving inverters + // (create a vector to avoid iterate-and-modify issues) + std::vector<std::pair<Cell *, Cell*>> lut_inv; + for (auto cell : module->selected_cells()) { + auto found_type = lut_types.find(cell->type); + if (found_type == lut_types.end()) + continue; + if (!cell->hasPort(ID::O)) + continue; + auto o_sig = cell->getPort(ID::O); + if (GetSize(o_sig) == 0) + continue; + SigBit o = sigmap(o_sig[0]); + auto found_inv = inverter_input.find(o); + if (found_inv == inverter_input.end()) + continue; // doesn't drive an inverter + lut_inv.emplace_back(cell, found_inv->second); + } + for (auto pair : lut_inv) { + Cell *orig_lut = pair.first; + Cell *inv = pair.second; + // Find the inverter output + SigBit inv_y = sigmap(inv->getPort(ID::Y)[0]); + // Inverter output might not actually be used; if all users were folded into inputs already + if (!used_bits.count(inv_y)) + continue; + // Create a duplicate of the LUT with an inverted output + // (if the uninverted version becomes unused it will be swept away) + Cell *dup_lut = module->addCell(NEW_ID, orig_lut->type); + inv->unsetPort(ID::Y); + dup_lut->setPort(ID::O, inv_y); + for (auto conn : orig_lut->connections()) { + if (conn.first == ID::O) + continue; + dup_lut->setPort(conn.first, conn.second); + } + for (auto param : orig_lut->parameters) { + if (param.first == lut_types.at(orig_lut->type).output_param) + dup_lut->parameters[param.first] = invert_lut_output(param.second); + else + dup_lut->parameters[param.first] = param.second; + } + } + } + + void operator()() + { + find_inverted_bits(); + fold_input_inverters(); + fold_output_inverters(); + } +}; + +struct GatemateFoldInvPass : public Pass { + GatemateFoldInvPass() : Pass("gatemate_foldinv", "fold inverters into Gatemate LUT trees") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" gatemate_foldinv [selection]\n"); + log("\n"); + log("\n"); + log("This pass searches for $__CC_NOT cells and folds them into CC_LUT2, CC_L2T4\n"); + log("and CC_L2T5 cells as created by LUT tree mapping.\n"); + log("\n"); + } + + void execute(std::vector<std::string> args, RTLIL::Design *design) override + { + log_header(design, "Executing GATEMATE_FOLDINV pass (folding LUT tree inverters).\n"); + + size_t argidx = 1; + extra_args(args, argidx, design); + + for (Module *module : design->selected_modules()) { + FoldInvWorker worker(module); + worker(); + } + } +} GatemateFoldInvPass; + +PRIVATE_NAMESPACE_END + diff --git a/techlibs/gatemate/inv_map.v b/techlibs/gatemate/inv_map.v new file mode 100644 index 000000000..8a5051747 --- /dev/null +++ b/techlibs/gatemate/inv_map.v @@ -0,0 +1,4 @@ +// Any inverters not folded into LUTs are mapped to a LUT of their own +module \$__CC_NOT (input A, output Y); + CC_LUT1 #(.INIT(2'b01)) _TECHMAP_REPLACE_ (.I0(A), .O(Y)); +endmodule diff --git a/techlibs/gatemate/make_lut_tree_lib.py b/techlibs/gatemate/make_lut_tree_lib.py new file mode 100644 index 000000000..25ca88882 --- /dev/null +++ b/techlibs/gatemate/make_lut_tree_lib.py @@ -0,0 +1,323 @@ +#!/usr/bin/env python3 + +class FNode: + def __init__(self, fun, *args): + self.fun = fun + self.args = args + + if len(self.args) == 0: + assert fun not in ("BUF", "NOT", "AND", "OR", "XOR", "MUX") + + if len(self.args) == 1: + assert fun in ("BUF", "NOT") + + if len(self.args) == 2: + assert fun in ("AND", "OR", "XOR") + + if len(self.args) == 3: + assert fun in ("MUX") + + def __str__(self): + if len(self.args) == 0: + return self.fun + if self.fun == "NOT" and len(self.args[0].args) == 0: + return "!" + self.args[0].fun + return self.fun + "(" + ",".join([str(a) for a in self.args]) + ")" + + def as_genlib_term(self): + if len(self.args) == 0: + return self.fun + if self.fun == "NOT": + assert len(self.args[0].args) == 0 + return "!" + self.args[0].fun + if self.fun == "AND": + return "(" + self.args[0].as_genlib_term() + "*" + self.args[1].as_genlib_term() + ")" + if self.fun == "OR": + return "(" + self.args[0].as_genlib_term() + "+" + self.args[1].as_genlib_term() + ")" + assert False + + def mapMux(self): + if self.fun == "MUX": + A, B, C = self.args + return OR(AND(A, NOT(C)), AND(B, C)).mapMux() + return FNode(self.fun, *[a.mapMux() for a in self.args]) + + def mapXor(self): + if self.fun == "XOR": + A, B = self.args + return OR(AND(A, NOT(B)), AND(NOT(A), B)).mapXor() + return FNode(self.fun, *[a.mapXor() for a in self.args]) + + def mapNot(self): + if self.fun == "BUF": + return self.arg1.mapNot() + if self.fun == "NOT": + if self.args[0].fun == "AND": + return OR(NOT(self.args[0].args[0]),NOT(self.args[0].args[1])).mapNot() + if self.args[0].fun == "OR": + return AND(NOT(self.args[0].args[0]),NOT(self.args[0].args[1])).mapNot() + if self.args[0].fun == "NOT": + return self.args[0].args[0].mapNot() + return FNode(self.fun, *[a.mapNot() for a in self.args]) + + def map(self): + n = self + n = n.mapMux() + n = n.mapXor() + n = n.mapNot() + return n + + def isInv(self): + if len(self.args) == 0: + return False + if self.fun == "XOR": + return False + if self.fun == "NOT": + return self.args[0].isNonInv() + for a in self.args: + if not a.isInv(): + return False + return True + + def isNonInv(self): + if len(self.args) == 0: + return True + if self.fun == "XOR": + return False + if self.fun == "NOT": + return self.args[0].isInv() + for a in self.args: + if not a.isNonInv(): + return False + return True + +A = FNode("A") +B = FNode("B") +C = FNode("C") +D = FNode("D") +E = FNode("E") + +def BUF(arg): return FNode("BUF", arg) +def NOT(arg): return FNode("NOT", arg) +def AND(arg1, arg2): return FNode("AND", arg1, arg2) +def OR(arg1, arg2): return FNode( "OR", arg1, arg2) +def XOR(arg1, arg2): return FNode("XOR", arg1, arg2) +def MUX(arg1, arg2, arg3): return FNode("MUX", arg1, arg2, arg3) + +# Genlib Format: +# +# GATE <cell-name> <cell-area> <cell-logic-function> +# +# PIN <pin-name> <phase> <input-load> <max-load> +# <rise-block-delay> <rise-fanout-delay> +# <fall-block-delay> <fall-fanout-delay> +# +# phase: +# INV, NONINV, or UNKNOWN +# +# cell-logic-function: +# <output> = <term with *(AND), +(OR), !(NOT)> + + +cells = [ + ["$__CC_BUF", 5, A], + ["$__CC_NOT", 0, NOT(A)], + ["$__CC_MUX", 5, MUX(A, B, C)], +] + +base_cells = [ + ["$__CC2_A", AND(A, B)], + ["$__CC2_O", OR(A, B)], + ["$__CC2_X", XOR(A, B)], + + ["$__CC3_AA", AND(AND(A, B), C)], + ["$__CC3_OO", OR( OR(A, B), C)], + ["$__CC3_XX", XOR(XOR(A, B), C)], + ["$__CC3_AO", OR(AND(A, B), C)], + ["$__CC3_OA", AND( OR(A, B), C)], + ["$__CC3_AX", XOR(AND(A, B), C)], + ["$__CC3_XA", AND(XOR(A, B), C)], + +# ["$__CC3_AAA", AND(AND(A,B),AND(A,C))], +# ["$__CC3_AXA", XOR(AND(A,B),AND(A,C))], +# ["$__CC3_XAX", AND(XOR(A,B),XOR(A,C))], +# ["$__CC3_AAX", AND(AND(A,B),XOR(A,C))], +# ["$__CC3_AXX", XOR(AND(A,B),XOR(A,C))], +# ["$__CC3_XXX", XOR(XOR(A,B),XOR(A,C))], +# ["$__CC3_AAO", AND(AND(A,B), OR(A,C))], +# ["$__CC3_AOA", OR(AND(A,B),AND(A,C))], +# ["$__CC3_AOX", OR(AND(A,B),XOR(A,C))], + +# ["$__CC3_AAA_N", AND(AND(A,B),AND(NOT(A),C))], +# ["$__CC3_AXA_N", XOR(AND(A,B),AND(NOT(A),C))], +# ["$__CC3_XAX_N", AND(XOR(A,B),XOR(NOT(A),C))], +# ["$__CC3_AAX_N", AND(AND(A,B),XOR(NOT(A),C))], +# ["$__CC3_AXX_N", XOR(AND(A,B),XOR(NOT(A),C))], +# ["$__CC3_XXX_N", XOR(XOR(A,B),XOR(NOT(A),C))], +# ["$__CC3_AAO_N", AND(AND(A,B), OR(NOT(A),C))], +# ["$__CC3_AOA_N", OR(AND(A,B),AND(NOT(A),C))], +# ["$__CC3_AOX_N", OR(AND(A,B),XOR(NOT(A),C))], + + ["$__CC4_AAA", AND(AND(A,B),AND(C,D))], + ["$__CC4_AXA", XOR(AND(A,B),AND(C,D))], + ["$__CC4_XAX", AND(XOR(A,B),XOR(C,D))], + ["$__CC4_AAX", AND(AND(A,B),XOR(C,D))], + ["$__CC4_AXX", XOR(AND(A,B),XOR(C,D))], + ["$__CC4_XXX", XOR(XOR(A,B),XOR(C,D))], + ["$__CC4_AAO", AND(AND(A,B), OR(C,D))], + ["$__CC4_AOA", OR(AND(A,B),AND(C,D))], + ["$__CC4_AOX", OR(AND(A,B),XOR(C,D))], +] + +for name, expr in base_cells: + cells.append([name, 10, expr]) + + name = (name + .replace("$__CC4_", "$__CC5_") + .replace("$__CC3_", "$__CC4_") + .replace("$__CC2_", "$__CC3_")) + + # Cells such as $__CC4_AA_A are redundant, as $__CC4_AAA is equivalent + if name not in ("$__CC4_AA", "$__CC3_A"): + cells.append([name + "_A", 12, AND(E, expr)]) + if name not in ("$__CC4_OO", "$__CC3_O"): + cells.append([name + "_O", 12, OR(E, expr)]) + if name not in ("$__CC4_XX", "$__CC3_X"): + cells.append([name + "_X", 12, XOR(E, expr)]) + +with open("techlibs/gatemate/lut_tree_cells.genlib", "w") as glf: + def mkGate(name, cost, expr, max_load=9999, block_delay = 10, fanout_delay = 5): + name = name.replace(" ", "") + expr = expr.map() + + phase = "UNKNOWN" + if expr.isInv(): phase = "INV" + if expr.isNonInv(): phase = "NONINV" + + print("", file=glf) + print("GATE %s %d Y=%s;" % (name, cost, expr.as_genlib_term()), file=glf) + print("PIN * %s 1 %d %d %d %d %d" % (phase, max_load, block_delay, fanout_delay, block_delay, fanout_delay), file=glf) + print("GATE $__ZERO 0 Y=CONST0;", file=glf) + print("GATE $__ONE 0 Y=CONST1;", file=glf) + for name, cost, expr in cells: + mkGate(name, cost, expr) + +class LUTTreeNode: + def __init__(self, name, width, inputs=None): + self.name = name + self.width = width + self.inputs = inputs + def is_input(self): + return self.width == 0 + def map(self, expr, params, ports): + if self.is_input(): + # Input to LUT tree + if expr is None: + ports[self.name] = "" # disconnected input + else: + assert(len(expr.args) == 0) + ports[self.name] = expr.fun + return + if expr is None: + # Unused part of tree + params[self.name] = "4'b0000" + for i in self.inputs: + i.map(None, params, ports) + return + elif len(expr.args) == 0: + # Input to the expression; but not LUT tree + # Insert a route through + params[self.name] = "4'b1010" + self.inputs[0].map(expr, params, ports) + for i in self.inputs[1:]: + i.map(None, params, ports) + return + # Map uphill LUTs; uninverting arguments and keeping track of that if needed + arg_inv = [] + for (i, arg) in zip(self.inputs, expr.args): + if arg.fun == "NOT": + i.map(arg.args[0], params, ports) + arg_inv.append(True) + else: + i.map(arg, params, ports) + arg_inv.append(False) + # Determine base init value + assert self.width == 2 + if expr.fun == "AND": + init = 0b1000 + elif expr.fun == "OR": + init = 0b1110 + elif expr.fun == "XOR": + init = 0b0110 + else: + assert False, expr.fun + # Swap bits if init inverted + swapped_init = 0b0000 + for b in range(4): + if ((init >> b) & 0x1) == 0: continue + for i in range(2): + if arg_inv[i]: + b ^= (1 << i) + swapped_init |= (1 << b) + # Set init param + params[self.name] = "4'b{:04b}".format(swapped_init) + +def LUT2(name, i0, i1): return LUTTreeNode(name, 2, [i0, i1]) +def I(name): return LUTTreeNode(name, 0) + +lut_prims = { + "CC_LUT2": LUT2("INIT", I("I0"), I("I1")), + "CC_L2T4": LUT2( + "INIT_L10", + LUT2("INIT_L00", I("I0"), I("I1")), + LUT2("INIT_L01", I("I2"), I("I3")), + ), + "CC_L2T5": LUT2( + "INIT_L20", I("I4"), LUT2("INIT_L11", + LUT2("INIT_L02", I("I0"), I("I1")), + LUT2("INIT_L03", I("I2"), I("I3")), + ) + ) +} + +with open("techlibs/gatemate/lut_tree_map.v", "w") as vf: + # Non-automatic rules + print(""" +module \\$__ZERO (output Y); assign Y = 1'b0; endmodule +module \\$__ONE (output Y); assign Y = 1'b1; endmodule + +module \\$__CC_BUF (input A, output Y); assign Y = A; endmodule + +module \\$__CC_MUX (input A, B, C, output Y); + CC_MX2 _TECHMAP_REPLACE_ ( + .D0(A), .D1(B), .S0(C), + .Y(Y) + ); +endmodule +""", file=vf) + for name, cost, expr in cells: + expr = expr.mapMux().mapNot() # Don't map XOR + if name in ("$__CC_BUF", "$__CC_NOT", "$__CC_MUX"): + # Special cases + continue + if name.startswith("$__CC2_"): + prim = "CC_LUT2" + elif name.startswith("$__CC5_") or (name.startswith("$__CC4_") and cost == 12): + prim = "CC_L2T5" + else: + prim = "CC_L2T4" + ports = {} + params = {} + lut_prims[prim].map(expr, params, ports) + print("", file=vf) + print("module \\%s (input %s, output Y);" % (name, + ", ".join(sorted(set(x for x in ports.values() if x)))), file=vf) + print(" %s #(" % prim, file=vf) + for k, v in sorted(params.items(), key=lambda x: x[0]): + print(" .%s(%s)," % (k, v), file=vf) + print(" ) _TECHMAP_REPLACE_ (", file=vf) + print(" %s," % ", ".join(".%s(%s)" % (k, v) for k, v in sorted(ports.items(), key=lambda x:x[0])), + file=vf) + print(" .O(Y)", file=vf) + print(" );", file=vf) + print("endmodule", file=vf) diff --git a/techlibs/gatemate/synth_gatemate.cc b/techlibs/gatemate/synth_gatemate.cc index 93b16b2e0..dd4fde643 100644 --- a/techlibs/gatemate/synth_gatemate.cc +++ b/techlibs/gatemate/synth_gatemate.cc @@ -67,7 +67,10 @@ struct SynthGateMatePass : public ScriptPass log("\n");
log(" -nomx8, -nomx4\n");
log(" do not use CC_MX{8,4} multiplexer cells in output netlist.\n");
- log("\n");;
+ log("\n");
+ log(" -luttree\n");
+ log(" use new LUT tree mapping approach (EXPERIMENTAL).\n");
+ log("\n");
log(" -dff\n");
log(" run 'abc' with -dff option\n");
log("\n");
@@ -87,7 +90,7 @@ struct SynthGateMatePass : public ScriptPass }
string top_opt, vlog_file, json_file;
- bool noflatten, nobram, noaddf, nomult, nomx4, nomx8, dff, retime, noiopad, noclkbuf;
+ bool noflatten, nobram, noaddf, nomult, nomx4, nomx8, luttree, dff, retime, noiopad, noclkbuf;
void clear_flags() override
{
@@ -100,6 +103,7 @@ struct SynthGateMatePass : public ScriptPass nomult = false;
nomx4 = false;
nomx8 = false;
+ luttree = false;
dff = false;
retime = false;
noiopad = false;
@@ -158,6 +162,10 @@ struct SynthGateMatePass : public ScriptPass nomx8 = true;
continue;
}
+ if (args[argidx] == "-luttree") {
+ luttree = true;
+ continue;
+ }
if (args[argidx] == "-dff") {
dff = true;
continue;
@@ -298,11 +306,23 @@ struct SynthGateMatePass : public ScriptPass if (check_label("map_luts"))
{
- std::string abc_args = " -dress -lut 4";
- if (dff) {
- abc_args += " -dff";
+ if (luttree || help_mode) {
+ std::string abc_args = " -genlib +/gatemate/lut_tree_cells.genlib";
+ if (dff) {
+ abc_args += " -dff";
+ }
+ run("abc " + abc_args, "(with -luttree)");
+ run("techmap -map +/gatemate/lut_tree_map.v", "(with -luttree)");
+ run("gatemate_foldinv", "(with -luttree)");
+ run("techmap -map +/gatemate/inv_map.v", "(with -luttree)");
+ }
+ if (!luttree || help_mode) {
+ std::string abc_args = " -dress -lut 4";
+ if (dff) {
+ abc_args += " -dff";
+ }
+ run("abc " + abc_args, "(without -luttree)");
}
- run("abc " + abc_args);
run("clean");
}
diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 15a0c41e0..0dffdf498 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -131,7 +131,6 @@ struct SynthGowinPass : public ScriptPass if (args[argidx] == "-json" && argidx+1 < args.size()) { json_file = args[++argidx]; nobram = true; - nolutram = true; continue; } if (args[argidx] == "-run" && argidx+1 < args.size()) { diff --git a/tests/arch/gatemate/gen_luttrees.py b/tests/arch/gatemate/gen_luttrees.py new file mode 100644 index 000000000..27d2225a2 --- /dev/null +++ b/tests/arch/gatemate/gen_luttrees.py @@ -0,0 +1,48 @@ +from random import Random + +def main(): + r = Random(1) + + N = 750 + with open("tests/arch/gatemate/luttrees.v", "w") as v: + print(f"module luttrees(input [{N-1}:0] a, b, c, d, e, output [{N-1}:0] q);", file=v) + for i in range(N): + def f(): + return r.choice(["&", "|", "^"]) + + def a(x): + return f"({r.choice(['', '!'])}{x}[{i}])" + + # Bias towards testing bigger functions + k = r.choice([2, 3, 4, 4, 4, 5, 5, 5]) + if k == 2: + expr = f"{a('a')}{f()}{a('b')}" + elif k == 3: + expr = f"({a('a')}{f()}{a('b')}){f()}{a('c')}" + elif k == 4: + # Two types of 4-input function + if r.choice([False, True]): + expr = f"(({a('a')}{f()}{a('b')}){f()}{a('c')}){f()}{a('d')}" + else: + expr = f"({a('a')}{f()}{a('b')}){f()}({a('c')}{f()}{a('d')})" + elif k == 5: + expr = f"(({a('a')}{f()}{a('b')}){f()}({a('c')}{f()}{a('d')})){f()}{a('e')}" + print(f" assign q[{i}] = {expr};", file=v) + print("endmodule", file=v) + with open("tests/arch/gatemate/luttrees.ys", "w") as s: + print(f""" +read_verilog luttrees.v +design -save read + +hierarchy -top luttrees +proc +equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -nomx4 -nomx8 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd luttrees # Constrain all select calls below inside the top module + +select -assert-count {N} t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% +select -assert-none t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% t:* %D +""", file=s) + +if __name__ == '__main__': + main() diff --git a/tests/arch/gatemate/luttrees.v b/tests/arch/gatemate/luttrees.v new file mode 100644 index 000000000..7fc02916d --- /dev/null +++ b/tests/arch/gatemate/luttrees.v @@ -0,0 +1,752 @@ +module luttrees(input [749:0] a, b, c, d, e, output [749:0] q); + assign q[0] = ((!a[0])&(!b[0]))|((!c[0])^(!d[0])); + assign q[1] = ((!a[1])&(!b[1]))|((c[1])^(!d[1])); + assign q[2] = ((a[2])|(b[2]))&((c[2])^(d[2])); + assign q[3] = (((a[3])|(b[3]))^((c[3])|(!d[3])))^(e[3]); + assign q[4] = (((a[4])^(b[4]))|((!c[4])&(!d[4])))^(e[4]); + assign q[5] = (((a[5])^(!b[5]))^(!c[5]))^(d[5]); + assign q[6] = (((!a[6])^(!b[6]))^(c[6]))|(d[6]); + assign q[7] = (((!a[7])^(b[7]))|((!c[7])&(!d[7])))^(e[7]); + assign q[8] = (((!a[8])|(b[8]))|(c[8]))|(!d[8]); + assign q[9] = ((a[9])&(b[9]))^((c[9])|(!d[9])); + assign q[10] = (((!a[10])|(b[10]))|((c[10])^(d[10])))|(e[10]); + assign q[11] = (((!a[11])^(b[11]))^((!c[11])|(!d[11])))|(!e[11]); + assign q[12] = (!a[12])|(b[12]); + assign q[13] = ((a[13])&(!b[13]))&((c[13])&(d[13])); + assign q[14] = (((a[14])|(b[14]))|((c[14])^(d[14])))|(!e[14]); + assign q[15] = ((a[15])&(!b[15]))^(c[15]); + assign q[16] = (((!a[16])^(!b[16]))|(!c[16]))&(d[16]); + assign q[17] = (((!a[17])|(b[17]))|(c[17]))|(d[17]); + assign q[18] = (((a[18])&(b[18]))|((c[18])&(d[18])))|(!e[18]); + assign q[19] = (((a[19])^(b[19]))|(!c[19]))^(!d[19]); + assign q[20] = (!a[20])&(b[20]); + assign q[21] = (!a[21])&(b[21]); + assign q[22] = (((a[22])|(!b[22]))&(c[22]))^(d[22]); + assign q[23] = (((a[23])^(b[23]))|(c[23]))|(d[23]); + assign q[24] = (((a[24])|(b[24]))^(!c[24]))|(!d[24]); + assign q[25] = (!a[25])^(!b[25]); + assign q[26] = ((a[26])&(!b[26]))^((c[26])|(!d[26])); + assign q[27] = (((a[27])|(!b[27]))^(!c[27]))^(d[27]); + assign q[28] = ((a[28])&(b[28]))&(c[28]); + assign q[29] = (((!a[29])^(!b[29]))|(!c[29]))|(d[29]); + assign q[30] = ((!a[30])&(b[30]))|((c[30])|(d[30])); + assign q[31] = (((a[31])&(!b[31]))&((!c[31])&(d[31])))^(e[31]); + assign q[32] = (((!a[32])^(b[32]))|(!c[32]))&(d[32]); + assign q[33] = ((a[33])&(!b[33]))&((c[33])&(d[33])); + assign q[34] = (((a[34])&(!b[34]))&((c[34])&(d[34])))|(!e[34]); + assign q[35] = (((!a[35])|(b[35]))&(!c[35]))&(d[35]); + assign q[36] = (!a[36])^(!b[36]); + assign q[37] = (((!a[37])|(!b[37]))&((c[37])|(!d[37])))&(!e[37]); + assign q[38] = (((!a[38])|(b[38]))^(c[38]))|(d[38]); + assign q[39] = (((a[39])|(b[39]))|(c[39]))^(!d[39]); + assign q[40] = (((!a[40])&(!b[40]))&(!c[40]))^(!d[40]); + assign q[41] = (((a[41])^(b[41]))&(c[41]))&(d[41]); + assign q[42] = (((a[42])|(b[42]))^((c[42])&(d[42])))|(!e[42]); + assign q[43] = (((!a[43])&(b[43]))^((!c[43])&(d[43])))&(e[43]); + assign q[44] = (((!a[44])&(!b[44]))&(c[44]))&(d[44]); + assign q[45] = (((a[45])&(!b[45]))|((c[45])&(d[45])))|(e[45]); + assign q[46] = (((!a[46])^(!b[46]))^((!c[46])^(!d[46])))&(!e[46]); + assign q[47] = (((a[47])|(!b[47]))&((!c[47])^(d[47])))&(!e[47]); + assign q[48] = ((a[48])|(!b[48]))|((!c[48])&(d[48])); + assign q[49] = (((a[49])&(!b[49]))^(!c[49]))^(d[49]); + assign q[50] = (((!a[50])^(!b[50]))&(!c[50]))|(!d[50]); + assign q[51] = ((a[51])^(!b[51]))&((c[51])|(!d[51])); + assign q[52] = (((a[52])^(!b[52]))^(c[52]))&(!d[52]); + assign q[53] = ((!a[53])|(b[53]))^((c[53])|(!d[53])); + assign q[54] = (((!a[54])^(b[54]))^((c[54])^(d[54])))|(e[54]); + assign q[55] = ((a[55])^(b[55]))|((c[55])|(!d[55])); + assign q[56] = (((a[56])|(!b[56]))&((!c[56])&(d[56])))|(!e[56]); + assign q[57] = ((!a[57])|(b[57]))|(c[57]); + assign q[58] = (((a[58])&(b[58]))|(c[58]))&(!d[58]); + assign q[59] = ((!a[59])|(!b[59]))^((!c[59])&(!d[59])); + assign q[60] = (((!a[60])&(b[60]))^((!c[60])&(!d[60])))&(e[60]); + assign q[61] = ((a[61])^(!b[61]))^(c[61]); + assign q[62] = ((!a[62])^(!b[62]))|(!c[62]); + assign q[63] = (((a[63])&(!b[63]))^((!c[63])|(!d[63])))^(!e[63]); + assign q[64] = (((!a[64])&(!b[64]))|((c[64])^(d[64])))|(e[64]); + assign q[65] = (((!a[65])^(!b[65]))^((c[65])|(d[65])))|(e[65]); + assign q[66] = (((!a[66])|(!b[66]))^((c[66])|(d[66])))^(!e[66]); + assign q[67] = (!a[67])^(b[67]); + assign q[68] = (((!a[68])&(b[68]))^((c[68])|(!d[68])))^(!e[68]); + assign q[69] = ((!a[69])|(!b[69]))&((!c[69])^(d[69])); + assign q[70] = ((!a[70])&(!b[70]))&((!c[70])&(d[70])); + assign q[71] = ((!a[71])^(!b[71]))^((!c[71])&(d[71])); + assign q[72] = (((!a[72])&(b[72]))^(!c[72]))|(d[72]); + assign q[73] = (((!a[73])|(b[73]))|(!c[73]))&(!d[73]); + assign q[74] = (((a[74])|(b[74]))^(c[74]))^(!d[74]); + assign q[75] = (((!a[75])&(!b[75]))&((c[75])^(d[75])))^(!e[75]); + assign q[76] = (((!a[76])^(b[76]))&(c[76]))^(!d[76]); + assign q[77] = (((!a[77])|(b[77]))&((c[77])^(!d[77])))&(e[77]); + assign q[78] = (((!a[78])|(b[78]))&(c[78]))&(d[78]); + assign q[79] = ((!a[79])^(!b[79]))|((!c[79])&(d[79])); + assign q[80] = ((a[80])|(b[80]))|(!c[80]); + assign q[81] = (((a[81])&(b[81]))|((!c[81])^(!d[81])))&(!e[81]); + assign q[82] = (((!a[82])^(b[82]))&(c[82]))&(d[82]); + assign q[83] = (!a[83])|(!b[83]); + assign q[84] = ((!a[84])&(b[84]))&((c[84])|(d[84])); + assign q[85] = (!a[85])|(b[85]); + assign q[86] = ((!a[86])^(!b[86]))&(c[86]); + assign q[87] = (a[87])&(!b[87]); + assign q[88] = ((!a[88])&(b[88]))&(!c[88]); + assign q[89] = (((a[89])^(!b[89]))|(!c[89]))^(!d[89]); + assign q[90] = ((a[90])&(b[90]))|((!c[90])^(d[90])); + assign q[91] = (((!a[91])^(b[91]))^((!c[91])^(d[91])))^(!e[91]); + assign q[92] = ((!a[92])&(b[92]))&(c[92]); + assign q[93] = (((a[93])&(b[93]))^(!c[93]))^(!d[93]); + assign q[94] = ((!a[94])&(b[94]))^(c[94]); + assign q[95] = (((a[95])|(!b[95]))&((!c[95])&(!d[95])))|(e[95]); + assign q[96] = ((!a[96])&(!b[96]))|((c[96])|(!d[96])); + assign q[97] = ((!a[97])&(!b[97]))&(c[97]); + assign q[98] = (((!a[98])^(!b[98]))^((!c[98])&(d[98])))^(!e[98]); + assign q[99] = (!a[99])^(b[99]); + assign q[100] = (((!a[100])^(!b[100]))&(!c[100]))|(d[100]); + assign q[101] = ((a[101])|(!b[101]))|(!c[101]); + assign q[102] = (((!a[102])|(!b[102]))^((c[102])^(d[102])))&(!e[102]); + assign q[103] = (((!a[103])^(b[103]))|((!c[103])|(!d[103])))|(!e[103]); + assign q[104] = ((a[104])&(b[104]))^(!c[104]); + assign q[105] = ((!a[105])|(!b[105]))|((!c[105])|(!d[105])); + assign q[106] = ((a[106])|(b[106]))^((c[106])&(d[106])); + assign q[107] = (((a[107])&(!b[107]))^((c[107])&(!d[107])))&(e[107]); + assign q[108] = ((a[108])^(b[108]))^(!c[108]); + assign q[109] = (!a[109])|(!b[109]); + assign q[110] = ((!a[110])&(!b[110]))|((!c[110])^(d[110])); + assign q[111] = (((a[111])|(!b[111]))&((c[111])^(!d[111])))^(!e[111]); + assign q[112] = ((!a[112])^(!b[112]))&(!c[112]); + assign q[113] = (((a[113])&(!b[113]))^((c[113])^(d[113])))|(!e[113]); + assign q[114] = (((!a[114])^(!b[114]))|(!c[114]))&(!d[114]); + assign q[115] = ((!a[115])^(b[115]))|((c[115])|(!d[115])); + assign q[116] = (((!a[116])^(b[116]))&((c[116])&(!d[116])))|(!e[116]); + assign q[117] = (((!a[117])|(!b[117]))|(c[117]))|(!d[117]); + assign q[118] = (((a[118])&(b[118]))|(!c[118]))&(!d[118]); + assign q[119] = (((!a[119])^(!b[119]))^((!c[119])^(!d[119])))|(!e[119]); + assign q[120] = (((a[120])^(!b[120]))|((!c[120])&(d[120])))&(e[120]); + assign q[121] = ((a[121])&(!b[121]))&((!c[121])&(!d[121])); + assign q[122] = ((a[122])|(b[122]))^((c[122])^(!d[122])); + assign q[123] = (((a[123])^(b[123]))^((!c[123])^(d[123])))|(!e[123]); + assign q[124] = (((a[124])&(b[124]))|(c[124]))^(!d[124]); + assign q[125] = (((!a[125])&(!b[125]))&(c[125]))|(d[125]); + assign q[126] = (((!a[126])^(!b[126]))|(c[126]))^(!d[126]); + assign q[127] = (((a[127])&(!b[127]))^((!c[127])&(!d[127])))|(e[127]); + assign q[128] = (((!a[128])^(b[128]))|(c[128]))&(!d[128]); + assign q[129] = (((a[129])^(b[129]))|(!c[129]))|(!d[129]); + assign q[130] = (((!a[130])&(!b[130]))|(!c[130]))&(!d[130]); + assign q[131] = ((!a[131])^(b[131]))&((!c[131])^(d[131])); + assign q[132] = (((!a[132])|(!b[132]))&(c[132]))&(!d[132]); + assign q[133] = ((a[133])^(b[133]))^((c[133])&(d[133])); + assign q[134] = (((!a[134])&(b[134]))|(c[134]))&(d[134]); + assign q[135] = (((!a[135])^(!b[135]))&(c[135]))|(!d[135]); + assign q[136] = ((!a[136])&(b[136]))|((c[136])&(d[136])); + assign q[137] = (((a[137])|(b[137]))|(c[137]))&(d[137]); + assign q[138] = (((!a[138])^(b[138]))&((!c[138])|(d[138])))^(!e[138]); + assign q[139] = ((!a[139])^(b[139]))^(!c[139]); + assign q[140] = (((a[140])^(!b[140]))^((!c[140])^(!d[140])))|(e[140]); + assign q[141] = ((a[141])^(b[141]))&((c[141])&(!d[141])); + assign q[142] = ((!a[142])^(!b[142]))^((!c[142])|(d[142])); + assign q[143] = (((a[143])^(!b[143]))&((!c[143])^(d[143])))^(!e[143]); + assign q[144] = (((a[144])&(b[144]))^((c[144])^(d[144])))|(!e[144]); + assign q[145] = (((!a[145])&(b[145]))|((!c[145])|(d[145])))^(e[145]); + assign q[146] = (((a[146])^(b[146]))^(c[146]))|(d[146]); + assign q[147] = (((a[147])|(!b[147]))|((!c[147])|(!d[147])))^(!e[147]); + assign q[148] = (a[148])|(b[148]); + assign q[149] = (a[149])&(b[149]); + assign q[150] = (((!a[150])^(!b[150]))|((c[150])^(d[150])))&(!e[150]); + assign q[151] = ((a[151])^(!b[151]))|((!c[151])|(d[151])); + assign q[152] = (((!a[152])|(!b[152]))|((!c[152])|(d[152])))^(e[152]); + assign q[153] = (!a[153])^(b[153]); + assign q[154] = (((!a[154])^(b[154]))^(c[154]))|(d[154]); + assign q[155] = (((a[155])|(b[155]))&((c[155])|(!d[155])))^(e[155]); + assign q[156] = (((!a[156])|(!b[156]))^((c[156])|(!d[156])))|(e[156]); + assign q[157] = (((!a[157])&(b[157]))&((!c[157])|(d[157])))&(e[157]); + assign q[158] = (((!a[158])^(!b[158]))&(c[158]))^(d[158]); + assign q[159] = ((!a[159])|(b[159]))^((!c[159])&(d[159])); + assign q[160] = (((a[160])^(b[160]))|((c[160])&(d[160])))&(!e[160]); + assign q[161] = (a[161])|(b[161]); + assign q[162] = (a[162])^(b[162]); + assign q[163] = (((!a[163])&(b[163]))|(c[163]))^(d[163]); + assign q[164] = (((a[164])^(b[164]))&((c[164])|(!d[164])))|(!e[164]); + assign q[165] = ((!a[165])^(!b[165]))^((!c[165])^(d[165])); + assign q[166] = (((!a[166])&(!b[166]))|((!c[166])&(!d[166])))^(!e[166]); + assign q[167] = ((!a[167])|(b[167]))|((!c[167])|(!d[167])); + assign q[168] = (((!a[168])^(!b[168]))&((c[168])&(!d[168])))&(e[168]); + assign q[169] = ((a[169])^(!b[169]))^(c[169]); + assign q[170] = (((!a[170])^(b[170]))&(c[170]))&(d[170]); + assign q[171] = (!a[171])|(!b[171]); + assign q[172] = ((a[172])&(!b[172]))&((!c[172])&(!d[172])); + assign q[173] = (((a[173])&(!b[173]))^((c[173])|(!d[173])))^(!e[173]); + assign q[174] = ((!a[174])&(!b[174]))&(!c[174]); + assign q[175] = ((!a[175])|(!b[175]))^(c[175]); + assign q[176] = (!a[176])&(b[176]); + assign q[177] = ((a[177])|(b[177]))^(c[177]); + assign q[178] = (((a[178])^(b[178]))|((c[178])^(!d[178])))^(e[178]); + assign q[179] = ((a[179])^(!b[179]))^(!c[179]); + assign q[180] = (((a[180])^(b[180]))^(c[180]))|(!d[180]); + assign q[181] = (((!a[181])|(!b[181]))&((c[181])&(d[181])))|(e[181]); + assign q[182] = (((a[182])|(!b[182]))&((c[182])&(d[182])))|(!e[182]); + assign q[183] = ((a[183])^(!b[183]))^((!c[183])&(d[183])); + assign q[184] = (((a[184])|(b[184]))|((c[184])^(d[184])))&(!e[184]); + assign q[185] = (((a[185])^(b[185]))^((!c[185])&(!d[185])))^(!e[185]); + assign q[186] = (((!a[186])|(!b[186]))&((!c[186])&(!d[186])))|(!e[186]); + assign q[187] = (((a[187])^(!b[187]))|(!c[187]))^(d[187]); + assign q[188] = ((a[188])^(b[188]))&(!c[188]); + assign q[189] = (((!a[189])^(b[189]))^((!c[189])^(d[189])))|(e[189]); + assign q[190] = (((!a[190])^(b[190]))&((!c[190])|(d[190])))&(e[190]); + assign q[191] = ((!a[191])|(!b[191]))|(!c[191]); + assign q[192] = (((a[192])^(b[192]))^(c[192]))|(!d[192]); + assign q[193] = ((a[193])^(b[193]))|((!c[193])&(d[193])); + assign q[194] = (((a[194])&(b[194]))|(!c[194]))&(!d[194]); + assign q[195] = ((!a[195])|(!b[195]))^((c[195])&(!d[195])); + assign q[196] = (((a[196])&(!b[196]))|((c[196])^(d[196])))^(!e[196]); + assign q[197] = ((a[197])&(b[197]))^((c[197])^(!d[197])); + assign q[198] = (((a[198])&(!b[198]))|((!c[198])^(!d[198])))&(e[198]); + assign q[199] = (!a[199])&(b[199]); + assign q[200] = ((a[200])&(b[200]))^((c[200])&(d[200])); + assign q[201] = (((!a[201])&(!b[201]))^(!c[201]))|(!d[201]); + assign q[202] = ((a[202])^(b[202]))&(!c[202]); + assign q[203] = (((!a[203])|(b[203]))|((c[203])&(!d[203])))^(!e[203]); + assign q[204] = (((a[204])^(!b[204]))&((!c[204])^(!d[204])))^(!e[204]); + assign q[205] = (((a[205])|(!b[205]))^((!c[205])^(!d[205])))|(!e[205]); + assign q[206] = (a[206])|(!b[206]); + assign q[207] = (((a[207])^(!b[207]))&((!c[207])|(d[207])))|(!e[207]); + assign q[208] = (a[208])|(b[208]); + assign q[209] = ((!a[209])|(b[209]))|((!c[209])|(d[209])); + assign q[210] = ((!a[210])&(b[210]))&((!c[210])|(!d[210])); + assign q[211] = ((a[211])^(!b[211]))|((!c[211])|(!d[211])); + assign q[212] = (((a[212])&(!b[212]))&((c[212])^(d[212])))^(e[212]); + assign q[213] = (((!a[213])&(b[213]))^(!c[213]))^(!d[213]); + assign q[214] = (!a[214])|(!b[214]); + assign q[215] = ((a[215])|(!b[215]))^((!c[215])^(!d[215])); + assign q[216] = (((a[216])^(!b[216]))^((!c[216])|(d[216])))|(e[216]); + assign q[217] = (((a[217])^(b[217]))^((!c[217])|(!d[217])))&(e[217]); + assign q[218] = ((a[218])&(!b[218]))&(c[218]); + assign q[219] = ((a[219])|(b[219]))&((c[219])&(d[219])); + assign q[220] = (((!a[220])&(b[220]))^((c[220])|(d[220])))|(!e[220]); + assign q[221] = ((a[221])&(!b[221]))&((c[221])^(!d[221])); + assign q[222] = (!a[222])|(!b[222]); + assign q[223] = ((a[223])^(b[223]))^(c[223]); + assign q[224] = ((a[224])&(!b[224]))&((c[224])|(d[224])); + assign q[225] = ((!a[225])&(b[225]))&(!c[225]); + assign q[226] = (((a[226])^(b[226]))|((c[226])&(d[226])))&(e[226]); + assign q[227] = ((a[227])&(b[227]))|((!c[227])^(!d[227])); + assign q[228] = ((!a[228])&(!b[228]))|((!c[228])|(!d[228])); + assign q[229] = (((a[229])|(b[229]))|((!c[229])&(d[229])))&(e[229]); + assign q[230] = (((!a[230])^(!b[230]))|((!c[230])|(!d[230])))|(!e[230]); + assign q[231] = (((!a[231])|(b[231]))|((c[231])|(d[231])))|(e[231]); + assign q[232] = ((!a[232])^(b[232]))&((c[232])&(!d[232])); + assign q[233] = (((!a[233])&(!b[233]))|(!c[233]))&(!d[233]); + assign q[234] = (((!a[234])&(b[234]))^(!c[234]))&(d[234]); + assign q[235] = (((a[235])&(b[235]))^((!c[235])^(!d[235])))^(!e[235]); + assign q[236] = (((!a[236])^(b[236]))&((!c[236])&(!d[236])))^(e[236]); + assign q[237] = (a[237])|(!b[237]); + assign q[238] = (((a[238])|(b[238]))&((!c[238])^(d[238])))&(e[238]); + assign q[239] = ((!a[239])^(!b[239]))&((c[239])&(d[239])); + assign q[240] = (((!a[240])^(!b[240]))&(!c[240]))&(!d[240]); + assign q[241] = ((!a[241])&(b[241]))&(c[241]); + assign q[242] = ((a[242])|(!b[242]))&((c[242])|(d[242])); + assign q[243] = ((a[243])|(b[243]))^((!c[243])&(d[243])); + assign q[244] = (((!a[244])^(b[244]))&(!c[244]))|(!d[244]); + assign q[245] = (((a[245])^(!b[245]))^(!c[245]))^(!d[245]); + assign q[246] = ((!a[246])|(!b[246]))&(!c[246]); + assign q[247] = ((!a[247])&(b[247]))|(c[247]); + assign q[248] = (((!a[248])|(!b[248]))|((!c[248])&(!d[248])))&(!e[248]); + assign q[249] = (a[249])|(!b[249]); + assign q[250] = (((!a[250])^(!b[250]))^(!c[250]))^(!d[250]); + assign q[251] = (((a[251])|(b[251]))|(!c[251]))^(d[251]); + assign q[252] = (((!a[252])&(!b[252]))^((c[252])&(d[252])))&(e[252]); + assign q[253] = (!a[253])^(!b[253]); + assign q[254] = (((a[254])^(!b[254]))|((c[254])|(!d[254])))&(!e[254]); + assign q[255] = (!a[255])|(!b[255]); + assign q[256] = (((a[256])|(!b[256]))&(c[256]))&(!d[256]); + assign q[257] = (!a[257])^(!b[257]); + assign q[258] = (((!a[258])&(b[258]))^(c[258]))|(d[258]); + assign q[259] = (((!a[259])&(!b[259]))|(c[259]))&(!d[259]); + assign q[260] = ((!a[260])&(!b[260]))|((!c[260])^(!d[260])); + assign q[261] = (((a[261])|(b[261]))^(c[261]))|(d[261]); + assign q[262] = (((!a[262])^(b[262]))^((!c[262])|(!d[262])))|(e[262]); + assign q[263] = (a[263])^(b[263]); + assign q[264] = ((!a[264])&(!b[264]))|(c[264]); + assign q[265] = (((!a[265])^(b[265]))^((c[265])^(!d[265])))|(!e[265]); + assign q[266] = (((a[266])^(!b[266]))&(c[266]))^(d[266]); + assign q[267] = ((a[267])|(!b[267]))|(!c[267]); + assign q[268] = ((!a[268])&(!b[268]))|(!c[268]); + assign q[269] = (((!a[269])^(b[269]))&((!c[269])^(!d[269])))^(!e[269]); + assign q[270] = (((a[270])|(b[270]))^(c[270]))&(d[270]); + assign q[271] = (((a[271])&(b[271]))|((c[271])|(d[271])))|(!e[271]); + assign q[272] = (((a[272])|(!b[272]))^(!c[272]))|(!d[272]); + assign q[273] = (((!a[273])|(b[273]))&((!c[273])&(!d[273])))&(!e[273]); + assign q[274] = ((a[274])^(!b[274]))|(!c[274]); + assign q[275] = (((!a[275])^(!b[275]))|((!c[275])^(!d[275])))^(e[275]); + assign q[276] = ((a[276])^(b[276]))&((!c[276])^(d[276])); + assign q[277] = (((!a[277])&(!b[277]))|((!c[277])^(!d[277])))&(!e[277]); + assign q[278] = (((!a[278])^(!b[278]))^(c[278]))&(!d[278]); + assign q[279] = (((a[279])&(b[279]))^((!c[279])|(d[279])))^(!e[279]); + assign q[280] = ((!a[280])&(!b[280]))&(!c[280]); + assign q[281] = ((a[281])|(b[281]))|((!c[281])|(!d[281])); + assign q[282] = ((a[282])&(b[282]))&((c[282])|(d[282])); + assign q[283] = (((a[283])|(!b[283]))^((c[283])&(!d[283])))&(e[283]); + assign q[284] = (((!a[284])&(b[284]))&(!c[284]))^(d[284]); + assign q[285] = (((a[285])|(!b[285]))&(!c[285]))|(d[285]); + assign q[286] = (((a[286])^(b[286]))&((c[286])^(!d[286])))&(!e[286]); + assign q[287] = ((a[287])&(!b[287]))|((c[287])|(!d[287])); + assign q[288] = ((!a[288])|(!b[288]))|((!c[288])|(!d[288])); + assign q[289] = ((a[289])&(b[289]))&((c[289])&(!d[289])); + assign q[290] = (((!a[290])^(b[290]))&((c[290])^(d[290])))&(!e[290]); + assign q[291] = (((a[291])&(!b[291]))|(!c[291]))^(d[291]); + assign q[292] = (((a[292])^(!b[292]))^((c[292])|(d[292])))&(e[292]); + assign q[293] = (((a[293])&(!b[293]))&((c[293])|(d[293])))|(e[293]); + assign q[294] = (((a[294])^(!b[294]))&((!c[294])^(d[294])))&(!e[294]); + assign q[295] = (((a[295])^(!b[295]))|((!c[295])|(d[295])))&(e[295]); + assign q[296] = (((a[296])&(!b[296]))&((c[296])&(d[296])))&(!e[296]); + assign q[297] = ((!a[297])|(b[297]))^((!c[297])^(!d[297])); + assign q[298] = (((a[298])^(b[298]))|((!c[298])|(d[298])))|(!e[298]); + assign q[299] = (((!a[299])^(b[299]))|((c[299])^(!d[299])))|(!e[299]); + assign q[300] = (((!a[300])^(!b[300]))^(!c[300]))|(d[300]); + assign q[301] = ((a[301])&(!b[301]))&((!c[301])|(!d[301])); + assign q[302] = ((a[302])^(b[302]))|((c[302])|(!d[302])); + assign q[303] = (((!a[303])&(b[303]))^((c[303])|(d[303])))|(!e[303]); + assign q[304] = (!a[304])^(b[304]); + assign q[305] = (((a[305])&(!b[305]))^((!c[305])&(!d[305])))^(!e[305]); + assign q[306] = (a[306])&(b[306]); + assign q[307] = ((a[307])&(!b[307]))&(c[307]); + assign q[308] = ((a[308])&(!b[308]))^((!c[308])|(d[308])); + assign q[309] = ((a[309])^(!b[309]))&((c[309])|(!d[309])); + assign q[310] = (((!a[310])|(b[310]))&((c[310])^(d[310])))^(!e[310]); + assign q[311] = (((!a[311])|(b[311]))&((c[311])&(d[311])))|(e[311]); + assign q[312] = (((!a[312])&(b[312]))|((c[312])^(!d[312])))&(!e[312]); + assign q[313] = (!a[313])|(!b[313]); + assign q[314] = ((a[314])^(!b[314]))^((c[314])|(!d[314])); + assign q[315] = (a[315])&(!b[315]); + assign q[316] = ((!a[316])^(!b[316]))&(!c[316]); + assign q[317] = ((a[317])&(!b[317]))^(c[317]); + assign q[318] = (((!a[318])^(!b[318]))|(!c[318]))&(!d[318]); + assign q[319] = (((a[319])&(!b[319]))|(!c[319]))^(d[319]); + assign q[320] = (((!a[320])^(!b[320]))|(c[320]))|(d[320]); + assign q[321] = ((a[321])|(!b[321]))|((c[321])|(d[321])); + assign q[322] = ((!a[322])^(!b[322]))&(!c[322]); + assign q[323] = (((!a[323])&(b[323]))|(c[323]))|(d[323]); + assign q[324] = ((!a[324])&(!b[324]))^((c[324])|(d[324])); + assign q[325] = ((a[325])&(!b[325]))|(!c[325]); + assign q[326] = ((!a[326])^(!b[326]))|(c[326]); + assign q[327] = (((a[327])|(b[327]))&((c[327])|(!d[327])))^(!e[327]); + assign q[328] = ((!a[328])|(b[328]))&((c[328])&(d[328])); + assign q[329] = (((a[329])&(b[329]))^(c[329]))|(!d[329]); + assign q[330] = ((a[330])|(b[330]))|((c[330])^(!d[330])); + assign q[331] = (((!a[331])|(b[331]))&(c[331]))&(d[331]); + assign q[332] = (((!a[332])&(b[332]))|((!c[332])^(d[332])))&(e[332]); + assign q[333] = (((a[333])^(!b[333]))|(!c[333]))|(!d[333]); + assign q[334] = ((a[334])&(!b[334]))&((c[334])&(!d[334])); + assign q[335] = (((!a[335])&(b[335]))^((c[335])&(d[335])))&(e[335]); + assign q[336] = (!a[336])^(b[336]); + assign q[337] = (((a[337])^(b[337]))&(c[337]))&(d[337]); + assign q[338] = (((a[338])^(!b[338]))&(!c[338]))&(!d[338]); + assign q[339] = (((!a[339])^(!b[339]))|((!c[339])|(d[339])))&(!e[339]); + assign q[340] = (((a[340])^(b[340]))^((c[340])^(d[340])))|(e[340]); + assign q[341] = (((!a[341])&(!b[341]))^(!c[341]))^(d[341]); + assign q[342] = (a[342])^(!b[342]); + assign q[343] = (((!a[343])^(b[343]))&((c[343])|(!d[343])))|(e[343]); + assign q[344] = ((a[344])&(b[344]))&((!c[344])&(d[344])); + assign q[345] = (((!a[345])&(b[345]))&((c[345])^(!d[345])))|(e[345]); + assign q[346] = (((a[346])^(!b[346]))&(c[346]))&(!d[346]); + assign q[347] = (((!a[347])^(!b[347]))|((c[347])|(!d[347])))|(!e[347]); + assign q[348] = (((a[348])|(b[348]))&((!c[348])&(d[348])))|(!e[348]); + assign q[349] = (!a[349])&(b[349]); + assign q[350] = (((!a[350])^(b[350]))|((c[350])|(!d[350])))&(e[350]); + assign q[351] = (((!a[351])^(!b[351]))^((c[351])|(!d[351])))&(!e[351]); + assign q[352] = ((!a[352])|(b[352]))^(c[352]); + assign q[353] = (((a[353])&(!b[353]))^((c[353])&(!d[353])))|(!e[353]); + assign q[354] = (((!a[354])^(b[354]))^((!c[354])^(d[354])))^(e[354]); + assign q[355] = (a[355])|(b[355]); + assign q[356] = (((a[356])^(!b[356]))^(!c[356]))&(!d[356]); + assign q[357] = (((a[357])&(!b[357]))^((c[357])&(!d[357])))^(e[357]); + assign q[358] = (((a[358])&(b[358]))&((!c[358])&(d[358])))|(e[358]); + assign q[359] = (((a[359])&(!b[359]))&((!c[359])^(!d[359])))&(e[359]); + assign q[360] = (((!a[360])|(!b[360]))|((!c[360])|(d[360])))&(!e[360]); + assign q[361] = (((a[361])|(b[361]))^((c[361])|(!d[361])))^(!e[361]); + assign q[362] = (((!a[362])|(!b[362]))|(c[362]))|(d[362]); + assign q[363] = ((a[363])|(!b[363]))&((!c[363])^(!d[363])); + assign q[364] = (((a[364])&(!b[364]))&((c[364])&(d[364])))|(e[364]); + assign q[365] = ((a[365])|(!b[365]))&((c[365])|(d[365])); + assign q[366] = (((a[366])|(!b[366]))&((!c[366])|(!d[366])))^(!e[366]); + assign q[367] = ((a[367])^(!b[367]))^((!c[367])|(!d[367])); + assign q[368] = (((!a[368])&(b[368]))&((!c[368])|(!d[368])))&(!e[368]); + assign q[369] = ((a[369])^(b[369]))|((c[369])|(d[369])); + assign q[370] = (((a[370])^(b[370]))^(!c[370]))|(!d[370]); + assign q[371] = (((a[371])^(b[371]))&((!c[371])&(d[371])))&(!e[371]); + assign q[372] = (((!a[372])|(!b[372]))|((!c[372])&(d[372])))&(!e[372]); + assign q[373] = ((a[373])&(b[373]))&((!c[373])&(!d[373])); + assign q[374] = (((!a[374])^(!b[374]))^((!c[374])&(!d[374])))|(e[374]); + assign q[375] = ((!a[375])&(b[375]))^(!c[375]); + assign q[376] = (!a[376])|(b[376]); + assign q[377] = (((!a[377])^(b[377]))^((!c[377])^(!d[377])))^(e[377]); + assign q[378] = (((a[378])|(!b[378]))^((c[378])^(d[378])))&(!e[378]); + assign q[379] = (((a[379])|(b[379]))&((!c[379])^(!d[379])))^(e[379]); + assign q[380] = (((!a[380])^(!b[380]))^((c[380])|(!d[380])))&(!e[380]); + assign q[381] = (((!a[381])^(b[381]))^(c[381]))^(!d[381]); + assign q[382] = (((!a[382])^(b[382]))^(!c[382]))&(!d[382]); + assign q[383] = (((!a[383])&(!b[383]))&((c[383])^(d[383])))|(e[383]); + assign q[384] = (((a[384])&(b[384]))&((c[384])&(d[384])))^(e[384]); + assign q[385] = ((a[385])|(!b[385]))&(!c[385]); + assign q[386] = ((a[386])|(b[386]))&(!c[386]); + assign q[387] = (((!a[387])^(b[387]))|(c[387]))^(d[387]); + assign q[388] = (!a[388])&(!b[388]); + assign q[389] = ((a[389])^(b[389]))^(!c[389]); + assign q[390] = (((!a[390])|(b[390]))^(c[390]))|(d[390]); + assign q[391] = (!a[391])^(!b[391]); + assign q[392] = ((!a[392])^(b[392]))|(c[392]); + assign q[393] = (((!a[393])&(!b[393]))^((c[393])^(d[393])))^(e[393]); + assign q[394] = (((!a[394])^(b[394]))|(!c[394]))|(!d[394]); + assign q[395] = ((!a[395])&(!b[395]))^(!c[395]); + assign q[396] = ((a[396])^(b[396]))|((!c[396])|(d[396])); + assign q[397] = (((a[397])|(!b[397]))&((!c[397])&(d[397])))&(!e[397]); + assign q[398] = (((a[398])&(!b[398]))^((c[398])&(d[398])))|(!e[398]); + assign q[399] = (((!a[399])^(!b[399]))^((c[399])&(d[399])))|(!e[399]); + assign q[400] = (!a[400])&(b[400]); + assign q[401] = (((a[401])&(!b[401]))^(!c[401]))^(!d[401]); + assign q[402] = ((a[402])|(!b[402]))^((!c[402])^(!d[402])); + assign q[403] = (((!a[403])|(!b[403]))|((c[403])|(d[403])))^(!e[403]); + assign q[404] = (((!a[404])^(b[404]))&((c[404])&(d[404])))^(!e[404]); + assign q[405] = (((!a[405])^(b[405]))&(!c[405]))&(d[405]); + assign q[406] = (((!a[406])|(b[406]))|((c[406])^(!d[406])))&(!e[406]); + assign q[407] = (!a[407])|(b[407]); + assign q[408] = (((!a[408])&(!b[408]))|(!c[408]))&(!d[408]); + assign q[409] = (!a[409])^(!b[409]); + assign q[410] = (((!a[410])|(b[410]))|((!c[410])|(d[410])))|(!e[410]); + assign q[411] = (((!a[411])^(b[411]))|((c[411])&(d[411])))|(e[411]); + assign q[412] = ((!a[412])&(!b[412]))&((c[412])|(d[412])); + assign q[413] = (((!a[413])^(b[413]))^((c[413])&(!d[413])))&(!e[413]); + assign q[414] = (a[414])^(!b[414]); + assign q[415] = (((!a[415])^(b[415]))&(c[415]))|(!d[415]); + assign q[416] = ((!a[416])|(!b[416]))&(c[416]); + assign q[417] = (((!a[417])^(!b[417]))^((c[417])^(d[417])))|(!e[417]); + assign q[418] = ((!a[418])&(!b[418]))^((!c[418])&(!d[418])); + assign q[419] = (!a[419])&(!b[419]); + assign q[420] = ((a[420])^(!b[420]))|(!c[420]); + assign q[421] = ((!a[421])&(!b[421]))&((!c[421])^(d[421])); + assign q[422] = ((!a[422])^(b[422]))^((!c[422])&(!d[422])); + assign q[423] = (((a[423])|(b[423]))^((c[423])&(d[423])))^(!e[423]); + assign q[424] = (a[424])|(b[424]); + assign q[425] = (!a[425])^(b[425]); + assign q[426] = (!a[426])^(!b[426]); + assign q[427] = ((a[427])&(!b[427]))^((!c[427])^(!d[427])); + assign q[428] = (((!a[428])&(!b[428]))^(!c[428]))^(d[428]); + assign q[429] = (((!a[429])^(b[429]))&(c[429]))&(d[429]); + assign q[430] = ((!a[430])&(b[430]))^((c[430])^(d[430])); + assign q[431] = (((!a[431])|(b[431]))^((!c[431])|(d[431])))&(e[431]); + assign q[432] = (((!a[432])|(!b[432]))|((!c[432])^(d[432])))|(!e[432]); + assign q[433] = (((a[433])^(!b[433]))&(!c[433]))&(d[433]); + assign q[434] = ((!a[434])&(!b[434]))|((c[434])|(!d[434])); + assign q[435] = (!a[435])|(!b[435]); + assign q[436] = (((!a[436])^(!b[436]))&((!c[436])|(!d[436])))&(e[436]); + assign q[437] = (((!a[437])^(!b[437]))^(!c[437]))&(!d[437]); + assign q[438] = (!a[438])^(b[438]); + assign q[439] = ((a[439])^(!b[439]))|(c[439]); + assign q[440] = ((a[440])^(!b[440]))|((!c[440])&(!d[440])); + assign q[441] = (((a[441])&(b[441]))^((c[441])&(d[441])))|(e[441]); + assign q[442] = (!a[442])|(b[442]); + assign q[443] = (!a[443])^(b[443]); + assign q[444] = ((a[444])^(!b[444]))|((c[444])&(d[444])); + assign q[445] = (((a[445])|(!b[445]))&(c[445]))|(d[445]); + assign q[446] = ((a[446])&(b[446]))^((c[446])^(!d[446])); + assign q[447] = ((!a[447])&(!b[447]))^(!c[447]); + assign q[448] = (((!a[448])^(b[448]))&(c[448]))|(!d[448]); + assign q[449] = (((a[449])|(!b[449]))|((c[449])&(d[449])))|(!e[449]); + assign q[450] = (((!a[450])|(b[450]))|(c[450]))^(!d[450]); + assign q[451] = ((a[451])^(b[451]))|((c[451])^(d[451])); + assign q[452] = (((a[452])^(!b[452]))|(c[452]))|(d[452]); + assign q[453] = (!a[453])^(!b[453]); + assign q[454] = (((a[454])|(!b[454]))|(c[454]))^(d[454]); + assign q[455] = ((!a[455])&(b[455]))^((!c[455])|(!d[455])); + assign q[456] = (((a[456])^(!b[456]))|((c[456])^(d[456])))^(e[456]); + assign q[457] = (((a[457])&(!b[457]))^(c[457]))|(d[457]); + assign q[458] = (((!a[458])^(b[458]))^(c[458]))&(!d[458]); + assign q[459] = (((!a[459])&(b[459]))^((!c[459])&(!d[459])))&(e[459]); + assign q[460] = ((!a[460])^(!b[460]))|((c[460])&(!d[460])); + assign q[461] = ((a[461])&(!b[461]))&(c[461]); + assign q[462] = (((a[462])|(b[462]))^((c[462])^(d[462])))|(!e[462]); + assign q[463] = (((a[463])|(!b[463]))&((!c[463])|(d[463])))|(e[463]); + assign q[464] = (((!a[464])^(b[464]))&((!c[464])|(!d[464])))^(e[464]); + assign q[465] = ((!a[465])|(b[465]))&((c[465])&(d[465])); + assign q[466] = (((!a[466])^(b[466]))|((!c[466])&(d[466])))&(e[466]); + assign q[467] = (((!a[467])|(!b[467]))&((!c[467])&(!d[467])))^(!e[467]); + assign q[468] = ((!a[468])^(!b[468]))&((c[468])&(!d[468])); + assign q[469] = (((a[469])^(b[469]))^(c[469]))&(!d[469]); + assign q[470] = (((a[470])&(b[470]))^(c[470]))&(d[470]); + assign q[471] = (((!a[471])&(b[471]))^(c[471]))&(!d[471]); + assign q[472] = (((!a[472])|(b[472]))|((!c[472])|(!d[472])))|(!e[472]); + assign q[473] = (((a[473])|(b[473]))|((c[473])^(d[473])))|(e[473]); + assign q[474] = (a[474])^(!b[474]); + assign q[475] = (a[475])&(!b[475]); + assign q[476] = (((a[476])^(!b[476]))&((c[476])&(d[476])))|(!e[476]); + assign q[477] = ((a[477])^(b[477]))&(!c[477]); + assign q[478] = (((a[478])|(!b[478]))&((c[478])^(d[478])))|(e[478]); + assign q[479] = (((a[479])|(!b[479]))&((c[479])&(!d[479])))|(!e[479]); + assign q[480] = (((!a[480])|(b[480]))&((!c[480])|(!d[480])))|(e[480]); + assign q[481] = (((!a[481])&(b[481]))|((!c[481])^(d[481])))&(!e[481]); + assign q[482] = (a[482])^(!b[482]); + assign q[483] = (a[483])|(b[483]); + assign q[484] = (((a[484])|(!b[484]))&(c[484]))|(!d[484]); + assign q[485] = (((a[485])^(!b[485]))&(c[485]))|(!d[485]); + assign q[486] = ((!a[486])^(b[486]))&(c[486]); + assign q[487] = ((!a[487])&(b[487]))^((!c[487])^(!d[487])); + assign q[488] = ((a[488])&(b[488]))^((c[488])^(d[488])); + assign q[489] = (a[489])^(!b[489]); + assign q[490] = (((!a[490])^(b[490]))&(!c[490]))|(!d[490]); + assign q[491] = (a[491])^(!b[491]); + assign q[492] = (!a[492])|(!b[492]); + assign q[493] = (((!a[493])|(!b[493]))|((c[493])^(d[493])))^(e[493]); + assign q[494] = (((a[494])&(b[494]))^((c[494])&(!d[494])))&(e[494]); + assign q[495] = (((a[495])|(!b[495]))|((!c[495])^(d[495])))^(!e[495]); + assign q[496] = (((a[496])^(b[496]))&((!c[496])^(!d[496])))&(!e[496]); + assign q[497] = (((a[497])^(!b[497]))|((!c[497])&(d[497])))|(e[497]); + assign q[498] = (((!a[498])|(!b[498]))&(c[498]))&(!d[498]); + assign q[499] = (((a[499])|(b[499]))^((c[499])^(!d[499])))|(!e[499]); + assign q[500] = ((a[500])&(b[500]))^((!c[500])^(!d[500])); + assign q[501] = (((a[501])&(!b[501]))|(!c[501]))|(!d[501]); + assign q[502] = (((a[502])^(!b[502]))^(!c[502]))|(!d[502]); + assign q[503] = (((!a[503])&(b[503]))|(!c[503]))^(!d[503]); + assign q[504] = (((a[504])&(b[504]))|(c[504]))|(d[504]); + assign q[505] = (((!a[505])&(b[505]))&((c[505])&(!d[505])))^(!e[505]); + assign q[506] = (((!a[506])|(b[506]))|(c[506]))&(!d[506]); + assign q[507] = (((!a[507])^(b[507]))^(c[507]))&(d[507]); + assign q[508] = (((!a[508])&(b[508]))|((!c[508])|(d[508])))|(!e[508]); + assign q[509] = (!a[509])|(b[509]); + assign q[510] = (((a[510])|(!b[510]))^(c[510]))^(d[510]); + assign q[511] = ((!a[511])|(!b[511]))|((c[511])|(d[511])); + assign q[512] = ((a[512])|(!b[512]))&((!c[512])&(d[512])); + assign q[513] = (!a[513])&(!b[513]); + assign q[514] = (((a[514])|(!b[514]))^(!c[514]))&(d[514]); + assign q[515] = (((!a[515])|(!b[515]))^(c[515]))|(!d[515]); + assign q[516] = ((a[516])|(b[516]))|((c[516])&(!d[516])); + assign q[517] = (((a[517])^(!b[517]))^((c[517])&(!d[517])))&(e[517]); + assign q[518] = (((a[518])&(!b[518]))^((c[518])|(!d[518])))^(!e[518]); + assign q[519] = (((!a[519])^(!b[519]))&((c[519])&(d[519])))|(e[519]); + assign q[520] = ((a[520])^(b[520]))|((c[520])&(!d[520])); + assign q[521] = (((!a[521])^(!b[521]))^((!c[521])|(!d[521])))|(e[521]); + assign q[522] = (((a[522])|(b[522]))|(c[522]))&(!d[522]); + assign q[523] = (((a[523])|(b[523]))^((c[523])|(!d[523])))|(e[523]); + assign q[524] = ((!a[524])^(b[524]))&(c[524]); + assign q[525] = (a[525])&(b[525]); + assign q[526] = ((a[526])|(!b[526]))^((!c[526])^(!d[526])); + assign q[527] = ((!a[527])&(!b[527]))&((!c[527])|(!d[527])); + assign q[528] = ((a[528])^(b[528]))&(!c[528]); + assign q[529] = ((a[529])^(b[529]))|((c[529])|(!d[529])); + assign q[530] = ((!a[530])&(b[530]))|((c[530])&(!d[530])); + assign q[531] = (a[531])|(b[531]); + assign q[532] = (((!a[532])|(b[532]))&(c[532]))|(d[532]); + assign q[533] = ((a[533])&(!b[533]))&((c[533])&(!d[533])); + assign q[534] = (((a[534])&(!b[534]))&(!c[534]))|(d[534]); + assign q[535] = ((!a[535])^(b[535]))|((c[535])&(!d[535])); + assign q[536] = (((a[536])&(!b[536]))|((c[536])|(!d[536])))|(!e[536]); + assign q[537] = ((!a[537])^(b[537]))^((c[537])&(!d[537])); + assign q[538] = (((!a[538])&(b[538]))&(c[538]))|(d[538]); + assign q[539] = (a[539])|(!b[539]); + assign q[540] = (((!a[540])|(!b[540]))^((!c[540])|(d[540])))&(!e[540]); + assign q[541] = ((!a[541])&(!b[541]))&((c[541])^(d[541])); + assign q[542] = (((a[542])|(!b[542]))^(!c[542]))&(d[542]); + assign q[543] = (((!a[543])&(b[543]))&(!c[543]))^(d[543]); + assign q[544] = (((!a[544])|(b[544]))&((!c[544])&(d[544])))&(e[544]); + assign q[545] = (((a[545])^(!b[545]))|(!c[545]))&(d[545]); + assign q[546] = (((!a[546])|(!b[546]))^((!c[546])|(d[546])))&(!e[546]); + assign q[547] = (((a[547])^(!b[547]))|(c[547]))|(!d[547]); + assign q[548] = (((!a[548])^(b[548]))&((c[548])|(!d[548])))&(!e[548]); + assign q[549] = ((a[549])|(!b[549]))^((!c[549])^(d[549])); + assign q[550] = ((!a[550])&(!b[550]))^(c[550]); + assign q[551] = (((!a[551])&(b[551]))|((c[551])&(!d[551])))&(!e[551]); + assign q[552] = (((a[552])|(b[552]))^((!c[552])|(!d[552])))&(!e[552]); + assign q[553] = (((a[553])|(b[553]))|((!c[553])|(d[553])))&(e[553]); + assign q[554] = (((a[554])&(!b[554]))^(!c[554]))^(d[554]); + assign q[555] = ((!a[555])^(b[555]))|(!c[555]); + assign q[556] = (((!a[556])^(!b[556]))^(!c[556]))|(d[556]); + assign q[557] = ((a[557])&(!b[557]))|((c[557])&(d[557])); + assign q[558] = (((a[558])&(!b[558]))^((!c[558])^(!d[558])))^(!e[558]); + assign q[559] = (((!a[559])|(!b[559]))|((!c[559])|(!d[559])))^(!e[559]); + assign q[560] = ((!a[560])|(!b[560]))|((!c[560])^(d[560])); + assign q[561] = (((!a[561])|(b[561]))|(c[561]))^(!d[561]); + assign q[562] = ((!a[562])&(!b[562]))&((!c[562])^(!d[562])); + assign q[563] = (((a[563])^(b[563]))^(!c[563]))|(d[563]); + assign q[564] = (((!a[564])|(b[564]))|(!c[564]))|(d[564]); + assign q[565] = (((a[565])&(!b[565]))&((c[565])|(d[565])))|(!e[565]); + assign q[566] = (((a[566])&(b[566]))^(!c[566]))|(!d[566]); + assign q[567] = (((!a[567])&(!b[567]))&((c[567])&(!d[567])))|(!e[567]); + assign q[568] = (((!a[568])|(!b[568]))|(!c[568]))&(!d[568]); + assign q[569] = (!a[569])&(b[569]); + assign q[570] = ((!a[570])|(b[570]))|((!c[570])|(!d[570])); + assign q[571] = (((a[571])|(b[571]))&((!c[571])|(!d[571])))&(!e[571]); + assign q[572] = ((!a[572])&(b[572]))|((c[572])|(!d[572])); + assign q[573] = ((a[573])^(!b[573]))|((!c[573])|(!d[573])); + assign q[574] = (((!a[574])|(b[574]))&((!c[574])&(!d[574])))&(!e[574]); + assign q[575] = (((!a[575])&(b[575]))&((!c[575])|(!d[575])))|(!e[575]); + assign q[576] = (((a[576])|(!b[576]))^((c[576])^(d[576])))|(e[576]); + assign q[577] = (((a[577])|(b[577]))&(c[577]))^(d[577]); + assign q[578] = ((a[578])^(!b[578]))&(!c[578]); + assign q[579] = (((!a[579])&(!b[579]))^((!c[579])|(!d[579])))|(!e[579]); + assign q[580] = (((!a[580])|(b[580]))|(!c[580]))^(d[580]); + assign q[581] = ((a[581])&(b[581]))&((!c[581])|(d[581])); + assign q[582] = (((!a[582])^(b[582]))|(!c[582]))&(!d[582]); + assign q[583] = (a[583])&(b[583]); + assign q[584] = (((!a[584])|(b[584]))|((c[584])^(d[584])))^(e[584]); + assign q[585] = ((a[585])&(b[585]))|((!c[585])|(!d[585])); + assign q[586] = (((a[586])|(b[586]))^((!c[586])|(d[586])))^(!e[586]); + assign q[587] = ((a[587])|(!b[587]))&(!c[587]); + assign q[588] = (((!a[588])&(b[588]))^((!c[588])|(!d[588])))|(!e[588]); + assign q[589] = (((!a[589])|(b[589]))&((!c[589])|(d[589])))&(e[589]); + assign q[590] = (((a[590])^(b[590]))^((!c[590])&(d[590])))&(!e[590]); + assign q[591] = ((a[591])^(!b[591]))|(!c[591]); + assign q[592] = ((a[592])|(!b[592]))^((!c[592])^(!d[592])); + assign q[593] = ((!a[593])|(b[593]))&((c[593])&(!d[593])); + assign q[594] = ((!a[594])&(!b[594]))^(!c[594]); + assign q[595] = (((!a[595])^(b[595]))|(!c[595]))&(d[595]); + assign q[596] = (((a[596])|(!b[596]))&(!c[596]))|(!d[596]); + assign q[597] = (a[597])&(!b[597]); + assign q[598] = ((a[598])^(b[598]))|((!c[598])&(d[598])); + assign q[599] = ((a[599])&(b[599]))&(!c[599]); + assign q[600] = ((!a[600])|(b[600]))|((!c[600])^(!d[600])); + assign q[601] = ((a[601])&(!b[601]))|((c[601])^(!d[601])); + assign q[602] = ((!a[602])&(!b[602]))^(!c[602]); + assign q[603] = ((a[603])&(!b[603]))^((c[603])&(!d[603])); + assign q[604] = ((a[604])&(!b[604]))&((c[604])^(!d[604])); + assign q[605] = (((!a[605])|(b[605]))&((c[605])|(d[605])))|(e[605]); + assign q[606] = (((a[606])|(!b[606]))|((!c[606])^(d[606])))&(e[606]); + assign q[607] = ((a[607])&(!b[607]))^(!c[607]); + assign q[608] = ((a[608])^(!b[608]))&(!c[608]); + assign q[609] = ((a[609])^(!b[609]))&((!c[609])&(d[609])); + assign q[610] = ((!a[610])&(!b[610]))&(c[610]); + assign q[611] = (((!a[611])|(b[611]))&(!c[611]))|(!d[611]); + assign q[612] = (((a[612])^(!b[612]))&((!c[612])|(d[612])))^(e[612]); + assign q[613] = (((!a[613])|(b[613]))^((c[613])&(!d[613])))|(!e[613]); + assign q[614] = (a[614])^(!b[614]); + assign q[615] = (((!a[615])^(b[615]))|(!c[615]))^(d[615]); + assign q[616] = ((!a[616])&(!b[616]))|((c[616])&(!d[616])); + assign q[617] = (((a[617])^(b[617]))|(c[617]))|(d[617]); + assign q[618] = (((!a[618])^(!b[618]))^((c[618])^(d[618])))^(e[618]); + assign q[619] = (((!a[619])|(!b[619]))|(c[619]))^(!d[619]); + assign q[620] = (!a[620])^(!b[620]); + assign q[621] = ((!a[621])&(!b[621]))&((!c[621])|(d[621])); + assign q[622] = (((a[622])^(b[622]))&((!c[622])|(!d[622])))|(!e[622]); + assign q[623] = (((a[623])&(!b[623]))^(c[623]))&(d[623]); + assign q[624] = (((a[624])&(b[624]))|(c[624]))^(!d[624]); + assign q[625] = (((!a[625])^(!b[625]))&((!c[625])|(d[625])))&(!e[625]); + assign q[626] = (((!a[626])&(!b[626]))^(!c[626]))|(!d[626]); + assign q[627] = ((!a[627])|(b[627]))|(c[627]); + assign q[628] = (((!a[628])&(!b[628]))^((!c[628])|(!d[628])))^(e[628]); + assign q[629] = ((a[629])&(!b[629]))|((c[629])^(d[629])); + assign q[630] = (((!a[630])|(b[630]))^((c[630])|(!d[630])))|(!e[630]); + assign q[631] = (((!a[631])&(b[631]))&(!c[631]))^(!d[631]); + assign q[632] = (((a[632])&(!b[632]))&(!c[632]))|(!d[632]); + assign q[633] = (((a[633])|(b[633]))^(c[633]))|(d[633]); + assign q[634] = (((a[634])&(b[634]))|((c[634])|(d[634])))&(e[634]); + assign q[635] = (((a[635])&(!b[635]))&((c[635])&(!d[635])))&(!e[635]); + assign q[636] = (((!a[636])|(b[636]))^((!c[636])^(d[636])))^(e[636]); + assign q[637] = (((a[637])&(b[637]))&((!c[637])&(d[637])))|(!e[637]); + assign q[638] = ((!a[638])|(!b[638]))&(!c[638]); + assign q[639] = (((a[639])|(!b[639]))&((c[639])|(d[639])))^(!e[639]); + assign q[640] = (!a[640])&(b[640]); + assign q[641] = ((!a[641])^(!b[641]))^((!c[641])^(d[641])); + assign q[642] = (((!a[642])^(!b[642]))&(c[642]))&(!d[642]); + assign q[643] = (!a[643])^(!b[643]); + assign q[644] = ((!a[644])|(!b[644]))|((!c[644])^(!d[644])); + assign q[645] = (((a[645])&(b[645]))^((c[645])&(!d[645])))|(e[645]); + assign q[646] = ((a[646])&(!b[646]))&(c[646]); + assign q[647] = ((a[647])&(!b[647]))^((!c[647])^(!d[647])); + assign q[648] = (((!a[648])|(b[648]))&((!c[648])&(d[648])))|(e[648]); + assign q[649] = ((!a[649])|(b[649]))|((c[649])&(!d[649])); + assign q[650] = (((!a[650])&(b[650]))^(c[650]))^(d[650]); + assign q[651] = ((a[651])|(b[651]))^(!c[651]); + assign q[652] = (((a[652])^(b[652]))&((c[652])|(d[652])))|(e[652]); + assign q[653] = (((!a[653])|(b[653]))^(c[653]))^(d[653]); + assign q[654] = (((a[654])^(!b[654]))^(!c[654]))^(d[654]); + assign q[655] = (((!a[655])|(b[655]))|((!c[655])&(d[655])))&(e[655]); + assign q[656] = (((a[656])^(b[656]))|((!c[656])^(!d[656])))^(!e[656]); + assign q[657] = ((a[657])&(!b[657]))&(c[657]); + assign q[658] = (((!a[658])|(b[658]))|((!c[658])^(!d[658])))|(e[658]); + assign q[659] = (((a[659])&(b[659]))&((c[659])|(!d[659])))^(e[659]); + assign q[660] = (((!a[660])&(!b[660]))|((!c[660])|(!d[660])))&(e[660]); + assign q[661] = ((a[661])&(!b[661]))^((!c[661])^(!d[661])); + assign q[662] = (((!a[662])|(!b[662]))|((c[662])|(!d[662])))^(!e[662]); + assign q[663] = (a[663])^(b[663]); + assign q[664] = ((!a[664])&(!b[664]))|((!c[664])&(!d[664])); + assign q[665] = (((a[665])|(b[665]))&((!c[665])&(!d[665])))^(e[665]); + assign q[666] = (((a[666])&(b[666]))|((c[666])|(d[666])))|(!e[666]); + assign q[667] = ((a[667])&(!b[667]))&(!c[667]); + assign q[668] = (((!a[668])&(b[668]))^(c[668]))|(d[668]); + assign q[669] = (((!a[669])^(b[669]))^((!c[669])^(!d[669])))&(e[669]); + assign q[670] = ((!a[670])|(b[670]))&((c[670])|(!d[670])); + assign q[671] = (((a[671])&(!b[671]))^(c[671]))^(!d[671]); + assign q[672] = (((a[672])^(b[672]))^((c[672])&(!d[672])))|(!e[672]); + assign q[673] = (((a[673])^(!b[673]))&((c[673])|(d[673])))|(!e[673]); + assign q[674] = ((!a[674])|(!b[674]))|((!c[674])^(d[674])); + assign q[675] = ((!a[675])^(b[675]))&((!c[675])|(!d[675])); + assign q[676] = (((!a[676])&(!b[676]))^((!c[676])&(d[676])))|(!e[676]); + assign q[677] = (((!a[677])&(!b[677]))^(c[677]))&(!d[677]); + assign q[678] = (((!a[678])|(!b[678]))&((c[678])^(!d[678])))&(e[678]); + assign q[679] = (!a[679])|(b[679]); + assign q[680] = (a[680])&(!b[680]); + assign q[681] = (((!a[681])|(b[681]))|((c[681])&(d[681])))|(!e[681]); + assign q[682] = ((a[682])&(!b[682]))^((!c[682])|(!d[682])); + assign q[683] = ((!a[683])&(!b[683]))|((!c[683])^(!d[683])); + assign q[684] = (!a[684])&(!b[684]); + assign q[685] = (((a[685])&(!b[685]))|((c[685])&(!d[685])))|(!e[685]); + assign q[686] = (a[686])^(!b[686]); + assign q[687] = (((!a[687])|(b[687]))&((!c[687])|(d[687])))^(e[687]); + assign q[688] = (((a[688])^(!b[688]))^((!c[688])&(!d[688])))&(!e[688]); + assign q[689] = (((!a[689])^(b[689]))^(c[689]))&(!d[689]); + assign q[690] = ((a[690])^(!b[690]))|((!c[690])|(!d[690])); + assign q[691] = (((!a[691])^(b[691]))&((!c[691])&(!d[691])))^(!e[691]); + assign q[692] = ((a[692])^(!b[692]))|((c[692])|(!d[692])); + assign q[693] = (((a[693])&(b[693]))&((!c[693])|(d[693])))^(e[693]); + assign q[694] = ((!a[694])^(!b[694]))^((c[694])^(!d[694])); + assign q[695] = ((a[695])&(b[695]))&((!c[695])|(!d[695])); + assign q[696] = ((a[696])|(b[696]))&((c[696])|(d[696])); + assign q[697] = (((!a[697])^(b[697]))|((c[697])^(!d[697])))|(e[697]); + assign q[698] = (((a[698])|(b[698]))|((!c[698])&(!d[698])))^(!e[698]); + assign q[699] = (((!a[699])|(!b[699]))&(c[699]))|(!d[699]); + assign q[700] = ((!a[700])&(b[700]))|((!c[700])|(d[700])); + assign q[701] = (((!a[701])|(b[701]))|((c[701])^(d[701])))&(e[701]); + assign q[702] = (((!a[702])&(b[702]))&(c[702]))&(!d[702]); + assign q[703] = ((!a[703])&(!b[703]))|((c[703])|(d[703])); + assign q[704] = (((a[704])^(b[704]))^((c[704])&(d[704])))|(!e[704]); + assign q[705] = ((a[705])^(!b[705]))^((!c[705])^(!d[705])); + assign q[706] = (((!a[706])^(b[706]))^((!c[706])&(!d[706])))&(e[706]); + assign q[707] = ((a[707])&(!b[707]))|((c[707])^(d[707])); + assign q[708] = (((a[708])^(b[708]))|(!c[708]))|(d[708]); + assign q[709] = (((!a[709])&(b[709]))^((!c[709])&(!d[709])))&(!e[709]); + assign q[710] = ((!a[710])^(!b[710]))^(c[710]); + assign q[711] = (!a[711])&(b[711]); + assign q[712] = ((a[712])^(b[712]))&((c[712])^(!d[712])); + assign q[713] = (((a[713])^(b[713]))|((!c[713])^(d[713])))|(!e[713]); + assign q[714] = (((a[714])|(b[714]))&((c[714])^(d[714])))^(!e[714]); + assign q[715] = ((a[715])|(b[715]))|((!c[715])^(d[715])); + assign q[716] = (((a[716])|(b[716]))^(c[716]))^(!d[716]); + assign q[717] = (((!a[717])|(!b[717]))^((!c[717])^(!d[717])))^(e[717]); + assign q[718] = (((a[718])^(!b[718]))&(!c[718]))^(d[718]); + assign q[719] = (((!a[719])^(!b[719]))&((!c[719])|(d[719])))&(!e[719]); + assign q[720] = ((!a[720])^(b[720]))|(c[720]); + assign q[721] = ((!a[721])&(!b[721]))|((c[721])&(d[721])); + assign q[722] = (((!a[722])|(!b[722]))&((!c[722])&(!d[722])))&(!e[722]); + assign q[723] = ((a[723])|(b[723]))&((c[723])|(d[723])); + assign q[724] = (((!a[724])|(b[724]))^((c[724])^(!d[724])))^(e[724]); + assign q[725] = (((!a[725])^(!b[725]))|(!c[725]))&(!d[725]); + assign q[726] = ((a[726])^(!b[726]))^(c[726]); + assign q[727] = ((!a[727])&(!b[727]))^(c[727]); + assign q[728] = ((!a[728])^(!b[728]))^(c[728]); + assign q[729] = ((!a[729])&(b[729]))&(!c[729]); + assign q[730] = (((a[730])|(!b[730]))&(!c[730]))&(!d[730]); + assign q[731] = ((!a[731])|(!b[731]))^(c[731]); + assign q[732] = ((!a[732])&(!b[732]))|(c[732]); + assign q[733] = ((!a[733])&(!b[733]))^(!c[733]); + assign q[734] = (((a[734])|(b[734]))|((!c[734])^(!d[734])))|(!e[734]); + assign q[735] = (a[735])^(b[735]); + assign q[736] = ((!a[736])|(b[736]))&(!c[736]); + assign q[737] = (((!a[737])|(b[737]))|(c[737]))&(!d[737]); + assign q[738] = (((a[738])^(b[738]))^((c[738])^(!d[738])))|(e[738]); + assign q[739] = (!a[739])^(b[739]); + assign q[740] = (((a[740])|(b[740]))^((!c[740])^(!d[740])))&(!e[740]); + assign q[741] = ((!a[741])&(b[741]))^((!c[741])^(!d[741])); + assign q[742] = (((a[742])|(b[742]))|(c[742]))|(d[742]); + assign q[743] = (((a[743])&(b[743]))&((c[743])&(d[743])))|(!e[743]); + assign q[744] = (((!a[744])&(!b[744]))^((!c[744])&(d[744])))^(e[744]); + assign q[745] = (((!a[745])&(b[745]))^((!c[745])|(!d[745])))^(e[745]); + assign q[746] = (((a[746])&(b[746]))^(!c[746]))&(!d[746]); + assign q[747] = (((!a[747])^(b[747]))^((!c[747])^(d[747])))|(e[747]); + assign q[748] = (((a[748])^(b[748]))|((c[748])^(d[748])))&(!e[748]); + assign q[749] = (((a[749])^(b[749]))|((c[749])|(!d[749])))|(e[749]); +endmodule diff --git a/tests/arch/gatemate/luttrees.ys b/tests/arch/gatemate/luttrees.ys new file mode 100644 index 000000000..545643226 --- /dev/null +++ b/tests/arch/gatemate/luttrees.ys @@ -0,0 +1,13 @@ + +read_verilog luttrees.v +design -save read + +hierarchy -top luttrees +proc +equiv_opt -async2sync -assert -map +/gatemate/cells_sim.v synth_gatemate -noiopad -luttree -nomx4 -nomx8 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd luttrees # Constrain all select calls below inside the top module + +select -assert-count 750 t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% +select -assert-none t:CC_LUT2 t:CC_L2T4 t:CC_L2T5 %% t:* %D + |