diff options
510 files changed, 35310 insertions, 12118 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..f85ae06c9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.v linguist-language=Verilog @@ -39,7 +39,7 @@ Yosys 0.9 .. Yosys 0.9-dev - Improvements in pmgen: slices, choices, define, generate - Added "xilinx_srl" for Xilinx shift register extraction - Removed "shregmap -tech xilinx" (superseded by "xilinx_srl") - - Added "_TECHMAP_WIREINIT_*_" attribute and "_TECHMAP_REMOVEINIT_*_" wire for "techmap" pass + - Added "_TECHMAP_WIREINIT_*_" parameter and "_TECHMAP_REMOVEINIT_*_" wire for "techmap" pass - Added "-match-init" option to "dff2dffs" pass - Added "techmap_autopurge" support to techmap - Added "add -mod <modname[s]>" @@ -62,11 +62,14 @@ Yosys 0.9 .. Yosys 0.9-dev - Improved support of $readmem[hb] Memory Content File inclusion - Added "opt_lut_ins" pass - Added "logger" pass - - Removed "dffsr2dff" (use opt_rmdff instead) - Added "design -delete" - Added "select -unset" - Use YosysHQ/abc instead of upstream berkeley-abc/abc - Added $divfloor and $modfloor cells + - Added $adffe, $dffsre, $sdff, $sdffe, $sdffce, $adlatch cells + - Added "dfflegalize" pass + - Added "_TECHMAP_CELLNAME_" parameter for "techmap" pass + - Merged "dffsr2dff", "opt_rmdff", "dff2dffe", "dff2dffs", "peepopt.dffmux" passes into a new "opt_dff" pass Yosys 0.8 .. Yosys 0.9 ---------------------- diff --git a/CODEOWNERS b/CODEOWNERS index a73779920..350a62120 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -33,5 +33,6 @@ misc/*.py @btut backends/firrtl @ucbjrl @azidar passes/sat/qbfsat.cc @boqwxp +passes/sat/qbfsat.h @boqwxp passes/cmds/exec.cc @boqwxp passes/cmds/printattrs.cc @boqwxp @@ -30,6 +30,9 @@ ENABLE_GCOV := 0 ENABLE_GPROF := 0 ENABLE_DEBUG := 0 ENABLE_NDEBUG := 0 +ENABLE_CCACHE := 0 +# sccache is not always a drop-in replacement for ccache in practice +ENABLE_SCCACHE := 0 LINK_CURSES := 0 LINK_TERMCAP := 0 LINK_ABC := 0 @@ -81,7 +84,7 @@ all: top-all YOSYS_SRC := $(dir $(firstword $(MAKEFILE_LIST))) VPATH := $(YOSYS_SRC) -CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -D_YOSYS_ -fPIC -I$(PREFIX)/include +CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include LDLIBS := $(LDLIBS) -lstdc++ -lm PLUGIN_LDFLAGS := @@ -122,7 +125,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+2406 +YOSYS_VER := 0.9+3696 GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o @@ -135,7 +138,7 @@ 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 = fd2c9b1 +ABCREV = 4f5f73d ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 @@ -170,8 +173,7 @@ else PYTHON_CONFIG := $(PYTHON_EXECUTABLE)-config endif -PYTHON_PREFIX := $(shell $(PYTHON_CONFIG) --prefix) -PYTHON_DESTDIR := $(PYTHON_PREFIX)/lib/python$(PYTHON_VERSION)/site-packages +PYTHON_DESTDIR := $(shell $(PYTHON_EXECUTABLE) -c "import site; print(site.getsitepackages()[-1]);") # Reload Makefile.conf to override python specific variables if defined ifneq ($(wildcard Makefile.conf),) @@ -246,7 +248,7 @@ CXXFLAGS := -std=c++11 $(filter-out -fPIC -ggdb,$(CXXFLAGS)) ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8" EMCCFLAGS := -Os -Wno-warn-absolute-paths EMCCFLAGS += --memory-init-file 0 --embed-file share -s NO_EXIT_RUNTIME=1 -EMCCFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg']" +EMCCFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg','_memset']" EMCCFLAGS += -s TOTAL_MEMORY=134217728 EMCCFLAGS += -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' # https://github.com/kripken/emscripten/blob/master/src/settings.js @@ -528,6 +530,14 @@ ifeq ($(ENABLE_COVER),1) CXXFLAGS += -DYOSYS_ENABLE_COVER endif +ifeq ($(ENABLE_CCACHE),1) +CXX := ccache $(CXX) +else +ifeq ($(ENABLE_SCCACHE),1) +CXX := sccache $(CXX) +endif +endif + define add_share_file EXTRA_TARGETS += $(subst //,/,$(1)/$(notdir $(2))) $(subst //,/,$(1)/$(notdir $(2))): $(2) @@ -580,13 +590,16 @@ $(eval $(call add_include_file,kernel/modtools.h)) $(eval $(call add_include_file,kernel/macc.h)) $(eval $(call add_include_file,kernel/utils.h)) $(eval $(call add_include_file,kernel/satgen.h)) +$(eval $(call add_include_file,kernel/ff.h)) +$(eval $(call add_include_file,kernel/ffinit.h)) +$(eval $(call add_include_file,kernel/mem.h)) $(eval $(call add_include_file,libs/ezsat/ezsat.h)) $(eval $(call add_include_file,libs/ezsat/ezminisat.h)) $(eval $(call add_include_file,libs/sha1/sha1.h)) $(eval $(call add_include_file,libs/json11/json11.hpp)) $(eval $(call add_include_file,passes/fsm/fsmdata.h)) $(eval $(call add_include_file,frontends/ast/ast.h)) -$(eval $(call add_include_file,backends/ilang/ilang_backend.h)) +$(eval $(call add_include_file,backends/rtlil/rtlil_backend.h)) $(eval $(call add_include_file,backends/cxxrtl/cxxrtl.h)) $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd.h)) $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_capi.cc)) @@ -595,7 +608,7 @@ $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd_capi.cc)) $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd_capi.h)) OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o -OBJS += kernel/cellaigs.o kernel/celledges.o +OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/mem.o kernel/log.o: CXXFLAGS += -DYOSYS_SRC='"$(YOSYS_SRC)"' kernel/yosys.o: CXXFLAGS += -DYOSYS_DATDIR='"$(DATDIR)"' -DYOSYS_PROGRAM_PREFIX='"$(PROGRAM_PREFIX)"' @@ -627,7 +640,7 @@ include $(YOSYS_SRC)/techlibs/*/Makefile.inc else include $(YOSYS_SRC)/frontends/verilog/Makefile.inc -include $(YOSYS_SRC)/frontends/ilang/Makefile.inc +include $(YOSYS_SRC)/frontends/rtlil/Makefile.inc include $(YOSYS_SRC)/frontends/ast/Makefile.inc include $(YOSYS_SRC)/frontends/blif/Makefile.inc @@ -644,7 +657,7 @@ include $(YOSYS_SRC)/passes/opt/Makefile.inc include $(YOSYS_SRC)/passes/techmap/Makefile.inc include $(YOSYS_SRC)/backends/verilog/Makefile.inc -include $(YOSYS_SRC)/backends/ilang/Makefile.inc +include $(YOSYS_SRC)/backends/rtlil/Makefile.inc include $(YOSYS_SRC)/techlibs/common/Makefile.inc @@ -654,6 +667,10 @@ ifeq ($(LINK_ABC),1) OBJS += $(PROGRAM_PREFIX)yosys-libabc.a endif +# prevent the CXXFLAGS set by this Makefile from reaching abc/Makefile, +# especially the -MD flag which will break the build when CXX is clang +unexport CXXFLAGS + top-all: $(TARGETS) $(EXTRA_TARGETS) @echo "" @echo " Build successful." @@ -679,7 +696,7 @@ endif %.pyh: %.h $(Q) mkdir -p $(dir $@) - $(P) cat $< | grep -E -v "#[ ]*(include|error)" | $(LD) -x c++ -o $@ -E -P - + $(P) cat $< | grep -E -v "#[ ]*(include|error)" | $(LD) $(CXXFLAGS) -x c++ -o $@ -E -P - ifeq ($(ENABLE_PYOSYS),1) $(PY_WRAPPER_FILE).cc: misc/$(PY_GEN_SCRIPT).py $(PY_WRAP_INCLUDES) @@ -783,6 +800,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/arch/anlogic && bash run-test.sh $(SEEDOPT) +cd tests/arch/gowin && bash run-test.sh $(SEEDOPT) +cd tests/arch/intel_alm && bash run-test.sh $(SEEDOPT) + +cd tests/arch/nexus && bash run-test.sh $(SEEDOPT) +cd tests/rpc && bash run-test.sh +cd tests/memfile && bash run-test.sh +cd tests/verilog && bash run-test.sh @@ -839,9 +857,9 @@ ifeq ($(ENABLE_LIBYOSYS),1) $(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(LIBDIR)/ $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(LIBDIR)/libyosys.so ifeq ($(ENABLE_PYOSYS),1) - $(INSTALL_SUDO) mkdir -p $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys - $(INSTALL_SUDO) cp libyosys.so $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so - $(INSTALL_SUDO) cp misc/__init__.py $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/ + $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys + $(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so + $(INSTALL_SUDO) cp misc/__init__.py $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/ endif endif @@ -851,9 +869,9 @@ uninstall: ifeq ($(ENABLE_LIBYOSYS),1) $(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.so ifeq ($(ENABLE_PYOSYS),1) - $(INSTALL_SUDO) rm -vf $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so - $(INSTALL_SUDO) rm -vf $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/__init__.py - $(INSTALL_SUDO) rmdir $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys + $(INSTALL_SUDO) rm -vf $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so + $(INSTALL_SUDO) rm -vf $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/__init__.py + $(INSTALL_SUDO) rmdir $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys endif endif @@ -1007,4 +1025,3 @@ echo-abc-rev: .PHONY: all top-all abc test install install-abc manual clean mrproper qtcreator coverage vcxsrc mxebin .PHONY: config-clean config-clang config-gcc config-gcc-static config-gcc-4.8 config-afl-gcc config-gprof config-sudo - diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc index e5a41b5c5..476b30488 100644 --- a/backends/aiger/aiger.cc +++ b/backends/aiger/aiger.cc @@ -111,7 +111,7 @@ struct AigerWriter // promote public wires for (auto wire : module->wires()) - if (wire->name[0] == '\\') + if (wire->name.isPublic()) sigmap.add(wire); // promote input wires @@ -681,7 +681,7 @@ struct AigerWriter struct AigerBackend : public Backend { AigerBackend() : Backend("aiger", "write design to AIGER file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -719,7 +719,7 @@ struct AigerBackend : public Backend { log(" AIGER file happy.\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { bool ascii_mode = false; bool zinit_mode = false; diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8bbadbc91..27499b64a 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -146,7 +146,7 @@ struct XAigerWriter // promote public wires for (auto wire : module->wires()) - if (wire->name[0] == '\\') + if (wire->name.isPublic()) sigmap.add(wire); // promote input wires @@ -731,7 +731,7 @@ struct XAigerWriter struct XAigerBackend : public Backend { XAigerBackend() : Backend("xaiger", "write design to XAIGER file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -753,7 +753,7 @@ struct XAigerBackend : public Backend { log(" write $_DFF_[NP]_ cells\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { bool ascii_mode = false, dff_mode = false; std::string map_filename; diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index b028df848..088819042 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -86,20 +86,18 @@ struct BlifDumper } } - vector<shared_str> cstr_buf; pool<SigBit> cstr_bits_seen; - const char *cstr(RTLIL::IdString id) + const std::string str(RTLIL::IdString id) { std::string str = RTLIL::unescape_id(id); for (size_t i = 0; i < str.size(); i++) if (str[i] == '#' || str[i] == '=' || str[i] == '<' || str[i] == '>') str[i] = '?'; - cstr_buf.push_back(str); - return cstr_buf.back().c_str(); + return str; } - const char *cstr(RTLIL::SigBit sig) + const std::string str(RTLIL::SigBit sig) { cstr_bits_seen.insert(sig); @@ -117,11 +115,10 @@ struct BlifDumper if (sig.wire->width != 1) str += stringf("[%d]", sig.wire->upto ? sig.wire->start_offset+sig.wire->width-sig.offset-1 : sig.wire->start_offset+sig.offset); - cstr_buf.push_back(str); - return cstr_buf.back().c_str(); + return str; } - const char *cstr_init(RTLIL::SigBit sig) + const std::string str_init(RTLIL::SigBit sig) { sigmap.apply(sig); @@ -130,8 +127,7 @@ struct BlifDumper string str = stringf(" %d", init_bits.at(sig)); - cstr_buf.push_back(str); - return cstr_buf.back().c_str(); + return str; } const char *subckt_or_gate(std::string cell_type) @@ -168,7 +164,7 @@ struct BlifDumper void dump() { f << stringf("\n"); - f << stringf(".model %s\n", cstr(module->name)); + f << stringf(".model %s\n", str(module->name).c_str()); std::map<int, RTLIL::Wire*> inputs, outputs; @@ -183,7 +179,7 @@ struct BlifDumper for (auto &it : inputs) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) - f << stringf(" %s", cstr(RTLIL::SigSpec(wire, i))); + f << stringf(" %s", str(RTLIL::SigSpec(wire, i)).c_str()); } f << stringf("\n"); @@ -191,7 +187,7 @@ struct BlifDumper for (auto &it : outputs) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) - f << stringf(" %s", cstr(RTLIL::SigSpec(wire, i))); + f << stringf(" %s", str(RTLIL::SigSpec(wire, i)).c_str()); } f << stringf("\n"); @@ -233,131 +229,131 @@ struct BlifDumper if (config->unbuf_types.count(cell->type)) { auto portnames = config->unbuf_types.at(cell->type); f << stringf(".names %s %s\n1 1\n", - cstr(cell->getPort(portnames.first)), cstr(cell->getPort(portnames.second))); + str(cell->getPort(portnames.first)).c_str(), str(cell->getPort(portnames.second)).c_str()); continue; } if (!config->icells_mode && cell->type == ID($_NOT_)) { f << stringf(".names %s %s\n0 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_AND_)) { f << stringf(".names %s %s %s\n11 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_OR_)) { f << stringf(".names %s %s %s\n1- 1\n-1 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_XOR_)) { f << stringf(".names %s %s %s\n10 1\n01 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_NAND_)) { f << stringf(".names %s %s %s\n0- 1\n-0 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_NOR_)) { f << stringf(".names %s %s %s\n00 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_XNOR_)) { f << stringf(".names %s %s %s\n11 1\n00 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_ANDNOT_)) { f << stringf(".names %s %s %s\n10 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_ORNOT_)) { f << stringf(".names %s %s %s\n1- 1\n-0 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_AOI3_)) { f << stringf(".names %s %s %s %s\n-00 1\n0-0 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), str(cell->getPort(ID::C)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_OAI3_)) { f << stringf(".names %s %s %s %s\n00- 1\n--0 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), str(cell->getPort(ID::C)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_AOI4_)) { f << stringf(".names %s %s %s %s %s\n-0-0 1\n-00- 1\n0--0 1\n0-0- 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), - cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), + str(cell->getPort(ID::C)).c_str(), str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_OAI4_)) { f << stringf(".names %s %s %s %s %s\n00-- 1\n--00 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), - cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), + str(cell->getPort(ID::C)).c_str(), str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_MUX_)) { f << stringf(".names %s %s %s %s\n1-0 1\n-11 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), - cstr(cell->getPort(ID::S)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), + str(cell->getPort(ID::S)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_NMUX_)) { f << stringf(".names %s %s %s %s\n0-0 1\n-01 1\n", - cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), - cstr(cell->getPort(ID::S)), cstr(cell->getPort(ID::Y))); + str(cell->getPort(ID::A)).c_str(), str(cell->getPort(ID::B)).c_str(), + str(cell->getPort(ID::S)).c_str(), str(cell->getPort(ID::Y)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_FF_)) { - f << stringf(".latch %s %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)), - cstr_init(cell->getPort(ID::Q))); + f << stringf(".latch %s %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(), + str_init(cell->getPort(ID::Q)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_DFF_N_)) { - f << stringf(".latch %s %s fe %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)), - cstr(cell->getPort(ID::C)), cstr_init(cell->getPort(ID::Q))); + f << stringf(".latch %s %s fe %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(), + str(cell->getPort(ID::C)).c_str(), str_init(cell->getPort(ID::Q)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_DFF_P_)) { - f << stringf(".latch %s %s re %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)), - cstr(cell->getPort(ID::C)), cstr_init(cell->getPort(ID::Q))); + f << stringf(".latch %s %s re %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(), + str(cell->getPort(ID::C)).c_str(), str_init(cell->getPort(ID::Q)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_DLATCH_N_)) { - f << stringf(".latch %s %s al %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)), - cstr(cell->getPort(ID::E)), cstr_init(cell->getPort(ID::Q))); + f << stringf(".latch %s %s al %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(), + str(cell->getPort(ID::E)).c_str(), str_init(cell->getPort(ID::Q)).c_str()); goto internal_cell; } if (!config->icells_mode && cell->type == ID($_DLATCH_P_)) { - f << stringf(".latch %s %s ah %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)), - cstr(cell->getPort(ID::E)), cstr_init(cell->getPort(ID::Q))); + f << stringf(".latch %s %s ah %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(), + str(cell->getPort(ID::E)).c_str(), str_init(cell->getPort(ID::Q)).c_str()); goto internal_cell; } @@ -367,10 +363,10 @@ struct BlifDumper auto width = cell->parameters.at(ID::WIDTH).as_int(); log_assert(inputs.size() == width); for (int i = width-1; i >= 0; i--) - f << stringf(" %s", cstr(inputs.extract(i, 1))); + f << stringf(" %s", str(inputs.extract(i, 1)).c_str()); auto &output = cell->getPort(ID::Y); log_assert(output.size() == 1); - f << stringf(" %s", cstr(output)); + f << stringf(" %s", str(output).c_str()); f << stringf("\n"); RTLIL::SigSpec mask = cell->parameters.at(ID::LUT); for (int i = 0; i < (1 << width); i++) @@ -393,10 +389,10 @@ struct BlifDumper table.push_back(State::S0); log_assert(inputs.size() == width); for (int i = 0; i < width; i++) - f << stringf(" %s", cstr(inputs.extract(i, 1))); + f << stringf(" %s", str(inputs.extract(i, 1)).c_str()); auto &output = cell->getPort(ID::Y); log_assert(output.size() == 1); - f << stringf(" %s", cstr(output)); + f << stringf(" %s", str(output).c_str()); f << stringf("\n"); for (int i = 0; i < depth; i++) { for (int j = 0; j < width; j++) { @@ -411,11 +407,11 @@ struct BlifDumper goto internal_cell; } - f << stringf(".%s %s", subckt_or_gate(cell->type.str()), cstr(cell->type)); + f << stringf(".%s %s", subckt_or_gate(cell->type.str()), str(cell->type).c_str()); for (auto &conn : cell->connections()) { if (conn.second.size() == 1) { - f << stringf(" %s=%s", cstr(conn.first), cstr(conn.second[0])); + f << stringf(" %s=%s", str(conn.first).c_str(), str(conn.second[0]).c_str()); continue; } @@ -424,20 +420,20 @@ struct BlifDumper if (w == nullptr) { for (int i = 0; i < GetSize(conn.second); i++) - f << stringf(" %s[%d]=%s", cstr(conn.first), i, cstr(conn.second[i])); + f << stringf(" %s[%d]=%s", str(conn.first).c_str(), i, str(conn.second[i]).c_str()); } else { for (int i = 0; i < std::min(GetSize(conn.second), GetSize(w)); i++) { SigBit sig(w, i); - f << stringf(" %s[%d]=%s", cstr(conn.first), sig.wire->upto ? + f << stringf(" %s[%d]=%s", str(conn.first).c_str(), sig.wire->upto ? sig.wire->start_offset+sig.wire->width-sig.offset-1 : - sig.wire->start_offset+sig.offset, cstr(conn.second[i])); + sig.wire->start_offset+sig.offset, str(conn.second[i]).c_str()); } } } f << stringf("\n"); if (config->cname_mode) - f << stringf(".cname %s\n", cstr(cell->name)); + f << stringf(".cname %s\n", str(cell->name).c_str()); if (config->attr_mode) dump_params(".attr", cell->attributes); if (config->param_mode) @@ -446,7 +442,7 @@ struct BlifDumper if (0) { internal_cell: if (config->iname_mode) - f << stringf(".cname %s\n", cstr(cell->name)); + f << stringf(".cname %s\n", str(cell->name).c_str()); if (config->iattr_mode) dump_params(".attr", cell->attributes); } @@ -462,12 +458,12 @@ struct BlifDumper continue; if (config->conn_mode) - f << stringf(".conn %s %s\n", cstr(rhs_bit), cstr(lhs_bit)); + f << stringf(".conn %s %s\n", str(rhs_bit).c_str(), str(lhs_bit).c_str()); else if (!config->buf_type.empty()) f << stringf(".%s %s %s=%s %s=%s\n", subckt_or_gate(config->buf_type), config->buf_type.c_str(), - config->buf_in.c_str(), cstr(rhs_bit), config->buf_out.c_str(), cstr(lhs_bit)); + config->buf_in.c_str(), str(rhs_bit).c_str(), config->buf_out.c_str(), str(lhs_bit).c_str()); else - f << stringf(".names %s %s\n1 1\n", cstr(rhs_bit), cstr(lhs_bit)); + f << stringf(".names %s %s\n1 1\n", str(rhs_bit).c_str(), str(lhs_bit).c_str()); } f << stringf(".end\n"); @@ -482,7 +478,7 @@ struct BlifDumper struct BlifBackend : public Backend { BlifBackend() : Backend("blif", "write design to BLIF file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -552,7 +548,7 @@ struct BlifBackend : public Backend { log(" do not write definitions for the $true, $false and $undef wires.\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { std::string top_module_name; std::string buf_type, buf_in, buf_out; diff --git a/backends/btor/.gitignore b/backends/btor/.gitignore new file mode 100644 index 000000000..d23d492d7 --- /dev/null +++ b/backends/btor/.gitignore @@ -0,0 +1 @@ +/test_cells.tmp/ diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 9ac312480..639c6f129 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -27,6 +27,7 @@ #include "kernel/sigtools.h" #include "kernel/celltypes.h" #include "kernel/log.h" +#include "kernel/mem.h" #include <string> USING_YOSYS_NAMESPACE @@ -68,12 +69,15 @@ struct BtorWorker // ff inputs that need to be evaluated (<nid>, <ff_cell>) vector<pair<int, Cell*>> ff_todo; + vector<pair<int, Mem*>> mem_todo; pool<Cell*> cell_recursion_guard; vector<int> bad_properties; dict<SigBit, bool> initbits; pool<Wire*> statewires; pool<string> srcsymbols; + vector<Mem> memories; + dict<Cell*, Mem*> mem_cells; string indent, info_filename; vector<string> info_lines; @@ -205,9 +209,8 @@ struct BtorWorker if (cell->type.in(ID($xnor), ID($_XNOR_))) btor_op = "xnor"; log_assert(!btor_op.empty()); - int width = GetSize(cell->getPort(ID::Y)); - width = std::max(width, GetSize(cell->getPort(ID::A))); - width = std::max(width, GetSize(cell->getPort(ID::B))); + int width_ay = std::max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::Y))); + int width = std::max(width_ay, GetSize(cell->getPort(ID::B))); bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false; bool b_signed = cell->hasParam(ID::B_SIGNED) ? cell->getParam(ID::B_SIGNED).as_bool() : false; @@ -224,11 +227,23 @@ struct BtorWorker int sid = get_bv_sid(width); int nid; + int nid_a; + if (cell->type.in(ID($shl), ID($shr), ID($shift), ID($shiftx)) && a_signed && width_ay < width) { + // sign-extend A up to the width of Y + int nid_a_padded = get_sig_nid(cell->getPort(ID::A), width_ay, a_signed); + + // zero-extend the rest + int zeroes = get_sig_nid(Const(0, width-width_ay)); + nid_a = next_nid++; + btorf("%d concat %d %d %d\n", nid_a, sid, zeroes, nid_a_padded); + } else { + nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed); + } + + int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed); + if (btor_op == "shift") { - int nid_a = get_sig_nid(cell->getPort(ID::A), width, false); - int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed); - int nid_r = next_nid++; btorf("%d srl %d %d %d\n", nid_r, sid, nid_a, nid_b); @@ -248,9 +263,6 @@ struct BtorWorker } else { - int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed); - int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed); - nid = next_nid++; btorf("%d %s %d %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str()); } @@ -696,49 +708,45 @@ struct BtorWorker goto okay; } - if (cell->type == ID($mem)) + if (cell->type.in(ID($mem), ID($memrd), ID($memwr), ID($meminit))) { - int abits = cell->getParam(ID::ABITS).as_int(); - int width = cell->getParam(ID::WIDTH).as_int(); - int nwords = cell->getParam(ID::SIZE).as_int(); - int rdports = cell->getParam(ID::RD_PORTS).as_int(); - int wrports = cell->getParam(ID::WR_PORTS).as_int(); + Mem *mem = mem_cells[cell]; - Const wr_clk_en = cell->getParam(ID::WR_CLK_ENABLE); - Const rd_clk_en = cell->getParam(ID::RD_CLK_ENABLE); + int abits = ceil_log2(mem->size); - bool asyncwr = wr_clk_en.is_fully_zero(); + bool asyncwr = false; + bool syncwr = false; - if (!asyncwr && !wr_clk_en.is_fully_ones()) - log_error("Memory %s.%s has mixed async/sync write ports.\n", - log_id(module), log_id(cell)); - - if (!rd_clk_en.is_fully_zero()) - log_error("Memory %s.%s has sync read ports.\n", - log_id(module), log_id(cell)); + for (auto &port : mem->wr_ports) { + if (port.clk_enable) + syncwr = true; + else + asyncwr = true; + } - SigSpec sig_rd_addr = sigmap(cell->getPort(ID::RD_ADDR)); - SigSpec sig_rd_data = sigmap(cell->getPort(ID::RD_DATA)); + if (asyncwr && syncwr) + log_error("Memory %s.%s has mixed async/sync write ports.\n", + log_id(module), log_id(mem->memid)); - SigSpec sig_wr_addr = sigmap(cell->getPort(ID::WR_ADDR)); - SigSpec sig_wr_data = sigmap(cell->getPort(ID::WR_DATA)); - SigSpec sig_wr_en = sigmap(cell->getPort(ID::WR_EN)); + for (auto &port : mem->rd_ports) + if (port.clk_enable) + log_error("Memory %s.%s has sync read ports.\n", + log_id(module), log_id(mem->memid)); - int data_sid = get_bv_sid(width); + int data_sid = get_bv_sid(mem->width); int bool_sid = get_bv_sid(1); - int sid = get_mem_sid(abits, width); + int sid = get_mem_sid(abits, mem->width); - Const initdata = cell->getParam(ID::INIT); - initdata.exts(nwords*width); int nid_init_val = -1; - if (!initdata.is_fully_undef()) + if (!mem->inits.empty()) { + Const initdata = mem->get_init_data(); bool constword = true; - Const firstword = initdata.extract(0, width); + Const firstword = initdata.extract(0, mem->width); - for (int i = 1; i < nwords; i++) { - Const thisword = initdata.extract(i*width, width); + for (int i = 1; i < mem->size; i++) { + Const thisword = initdata.extract(i*mem->width, mem->width); if (thisword != firstword) { constword = false; break; @@ -756,8 +764,8 @@ struct BtorWorker nid_init_val = next_nid++; btorf("%d state %d\n", nid_init_val, sid); - for (int i = 0; i < nwords; i++) { - Const thisword = initdata.extract(i*width, width); + for (int i = 0; i < mem->size; i++) { + Const thisword = initdata.extract(i*mem->width, mem->width); if (thisword.is_fully_undef()) continue; Const thisaddr(i, abits); @@ -776,10 +784,10 @@ struct BtorWorker int nid = next_nid++; int nid_head = nid; - if (cell->name[0] == '$') + if (mem->memid[0] == '$') btorf("%d state %d\n", nid, sid); else - btorf("%d state %d %s\n", nid, sid, log_id(cell)); + btorf("%d state %d %s\n", nid, sid, log_id(mem->memid)); if (nid_init_val >= 0) { @@ -789,15 +797,14 @@ struct BtorWorker if (asyncwr) { - for (int port = 0; port < wrports; port++) + for (auto &port : mem->wr_ports) { - SigSpec wa = sig_wr_addr.extract(port*abits, abits); - SigSpec wd = sig_wr_data.extract(port*width, width); - SigSpec we = sig_wr_en.extract(port*width, width); + SigSpec wa = port.addr; + wa.extend_u0(abits); int wa_nid = get_sig_nid(wa); - int wd_nid = get_sig_nid(wd); - int we_nid = get_sig_nid(we); + int wd_nid = get_sig_nid(port.data); + int we_nid = get_sig_nid(port.en); int nid2 = next_nid++; btorf("%d read %d %d %d\n", nid2, data_sid, nid_head, wa_nid); @@ -827,22 +834,22 @@ struct BtorWorker } } - for (int port = 0; port < rdports; port++) + for (auto &port : mem->rd_ports) { - SigSpec ra = sig_rd_addr.extract(port*abits, abits); - SigSpec rd = sig_rd_data.extract(port*width, width); + SigSpec ra = port.addr; + ra.extend_u0(abits); int ra_nid = get_sig_nid(ra); int rd_nid = next_nid++; btorf("%d read %d %d %d\n", rd_nid, data_sid, nid_head, ra_nid); - add_nid_sig(rd_nid, rd); + add_nid_sig(rd_nid, port.data); } if (!asyncwr) { - ff_todo.push_back(make_pair(nid, cell)); + mem_todo.push_back(make_pair(nid, mem)); } else { @@ -1057,6 +1064,15 @@ struct BtorWorker if (!info_filename.empty()) infof("name %s\n", log_id(module)); + memories = Mem::get_all_memories(module); + + dict<IdString, Mem*> mem_dict; + for (auto &mem : memories) + mem_dict[mem.memid] = &mem; + for (auto cell : module->cells()) + if (cell->type.in(ID($mem), ID($memwr), ID($memrd), ID($meminit))) + mem_cells[cell] = mem_dict[cell->parameters.at(ID::MEMID).decode_string()]; + btorf_push("inputs"); for (auto wire : module->wires()) @@ -1193,7 +1209,7 @@ struct BtorWorker continue; } - while (!ff_todo.empty()) + while (!ff_todo.empty() || !mem_todo.empty()) { vector<pair<int, Cell*>> todo; todo.swap(ff_todo); @@ -1205,70 +1221,71 @@ struct BtorWorker btorf_push(stringf("next %s", log_id(cell))); - if (cell->type == ID($mem)) - { - int abits = cell->getParam(ID::ABITS).as_int(); - int width = cell->getParam(ID::WIDTH).as_int(); - int wrports = cell->getParam(ID::WR_PORTS).as_int(); + SigSpec sig = sigmap(cell->getPort(ID::D)); + int nid_q = get_sig_nid(sig); + int sid = get_bv_sid(GetSize(sig)); + btorf("%d next %d %d %d%s\n", next_nid++, sid, nid, nid_q, getinfo(cell).c_str()); - SigSpec sig_wr_addr = sigmap(cell->getPort(ID::WR_ADDR)); - SigSpec sig_wr_data = sigmap(cell->getPort(ID::WR_DATA)); - SigSpec sig_wr_en = sigmap(cell->getPort(ID::WR_EN)); + btorf_pop(stringf("next %s", log_id(cell))); + } - int data_sid = get_bv_sid(width); - int bool_sid = get_bv_sid(1); - int sid = get_mem_sid(abits, width); - int nid_head = nid; + vector<pair<int, Mem*>> mtodo; + mtodo.swap(mem_todo); - for (int port = 0; port < wrports; port++) - { - SigSpec wa = sig_wr_addr.extract(port*abits, abits); - SigSpec wd = sig_wr_data.extract(port*width, width); - SigSpec we = sig_wr_en.extract(port*width, width); + for (auto &it : mtodo) + { + int nid = it.first; + Mem *mem = it.second; + + btorf_push(stringf("next %s", log_id(mem->memid))); + + int abits = ceil_log2(mem->size); - int wa_nid = get_sig_nid(wa); - int wd_nid = get_sig_nid(wd); - int we_nid = get_sig_nid(we); + int data_sid = get_bv_sid(mem->width); + int bool_sid = get_bv_sid(1); + int sid = get_mem_sid(abits, mem->width); + int nid_head = nid; - int nid2 = next_nid++; - btorf("%d read %d %d %d\n", nid2, data_sid, nid_head, wa_nid); + for (auto &port : mem->wr_ports) + { + SigSpec wa = port.addr; + wa.extend_u0(abits); - int nid3 = next_nid++; - btorf("%d not %d %d\n", nid3, data_sid, we_nid); + int wa_nid = get_sig_nid(wa); + int wd_nid = get_sig_nid(port.data); + int we_nid = get_sig_nid(port.en); - int nid4 = next_nid++; - btorf("%d and %d %d %d\n", nid4, data_sid, nid2, nid3); + int nid2 = next_nid++; + btorf("%d read %d %d %d\n", nid2, data_sid, nid_head, wa_nid); + + int nid3 = next_nid++; + btorf("%d not %d %d\n", nid3, data_sid, we_nid); - int nid5 = next_nid++; - btorf("%d and %d %d %d\n", nid5, data_sid, wd_nid, we_nid); + int nid4 = next_nid++; + btorf("%d and %d %d %d\n", nid4, data_sid, nid2, nid3); - int nid6 = next_nid++; - btorf("%d or %d %d %d\n", nid6, data_sid, nid5, nid4); + int nid5 = next_nid++; + btorf("%d and %d %d %d\n", nid5, data_sid, wd_nid, we_nid); - int nid7 = next_nid++; - btorf("%d write %d %d %d %d\n", nid7, sid, nid_head, wa_nid, nid6); + int nid6 = next_nid++; + btorf("%d or %d %d %d\n", nid6, data_sid, nid5, nid4); - int nid8 = next_nid++; - btorf("%d redor %d %d\n", nid8, bool_sid, we_nid); + int nid7 = next_nid++; + btorf("%d write %d %d %d %d\n", nid7, sid, nid_head, wa_nid, nid6); - int nid9 = next_nid++; - btorf("%d ite %d %d %d %d\n", nid9, sid, nid8, nid7, nid_head); + int nid8 = next_nid++; + btorf("%d redor %d %d\n", nid8, bool_sid, we_nid); - nid_head = nid9; - } + int nid9 = next_nid++; + btorf("%d ite %d %d %d %d\n", nid9, sid, nid8, nid7, nid_head); - int nid2 = next_nid++; - btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, getinfo(cell).c_str()); - } - else - { - SigSpec sig = sigmap(cell->getPort(ID::D)); - int nid_q = get_sig_nid(sig); - int sid = get_bv_sid(GetSize(sig)); - btorf("%d next %d %d %d%s\n", next_nid++, sid, nid, nid_q, getinfo(cell).c_str()); + nid_head = nid9; } - btorf_pop(stringf("next %s", log_id(cell))); + int nid2 = next_nid++; + btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, (mem->cell ? getinfo(mem->cell) : getinfo(mem->mem)).c_str()); + + btorf_pop(stringf("next %s", log_id(mem->memid))); } } @@ -1335,7 +1352,7 @@ struct BtorWorker struct BtorBackend : public Backend { BtorBackend() : Backend("btor", "write design to BTOR file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1359,7 +1376,7 @@ struct BtorBackend : public Backend { log(" Output symbols for internal netnames (starting with '$')\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { bool verbose = false, single_bad = false, cover_mode = false, print_internal_names = false; string info_filename; diff --git a/backends/btor/test_cells.sh b/backends/btor/test_cells.sh index 3f077201a..0a011932d 100644..100755 --- a/backends/btor/test_cells.sh +++ b/backends/btor/test_cells.sh @@ -6,7 +6,7 @@ rm -rf test_cells.tmp mkdir -p test_cells.tmp cd test_cells.tmp -../../../yosys -p 'test_cell -n 5 -w test all /$alu /$fa /$lcu /$lut /$sop /$macc /$mul /$div /$mod /$divfloor /$modfloor' +../../../yosys -p 'test_cell -n 5 -w test all /$alu /$fa /$lcu /$lut /$sop /$macc /$mul /$div /$mod /$divfloor /$modfloor /$shiftx' for fn in test_*.il; do ../../../yosys -p " @@ -19,7 +19,7 @@ for fn in test_*.il; do hierarchy -top main write_btor ${fn%.il}.btor " - boolectormc -kmax 1 --trace-gen --stop-first -v ${fn%.il}.btor > ${fn%.il}.out + btormc -kmax 1 --trace-gen --stop-first -v ${fn%.il}.btor > ${fn%.il}.out if grep " SATISFIABLE" ${fn%.il}.out; then echo "Check failed for ${fn%.il}." exit 1 diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index c988c9e80..41089a153 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -17,6 +17,11 @@ */ // This file is included by the designs generated with `write_cxxrtl`. It is not used in Yosys itself. +// +// The CXXRTL support library implements compile time specialized arbitrary width arithmetics, as well as provides +// composite lvalues made out of bit slices and concatenations of lvalues. This allows the `write_cxxrtl` pass +// to perform a straightforward translation of RTLIL structures to readable C++, relying on the C++ compiler +// to unwrap the abstraction and generate efficient code. #ifndef CXXRTL_H #define CXXRTL_H @@ -35,10 +40,19 @@ #include <backends/cxxrtl/cxxrtl_capi.h> -// The CXXRTL support library implements compile time specialized arbitrary width arithmetics, as well as provides -// composite lvalues made out of bit slices and concatenations of lvalues. This allows the `write_cxxrtl` pass -// to perform a straightforward translation of RTLIL structures to readable C++, relying on the C++ compiler -// to unwrap the abstraction and generate efficient code. +// CXXRTL essentially uses the C++ compiler as a hygienic macro engine that feeds an instruction selector. +// It generates a lot of specialized template functions with relatively large bodies that, when inlined +// into the caller and (for those with loops) unrolled, often expose many new optimization opportunities. +// Because of this, most of the CXXRTL runtime must be always inlined for best performance. +#ifndef __has_attribute +# define __has_attribute(x) 0 +#endif +#if __has_attribute(always_inline) +#define CXXRTL_ALWAYS_INLINE inline __attribute__((__always_inline__)) +#else +#define CXXRTL_ALWAYS_INLINE inline +#endif + namespace cxxrtl { // All arbitrary-width values in CXXRTL are backed by arrays of unsigned integers called chunks. The chunk size @@ -52,6 +66,7 @@ namespace cxxrtl { // Therefore, using relatively wide chunks and clearing the high bits explicitly and only when we know they may be // clobbered results in simpler generated code. typedef uint32_t chunk_t; +typedef uint64_t wide_chunk_t; template<typename T> struct chunk_traits { @@ -85,6 +100,7 @@ struct value : public expr_base<value<Bits>> { value<Bits> &operator=(const value<Bits> &) = default; // A (no-op) helper that forces the cast to value<>. + CXXRTL_ALWAYS_INLINE const value<Bits> &val() const { return *this; } @@ -95,12 +111,42 @@ struct value : public expr_base<value<Bits>> { return ss.str(); } + // Conversion operations. + // + // These functions ensure that a conversion is never out of range, and should be always used, if at all + // possible, instead of direct manipulation of the `data` member. For very large types, .slice() and + // .concat() can be used to split them into more manageable parts. + template<class IntegerT> + CXXRTL_ALWAYS_INLINE + IntegerT get() const { + static_assert(std::numeric_limits<IntegerT>::is_integer && !std::numeric_limits<IntegerT>::is_signed, + "get<T>() requires T to be an unsigned integral type"); + static_assert(std::numeric_limits<IntegerT>::digits >= Bits, + "get<T>() requires T to be at least as wide as the value is"); + IntegerT result = 0; + for (size_t n = 0; n < chunks; n++) + result |= IntegerT(data[n]) << (n * chunk::bits); + return result; + } + + template<class IntegerT> + CXXRTL_ALWAYS_INLINE + void set(IntegerT other) { + static_assert(std::numeric_limits<IntegerT>::is_integer && !std::numeric_limits<IntegerT>::is_signed, + "set<T>() requires T to be an unsigned integral type"); + static_assert(std::numeric_limits<IntegerT>::digits >= Bits, + "set<T>() requires the value to be at least as wide as T is"); + for (size_t n = 0; n < chunks; n++) + data[n] = (other >> (n * chunk::bits)) & chunk::mask; + } + // Operations with compile-time parameters. // // These operations are used to implement slicing, concatenation, and blitting. // The trunc, zext and sext operations add or remove most significant bits (i.e. on the left); // the rtrunc and rzext operations add or remove least significant bits (i.e. on the right). template<size_t NewBits> + CXXRTL_ALWAYS_INLINE value<NewBits> trunc() const { static_assert(NewBits <= Bits, "trunc() may not increase width"); value<NewBits> result; @@ -111,6 +157,7 @@ struct value : public expr_base<value<Bits>> { } template<size_t NewBits> + CXXRTL_ALWAYS_INLINE value<NewBits> zext() const { static_assert(NewBits >= Bits, "zext() may not decrease width"); value<NewBits> result; @@ -120,6 +167,7 @@ struct value : public expr_base<value<Bits>> { } template<size_t NewBits> + CXXRTL_ALWAYS_INLINE value<NewBits> sext() const { static_assert(NewBits >= Bits, "sext() may not decrease width"); value<NewBits> result; @@ -135,6 +183,7 @@ struct value : public expr_base<value<Bits>> { } template<size_t NewBits> + CXXRTL_ALWAYS_INLINE value<NewBits> rtrunc() const { static_assert(NewBits <= Bits, "rtrunc() may not increase width"); value<NewBits> result; @@ -154,6 +203,7 @@ struct value : public expr_base<value<Bits>> { } template<size_t NewBits> + CXXRTL_ALWAYS_INLINE value<NewBits> rzext() const { static_assert(NewBits >= Bits, "rzext() may not decrease width"); value<NewBits> result; @@ -165,13 +215,14 @@ struct value : public expr_base<value<Bits>> { carry = (shift_bits == 0) ? 0 : data[n] >> (chunk::bits - shift_bits); } - if (carry != 0) - result.data[result.chunks - 1] = carry; + if (shift_chunks + chunks < result.chunks) + result.data[shift_chunks + chunks] = carry; return result; } // Bit blit operation, i.e. a partial read-modify-write. template<size_t Stop, size_t Start> + CXXRTL_ALWAYS_INLINE value<Bits> blit(const value<Stop - Start + 1> &source) const { static_assert(Stop >= Start, "blit() may not reverse bit order"); constexpr chunk::type start_mask = ~(chunk::mask << (Start % chunk::bits)); @@ -196,6 +247,7 @@ struct value : public expr_base<value<Bits>> { // than the operand. In C++17 these can be replaced with `if constexpr`. template<size_t NewBits, typename = void> struct zext_cast { + CXXRTL_ALWAYS_INLINE value<NewBits> operator()(const value<Bits> &val) { return val.template zext<NewBits>(); } @@ -203,6 +255,7 @@ struct value : public expr_base<value<Bits>> { template<size_t NewBits> struct zext_cast<NewBits, typename std::enable_if<(NewBits < Bits)>::type> { + CXXRTL_ALWAYS_INLINE value<NewBits> operator()(const value<Bits> &val) { return val.template trunc<NewBits>(); } @@ -210,6 +263,7 @@ struct value : public expr_base<value<Bits>> { template<size_t NewBits, typename = void> struct sext_cast { + CXXRTL_ALWAYS_INLINE value<NewBits> operator()(const value<Bits> &val) { return val.template sext<NewBits>(); } @@ -217,17 +271,20 @@ struct value : public expr_base<value<Bits>> { template<size_t NewBits> struct sext_cast<NewBits, typename std::enable_if<(NewBits < Bits)>::type> { + CXXRTL_ALWAYS_INLINE value<NewBits> operator()(const value<Bits> &val) { return val.template trunc<NewBits>(); } }; template<size_t NewBits> + CXXRTL_ALWAYS_INLINE value<NewBits> zcast() const { return zext_cast<NewBits>()(*this); } template<size_t NewBits> + CXXRTL_ALWAYS_INLINE value<NewBits> scast() const { return sext_cast<NewBits>()(*this); } @@ -246,6 +303,10 @@ struct value : public expr_base<value<Bits>> { data[offset_chunks] |= value ? 1 << offset_bits : 0; } + explicit operator bool() const { + return !is_zero(); + } + bool is_zero() const { for (size_t n = 0; n < chunks; n++) if (data[n] != 0) @@ -253,10 +314,6 @@ struct value : public expr_base<value<Bits>> { return true; } - explicit operator bool() const { - return !is_zero(); - } - bool is_neg() const { return data[chunks - 1] & (1 << ((Bits - 1) % chunk::bits)); } @@ -349,10 +406,12 @@ struct value : public expr_base<value<Bits>> { : data[chunks - 1 - n] << (chunk::bits - shift_bits); } if (Signed && is_neg()) { - for (size_t n = chunks - shift_chunks; n < chunks; n++) + size_t top_chunk_idx = (Bits - shift_bits) / chunk::bits; + size_t top_chunk_bits = (Bits - shift_bits) % chunk::bits; + for (size_t n = top_chunk_idx + 1; n < chunks; n++) result.data[n] = chunk::mask; if (shift_bits != 0) - result.data[chunks - shift_chunks] |= chunk::mask << (chunk::bits - shift_bits); + result.data[top_chunk_idx] |= chunk::mask << top_chunk_bits; } return result; } @@ -393,10 +452,11 @@ struct value : public expr_base<value<Bits>> { bool carry = CarryIn; for (size_t n = 0; n < result.chunks; n++) { result.data[n] = data[n] + (Invert ? ~other.data[n] : other.data[n]) + carry; + if (result.chunks - 1 == n) + result.data[result.chunks - 1] &= result.msb_mask; carry = (result.data[n] < data[n]) || (result.data[n] == data[n] && carry); } - result.data[result.chunks - 1] &= result.msb_mask; return {result, carry}; } @@ -425,6 +485,24 @@ struct value : public expr_base<value<Bits>> { bool overflow = (is_neg() == !other.is_neg()) && (is_neg() != result.is_neg()); return result.is_neg() ^ overflow; // a.scmp(b) ≡ a s< b } + + template<size_t ResultBits> + value<ResultBits> mul(const value<Bits> &other) const { + value<ResultBits> result; + wide_chunk_t wide_result[result.chunks + 1] = {}; + for (size_t n = 0; n < chunks; n++) { + for (size_t m = 0; m < chunks && n + m < result.chunks; m++) { + wide_result[n + m] += wide_chunk_t(data[n]) * wide_chunk_t(other.data[m]); + wide_result[n + m + 1] += wide_result[n + m] >> chunk::bits; + wide_result[n + m] &= chunk::mask; + } + } + for (size_t n = 0; n < result.chunks; n++) { + result.data[n] = wide_result[n]; + } + result.data[result.chunks - 1] &= result.msb_mask; + return result; + } }; // Expression template for a slice, usable as lvalue or rvalue, and composable with other expression templates here. @@ -439,12 +517,14 @@ struct slice_expr : public expr_base<slice_expr<T, Stop, Start>> { slice_expr(T &expr) : expr(expr) {} slice_expr(const slice_expr<T, Stop, Start> &) = delete; + CXXRTL_ALWAYS_INLINE operator value<bits>() const { return static_cast<const value<T::bits> &>(expr) .template rtrunc<T::bits - Start>() .template trunc<bits>(); } + CXXRTL_ALWAYS_INLINE slice_expr<T, Stop, Start> &operator=(const value<bits> &rhs) { // Generic partial assignment implemented using a read-modify-write operation on the sliced expression. expr = static_cast<const value<T::bits> &>(expr) @@ -453,6 +533,7 @@ struct slice_expr : public expr_base<slice_expr<T, Stop, Start>> { } // A helper that forces the cast to value<>, which allows deduction to work. + CXXRTL_ALWAYS_INLINE value<bits> val() const { return static_cast<const value<bits> &>(*this); } @@ -469,6 +550,7 @@ struct concat_expr : public expr_base<concat_expr<T, U>> { concat_expr(T &ms_expr, U &ls_expr) : ms_expr(ms_expr), ls_expr(ls_expr) {} concat_expr(const concat_expr<T, U> &) = delete; + CXXRTL_ALWAYS_INLINE operator value<bits>() const { value<bits> ms_shifted = static_cast<const value<T::bits> &>(ms_expr) .template rzext<bits>(); @@ -477,6 +559,7 @@ struct concat_expr : public expr_base<concat_expr<T, U>> { return ms_shifted.bit_or(ls_extended); } + CXXRTL_ALWAYS_INLINE concat_expr<T, U> &operator=(const value<bits> &rhs) { ms_expr = rhs.template rtrunc<T::bits>(); ls_expr = rhs.template trunc<U::bits>(); @@ -484,6 +567,7 @@ struct concat_expr : public expr_base<concat_expr<T, U>> { } // A helper that forces the cast to value<>, which allows deduction to work. + CXXRTL_ALWAYS_INLINE value<bits> val() const { return static_cast<const value<bits> &>(*this); } @@ -508,21 +592,25 @@ struct concat_expr : public expr_base<concat_expr<T, U>> { template<class T> struct expr_base { template<size_t Stop, size_t Start = Stop> + CXXRTL_ALWAYS_INLINE slice_expr<const T, Stop, Start> slice() const { return {*static_cast<const T *>(this)}; } template<size_t Stop, size_t Start = Stop> + CXXRTL_ALWAYS_INLINE slice_expr<T, Stop, Start> slice() { return {*static_cast<T *>(this)}; } template<class U> + CXXRTL_ALWAYS_INLINE concat_expr<const T, typename std::remove_reference<const U>::type> concat(const U &other) const { return {*static_cast<const T *>(this), other}; } template<class U> + CXXRTL_ALWAYS_INLINE concat_expr<T, typename std::remove_reference<U>::type> concat(U &&other) { return {*static_cast<T *>(this), other}; } @@ -563,6 +651,18 @@ struct wire { wire(wire<Bits> &&) = default; wire<Bits> &operator=(const wire<Bits> &) = delete; + template<class IntegerT> + CXXRTL_ALWAYS_INLINE + IntegerT get() const { + return curr.template get<IntegerT>(); + } + + template<class IntegerT> + CXXRTL_ALWAYS_INLINE + void set(IntegerT other) { + next.template set<IntegerT>(other); + } + bool commit() { if (curr != next) { curr = next; @@ -608,6 +708,7 @@ struct memory { // This utterly reprehensible construct is the most reasonable way to apply a function to every element // of a parameter pack, if the elements all have different types and so cannot be cast to an initializer list. auto _ = {std::move(std::begin(init.data), std::end(init.data), data.begin() + init.offset)...}; + (void)_; } // An operator for direct memory reads. May be used at any time during the simulation. @@ -676,10 +777,8 @@ struct metadata { // In debug mode, using the wrong .as_*() function will assert. // In release mode, using the wrong .as_*() function will safely return a default value. - union { - const unsigned uint_value = 0; - const signed sint_value; - }; + const unsigned uint_value = 0; + const signed sint_value = 0; const std::string string_value = ""; const double double_value = 0.0; @@ -716,68 +815,155 @@ struct metadata { typedef std::map<std::string, metadata> metadata_map; +// Helper class to disambiguate values/wires and their aliases. +struct debug_alias {}; + // This structure is intended for consumption via foreign function interfaces, like Python's ctypes. // Because of this it uses a C-style layout that is easy to parse rather than more idiomatic C++. // // To avoid violating strict aliasing rules, this structure has to be a subclass of the one used // in the C API, or it would not be possible to cast between the pointers to these. struct debug_item : ::cxxrtl_object { + // Object types. enum : uint32_t { VALUE = CXXRTL_VALUE, WIRE = CXXRTL_WIRE, MEMORY = CXXRTL_MEMORY, + ALIAS = CXXRTL_ALIAS, + }; + + // Object flags. + enum : uint32_t { + INPUT = CXXRTL_INPUT, + OUTPUT = CXXRTL_OUTPUT, + INOUT = CXXRTL_INOUT, + DRIVEN_SYNC = CXXRTL_DRIVEN_SYNC, + DRIVEN_COMB = CXXRTL_DRIVEN_COMB, + UNDRIVEN = CXXRTL_UNDRIVEN, }; debug_item(const ::cxxrtl_object &object) : cxxrtl_object(object) {} template<size_t Bits> - debug_item(value<Bits> &item) { + debug_item(value<Bits> &item, size_t lsb_offset = 0, uint32_t flags_ = 0) { static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t), "value<Bits> is not compatible with C layout"); - type = VALUE; - width = Bits; - depth = 1; - curr = item.data; - next = item.data; + type = VALUE; + flags = flags_; + width = Bits; + lsb_at = lsb_offset; + depth = 1; + zero_at = 0; + curr = item.data; + next = item.data; } template<size_t Bits> - debug_item(const value<Bits> &item) { + debug_item(const value<Bits> &item, size_t lsb_offset = 0) { static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t), "value<Bits> is not compatible with C layout"); - type = VALUE; - width = Bits; - depth = 1; - curr = const_cast<uint32_t*>(item.data); - next = nullptr; + type = VALUE; + flags = DRIVEN_COMB; + width = Bits; + lsb_at = lsb_offset; + depth = 1; + zero_at = 0; + curr = const_cast<chunk_t*>(item.data); + next = nullptr; } template<size_t Bits> - debug_item(wire<Bits> &item) { + debug_item(wire<Bits> &item, size_t lsb_offset = 0, uint32_t flags_ = 0) { static_assert(sizeof(item.curr) == value<Bits>::chunks * sizeof(chunk_t) && sizeof(item.next) == value<Bits>::chunks * sizeof(chunk_t), "wire<Bits> is not compatible with C layout"); - type = WIRE; - width = Bits; - depth = 1; - curr = item.curr.data; - next = item.next.data; + type = WIRE; + flags = flags_; + width = Bits; + lsb_at = lsb_offset; + depth = 1; + zero_at = 0; + curr = item.curr.data; + next = item.next.data; } template<size_t Width> - debug_item(memory<Width> &item) { + debug_item(memory<Width> &item, size_t zero_offset = 0) { static_assert(sizeof(item.data[0]) == value<Width>::chunks * sizeof(chunk_t), "memory<Width> is not compatible with C layout"); - type = MEMORY; - width = Width; - depth = item.data.size(); - curr = item.data.empty() ? nullptr : item.data[0].data; - next = nullptr; + type = MEMORY; + flags = 0; + width = Width; + lsb_at = 0; + depth = item.data.size(); + zero_at = zero_offset; + curr = item.data.empty() ? nullptr : item.data[0].data; + next = nullptr; + } + + template<size_t Bits> + debug_item(debug_alias, const value<Bits> &item, size_t lsb_offset = 0) { + static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t), + "value<Bits> is not compatible with C layout"); + type = ALIAS; + flags = DRIVEN_COMB; + width = Bits; + lsb_at = lsb_offset; + depth = 1; + zero_at = 0; + curr = const_cast<chunk_t*>(item.data); + next = nullptr; + } + + template<size_t Bits> + debug_item(debug_alias, const wire<Bits> &item, size_t lsb_offset = 0) { + static_assert(sizeof(item.curr) == value<Bits>::chunks * sizeof(chunk_t) && + sizeof(item.next) == value<Bits>::chunks * sizeof(chunk_t), + "wire<Bits> is not compatible with C layout"); + type = ALIAS; + flags = DRIVEN_COMB; + width = Bits; + lsb_at = lsb_offset; + depth = 1; + zero_at = 0; + curr = const_cast<chunk_t*>(item.curr.data); + next = nullptr; } }; static_assert(std::is_standard_layout<debug_item>::value, "debug_item is not compatible with C layout"); -typedef std::map<std::string, debug_item> debug_items; +struct debug_items { + std::map<std::string, std::vector<debug_item>> table; + + void add(const std::string &name, debug_item &&item) { + std::vector<debug_item> &parts = table[name]; + parts.emplace_back(item); + std::sort(parts.begin(), parts.end(), + [](const debug_item &a, const debug_item &b) { + return a.lsb_at < b.lsb_at; + }); + } + + size_t count(const std::string &name) const { + if (table.count(name) == 0) + return 0; + return table.at(name).size(); + } + + const std::vector<debug_item> &parts_at(const std::string &name) const { + return table.at(name); + } + + const debug_item &at(const std::string &name) const { + const std::vector<debug_item> &parts = table.at(name); + assert(parts.size() == 1); + return parts.at(0); + } + + const debug_item &operator [](const std::string &name) const { + return at(name); + } +}; struct module { module() {} @@ -799,7 +985,9 @@ struct module { return deltas; } - virtual void debug_info(debug_items &items, std::string path = "") {} + virtual void debug_info(debug_items &items, std::string path = "") { + (void)items, (void)path; + } }; } // namespace cxxrtl @@ -823,271 +1011,322 @@ using namespace cxxrtl; // std::max isn't constexpr until C++14 for no particular reason (it's an oversight), so we define our own. template<class T> +CXXRTL_ALWAYS_INLINE constexpr T max(const T &a, const T &b) { return a > b ? a : b; } // Logic operations template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> logic_not(const value<BitsA> &a) { return value<BitsY> { a ? 0u : 1u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> logic_and(const value<BitsA> &a, const value<BitsB> &b) { - return value<BitsY> { (bool(a) & bool(b)) ? 1u : 0u }; + return value<BitsY> { (bool(a) && bool(b)) ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> logic_or(const value<BitsA> &a, const value<BitsB> &b) { - return value<BitsY> { (bool(a) | bool(b)) ? 1u : 0u }; + return value<BitsY> { (bool(a) || bool(b)) ? 1u : 0u }; } // Reduction operations template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> reduce_and(const value<BitsA> &a) { return value<BitsY> { a.bit_not().is_zero() ? 1u : 0u }; } template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> reduce_or(const value<BitsA> &a) { return value<BitsY> { a ? 1u : 0u }; } template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> reduce_xor(const value<BitsA> &a) { return value<BitsY> { (a.ctpop() % 2) ? 1u : 0u }; } template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> reduce_xnor(const value<BitsA> &a) { return value<BitsY> { (a.ctpop() % 2) ? 0u : 1u }; } template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> reduce_bool(const value<BitsA> &a) { return value<BitsY> { a ? 1u : 0u }; } // Bitwise operations template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> not_u(const value<BitsA> &a) { return a.template zcast<BitsY>().bit_not(); } template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> not_s(const value<BitsA> &a) { return a.template scast<BitsY>().bit_not(); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> and_uu(const value<BitsA> &a, const value<BitsB> &b) { return a.template zcast<BitsY>().bit_and(b.template zcast<BitsY>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> and_ss(const value<BitsA> &a, const value<BitsB> &b) { return a.template scast<BitsY>().bit_and(b.template scast<BitsY>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> or_uu(const value<BitsA> &a, const value<BitsB> &b) { return a.template zcast<BitsY>().bit_or(b.template zcast<BitsY>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> or_ss(const value<BitsA> &a, const value<BitsB> &b) { return a.template scast<BitsY>().bit_or(b.template scast<BitsY>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> xor_uu(const value<BitsA> &a, const value<BitsB> &b) { return a.template zcast<BitsY>().bit_xor(b.template zcast<BitsY>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> xor_ss(const value<BitsA> &a, const value<BitsB> &b) { return a.template scast<BitsY>().bit_xor(b.template scast<BitsY>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> xnor_uu(const value<BitsA> &a, const value<BitsB> &b) { return a.template zcast<BitsY>().bit_xor(b.template zcast<BitsY>()).bit_not(); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> xnor_ss(const value<BitsA> &a, const value<BitsB> &b) { return a.template scast<BitsY>().bit_xor(b.template scast<BitsY>()).bit_not(); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shl_uu(const value<BitsA> &a, const value<BitsB> &b) { return a.template zcast<BitsY>().template shl(b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shl_su(const value<BitsA> &a, const value<BitsB> &b) { return a.template scast<BitsY>().template shl(b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> sshl_uu(const value<BitsA> &a, const value<BitsB> &b) { return a.template zcast<BitsY>().template shl(b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> sshl_su(const value<BitsA> &a, const value<BitsB> &b) { return a.template scast<BitsY>().template shl(b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shr_uu(const value<BitsA> &a, const value<BitsB> &b) { return a.template shr(b).template zcast<BitsY>(); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shr_su(const value<BitsA> &a, const value<BitsB> &b) { return a.template shr(b).template scast<BitsY>(); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> sshr_uu(const value<BitsA> &a, const value<BitsB> &b) { return a.template shr(b).template zcast<BitsY>(); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> sshr_su(const value<BitsA> &a, const value<BitsB> &b) { return a.template sshr(b).template scast<BitsY>(); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shift_uu(const value<BitsA> &a, const value<BitsB> &b) { return shr_uu<BitsY>(a, b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shift_su(const value<BitsA> &a, const value<BitsB> &b) { return shr_su<BitsY>(a, b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shift_us(const value<BitsA> &a, const value<BitsB> &b) { return b.is_neg() ? shl_uu<BitsY>(a, b.template sext<BitsB + 1>().neg()) : shr_uu<BitsY>(a, b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shift_ss(const value<BitsA> &a, const value<BitsB> &b) { return b.is_neg() ? shl_su<BitsY>(a, b.template sext<BitsB + 1>().neg()) : shr_su<BitsY>(a, b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shiftx_uu(const value<BitsA> &a, const value<BitsB> &b) { return shift_uu<BitsY>(a, b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shiftx_su(const value<BitsA> &a, const value<BitsB> &b) { return shift_su<BitsY>(a, b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shiftx_us(const value<BitsA> &a, const value<BitsB> &b) { return shift_us<BitsY>(a, b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> shiftx_ss(const value<BitsA> &a, const value<BitsB> &b) { return shift_ss<BitsY>(a, b); } // Comparison operations template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> eq_uu(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY>{ a.template zext<BitsExt>() == b.template zext<BitsExt>() ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> eq_ss(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY>{ a.template sext<BitsExt>() == b.template sext<BitsExt>() ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> ne_uu(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY>{ a.template zext<BitsExt>() != b.template zext<BitsExt>() ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> ne_ss(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY>{ a.template sext<BitsExt>() != b.template sext<BitsExt>() ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> eqx_uu(const value<BitsA> &a, const value<BitsB> &b) { return eq_uu<BitsY>(a, b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> eqx_ss(const value<BitsA> &a, const value<BitsB> &b) { return eq_ss<BitsY>(a, b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> nex_uu(const value<BitsA> &a, const value<BitsB> &b) { return ne_uu<BitsY>(a, b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> nex_ss(const value<BitsA> &a, const value<BitsB> &b) { return ne_ss<BitsY>(a, b); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> gt_uu(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY> { b.template zext<BitsExt>().ucmp(a.template zext<BitsExt>()) ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> gt_ss(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY> { b.template sext<BitsExt>().scmp(a.template sext<BitsExt>()) ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> ge_uu(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY> { !a.template zext<BitsExt>().ucmp(b.template zext<BitsExt>()) ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> ge_ss(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY> { !a.template sext<BitsExt>().scmp(b.template sext<BitsExt>()) ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> lt_uu(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY> { a.template zext<BitsExt>().ucmp(b.template zext<BitsExt>()) ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> lt_ss(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY> { a.template sext<BitsExt>().scmp(b.template sext<BitsExt>()) ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> le_uu(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY> { !b.template zext<BitsExt>().ucmp(a.template zext<BitsExt>()) ? 1u : 0u }; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> le_ss(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t BitsExt = max(BitsA, BitsB); return value<BitsY> { !b.template sext<BitsExt>().scmp(a.template sext<BitsExt>()) ? 1u : 0u }; @@ -1095,71 +1334,68 @@ value<BitsY> le_ss(const value<BitsA> &a, const value<BitsB> &b) { // Arithmetic operations template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> pos_u(const value<BitsA> &a) { return a.template zcast<BitsY>(); } template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> pos_s(const value<BitsA> &a) { return a.template scast<BitsY>(); } template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> neg_u(const value<BitsA> &a) { return a.template zcast<BitsY>().neg(); } template<size_t BitsY, size_t BitsA> +CXXRTL_ALWAYS_INLINE value<BitsY> neg_s(const value<BitsA> &a) { return a.template scast<BitsY>().neg(); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> add_uu(const value<BitsA> &a, const value<BitsB> &b) { return a.template zcast<BitsY>().add(b.template zcast<BitsY>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> add_ss(const value<BitsA> &a, const value<BitsB> &b) { return a.template scast<BitsY>().add(b.template scast<BitsY>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> sub_uu(const value<BitsA> &a, const value<BitsB> &b) { return a.template zcast<BitsY>().sub(b.template zcast<BitsY>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> sub_ss(const value<BitsA> &a, const value<BitsB> &b) { return a.template scast<BitsY>().sub(b.template scast<BitsY>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> mul_uu(const value<BitsA> &a, const value<BitsB> &b) { - value<BitsY> product; - value<BitsY> multiplicand = a.template zcast<BitsY>(); - const value<BitsB> &multiplier = b; - uint32_t multiplicand_shift = 0; - for (size_t step = 0; step < BitsB; step++) { - if (multiplier.bit(step)) { - multiplicand = multiplicand.shl(value<32> { multiplicand_shift }); - product = product.add(multiplicand); - multiplicand_shift = 0; - } - multiplicand_shift++; - } - return product; + constexpr size_t BitsM = BitsA >= BitsB ? BitsA : BitsB; + return a.template zcast<BitsM>().template mul<BitsY>(b.template zcast<BitsM>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> mul_ss(const value<BitsA> &a, const value<BitsB> &b) { - value<BitsB + 1> ub = b.template sext<BitsB + 1>(); - if (ub.is_neg()) ub = ub.neg(); - value<BitsY> y = mul_uu<BitsY>(a.template scast<BitsY>(), ub); - return b.is_neg() ? y.neg() : y; + return a.template scast<BitsY>().template mul<BitsY>(b.template scast<BitsY>()); } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE std::pair<value<BitsY>, value<BitsY>> divmod_uu(const value<BitsA> &a, const value<BitsB> &b) { constexpr size_t Bits = max(BitsY, max(BitsA, BitsB)); value<Bits> quotient; @@ -1181,6 +1417,7 @@ std::pair<value<BitsY>, value<BitsY>> divmod_uu(const value<BitsA> &a, const val } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE std::pair<value<BitsY>, value<BitsY>> divmod_ss(const value<BitsA> &a, const value<BitsB> &b) { value<BitsA + 1> ua = a.template sext<BitsA + 1>(); value<BitsB + 1> ub = b.template sext<BitsB + 1>(); @@ -1194,21 +1431,25 @@ std::pair<value<BitsY>, value<BitsY>> divmod_ss(const value<BitsA> &a, const val } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> div_uu(const value<BitsA> &a, const value<BitsB> &b) { return divmod_uu<BitsY>(a, b).first; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> div_ss(const value<BitsA> &a, const value<BitsB> &b) { return divmod_ss<BitsY>(a, b).first; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> mod_uu(const value<BitsA> &a, const value<BitsB> &b) { return divmod_uu<BitsY>(a, b).second; } template<size_t BitsY, size_t BitsA, size_t BitsB> +CXXRTL_ALWAYS_INLINE value<BitsY> mod_ss(const value<BitsA> &a, const value<BitsB> &b) { return divmod_ss<BitsY>(a, b).second; } diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 4c04a2f14..a48ea5b23 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -22,6 +22,7 @@ #include "kernel/sigtools.h" #include "kernel/utils.h" #include "kernel/celltypes.h" +#include "kernel/mem.h" #include "kernel/log.h" USING_YOSYS_NAMESPACE @@ -171,11 +172,6 @@ struct Scheduler { } }; -bool is_input_wire(const RTLIL::Wire *wire) -{ - return wire->port_input && !wire->port_output; -} - bool is_unary_cell(RTLIL::IdString type) { return type.in( @@ -202,19 +198,15 @@ bool is_extending_cell(RTLIL::IdString type) bool is_elidable_cell(RTLIL::IdString type) { return is_unary_cell(type) || is_binary_cell(type) || type.in( - ID($mux), ID($concat), ID($slice)); -} - -bool is_sync_ff_cell(RTLIL::IdString type) -{ - return type.in( - ID($dff), ID($dffe)); + ID($mux), ID($concat), ID($slice), ID($pmux)); } bool is_ff_cell(RTLIL::IdString type) { - return is_sync_ff_cell(type) || type.in( - ID($adff), ID($dffsr), ID($dlatch), ID($dlatchsr), ID($sr)); + return type.in( + ID($dff), ID($dffe), ID($sdff), ID($sdffe), ID($sdffce), + ID($adff), ID($adffe), ID($dffsr), ID($dffsre), + ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr)); } bool is_internal_cell(RTLIL::IdString type) @@ -282,6 +274,7 @@ struct FlowGraph { std::vector<Node*> nodes; dict<const RTLIL::Wire*, pool<Node*, hash_ptr_ops>> wire_comb_defs, wire_sync_defs, wire_uses; dict<const RTLIL::Wire*, bool> wire_def_elidable, wire_use_elidable; + dict<RTLIL::SigBit, bool> bit_has_state; ~FlowGraph() { @@ -289,17 +282,24 @@ struct FlowGraph { delete node; } - void add_defs(Node *node, const RTLIL::SigSpec &sig, bool fully_sync, bool elidable) + void add_defs(Node *node, const RTLIL::SigSpec &sig, bool is_ff, bool elidable) { for (auto chunk : sig.chunks()) if (chunk.wire) { - if (fully_sync) + if (is_ff) { + // A sync def means that a wire holds design state because it is driven directly by + // a flip-flop output. Such a wire can never be unbuffered. wire_sync_defs[chunk.wire].insert(node); - else + } else { + // A comb def means that a wire doesn't hold design state. It might still be connected, + // indirectly, to a flip-flop output. wire_comb_defs[chunk.wire].insert(node); + } } + for (auto bit : sig.bits()) + bit_has_state[bit] |= is_ff; // Only comb defs of an entire wire in the right order can be elided. - if (!fully_sync && sig.is_wire()) + if (!is_ff && sig.is_wire()) wire_def_elidable[sig.as_wire()] = elidable; } @@ -327,7 +327,7 @@ struct FlowGraph { // Connections void add_connect_defs_uses(Node *node, const RTLIL::SigSig &conn) { - add_defs(node, conn.first, /*fully_sync=*/false, /*elidable=*/true); + add_defs(node, conn.first, /*is_ff=*/false, /*elidable=*/true); add_uses(node, conn.second); } @@ -374,7 +374,7 @@ struct FlowGraph { if (cell->output(conn.first)) if (is_cxxrtl_sync_port(cell, conn.first)) { // See note regarding elidability below. - add_defs(node, conn.second, /*fully_sync=*/false, /*elidable=*/false); + add_defs(node, conn.second, /*is_ff=*/false, /*elidable=*/false); } } @@ -383,18 +383,18 @@ struct FlowGraph { for (auto conn : cell->connections()) { if (cell->output(conn.first)) { if (is_elidable_cell(cell->type)) - add_defs(node, conn.second, /*fully_sync=*/false, /*elidable=*/true); - else if (is_sync_ff_cell(cell->type) || (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool())) - add_defs(node, conn.second, /*fully_sync=*/true, /*elidable=*/false); + add_defs(node, conn.second, /*is_ff=*/false, /*elidable=*/true); + else if (is_ff_cell(cell->type) || (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool())) + add_defs(node, conn.second, /*is_ff=*/true, /*elidable=*/false); else if (is_internal_cell(cell->type)) - add_defs(node, conn.second, /*fully_sync=*/false, /*elidable=*/false); + add_defs(node, conn.second, /*is_ff=*/false, /*elidable=*/false); else if (!is_cxxrtl_sync_port(cell, conn.first)) { // Although at first it looks like outputs of user-defined cells may always be elided, the reality is // more complex. Fully sync outputs produce no defs and so don't participate in elision. Fully comb // outputs are assigned in a different way depending on whether the cell's eval() immediately converged. // Unknown/mixed outputs could be elided, but should be rare in practical designs and don't justify // the infrastructure required to elide outputs of cells with many of them. - add_defs(node, conn.second, /*fully_sync=*/false, /*elidable=*/false); + add_defs(node, conn.second, /*is_ff=*/false, /*elidable=*/false); } } if (cell->input(conn.first)) @@ -432,7 +432,7 @@ struct FlowGraph { void add_case_defs_uses(Node *node, const RTLIL::CaseRule *case_) { for (auto &action : case_->actions) { - add_defs(node, action.first, /*is_sync=*/false, /*elidable=*/false); + add_defs(node, action.first, /*is_ff=*/false, /*elidable=*/false); add_uses(node, action.second); } for (auto sub_switch : case_->switches) { @@ -451,9 +451,9 @@ struct FlowGraph { for (auto sync : process->syncs) for (auto action : sync->actions) { if (sync->type == RTLIL::STp || sync->type == RTLIL::STn || sync->type == RTLIL::STe) - add_defs(node, action.first, /*is_sync=*/true, /*elidable=*/false); + add_defs(node, action.first, /*is_ff=*/true, /*elidable=*/false); else - add_defs(node, action.first, /*is_sync=*/false, /*elidable=*/false); + add_defs(node, action.first, /*is_ff=*/false, /*elidable=*/false); add_uses(node, action.second); } } @@ -527,12 +527,16 @@ struct CxxrtlWorker { std::ostream *impl_f = nullptr; std::ostream *intf_f = nullptr; - bool elide_internal = false; - bool elide_public = false; + bool run_hierarchy = false; + bool run_flatten = false; + bool run_proc = false; + + bool unbuffer_internal = false; + bool unbuffer_public = false; bool localize_internal = false; bool localize_public = false; - bool run_proc_flatten = false; - bool max_opt_level = false; + bool elide_internal = false; + bool elide_public = false; bool debug_info = false; @@ -547,9 +551,11 @@ struct CxxrtlWorker { dict<const RTLIL::Cell*, pool<const RTLIL::Cell*>> transparent_for; dict<const RTLIL::Wire*, FlowGraph::Node> elided_wires; dict<const RTLIL::Module*, std::vector<FlowGraph::Node>> schedule; + pool<const RTLIL::Wire*> unbuffered_wires; pool<const RTLIL::Wire*> localized_wires; dict<const RTLIL::Wire*, const RTLIL::Wire*> debug_alias_wires; dict<const RTLIL::Wire*, RTLIL::Const> debug_const_wires; + dict<RTLIL::SigBit, bool> bit_has_state; dict<const RTLIL::Module*, pool<std::string>> blackbox_specializations; dict<const RTLIL::Module*, bool> eval_converges; @@ -786,7 +792,8 @@ struct CxxrtlWorker { dump_const(chunk.data, chunk.width, chunk.offset); return false; } else { - if (!is_lhs && elided_wires.count(chunk.wire)) { + if (elided_wires.count(chunk.wire)) { + log_assert(!is_lhs); const FlowGraph::Node &node = elided_wires[chunk.wire]; switch (node.type) { case FlowGraph::Node::Type::CONNECT: @@ -799,7 +806,7 @@ struct CxxrtlWorker { default: log_assert(false); } - } else if (localized_wires[chunk.wire] || is_input_wire(chunk.wire)) { + } else if (unbuffered_wires[chunk.wire]) { f << mangle(chunk.wire); } else { f << mangle(chunk.wire) << (is_lhs ? ".next" : ".curr"); @@ -942,6 +949,21 @@ struct CxxrtlWorker { f << " : "; dump_sigspec_rhs(cell->getPort(ID::A)); f << ")"; + // Parallel (one-hot) muxes + } else if (cell->type == ID($pmux)) { + int width = cell->getParam(ID::WIDTH).as_int(); + int s_width = cell->getParam(ID::S_WIDTH).as_int(); + for (int part = 0; part < s_width; part++) { + f << "("; + dump_sigspec_rhs(cell->getPort(ID::S).extract(part)); + f << " ? "; + dump_sigspec_rhs(cell->getPort(ID::B).extract(part * width, width)); + f << " : "; + } + dump_sigspec_rhs(cell->getPort(ID::A)); + for (int part = 0; part < s_width; part++) { + f << ")"; + } // Concats } else if (cell->type == ID($concat)) { dump_sigspec_rhs(cell->getPort(ID::B)); @@ -1008,35 +1030,6 @@ struct CxxrtlWorker { f << " = "; dump_cell_elided(cell); f << ";\n"; - // Parallel (one-hot) muxes - } else if (cell->type == ID($pmux)) { - int width = cell->getParam(ID::WIDTH).as_int(); - int s_width = cell->getParam(ID::S_WIDTH).as_int(); - bool first = true; - for (int part = 0; part < s_width; part++) { - f << (first ? indent : " else "); - first = false; - f << "if ("; - dump_sigspec_rhs(cell->getPort(ID::S).extract(part)); - f << ") {\n"; - inc_indent(); - f << indent; - dump_sigspec_lhs(cell->getPort(ID::Y)); - f << " = "; - dump_sigspec_rhs(cell->getPort(ID::B).extract(part * width, width)); - f << ";\n"; - dec_indent(); - f << indent << "}"; - } - f << " else {\n"; - inc_indent(); - f << indent; - dump_sigspec_lhs(cell->getPort(ID::Y)); - f << " = "; - dump_sigspec_rhs(cell->getPort(ID::A)); - f << ";\n"; - dec_indent(); - f << indent << "}\n"; // Flip-flops } else if (is_ff_cell(cell->type)) { if (cell->hasPort(ID::CLK) && cell->getPort(ID::CLK).is_wire()) { @@ -1046,7 +1039,7 @@ struct CxxrtlWorker { f << indent << "if (" << (cell->getParam(ID::CLK_POLARITY).as_bool() ? "posedge_" : "negedge_") << mangle(clk_bit) << ") {\n"; inc_indent(); - if (cell->type == ID($dffe)) { + if (cell->hasPort(ID::EN)) { f << indent << "if ("; dump_sigspec_rhs(cell->getPort(ID::EN)); f << " == value<1> {" << cell->getParam(ID::EN_POLARITY).as_bool() << "u}) {\n"; @@ -1057,7 +1050,24 @@ struct CxxrtlWorker { f << " = "; dump_sigspec_rhs(cell->getPort(ID::D)); f << ";\n"; - if (cell->type == ID($dffe)) { + if (cell->hasPort(ID::EN) && cell->type != ID($sdffce)) { + dec_indent(); + f << indent << "}\n"; + } + if (cell->hasPort(ID::SRST)) { + f << indent << "if ("; + dump_sigspec_rhs(cell->getPort(ID::SRST)); + f << " == value<1> {" << cell->getParam(ID::SRST_POLARITY).as_bool() << "u}) {\n"; + inc_indent(); + f << indent; + dump_sigspec_lhs(cell->getPort(ID::Q)); + f << " = "; + dump_const(cell->getParam(ID::SRST_VALUE)); + f << ";\n"; + dec_indent(); + f << indent << "}\n"; + } + if (cell->hasPort(ID::EN) && cell->type == ID($sdffce)) { dec_indent(); f << indent << "}\n"; } @@ -1139,7 +1149,7 @@ struct CxxrtlWorker { } // The generated code has two bounds checks; one in an assertion, and another that guards the read. // This is done so that the code does not invoke undefined behavior under any conditions, but nevertheless - // loudly crashes if an illegal condition is encountered. The assert may be turned off with -NDEBUG not + // loudly crashes if an illegal condition is encountered. The assert may be turned off with -DNDEBUG not // just for release builds, but also to make sure the simulator (which is presumably embedded in some // larger program) will never crash the code that calls into it. // @@ -1148,31 +1158,33 @@ struct CxxrtlWorker { f << indent << "if(" << valid_index_temp << ".valid) {\n"; inc_indent(); if (writable_memories[memory]) { - std::string addr_temp = fresh_temporary(); - f << indent << "const value<" << cell->getPort(ID::ADDR).size() << "> &" << addr_temp << " = "; - dump_sigspec_rhs(cell->getPort(ID::ADDR)); - f << ";\n"; std::string lhs_temp = fresh_temporary(); f << indent << "value<" << memory->width << "> " << lhs_temp << " = " << mangle(memory) << "[" << valid_index_temp << ".index];\n"; std::vector<const RTLIL::Cell*> memwr_cells(transparent_for[cell].begin(), transparent_for[cell].end()); - std::sort(memwr_cells.begin(), memwr_cells.end(), - [](const RTLIL::Cell *a, const RTLIL::Cell *b) { - return a->getParam(ID::PRIORITY).as_int() < b->getParam(ID::PRIORITY).as_int(); - }); - for (auto memwr_cell : memwr_cells) { - f << indent << "if (" << addr_temp << " == "; - dump_sigspec_rhs(memwr_cell->getPort(ID::ADDR)); - f << ") {\n"; - inc_indent(); - f << indent << lhs_temp << " = " << lhs_temp; - f << ".update("; - dump_sigspec_rhs(memwr_cell->getPort(ID::DATA)); - f << ", "; - dump_sigspec_rhs(memwr_cell->getPort(ID::EN)); - f << ");\n"; - dec_indent(); - f << indent << "}\n"; + if (!memwr_cells.empty()) { + std::string addr_temp = fresh_temporary(); + f << indent << "const value<" << cell->getPort(ID::ADDR).size() << "> &" << addr_temp << " = "; + dump_sigspec_rhs(cell->getPort(ID::ADDR)); + f << ";\n"; + std::sort(memwr_cells.begin(), memwr_cells.end(), + [](const RTLIL::Cell *a, const RTLIL::Cell *b) { + return a->getParam(ID::PRIORITY).as_int() < b->getParam(ID::PRIORITY).as_int(); + }); + for (auto memwr_cell : memwr_cells) { + f << indent << "if (" << addr_temp << " == "; + dump_sigspec_rhs(memwr_cell->getPort(ID::ADDR)); + f << ") {\n"; + inc_indent(); + f << indent << lhs_temp << " = " << lhs_temp; + f << ".update("; + dump_sigspec_rhs(memwr_cell->getPort(ID::DATA)); + f << ", "; + dump_sigspec_rhs(memwr_cell->getPort(ID::EN)); + f << ");\n"; + dec_indent(); + f << indent << "}\n"; + } } f << indent; dump_sigspec_lhs(cell->getPort(ID::DATA)); @@ -1434,13 +1446,12 @@ struct CxxrtlWorker { { if (elided_wires.count(wire)) return; - if (localized_wires.count(wire) != is_local_context) - return; - if (is_local_context) { + if (localized_wires[wire] && is_local_context) { dump_attrs(wire); f << indent << "value<" << wire->width << "> " << mangle(wire) << ";\n"; - } else { + } + if (!localized_wires[wire] && !is_local_context) { std::string width; if (wire->module->has_attribute(ID(cxxrtl_blackbox)) && wire->has_attribute(ID(cxxrtl_width))) { width = wire->get_string_attribute(ID(cxxrtl_width)); @@ -1449,14 +1460,21 @@ struct CxxrtlWorker { } dump_attrs(wire); - f << indent << (is_input_wire(wire) ? "value" : "wire") << "<" << width << "> " << mangle(wire); + f << indent; + if (wire->port_input && wire->port_output) + f << "/*inout*/ "; + else if (wire->port_input) + f << "/*input*/ "; + else if (wire->port_output) + f << "/*output*/ "; + f << (unbuffered_wires[wire] ? "value" : "wire") << "<" << width << "> " << mangle(wire); if (wire->has_attribute(ID::init)) { f << " "; dump_const_init(wire->attributes.at(ID::init)); } f << ";\n"; if (edge_wires[wire]) { - if (is_input_wire(wire)) { + if (unbuffered_wires[wire]) { f << indent << "value<" << width << "> prev_" << mangle(wire); if (wire->has_attribute(ID::init)) { f << " "; @@ -1467,7 +1485,7 @@ struct CxxrtlWorker { for (auto edge_type : edge_types) { if (edge_type.first.wire == wire) { std::string prev, next; - if (is_input_wire(wire)) { + if (unbuffered_wires[wire]) { prev = "prev_" + mangle(edge_type.first.wire); next = mangle(edge_type.first.wire); } else { @@ -1590,9 +1608,9 @@ struct CxxrtlWorker { inc_indent(); f << indent << "bool changed = false;\n"; for (auto wire : module->wires()) { - if (elided_wires.count(wire) || localized_wires.count(wire)) + if (elided_wires.count(wire)) continue; - if (is_input_wire(wire)) { + if (unbuffered_wires[wire]) { if (edge_wires[wire]) f << indent << "prev_" << mangle(wire) << " = " << mangle(wire) << ";\n"; continue; @@ -1619,57 +1637,122 @@ struct CxxrtlWorker { void dump_debug_info_method(RTLIL::Module *module) { + size_t count_public_wires = 0; size_t count_const_wires = 0; size_t count_alias_wires = 0; size_t count_member_wires = 0; size_t count_skipped_wires = 0; + size_t count_driven_sync = 0; + size_t count_driven_comb = 0; + size_t count_undriven = 0; + size_t count_mixed_driver = 0; inc_indent(); f << indent << "assert(path.empty() || path[path.size() - 1] == ' ');\n"; for (auto wire : module->wires()) { if (wire->name[0] != '\\') continue; + if (module->get_bool_attribute(ID(cxxrtl_blackbox)) && (wire->port_id == 0)) + continue; + count_public_wires++; if (debug_const_wires.count(wire)) { // Wire tied to a constant f << indent << "static const value<" << wire->width << "> const_" << mangle(wire) << " = "; dump_const(debug_const_wires[wire]); f << ";\n"; - f << indent << "items.emplace(path + " << escape_cxx_string(get_hdl_name(wire)); - f << ", debug_item(const_" << mangle(wire) << "));\n"; + f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); + f << ", debug_item(const_" << mangle(wire) << ", "; + f << wire->start_offset << "));\n"; count_const_wires++; } else if (debug_alias_wires.count(wire)) { // Alias of a member wire - f << indent << "items.emplace(path + " << escape_cxx_string(get_hdl_name(wire)); - f << ", debug_item(" << mangle(debug_alias_wires[wire]) << "));\n"; + f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); + f << ", debug_item(debug_alias(), " << mangle(debug_alias_wires[wire]) << ", "; + f << wire->start_offset << "));\n"; count_alias_wires++; } else if (!localized_wires.count(wire)) { // Member wire - f << indent << "items.emplace(path + " << escape_cxx_string(get_hdl_name(wire)); - f << ", debug_item(" << mangle(wire) << "));\n"; + std::vector<std::string> flags; + + if (wire->port_input && wire->port_output) + flags.push_back("INOUT"); + else if (wire->port_input) + flags.push_back("INPUT"); + else if (wire->port_output) + flags.push_back("OUTPUT"); + + bool has_driven_sync = false; + bool has_driven_comb = false; + bool has_undriven = false; + SigSpec sig(wire); + for (auto bit : sig.bits()) + if (!bit_has_state.count(bit)) + has_undriven = true; + else if (bit_has_state[bit]) + has_driven_sync = true; + else + has_driven_comb = true; + if (has_driven_sync) + flags.push_back("DRIVEN_SYNC"); + if (has_driven_sync && !has_driven_comb && !has_undriven) + count_driven_sync++; + if (has_driven_comb) + flags.push_back("DRIVEN_COMB"); + if (!has_driven_sync && has_driven_comb && !has_undriven) + count_driven_comb++; + if (has_undriven) + flags.push_back("UNDRIVEN"); + if (!has_driven_sync && !has_driven_comb && has_undriven) + count_undriven++; + if (has_driven_sync + has_driven_comb + has_undriven > 1) + count_mixed_driver++; + + f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire)); + f << ", debug_item(" << mangle(wire) << ", "; + f << wire->start_offset; + bool first = true; + for (auto flag : flags) { + if (first) { + first = false; + f << ", "; + } else { + f << "|"; + } + f << "debug_item::" << flag; + } + f << "));\n"; count_member_wires++; } else { count_skipped_wires++; } } - for (auto &memory_it : module->memories) { - if (memory_it.first[0] != '\\') - continue; - f << indent << "items.emplace(path + " << escape_cxx_string(get_hdl_name(memory_it.second)); - f << ", debug_item(" << mangle(memory_it.second) << "));\n"; - } - for (auto cell : module->cells()) { - if (is_internal_cell(cell->type)) - continue; - const char *access = is_cxxrtl_blackbox_cell(cell) ? "->" : "."; - f << indent << mangle(cell) << access << "debug_info(items, "; - f << "path + " << escape_cxx_string(get_hdl_name(cell) + ' ') << ");\n"; + if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { + for (auto &memory_it : module->memories) { + if (memory_it.first[0] != '\\') + continue; + f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(memory_it.second)); + f << ", debug_item(" << mangle(memory_it.second) << ", "; + f << memory_it.second->start_offset << "));\n"; + } + for (auto cell : module->cells()) { + if (is_internal_cell(cell->type)) + continue; + const char *access = is_cxxrtl_blackbox_cell(cell) ? "->" : "."; + f << indent << mangle(cell) << access << "debug_info(items, "; + f << "path + " << escape_cxx_string(get_hdl_name(cell) + ' ') << ");\n"; + } } dec_indent(); - log_debug("Debug information statistics for module %s:\n", log_id(module)); - log_debug(" Const wires: %zu\n", count_const_wires); - log_debug(" Alias wires: %zu\n", count_alias_wires); - log_debug(" Member wires: %zu\n", count_member_wires); - log_debug(" Other wires: %zu (no debug information)\n", count_skipped_wires); + log_debug("Debug information statistics for module `%s':\n", log_id(module)); + log_debug(" Public wires: %zu, of which:\n", count_public_wires); + log_debug(" Const wires: %zu\n", count_const_wires); + log_debug(" Alias wires: %zu\n", count_alias_wires); + log_debug(" Member wires: %zu, of which:\n", count_member_wires); + log_debug(" Driven sync: %zu\n", count_driven_sync); + log_debug(" Driven comb: %zu\n", count_driven_comb); + log_debug(" Undriven: %zu\n", count_undriven); + log_debug(" Mixed driver: %zu\n", count_mixed_driver); + log_debug(" Other wires: %zu (no debug information)\n", count_skipped_wires); } void dump_metadata_map(const dict<RTLIL::IdString, RTLIL::Const> &metadata_map) @@ -1840,7 +1923,8 @@ struct CxxrtlWorker { topo_design.edge(cell_module, module); } } - log_assert(topo_design.sort()); + bool no_loops = topo_design.sort(); + log_assert(no_loops); modules.insert(modules.end(), topo_design.sorted.begin(), topo_design.sorted.end()); if (split_intf) { @@ -1912,10 +1996,12 @@ struct CxxrtlWorker { f << "} // namespace " << design_ns << "\n"; f << "\n"; if (top_module != nullptr && debug_info) { + f << "extern \"C\"\n"; f << "cxxrtl_toplevel " << design_ns << "_create() {\n"; inc_indent(); + std::string top_type = design_ns + "::" + mangle(top_module); f << indent << "return new _cxxrtl_toplevel { "; - f << "std::make_unique<" << design_ns << "::" << mangle(top_module) << ">()"; + f << "std::unique_ptr<" << top_type << ">(new " + top_type + ")"; f << " };\n"; dec_indent(); f << "}\n"; @@ -1949,7 +2035,7 @@ struct CxxrtlWorker { void analyze_design(RTLIL::Design *design) { bool has_feedback_arcs = false; - bool has_buffered_wires = false; + bool has_buffered_comb_wires = false; for (auto module : design->modules()) { if (!design->selected_module(module)) @@ -1961,6 +2047,8 @@ struct CxxrtlWorker { if (module->get_bool_attribute(ID(cxxrtl_blackbox))) { for (auto port : module->ports) { RTLIL::Wire *wire = module->wire(port); + if (wire->port_input && !wire->port_output) + unbuffered_wires.insert(wire); if (wire->has_attribute(ID(cxxrtl_edge))) { RTLIL::Const edge_attr = wire->attributes[ID(cxxrtl_edge)]; if (!(edge_attr.flags & RTLIL::CONST_FLAG_STRING) || (int)edge_attr.decode_string().size() != GetSize(wire)) @@ -2016,7 +2104,7 @@ struct CxxrtlWorker { FlowGraph::Node *node = flow.add_node(cell); // Various DFF cells are treated like posedge/negedge processes, see above for details. - if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($dffsr))) { + if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($dffsr), ID($dffsre), ID($sdff), ID($sdffe), ID($sdffce))) { if (cell->getPort(ID::CLK).is_wire()) register_edge_signal(sigmap, cell->getPort(ID::CLK), cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); @@ -2096,6 +2184,8 @@ struct CxxrtlWorker { if (wire->name.begins_with("$") && !elide_internal) continue; if (wire->name.begins_with("\\") && !elide_public) continue; if (edge_wires[wire]) continue; + if (flow.wire_comb_defs[wire].size() > 1) + log_cmd_error("Wire %s.%s has multiple drivers.\n", log_id(module), log_id(wire)); log_assert(flow.wire_comb_defs[wire].size() == 1); elided_wires[wire] = **flow.wire_comb_defs[wire].begin(); } @@ -2145,17 +2235,20 @@ struct CxxrtlWorker { log("Module `%s' contains feedback arcs through wires:\n", log_id(module)); for (auto wire : feedback_wires) log(" %s\n", log_id(wire)); - log("\n"); } for (auto wire : module->wires()) { if (feedback_wires[wire]) continue; - if (wire->port_id != 0) continue; + if (wire->port_output && !module->get_bool_attribute(ID::top)) continue; + if (wire->name.begins_with("$") && !unbuffer_internal) continue; + if (wire->name.begins_with("\\") && !unbuffer_public) continue; + if (flow.wire_sync_defs.count(wire) > 0) continue; + unbuffered_wires.insert(wire); + if (edge_wires[wire]) continue; if (wire->get_bool_attribute(ID::keep)) continue; + if (wire->port_input || wire->port_output) continue; if (wire->name.begins_with("$") && !localize_internal) continue; if (wire->name.begins_with("\\") && !localize_public) continue; - if (edge_wires[wire]) continue; - if (flow.wire_sync_defs.count(wire) > 0) continue; localized_wires.insert(wire); } @@ -2165,22 +2258,22 @@ struct CxxrtlWorker { // it is possible that a design with no feedback arcs would end up with doubly buffered wires in such cases // as a wire with multiple drivers where one of them is combinatorial and the other is synchronous. Such designs // also require more than one delta cycle to converge. - pool<const RTLIL::Wire*> buffered_wires; + pool<const RTLIL::Wire*> buffered_comb_wires; for (auto wire : module->wires()) { - if (flow.wire_comb_defs[wire].size() > 0 && !elided_wires.count(wire) && !localized_wires[wire]) { - if (!feedback_wires[wire]) - buffered_wires.insert(wire); - } + if (flow.wire_comb_defs[wire].size() > 0 && !unbuffered_wires[wire] && !feedback_wires[wire]) + buffered_comb_wires.insert(wire); } - if (!buffered_wires.empty()) { - has_buffered_wires = true; + if (!buffered_comb_wires.empty()) { + has_buffered_comb_wires = true; log("Module `%s' contains buffered combinatorial wires:\n", log_id(module)); - for (auto wire : buffered_wires) + for (auto wire : buffered_comb_wires) log(" %s\n", log_id(wire)); - log("\n"); } - eval_converges[module] = feedback_wires.empty() && buffered_wires.empty(); + eval_converges[module] = feedback_wires.empty() && buffered_comb_wires.empty(); + + for (auto item : flow.bit_has_state) + bit_has_state.insert(item); if (debug_info) { // Find wires that alias other wires or are tied to a constant; debug information can be enriched with these @@ -2191,7 +2284,7 @@ struct CxxrtlWorker { for (auto wire : module->wires()) { if (wire->name[0] != '\\') continue; - if (!localized_wires[wire]) + if (!unbuffered_wires[wire]) continue; const RTLIL::Wire *wire_it = wire; while (1) { @@ -2204,7 +2297,7 @@ struct CxxrtlWorker { RTLIL::SigSpec rhs_sig = node->connect.second; if (rhs_sig.is_wire()) { RTLIL::Wire *rhs_wire = rhs_sig.as_wire(); - if (localized_wires[rhs_wire]) { + if (unbuffered_wires[rhs_wire]) { wire_it = rhs_wire; // maybe an alias } else { debug_alias_wires[wire] = rhs_wire; // is an alias @@ -2220,24 +2313,26 @@ struct CxxrtlWorker { } } } - if (has_feedback_arcs || has_buffered_wires) { + if (has_feedback_arcs || has_buffered_comb_wires) { // Although both non-feedback buffered combinatorial wires and apparent feedback wires may be eliminated // by optimizing the design, if after `proc; flatten` there are any feedback wires remaining, it is very // likely that these feedback wires are indicative of a true logic loop, so they get emphasized in the message. const char *why_pessimistic = nullptr; if (has_feedback_arcs) why_pessimistic = "feedback wires"; - else if (has_buffered_wires) + else if (has_buffered_comb_wires) why_pessimistic = "buffered combinatorial wires"; log_warning("Design contains %s, which require delta cycles during evaluation.\n", why_pessimistic); - if (!max_opt_level) - log("Increasing the optimization level may eliminate %s from the design.\n", why_pessimistic); + if (!run_flatten) + log("Flattening may eliminate %s from the design.\n", why_pessimistic); + if (!run_proc) + log("Converting processes to netlists may eliminate %s from the design.\n", why_pessimistic); } } - void check_design(RTLIL::Design *design, bool &has_sync_init, bool &has_packed_mem) + void check_design(RTLIL::Design *design, bool &has_top, bool &has_sync_init, bool &has_packed_mem) { - has_sync_init = has_packed_mem = false; + has_sync_init = has_packed_mem = has_top = false; for (auto module : design->modules()) { if (module->get_blackbox_attribute() && !module->has_attribute(ID(cxxrtl_blackbox))) @@ -2249,13 +2344,17 @@ struct CxxrtlWorker { if (!design->selected_module(module)) continue; + if (module->get_bool_attribute(ID::top)) + has_top = true; + for (auto proc : module->processes) for (auto sync : proc.second->syncs) if (sync->type == RTLIL::STi) has_sync_init = true; - for (auto cell : module->cells()) - if (cell->type == ID($mem)) + // The Mem constructor also checks for well-formedness of $meminit cells, if any. + for (auto &mem : Mem::get_all_memories(module)) + if (mem.packed) has_packed_mem = true; } } @@ -2263,13 +2362,20 @@ struct CxxrtlWorker { void prepare_design(RTLIL::Design *design) { bool did_anything = false; - bool has_sync_init, has_packed_mem; + bool has_top, has_sync_init, has_packed_mem; log_push(); - check_design(design, has_sync_init, has_packed_mem); - if (run_proc_flatten) { - Pass::call(design, "proc"); + check_design(design, has_top, has_sync_init, has_packed_mem); + if (run_hierarchy && !has_top) { + Pass::call(design, "hierarchy -auto-top"); + did_anything = true; + } + if (run_flatten) { Pass::call(design, "flatten"); did_anything = true; + } + if (run_proc) { + Pass::call(design, "proc"); + did_anything = true; } else if (has_sync_init) { // We're only interested in proc_init, but it depends on proc_prune and proc_clean, so call those // in case they weren't already. (This allows `yosys foo.v -o foo.cc` to work.) @@ -2283,9 +2389,9 @@ struct CxxrtlWorker { did_anything = true; } // Recheck the design if it was modified. - if (has_sync_init || has_packed_mem) - check_design(design, has_sync_init, has_packed_mem); - log_assert(!(has_sync_init || has_packed_mem)); + if (did_anything) + check_design(design, has_top, has_sync_init, has_packed_mem); + log_assert(has_top && !has_sync_init && !has_packed_mem); log_pop(); if (did_anything) log_spacer(); @@ -2294,11 +2400,12 @@ struct CxxrtlWorker { }; struct CxxrtlBackend : public Backend { - static const int DEFAULT_OPT_LEVEL = 5; + static const int DEFAULT_OPT_LEVEL = 6; + static const int OPT_LEVEL_DEBUG = 4; static const int DEFAULT_DEBUG_LEVEL = 1; CxxrtlBackend() : Backend("cxxrtl", "convert design to C++ RTL simulation") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -2317,9 +2424,9 @@ struct CxxrtlBackend : public Backend { log(" top.step();\n"); log(" while (1) {\n"); log(" /* user logic */\n"); - log(" top.p_clk = value<1> {0u};\n"); + log(" top.p_clk.set(false);\n"); log(" top.step();\n"); - log(" top.p_clk = value<1> {1u};\n"); + log(" top.p_clk.set(true);\n"); log(" top.step();\n"); log(" }\n"); log(" }\n"); @@ -2466,6 +2573,22 @@ struct CxxrtlBackend : public Backend { log(" place the generated code into namespace <ns-name>. if not specified,\n"); log(" \"cxxrtl_design\" is used.\n"); log("\n"); + log(" -nohierarchy\n"); + log(" use design hierarchy as-is. in most designs, a top module should be\n"); + log(" present as it is exposed through the C API and has unbuffered outputs\n"); + log(" for improved performance; it will be determined automatically if absent.\n"); + log("\n"); + log(" -noflatten\n"); + log(" don't flatten the design. fully flattened designs can evaluate within\n"); + log(" one delta cycle if they have no combinatorial feedback.\n"); + log(" note that the debug interface and waveform dumps use full hierarchical\n"); + log(" names for all wires even in flattened designs.\n"); + log("\n"); + log(" -noproc\n"); + log(" don't convert processes to netlists. in most designs, converting\n"); + log(" processes significantly improves evaluation performance at the cost of\n"); + log(" slight increase in compilation time.\n"); + log("\n"); log(" -O <level>\n"); log(" set the optimization level. the default is -O%d. higher optimization\n", DEFAULT_OPT_LEVEL); log(" levels dramatically decrease compile and run time, and highest level\n"); @@ -2475,19 +2598,26 @@ struct CxxrtlBackend : public Backend { log(" no optimization.\n"); log("\n"); log(" -O1\n"); - log(" elide internal wires if possible.\n"); + log(" localize internal wires if possible.\n"); log("\n"); log(" -O2\n"); - log(" like -O1, and localize internal wires if possible.\n"); + log(" like -O1, and unbuffer internal wires if possible.\n"); log("\n"); log(" -O3\n"); - log(" like -O2, and elide public wires not marked (*keep*) if possible.\n"); + log(" like -O2, and elide internal wires if possible.\n"); log("\n"); log(" -O4\n"); - log(" like -O3, and localize public wires not marked (*keep*) if possible.\n"); + log(" like -O3, and unbuffer public wires not marked (*keep*) if possible.\n"); log("\n"); log(" -O5\n"); - log(" like -O4, and run `proc; flatten` first.\n"); + log(" like -O4, and localize public wires not marked (*keep*) if possible.\n"); + log("\n"); + log(" -O6\n"); + log(" like -O5, and elide public wires not marked (*keep*) if possible.\n"); + log("\n"); + log(" -Og\n"); + log(" highest optimization level that provides debug information for all\n"); + log(" public wires. currently, alias for -O%d.\n", OPT_LEVEL_DEBUG); log("\n"); log(" -g <level>\n"); log(" set the debug level. the default is -g%d. higher debug levels provide\n", DEFAULT_DEBUG_LEVEL); @@ -2502,8 +2632,11 @@ struct CxxrtlBackend : public Backend { log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { + bool nohierarchy = false; + bool noflatten = false; + bool noproc = false; int opt_level = DEFAULT_OPT_LEVEL; int debug_level = DEFAULT_DEBUG_LEVEL; CxxrtlWorker worker; @@ -2513,6 +2646,27 @@ struct CxxrtlBackend : public Backend { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-nohierarchy") { + nohierarchy = true; + continue; + } + if (args[argidx] == "-noflatten") { + noflatten = true; + continue; + } + if (args[argidx] == "-noproc") { + noproc = true; + continue; + } + if (args[argidx] == "-Og") { + opt_level = OPT_LEVEL_DEBUG; + continue; + } + if (args[argidx] == "-O" && argidx+1 < args.size() && args[argidx+1] == "g") { + argidx++; + opt_level = OPT_LEVEL_DEBUG; + continue; + } if (args[argidx] == "-O" && argidx+1 < args.size()) { opt_level = std::stoi(args[++argidx]); continue; @@ -2541,30 +2695,34 @@ struct CxxrtlBackend : public Backend { } extra_args(f, filename, args, argidx); + worker.run_hierarchy = !nohierarchy; + worker.run_flatten = !noflatten; + worker.run_proc = !noproc; switch (opt_level) { // the highest level here must match DEFAULT_OPT_LEVEL + case 6: + worker.elide_public = true; + YS_FALLTHROUGH case 5: - worker.max_opt_level = true; - worker.run_proc_flatten = true; + worker.localize_public = true; YS_FALLTHROUGH case 4: - worker.localize_public = true; + worker.unbuffer_public = true; YS_FALLTHROUGH case 3: - worker.elide_public = true; + worker.elide_internal = true; YS_FALLTHROUGH case 2: worker.localize_internal = true; YS_FALLTHROUGH case 1: - worker.elide_internal = true; + worker.unbuffer_internal = true; YS_FALLTHROUGH case 0: break; default: log_cmd_error("Invalid optimization level %d.\n", opt_level); } - switch (debug_level) { // the highest level here must match DEFAULT_DEBUG_LEVEL case 1: diff --git a/backends/cxxrtl/cxxrtl_capi.cc b/backends/cxxrtl/cxxrtl_capi.cc index 489d72da5..b77e4c491 100644 --- a/backends/cxxrtl/cxxrtl_capi.cc +++ b/backends/cxxrtl/cxxrtl_capi.cc @@ -43,18 +43,29 @@ void cxxrtl_destroy(cxxrtl_handle handle) { delete handle; } +int cxxrtl_eval(cxxrtl_handle handle) { + return handle->module->eval(); +} + +int cxxrtl_commit(cxxrtl_handle handle) { + return handle->module->commit(); +} + size_t cxxrtl_step(cxxrtl_handle handle) { return handle->module->step(); } -cxxrtl_object *cxxrtl_get(cxxrtl_handle handle, const char *name) { - if (handle->objects.count(name) > 0) - return static_cast<cxxrtl_object*>(&handle->objects.at(name)); - return nullptr; +struct cxxrtl_object *cxxrtl_get_parts(cxxrtl_handle handle, const char *name, size_t *parts) { + auto it = handle->objects.table.find(name); + if (it == handle->objects.table.end()) + return nullptr; + *parts = it->second.size(); + return static_cast<cxxrtl_object*>(&it->second[0]); } void cxxrtl_enum(cxxrtl_handle handle, void *data, - void (*callback)(void *data, const char *name, cxxrtl_object *object)) { - for (auto &it : handle->objects) - callback(data, it.first.c_str(), static_cast<cxxrtl_object*>(&it.second)); + void (*callback)(void *data, const char *name, + cxxrtl_object *object, size_t parts)) { + for (auto &it : handle->objects.table) + callback(data, it.first.c_str(), static_cast<cxxrtl_object*>(&it.second[0]), it.second.size()); } diff --git a/backends/cxxrtl/cxxrtl_capi.h b/backends/cxxrtl/cxxrtl_capi.h index 46aa662b2..385d6dcf3 100644 --- a/backends/cxxrtl/cxxrtl_capi.h +++ b/backends/cxxrtl/cxxrtl_capi.h @@ -26,6 +26,7 @@ #include <stddef.h> #include <stdint.h> +#include <assert.h> #ifdef __cplusplus extern "C" { @@ -54,12 +55,28 @@ cxxrtl_handle cxxrtl_create(cxxrtl_toplevel design); // Release all resources used by a design and its handle. void cxxrtl_destroy(cxxrtl_handle handle); +// Evaluate the design, propagating changes on inputs to the `next` value of internal state and +// output wires. +// +// Returns 1 if the design is known to immediately converge, 0 otherwise. +int cxxrtl_eval(cxxrtl_handle handle); + +// Commit the design, replacing the `curr` value of internal state and output wires with the `next` +// value. +// +// Return 1 if any of the `curr` values were updated, 0 otherwise. +int cxxrtl_commit(cxxrtl_handle handle); + // Simulate the design to a fixed point. // // Returns the number of delta cycles. size_t cxxrtl_step(cxxrtl_handle handle); // Type of a simulated object. +// +// The type of a simulated object indicates the way it is stored and the operations that are legal +// to perform on it (i.e. won't crash the simulation). It says very little about object semantics, +// which is specified through flags. enum cxxrtl_type { // Values correspond to singly buffered netlist nodes, i.e. nodes driven exclusively by // combinatorial cells, or toplevel input nodes. @@ -73,7 +90,8 @@ enum cxxrtl_type { CXXRTL_VALUE = 0, // Wires correspond to doubly buffered netlist nodes, i.e. nodes driven, at least in part, by - // storage cells, or by combinatorial cells that are a part of a feedback path. + // storage cells, or by combinatorial cells that are a part of a feedback path. They are also + // present in non-optimized builds. // // Wires can be inspected via the `curr` pointer and modified via the `next` pointer (which are // distinct for wires). Note that changes to the bits driven by combinatorial cells will be @@ -89,7 +107,74 @@ enum cxxrtl_type { // always NULL. CXXRTL_MEMORY = 2, - // More object types will be added in the future, but the existing ones will never change. + // Aliases correspond to netlist nodes driven by another node such that their value is always + // exactly equal. + // + // Aliases can be inspected via the `curr` pointer. They cannot be modified, and the `next` + // pointer is always NULL. + CXXRTL_ALIAS = 3, + + // More object types may be added in the future, but the existing ones will never change. +}; + +// Flags of a simulated object. +// +// The flags of a simulated object indicate its role in the netlist: +// * The flags `CXXRTL_INPUT` and `CXXRTL_OUTPUT` designate module ports. +// * The flags `CXXRTL_DRIVEN_SYNC`, `CXXRTL_DRIVEN_COMB`, and `CXXRTL_UNDRIVEN` specify +// the semantics of node state. An object with several of these flags set has different bits +// follow different semantics. +enum cxxrtl_flag { + // Node is a module input port. + // + // This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined + // with `CXXRTL_OUTPUT`, as well as other flags. + CXXRTL_INPUT = 1 << 0, + + // Node is a module output port. + // + // This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with `CXXRTL_INPUT`, + // as well as other flags. + CXXRTL_OUTPUT = 1 << 1, + + // Node is a module inout port. + // + // This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with other flags. + CXXRTL_INOUT = (CXXRTL_INPUT|CXXRTL_OUTPUT), + + // Node has bits that are driven by a storage cell. + // + // This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with + // `CXXRTL_DRIVEN_COMB` and `CXXRTL_UNDRIVEN`, as well as other flags. + // + // This flag is set on wires that have bits connected directly to the output of a flip-flop or + // a latch, and hold its state. Many `CXXRTL_WIRE` objects may not have the `CXXRTL_DRIVEN_SYNC` + // flag set; for example, output ports and feedback wires generally won't. Writing to the `next` + // pointer of these wires updates stored state, and for designs without combinatorial loops, + // capturing the value from every of these wires through the `curr` pointer creates a complete + // snapshot of the design state. + CXXRTL_DRIVEN_SYNC = 1 << 2, + + // Node has bits that are driven by a combinatorial cell or another node. + // + // This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined + // with `CXXRTL_DRIVEN_SYNC` and `CXXRTL_UNDRIVEN`, as well as other flags. + // + // This flag is set on objects that have bits connected to the output of a combinatorial cell, + // or directly to another node. For designs without combinatorial loops, writing to such bits + // through the `next` pointer (if it is not NULL) has no effect. + CXXRTL_DRIVEN_COMB = 1 << 3, + + // Node has bits that are not driven. + // + // This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined + // with `CXXRTL_DRIVEN_SYNC` and `CXXRTL_DRIVEN_COMB`, as well as other flags. + // + // This flag is set on objects that have bits not driven by an output of any cell or by another + // node, such as inputs and dangling wires. + CXXRTL_UNDRIVEN = 1 << 4, + + // More object flags may be added in the future, but the existing ones will never change. }; // Description of a simulated object. @@ -103,12 +188,21 @@ struct cxxrtl_object { // determines all other properties of the object. uint32_t type; // actually `enum cxxrtl_type` + // Flags of the object. + uint32_t flags; // actually bit mask of `enum cxxrtl_flags` + // Width of the object in bits. size_t width; + // Index of the least significant bit. + size_t lsb_at; + // Depth of the object. Only meaningful for memories; for other objects, always 1. size_t depth; + // Index of the first word. Only meaningful for memories; for other objects, always 0; + size_t zero_at; + // Bits stored in the object, as 32-bit chunks, least significant bits first. // // The width is rounded up to a multiple of 32; the padding bits are always set to 0 by @@ -123,7 +217,7 @@ struct cxxrtl_object { uint32_t *curr; uint32_t *next; - // More description fields will be added in the future, but the existing ones will never change. + // More description fields may be added in the future, but the existing ones will never change. }; // Retrieve description of a simulated object. @@ -133,17 +227,36 @@ struct cxxrtl_object { // the top-level module instantiates a module `foo`, which in turn contains a wire `bar`, the full // hierarchical name is `\foo \bar`. // -// Returns the object if it was found, NULL otherwise. The returned value is valid until the design -// is destroyed. -struct cxxrtl_object *cxxrtl_get(cxxrtl_handle handle, const char *name); +// The storage of a single abstract object may be split (usually with the `splitnets` pass) into +// many physical parts, all of which correspond to the same hierarchical name. To handle such cases, +// this function returns an array and writes its length to `parts`. The array is sorted by `lsb_at`. +// +// Returns the object parts if it was found, NULL otherwise. The returned parts are valid until +// the design is destroyed. +struct cxxrtl_object *cxxrtl_get_parts(cxxrtl_handle handle, const char *name, size_t *parts); + +// Retrieve description of a single part simulated object. +// +// This function is a shortcut for the most common use of `cxxrtl_get_parts`. It asserts that, +// if the object exists, it consists of a single part. If assertions are disabled, it returns NULL +// for multi-part objects. +inline struct cxxrtl_object *cxxrtl_get(cxxrtl_handle handle, const char *name) { + size_t parts = 0; + struct cxxrtl_object *object = cxxrtl_get_parts(handle, name, &parts); + assert(object == NULL || parts == 1); + if (object == NULL || parts == 1) + return object; + return NULL; +} // Enumerate simulated objects. // // For every object in the simulation, `callback` is called with the provided `data`, the full -// hierarchical name of the object (see `cxxrtl_get` for details), and the object description. +// hierarchical name of the object (see `cxxrtl_get` for details), and the object parts. // The provided `name` and `object` values are valid until the design is destroyed. void cxxrtl_enum(cxxrtl_handle handle, void *data, - void (*callback)(void *data, const char *name, struct cxxrtl_object *object)); + void (*callback)(void *data, const char *name, + struct cxxrtl_object *object, size_t parts)); #ifdef __cplusplus } diff --git a/backends/cxxrtl/cxxrtl_vcd.h b/backends/cxxrtl/cxxrtl_vcd.h index f6b78bbf7..dbeabbaf2 100644 --- a/backends/cxxrtl/cxxrtl_vcd.h +++ b/backends/cxxrtl/cxxrtl_vcd.h @@ -66,11 +66,19 @@ class vcd_writer { } while (ident != 0); } - void emit_var(const variable &var, const std::string &type, const std::string &name) { + void emit_var(const variable &var, const std::string &type, const std::string &name, + size_t lsb_at, bool multipart) { assert(!streaming); buffer += "$var " + type + " " + std::to_string(var.width) + " "; emit_ident(var.ident); - buffer += " " + name + " $end\n"; + buffer += " " + name; + if (multipart || name.back() == ']' || lsb_at != 0) { + if (var.width == 1) + buffer += " [" + std::to_string(lsb_at) + "]"; + else + buffer += " [" + std::to_string(lsb_at + var.width - 1) + ":" + std::to_string(lsb_at) + "]"; + } + buffer += " $end\n"; } void emit_enddefinitions() { @@ -104,13 +112,13 @@ class vcd_writer { buffer += '\n'; } - const variable ®ister_variable(size_t width, chunk_t *curr, bool immutable = false) { + const variable ®ister_variable(size_t width, chunk_t *curr, bool constant = false) { if (aliases.count(curr)) { return variables[aliases[curr]]; } else { const size_t chunks = (width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8); aliases[curr] = variables.size(); - if (immutable) { + if (constant) { variables.emplace_back(variable { variables.size(), width, curr, (size_t)-1 }); } else { variables.emplace_back(variable { variables.size(), width, curr, cache.size() }); @@ -122,7 +130,7 @@ class vcd_writer { bool test_variable(const variable &var) { if (var.prev_off == (size_t)-1) - return false; // immutable + return false; // constant const size_t chunks = (var.width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8); if (std::equal(&var.curr[0], &var.curr[chunks], &cache[var.prev_off])) { return false; @@ -155,7 +163,7 @@ public: emit_timescale(number, unit); } - void add(const std::string &hier_name, const debug_item &item) { + void add(const std::string &hier_name, const debug_item &item, bool multipart = false) { std::vector<std::string> scope = split_hierarchy(hier_name); std::string name = scope.back(); scope.pop_back(); @@ -164,20 +172,31 @@ public: switch (item.type) { // Not the best naming but oh well... case debug_item::VALUE: - emit_var(register_variable(item.width, item.curr, /*immutable=*/item.next == nullptr), "wire", name); + emit_var(register_variable(item.width, item.curr, /*constant=*/item.next == nullptr), + "wire", name, item.lsb_at, multipart); break; case debug_item::WIRE: - emit_var(register_variable(item.width, item.curr), "reg", name); + emit_var(register_variable(item.width, item.curr), + "reg", name, item.lsb_at, multipart); break; case debug_item::MEMORY: { const size_t stride = (item.width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8); for (size_t index = 0; index < item.depth; index++) { chunk_t *nth_curr = &item.curr[stride * index]; std::string nth_name = name + '[' + std::to_string(index) + ']'; - emit_var(register_variable(item.width, nth_curr), "reg", nth_name); + emit_var(register_variable(item.width, nth_curr), + "reg", nth_name, item.lsb_at, multipart); } break; } + case debug_item::ALIAS: + // Like VALUE, but, even though `item.next == nullptr` always holds, the underlying value + // can actually change, and must be tracked. In most cases the VCD identifier will be + // unified with the aliased reg, but we should handle the case where only the alias is + // added to the VCD writer, too. + emit_var(register_variable(item.width, item.curr), + "wire", name, item.lsb_at, multipart); + break; } } @@ -185,9 +204,10 @@ public: void add(const debug_items &items, const Filter &filter) { // `debug_items` is a map, so the items are already sorted in an order optimal for emitting // VCD scope sections. - for (auto &it : items) - if (filter(it.first, it.second)) - add(it.first, it.second); + for (auto &it : items.table) + for (auto &part : it.second) + if (filter(it.first, part)) + add(it.first, part, it.second.size() > 1); } void add(const debug_items &items) { @@ -198,7 +218,7 @@ public: void add_without_memories(const debug_items &items) { this->template add(items, [](const std::string &, const debug_item &item) { - return item.type == debug_item::VALUE || item.type == debug_item::WIRE; + return item.type != debug_item::MEMORY; }); } diff --git a/backends/cxxrtl/cxxrtl_vcd_capi.h b/backends/cxxrtl/cxxrtl_vcd_capi.h index 6a7fb9f47..d55afe223 100644 --- a/backends/cxxrtl/cxxrtl_vcd_capi.h +++ b/backends/cxxrtl/cxxrtl_vcd_capi.h @@ -75,8 +75,8 @@ void cxxrtl_vcd_add_from(cxxrtl_vcd vcd, cxxrtl_handle handle); // // Objects can only be scheduled before the first call to `cxxrtl_vcd_sample`. void cxxrtl_vcd_add_from_if(cxxrtl_vcd vcd, cxxrtl_handle handle, void *data, - int (*filter)(void *data, const char *name, - const struct cxxrtl_object *object)); + int (*filter)(void *data, const char *name, + const struct cxxrtl_object *object)); // Schedule all CXXRTL objects in a simulation except for memories. // diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 7e24468c0..e0013238c 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -90,7 +90,7 @@ struct EdifNames struct EdifBackend : public Backend { EdifBackend() : Backend("edif", "write design to EDIF netlist file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -126,7 +126,7 @@ struct EdifBackend : public Backend { log("is targeted.\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing EDIF backend.\n"); std::string top_module_name; @@ -330,7 +330,7 @@ struct EdifBackend : public Backend { } *f << stringf("\n (property %s (string \"%d'h%s\"))", EDIF_DEF(name), GetSize(val.bits), hex_string.c_str()); } - }; + }; for (auto module : sorted_modules) { if (module->get_blackbox_attribute()) @@ -373,8 +373,8 @@ struct EdifBackend : public Backend { } { - int c1 = w1->name[0] == '\\'; - int c2 = w2->name[0] == '\\'; + int c1 = w1->name.isPublic(); + int c2 = w2->name.isPublic(); if (c1 > c2) goto promote; if (c1 < c2) goto nopromote; @@ -524,7 +524,7 @@ struct EdifBackend : public Backend { *f << stringf(" (portRef %c (instanceRef GND))\n", gndvccy ? 'Y' : 'G'); if (sig == RTLIL::State::S1) *f << stringf(" (portRef %c (instanceRef VCC))\n", gndvccy ? 'Y' : 'P'); - } + } *f << stringf(" )"); if (attr_properties && sig.wire != NULL) for (auto &p : sig.wire->attributes) diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index b1d8500bb..44c3397da 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -102,6 +102,260 @@ const char *make_id(IdString id) return namecache.at(id).c_str(); } +std::string dump_const_string(const RTLIL::Const &data) +{ + std::string res_str; + + std::string str = data.decode_string(); + for (size_t i = 0; i < str.size(); i++) + { + if (str[i] == '\n') + res_str += "\\n"; + else if (str[i] == '\t') + res_str += "\\t"; + else if (str[i] < 32) + res_str += stringf("\\%03o", str[i]); + else if (str[i] == '"') + res_str += "\\\""; + else if (str[i] == '\\') + res_str += "\\\\"; + else + res_str += str[i]; + } + + return res_str; +} + +std::string dump_const(const RTLIL::Const &data) +{ + std::string res_str; + + // // For debugging purposes to find out how Yosys encodes flags. + // res_str += stringf("flags_%x --> ", data.flags); + + // Real-valued parameter. + if (data.flags & RTLIL::CONST_FLAG_REAL) + { + // Yosys stores real values as strings, so we call the string dumping code. + res_str += dump_const_string(data); + } + // String parameter. + else if (data.flags & RTLIL::CONST_FLAG_STRING) + { + res_str += "\""; + res_str += dump_const_string(data); + res_str += "\""; + } + // Numeric (non-real) parameter. + else + { + int width = data.bits.size(); + + // If a standard 32-bit int, then emit standard int value like "56" or + // "-56". Firrtl supports negative-valued int literals. + // + // SignedInt + // : ( '+' | '-' ) PosInt + // ; + if (width <= 32) + { + int32_t int_val = 0; + + for (int i = 0; i < width; i++) + { + switch (data.bits[i]) + { + case State::S0: break; + case State::S1: int_val |= (1 << i); break; + default: + log_error("Unexpected int value\n"); + break; + } + } + + res_str += stringf("%d", int_val); + } + else + { + // If value is larger than 32 bits, then emit a binary representation of + // the number as integers are not large enough to contain the result. + // There is a caveat to this approach though: + // + // Note that parameter may be defined as having a fixed width as follows: + // + // parameter signed [26:0] test_signed; + // parameter [26:0] test_unsigned; + // parameter signed [40:0] test_signed_large; + // + // However, if you assign a value on the RHS without specifying the + // precision, then yosys considers the value you used as an int and + // assigns it a width of 32 bits regardless of the type of the parameter. + // + // defparam <inst_name> .test_signed = 49; (width = 32, though should be 27 based on definition) + // defparam <inst_name> .test_unsigned = 40'd35; (width = 40, though should be 27 based on definition) + // defparam <inst_name> .test_signed_large = 40'd12; (width = 40) + // + // We therefore may lose the precision of the original verilog literal if + // it was written without its bitwidth specifier. + + // Emit binary prefix for string. + res_str += "\"b"; + + // Emit bits. + for (int i = width - 1; i >= 0; i--) + { + log_assert(i < width); + switch (data.bits[i]) + { + case State::S0: res_str += "0"; break; + case State::S1: res_str += "1"; break; + case State::Sx: res_str += "x"; break; + case State::Sz: res_str += "z"; break; + case State::Sa: res_str += "-"; break; + case State::Sm: res_str += "m"; break; + } + } + + res_str += "\""; + } + } + + return res_str; +} + +std::string extmodule_name(RTLIL::Cell *cell, RTLIL::Module *mod_instance) +{ + // Since we are creating a custom extmodule for every cell that instantiates + // this blackbox, we need to create a custom name for it. We just use the + // name of the blackbox itself followed by the name of the cell. + const std::string cell_name = std::string(make_id(cell->name)); + const std::string blackbox_name = std::string(make_id(mod_instance->name)); + const std::string extmodule_name = blackbox_name + "_" + cell_name; + return extmodule_name; +} + +/** + * Emits a parameterized extmodule. Instance parameters are obtained from + * ''cell'' as it represents the instantiation of the blackbox defined by + * ''mod_instance'' and therefore contains all its instance parameters. + */ +void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream &f) +{ + const std::string indent = " "; + + const std::string blackbox_name = std::string(make_id(mod_instance->name)); + const std::string exported_name = extmodule_name(cell, mod_instance); + + // We use the cell's fileinfo for this extmodule as its parameters come from + // the cell and not from the module itself (the module contains default + // parameters, not the instance-specific ones we're using to emit the + // extmodule). + const std::string extmoduleFileinfo = getFileinfo(cell); + + // Emit extmodule header. + f << stringf(" extmodule %s: %s\n", exported_name.c_str(), extmoduleFileinfo.c_str()); + + // Emit extmodule ports. + for (auto wire : mod_instance->wires()) + { + const auto wireName = make_id(wire->name); + const std::string wireFileinfo = getFileinfo(wire); + + if (wire->port_input && wire->port_output) + { + log_error("Module port %s.%s is inout!\n", log_id(mod_instance), log_id(wire)); + } + + const std::string portDecl = stringf("%s%s %s: UInt<%d> %s\n", + indent.c_str(), + wire->port_input ? "input" : "output", + wireName, + wire->width, + wireFileinfo.c_str() + ); + + f << portDecl; + } + + // Emit extmodule "defname" field. This is the name of the verilog blackbox + // that is used when verilog is emitted, so we use the name of mod_instance + // here. + f << stringf("%sdefname = %s\n", indent.c_str(), blackbox_name.c_str()); + + // Emit extmodule generic parameters. + for (const auto &p : cell->parameters) + { + const RTLIL::IdString p_id = p.first; + const RTLIL::Const p_value = p.second; + + std::string param_name(p_id.c_str()); + const std::string param_value = dump_const(p_value); + + // Remove backslashes from parameters as these come from the internal RTLIL + // naming scheme, but should not exist in the emitted firrtl blackboxes. + // When firrtl is converted to verilog and given to downstream synthesis + // tools, these tools expect to find blackbox names and parameters as they + // were originally defined, i.e. without the extra RTLIL naming conventions. + param_name.erase( + std::remove(param_name.begin(), param_name.end(), '\\'), + param_name.end() + ); + + f << stringf("%sparameter %s = %s\n", indent.c_str(), param_name.c_str(), param_value.c_str()); + } + + f << "\n"; +} + +/** + * Emits extmodules for every instantiated blackbox in the design. + * + * RTLIL stores instance parameters at the cell's instantiation location. + * However, firrtl does not support module parameterization (everything is + * already elaborated). Firrtl instead supports external modules (extmodule), + * i.e. blackboxes that are defined by verilog and which have no body in + * firrtl itself other than the declaration of the blackboxes ports and + * parameters. + * + * Furthermore, firrtl does not support parameterization (even of extmodules) + * at a module's instantiation location and users must instead declare + * different extmodules with different instance parameters in the extmodule + * definition itself. + * + * This function goes through the design to identify all RTLIL blackboxes + * and emit parameterized extmodules with a unique name for each of them. The + * name that's given to the extmodule is + * + * <blackbox_name>_<instance_name> + * + * Beware that it is therefore necessary for users to replace "parameterized" + * instances in the RTLIL sense with these custom extmodules for the firrtl to + * be valid. + */ +void emit_elaborated_extmodules(RTLIL::Design *design, std::ostream &f) +{ + for (auto module : design->modules()) + { + for (auto cell : module->cells()) + { + // Is this cell a module instance? + bool cellIsModuleInstance = cell->type[0] != '$'; + + if (cellIsModuleInstance) + { + // Find the module corresponding to this instance. + auto modInstance = design->module(cell->type); + bool modIsBlackbox = modInstance->get_blackbox_attribute(); + + if (modIsBlackbox) + { + emit_extmodule(cell, modInstance, f); + } + } + } + } +} + struct FirrtlWorker { Module *module; @@ -328,8 +582,16 @@ struct FirrtlWorker log_warning("No instance for %s.%s\n", cell_type.c_str(), cell_name.c_str()); return; } + + // If the instance is that of a blackbox, use the modified extmodule name + // that contains per-instance parameterizations. These instances were + // emitted earlier in the firrtl backend. + const std::string instanceName = instModule->get_blackbox_attribute() ? + extmodule_name(cell, instModule) : + instanceOf; + std::string cellFileinfo = getFileinfo(cell); - wire_exprs.push_back(stringf("%s" "inst %s%s of %s %s", indent.c_str(), cell_name.c_str(), cell_name_comment.c_str(), instanceOf.c_str(), cellFileinfo.c_str())); + wire_exprs.push_back(stringf("%s" "inst %s%s of %s %s", indent.c_str(), cell_name.c_str(), cell_name_comment.c_str(), instanceName.c_str(), cellFileinfo.c_str())); for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) { if (it->second.size() > 0) { @@ -392,33 +654,6 @@ struct FirrtlWorker return result; } - void emit_extmodule() - { - std::string moduleFileinfo = getFileinfo(module); - f << stringf(" extmodule %s: %s\n", make_id(module->name), moduleFileinfo.c_str()); - vector<std::string> port_decls; - - for (auto wire : module->wires()) - { - const auto wireName = make_id(wire->name); - std::string wireFileinfo = getFileinfo(wire); - - if (wire->port_input && wire->port_output) - { - log_error("Module port %s.%s is inout!\n", log_id(module), log_id(wire)); - } - port_decls.push_back(stringf(" %s %s: UInt<%d> %s\n", wire->port_input ? "input" : "output", - wireName, wire->width, wireFileinfo.c_str())); - } - - for (auto &str : port_decls) - { - f << str; - } - - f << stringf("\n"); - } - void emit_module() { std::string moduleFileinfo = getFileinfo(module); @@ -440,12 +675,12 @@ struct FirrtlWorker { if (wire->port_input && wire->port_output) log_error("Module port %s.%s is inout!\n", log_id(module), log_id(wire)); - port_decls.push_back(stringf(" %s %s: UInt<%d> %s\n", wire->port_input ? "input" : "output", + port_decls.push_back(stringf("%s%s %s: UInt<%d> %s\n", indent.c_str(), wire->port_input ? "input" : "output", wireName, wire->width, wireFileinfo.c_str())); } else { - wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", wireName, wire->width, wireFileinfo.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), wireName, wire->width, wireFileinfo.c_str())); } } @@ -476,7 +711,7 @@ struct FirrtlWorker if (cell->type.in(ID($not), ID($logic_not), ID($_NOT_), ID($neg), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_bool), ID($reduce_xnor))) { string a_expr = make_expr(cell->getPort(ID::A)); - wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), y_width, cellFileinfo.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), y_width, cellFileinfo.c_str())); if (a_signed) { a_expr = "asSInt(" + a_expr + ")"; @@ -516,7 +751,7 @@ struct FirrtlWorker if ((firrtl_is_signed && !always_uint)) expr = stringf("asUInt(%s)", expr.c_str()); - cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; @@ -528,7 +763,7 @@ struct FirrtlWorker string a_expr = make_expr(cell->getPort(ID::A)); string b_expr = make_expr(cell->getPort(ID::B)); std::string cellFileinfo = getFileinfo(cell); - wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), y_width, cellFileinfo.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), y_width, cellFileinfo.c_str())); if (a_signed) { a_expr = "asSInt(" + a_expr + ")"; @@ -746,7 +981,7 @@ struct FirrtlWorker if ((firrtl_is_signed && !always_uint)) expr = stringf("asUInt(%s)", expr.c_str()); - cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; @@ -759,11 +994,11 @@ struct FirrtlWorker string a_expr = make_expr(cell->getPort(ID::A)); string b_expr = make_expr(cell->getPort(ID::B)); string s_expr = make_expr(cell->getPort(ID::S)); - wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), width, cellFileinfo.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), width, cellFileinfo.c_str())); string expr = stringf("mux(%s, %s, %s)", s_expr.c_str(), b_expr.c_str(), a_expr.c_str()); - cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; @@ -902,9 +1137,9 @@ struct FirrtlWorker string expr = make_expr(cell->getPort(ID::D)); string clk_expr = "asClock(" + make_expr(cell->getPort(ID::CLK)) + ")"; - wire_decls.push_back(stringf(" reg %s: UInt<%d>, %s %s\n", y_id.c_str(), width, clk_expr.c_str(), cellFileinfo.c_str())); + wire_decls.push_back(stringf("%sreg %s: UInt<%d>, %s %s\n", indent.c_str(), y_id.c_str(), width, clk_expr.c_str(), cellFileinfo.c_str())); - cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Q)); continue; @@ -923,7 +1158,7 @@ struct FirrtlWorker string a_expr = make_expr(cell->getPort(ID::A)); // Get the initial bit selector string b_expr = make_expr(cell->getPort(ID::B)); - wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width)); + wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width)); if (cell->getParam(ID::B_SIGNED).as_bool()) { // Use validif to constrain the selection (test the sign bit) @@ -933,7 +1168,7 @@ struct FirrtlWorker } string expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_expr.c_str()); - cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; } @@ -945,7 +1180,7 @@ struct FirrtlWorker string b_expr = make_expr(cell->getPort(ID::B)); auto b_string = b_expr.c_str(); string expr; - wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width)); + wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width)); if (cell->getParam(ID::B_SIGNED).as_bool()) { // We generate a left or right shift based on the sign of b. @@ -959,7 +1194,7 @@ struct FirrtlWorker } else { expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string); } - cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str())); + cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; } @@ -972,8 +1207,8 @@ struct FirrtlWorker if (a_width < y_width) { a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width); } - wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width)); - cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), a_expr.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width)); + cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), a_expr.c_str())); register_reverse_wire_map(y_id, cell->getPort(ID::Y)); continue; } @@ -986,8 +1221,8 @@ struct FirrtlWorker int y_width = GetSize(conn.first); string expr = make_expr(conn.second); - wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width)); - cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width)); + cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str())); register_reverse_wire_map(y_id, conn.first); } @@ -1053,13 +1288,13 @@ struct FirrtlWorker if (is_valid) { if (make_unconn_id) { - wire_decls.push_back(stringf(" wire %s: UInt<1> %s\n", unconn_id.c_str(), wireFileinfo.c_str())); + wire_decls.push_back(stringf("%swire %s: UInt<1> %s\n", indent.c_str(), unconn_id.c_str(), wireFileinfo.c_str())); // `invalid` is a firrtl construction for simulation so we will not // tag it with a @[fileinfo] tag as it doesn't directly correspond to // a specific line of verilog code. - wire_decls.push_back(stringf(" %s is invalid\n", unconn_id.c_str())); + wire_decls.push_back(stringf("%s%s is invalid\n", indent.c_str(), unconn_id.c_str())); } - wire_exprs.push_back(stringf(" %s <= %s %s\n", make_id(wire->name), expr.c_str(), wireFileinfo.c_str())); + wire_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), make_id(wire->name), expr.c_str(), wireFileinfo.c_str())); } else { if (make_unconn_id) { unconn_id.clear(); @@ -1067,7 +1302,7 @@ struct FirrtlWorker // `invalid` is a firrtl construction for simulation so we will not // tag it with a @[fileinfo] tag as it doesn't directly correspond to // a specific line of verilog code. - wire_decls.push_back(stringf(" %s is invalid\n", make_id(wire->name))); + wire_decls.push_back(stringf("%s%s is invalid\n", indent.c_str(), make_id(wire->name))); } } @@ -1112,18 +1347,13 @@ struct FirrtlWorker void run() { - // Blackboxes should be emitted as `extmodule`s in firrtl. Only ports are - // emitted in such a case. - if (module->get_blackbox_attribute()) - emit_extmodule(); - else - emit_module(); + emit_module(); } }; struct FirrtlBackend : public Backend { FirrtlBackend() : Backend("firrtl", "write design to a FIRRTL file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1134,7 +1364,7 @@ struct FirrtlBackend : public Backend { log(" pmuxtree\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx = args.size(); // We aren't expecting any arguments. @@ -1180,10 +1410,16 @@ struct FirrtlBackend : public Backend { std::string circuitFileinfo = getFileinfo(top); *f << stringf("circuit %s: %s\n", make_id(top->name), circuitFileinfo.c_str()); + emit_elaborated_extmodules(design, *f); + + // Emit non-blackbox modules. for (auto module : design->modules()) { - FirrtlWorker worker(module, *f, design); - worker.run(); + if (!module->get_blackbox_attribute()) + { + FirrtlWorker worker(module, *f, design); + worker.run(); + } } namecache.clear(); diff --git a/backends/ilang/Makefile.inc b/backends/ilang/Makefile.inc deleted file mode 100644 index 52fc2b891..000000000 --- a/backends/ilang/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/ilang/ilang_backend.o - diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 31dce1cca..a6b36de6c 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -46,7 +46,7 @@ static std::string netname(std::set<std::string> &conntypes_code, std::set<std:: struct IntersynthBackend : public Backend { IntersynthBackend() : Backend("intersynth", "write design to InterSynth netlist file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -59,7 +59,7 @@ struct IntersynthBackend : public Backend { log(" do not generate celltypes and conntypes commands. i.e. just output\n"); log(" the netlists. this is used for postsilicon synthesis.\n"); log("\n"); - log(" -lib <verilog_or_ilang_file>\n"); + log(" -lib <verilog_or_rtlil_file>\n"); log(" Use the specified library file for determining whether cell ports are\n"); log(" inputs or outputs. This option can be used multiple times to specify\n"); log(" more than one library.\n"); @@ -71,7 +71,7 @@ struct IntersynthBackend : public Backend { log("http://www.clifford.at/intersynth/\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing INTERSYNTH backend.\n"); log_push(); @@ -108,7 +108,7 @@ struct IntersynthBackend : public Backend { if (f.fail()) log_error("Can't open lib file `%s'.\n", filename.c_str()); RTLIL::Design *lib = new RTLIL::Design; - Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog")); + Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : "verilog")); libs.push_back(lib); } diff --git a/backends/json/json.cc b/backends/json/json.cc index 5edc50f60..eeadc1b89 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -294,7 +294,7 @@ struct JsonWriter struct JsonBackend : public Backend { JsonBackend() : Backend("json", "write design to a JSON file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -530,7 +530,7 @@ struct JsonBackend : public Backend { log("format. A program processing this format must ignore all unknown fields.\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { bool aig_mode = false; bool compat_int_mode = false; @@ -559,7 +559,7 @@ struct JsonBackend : public Backend { struct JsonPass : public Pass { JsonPass() : Pass("json", "write design in JSON format") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -580,7 +580,7 @@ struct JsonPass : public Pass { log("See 'help write_json' for a description of the JSON format used.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string filename; bool aig_mode = false; diff --git a/backends/protobuf/protobuf.cc b/backends/protobuf/protobuf.cc index 671686173..f6623a382 100644 --- a/backends/protobuf/protobuf.cc +++ b/backends/protobuf/protobuf.cc @@ -231,7 +231,7 @@ struct ProtobufDesignSerializer struct ProtobufBackend : public Backend { ProtobufBackend(): Backend("protobuf", "write design to a Protocol Buffer file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -249,7 +249,7 @@ struct ProtobufBackend : public Backend { log("Yosys source code distribution.\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { bool aig_mode = false; bool text_mode = false; @@ -286,7 +286,7 @@ struct ProtobufBackend : public Backend { struct ProtobufPass : public Pass { ProtobufPass() : Pass("protobuf", "write design in Protobuf format") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -307,7 +307,7 @@ struct ProtobufPass : public Pass { log("Yosys source code distribution.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string filename; bool aig_mode = false; diff --git a/backends/rtlil/Makefile.inc b/backends/rtlil/Makefile.inc new file mode 100644 index 000000000..f691282ca --- /dev/null +++ b/backends/rtlil/Makefile.inc @@ -0,0 +1,3 @@ + +OBJS += backends/rtlil/rtlil_backend.o + diff --git a/backends/ilang/ilang_backend.cc b/backends/rtlil/rtlil_backend.cc index 3a418de3c..01b4bde53 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -18,19 +18,19 @@ * --- * * A very simple and straightforward backend for the RTLIL text - * representation (as understood by the 'ilang' frontend). + * representation. * */ -#include "ilang_backend.h" +#include "rtlil_backend.h" #include "kernel/yosys.h" #include <errno.h> USING_YOSYS_NAMESPACE -using namespace ILANG_BACKEND; +using namespace RTLIL_BACKEND; YOSYS_NAMESPACE_BEGIN -void ILANG_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int width, int offset, bool autoint) +void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int width, int offset, bool autoint) { if (width < 0) width = data.bits.size() - offset; @@ -83,7 +83,7 @@ void ILANG_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi } } -void ILANG_BACKEND::dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint) +void RTLIL_BACKEND::dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint) { if (chunk.wire == NULL) { dump_const(f, chunk.data, chunk.width, chunk.offset, autoint); @@ -97,7 +97,7 @@ void ILANG_BACKEND::dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, } } -void ILANG_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint) +void RTLIL_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint) { if (sig.is_chunk()) { dump_sigchunk(f, sig.as_chunk(), autoint); @@ -111,7 +111,7 @@ void ILANG_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, boo } } -void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire) +void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire) { for (auto &it : wire->attributes) { f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str()); @@ -136,7 +136,7 @@ void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL:: f << stringf("%s\n", wire->name.c_str()); } -void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory) +void RTLIL_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory) { for (auto &it : memory->attributes) { f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str()); @@ -153,7 +153,7 @@ void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL f << stringf("%s\n", memory->name.c_str()); } -void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell) +void RTLIL_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell) { for (auto &it : cell->attributes) { f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str()); @@ -177,7 +177,7 @@ void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL:: f << stringf("%s" "end\n", indent.c_str()); } -void ILANG_BACKEND::dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs) +void RTLIL_BACKEND::dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs) { for (auto it = cs->actions.begin(); it != cs->actions.end(); ++it) { @@ -192,7 +192,7 @@ void ILANG_BACKEND::dump_proc_case_body(std::ostream &f, std::string indent, con dump_proc_switch(f, indent, *it); } -void ILANG_BACKEND::dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw) +void RTLIL_BACKEND::dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw) { for (auto it = sw->attributes.begin(); it != sw->attributes.end(); ++it) { f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); @@ -225,7 +225,7 @@ void ILANG_BACKEND::dump_proc_switch(std::ostream &f, std::string indent, const f << stringf("%s" "end\n", indent.c_str()); } -void ILANG_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy) +void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy) { f << stringf("%s" "sync ", indent.c_str()); switch (sy->type) { @@ -251,7 +251,7 @@ void ILANG_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RT } } -void ILANG_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc) +void RTLIL_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc) { for (auto it = proc->attributes.begin(); it != proc->attributes.end(); ++it) { f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); @@ -265,7 +265,7 @@ void ILANG_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL:: f << stringf("%s" "end\n", indent.c_str()); } -void ILANG_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) +void RTLIL_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { f << stringf("%s" "connect ", indent.c_str()); dump_sigspec(f, left); @@ -274,7 +274,7 @@ void ILANG_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL:: f << stringf("\n"); } -void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) +void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { bool print_header = flag_m || design->selected_whole_module(module->name); bool print_body = !flag_n || !design->selected_whole_module(module->name); @@ -360,11 +360,9 @@ void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu f << stringf("%s" "end\n", indent.c_str()); } -void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) +void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { -#ifndef NDEBUG int init_autoidx = autoidx; -#endif if (!flag_m) { int count_selected_mods = 0; @@ -398,26 +396,26 @@ void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl YOSYS_NAMESPACE_END PRIVATE_NAMESPACE_BEGIN -struct IlangBackend : public Backend { - IlangBackend() : Backend("ilang", "write design to ilang file") { } - void help() YS_OVERRIDE +struct RTLILBackend : public Backend { + RTLILBackend() : Backend("rtlil", "write design to RTLIL file") { } + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" write_ilang [filename]\n"); + log(" write_rtlil [filename]\n"); log("\n"); - log("Write the current design to an 'ilang' file. (ilang is a text representation\n"); + log("Write the current design to an RTLIL file. (RTLIL is a text representation\n"); log("of a design in yosys's internal format.)\n"); log("\n"); log(" -selected\n"); log(" only write selected parts of the design.\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { bool selected = false; - log_header(design, "Executing ILANG backend.\n"); + log_header(design, "Executing RTLIL backend.\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -434,20 +432,35 @@ struct IlangBackend : public Backend { log("Output filename: %s\n", filename.c_str()); *f << stringf("# Generated by %s\n", yosys_version_str); - ILANG_BACKEND::dump_design(*f, design, selected, true, false); + RTLIL_BACKEND::dump_design(*f, design, selected, true, false); + } +} RTLILBackend; + +struct IlangBackend : public Backend { + IlangBackend() : Backend("ilang", "(deprecated) alias of write_rtlil") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log("See `help write_rtlil`.\n"); + log("\n"); + } + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override + { + RTLILBackend.execute(f, filename, args, design); } } IlangBackend; struct DumpPass : public Pass { - DumpPass() : Pass("dump", "print parts of the design in ilang format") { } - void help() YS_OVERRIDE + DumpPass() : Pass("dump", "print parts of the design in RTLIL format") { } + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" dump [options] [selection]\n"); log("\n"); log("Write the selected parts of the design to the console or specified file in\n"); - log("ilang format.\n"); + log("RTLIL format.\n"); log("\n"); log(" -m\n"); log(" also dump the module headers, even if only parts of a single\n"); @@ -463,7 +476,7 @@ struct DumpPass : public Pass { log(" like -outfile but append instead of overwrite\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string filename; bool flag_m = false, flag_n = false, append = false; @@ -510,7 +523,7 @@ struct DumpPass : public Pass { f = &buf; } - ILANG_BACKEND::dump_design(*f, design, true, flag_m, flag_n); + RTLIL_BACKEND::dump_design(*f, design, true, flag_m, flag_n); if (!filename.empty()) { delete f; diff --git a/backends/ilang/ilang_backend.h b/backends/rtlil/rtlil_backend.h index 97dcbb628..77eea353c 100644 --- a/backends/ilang/ilang_backend.h +++ b/backends/rtlil/rtlil_backend.h @@ -18,19 +18,19 @@ * --- * * A very simple and straightforward backend for the RTLIL text - * representation (as understood by the 'ilang' frontend). + * representation. * */ -#ifndef ILANG_BACKEND_H -#define ILANG_BACKEND_H +#ifndef RTLIL_BACKEND_H +#define RTLIL_BACKEND_H #include "kernel/yosys.h" #include <stdio.h> YOSYS_NAMESPACE_BEGIN -namespace ILANG_BACKEND { +namespace RTLIL_BACKEND { void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true); void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint = true); void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint = true); diff --git a/backends/simplec/simplec.cc b/backends/simplec/simplec.cc index 83ed5e6e0..3adeaa6c0 100644 --- a/backends/simplec/simplec.cc +++ b/backends/simplec/simplec.cc @@ -744,7 +744,7 @@ struct SimplecWorker struct SimplecBackend : public Backend { SimplecBackend() : Backend("simplec", "convert design to simple C code") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -763,7 +763,7 @@ struct SimplecBackend : public Backend { log("THIS COMMAND IS UNDER CONSTRUCTION\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { reserved_cids.clear(); id2cid.clear(); diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 26f17bcb3..a185fdd74 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -22,6 +22,7 @@ #include "kernel/sigtools.h" #include "kernel/celltypes.h" #include "kernel/log.h" +#include "kernel/mem.h" #include <string> USING_YOSYS_NAMESPACE @@ -40,12 +41,15 @@ struct Smt2Worker std::map<RTLIL::SigBit, RTLIL::Cell*> bit_driver; std::set<RTLIL::Cell*> exported_cells, hiercells, hiercells_queue; pool<Cell*> recursive_cells, registers; + std::vector<Mem> memories; + dict<Cell*, Mem*> mem_cells; + std::set<Mem*> memory_queue; pool<SigBit> clock_posedge, clock_negedge; vector<string> ex_state_eq, ex_input_eq; std::map<RTLIL::SigBit, std::pair<int, int>> fcache; - std::map<Cell*, int> memarrays; + std::map<Mem*, int> memarrays; std::map<int, int> bvsizes; dict<IdString, char*> ids; @@ -116,12 +120,73 @@ struct Smt2Worker makebits(stringf("%s_is", get_id(module))); + dict<IdString, Mem*> mem_dict; + memories = Mem::get_all_memories(module); + for (auto &mem : memories) + { + mem_dict[mem.memid] = &mem; + for (auto &port : mem.wr_ports) + { + if (port.clk_enable) { + SigSpec clk = sigmap(port.clk); + for (int i = 0; i < GetSize(clk); i++) + { + if (clk[i].wire == nullptr) + continue; + if (port.clk_polarity) + clock_posedge.insert(clk[i]); + else + clock_negedge.insert(clk[i]); + } + } + for (auto bit : sigmap(port.en)) + noclock.insert(bit); + for (auto bit : sigmap(port.addr)) + noclock.insert(bit); + for (auto bit : sigmap(port.data)) + noclock.insert(bit); + } + for (auto &port : mem.rd_ports) + { + if (port.clk_enable) { + SigSpec clk = sigmap(port.clk); + for (int i = 0; i < GetSize(clk); i++) + { + if (clk[i].wire == nullptr) + continue; + if (port.clk_polarity) + clock_posedge.insert(clk[i]); + else + clock_negedge.insert(clk[i]); + } + } + for (auto bit : sigmap(port.en)) + noclock.insert(bit); + for (auto bit : sigmap(port.addr)) + noclock.insert(bit); + for (auto bit : sigmap(port.data)) + noclock.insert(bit); + Cell *driver = port.cell ? port.cell : mem.cell; + for (auto bit : sigmap(port.data)) { + if (bit_driver.count(bit)) + log_error("Found multiple drivers for %s.\n", log_signal(bit)); + bit_driver[bit] = driver; + } + } + } + for (auto cell : module->cells()) for (auto &conn : cell->connections()) { if (GetSize(conn.second) == 0) continue; + // Handled above. + if (cell->type.in(ID($mem), ID($memrd), ID($memwr), ID($meminit))) { + mem_cells[cell] = mem_dict[cell->parameters.at(ID::MEMID).decode_string()]; + continue; + } + bool is_input = ct.cell_input(cell->type, conn.first); bool is_output = ct.cell_output(cell->type, conn.first); @@ -135,24 +200,6 @@ struct Smt2Worker log_error("Unsupported or unknown directionality on port %s of cell %s.%s (%s).\n", log_id(conn.first), log_id(module), log_id(cell), log_id(cell->type)); - if (cell->type.in(ID($mem)) && conn.first.in(ID::RD_CLK, ID::WR_CLK)) - { - SigSpec clk = sigmap(conn.second); - for (int i = 0; i < GetSize(clk); i++) - { - if (clk[i].wire == nullptr) - continue; - - if (cell->getParam(conn.first == ID::RD_CLK ? ID::RD_CLK_ENABLE : ID::WR_CLK_ENABLE)[i] != State::S1) - continue; - - if (cell->getParam(conn.first == ID::RD_CLK ? ID::RD_CLK_POLARITY : ID::WR_CLK_POLARITY)[i] == State::S1) - clock_posedge.insert(clk[i]); - else - clock_negedge.insert(clk[i]); - } - } - else if (cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_)) && conn.first.in(ID::CLK, ID::C)) { bool posedge = (cell->type == ID($_DFF_N_)) || (cell->type == ID($dff) && cell->getParam(ID::CLK_POLARITY).as_bool()); @@ -647,27 +694,35 @@ struct Smt2Worker // FIXME: $slice $concat } - if (memmode && cell->type == ID($mem)) + if (memmode && cell->type.in(ID($mem), ID($memrd), ID($memwr), ID($meminit))) { + Mem *mem = mem_cells[cell]; + + if (memarrays.count(mem)) { + recursive_cells.erase(cell); + return; + } + int arrayid = idcounter++; - memarrays[cell] = arrayid; - - int abits = cell->getParam(ID::ABITS).as_int(); - int width = cell->getParam(ID::WIDTH).as_int(); - int rd_ports = cell->getParam(ID::RD_PORTS).as_int(); - int wr_ports = cell->getParam(ID::WR_PORTS).as_int(); - - bool async_read = false; - if (!cell->getParam(ID::WR_CLK_ENABLE).is_fully_ones()) { - if (!cell->getParam(ID::WR_CLK_ENABLE).is_fully_zero()) - log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", log_id(cell), log_id(module)); - async_read = true; + memarrays[mem] = arrayid; + + int abits = ceil_log2(mem->size); + + bool has_sync_wr = false; + bool has_async_wr = false; + for (auto &port : mem->wr_ports) { + if (port.clk_enable) + has_sync_wr = true; + else + has_async_wr = true; } + if (has_async_wr && has_sync_wr) + log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", log_id(cell), log_id(module)); - decls.push_back(stringf("; yosys-smt2-memory %s %d %d %d %d %s\n", get_id(cell), abits, width, rd_ports, wr_ports, async_read ? "async" : "sync")); + decls.push_back(stringf("; yosys-smt2-memory %s %d %d %d %d %s\n", get_id(mem->memid), abits, mem->width, GetSize(mem->rd_ports), GetSize(mem->wr_ports), has_async_wr ? "async" : "sync")); string memstate; - if (async_read) { + if (has_async_wr) { memstate = stringf("%s#%d#final", get_id(module), arrayid); } else { memstate = stringf("%s#%d#0", get_id(module), arrayid); @@ -675,80 +730,79 @@ struct Smt2Worker if (statebv) { - int mem_size = cell->getParam(ID::SIZE).as_int(); - int mem_offset = cell->getParam(ID::OFFSET).as_int(); - - makebits(memstate, width*mem_size, get_id(cell)); + makebits(memstate, mem->width*mem->size, get_id(mem->memid)); decls.push_back(stringf("(define-fun |%s_m %s| ((state |%s_s|)) (_ BitVec %d) (|%s| state))\n", - get_id(module), get_id(cell), get_id(module), width*mem_size, memstate.c_str())); + get_id(module), get_id(mem->memid), get_id(module), mem->width*mem->size, memstate.c_str())); - for (int i = 0; i < rd_ports; i++) + for (int i = 0; i < GetSize(mem->rd_ports); i++) { - SigSpec addr_sig = cell->getPort(ID::RD_ADDR).extract(abits*i, abits); - SigSpec data_sig = cell->getPort(ID::RD_DATA).extract(width*i, width); + auto &port = mem->rd_ports[i]; + SigSpec addr_sig = port.addr; + addr_sig.extend_u0(abits); std::string addr = get_bv(addr_sig); - if (cell->getParam(ID::RD_CLK_ENABLE).extract(i).as_bool()) + if (port.clk_enable) log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! " - "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(data_sig), log_id(cell), log_id(module)); + "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), log_id(mem->memid), log_id(module)); decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), i, get_id(cell), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); + get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); std::string read_expr = "#b"; - for (int k = 0; k < width; k++) + for (int k = 0; k < mem->width; k++) read_expr += "0"; - for (int k = 0; k < mem_size; k++) + for (int k = 0; k < mem->size; k++) read_expr = stringf("(ite (= (|%s_m:R%dA %s| state) #b%s) ((_ extract %d %d) (|%s| state))\n %s)", - get_id(module), i, get_id(cell), Const(k+mem_offset, abits).as_string().c_str(), - width*(k+1)-1, width*k, memstate.c_str(), read_expr.c_str()); + get_id(module), i, get_id(mem->memid), Const(k+mem->start_offset, abits).as_string().c_str(), + mem->width*(k+1)-1, mem->width*k, memstate.c_str(), read_expr.c_str()); decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) (_ BitVec %d)\n %s) ; %s\n", - get_id(module), idcounter, get_id(module), width, read_expr.c_str(), log_signal(data_sig))); + get_id(module), idcounter, get_id(module), mem->width, read_expr.c_str(), log_signal(port.data))); decls.push_back(stringf("(define-fun |%s_m:R%dD %s| ((state |%s_s|)) (_ BitVec %d) (|%s#%d| state))\n", - get_id(module), i, get_id(cell), get_id(module), width, get_id(module), idcounter)); + get_id(module), i, get_id(mem->memid), get_id(module), mem->width, get_id(module), idcounter)); - register_bv(data_sig, idcounter++); + register_bv(port.data, idcounter++); } } else { if (statedt) dtmembers.push_back(stringf(" (|%s| (Array (_ BitVec %d) (_ BitVec %d))) ; %s\n", - memstate.c_str(), abits, width, get_id(cell))); + memstate.c_str(), abits, mem->width, get_id(mem->memid))); else decls.push_back(stringf("(declare-fun |%s| (|%s_s|) (Array (_ BitVec %d) (_ BitVec %d))) ; %s\n", - memstate.c_str(), get_id(module), abits, width, get_id(cell))); + memstate.c_str(), get_id(module), abits, mem->width, get_id(mem->memid))); decls.push_back(stringf("(define-fun |%s_m %s| ((state |%s_s|)) (Array (_ BitVec %d) (_ BitVec %d)) (|%s| state))\n", - get_id(module), get_id(cell), get_id(module), abits, width, memstate.c_str())); + get_id(module), get_id(mem->memid), get_id(module), abits, mem->width, memstate.c_str())); - for (int i = 0; i < rd_ports; i++) + for (int i = 0; i < GetSize(mem->rd_ports); i++) { - SigSpec addr_sig = cell->getPort(ID::RD_ADDR).extract(abits*i, abits); - SigSpec data_sig = cell->getPort(ID::RD_DATA).extract(width*i, width); + auto &port = mem->rd_ports[i]; + SigSpec addr_sig = port.addr; + addr_sig.extend_u0(abits); std::string addr = get_bv(addr_sig); - if (cell->getParam(ID::RD_CLK_ENABLE).extract(i).as_bool()) + if (port.clk_enable) log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! " - "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(data_sig), log_id(cell), log_id(module)); + "Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(port.data), log_id(mem->memid), log_id(module)); decls.push_back(stringf("(define-fun |%s_m:R%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), i, get_id(cell), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); + get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) (_ BitVec %d) (select (|%s| state) (|%s_m:R%dA %s| state))) ; %s\n", - get_id(module), idcounter, get_id(module), width, memstate.c_str(), get_id(module), i, get_id(cell), log_signal(data_sig))); + get_id(module), idcounter, get_id(module), mem->width, memstate.c_str(), get_id(module), i, get_id(mem->memid), log_signal(port.data))); decls.push_back(stringf("(define-fun |%s_m:R%dD %s| ((state |%s_s|)) (_ BitVec %d) (|%s#%d| state))\n", - get_id(module), i, get_id(cell), get_id(module), width, get_id(module), idcounter)); + get_id(module), i, get_id(mem->memid), get_id(module), mem->width, get_id(module), idcounter)); - register_bv(data_sig, idcounter++); + register_bv(port.data, idcounter++); } } - registers.insert(cell); + memory_queue.insert(mem); recursive_cells.erase(cell); return; } @@ -822,40 +876,51 @@ struct Smt2Worker for (auto bit : SigSpec(wire)) if (reg_bits.count(bit)) is_register = true; - if (wire->port_id || is_register || wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name[0] == '\\')) { + if (wire->port_id || is_register || wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name.isPublic())) { RTLIL::SigSpec sig = sigmap(wire); + std::vector<std::string> comments; if (wire->port_input) - decls.push_back(stringf("; yosys-smt2-input %s %d\n", get_id(wire), wire->width)); + comments.push_back(stringf("; yosys-smt2-input %s %d\n", get_id(wire), wire->width)); if (wire->port_output) - decls.push_back(stringf("; yosys-smt2-output %s %d\n", get_id(wire), wire->width)); + comments.push_back(stringf("; yosys-smt2-output %s %d\n", get_id(wire), wire->width)); if (is_register) - decls.push_back(stringf("; yosys-smt2-register %s %d\n", get_id(wire), wire->width)); - if (wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name[0] == '\\')) - decls.push_back(stringf("; yosys-smt2-wire %s %d\n", get_id(wire), wire->width)); + comments.push_back(stringf("; yosys-smt2-register %s %d\n", get_id(wire), wire->width)); + if (wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name.isPublic())) + comments.push_back(stringf("; yosys-smt2-wire %s %d\n", get_id(wire), wire->width)); if (GetSize(wire) == 1 && (clock_posedge.count(sig) || clock_negedge.count(sig))) - decls.push_back(stringf("; yosys-smt2-clock %s%s%s\n", get_id(wire), + comments.push_back(stringf("; yosys-smt2-clock %s%s%s\n", get_id(wire), clock_posedge.count(sig) ? " posedge" : "", clock_negedge.count(sig) ? " negedge" : "")); if (bvmode && GetSize(sig) > 1) { + std::string sig_bv = get_bv(sig); + if (!comments.empty()) + decls.insert(decls.end(), comments.begin(), comments.end()); decls.push_back(stringf("(define-fun |%s_n %s| ((state |%s_s|)) (_ BitVec %d) %s)\n", - get_id(module), get_id(wire), get_id(module), GetSize(sig), get_bv(sig).c_str())); + get_id(module), get_id(wire), get_id(module), GetSize(sig), sig_bv.c_str())); if (wire->port_input) ex_input_eq.push_back(stringf(" (= (|%s_n %s| state) (|%s_n %s| other_state))", get_id(module), get_id(wire), get_id(module), get_id(wire))); } else { - for (int i = 0; i < GetSize(sig); i++) + std::vector<std::string> sig_bool; + for (int i = 0; i < GetSize(sig); i++) { + sig_bool.push_back(get_bool(sig[i])); + } + if (!comments.empty()) + decls.insert(decls.end(), comments.begin(), comments.end()); + for (int i = 0; i < GetSize(sig); i++) { if (GetSize(sig) > 1) { decls.push_back(stringf("(define-fun |%s_n %s %d| ((state |%s_s|)) Bool %s)\n", - get_id(module), get_id(wire), i, get_id(module), get_bool(sig[i]).c_str())); + get_id(module), get_id(wire), i, get_id(module), sig_bool[i].c_str())); if (wire->port_input) ex_input_eq.push_back(stringf(" (= (|%s_n %s %d| state) (|%s_n %s %d| other_state))", get_id(module), get_id(wire), i, get_id(module), get_id(wire), i)); } else { decls.push_back(stringf("(define-fun |%s_n %s| ((state |%s_s|)) Bool %s)\n", - get_id(module), get_id(wire), get_id(module), get_bool(sig[i]).c_str())); + get_id(module), get_id(wire), get_id(module), sig_bool[i].c_str())); if (wire->port_input) ex_input_eq.push_back(stringf(" (= (|%s_n %s| state) (|%s_n %s| other_state))", get_id(module), get_id(wire), get_id(module), get_id(wire))); } + } } } } @@ -966,7 +1031,7 @@ struct Smt2Worker } } - for (int iter = 1; !registers.empty(); iter++) + for (int iter = 1; !registers.empty() || !memory_queue.empty(); iter++) { pool<Cell*> this_regs; this_regs.swap(registers); @@ -999,152 +1064,156 @@ struct Smt2Worker if (cell->type == ID($anyconst)) ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Y)).c_str(), get_bv(cell->getPort(ID::Y), "other_state").c_str())); } + } - if (cell->type == ID($mem)) - { - int arrayid = memarrays.at(cell); + std::set<Mem*> this_mems; + this_mems.swap(memory_queue); + + for (auto mem : this_mems) + { + int arrayid = memarrays.at(mem); + + int abits = ceil_log2(mem->size);; + + bool has_sync_wr = false; + bool has_async_wr = false; + for (auto &port : mem->wr_ports) { + if (port.clk_enable) + has_sync_wr = true; + else + has_async_wr = true; + } - int abits = cell->getParam(ID::ABITS).as_int(); - int width = cell->getParam(ID::WIDTH).as_int(); - int wr_ports = cell->getParam(ID::WR_PORTS).as_int(); + string initial_memstate, final_memstate; - bool async_read = false; - string initial_memstate, final_memstate; + if (has_async_wr) { + log_assert(!has_sync_wr); + initial_memstate = stringf("%s#%d#0", get_id(module), arrayid); + final_memstate = stringf("%s#%d#final", get_id(module), arrayid); + } - if (!cell->getParam(ID::WR_CLK_ENABLE).is_fully_ones()) { - log_assert(cell->getParam(ID::WR_CLK_ENABLE).is_fully_zero()); - async_read = true; - initial_memstate = stringf("%s#%d#0", get_id(module), arrayid); - final_memstate = stringf("%s#%d#final", get_id(module), arrayid); + if (statebv) + { + if (has_async_wr) { + makebits(final_memstate, mem->width*mem->size, get_id(mem->memid)); } - if (statebv) + for (int i = 0; i < GetSize(mem->wr_ports); i++) { - int mem_size = cell->getParam(ID::SIZE).as_int(); - int mem_offset = cell->getParam(ID::OFFSET).as_int(); - - if (async_read) { - makebits(final_memstate, width*mem_size, get_id(cell)); + auto &port = mem->wr_ports[i]; + SigSpec addr_sig = port.addr; + addr_sig.extend_u0(abits); + + std::string addr = get_bv(addr_sig); + std::string data = get_bv(port.data); + std::string mask = get_bv(port.en); + + decls.push_back(stringf("(define-fun |%s_m:W%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); + addr = stringf("(|%s_m:W%dA %s| state)", get_id(module), i, get_id(mem->memid)); + + decls.push_back(stringf("(define-fun |%s_m:W%dD %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(mem->memid), get_id(module), mem->width, data.c_str(), log_signal(port.data))); + data = stringf("(|%s_m:W%dD %s| state)", get_id(module), i, get_id(mem->memid)); + + decls.push_back(stringf("(define-fun |%s_m:W%dM %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(mem->memid), get_id(module), mem->width, mask.c_str(), log_signal(port.en))); + mask = stringf("(|%s_m:W%dM %s| state)", get_id(module), i, get_id(mem->memid)); + + std::string data_expr; + + for (int k = mem->size-1; k >= 0; k--) { + std::string new_data = stringf("(bvor (bvand %s %s) (bvand ((_ extract %d %d) (|%s#%d#%d| state)) (bvnot %s)))", + data.c_str(), mask.c_str(), mem->width*(k+1)-1, mem->width*k, get_id(module), arrayid, i, mask.c_str()); + data_expr += stringf("\n (ite (= %s #b%s) %s ((_ extract %d %d) (|%s#%d#%d| state)))", + addr.c_str(), Const(k+mem->start_offset, abits).as_string().c_str(), new_data.c_str(), + mem->width*(k+1)-1, mem->width*k, get_id(module), arrayid, i); } - for (int i = 0; i < wr_ports; i++) - { - SigSpec addr_sig = cell->getPort(ID::WR_ADDR).extract(abits*i, abits); - SigSpec data_sig = cell->getPort(ID::WR_DATA).extract(width*i, width); - SigSpec mask_sig = cell->getPort(ID::WR_EN).extract(width*i, width); + decls.push_back(stringf("(define-fun |%s#%d#%d| ((state |%s_s|)) (_ BitVec %d) (concat%s)) ; %s\n", + get_id(module), arrayid, i+1, get_id(module), mem->width*mem->size, data_expr.c_str(), get_id(mem->memid))); + } + } + else + { + if (has_async_wr) { + if (statedt) + dtmembers.push_back(stringf(" (|%s| (Array (_ BitVec %d) (_ BitVec %d))) ; %s\n", + initial_memstate.c_str(), abits, mem->width, get_id(mem->memid))); + else + decls.push_back(stringf("(declare-fun |%s| (|%s_s|) (Array (_ BitVec %d) (_ BitVec %d))) ; %s\n", + initial_memstate.c_str(), get_id(module), abits, mem->width, get_id(mem->memid))); + } - std::string addr = get_bv(addr_sig); - std::string data = get_bv(data_sig); - std::string mask = get_bv(mask_sig); + for (int i = 0; i < GetSize(mem->wr_ports); i++) + { + auto &port = mem->wr_ports[i]; + SigSpec addr_sig = port.addr; + addr_sig.extend_u0(abits); - decls.push_back(stringf("(define-fun |%s_m:W%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), i, get_id(cell), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); - addr = stringf("(|%s_m:W%dA %s| state)", get_id(module), i, get_id(cell)); + std::string addr = get_bv(addr_sig); + std::string data = get_bv(port.data); + std::string mask = get_bv(port.en); - decls.push_back(stringf("(define-fun |%s_m:W%dD %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), i, get_id(cell), get_id(module), width, data.c_str(), log_signal(data_sig))); - data = stringf("(|%s_m:W%dD %s| state)", get_id(module), i, get_id(cell)); + decls.push_back(stringf("(define-fun |%s_m:W%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(mem->memid), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); + addr = stringf("(|%s_m:W%dA %s| state)", get_id(module), i, get_id(mem->memid)); - decls.push_back(stringf("(define-fun |%s_m:W%dM %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), i, get_id(cell), get_id(module), width, mask.c_str(), log_signal(mask_sig))); - mask = stringf("(|%s_m:W%dM %s| state)", get_id(module), i, get_id(cell)); + decls.push_back(stringf("(define-fun |%s_m:W%dD %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(mem->memid), get_id(module), mem->width, data.c_str(), log_signal(port.data))); + data = stringf("(|%s_m:W%dD %s| state)", get_id(module), i, get_id(mem->memid)); - std::string data_expr; + decls.push_back(stringf("(define-fun |%s_m:W%dM %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", + get_id(module), i, get_id(mem->memid), get_id(module), mem->width, mask.c_str(), log_signal(port.en))); + mask = stringf("(|%s_m:W%dM %s| state)", get_id(module), i, get_id(mem->memid)); - for (int k = mem_size-1; k >= 0; k--) { - std::string new_data = stringf("(bvor (bvand %s %s) (bvand ((_ extract %d %d) (|%s#%d#%d| state)) (bvnot %s)))", - data.c_str(), mask.c_str(), width*(k+1)-1, width*k, get_id(module), arrayid, i, mask.c_str()); - data_expr += stringf("\n (ite (= %s #b%s) %s ((_ extract %d %d) (|%s#%d#%d| state)))", - addr.c_str(), Const(k+mem_offset, abits).as_string().c_str(), new_data.c_str(), - width*(k+1)-1, width*k, get_id(module), arrayid, i); - } + data = stringf("(bvor (bvand %s %s) (bvand (select (|%s#%d#%d| state) %s) (bvnot %s)))", + data.c_str(), mask.c_str(), get_id(module), arrayid, i, addr.c_str(), mask.c_str()); - decls.push_back(stringf("(define-fun |%s#%d#%d| ((state |%s_s|)) (_ BitVec %d) (concat%s)) ; %s\n", - get_id(module), arrayid, i+1, get_id(module), width*mem_size, data_expr.c_str(), get_id(cell))); - } + decls.push_back(stringf("(define-fun |%s#%d#%d| ((state |%s_s|)) (Array (_ BitVec %d) (_ BitVec %d)) " + "(store (|%s#%d#%d| state) %s %s)) ; %s\n", + get_id(module), arrayid, i+1, get_id(module), abits, mem->width, + get_id(module), arrayid, i, addr.c_str(), data.c_str(), get_id(mem->memid))); } - else - { - if (async_read) { - if (statedt) - dtmembers.push_back(stringf(" (|%s| (Array (_ BitVec %d) (_ BitVec %d))) ; %s\n", - initial_memstate.c_str(), abits, width, get_id(cell))); - else - decls.push_back(stringf("(declare-fun |%s| (|%s_s|) (Array (_ BitVec %d) (_ BitVec %d))) ; %s\n", - initial_memstate.c_str(), get_id(module), abits, width, get_id(cell))); - } - - for (int i = 0; i < wr_ports; i++) - { - SigSpec addr_sig = cell->getPort(ID::WR_ADDR).extract(abits*i, abits); - SigSpec data_sig = cell->getPort(ID::WR_DATA).extract(width*i, width); - SigSpec mask_sig = cell->getPort(ID::WR_EN).extract(width*i, width); + } - std::string addr = get_bv(addr_sig); - std::string data = get_bv(data_sig); - std::string mask = get_bv(mask_sig); + std::string expr_d = stringf("(|%s#%d#%d| state)", get_id(module), arrayid, GetSize(mem->wr_ports)); + std::string expr_q = stringf("(|%s#%d#0| next_state)", get_id(module), arrayid); + trans.push_back(stringf(" (= %s %s) ; %s\n", expr_d.c_str(), expr_q.c_str(), get_id(mem->memid))); + ex_state_eq.push_back(stringf("(= (|%s#%d#0| state) (|%s#%d#0| other_state))", get_id(module), arrayid, get_id(module), arrayid)); - decls.push_back(stringf("(define-fun |%s_m:W%dA %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), i, get_id(cell), get_id(module), abits, addr.c_str(), log_signal(addr_sig))); - addr = stringf("(|%s_m:W%dA %s| state)", get_id(module), i, get_id(cell)); + if (has_async_wr) + hier.push_back(stringf(" (= %s (|%s| state)) ; %s\n", expr_d.c_str(), final_memstate.c_str(), get_id(mem->memid))); - decls.push_back(stringf("(define-fun |%s_m:W%dD %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), i, get_id(cell), get_id(module), width, data.c_str(), log_signal(data_sig))); - data = stringf("(|%s_m:W%dD %s| state)", get_id(module), i, get_id(cell)); + Const init_data = mem->get_init_data(); - decls.push_back(stringf("(define-fun |%s_m:W%dM %s| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n", - get_id(module), i, get_id(cell), get_id(module), width, mask.c_str(), log_signal(mask_sig))); - mask = stringf("(|%s_m:W%dM %s| state)", get_id(module), i, get_id(cell)); + for (int i = 0; i < mem->size; i++) + { + if (i*mem->width >= GetSize(init_data)) + break; - data = stringf("(bvor (bvand %s %s) (bvand (select (|%s#%d#%d| state) %s) (bvnot %s)))", - data.c_str(), mask.c_str(), get_id(module), arrayid, i, addr.c_str(), mask.c_str()); + Const initword = init_data.extract(i*mem->width, mem->width, State::Sx); + Const initmask = initword; + bool gen_init_constr = false; - decls.push_back(stringf("(define-fun |%s#%d#%d| ((state |%s_s|)) (Array (_ BitVec %d) (_ BitVec %d)) " - "(store (|%s#%d#%d| state) %s %s)) ; %s\n", - get_id(module), arrayid, i+1, get_id(module), abits, width, - get_id(module), arrayid, i, addr.c_str(), data.c_str(), get_id(cell))); + for (int k = 0; k < GetSize(initword); k++) { + if (initword[k] == State::S0 || initword[k] == State::S1) { + gen_init_constr = true; + initmask[k] = State::S1; + } else { + initmask[k] = State::S0; + initword[k] = State::S0; } } - std::string expr_d = stringf("(|%s#%d#%d| state)", get_id(module), arrayid, wr_ports); - std::string expr_q = stringf("(|%s#%d#0| next_state)", get_id(module), arrayid); - trans.push_back(stringf(" (= %s %s) ; %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell))); - ex_state_eq.push_back(stringf("(= (|%s#%d#0| state) (|%s#%d#0| other_state))", get_id(module), arrayid, get_id(module), arrayid)); - - if (async_read) - hier.push_back(stringf(" (= %s (|%s| state)) ; %s\n", expr_d.c_str(), final_memstate.c_str(), get_id(cell))); - - Const init_data = cell->getParam(ID::INIT); - int memsize = cell->getParam(ID::SIZE).as_int(); - - for (int i = 0; i < memsize; i++) + if (gen_init_constr) { - if (i*width >= GetSize(init_data)) - break; - - Const initword = init_data.extract(i*width, width, State::Sx); - Const initmask = initword; - bool gen_init_constr = false; - - for (int k = 0; k < GetSize(initword); k++) { - if (initword[k] == State::S0 || initword[k] == State::S1) { - gen_init_constr = true; - initmask[k] = State::S1; - } else { - initmask[k] = State::S0; - initword[k] = State::S0; - } - } - - if (gen_init_constr) - { - if (statebv) - /* FIXME */; - else - init_list.push_back(stringf("(= (bvand (select (|%s#%d#0| state) #b%s) #b%s) #b%s) ; %s[%d]", - get_id(module), arrayid, Const(i, abits).as_string().c_str(), - initmask.as_string().c_str(), initword.as_string().c_str(), get_id(cell), i)); - } + if (statebv) + /* FIXME */; + else + init_list.push_back(stringf("(= (bvand (select (|%s#%d#0| state) #b%s) #b%s) #b%s) ; %s[%d]", + get_id(module), arrayid, Const(i, abits).as_string().c_str(), + initmask.as_string().c_str(), initword.as_string().c_str(), get_id(mem->memid), i)); } } } @@ -1280,7 +1349,7 @@ struct Smt2Worker struct Smt2Backend : public Backend { Smt2Backend() : Backend("smt2", "write design to SMT-LIBv2 file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1387,8 +1456,12 @@ struct Smt2Backend : public Backend { log(" use the given template file. the line containing only the token '%%%%'\n"); log(" is replaced with the regular output of this command.\n"); log("\n"); + log(" -solver-option <option> <value>\n"); + log(" emit a `; yosys-smt2-solver-option` directive for yosys-smtbmc to write\n"); + log(" the given option as a `(set-option ...)` command in the SMT-LIBv2.\n"); + log("\n"); log("[1] For more information on SMT-LIBv2 visit http://smt-lib.org/ or read David\n"); - log("R. Cok's tutorial: http://www.grammatech.com/resources/smt/SMTLIBTutorial.pdf\n"); + log("R. Cok's tutorial: https://smtlib.github.io/jSMTLIB/SMTLIBTutorial.pdf\n"); log("\n"); log("---------------------------------------------------------------------------\n"); log("\n"); @@ -1436,11 +1509,12 @@ struct Smt2Backend : public Backend { log("from non-zero to zero in the test design.\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { std::ifstream template_f; bool bvmode = true, memmode = true, wiresmode = false, verbose = false, statebv = false, statedt = false; bool forallmode = false; + dict<std::string, std::string> solver_options; log_header(design, "Executing SMT2 backend.\n"); @@ -1484,6 +1558,11 @@ struct Smt2Backend : public Backend { verbose = true; continue; } + if (args[argidx] == "-solver-option" && argidx+2 < args.size()) { + solver_options.emplace(args[argidx+1], args[argidx+2]); + argidx += 2; + continue; + } break; } extra_args(f, filename, args, argidx); @@ -1514,6 +1593,9 @@ struct Smt2Backend : public Backend { if (statedt) *f << stringf("; yosys-smt2-stdt\n"); + for (auto &it : solver_options) + *f << stringf("; yosys-smt2-solver-option %s %s\n", it.first.c_str(), it.second.c_str()); + std::vector<RTLIL::Module*> sorted_modules; // extract module dependencies @@ -1562,7 +1644,7 @@ struct Smt2Backend : public Backend { for (auto module : sorted_modules) { - if (module->get_blackbox_attribute() || module->has_memories_warn() || module->has_processes_warn()) + if (module->get_blackbox_attribute() || module->has_processes_warn()) continue; log("Creating SMT-LIBv2 representation of module %s.\n", log_id(module)); diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py index 03f001bfd..da5a7f57e 100644 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -817,6 +817,24 @@ def write_vcd_trace(steps_start, steps_stop, index): vcd.set_time(steps_stop) +def char_ok_in_verilog(c,i): + if ('A' <= c <= 'Z'): return True + if ('a' <= c <= 'z'): return True + if ('0' <= c <= '9' and i>0): return True + if (c == '_'): return True + if (c == '$'): return True + return False + +def escape_identifier(identifier): + if type(identifier) is list: + return map(escape_identifier, identifier) + if "." in identifier: + return ".".join(escape_identifier(identifier.split("."))) + if (all(char_ok_in_verilog(identifier[i],i) for i in range(0, len(identifier)))): + return identifier + return "\\"+identifier+" " + + def write_vlogtb_trace(steps_start, steps_stop, index): filename = vlogtbfile.replace("%", index) @@ -858,12 +876,12 @@ def write_vlogtb_trace(steps_start, steps_stop, index): for name, width in primary_inputs: if name in clock_inputs: - print(" wire [%d:0] PI_%s = clock;" % (width-1, name), file=f) + print(" wire [%d:0] %s = clock;" % (width-1, escape_identifier("PI_"+name)), file=f) else: - print(" reg [%d:0] PI_%s;" % (width-1, name), file=f) + print(" reg [%d:0] %s;" % (width-1, escape_identifier("PI_"+name)), file=f) - print(" %s UUT (" % vlogtb_topmod, file=f) - print(",\n".join(" .{name}(PI_{name})".format(name=name) for name, _ in primary_inputs), file=f) + print(" %s UUT (" % escape_identifier(vlogtb_topmod), file=f) + print(",\n".join(" .%s(%s)" % (escape_identifier(name), escape_identifier("PI_"+name)) for name, _ in primary_inputs), file=f) print(" );", file=f) print("`ifndef VERILATOR", file=f) @@ -893,14 +911,14 @@ def write_vlogtb_trace(steps_start, steps_stop, index): for n in reg: if n.startswith("$"): hidden_net = True - print(" %sUUT.%s = %d'b%s;" % ("// " if hidden_net else "", ".".join(reg), len(val), val), file=f) + print(" %sUUT.%s = %d'b%s;" % ("// " if hidden_net else "", ".".join(escape_identifier(reg)), len(val), val), file=f) anyconsts = sorted(smt.hieranyconsts(vlogtb_topmod)) for info in anyconsts: if info[3] is not None: modstate = smt.net_expr(vlogtb_topmod, vlogtb_state.replace("@@step_idx@@", str(steps_start)), info[0]) value = smt.bv2bin(smt.get("(|%s| %s)" % (info[1], modstate))) - print(" UUT.%s = %d'b%s;" % (".".join(info[0] + [info[3]]), len(value), value), file=f); + print(" UUT.%s = %d'b%s;" % (".".join(escape_identifier(info[0] + [info[3]])), len(value), value), file=f); mems = sorted(smt.hiermems(vlogtb_topmod)) for mempath in mems: @@ -924,7 +942,7 @@ def write_vlogtb_trace(steps_start, steps_stop, index): addr_data[addr] = data for addr, data in addr_data.items(): - print(" UUT.%s[%d'b%s] = %d'b%s;" % (".".join(mempath), len(addr), addr, len(data), data), file=f) + print(" UUT.%s[%d'b%s] = %d'b%s;" % (".".join(escape_identifier(mempath)), len(addr), addr, len(data), data), file=f) print("", file=f) anyseqs = sorted(smt.hieranyseqs(vlogtb_topmod)) @@ -940,18 +958,18 @@ def write_vlogtb_trace(steps_start, steps_stop, index): for name, val in zip(pi_names, pi_values): if i > 0: - print(" PI_%s <= %d'b%s;" % (".".join(name), len(val), val), file=f) + print(" %s <= %d'b%s;" % (escape_identifier("PI_"+".".join(name)), len(val), val), file=f) else: - print(" PI_%s = %d'b%s;" % (".".join(name), len(val), val), file=f) + print(" %s = %d'b%s;" % (escape_identifier("PI_"+".".join(name)), len(val), val), file=f) for info in anyseqs: if info[3] is not None: modstate = smt.net_expr(vlogtb_topmod, vlogtb_state.replace("@@step_idx@@", str(i)), info[0]) value = smt.bv2bin(smt.get("(|%s| %s)" % (info[1], modstate))) if i > 0: - print(" UUT.%s <= %d'b%s;" % (".".join(info[0] + [info[3]]), len(value), value), file=f); + print(" UUT.%s <= %d'b%s;" % (".".join(escape_identifier(info[0] + [info[3]])), len(value), value), file=f); else: - print(" UUT.%s = %d'b%s;" % (".".join(info[0] + [info[3]]), len(value), value), file=f); + print(" UUT.%s = %d'b%s;" % (".".join(escape_identifier(info[0] + [info[3]])), len(value), value), file=f); if i > 0: print(" end", file=f) @@ -1275,10 +1293,10 @@ def smt_pop(): asserts_consequent_cache.pop() smt.write("(pop 1)") -def smt_check_sat(): +def smt_check_sat(expected=["sat", "unsat"]): if asserts_cache_dirty: smt_forall_assert() - return smt.check_sat() + return smt.check_sat(expected=expected) if tempind: retstatus = "FAILED" diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index 72ab39d39..516091011 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -124,6 +124,7 @@ class SmtIo: self.timeout = 0 self.produce_models = True self.smt2cache = [list()] + self.smt2_options = dict() self.p = None self.p_index = solvers_index solvers_index += 1 @@ -258,14 +259,24 @@ class SmtIo: for stmt in self.info_stmts: self.write(stmt) - if self.forall and self.solver == "yices": - self.write("(set-option :yices-ef-max-iters 1000000000)") - if self.produce_models: self.write("(set-option :produce-models true)") + #See the SMT-LIB Standard, Section 4.1.7 + modestart_options = [":global-declarations", ":interactive-mode", ":produce-assertions", ":produce-assignments", ":produce-models", ":produce-proofs", ":produce-unsat-assumptions", ":produce-unsat-cores", ":random-seed"] + for key, val in self.smt2_options.items(): + if key in modestart_options: + self.write("(set-option {} {})".format(key, val)) + self.write("(set-logic %s)" % self.logic) + if self.forall and self.solver == "yices": + self.write("(set-option :yices-ef-max-iters 1000000000)") + + for key, val in self.smt2_options.items(): + if key not in modestart_options: + self.write("(set-option {} {})".format(key, val)) + def timestamp(self): secs = int(time() - self.start_time) return "## %3d:%02d:%02d " % (secs // (60*60), (secs // 60) % 60, secs % 60) @@ -468,6 +479,9 @@ class SmtIo: fields = stmt.split() + if fields[1] == "yosys-smt2-solver-option": + self.smt2_options[fields[2]] = fields[3] + if fields[1] == "yosys-smt2-nomem": if self.logic is None: self.logic_ax = False @@ -653,7 +667,7 @@ class SmtIo: return stmt - def check_sat(self): + def check_sat(self, expected=["sat", "unsat", "unknown", "timeout", "interrupted"]): if self.debug_print: print("> (check-sat)") if self.debug_file and not self.nocomments: @@ -740,7 +754,7 @@ class SmtIo: print("(check-sat)", file=self.debug_file) self.debug_file.flush() - if result not in ["sat", "unsat", "unknown", "timeout", "interrupted"]: + if result not in expected: if result == "": print("%s Unexpected EOF response from solver." % (self.timestamp()), flush=True) else: diff --git a/backends/smv/.gitignore b/backends/smv/.gitignore new file mode 100644 index 000000000..d23d492d7 --- /dev/null +++ b/backends/smv/.gitignore @@ -0,0 +1 @@ +/test_cells.tmp/ diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc index 2fc7099f4..4e5c6050d 100644 --- a/backends/smv/smv.cc +++ b/backends/smv/smv.cc @@ -702,7 +702,7 @@ struct SmvWorker struct SmvBackend : public Backend { SmvBackend() : Backend("smv", "write design to SMV file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -720,7 +720,7 @@ struct SmvBackend : public Backend { log("THIS COMMAND IS UNDER CONSTRUCTION\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { std::ifstream template_f; bool verbose = false; diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index 84e93b61b..aa20f106a 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -130,7 +130,7 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De struct SpiceBackend : public Backend { SpiceBackend() : Backend("spice", "write design to SPICE netlist file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -159,7 +159,7 @@ struct SpiceBackend : public Backend { log(" set the specified module as design top module\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { std::string top_module_name; RTLIL::Module *top_module = NULL; diff --git a/backends/table/table.cc b/backends/table/table.cc index 796f18059..77642ccbd 100644 --- a/backends/table/table.cc +++ b/backends/table/table.cc @@ -29,7 +29,7 @@ PRIVATE_NAMESPACE_BEGIN struct TableBackend : public Backend { TableBackend() : Backend("table", "write design as connectivity table") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -48,7 +48,7 @@ struct TableBackend : public Backend { log("module inputs and outputs are output using cell type and port '-' and with\n"); log("'pi' (primary input) or 'po' (primary output) or 'pio' as direction.\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing TABLE backend.\n"); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 4f44a053a..9523f4a52 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -25,6 +25,8 @@ #include "kernel/celltypes.h" #include "kernel/log.h" #include "kernel/sigtools.h" +#include "kernel/ff.h" +#include "kernel/mem.h" #include <string> #include <sstream> #include <set> @@ -33,10 +35,10 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit; +bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog; int auto_name_counter, auto_name_offset, auto_name_digits, extmem_counter; std::map<RTLIL::IdString, int> auto_name_map; -std::set<RTLIL::IdString> reg_wires, reg_ct; +std::set<RTLIL::IdString> reg_wires; std::string auto_prefix, extmem_prefix; RTLIL::Module *active_module; @@ -433,10 +435,250 @@ void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire) #endif } -void dump_memory(std::ostream &f, std::string indent, RTLIL::Memory *memory) +void dump_memory(std::ostream &f, std::string indent, Mem &mem) { - dump_attributes(f, indent, memory->attributes); - f << stringf("%s" "reg [%d:0] %s [%d:%d];\n", indent.c_str(), memory->width-1, id(memory->name).c_str(), memory->size+memory->start_offset-1, memory->start_offset); + std::string mem_id = id(mem.memid); + + dump_attributes(f, indent, mem.attributes); + f << stringf("%s" "reg [%d:0] %s [%d:%d];\n", indent.c_str(), mem.width-1, mem_id.c_str(), mem.size+mem.start_offset-1, mem.start_offset); + + // for memory block make something like: + // reg [7:0] memid [3:0]; + // initial begin + // memid[0] = ... + // end + if (!mem.inits.empty()) + { + if (extmem) + { + std::string extmem_filename = stringf("%s-%d.mem", extmem_prefix.c_str(), extmem_counter++); + + std::string extmem_filename_esc; + for (auto c : extmem_filename) + { + if (c == '\n') + extmem_filename_esc += "\\n"; + else if (c == '\t') + extmem_filename_esc += "\\t"; + else if (c < 32) + extmem_filename_esc += stringf("\\%03o", c); + else if (c == '"') + extmem_filename_esc += "\\\""; + else if (c == '\\') + extmem_filename_esc += "\\\\"; + else + extmem_filename_esc += c; + } + f << stringf("%s" "initial $readmemb(\"%s\", %s);\n", indent.c_str(), extmem_filename_esc.c_str(), mem_id.c_str()); + + std::ofstream extmem_f(extmem_filename, std::ofstream::trunc); + if (extmem_f.fail()) + log_error("Can't open file `%s' for writing: %s\n", extmem_filename.c_str(), strerror(errno)); + else + { + Const data = mem.get_init_data(); + for (int i=0; i<mem.size; i++) + { + RTLIL::Const element = data.extract(i*mem.width, mem.width); + for (int j=0; j<element.size(); j++) + { + switch (element[element.size()-j-1]) + { + case State::S0: extmem_f << '0'; break; + case State::S1: extmem_f << '1'; break; + case State::Sx: extmem_f << 'x'; break; + case State::Sz: extmem_f << 'z'; break; + case State::Sa: extmem_f << '_'; break; + case State::Sm: log_error("Found marker state in final netlist."); + } + } + extmem_f << '\n'; + } + } + } + else + { + f << stringf("%s" "initial begin\n", indent.c_str()); + for (auto &init : mem.inits) { + int words = GetSize(init.data) / mem.width; + int start = init.addr.as_int(); + for (int i=0; i<words; i++) + { + f << stringf("%s" " %s[%d] = ", indent.c_str(), mem_id.c_str(), i + start); + dump_const(f, init.data.extract(i*mem.width, mem.width)); + f << stringf(";\n"); + } + } + f << stringf("%s" "end\n", indent.c_str()); + } + } + + // create a map : "edge clk" -> expressions within that clock domain + dict<std::string, std::vector<std::string>> clk_to_lof_body; + clk_to_lof_body[""] = std::vector<std::string>(); + std::string clk_domain_str; + // create a list of reg declarations + std::vector<std::string> lof_reg_declarations; + + // read ports + for (auto &port : mem.rd_ports) + { + if (port.clk_enable) + { + { + std::ostringstream os; + dump_sigspec(os, port.clk); + clk_domain_str = stringf("%sedge %s", port.clk_polarity ? "pos" : "neg", os.str().c_str()); + if( clk_to_lof_body.count(clk_domain_str) == 0 ) + clk_to_lof_body[clk_domain_str] = std::vector<std::string>(); + } + if (!port.transparent) + { + // for clocked read ports make something like: + // reg [..] temp_id; + // always @(posedge clk) + // if (rd_en) temp_id <= array_reg[r_addr]; + // assign r_data = temp_id; + std::string temp_id = next_auto_id(); + lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.data.size() - 1, temp_id.c_str()) ); + { + std::ostringstream os; + if (port.en != RTLIL::SigBit(true)) + { + os << stringf("if ("); + dump_sigspec(os, port.en); + os << stringf(") "); + } + os << stringf("%s <= %s[", temp_id.c_str(), mem_id.c_str()); + dump_sigspec(os, port.addr); + os << stringf("];\n"); + clk_to_lof_body[clk_domain_str].push_back(os.str()); + } + { + std::ostringstream os; + dump_sigspec(os, port.data); + std::string line = stringf("assign %s = %s;\n", os.str().c_str(), temp_id.c_str()); + clk_to_lof_body[""].push_back(line); + } + } + else + { + // for rd-transparent read-ports make something like: + // reg [..] temp_id; + // always @(posedge clk) + // temp_id <= r_addr; + // assign r_data = array_reg[temp_id]; + std::string temp_id = next_auto_id(); + lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", port.addr.size() - 1, temp_id.c_str()) ); + { + std::ostringstream os; + dump_sigspec(os, port.addr); + std::string line = stringf("%s <= %s;\n", temp_id.c_str(), os.str().c_str()); + clk_to_lof_body[clk_domain_str].push_back(line); + } + { + std::ostringstream os; + dump_sigspec(os, port.data); + std::string line = stringf("assign %s = %s[%s];\n", os.str().c_str(), mem_id.c_str(), temp_id.c_str()); + clk_to_lof_body[""].push_back(line); + } + } + } else { + // for non-clocked read-ports make something like: + // assign r_data = array_reg[r_addr]; + std::ostringstream os, os2; + dump_sigspec(os, port.data); + dump_sigspec(os2, port.addr); + std::string line = stringf("assign %s = %s[%s];\n", os.str().c_str(), mem_id.c_str(), os2.str().c_str()); + clk_to_lof_body[""].push_back(line); + } + } + + // write ports + for (auto &port : mem.wr_ports) + { + { + std::ostringstream os; + dump_sigspec(os, port.clk); + clk_domain_str = stringf("%sedge %s", port.clk_polarity ? "pos" : "neg", os.str().c_str()); + if( clk_to_lof_body.count(clk_domain_str) == 0 ) + clk_to_lof_body[clk_domain_str] = std::vector<std::string>(); + } + // make something like: + // always @(posedge clk) + // if (wr_en_bit) memid[w_addr][??] <= w_data[??]; + // ... + for (int i = 0; i < GetSize(port.en); i++) + { + int start_i = i, width = 1; + SigBit wen_bit = port.en[i]; + + while (i+1 < GetSize(port.en) && active_sigmap(port.en[i+1]) == active_sigmap(wen_bit)) + i++, width++; + + if (wen_bit == State::S0) + continue; + + std::ostringstream os; + if (wen_bit != State::S1) + { + os << stringf("if ("); + dump_sigspec(os, wen_bit); + os << stringf(") "); + } + os << stringf("%s[", mem_id.c_str()); + dump_sigspec(os, port.addr); + if (width == GetSize(port.en)) + os << stringf("] <= "); + else + os << stringf("][%d:%d] <= ", i, start_i); + dump_sigspec(os, port.data.extract(start_i, width)); + os << stringf(";\n"); + clk_to_lof_body[clk_domain_str].push_back(os.str()); + } + } + // Output Verilog that looks something like this: + // reg [..] _3_; + // always @(posedge CLK2) begin + // _3_ <= memory[D1ADDR]; + // if (A1EN) + // memory[A1ADDR] <= A1DATA; + // if (A2EN) + // memory[A2ADDR] <= A2DATA; + // ... + // end + // always @(negedge CLK1) begin + // if (C1EN) + // memory[C1ADDR] <= C1DATA; + // end + // ... + // assign D1DATA = _3_; + // assign D2DATA <= memory[D2ADDR]; + + // the reg ... definitions + for(auto ® : lof_reg_declarations) + { + f << stringf("%s" "%s", indent.c_str(), reg.c_str()); + } + // the block of expressions by clock domain + for(auto &pair : clk_to_lof_body) + { + std::string clk_domain = pair.first; + std::vector<std::string> lof_lines = pair.second; + if( clk_domain != "") + { + f << stringf("%s" "always%s @(%s) begin\n", indent.c_str(), systemverilog ? "_ff" : "", clk_domain.c_str()); + for(auto &line : lof_lines) + f << stringf("%s%s" "%s", indent.c_str(), indent.c_str(), line.c_str()); + f << stringf("%s" "end\n", indent.c_str()); + } + else + { + // the non-clocked assignments + for(auto &line : lof_lines) + f << stringf("%s" "%s", indent.c_str(), line.c_str()); + } + } } void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, bool gen_signed = true) @@ -451,7 +693,7 @@ void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, b std::string cellname(RTLIL::Cell *cell) { - if (!norename && cell->name[0] == '$' && reg_ct.count(cell->type) && cell->hasPort(ID::Q)) + if (!norename && cell->name[0] == '$' && RTLIL::builtin_ff_cell_types().count(cell->type) && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_))) { RTLIL::SigSpec sig = cell->getPort(ID::Q); if (GetSize(sig) != 1 || sig.is_fully_const()) @@ -605,93 +847,6 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } - if (cell->type.begins_with("$_DFF_")) - { - std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name); - - if (!out_is_reg_wire) { - f << stringf("%s" "reg %s", indent.c_str(), reg_name.c_str()); - dump_reg_init(f, cell->getPort(ID::Q)); - f << ";\n"; - } - - dump_attributes(f, indent, cell->attributes); - f << stringf("%s" "always @(%sedge ", indent.c_str(), cell->type[6] == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->getPort(ID::C)); - if (cell->type[7] != '_') { - f << stringf(" or %sedge ", cell->type[7] == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->getPort(ID::R)); - } - f << stringf(")\n"); - - if (cell->type[7] != '_') { - f << stringf("%s" " if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!"); - dump_sigspec(f, cell->getPort(ID::R)); - f << stringf(")\n"); - f << stringf("%s" " %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]); - f << stringf("%s" " else\n", indent.c_str()); - } - - f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str()); - dump_cell_expr_port(f, cell, "D", false); - f << stringf(";\n"); - - if (!out_is_reg_wire) { - f << stringf("%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->getPort(ID::Q)); - f << stringf(" = %s;\n", reg_name.c_str()); - } - - return true; - } - - if (cell->type.begins_with("$_DFFSR_")) - { - char pol_c = cell->type[8], pol_s = cell->type[9], pol_r = cell->type[10]; - - std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name); - - if (!out_is_reg_wire) { - f << stringf("%s" "reg %s", indent.c_str(), reg_name.c_str()); - dump_reg_init(f, cell->getPort(ID::Q)); - f << ";\n"; - } - - dump_attributes(f, indent, cell->attributes); - f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_c == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->getPort(ID::C)); - f << stringf(" or %sedge ", pol_s == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->getPort(ID::S)); - f << stringf(" or %sedge ", pol_r == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->getPort(ID::R)); - f << stringf(")\n"); - - f << stringf("%s" " if (%s", indent.c_str(), pol_r == 'P' ? "" : "!"); - dump_sigspec(f, cell->getPort(ID::R)); - f << stringf(")\n"); - f << stringf("%s" " %s <= 0;\n", indent.c_str(), reg_name.c_str()); - - f << stringf("%s" " else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!"); - dump_sigspec(f, cell->getPort(ID::S)); - f << stringf(")\n"); - f << stringf("%s" " %s <= 1;\n", indent.c_str(), reg_name.c_str()); - - f << stringf("%s" " else\n", indent.c_str()); - f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str()); - dump_cell_expr_port(f, cell, "D", false); - f << stringf(";\n"); - - if (!out_is_reg_wire) { - f << stringf("%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->getPort(ID::Q)); - f << stringf(" = %s;\n", reg_name.c_str()); - } - - return true; - } - #define HANDLE_UNIOP(_type, _operator) \ if (cell->type ==_type) { dump_cell_expr_uniop(f, indent, cell, _operator); return true; } #define HANDLE_BINOP(_type, _operator) \ @@ -836,21 +991,19 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf(" = "); if (cell->getParam(ID::B_SIGNED).as_bool()) { - f << stringf("$signed("); - dump_sigspec(f, cell->getPort(ID::B)); - f << stringf(")"); + dump_cell_expr_port(f, cell, "B", true); f << stringf(" < 0 ? "); - dump_sigspec(f, cell->getPort(ID::A)); + dump_cell_expr_port(f, cell, "A", true); f << stringf(" << - "); dump_sigspec(f, cell->getPort(ID::B)); f << stringf(" : "); - dump_sigspec(f, cell->getPort(ID::A)); + dump_cell_expr_port(f, cell, "A", true); f << stringf(" >> "); dump_sigspec(f, cell->getPort(ID::B)); } else { - dump_sigspec(f, cell->getPort(ID::A)); + dump_cell_expr_port(f, cell, "A", true); f << stringf(" >> "); dump_sigspec(f, cell->getPort(ID::B)); } @@ -986,423 +1139,198 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } - if (cell->type == ID($dffsr)) + if (RTLIL::builtin_ff_cell_types().count(cell->type)) { - SigSpec sig_clk = cell->getPort(ID::CLK); - SigSpec sig_set = cell->getPort(ID::SET); - SigSpec sig_clr = cell->getPort(ID::CLR); - SigSpec sig_d = cell->getPort(ID::D); - SigSpec sig_q = cell->getPort(ID::Q); + FfData ff(nullptr, cell); - int width = cell->parameters[ID::WIDTH].as_int(); - bool pol_clk = cell->parameters[ID::CLK_POLARITY].as_bool(); - bool pol_set = cell->parameters[ID::SET_POLARITY].as_bool(); - bool pol_clr = cell->parameters[ID::CLR_POLARITY].as_bool(); + // $ff / $_FF_ cell: not supported. + if (ff.has_d && !ff.has_clk && !ff.has_en) + return false; std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(sig_q, reg_name); + bool out_is_reg_wire = is_reg_wire(ff.sig_q, reg_name); if (!out_is_reg_wire) { - f << stringf("%s" "reg [%d:0] %s", indent.c_str(), width-1, reg_name.c_str()); - dump_reg_init(f, sig_q); - f << ";\n"; - } - - for (int i = 0; i < width; i++) { - f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_clk ? "pos" : "neg"); - dump_sigspec(f, sig_clk); - f << stringf(", %sedge ", pol_set ? "pos" : "neg"); - dump_sigspec(f, sig_set); - f << stringf(", %sedge ", pol_clr ? "pos" : "neg"); - dump_sigspec(f, sig_clr); - f << stringf(")\n"); - - f << stringf("%s" " if (%s", indent.c_str(), pol_clr ? "" : "!"); - dump_sigspec(f, sig_clr); - f << stringf(") %s[%d] <= 1'b0;\n", reg_name.c_str(), i); - - f << stringf("%s" " else if (%s", indent.c_str(), pol_set ? "" : "!"); - dump_sigspec(f, sig_set); - f << stringf(") %s[%d] <= 1'b1;\n", reg_name.c_str(), i); - - f << stringf("%s" " else %s[%d] <= ", indent.c_str(), reg_name.c_str(), i); - dump_sigspec(f, sig_d[i]); - f << stringf(";\n"); - } - - if (!out_is_reg_wire) { - f << stringf("%s" "assign ", indent.c_str()); - dump_sigspec(f, sig_q); - f << stringf(" = %s;\n", reg_name.c_str()); - } - - return true; - } - - if (cell->type.in(ID($dff), ID($adff), ID($dffe))) - { - RTLIL::SigSpec sig_clk, sig_arst, sig_en, val_arst; - bool pol_clk, pol_arst = false, pol_en = false; - - sig_clk = cell->getPort(ID::CLK); - pol_clk = cell->parameters[ID::CLK_POLARITY].as_bool(); - - if (cell->type == ID($adff)) { - sig_arst = cell->getPort(ID::ARST); - pol_arst = cell->parameters[ID::ARST_POLARITY].as_bool(); - val_arst = RTLIL::SigSpec(cell->parameters[ID::ARST_VALUE]); - } - - if (cell->type == ID($dffe)) { - sig_en = cell->getPort(ID::EN); - pol_en = cell->parameters[ID::EN_POLARITY].as_bool(); - } - - std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name); - - if (!out_is_reg_wire) { - f << stringf("%s" "reg [%d:0] %s", indent.c_str(), cell->parameters[ID::WIDTH].as_int()-1, reg_name.c_str()); - dump_reg_init(f, cell->getPort(ID::Q)); - f << ";\n"; - } - - f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_clk ? "pos" : "neg"); - dump_sigspec(f, sig_clk); - if (cell->type == ID($adff)) { - f << stringf(" or %sedge ", pol_arst ? "pos" : "neg"); - dump_sigspec(f, sig_arst); - } - f << stringf(")\n"); - - if (cell->type == ID($adff)) { - f << stringf("%s" " if (%s", indent.c_str(), pol_arst ? "" : "!"); - dump_sigspec(f, sig_arst); - f << stringf(")\n"); - f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str()); - dump_sigspec(f, val_arst); - f << stringf(";\n"); - f << stringf("%s" " else\n", indent.c_str()); - } - - if (cell->type == ID($dffe)) { - f << stringf("%s" " if (%s", indent.c_str(), pol_en ? "" : "!"); - dump_sigspec(f, sig_en); - f << stringf(")\n"); - } - - f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str()); - dump_cell_expr_port(f, cell, "D", false); - f << stringf(";\n"); - - if (!out_is_reg_wire) { - f << stringf("%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->getPort(ID::Q)); - f << stringf(" = %s;\n", reg_name.c_str()); - } - - return true; - } - - if (cell->type == ID($dlatch)) - { - RTLIL::SigSpec sig_en; - bool pol_en = false; - - sig_en = cell->getPort(ID::EN); - pol_en = cell->parameters[ID::EN_POLARITY].as_bool(); - - std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name); - - if (!out_is_reg_wire) { - f << stringf("%s" "reg [%d:0] %s", indent.c_str(), cell->parameters[ID::WIDTH].as_int()-1, reg_name.c_str()); - dump_reg_init(f, cell->getPort(ID::Q)); + if (ff.width == 1) + f << stringf("%s" "reg %s", indent.c_str(), reg_name.c_str()); + else + f << stringf("%s" "reg [%d:0] %s", indent.c_str(), ff.width-1, reg_name.c_str()); + dump_reg_init(f, ff.sig_q); f << ";\n"; } - f << stringf("%s" "always @*\n", indent.c_str()); - - f << stringf("%s" " if (%s", indent.c_str(), pol_en ? "" : "!"); - dump_sigspec(f, sig_en); - f << stringf(")\n"); - - f << stringf("%s" " %s = ", indent.c_str(), reg_name.c_str()); - dump_cell_expr_port(f, cell, "D", false); - f << stringf(";\n"); - - if (!out_is_reg_wire) { - f << stringf("%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->getPort(ID::Q)); - f << stringf(" = %s;\n", reg_name.c_str()); - } + // If the FF has CLR/SET inputs, emit every bit slice separately. + int chunks = ff.has_sr ? ff.width : 1; + bool chunky = ff.has_sr && ff.width != 1; - return true; - } - - if (cell->type == ID($mem)) - { - RTLIL::IdString memid = cell->parameters[ID::MEMID].decode_string(); - std::string mem_id = id(cell->parameters[ID::MEMID].decode_string()); - int abits = cell->parameters[ID::ABITS].as_int(); - int size = cell->parameters[ID::SIZE].as_int(); - int offset = cell->parameters[ID::OFFSET].as_int(); - int width = cell->parameters[ID::WIDTH].as_int(); - bool use_init = !(RTLIL::SigSpec(cell->parameters[ID::INIT]).is_fully_undef()); - - // for memory block make something like: - // reg [7:0] memid [3:0]; - // initial begin - // memid[0] = ... - // end - dump_attributes(f, indent.c_str(), cell->attributes); - f << stringf("%s" "reg [%d:%d] %s [%d:%d];\n", indent.c_str(), width-1, 0, mem_id.c_str(), size+offset-1, offset); - if (use_init) + for (int i = 0; i < chunks; i++) { - if (extmem) - { - std::string extmem_filename = stringf("%s-%d.mem", extmem_prefix.c_str(), extmem_counter++); - - std::string extmem_filename_esc; - for (auto c : extmem_filename) + SigSpec sig_d; + Const val_arst, val_srst; + std::string reg_bit_name, sig_set_name, sig_clr_name, sig_arst_name; + if (chunky) { + reg_bit_name = stringf("%s[%d]", reg_name.c_str(), i); + if (ff.has_d) + sig_d = ff.sig_d[i]; + } else { + reg_bit_name = reg_name; + if (ff.has_d) + sig_d = ff.sig_d; + } + if (ff.has_arst) + val_arst = chunky ? ff.val_arst[i] : ff.val_arst; + if (ff.has_srst) + val_srst = chunky ? ff.val_srst[i] : ff.val_srst; + + // If there are constants in the sensitivity list, replace them with an intermediate wire + if (ff.has_sr) { + if (ff.sig_set[i].wire == NULL) { - if (c == '\n') - extmem_filename_esc += "\\n"; - else if (c == '\t') - extmem_filename_esc += "\\t"; - else if (c < 32) - extmem_filename_esc += stringf("\\%03o", c); - else if (c == '"') - extmem_filename_esc += "\\\""; - else if (c == '\\') - extmem_filename_esc += "\\\\"; - else - extmem_filename_esc += c; + sig_set_name = next_auto_id(); + f << stringf("%s" "wire %s = ", indent.c_str(), sig_set_name.c_str()); + dump_const(f, ff.sig_set[i].data); + f << stringf(";\n"); } - f << stringf("%s" "initial $readmemb(\"%s\", %s);\n", indent.c_str(), extmem_filename_esc.c_str(), mem_id.c_str()); - - std::ofstream extmem_f(extmem_filename, std::ofstream::trunc); - if (extmem_f.fail()) - log_error("Can't open file `%s' for writing: %s\n", extmem_filename.c_str(), strerror(errno)); - else + if (ff.sig_clr[i].wire == NULL) { - for (int i=0; i<size; i++) - { - RTLIL::Const element = cell->parameters[ID::INIT].extract(i*width, width); - for (int j=0; j<element.size(); j++) - { - switch (element[element.size()-j-1]) - { - case State::S0: extmem_f << '0'; break; - case State::S1: extmem_f << '1'; break; - case State::Sx: extmem_f << 'x'; break; - case State::Sz: extmem_f << 'z'; break; - case State::Sa: extmem_f << '_'; break; - case State::Sm: log_error("Found marker state in final netlist."); - } - } - extmem_f << '\n'; - } + sig_clr_name = next_auto_id(); + f << stringf("%s" "wire %s = ", indent.c_str(), sig_clr_name.c_str()); + dump_const(f, ff.sig_clr[i].data); + f << stringf(";\n"); } - - } - else - { - f << stringf("%s" "initial begin\n", indent.c_str()); - for (int i=0; i<size; i++) + } else if (ff.has_arst) { + if (ff.sig_arst[i].wire == NULL) { - f << stringf("%s" " %s[%d] = ", indent.c_str(), mem_id.c_str(), i); - dump_const(f, cell->parameters[ID::INIT].extract(i*width, width)); + sig_arst_name = next_auto_id(); + f << stringf("%s" "wire %s = ", indent.c_str(), sig_arst_name.c_str()); + dump_const(f, ff.sig_arst[i].data); f << stringf(";\n"); } - f << stringf("%s" "end\n", indent.c_str()); } - } - // create a map : "edge clk" -> expressions within that clock domain - dict<std::string, std::vector<std::string>> clk_to_lof_body; - clk_to_lof_body[""] = std::vector<std::string>(); - std::string clk_domain_str; - // create a list of reg declarations - std::vector<std::string> lof_reg_declarations; - - int nread_ports = cell->parameters[ID::RD_PORTS].as_int(); - RTLIL::SigSpec sig_rd_clk, sig_rd_en, sig_rd_data, sig_rd_addr; - bool use_rd_clk, rd_clk_posedge, rd_transparent; - // read ports - for (int i=0; i < nread_ports; i++) - { - sig_rd_clk = cell->getPort(ID::RD_CLK).extract(i); - sig_rd_en = cell->getPort(ID::RD_EN).extract(i); - sig_rd_data = cell->getPort(ID::RD_DATA).extract(i*width, width); - sig_rd_addr = cell->getPort(ID::RD_ADDR).extract(i*abits, abits); - use_rd_clk = cell->parameters[ID::RD_CLK_ENABLE].extract(i).as_bool(); - rd_clk_posedge = cell->parameters[ID::RD_CLK_POLARITY].extract(i).as_bool(); - rd_transparent = cell->parameters[ID::RD_TRANSPARENT].extract(i).as_bool(); - if (use_rd_clk) + dump_attributes(f, indent, cell->attributes); + if (ff.has_clk) { - { - std::ostringstream os; - dump_sigspec(os, sig_rd_clk); - clk_domain_str = stringf("%sedge %s", rd_clk_posedge ? "pos" : "neg", os.str().c_str()); - if( clk_to_lof_body.count(clk_domain_str) == 0 ) - clk_to_lof_body[clk_domain_str] = std::vector<std::string>(); + // FFs. + f << stringf("%s" "always%s @(%sedge ", indent.c_str(), systemverilog ? "_ff" : "", ff.pol_clk ? "pos" : "neg"); + dump_sigspec(f, ff.sig_clk); + if (ff.has_sr) { + f << stringf(", %sedge ", ff.pol_set ? "pos" : "neg"); + if (ff.sig_set[i].wire == NULL) + f << stringf("%s", sig_set_name.c_str()); + else + dump_sigspec(f, ff.sig_set[i]); + + f << stringf(", %sedge ", ff.pol_clr ? "pos" : "neg"); + if (ff.sig_clr[i].wire == NULL) + f << stringf("%s", sig_clr_name.c_str()); + else + dump_sigspec(f, ff.sig_clr[i]); + + } else if (ff.has_arst) { + f << stringf(", %sedge ", ff.pol_arst ? "pos" : "neg"); + if (ff.sig_arst[i].wire == NULL) + f << stringf("%s", sig_arst_name.c_str()); + else + dump_sigspec(f, ff.sig_arst); } - if (!rd_transparent) - { - // for clocked read ports make something like: - // reg [..] temp_id; - // always @(posedge clk) - // if (rd_en) temp_id <= array_reg[r_addr]; - // assign r_data = temp_id; - std::string temp_id = next_auto_id(); - lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", sig_rd_data.size() - 1, temp_id.c_str()) ); - { - std::ostringstream os; - if (sig_rd_en != RTLIL::SigBit(true)) - { - os << stringf("if ("); - dump_sigspec(os, sig_rd_en); - os << stringf(") "); - } - os << stringf("%s <= %s[", temp_id.c_str(), mem_id.c_str()); - dump_sigspec(os, sig_rd_addr); - os << stringf("];\n"); - clk_to_lof_body[clk_domain_str].push_back(os.str()); - } - { - std::ostringstream os; - dump_sigspec(os, sig_rd_data); - std::string line = stringf("assign %s = %s;\n", os.str().c_str(), temp_id.c_str()); - clk_to_lof_body[""].push_back(line); - } + f << stringf(")\n"); + + f << stringf("%s" " ", indent.c_str()); + if (ff.has_sr) { + f << stringf("if (%s", ff.pol_clr ? "" : "!"); + if (ff.sig_clr[i].wire == NULL) + f << stringf("%s", sig_clr_name.c_str()); + else + dump_sigspec(f, ff.sig_clr[i]); + f << stringf(") %s <= 1'b0;\n", reg_bit_name.c_str()); + f << stringf("%s" " else if (%s", indent.c_str(), ff.pol_set ? "" : "!"); + if (ff.sig_set[i].wire == NULL) + f << stringf("%s", sig_set_name.c_str()); + else + dump_sigspec(f, ff.sig_set[i]); + f << stringf(") %s <= 1'b1;\n", reg_bit_name.c_str()); + f << stringf("%s" " else ", indent.c_str()); + } else if (ff.has_arst) { + f << stringf("if (%s", ff.pol_arst ? "" : "!"); + if (ff.sig_arst[i].wire == NULL) + f << stringf("%s", sig_arst_name.c_str()); + else + dump_sigspec(f, ff.sig_arst); + f << stringf(") %s <= ", reg_bit_name.c_str()); + dump_sigspec(f, val_arst); + f << stringf(";\n"); + f << stringf("%s" " else ", indent.c_str()); } - else - { - // for rd-transparent read-ports make something like: - // reg [..] temp_id; - // always @(posedge clk) - // temp_id <= r_addr; - // assign r_data = array_reg[temp_id]; - std::string temp_id = next_auto_id(); - lof_reg_declarations.push_back( stringf("reg [%d:0] %s;\n", sig_rd_addr.size() - 1, temp_id.c_str()) ); - { - std::ostringstream os; - dump_sigspec(os, sig_rd_addr); - std::string line = stringf("%s <= %s;\n", temp_id.c_str(), os.str().c_str()); - clk_to_lof_body[clk_domain_str].push_back(line); + + if (ff.has_srst && ff.has_en && ff.ce_over_srst) { + f << stringf("if (%s", ff.pol_en ? "" : "!"); + dump_sigspec(f, ff.sig_en); + f << stringf(")\n"); + f << stringf("%s" " if (%s", indent.c_str(), ff.pol_srst ? "" : "!"); + dump_sigspec(f, ff.sig_srst); + f << stringf(") %s <= ", reg_bit_name.c_str()); + dump_sigspec(f, val_srst); + f << stringf(";\n"); + f << stringf("%s" " else ", indent.c_str()); + } else { + if (ff.has_srst) { + f << stringf("if (%s", ff.pol_srst ? "" : "!"); + dump_sigspec(f, ff.sig_srst); + f << stringf(") %s <= ", reg_bit_name.c_str()); + dump_sigspec(f, val_srst); + f << stringf(";\n"); + f << stringf("%s" " else ", indent.c_str()); } - { - std::ostringstream os; - dump_sigspec(os, sig_rd_data); - std::string line = stringf("assign %s = %s[%s];\n", os.str().c_str(), mem_id.c_str(), temp_id.c_str()); - clk_to_lof_body[""].push_back(line); + if (ff.has_en) { + f << stringf("if (%s", ff.pol_en ? "" : "!"); + dump_sigspec(f, ff.sig_en); + f << stringf(") "); } } - } else { - // for non-clocked read-ports make something like: - // assign r_data = array_reg[r_addr]; - std::ostringstream os, os2; - dump_sigspec(os, sig_rd_data); - dump_sigspec(os2, sig_rd_addr); - std::string line = stringf("assign %s = %s[%s];\n", os.str().c_str(), mem_id.c_str(), os2.str().c_str()); - clk_to_lof_body[""].push_back(line); - } - } - - int nwrite_ports = cell->parameters[ID::WR_PORTS].as_int(); - RTLIL::SigSpec sig_wr_clk, sig_wr_data, sig_wr_addr, sig_wr_en; - bool wr_clk_posedge; - // write ports - for (int i=0; i < nwrite_ports; i++) - { - sig_wr_clk = cell->getPort(ID::WR_CLK).extract(i); - sig_wr_data = cell->getPort(ID::WR_DATA).extract(i*width, width); - sig_wr_addr = cell->getPort(ID::WR_ADDR).extract(i*abits, abits); - sig_wr_en = cell->getPort(ID::WR_EN).extract(i*width, width); - wr_clk_posedge = cell->parameters[ID::WR_CLK_POLARITY].extract(i).as_bool(); - { - std::ostringstream os; - dump_sigspec(os, sig_wr_clk); - clk_domain_str = stringf("%sedge %s", wr_clk_posedge ? "pos" : "neg", os.str().c_str()); - if( clk_to_lof_body.count(clk_domain_str) == 0 ) - clk_to_lof_body[clk_domain_str] = std::vector<std::string>(); + f << stringf("%s <= ", reg_bit_name.c_str()); + dump_sigspec(f, sig_d); + f << stringf(";\n"); } - // make something like: - // always @(posedge clk) - // if (wr_en_bit) memid[w_addr][??] <= w_data[??]; - // ... - for (int i = 0; i < GetSize(sig_wr_en); i++) + else { - int start_i = i, width = 1; - SigBit wen_bit = sig_wr_en[i]; - - while (i+1 < GetSize(sig_wr_en) && active_sigmap(sig_wr_en[i+1]) == active_sigmap(wen_bit)) - i++, width++; - - if (wen_bit == State::S0) - continue; - - std::ostringstream os; - if (wen_bit != State::S1) - { - os << stringf("if ("); - dump_sigspec(os, wen_bit); - os << stringf(") "); + // Latches. + f << stringf("%s" "always%s\n", indent.c_str(), systemverilog ? "_latch" : " @*"); + + f << stringf("%s" " ", indent.c_str()); + if (ff.has_sr) { + f << stringf("if (%s", ff.pol_clr ? "" : "!"); + dump_sigspec(f, ff.sig_clr[i]); + f << stringf(") %s = 1'b0;\n", reg_bit_name.c_str()); + f << stringf("%s" " else if (%s", indent.c_str(), ff.pol_set ? "" : "!"); + dump_sigspec(f, ff.sig_set[i]); + f << stringf(") %s = 1'b1;\n", reg_bit_name.c_str()); + if (ff.has_d) + f << stringf("%s" " else ", indent.c_str()); + } else if (ff.has_arst) { + f << stringf("if (%s", ff.pol_arst ? "" : "!"); + dump_sigspec(f, ff.sig_arst); + f << stringf(") %s = ", reg_bit_name.c_str()); + dump_sigspec(f, val_arst); + f << stringf(";\n"); + if (ff.has_d) + f << stringf("%s" " else ", indent.c_str()); + } + if (ff.has_d) { + f << stringf("if (%s", ff.pol_en ? "" : "!"); + dump_sigspec(f, ff.sig_en); + f << stringf(") %s = ", reg_bit_name.c_str()); + dump_sigspec(f, sig_d); + f << stringf(";\n"); } - os << stringf("%s[", mem_id.c_str()); - dump_sigspec(os, sig_wr_addr); - if (width == GetSize(sig_wr_en)) - os << stringf("] <= "); - else - os << stringf("][%d:%d] <= ", i, start_i); - dump_sigspec(os, sig_wr_data.extract(start_i, width)); - os << stringf(";\n"); - clk_to_lof_body[clk_domain_str].push_back(os.str()); } } - // Output Verilog that looks something like this: - // reg [..] _3_; - // always @(posedge CLK2) begin - // _3_ <= memory[D1ADDR]; - // if (A1EN) - // memory[A1ADDR] <= A1DATA; - // if (A2EN) - // memory[A2ADDR] <= A2DATA; - // ... - // end - // always @(negedge CLK1) begin - // if (C1EN) - // memory[C1ADDR] <= C1DATA; - // end - // ... - // assign D1DATA = _3_; - // assign D2DATA <= memory[D2ADDR]; - - // the reg ... definitions - for(auto ® : lof_reg_declarations) - { - f << stringf("%s" "%s", indent.c_str(), reg.c_str()); - } - // the block of expressions by clock domain - for(auto &pair : clk_to_lof_body) - { - std::string clk_domain = pair.first; - std::vector<std::string> lof_lines = pair.second; - if( clk_domain != "") - { - f << stringf("%s" "always @(%s) begin\n", indent.c_str(), clk_domain.c_str()); - for(auto &line : lof_lines) - f << stringf("%s%s" "%s", indent.c_str(), indent.c_str(), line.c_str()); - f << stringf("%s" "end\n", indent.c_str()); - } - else - { - // the non-clocked assignments - for(auto &line : lof_lines) - f << stringf("%s" "%s", indent.c_str(), line.c_str()); - } + + if (!out_is_reg_wire) { + f << stringf("%s" "assign ", indent.c_str()); + dump_sigspec(f, ff.sig_q); + f << stringf(" = %s;\n", reg_name.c_str()); } return true; @@ -1410,7 +1338,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) if (cell->type.in(ID($assert), ID($assume), ID($cover))) { - f << stringf("%s" "always @* if (", indent.c_str()); + f << stringf("%s" "always%s if (", indent.c_str(), systemverilog ? "_comb" : " @*"); dump_sigspec(f, cell->getPort(ID::EN)); f << stringf(") %s(", cell->type.c_str()+1); dump_sigspec(f, cell->getPort(ID::A)); @@ -1528,14 +1456,17 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } - // FIXME: $_SR_[PN][PN]_, $_DLATCH_[PN]_, $_DLATCHSR_[PN][PN][PN]_ - // FIXME: $sr, $dlatch, $memrd, $memwr, $fsm + // FIXME: $fsm return false; } void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) { + // Handled by dump_memory + if (cell->type.in(ID($mem), ID($memwr), ID($memrd), ID($meminit))) + return; + if (cell->type[0] == '$' && !noexpr) { if (dump_cell_expr(f, indent, cell)) return; @@ -1602,7 +1533,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) } } - if (siminit && reg_ct.count(cell->type) && cell->hasPort(ID::Q)) { + if (siminit && RTLIL::builtin_ff_cell_types().count(cell->type) && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_))) { std::stringstream ss; dump_reg_init(ss, cell->getPort(ID::Q)); if (!ss.str().empty()) { @@ -1717,7 +1648,9 @@ void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, boo return; } - f << stringf("%s" "always @* begin\n", indent.c_str()); + f << stringf("%s" "always%s begin\n", indent.c_str(), systemverilog ? "_comb" : " @*"); + if (!systemverilog) + f << indent + " " << "if (" << id("\\initial") << ") begin end\n"; dump_case_body(f, indent, &proc->root_case, true); std::string backup_indent = indent; @@ -1728,11 +1661,11 @@ void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, boo indent = backup_indent; if (sync->type == RTLIL::STa) { - f << stringf("%s" "always @* begin\n", indent.c_str()); + f << stringf("%s" "always%s begin\n", indent.c_str(), systemverilog ? "_comb" : " @*"); } else if (sync->type == RTLIL::STi) { f << stringf("%s" "initial begin\n", indent.c_str()); } else { - f << stringf("%s" "always @(", indent.c_str()); + f << stringf("%s" "always%s @(", indent.c_str(), systemverilog ? "_ff" : ""); if (sync->type == RTLIL::STp || sync->type == RTLIL::ST1) f << stringf("posedge "); if (sync->type == RTLIL::STn || sync->type == RTLIL::ST0) @@ -1810,7 +1743,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) std::set<std::pair<RTLIL::Wire*,int>> reg_bits; for (auto cell : module->cells()) { - if (!reg_ct.count(cell->type) || !cell->hasPort(ID::Q)) + if (!RTLIL::builtin_ff_cell_types().count(cell->type) || !cell->hasPort(ID::Q) || cell->type.in(ID($ff), ID($_FF_))) continue; RTLIL::SigSpec sig = cell->getPort(ID::Q); @@ -1850,11 +1783,14 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) } f << stringf(");\n"); + if (!systemverilog && !module->processes.empty()) + f << indent + " " << "reg " << id("\\initial") << " = 0;\n"; + for (auto w : module->wires()) dump_wire(f, indent + " ", w); - for (auto it = module->memories.begin(); it != module->memories.end(); ++it) - dump_memory(f, indent + " ", it->second); + for (auto &mem : Mem::get_all_memories(module)) + dump_memory(f, indent + " ", mem); for (auto cell : module->cells()) dump_cell(f, indent + " ", cell); @@ -1873,7 +1809,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) struct VerilogBackend : public Backend { VerilogBackend() : Backend("verilog", "write design to Verilog file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1881,6 +1817,9 @@ struct VerilogBackend : public Backend { log("\n"); log("Write the current design to a Verilog file.\n"); log("\n"); + log(" -sv\n"); + log(" with this option, SystemVerilog constructs like always_comb are used\n"); + log("\n"); log(" -norename\n"); log(" without this option all internal object names (the ones with a dollar\n"); log(" instead of a backslash prefix) are changed to short names in the\n"); @@ -1953,7 +1892,7 @@ struct VerilogBackend : public Backend { log("this command is called on a design with RTLIL processes.\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing Verilog backend.\n"); @@ -1976,37 +1915,14 @@ struct VerilogBackend : public Backend { auto_name_map.clear(); reg_wires.clear(); - reg_ct.clear(); - - reg_ct.insert(ID($dff)); - reg_ct.insert(ID($adff)); - reg_ct.insert(ID($dffe)); - reg_ct.insert(ID($dlatch)); - - reg_ct.insert(ID($_DFF_N_)); - reg_ct.insert(ID($_DFF_P_)); - - reg_ct.insert(ID($_DFF_NN0_)); - reg_ct.insert(ID($_DFF_NN1_)); - reg_ct.insert(ID($_DFF_NP0_)); - reg_ct.insert(ID($_DFF_NP1_)); - reg_ct.insert(ID($_DFF_PN0_)); - reg_ct.insert(ID($_DFF_PN1_)); - reg_ct.insert(ID($_DFF_PP0_)); - reg_ct.insert(ID($_DFF_PP1_)); - - reg_ct.insert(ID($_DFFSR_NNN_)); - reg_ct.insert(ID($_DFFSR_NNP_)); - reg_ct.insert(ID($_DFFSR_NPN_)); - reg_ct.insert(ID($_DFFSR_NPP_)); - reg_ct.insert(ID($_DFFSR_PNN_)); - reg_ct.insert(ID($_DFFSR_PNP_)); - reg_ct.insert(ID($_DFFSR_PPN_)); - reg_ct.insert(ID($_DFFSR_PPP_)); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; + if (arg == "-sv") { + systemverilog = true; + continue; + } if (arg == "-norename") { norename = true; continue; @@ -2095,7 +2011,6 @@ struct VerilogBackend : public Backend { auto_name_map.clear(); reg_wires.clear(); - reg_ct.clear(); } } VerilogBackend; diff --git a/examples/cxx-api/evaldemo.cc b/examples/cxx-api/evaldemo.cc index 756b7faac..cfe0c0804 100644 --- a/examples/cxx-api/evaldemo.cc +++ b/examples/cxx-api/evaldemo.cc @@ -22,7 +22,7 @@ struct EvalDemoPass : public Pass { EvalDemoPass() : Pass("evaldemo") { } - void execute(vector<string>, Design *design) YS_OVERRIDE + void execute(vector<string>, Design *design) override { Module *module = design->top_module(); diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index fef788267..07e3cd6e0 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -69,7 +69,7 @@ struct ConstEvalAig continue; for (auto &it2 : it.second->connections()) if (yosys_celltypes.cell_output(it.second->type, it2.first)) { - auto r YS_ATTRIBUTE(unused) = sig2driver.insert(std::make_pair(it2.second, it.second)); + auto r = sig2driver.insert(std::make_pair(it2.second, it.second)); log_assert(r.second); } } @@ -400,9 +400,9 @@ void AigerReader::parse_xaiger() for (int c = f.get(); c != EOF; c = f.get()) { // XAIGER extensions if (c == 'm') { - uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); + uint32_t dataSize = parse_xaiger_literal(f); uint32_t lutNum = parse_xaiger_literal(f); - uint32_t lutSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); + uint32_t lutSize = parse_xaiger_literal(f); log_debug("m: dataSize=%u lutNum=%u lutSize=%u\n", dataSize, lutNum, lutSize); ConstEvalAig ce(module); for (unsigned i = 0; i < lutNum; ++i) { @@ -434,7 +434,7 @@ void AigerReader::parse_xaiger() int gray = j ^ (j >> 1); ce.set_incremental(input_sig, RTLIL::Const{gray, GetSize(input_sig)}); RTLIL::SigBit o(output_sig); - bool success YS_ATTRIBUTE(unused) = ce.eval(o); + bool success = ce.eval(o); log_assert(success); log_assert(o.wire == nullptr); lut_mask[gray] = o.data; @@ -446,7 +446,7 @@ void AigerReader::parse_xaiger() } } else if (c == 'r') { - uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); + uint32_t dataSize = parse_xaiger_literal(f); flopNum = parse_xaiger_literal(f); log_debug("flopNum = %u\n", flopNum); log_assert(dataSize == (flopNum+1) * sizeof(uint32_t)); @@ -455,7 +455,7 @@ void AigerReader::parse_xaiger() mergeability.emplace_back(parse_xaiger_literal(f)); } else if (c == 's') { - uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); + uint32_t dataSize = parse_xaiger_literal(f); flopNum = parse_xaiger_literal(f); log_assert(dataSize == (flopNum+1) * sizeof(uint32_t)); initial_state.reserve(flopNum); @@ -469,15 +469,15 @@ void AigerReader::parse_xaiger() } else if (c == 'h') { f.ignore(sizeof(uint32_t)); - uint32_t version YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); + uint32_t version = parse_xaiger_literal(f); log_assert(version == 1); - uint32_t ciNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); + uint32_t ciNum = parse_xaiger_literal(f); log_debug("ciNum = %u\n", ciNum); - uint32_t coNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); + uint32_t coNum = parse_xaiger_literal(f); log_debug("coNum = %u\n", coNum); piNum = parse_xaiger_literal(f); log_debug("piNum = %u\n", piNum); - uint32_t poNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); + uint32_t poNum = parse_xaiger_literal(f); log_debug("poNum = %u\n", poNum); uint32_t boxNum = parse_xaiger_literal(f); log_debug("boxNum = %u\n", boxNum); @@ -970,7 +970,7 @@ void AigerReader::post_process() struct AigerFrontend : public Frontend { AigerFrontend() : Frontend("aiger", "read AIGER file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -996,7 +996,7 @@ struct AigerFrontend : public Frontend { log(" read XAIGER extensions\n"); log("\n"); } - void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing AIGER frontend.\n"); diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 03fd272da..c8183580b 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -95,6 +95,7 @@ std::string AST::type2str(AstNodeType type) X(AST_TO_SIGNED) X(AST_TO_UNSIGNED) X(AST_SELFSZ) + X(AST_CAST_SIZE) X(AST_CONCAT) X(AST_REPLICATE) X(AST_BIT_NOT) @@ -335,6 +336,12 @@ void AstNode::dumpAst(FILE *f, std::string indent) const fprintf(f, " %d", v); fprintf(f, " ]"); } + if (!multirange_swapped.empty()) { + fprintf(f, " multirange_swapped=["); + for (auto v : multirange_swapped) + fprintf(f, " %d", v); + fprintf(f, " ]"); + } if (is_enum) { fprintf(f, " type=enum"); } diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index b8f24ee14..1b8ed22ca 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -76,6 +76,7 @@ namespace AST AST_TO_SIGNED, AST_TO_UNSIGNED, AST_SELFSZ, + AST_CAST_SIZE, AST_CONCAT, AST_REPLICATE, AST_BIT_NOT, @@ -201,6 +202,7 @@ namespace AST // if this is a multirange memory then this vector contains offset and length of each dimension std::vector<int> multirange_dimensions; + std::vector<bool> multirange_swapped; // true if range is swapped, not used for structs // this is set by simplify and used during RTLIL generation AstNode *id2ast; @@ -249,7 +251,7 @@ namespace AST // it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL() bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param); AstNode *readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init); - void expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map); + void expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map, bool original_scope = true); void replace_ids(const std::string &prefix, const std::map<std::string, std::string> &rules); void mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg_places, dict<AstNode*, uint32_t> &mem2reg_flags, dict<AstNode*, uint32_t> &proc_flags, uint32_t &status_flags); @@ -322,12 +324,12 @@ namespace AST struct AstModule : RTLIL::Module { AstNode *ast; bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire; - ~AstModule() YS_OVERRIDE; - RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail) YS_OVERRIDE; - RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) YS_OVERRIDE; + ~AstModule() override; + RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail) override; + RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) override; std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, AstNode **new_ast_out, bool quiet = false); - void reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) YS_OVERRIDE; - RTLIL::Module *clone() const YS_OVERRIDE; + void reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) override; + RTLIL::Module *clone() const override; void loadconfig() const; }; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9546558aa..e878d0dd2 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -814,6 +814,16 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun children.at(0)->detectSignWidthWorker(sub_width_hint, sign_hint); break; + case AST_CAST_SIZE: + while (children.at(0)->simplify(true, false, false, 1, -1, false, false)) { } + if (children.at(0)->type != AST_CONSTANT) + log_file_error(filename, location.first_line, "Static cast with non constant expression!\n"); + children.at(1)->detectSignWidthWorker(width_hint, sign_hint); + width_hint = children.at(0)->bitsAsConst().as_int(); + if (width_hint <= 0) + log_file_error(filename, location.first_line, "Static cast with zero or negative size!\n"); + break; + case AST_CONCAT: for (auto child : children) { sub_width_hint = 0; @@ -1289,6 +1299,20 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) return sig; } + // changing the size of signal can be done directly using RTLIL::SigSpec + case AST_CAST_SIZE: { + RTLIL::SigSpec size = children[0]->genRTLIL(); + RTLIL::SigSpec sig = children[1]->genRTLIL(); + if (!size.is_fully_const()) + log_file_error(filename, location.first_line, "Static cast with non constant expression!\n"); + int width = size.as_int(); + if (width <= 0) + log_file_error(filename, location.first_line, "Static cast with zero or negative size!\n"); + sig.extend_u0(width, sign_hint); + is_signed = sign_hint; + return sig; + } + // concatenation of signals can be done directly using RTLIL::SigSpec case AST_CONCAT: { RTLIL::SigSpec sig; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5f026dfed..fb6623f02 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -89,7 +89,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg case 'S': case 'd': case 'D': - if (got_len) + if (got_len && len_value != 0) goto unsupported_format; YS_FALLTHROUGH case 'x': @@ -110,6 +110,12 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg goto unsupported_format; break; + case 'l': + case 'L': + if (got_len) + goto unsupported_format; + break; + default: unsupported_format: log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str()); @@ -155,6 +161,11 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg sout += log_id(current_module->name); break; + case 'l': + case 'L': + sout += log_id(current_module->name); + break; + default: log_abort(); } @@ -380,31 +391,66 @@ static int size_packed_struct(AstNode *snode, int base_offset) static AstNode *node_int(int ival) { - // maybe mkconst_int should have default values for the common integer case - return AstNode::mkconst_int(ival, true, 32); + return AstNode::mkconst_int(ival, true); } -static AstNode *offset_indexed_range(int offset_right, int stride, AstNode *left_expr, AstNode *right_expr) +static AstNode *multiply_by_const(AstNode *expr_node, int stride) +{ + return new AstNode(AST_MUL, expr_node, node_int(stride)); +} + +static AstNode *offset_indexed_range(int offset, int stride, AstNode *left_expr, AstNode *right_expr) { // adjust the range expressions to add an offset into the struct // and maybe index using an array stride auto left = left_expr->clone(); auto right = right_expr->clone(); - if (stride == 1) { - // just add the offset - left = new AstNode(AST_ADD, node_int(offset_right), left); - right = new AstNode(AST_ADD, node_int(offset_right), right); + if (stride > 1) { + // newleft = (left + 1) * stride - 1 + left = new AstNode(AST_SUB, multiply_by_const(new AstNode(AST_ADD, left, node_int(1)), stride), node_int(1)); + // newright = right * stride + right = multiply_by_const(right, stride); + } + // add the offset + if (offset) { + left = new AstNode(AST_ADD, node_int(offset), left); + right = new AstNode(AST_ADD, node_int(offset), right); + } + return new AstNode(AST_RANGE, left, right); +} + +static AstNode *make_struct_index_range(AstNode *node, AstNode *rnode, int stride, int offset) +{ + // generate a range node to perform either bit or array indexing + if (rnode->children.size() == 1) { + // index e.g. s.a[i] + return offset_indexed_range(offset, stride, rnode->children[0], rnode->children[0]); + } + else if (rnode->children.size() == 2) { + // slice e.g. s.a[i:j] + return offset_indexed_range(offset, stride, rnode->children[0], rnode->children[1]); } else { - // newleft = offset_right - 1 + (left + 1) * stride - left = new AstNode(AST_ADD, new AstNode(AST_SUB, node_int(offset_right), node_int(1)), - new AstNode(AST_MUL, node_int(stride), new AstNode(AST_ADD, left, node_int(1)))); - // newright = offset_right + right * stride - right = new AstNode(AST_ADD, node_int(offset_right), new AstNode(AST_MUL, right, node_int(stride))); + struct_op_error(node); } +} + +static AstNode *slice_range(AstNode *rnode, AstNode *snode) +{ + // apply the bit slice indicated by snode to the range rnode + log_assert(rnode->type==AST_RANGE); + auto left = rnode->children[0]; + auto right = rnode->children[1]; + log_assert(snode->type==AST_RANGE); + auto slice_left = snode->children[0]; + auto slice_right = snode->children[1]; + auto width = new AstNode(AST_SUB, slice_left->clone(), slice_right->clone()); + right = new AstNode(AST_ADD, right->clone(), slice_right->clone()); + left = new AstNode(AST_ADD, right->clone(), width); return new AstNode(AST_RANGE, left, right); } + static AstNode *make_struct_member_range(AstNode *node, AstNode *member_node) { // Work out the range in the packed array that corresponds to a struct member @@ -414,27 +460,26 @@ static AstNode *make_struct_member_range(AstNode *node, AstNode *member_node) int range_right = member_node->range_right; if (node->children.empty()) { // no range operations apply, return the whole width + return make_range(range_left, range_right); } - else if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) { - auto rnode = node->children[0]; - int stride = get_struct_array_width(member_node); - if (rnode->children.size() == 1) { - // index e.g. s.a[i] - return offset_indexed_range(range_right, stride, rnode->children[0], rnode->children[0]); - } - else if (rnode->children.size() == 2) { - // slice e.g. s.a[i:j] - return offset_indexed_range(range_right, stride, rnode->children[0], rnode->children[1]); - } - else { - struct_op_error(node); - } + int stride = get_struct_array_width(member_node); + if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) { + // bit or array indexing e.g. s.a[2] or s.a[1:0] + return make_struct_index_range(node, node->children[0], stride, range_right); + } + else if (node->children.size() == 1 && node->children[0]->type == AST_MULTIRANGE) { + // multirange, i.e. bit slice after array index, e.g. s.a[i][p:q] + log_assert(stride > 1); + auto mrnode = node->children[0]; + auto element_range = make_struct_index_range(node, mrnode->children[0], stride, range_right); + // then apply bit slice range + auto range = slice_range(element_range, mrnode->children[1]); + delete element_range; + return range; } else { - // TODO multirange, i.e. bit slice after array index s.a[i][p:q] struct_op_error(node); } - return make_range(range_left, range_right); } static void add_members_to_scope(AstNode *snode, std::string name) @@ -483,6 +528,27 @@ static AstNode *make_packed_struct(AstNode *template_node, std::string &name) return wnode; } +// check if a node or its children contains an assignment to the given variable +static bool node_contains_assignment_to(const AstNode* node, const AstNode* var) +{ + if (node->type == AST_ASSIGN_EQ || node->type == AST_ASSIGN_LE) { + // current node is iteslf an assignment + log_assert(node->children.size() >= 2); + const AstNode* lhs = node->children[0]; + if (lhs->type == AST_IDENTIFIER && lhs->str == var->str) + return false; + } + for (const AstNode* child : node->children) { + // if this child shadows the given variable + if (child != var && child->str == var->str && child->type == AST_WIRE) + break; // skip the remainder of this block/scope + // depth-first short circuit + if (!node_contains_assignment_to(child, var)) + return false; + } + return true; +} + // convert the AST into a simpler AST that has all parameters substituted by their // values, unrolled for-loops, expanded generate blocks, etc. when this function // is done with an AST it can be converted into RTLIL using genRTLIL(). @@ -778,7 +844,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM)) did_something = true; if (node->type == AST_ENUM) { - for (auto enode YS_ATTRIBUTE(unused) : node->children){ + for (auto enode : node->children){ log_assert(enode->type==AST_ENUM_ITEM); while (node->simplify(true, false, false, 1, -1, false, in_param)) did_something = true; @@ -950,6 +1016,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_TO_SIGNED: case AST_TO_UNSIGNED: case AST_SELFSZ: + case AST_CAST_SIZE: case AST_CONCAT: case AST_REPLICATE: case AST_REDUCE_AND: @@ -1126,6 +1193,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, bool in_param_here = in_param; if (i == 0 && (type == AST_REPLICATE || type == AST_WIRE)) const_fold_here = true, in_param_here = true; + if (i == 0 && (type == AST_GENIF || type == AST_GENCASE)) + in_param_here = true; + if (i == 1 && (type == AST_FOR || type == AST_GENFOR)) + in_param_here = true; if (type == AST_PARAMETER || type == AST_LOCALPARAM) const_fold_here = true; if (i == 0 && (type == AST_ASSIGN || type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE)) @@ -1433,11 +1504,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, { int total_size = 1; multirange_dimensions.clear(); + multirange_swapped.clear(); for (auto range : children[1]->children) { if (!range->range_valid) log_file_error(filename, location.first_line, "Non-constant range on memory decl.\n"); multirange_dimensions.push_back(min(range->range_left, range->range_right)); multirange_dimensions.push_back(max(range->range_left, range->range_right) - min(range->range_left, range->range_right) + 1); + multirange_swapped.push_back(range->range_swapped); total_size *= multirange_dimensions.back(); } delete children[1]; @@ -1450,9 +1523,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, { AstNode *index_expr = nullptr; + integer = children[0]->children.size(); // save original number of dimensions for $size() etc. for (int i = 0; 2*i < GetSize(id2ast->multirange_dimensions); i++) { - if (GetSize(children[0]->children) < i) + if (GetSize(children[0]->children) <= i) log_file_error(filename, location.first_line, "Insufficient number of array indices for %s.\n", log_id(str)); AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone(); @@ -1537,6 +1611,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_IDENTIFIER) { if (current_scope.count(str) == 0) { AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod; + const std::string& mod_scope = current_scope_ast->str; + if (str[0] == '\\' && str.substr(0, mod_scope.size()) == mod_scope) { + std::string new_str = "\\" + str.substr(mod_scope.size() + 1); + if (current_scope.count(new_str)) { + str = new_str; + } + } for (auto node : current_scope_ast->children) { //log("looking at mod scope child %s\n", type2str(node->type).c_str()); switch (node->type) { @@ -1641,6 +1722,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, newNode = new AstNode(AST_IDENTIFIER, children[1]->clone()); newNode->str = wire_id; + newNode->integer = integer; // save original number of dimensions for $size() etc. newNode->id2ast = wire; goto apply_newNode; } @@ -1682,25 +1764,27 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, body_ast->children.size() == 1 && body_ast->children.at(0)->type == AST_GENBLOCK) body_ast = body_ast->children.at(0); + const char* loop_type_str = "procedural"; + const char* var_type_str = "register"; + AstNodeType var_type = AST_WIRE; + if (type == AST_GENFOR) { + loop_type_str = "generate"; + var_type_str = "genvar"; + var_type = AST_GENVAR; + } + if (init_ast->type != AST_ASSIGN_EQ) - log_file_error(filename, location.first_line, "Unsupported 1st expression of generate for-loop!\n"); + log_file_error(filename, location.first_line, "Unsupported 1st expression of %s for-loop!\n", loop_type_str); if (next_ast->type != AST_ASSIGN_EQ) - log_file_error(filename, location.first_line, "Unsupported 3rd expression of generate for-loop!\n"); + log_file_error(filename, location.first_line, "Unsupported 3rd expression of %s for-loop!\n", loop_type_str); - if (type == AST_GENFOR) { - if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_GENVAR) - log_file_error(filename, location.first_line, "Left hand side of 1st expression of generate for-loop is not a gen var!\n"); - if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_GENVAR) - log_file_error(filename, location.first_line, "Left hand side of 3rd expression of generate for-loop is not a gen var!\n"); - } else { - if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_WIRE) - log_file_error(filename, location.first_line, "Left hand side of 1st expression of generate for-loop is not a register!\n"); - if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_WIRE) - log_file_error(filename, location.first_line, "Left hand side of 3rd expression of generate for-loop is not a register!\n"); - } + if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != var_type) + log_file_error(filename, location.first_line, "Left hand side of 1st expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str); + if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != var_type) + log_file_error(filename, location.first_line, "Left hand side of 3rd expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str); if (init_ast->children[0]->id2ast != next_ast->children[0]->id2ast) - log_file_error(filename, location.first_line, "Incompatible left-hand sides in 1st and 3rd expression of generate for-loop!\n"); + log_file_error(filename, location.first_line, "Incompatible left-hand sides in 1st and 3rd expression of %s for-loop!\n", loop_type_str); // eval 1st expression AstNode *varbuf = init_ast->children[1]->clone(); @@ -1712,7 +1796,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (varbuf->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Right hand side of 1st expression of generate for-loop is not constant!\n"); + log_file_error(filename, location.first_line, "Right hand side of 1st expression of %s for-loop is not constant!\n", loop_type_str); auto resolved = current_scope.at(init_ast->children[0]->str); if (resolved->range_valid) { @@ -1753,7 +1837,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (buf->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "2nd expression of generate for-loop is not constant!\n"); + log_file_error(filename, location.first_line, "2nd expression of %s for-loop is not constant!\n", loop_type_str); if (buf->integer == 0) { delete buf; @@ -1779,7 +1863,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENFOR) { for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false, false); + buf->children[i]->simplify(const_fold, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } } else { @@ -1799,7 +1883,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (buf->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Right hand side of 3rd expression of generate for-loop is not constant (%s)!\n", type2str(buf->type).c_str()); + log_file_error(filename, location.first_line, "Right hand side of 3rd expression of %s for-loop is not constant (%s)!\n", loop_type_str, type2str(buf->type).c_str()); delete varbuf->children[0]; varbuf->children[0] = buf; @@ -1855,7 +1939,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < children.size(); i++) { - children[i]->simplify(false, false, false, stage, -1, false, false); + children[i]->simplify(const_fold, false, false, stage, -1, false, false); current_ast_mod->children.push_back(children[i]); } @@ -1892,7 +1976,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false, false); + buf->children[i]->simplify(const_fold, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -1942,7 +2026,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, continue; buf = child->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, true)) { } if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); @@ -1971,7 +2055,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false, false); + buf->children[i]->simplify(const_fold, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -2751,26 +2835,28 @@ skip_dynamic_range_lvalue_expansion:; goto apply_newNode; } - if (str == "\\$size" || str == "\\$bits") + if (str == "\\$size" || str == "\\$bits" || str == "\\$high" || str == "\\$low" || str == "\\$left" || str == "\\$right") { - if (str == "\\$bits" && children.size() != 1) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); - - if (str == "\\$size" && children.size() != 1 && children.size() != 2) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n", - RTLIL::unescape_id(str).c_str(), int(children.size())); - int dim = 1; - if (str == "\\$size" && children.size() == 2) { - AstNode *buf = children[1]->clone(); - // Evaluate constant expression - while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } - dim = buf->asInt(false); - delete buf; + if (str == "\\$bits") { + if (children.size() != 1) + log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", + RTLIL::unescape_id(str).c_str(), int(children.size())); + } else { + if (children.size() != 1 && children.size() != 2) + log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n", + RTLIL::unescape_id(str).c_str(), int(children.size())); + if (children.size() == 2) { + AstNode *buf = children[1]->clone(); + // Evaluate constant expression + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + dim = buf->asInt(false); + delete buf; + } } AstNode *buf = children[0]->clone(); int mem_depth = 1; + int result, high = 0, low = 0, left = 0, right = 0, width = 1; // defaults for a simple wire AstNode *id_ast = NULL; // Is this needed? @@ -2783,6 +2869,31 @@ skip_dynamic_range_lvalue_expansion:; id_ast = current_scope.at(buf->str); if (!id_ast) log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", buf->str.c_str()); + // a slice of our identifier means we advance to the next dimension, e.g. $size(a[3]) + if (buf->children.size() > 0) { + // something is hanging below this identifier + if (buf->children[0]->type == AST_RANGE && buf->integer == 0) + // if integer == 0, this node was originally created as AST_RANGE so it's dimension is 1 + dim++; + // more than one range, e.g. $size(a[3][2]) + else // created an AST_MULTIRANGE, converted to AST_RANGE, but original dimension saved in 'integer' field + dim += buf->integer; // increment by multirange size + } + // We have 4 cases: + // wire x; ==> AST_WIRE, no AST_RANGE children + // wire [1:0]x; ==> AST_WIRE, AST_RANGE children + // wire [1:0]x[1:0]; ==> AST_MEMORY, two AST_RANGE children (1st for packed, 2nd for unpacked) + // wire [1:0]x[1:0][1:0]; ==> AST_MEMORY, one AST_RANGE child (0) for packed, then AST_MULTIRANGE child (1) for unpacked + // (updated: actually by the time we are here, AST_MULTIRANGE is converted into one big AST_RANGE) + // case 0 handled by default + if ((id_ast->type == AST_WIRE || id_ast->type == AST_MEMORY) && id_ast->children.size() > 0) { + // handle packed array left/right for case 1, and cases 2/3 when requesting the last dimension (packed side) + AstNode *wire_range = id_ast->children[0]; + left = wire_range->children[0]->integer; + right = wire_range->children[1]->integer; + high = max(left, right); + low = min(left, right); + } if (id_ast->type == AST_MEMORY) { // We got here only if the argument is a memory // Otherwise $size() and $bits() return the expression width @@ -2795,29 +2906,58 @@ skip_dynamic_range_lvalue_expansion:; } else log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); } else { - // $size() + // $size(), $left(), $right(), $high(), $low() + int dims = 1; if (mem_range->type == AST_RANGE) { - if (!mem_range->range_valid) - log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str()); - int dims; - if (id_ast->multirange_dimensions.empty()) - dims = 1; - else + if (id_ast->multirange_dimensions.empty()) { + if (!mem_range->range_valid) + log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str()); + if (dim == 1) { + left = mem_range->range_right; + right = mem_range->range_left; + high = max(left, right); + low = min(left, right); + } + } else { dims = GetSize(id_ast->multirange_dimensions)/2; - if (dim == 1) - width_hint = (dims > 1) ? id_ast->multirange_dimensions[1] : (mem_range->range_left - mem_range->range_right + 1); - else if (dim <= dims) { - width_hint = id_ast->multirange_dimensions[2*dim-1]; - } else if ((dim > dims+1) || (dim < 0)) - log_file_error(filename, location.first_line, "Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, buf->str.c_str(), dims+1); - } else + if (dim <= dims) { + width_hint = id_ast->multirange_dimensions[2*dim-1]; + high = id_ast->multirange_dimensions[2*dim-2] + id_ast->multirange_dimensions[2*dim-1] - 1; + low = id_ast->multirange_dimensions[2*dim-2]; + if (id_ast->multirange_swapped[dim-1]) { + left = low; + right = high; + } else { + right = low; + left = high; + } + } else if ((dim > dims+1) || (dim < 0)) + log_file_error(filename, location.first_line, "Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, buf->str.c_str(), dims+1); + } + } else { log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); + } } } + width = high - low + 1; + } else { + width = width_hint; } delete buf; - - newNode = mkconst_int(width_hint * mem_depth, false); + if (str == "\\$high") + result = high; + else if (str == "\\$low") + result = low; + else if (str == "\\$left") + result = left; + else if (str == "\\$right") + result = right; + else if (str == "\\$size") + result = width; + else { + result = width * mem_depth; + } + newNode = mkconst_int(result, false); goto apply_newNode; } @@ -3024,7 +3164,7 @@ skip_dynamic_range_lvalue_expansion:; bool all_args_const = true; for (auto child : children) { while (child->simplify(true, false, false, 1, -1, false, true)) { } - if (child->type != AST_CONSTANT) + if (child->type != AST_CONSTANT && child->type != AST_REALVALUE) all_args_const = false; } @@ -3149,14 +3289,15 @@ skip_dynamic_range_lvalue_expansion:; if (wire_cache.count(child->str)) { wire = wire_cache.at(child->str); - if (wire->children.empty()) { + bool contains_value = wire->type == AST_LOCALPARAM; + if (wire->children.size() == contains_value) { for (auto c : child->children) wire->children.push_back(c->clone()); } else if (!child->children.empty()) { while (child->simplify(true, false, false, stage, -1, false, false)) { } - if (GetSize(child->children) == GetSize(wire->children)) { + if (GetSize(child->children) == GetSize(wire->children) - contains_value) { for (int i = 0; i < GetSize(child->children); i++) - if (*child->children.at(i) != *wire->children.at(i)) + if (*child->children.at(i) != *wire->children.at(i + contains_value)) goto tcall_incompatible_wires; } else { tcall_incompatible_wires: @@ -3191,6 +3332,13 @@ skip_dynamic_range_lvalue_expansion:; if ((child->is_input || child->is_output) && arg_count < children.size()) { AstNode *arg = children[arg_count++]->clone(); + // convert purely constant arguments into localparams + if (child->is_input && child->type == AST_WIRE && arg->type == AST_CONSTANT && node_contains_assignment_to(decl, child)) { + wire->type = AST_LOCALPARAM; + wire->attributes.erase(ID::nosync); + wire->children.insert(wire->children.begin(), arg->clone()); + continue; + } AstNode *wire_id = new AstNode(AST_IDENTIFIER); wire_id->str = wire->str; AstNode *assign = child->is_input ? @@ -3483,6 +3631,13 @@ replace_fcall_later:; } } break; + case AST_CAST_SIZE: + if (children.at(0)->type == AST_CONSTANT && children.at(1)->type == AST_CONSTANT) { + int width = children[0]->bitsAsConst().as_int(); + RTLIL::Const val = children[1]->bitsAsConst(width); + newNode = mkconst_bits(val.bits, children[1]->is_signed); + } + break; case AST_CONCAT: string_op = !children.empty(); for (auto it = children.begin(); it != children.end(); it++) { @@ -3669,8 +3824,11 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m } // annotate the names of all wires and other named objects in a generate block -void AstNode::expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map) +void AstNode::expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map, bool original_scope) { + // `original_scope` defaults to false, and is used to prevent the premature + // prefixing of items in named sub-blocks + if (!index_var.empty() && type == AST_IDENTIFIER && str == index_var) { if (children.empty()) { current_scope[index_var]->children[0]->cloneInto(this); @@ -3683,53 +3841,85 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma } } - if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE) && name_map.count(str) > 0) - str = name_map[str]; + if (type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE) { + if (name_map.count(str) > 0) { + str = name_map[str]; + } else { + // remap the prefix of this ident if it is a local generate scope + size_t pos = str.rfind('.'); + if (pos != std::string::npos) { + std::string existing_prefix = str.substr(0, pos); + if (name_map.count(existing_prefix) > 0) { + str = name_map[existing_prefix] + str.substr(pos); + } + } + } + } std::map<std::string, std::string> backup_name_map; + auto prefix_node = [&](AstNode* child) { + if (backup_name_map.size() == 0) + backup_name_map = name_map; + + // if within a nested scope + if (!original_scope) { + // this declaration shadows anything in the parent scope(s) + name_map[child->str] = child->str; + return; + } + + std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix; + size_t pos = child->str.rfind('.'); + if (pos == std::string::npos) + pos = child->str[0] == '\\' && prefix[0] == '\\' ? 1 : 0; + else + pos = pos + 1; + new_name = child->str.substr(0, pos) + new_name + child->str.substr(pos); + if (new_name[0] != '$' && new_name[0] != '\\') + new_name = prefix[0] + new_name; + + name_map[child->str] = new_name; + if (child->type == AST_FUNCTION) + replace_result_wire_name_in_function(child, child->str, new_name); + else + child->str = new_name; + current_scope[new_name] = child; + }; + for (size_t i = 0; i < children.size(); i++) { AstNode *child = children[i]; - if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM || - child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL || child->type == AST_TYPEDEF || child->type == AST_ENUM_ITEM) { - if (backup_name_map.size() == 0) - backup_name_map = name_map; - std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix; - size_t pos = child->str.rfind('.'); - if (pos == std::string::npos) - pos = child->str[0] == '\\' && prefix[0] == '\\' ? 1 : 0; - else - pos = pos + 1; - new_name = child->str.substr(0, pos) + new_name + child->str.substr(pos); - if (new_name[0] != '$' && new_name[0] != '\\') - new_name = prefix[0] + new_name; - name_map[child->str] = new_name; - if (child->type == AST_FUNCTION) - replace_result_wire_name_in_function(child, child->str, new_name); - else - child->str = new_name; - current_scope[new_name] = child; - } - if (child->type == AST_ENUM){ + + switch (child->type) { + case AST_WIRE: + case AST_MEMORY: + case AST_PARAMETER: + case AST_LOCALPARAM: + case AST_FUNCTION: + case AST_TASK: + case AST_CELL: + case AST_TYPEDEF: + case AST_ENUM_ITEM: + case AST_GENVAR: + prefix_node(child); + break; + + case AST_BLOCK: + case AST_GENBLOCK: + if (!child->str.empty()) + prefix_node(child); + break; + + case AST_ENUM: current_scope[child->str] = child; for (auto enode : child->children){ log_assert(enode->type == AST_ENUM_ITEM); - if (backup_name_map.size() == 0) - backup_name_map = name_map; - std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix; - size_t pos = enode->str.rfind('.'); - if (pos == std::string::npos) - pos = enode->str[0] == '\\' && prefix[0] == '\\' ? 1 : 0; - else - pos = pos + 1; - new_name = enode->str.substr(0, pos) + new_name + enode->str.substr(pos); - if (new_name[0] != '$' && new_name[0] != '\\') - new_name = prefix[0] + new_name; - name_map[enode->str] = new_name; - - enode->str = new_name; - current_scope[new_name] = enode; + prefix_node(enode); } + break; + + default: + break; } } @@ -3739,8 +3929,14 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma // still needs to recursed-into if (type == AST_PREFIX && i == 1 && child->type == AST_IDENTIFIER) continue; - if (child->type != AST_FUNCTION && child->type != AST_TASK) - child->expand_genblock(index_var, prefix, name_map); + // functions/tasks may reference wires, constants, etc. in this scope + if (child->type == AST_FUNCTION || child->type == AST_TASK) + child->expand_genblock(index_var, prefix, name_map, false); + // continue prefixing if this child block is anonymous + else if (child->type == AST_GENBLOCK || child->type == AST_BLOCK) + child->expand_genblock(index_var, prefix, name_map, original_scope && child->str.empty()); + else + child->expand_genblock(index_var, prefix, name_map, original_scope); } @@ -4219,6 +4415,8 @@ bool AstNode::detect_latch(const std::string &var) case AST_POSEDGE: case AST_NEGEDGE: return false; + case AST_EDGE: + break; case AST_BLOCK: if (!c->detect_latch(var)) return false; @@ -4326,27 +4524,9 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) size_t argidx = 0; for (auto child : children) { - if (child->type == AST_WIRE) - { - while (child->simplify(true, false, false, 1, -1, false, true)) { } - if (!child->range_valid) - log_file_error(child->filename, child->location.first_line, "Can't determine size of variable %s\n%s:%d.%d-%d.%d: ... called from here.\n", - child->str.c_str(), fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); - variables[child->str].val = RTLIL::Const(RTLIL::State::Sx, abs(child->range_left - child->range_right)+1); - variables[child->str].offset = min(child->range_left, child->range_right); - variables[child->str].is_signed = child->is_signed; - if (child->is_input && argidx < fcall->children.size()) - variables[child->str].val = fcall->children.at(argidx++)->bitsAsConst(variables[child->str].val.bits.size()); - backup_scope[child->str] = current_scope[child->str]; - current_scope[child->str] = child; - continue; - } - block->children.push_back(child->clone()); } - log_assert(variables.count(str) != 0); - while (!block->children.empty()) { AstNode *stmt = block->children.front(); @@ -4358,6 +4538,47 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) stmt->dumpAst(NULL, "stmt> "); #endif + if (stmt->type == AST_WIRE) + { + while (stmt->simplify(true, false, false, 1, -1, false, true)) { } + if (!stmt->range_valid) + log_file_error(stmt->filename, stmt->location.first_line, "Can't determine size of variable %s\n%s:%d.%d-%d.%d: ... called from here.\n", + stmt->str.c_str(), fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); + variables[stmt->str].val = RTLIL::Const(RTLIL::State::Sx, abs(stmt->range_left - stmt->range_right)+1); + variables[stmt->str].offset = min(stmt->range_left, stmt->range_right); + variables[stmt->str].is_signed = stmt->is_signed; + if (stmt->is_input && argidx < fcall->children.size()) { + int width = variables[stmt->str].val.bits.size(); + auto* arg_node = fcall->children.at(argidx++); + if (arg_node->type == AST_CONSTANT) { + variables[stmt->str].val = arg_node->bitsAsConst(width); + } else { + log_assert(arg_node->type == AST_REALVALUE); + variables[stmt->str].val = arg_node->realAsConst(width); + } + } + if (!backup_scope.count(stmt->str)) + backup_scope[stmt->str] = current_scope[stmt->str]; + current_scope[stmt->str] = stmt; + + block->children.erase(block->children.begin()); + continue; + } + + log_assert(variables.count(str) != 0); + + if (stmt->type == AST_LOCALPARAM) + { + while (stmt->simplify(true, false, false, 1, -1, false, true)) { } + + if (!backup_scope.count(stmt->str)) + backup_scope[stmt->str] = current_scope[stmt->str]; + current_scope[stmt->str] = stmt; + + block->children.erase(block->children.begin()); + continue; + } + if (stmt->type == AST_ASSIGN_EQ) { if (stmt->children.at(0)->type == AST_IDENTIFIER && stmt->children.at(0)->children.size() != 0 && diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc index 7cc157e49..9ae3fac2c 100644 --- a/frontends/blif/blifparse.cc +++ b/frontends/blif/blifparse.cc @@ -586,7 +586,7 @@ error_with_reason: struct BlifFrontend : public Frontend { BlifFrontend() : Frontend("blif", "read BLIF file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -602,7 +602,7 @@ struct BlifFrontend : public Frontend { log(" multi-bit port 'name'.\n"); log("\n"); } - void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { bool sop_mode = false; bool wideports = false; diff --git a/frontends/ilang/.gitignore b/frontends/ilang/.gitignore deleted file mode 100644 index f586b33c7..000000000 --- a/frontends/ilang/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -ilang_lexer.cc -ilang_parser.output -ilang_parser.tab.cc -ilang_parser.tab.hh diff --git a/frontends/ilang/Makefile.inc b/frontends/ilang/Makefile.inc deleted file mode 100644 index 6f1f0e8fc..000000000 --- a/frontends/ilang/Makefile.inc +++ /dev/null @@ -1,19 +0,0 @@ - -GENFILES += frontends/ilang/ilang_parser.tab.cc -GENFILES += frontends/ilang/ilang_parser.tab.hh -GENFILES += frontends/ilang/ilang_parser.output -GENFILES += frontends/ilang/ilang_lexer.cc - -frontends/ilang/ilang_parser.tab.cc: frontends/ilang/ilang_parser.y - $(Q) mkdir -p $(dir $@) - $(P) $(BISON) -o $@ -d -r all -b frontends/ilang/ilang_parser $< - -frontends/ilang/ilang_parser.tab.hh: frontends/ilang/ilang_parser.tab.cc - -frontends/ilang/ilang_lexer.cc: frontends/ilang/ilang_lexer.l - $(Q) mkdir -p $(dir $@) - $(P) flex -o frontends/ilang/ilang_lexer.cc $< - -OBJS += frontends/ilang/ilang_parser.tab.o frontends/ilang/ilang_lexer.o -OBJS += frontends/ilang/ilang_frontend.o - diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc index 8ae7c6578..1b34aaf3a 100644 --- a/frontends/json/jsonparse.cc +++ b/frontends/json/jsonparse.cc @@ -535,7 +535,7 @@ void json_import(Design *design, string &modname, JsonNode *node) struct JsonFrontend : public Frontend { JsonFrontend() : Frontend("json", "read JSON file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -545,7 +545,7 @@ struct JsonFrontend : public Frontend { log("for a description of the file format.\n"); log("\n"); } - void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing JSON frontend.\n"); diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 6f0c3fefa..f77d7da56 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -453,7 +453,7 @@ void parse_type_map(std::map<std::string, std::tuple<int, int, bool>> &type_map, struct LibertyFrontend : public Frontend { LibertyFrontend() : Frontend("liberty", "read cells from liberty file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -486,7 +486,7 @@ struct LibertyFrontend : public Frontend { log(" set the specified attribute (to the value 1) on all loaded modules\n"); log("\n"); } - void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { bool flag_lib = false; bool flag_nooverwrite = false; diff --git a/frontends/rpc/rpc_frontend.cc b/frontends/rpc/rpc_frontend.cc index 46ee6a733..c12640ef0 100644 --- a/frontends/rpc/rpc_frontend.cc +++ b/frontends/rpc/rpc_frontend.cc @@ -157,7 +157,7 @@ struct RpcServer { struct RpcModule : RTLIL::Module { std::shared_ptr<RpcServer> server; - RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool /*mayfail*/) YS_OVERRIDE { + RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool /*mayfail*/) override { std::string stripped_name = name.str(); if (stripped_name.compare(0, 9, "$abstract") == 0) stripped_name = stripped_name.substr(9); @@ -229,7 +229,7 @@ struct RpcModule : RTLIL::Module { return derived_name; } - RTLIL::Module *clone() const YS_OVERRIDE { + RTLIL::Module *clone() const override { RpcModule *new_mod = new RpcModule; new_mod->server = server; cloneInto(new_mod); @@ -250,7 +250,7 @@ struct HandleRpcServer : RpcServer { HandleRpcServer(const std::string &name, HANDLE hsend, HANDLE hrecv) : RpcServer(name), hsend(hsend), hrecv(hrecv) { } - void write(const std::string &data) YS_OVERRIDE { + void write(const std::string &data) override { log_assert(data.length() >= 1 && data.find('\n') == data.length() - 1); ssize_t offset = 0; do { @@ -261,7 +261,7 @@ struct HandleRpcServer : RpcServer { } while(offset < (ssize_t)data.length()); } - std::string read() YS_OVERRIDE { + std::string read() override { std::string data; ssize_t offset = 0; while (data.length() == 0 || data[data.length() - 1] != '\n') { @@ -304,7 +304,7 @@ struct FdRpcServer : RpcServer { log_cmd_error("RPC frontend terminated unexpectedly\n"); } - void write(const std::string &data) YS_OVERRIDE { + void write(const std::string &data) override { log_assert(data.length() >= 1 && data.find('\n') == data.length() - 1); ssize_t offset = 0; do { @@ -316,7 +316,7 @@ struct FdRpcServer : RpcServer { } while(offset < (ssize_t)data.length()); } - std::string read() YS_OVERRIDE { + std::string read() override { std::string data; ssize_t offset = 0; while (data.length() == 0 || data[data.length() - 1] != '\n') { @@ -346,7 +346,7 @@ struct FdRpcServer : RpcServer { // RpcFrontend does not inherit from Frontend since it does not read files. struct RpcFrontend : public Pass { RpcFrontend() : Pass("connect_rpc", "connect to RPC frontend") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -378,7 +378,7 @@ struct RpcFrontend : public Pass { log(" -> {\"method\": \"derive\", \"module\": \"<module-name\">, \"parameters\": {\n"); log(" \"<param-name>\": {\"type\": \"[unsigned|signed|string|real]\",\n"); log(" \"value\": \"<param-value>\"}, ...}}\n"); - log(" <- {\"frontend\": \"[ilang|verilog|...]\",\"source\": \"<source>\"}}\n"); + log(" <- {\"frontend\": \"[rtlil|verilog|...]\",\"source\": \"<source>\"}}\n"); log(" <- {\"error\": \"<error-message>\"}\n"); log(" request for the module <module-name> to be derived for a specific set of\n"); log(" parameters. <param-name> starts with \\ for named parameters, and with $\n"); @@ -390,7 +390,7 @@ struct RpcFrontend : public Pass { log(" so the response should be the same whenever the same set of parameters\n"); log(" is provided.\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Connecting to RPC frontend.\n"); @@ -401,10 +401,11 @@ struct RpcFrontend : public Pass { std::string arg = args[argidx]; if (arg == "-exec" && argidx+1 < args.size()) { command.insert(command.begin(), args.begin() + argidx + 1, args.end()); + argidx = args.size()-1; continue; } if (arg == "-path" && argidx+1 < args.size()) { - path = args[argidx+1]; + path = args[++argidx]; continue; } break; diff --git a/frontends/rtlil/.gitignore b/frontends/rtlil/.gitignore new file mode 100644 index 000000000..d4a322756 --- /dev/null +++ b/frontends/rtlil/.gitignore @@ -0,0 +1,4 @@ +rtlil_lexer.cc +rtlil_parser.output +rtlil_parser.tab.cc +rtlil_parser.tab.hh diff --git a/frontends/rtlil/Makefile.inc b/frontends/rtlil/Makefile.inc new file mode 100644 index 000000000..d0c0cfcf8 --- /dev/null +++ b/frontends/rtlil/Makefile.inc @@ -0,0 +1,19 @@ + +GENFILES += frontends/rtlil/rtlil_parser.tab.cc +GENFILES += frontends/rtlil/rtlil_parser.tab.hh +GENFILES += frontends/rtlil/rtlil_parser.output +GENFILES += frontends/rtlil/rtlil_lexer.cc + +frontends/rtlil/rtlil_parser.tab.cc: frontends/rtlil/rtlil_parser.y + $(Q) mkdir -p $(dir $@) + $(P) $(BISON) -o $@ -d -r all -b frontends/rtlil/rtlil_parser $< + +frontends/rtlil/rtlil_parser.tab.hh: frontends/rtlil/rtlil_parser.tab.cc + +frontends/rtlil/rtlil_lexer.cc: frontends/rtlil/rtlil_lexer.l + $(Q) mkdir -p $(dir $@) + $(P) flex -o frontends/rtlil/rtlil_lexer.cc $< + +OBJS += frontends/rtlil/rtlil_parser.tab.o frontends/rtlil/rtlil_lexer.o +OBJS += frontends/rtlil/rtlil_frontend.o + diff --git a/frontends/ilang/ilang_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index 30d9ff79d..00c34175e 100644 --- a/frontends/ilang/ilang_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -18,30 +18,30 @@ * --- * * A very simple and straightforward frontend for the RTLIL text - * representation (as generated by the 'ilang' backend). + * representation. * */ -#include "ilang_frontend.h" +#include "rtlil_frontend.h" #include "kernel/register.h" #include "kernel/log.h" -void rtlil_frontend_ilang_yyerror(char const *s) +void rtlil_frontend_yyerror(char const *s) { - YOSYS_NAMESPACE_PREFIX log_error("Parser error in line %d: %s\n", rtlil_frontend_ilang_yyget_lineno(), s); + YOSYS_NAMESPACE_PREFIX log_error("Parser error in line %d: %s\n", rtlil_frontend_yyget_lineno(), s); } YOSYS_NAMESPACE_BEGIN -struct IlangFrontend : public Frontend { - IlangFrontend() : Frontend("ilang", "read modules from ilang file") { } - void help() YS_OVERRIDE +struct RTLILFrontend : public Frontend { + RTLILFrontend() : Frontend("rtlil", "read modules from RTLIL file") { } + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" read_ilang [filename]\n"); + log(" read_rtlil [filename]\n"); log("\n"); - log("Load modules from an ilang file to the current design. (ilang is a text\n"); + log("Load modules from an RTLIL file to the current design. (RTLIL is a text\n"); log("representation of a design in yosys's internal format.)\n"); log("\n"); log(" -nooverwrite\n"); @@ -56,29 +56,29 @@ struct IlangFrontend : public Frontend { log(" only create empty blackbox modules\n"); log("\n"); } - void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { - ILANG_FRONTEND::flag_nooverwrite = false; - ILANG_FRONTEND::flag_overwrite = false; - ILANG_FRONTEND::flag_lib = false; + RTLIL_FRONTEND::flag_nooverwrite = false; + RTLIL_FRONTEND::flag_overwrite = false; + RTLIL_FRONTEND::flag_lib = false; - log_header(design, "Executing ILANG frontend.\n"); + log_header(design, "Executing RTLIL frontend.\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; if (arg == "-nooverwrite") { - ILANG_FRONTEND::flag_nooverwrite = true; - ILANG_FRONTEND::flag_overwrite = false; + RTLIL_FRONTEND::flag_nooverwrite = true; + RTLIL_FRONTEND::flag_overwrite = false; continue; } if (arg == "-overwrite") { - ILANG_FRONTEND::flag_nooverwrite = false; - ILANG_FRONTEND::flag_overwrite = true; + RTLIL_FRONTEND::flag_nooverwrite = false; + RTLIL_FRONTEND::flag_overwrite = true; continue; } if (arg == "-lib") { - ILANG_FRONTEND::flag_lib = true; + RTLIL_FRONTEND::flag_lib = true; continue; } break; @@ -87,12 +87,27 @@ struct IlangFrontend : public Frontend { log("Input filename: %s\n", filename.c_str()); - ILANG_FRONTEND::lexin = f; - ILANG_FRONTEND::current_design = design; - rtlil_frontend_ilang_yydebug = false; - rtlil_frontend_ilang_yyrestart(NULL); - rtlil_frontend_ilang_yyparse(); - rtlil_frontend_ilang_yylex_destroy(); + RTLIL_FRONTEND::lexin = f; + RTLIL_FRONTEND::current_design = design; + rtlil_frontend_yydebug = false; + rtlil_frontend_yyrestart(NULL); + rtlil_frontend_yyparse(); + rtlil_frontend_yylex_destroy(); + } +} RTLILFrontend; + +struct IlangFrontend : public Frontend { + IlangFrontend() : Frontend("ilang", "(deprecated) alias of read_rtlil") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log("See `help read_rtlil`.\n"); + log("\n"); + } + void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override + { + RTLILFrontend.execute(f, filename, args, design); } } IlangFrontend; diff --git a/frontends/ilang/ilang_frontend.h b/frontends/rtlil/rtlil_frontend.h index f8a152841..a420778b0 100644 --- a/frontends/ilang/ilang_frontend.h +++ b/frontends/rtlil/rtlil_frontend.h @@ -18,18 +18,18 @@ * --- * * A very simple and straightforward frontend for the RTLIL text - * representation (as generated by the 'ilang' backend). + * representation. * */ -#ifndef ILANG_FRONTEND_H -#define ILANG_FRONTEND_H +#ifndef RTLIL_FRONTEND_H +#define RTLIL_FRONTEND_H #include "kernel/yosys.h" YOSYS_NAMESPACE_BEGIN -namespace ILANG_FRONTEND { +namespace RTLIL_FRONTEND { extern std::istream *lexin; extern RTLIL::Design *current_design; extern bool flag_nooverwrite; @@ -39,13 +39,13 @@ namespace ILANG_FRONTEND { YOSYS_NAMESPACE_END -extern int rtlil_frontend_ilang_yydebug; -int rtlil_frontend_ilang_yylex(void); -void rtlil_frontend_ilang_yyerror(char const *s); -void rtlil_frontend_ilang_yyrestart(FILE *f); -int rtlil_frontend_ilang_yyparse(void); -int rtlil_frontend_ilang_yylex_destroy(void); -int rtlil_frontend_ilang_yyget_lineno(void); +extern int rtlil_frontend_yydebug; +int rtlil_frontend_yylex(void); +void rtlil_frontend_yyerror(char const *s); +void rtlil_frontend_yyrestart(FILE *f); +int rtlil_frontend_yyparse(void); +int rtlil_frontend_yylex_destroy(void); +int rtlil_frontend_yyget_lineno(void); #endif diff --git a/frontends/ilang/ilang_lexer.l b/frontends/rtlil/rtlil_lexer.l index 3362ed641..295455f53 100644 --- a/frontends/ilang/ilang_lexer.l +++ b/frontends/rtlil/rtlil_lexer.l @@ -18,7 +18,7 @@ * --- * * A very simple and straightforward frontend for the RTLIL text - * representation (as generated by the 'ilang' backend). + * representation. * */ @@ -30,20 +30,20 @@ #endif #include <cstdlib> -#include "frontends/ilang/ilang_frontend.h" -#include "ilang_parser.tab.hh" +#include "frontends/rtlil/rtlil_frontend.h" +#include "rtlil_parser.tab.hh" USING_YOSYS_NAMESPACE #define YY_INPUT(buf,result,max_size) \ - result = readsome(*ILANG_FRONTEND::lexin, buf, max_size) + result = readsome(*RTLIL_FRONTEND::lexin, buf, max_size) %} %option yylineno %option noyywrap %option nounput -%option prefix="rtlil_frontend_ilang_yy" +%option prefix="rtlil_frontend_yy" %x STRING @@ -84,11 +84,11 @@ USING_YOSYS_NAMESPACE [a-z]+ { return TOK_INVALID; } -"\\"[^ \t\r\n]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } -"$"[^ \t\r\n]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } -"."[0-9]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } +"\\"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; } +"$"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; } +"."[0-9]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; } -[0-9]+'[01xzm-]* { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_VALUE; } +[0-9]+'[01xzm-]* { rtlil_frontend_yylval.string = strdup(yytext); return TOK_VALUE; } -?[0-9]+ { char *end = nullptr; errno = 0; @@ -98,7 +98,7 @@ USING_YOSYS_NAMESPACE return TOK_INVALID; // literal out of range of long if (value < INT_MIN || value > INT_MAX) return TOK_INVALID; // literal out of range of int (relevant mostly for LP64 platforms) - rtlil_frontend_ilang_yylval.integer = value; + rtlil_frontend_yylval.integer = value; return TOK_INT; } @@ -131,7 +131,7 @@ USING_YOSYS_NAMESPACE yystr[j++] = yystr[i++]; } yystr[j] = 0; - rtlil_frontend_ilang_yylval.string = yystr; + rtlil_frontend_yylval.string = yystr; return TOK_STRING; } <STRING>. { yymore(); } @@ -145,6 +145,6 @@ USING_YOSYS_NAMESPACE %% // this is a hack to avoid the 'yyinput defined but not used' error msgs -void *rtlil_frontend_ilang_avoid_input_warnings() { +void *rtlil_frontend_avoid_input_warnings() { return (void*)&yyinput; } diff --git a/frontends/ilang/ilang_parser.y b/frontends/rtlil/rtlil_parser.y index 879ef4af9..646489196 100644 --- a/frontends/ilang/ilang_parser.y +++ b/frontends/rtlil/rtlil_parser.y @@ -18,15 +18,15 @@ * --- * * A very simple and straightforward frontend for the RTLIL text - * representation (as generated by the 'ilang' backend). + * representation. * */ %{ #include <list> -#include "frontends/ilang/ilang_frontend.h" +#include "frontends/rtlil/rtlil_frontend.h" YOSYS_NAMESPACE_BEGIN -namespace ILANG_FRONTEND { +namespace RTLIL_FRONTEND { std::istream *lexin; RTLIL::Design *current_design; RTLIL::Module *current_module; @@ -40,12 +40,12 @@ namespace ILANG_FRONTEND { bool flag_nooverwrite, flag_overwrite, flag_lib; bool delete_current_module; } -using namespace ILANG_FRONTEND; +using namespace RTLIL_FRONTEND; YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE %} -%define api.prefix {rtlil_frontend_ilang_yy} +%define api.prefix {rtlil_frontend_yy} /* The union is defined in the header, so we need to provide all the * includes it requires @@ -53,7 +53,7 @@ USING_YOSYS_NAMESPACE %code requires { #include <string> #include <vector> -#include "frontends/ilang/ilang_frontend.h" +#include "frontends/rtlil/rtlil_frontend.h" } %union { @@ -87,7 +87,7 @@ input: attrbuf.clear(); } design { if (attrbuf.size() != 0) - rtlil_frontend_ilang_yyerror("dangling attribute"); + rtlil_frontend_yyerror("dangling attribute"); }; EOL: @@ -111,7 +111,7 @@ module: log("Ignoring blackbox re-definition of module %s.\n", $2); delete_current_module = true; } else if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute(ID::blackbox)) { - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of module %s.", $2).c_str()); } else if (flag_nooverwrite) { log("Ignoring re-definition of module %s.\n", $2); delete_current_module = true; @@ -129,7 +129,7 @@ module: free($2); } module_body TOK_END { if (attrbuf.size() != 0) - rtlil_frontend_ilang_yyerror("dangling attribute"); + rtlil_frontend_yyerror("dangling attribute"); current_module->fixup_ports(); if (delete_current_module) delete current_module; @@ -172,12 +172,12 @@ autoidx_stmt: wire_stmt: TOK_WIRE { - current_wire = current_module->addWire("$__ilang_frontend_tmp__"); + current_wire = current_module->addWire("$__rtlil_frontend_tmp__"); current_wire->attributes = attrbuf; attrbuf.clear(); } wire_options TOK_ID EOL { if (current_module->wire($4) != nullptr) - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of wire %s.", $4).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of wire %s.", $4).c_str()); current_module->rename(current_wire, $4); free($4); }; @@ -187,7 +187,7 @@ wire_options: current_wire->width = $3; } | wire_options TOK_WIDTH TOK_INVALID { - rtlil_frontend_ilang_yyerror("ilang error: invalid wire width"); + rtlil_frontend_yyerror("RTLIL error: invalid wire width"); } | wire_options TOK_UPTO { current_wire->upto = true; @@ -222,7 +222,7 @@ memory_stmt: attrbuf.clear(); } memory_options TOK_ID EOL { if (current_module->memories.count($4) != 0) - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of memory %s.", $4).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of memory %s.", $4).c_str()); current_memory->name = $4; current_module->memories[$4] = current_memory; free($4); @@ -243,7 +243,7 @@ memory_options: cell_stmt: TOK_CELL TOK_ID TOK_ID EOL { if (current_module->cell($3) != nullptr) - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell %s.", $3).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of cell %s.", $3).c_str()); current_cell = current_module->addCell($3, $2); current_cell->attributes = attrbuf; attrbuf.clear(); @@ -271,7 +271,7 @@ cell_body: } | cell_body TOK_CONNECT TOK_ID sigspec EOL { if (current_cell->hasPort($3)) - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of cell port %s.", $3).c_str()); current_cell->setPort($3, *$4); delete $4; free($3); @@ -281,7 +281,7 @@ cell_body: proc_stmt: TOK_PROCESS TOK_ID EOL { if (current_module->processes.count($2) != 0) - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of process %s.", $2).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of process %s.", $2).c_str()); current_process = new RTLIL::Process; current_process->name = $2; current_process->attributes = attrbuf; @@ -342,7 +342,7 @@ case_body: assign_stmt: TOK_ASSIGN sigspec sigspec EOL { if (attrbuf.size() != 0) - rtlil_frontend_ilang_yyerror("dangling attribute"); + rtlil_frontend_yyerror("dangling attribute"); case_stack.back()->actions.push_back(RTLIL::SigSig(*$2, *$3)); delete $2; delete $3; @@ -438,19 +438,19 @@ sigspec: } | TOK_ID { if (current_module->wire($1) == nullptr) - rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: wire %s not found", $1).c_str()); $$ = new RTLIL::SigSpec(current_module->wire($1)); free($1); } | sigspec '[' TOK_INT ']' { if ($3 >= $1->size() || $3 < 0) - rtlil_frontend_ilang_yyerror("bit index out of range"); + rtlil_frontend_yyerror("bit index out of range"); $$ = new RTLIL::SigSpec($1->extract($3)); delete $1; } | sigspec '[' TOK_INT ':' TOK_INT ']' { if ($3 >= $1->size() || $3 < 0 || $3 < $5) - rtlil_frontend_ilang_yyerror("invalid slice"); + rtlil_frontend_yyerror("invalid slice"); $$ = new RTLIL::SigSpec($1->extract($5, $3 - $5 + 1)); delete $1; } | @@ -477,7 +477,7 @@ sigspec_list: sigspec_list_reversed { conn_stmt: TOK_CONNECT sigspec sigspec EOL { if (attrbuf.size() != 0) - rtlil_frontend_ilang_yyerror("dangling attribute"); + rtlil_frontend_yyerror("dangling attribute"); current_module->connect(*$2, *$3); delete $2; delete $3; diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index cb0368fd5..31c77d39c 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -21,6 +21,7 @@ #include "kernel/sigtools.h" #include "kernel/celltypes.h" #include "kernel/log.h" +#include "libs/sha1/sha1.h" #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -48,12 +49,13 @@ USING_YOSYS_NAMESPACE #include "VeriWrite.h" #include "VhdlUnits.h" #include "VeriLibrary.h" +#include "VeriExtensions.h" #ifndef SYMBIOTIC_VERIFIC_API_VERSION # error "Only Symbiotic EDA flavored Verific is supported. Please contact office@symbioticeda.com for commercial support for Yosys+Verific." #endif -#if SYMBIOTIC_VERIFIC_API_VERSION < 1 +#if SYMBIOTIC_VERIFIC_API_VERSION < 20201001 # error "Please update your version of Symbiotic EDA flavored Verific." #endif @@ -198,12 +200,17 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att attributes.emplace(stringf("\\enum_value_%s", p+2), RTLIL::escape_id(k)); } else if (nl->IsFromVhdl()) { - // Expect "<binary>" + // Expect "<binary>" or plain <binary> auto p = v; if (p) { - if (*p != '"') - p = nullptr; - else { + if (*p != '"') { + auto l = strlen(p); + auto q = (char*)malloc(l+1); + strncpy(q, p, l); + q[l] = '\0'; + for(char *ptr = q; *ptr; ++ptr )*ptr = tolower(*ptr); + attributes.emplace(stringf("\\enum_value_%s", q), RTLIL::escape_id(k)); + } else { auto *q = p+1; for (; *q != '"'; q++) if (*q != '0' && *q != '1') { @@ -212,16 +219,20 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att } if (p && *(q+1) != '\0') p = nullptr; + + if (p != nullptr) + { + auto l = strlen(p); + auto q = (char*)malloc(l+1-2); + strncpy(q, p+1, l-2); + q[l-2] = '\0'; + attributes.emplace(stringf("\\enum_value_%s", q), RTLIL::escape_id(k)); + free(q); + } } } if (p == nullptr) - log_error("Expected TypeRange value '%s' to be of form \"<binary>\".\n", v); - auto l = strlen(p); - auto q = (char*)malloc(l+1-2); - strncpy(q, p+1, l-2); - q[l-2] = '\0'; - attributes.emplace(stringf("\\enum_value_%s", q), RTLIL::escape_id(k)); - free(q); + log_error("Expected TypeRange value '%s' to be of form \"<binary>\" or <binary>.\n", v); } } } @@ -854,6 +865,21 @@ void VerificImporter::merge_past_ffs(pool<RTLIL::Cell*> &candidates) merge_past_ffs_clock(it.second, it.first.first, it.first.second); } +static std::string sha1_if_contain_spaces(std::string str) +{ + if(str.find_first_of(' ') != std::string::npos) { + std::size_t open = str.find_first_of('('); + std::size_t closed = str.find_last_of(')'); + if (open != std::string::npos && closed != std::string::npos) { + std::string content = str.substr(open + 1, closed - open - 1); + return str.substr(0, open + 1) + sha1(content) + str.substr(closed); + } else { + return sha1(str); + } + } + return str; +} + void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::set<Netlist*> &nl_todo, bool norename) { std::string netlist_name = nl->GetAtt(" \\top") ? nl->CellBaseName() : nl->Owner()->Name(); @@ -867,7 +893,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se module_name += nl->Name(); module_name += ")"; } - module_name = "\\" + module_name; + module_name = "\\" + sha1_if_contain_spaces(module_name); } netlist = nl; @@ -1109,7 +1135,12 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se RTLIL::Wire *wire = module->addWire(wire_name, netbus->Size()); wire->start_offset = min(netbus->LeftIndex(), netbus->RightIndex()); - import_attributes(wire->attributes, netbus, nl); + MapIter mibus; + FOREACH_NET_OF_NETBUS(netbus, mibus, net) { + if (net) + import_attributes(wire->attributes, net, nl); + break; + } RTLIL::Const initval = Const(State::Sx, GetSize(wire)); bool initval_valid = false; @@ -1262,7 +1293,10 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se if (inst->Type() == OPER_READ_PORT) { - RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetInput()->Name())); + RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetInput()->Name()), nullptr); + if (!memory) + log_error("Memory net '%s' missing, possibly no driver, use verific -flatten.\n", inst->GetInput()->Name()); + int numchunks = int(inst->OutputSize()) / memory->width; int chunksbits = ceil_log2(numchunks); @@ -1289,7 +1323,9 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se if (inst->Type() == OPER_WRITE_PORT || inst->Type() == OPER_CLOCKED_WRITE_PORT) { - RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetOutput()->Name())); + RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetOutput()->Name()), nullptr); + if (!memory) + log_error("Memory net '%s' missing, possibly no driver, use verific -flatten.\n", inst->GetInput()->Name()); int numchunks = int(inst->Input2Size()) / memory->width; int chunksbits = ceil_log2(numchunks); @@ -1435,6 +1471,16 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se continue; } + if (inst->Type() == PRIM_SEDA_INITSTATE) + { + SigBit initstate = module->Initstate(new_verific_id(inst)); + SigBit sig_o = net_map_at(inst->GetOutput()); + module->connect(sig_o, initstate); + + if (!mode_keep) + continue; + } + if (!mode_keep && verific_sva_prims.count(inst->Type())) { if (verific_verbose) log(" skipping SVA cell in non k-mode\n"); @@ -1482,7 +1528,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se inst_type += inst->View()->Name(); inst_type += ")"; } - inst_type = "\\" + inst_type; + inst_type = "\\" + sha1_if_contain_spaces(inst_type); } RTLIL::Cell *cell = module->addCell(inst_name, inst_type); @@ -1877,7 +1923,7 @@ struct VerificExtNets new_net = new Net(name.c_str()); nl->Add(new_net); - Net *n YS_ATTRIBUTE(unused) = route_up(new_net, port->IsOutput(), ca_nl, ca_net); + Net *n = route_up(new_net, port->IsOutput(), ca_nl, ca_net); log_assert(n == ca_net); } @@ -1912,6 +1958,9 @@ void verific_import(Design *design, const std::map<std::string,std::string> &par for (const auto &i : parameters) verific_params.Insert(i.first.c_str(), i.second.c_str()); + InitialAssertionRewriter rw; + rw.RegisterCallBack(); + if (top.empty()) { netlists = hier_tree::ElaborateAll(&veri_libs, &vhdl_libs, &verific_params); } @@ -2003,7 +2052,7 @@ bool check_noverific_env() struct VerificPass : public Pass { VerificPass() : Pass("verific", "load Verilog and VHDL designs using Verific") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -2134,6 +2183,73 @@ struct VerificPass : public Pass { log(" Dump the Verific netlist as a verilog file.\n"); log("\n"); log("\n"); + log(" verific [-work <libname>] -pp [options] <filename> [<module>]..\n"); + log("\n"); + log("Pretty print design (or just module) to the specified file from the\n"); + log("specified library. (default library when -work is not present: \"work\")\n"); + log("\n"); + log("Pretty print options:\n"); + log("\n"); + log(" -verilog\n"); + log(" Save output for Verilog/SystemVerilog design modules (default).\n"); + log("\n"); + log(" -vhdl\n"); + log(" Save output for VHDL design units.\n"); + log("\n"); + log("\n"); + log(" verific -app <application>..\n"); + log("\n"); + log("Execute SEDA formal application on loaded Verilog files.\n"); + log("\n"); + log("Application options:\n"); + log("\n"); + log(" -module <module>\n"); + log(" Run formal application only on specified module.\n"); + log("\n"); + log(" -blacklist <filename[:lineno]>\n"); + log(" Do not run application on modules from files that match the filename\n"); + log(" or filename and line number if provided in such format.\n"); + log(" Parameter can also contain comma separated list of file locations.\n"); + log("\n"); + log(" -blfile <file>\n"); + log(" Do not run application on locations specified in file, they can represent filename\n"); + log(" or filename and location in file.\n"); + log("\n"); + log("Applications:\n"); + log("\n"); +#ifdef YOSYS_ENABLE_VERIFIC + VerificFormalApplications vfa; + log("%s\n",vfa.GetHelp().c_str()); +#else + log(" WARNING: Applications only available in commercial build.\n"); + +#endif + log("\n"); + log("\n"); + log(" verific -template <name> <top_module>..\n"); + log("\n"); + log("Generate template for specified top module of loaded design.\n"); + log("\n"); + log("Template options:\n"); + log("\n"); + log(" -out\n"); + log(" Specifies output file for generated template, by default output is stdout\n"); + log("\n"); + log(" -chparam name value \n"); + log(" Generate template using this parameter value. Otherwise default parameter\n"); + log(" values will be used for templat generate functionality. This option\n"); + log(" can be specified multiple times to override multiple parameters.\n"); + log(" String values must be passed in double quotes (\").\n"); + log("\n"); + log("Templates:\n"); + log("\n"); +#ifdef YOSYS_ENABLE_VERIFIC + VerificTemplateGenerator vfg; + log("%s\n",vfg.GetHelp().c_str()); +#else + log(" WARNING: Templates only available in commercial build.\n"); + log("\n"); +#endif log("Use Symbiotic EDA Suite if you need Yosys+Verifc.\n"); log("https://www.symbioticeda.com/seda-suite\n"); log("\n"); @@ -2142,7 +2258,7 @@ struct VerificPass : public Pass { log("\n"); } #ifdef YOSYS_ENABLE_VERIFIC - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { static bool set_verific_global_flags = true; @@ -2175,6 +2291,12 @@ struct VerificPass : public Pass { RuntimeFlags::SetVar("vhdl_support_variable_slice", 1); RuntimeFlags::SetVar("vhdl_ignore_assertion_statements", 0); + RuntimeFlags::SetVar("veri_preserve_assignments", 1); + RuntimeFlags::SetVar("vhdl_preserve_assignments", 1); + + RuntimeFlags::SetVar("veri_preserve_comments",1); + //RuntimeFlags::SetVar("vhdl_preserve_comments",1); + // Workaround for VIPER #13851 RuntimeFlags::SetVar("veri_create_name_for_unnamed_gen_block", 1); @@ -2327,8 +2449,10 @@ struct VerificPass : public Pass { while (argidx < GetSize(args)) file_names.Insert(args[argidx++].c_str()); - if (!veri_file::AnalyzeMultipleFiles(&file_names, verilog_mode, work.c_str(), veri_file::MFCU)) + if (!veri_file::AnalyzeMultipleFiles(&file_names, verilog_mode, work.c_str(), veri_file::MFCU)) { + verific_error_msg.clear(); log_cmd_error("Reading Verilog/SystemVerilog sources failed.\n"); + } verific_import_pending = true; goto check_error; @@ -2370,6 +2494,226 @@ struct VerificPass : public Pass { goto check_error; } + if (argidx < GetSize(args) && args[argidx] == "-app") + { + if (!(argidx+1 < GetSize(args))) + cmd_error(args, argidx, "No formal application specified.\n"); + + VerificFormalApplications vfa; + auto apps = vfa.GetApps(); + std::string app = args[++argidx]; + std::vector<std::string> blacklists; + if (apps.find(app) == apps.end()) + log_cmd_error("Application '%s' does not exist.\n", app.c_str()); + + FormalApplication *application = apps[app]; + application->setLogger([](std::string msg) { log("%s",msg.c_str()); } ); + VeriModule *selected_module = nullptr; + + for (argidx++; argidx < GetSize(args); argidx++) { + std::string error; + if (application->checkParams(args, argidx, error)) { + if (!error.empty()) + cmd_error(args, argidx, error); + continue; + } + + if (args[argidx] == "-module" && argidx < GetSize(args)) { + if (!(argidx+1 < GetSize(args))) + cmd_error(args, argidx+1, "No module name specified.\n"); + std::string module = args[++argidx]; + VeriLibrary* veri_lib = veri_file::GetLibrary(work.c_str(), 1); + selected_module = veri_lib ? veri_lib->GetModule(module.c_str(), 1) : nullptr; + if (!selected_module) { + log_error("Can't find module '%s'.\n", module.c_str()); + } + continue; + } + if (args[argidx] == "-blacklist" && argidx < GetSize(args)) { + if (!(argidx+1 < GetSize(args))) + cmd_error(args, argidx+1, "No blacklist specified.\n"); + + std::string line = args[++argidx]; + std::string p; + while (!(p = next_token(line, ",\t\r\n ")).empty()) + blacklists.push_back(p); + continue; + } + if (args[argidx] == "-blfile" && argidx < GetSize(args)) { + if (!(argidx+1 < GetSize(args))) + cmd_error(args, argidx+1, "No blacklist file specified.\n"); + std::string fn = args[++argidx]; + std::ifstream f(fn); + if (f.fail()) + log_cmd_error("Can't open blacklist file '%s'!\n", fn.c_str()); + + std::string line,p; + while (std::getline(f, line)) { + while (!(p = next_token(line, ",\t\r\n ")).empty()) + blacklists.push_back(p); + } + continue; + } + break; + } + if (argidx < GetSize(args)) + cmd_error(args, argidx, "unknown option/parameter"); + + application->setBlacklists(&blacklists); + application->setSingleModuleMode(selected_module!=nullptr); + + const char *err = application->validate(); + if (err) + cmd_error(args, argidx, err); + + MapIter mi; + VeriLibrary *veri_lib = veri_file::GetLibrary(work.c_str(), 1); + log("Running formal application '%s'.\n", app.c_str()); + + if (selected_module) { + std::string out; + if (!application->execute(selected_module, out)) + log_error("%s", out.c_str()); + } + else { + VeriModule *module ; + FOREACH_VERILOG_MODULE_IN_LIBRARY(veri_lib, mi, module) { + std::string out; + if (!application->execute(module, out)) { + log_error("%s", out.c_str()); + break; + } + } + } + goto check_error; + } + + if (argidx < GetSize(args) && args[argidx] == "-pp") + { + const char* filename = nullptr; + const char* module = nullptr; + bool mode_vhdl = false; + for (argidx++; argidx < GetSize(args); argidx++) { + if (args[argidx] == "-vhdl") { + mode_vhdl = true; + continue; + } + if (args[argidx] == "-verilog") { + mode_vhdl = false; + continue; + } + + if (args[argidx].compare(0, 1, "-") == 0) { + cmd_error(args, argidx, "unknown option"); + goto check_error; + } + + if (!filename) { + filename = args[argidx].c_str(); + continue; + } + if (module) + log_cmd_error("Only one module can be specified.\n"); + module = args[argidx].c_str(); + } + + if (argidx < GetSize(args)) + cmd_error(args, argidx, "unknown option/parameter"); + + if (!filename) + log_cmd_error("Filname must be specified.\n"); + + if (mode_vhdl) + vhdl_file::PrettyPrint(filename, module, work.c_str()); + else + veri_file::PrettyPrint(filename, module, work.c_str()); + goto check_error; + } + + if (argidx < GetSize(args) && args[argidx] == "-template") + { + if (!(argidx+1 < GetSize(args))) + cmd_error(args, argidx+1, "No template type specified.\n"); + + VerificTemplateGenerator vfg; + auto gens = vfg.GetGenerators(); + std::string app = args[++argidx]; + if (gens.find(app) == gens.end()) + log_cmd_error("Template generator '%s' does not exist.\n", app.c_str()); + TemplateGenerator *generator = gens[app]; + if (!(argidx+1 < GetSize(args))) + cmd_error(args, argidx+1, "No top module specified.\n"); + generator->setLogger([](std::string msg) { log("%s",msg.c_str()); } ); + + std::string module = args[++argidx]; + VeriLibrary* veri_lib = veri_file::GetLibrary(work.c_str(), 1); + VeriModule *veri_module = veri_lib ? veri_lib->GetModule(module.c_str(), 1) : nullptr; + if (!veri_module) { + log_error("Can't find module/unit '%s'.\n", module.c_str()); + } + + log("Template '%s' is running for module '%s'.\n", app.c_str(),module.c_str()); + + Map parameters(STRING_HASH); + const char *out_filename = nullptr; + + for (argidx++; argidx < GetSize(args); argidx++) { + std::string error; + if (generator->checkParams(args, argidx, error)) { + if (!error.empty()) + cmd_error(args, argidx, error); + continue; + } + + if (args[argidx] == "-chparam" && argidx < GetSize(args)) { + if (!(argidx+1 < GetSize(args))) + cmd_error(args, argidx+1, "No param name specified.\n"); + if (!(argidx+2 < GetSize(args))) + cmd_error(args, argidx+2, "No param value specified.\n"); + + const std::string &key = args[++argidx]; + const std::string &value = args[++argidx]; + unsigned new_insertion = parameters.Insert(key.c_str(), value.c_str(), + 1 /* force_overwrite */); + if (!new_insertion) + log_warning_noprefix("-chparam %s already specified: overwriting.\n", key.c_str()); + continue; + } + + if (args[argidx] == "-out" && argidx < GetSize(args)) { + if (!(argidx+1 < GetSize(args))) + cmd_error(args, argidx+1, "No output file specified.\n"); + out_filename = args[++argidx].c_str(); + continue; + } + + break; + } + if (argidx < GetSize(args)) + cmd_error(args, argidx, "unknown option/parameter"); + + const char *err = generator->validate(); + if (err) + cmd_error(args, argidx, err); + + std::string val; + if (!generator->generate(veri_module, val, ¶meters)) + log_error("%s", val.c_str()); + + FILE *of = stdout; + if (out_filename) { + of = fopen(out_filename, "w"); + if (of == nullptr) + log_error("Can't open '%s' for writing: %s\n", out_filename, strerror(errno)); + log("Writing output to '%s'\n",out_filename); + } + fprintf(of, "%s\n",val.c_str()); + fflush(of); + if (of!=stdout) + fclose(of); + goto check_error; + } + if (GetSize(args) > argidx && args[argidx] == "-import") { std::set<Netlist*> nl_todo, nl_done; @@ -2454,6 +2798,9 @@ struct VerificPass : public Pass { std::set<std::string> top_mod_names; + InitialAssertionRewriter rw; + rw.RegisterCallBack(); + if (mode_all) { log("Running hier_tree::ElaborateAll().\n"); @@ -2478,31 +2825,23 @@ struct VerificPass : public Pass { if (argidx == GetSize(args)) cmd_error(args, argidx, "No top module specified.\n"); + VeriLibrary* veri_lib = veri_file::GetLibrary(work.c_str(), 1); + VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary(work.c_str(), 1); + Array veri_modules, vhdl_units; for (; argidx < GetSize(args); argidx++) { const char *name = args[argidx].c_str(); top_mod_names.insert(name); - VeriLibrary* veri_lib = veri_file::GetLibrary(work.c_str(), 1); - if (veri_lib) { - VeriModule *veri_module = veri_lib->GetModule(name, 1); - if (veri_module) { - log("Adding Verilog module '%s' to elaboration queue.\n", name); - veri_modules.InsertLast(veri_module); - continue; - } - - // Also elaborate all root modules since they may contain bind statements - MapIter mi; - FOREACH_VERILOG_MODULE_IN_LIBRARY(veri_lib, mi, veri_module) { - if (!veri_module->IsRootModule()) continue; - veri_modules.InsertLast(veri_module); - } + VeriModule *veri_module = veri_lib ? veri_lib->GetModule(name, 1) : nullptr; + if (veri_module) { + log("Adding Verilog module '%s' to elaboration queue.\n", name); + veri_modules.InsertLast(veri_module); + continue; } - VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary(work.c_str(), 1); - VhdlDesignUnit *vhdl_unit = vhdl_lib->GetPrimUnit(name); + VhdlDesignUnit *vhdl_unit = vhdl_lib ? vhdl_lib->GetPrimUnit(name) : nullptr; if (vhdl_unit) { log("Adding VHDL unit '%s' to elaboration queue.\n", name); vhdl_units.InsertLast(vhdl_unit); @@ -2512,6 +2851,16 @@ struct VerificPass : public Pass { log_error("Can't find module/unit '%s'.\n", name); } + if (veri_lib) { + // Also elaborate all root modules since they may contain bind statements + MapIter mi; + VeriModule *veri_module; + FOREACH_VERILOG_MODULE_IN_LIBRARY(veri_lib, mi, veri_module) { + if (!veri_module->IsRootModule()) continue; + veri_modules.InsertLast(veri_module); + } + } + log("Running hier_tree::Elaborate().\n"); Array *netlists = hier_tree::Elaborate(&veri_modules, &vhdl_units, ¶meters); Netlist *nl; @@ -2574,7 +2923,7 @@ struct VerificPass : public Pass { } #else /* YOSYS_ENABLE_VERIFIC */ - void execute(std::vector<std::string>, RTLIL::Design *) YS_OVERRIDE { + void execute(std::vector<std::string>, RTLIL::Design *) override { log_cmd_error("This version of Yosys is built without Verific support.\n" "\n" "Use Symbiotic EDA Suite if you need Yosys+Verifc.\n" @@ -2588,7 +2937,7 @@ struct VerificPass : public Pass { struct ReadPass : public Pass { ReadPass() : Pass("read", "load HDL designs") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -2629,7 +2978,7 @@ struct ReadPass : public Pass { log("Verific support. The default is to use Verific if it is available.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { #ifdef YOSYS_ENABLE_VERIFIC static bool verific_available = !check_noverific_env(); diff --git a/frontends/verific/verificsva.cc b/frontends/verific/verificsva.cc index 49c0c40ac..632043b6f 100644 --- a/frontends/verific/verificsva.cc +++ b/frontends/verific/verificsva.cc @@ -1040,8 +1040,14 @@ struct VerificSvaImporter [[noreturn]] void parser_error(Instance *inst) { - parser_error(stringf("Verific SVA primitive %s (%s) is currently unsupported in this context", - inst->View()->Owner()->Name(), inst->Name()), inst->Linefile()); + std::string msg; + if (inst->Type() == PRIM_SVA_MATCH_ITEM_TRIGGER || inst->Type() == PRIM_SVA_MATCH_ITEM_ASSIGN) + { + msg = "SVA sequences with local variable assignments are currently not supported.\n"; + } + + parser_error(stringf("%sVerific SVA primitive %s (%s) is currently unsupported in this context", + msg.c_str(), inst->View()->Owner()->Name(), inst->Name()), inst->Linefile()); } dict<Net*, bool, hash_ptr_ops> check_expression_cache; diff --git a/frontends/verilog/Makefile.inc b/frontends/verilog/Makefile.inc index cf9b9531e..2c923f0b7 100644 --- a/frontends/verilog/Makefile.inc +++ b/frontends/verilog/Makefile.inc @@ -6,7 +6,7 @@ GENFILES += frontends/verilog/verilog_lexer.cc frontends/verilog/verilog_parser.tab.cc: frontends/verilog/verilog_parser.y $(Q) mkdir -p $(dir $@) - $(P) $(BISON) -o $@ -d -r all -b frontends/verilog/verilog_parser $< + $(P) $(BISON) -Wall -Werror -o $@ -d -r all -b frontends/verilog/verilog_parser $< frontends/verilog/verilog_parser.tab.hh: frontends/verilog/verilog_parser.tab.cc diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 7905ea598..ea23139e2 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -591,7 +591,7 @@ read_define_args() default: // The only FSM states are 0-2 and we dealt with 2 at the start of the loop. - __builtin_unreachable(); + log_assert(false); } } diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 26abe49b5..2e9c9b2e2 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -67,7 +67,7 @@ static void add_package_types(dict<std::string, AST::AstNode *> &user_types, std struct VerilogFrontend : public Frontend { VerilogFrontend() : Frontend("verilog", "read modules from Verilog file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -232,7 +232,7 @@ struct VerilogFrontend : public Frontend { log("supported by the Yosys Verilog front-end.\n"); log("\n"); } - void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { bool flag_dump_ast1 = false; bool flag_dump_ast2 = false; @@ -503,7 +503,7 @@ struct VerilogFrontend : public Frontend { struct VerilogDefaults : public Pass { VerilogDefaults() : Pass("verilog_defaults", "set default options for read_verilog") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -524,7 +524,7 @@ struct VerilogDefaults : public Pass { log("not imply -clear.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design*) override { if (args.size() < 2) cmd_error(args, 1, "Missing argument."); @@ -561,7 +561,7 @@ struct VerilogDefaults : public Pass { struct VerilogDefines : public Pass { VerilogDefines() : Pass("verilog_defines", "define and undefine verilog defines") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -583,7 +583,7 @@ struct VerilogDefines : public Pass { log(" list currently defined preprocessor symbols\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index e6fa6361e..f2241066f 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -517,6 +517,8 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { "<<<" { return OP_SSHL; } ">>>" { return OP_SSHR; } +"'" { return OP_CAST; } + "::" { return TOK_PACKAGESEP; } "++" { return TOK_INCREMENT; } "--" { return TOK_DECREMENT; } @@ -526,6 +528,12 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { ".*" { return TOK_WILDCARD_CONNECT; } +"|=" { SV_KEYWORD(TOK_OR_ASSIGN); } +"&=" { SV_KEYWORD(TOK_AND_ASSIGN); } +"+=" { SV_KEYWORD(TOK_PLUS_ASSIGN); } +"-=" { SV_KEYWORD(TOK_SUB_ASSIGN); } +"^=" { SV_KEYWORD(TOK_XOR_ASSIGN); } + [-+]?[=*]> { if (!specify_mode) REJECT; yylval->string = new std::string(yytext); diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index b34a62248..678ce6c87 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -210,14 +210,23 @@ static AstNode *checkRange(AstNode *type_node, AstNode *range_node) return range_node; } -static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) +static void rewriteRange(AstNode *rangeNode) { - node->type = AST_MEMORY; if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) { // SV array size [n], rewrite as [n-1:0] rangeNode->children[0] = new AstNode(AST_SUB, rangeNode->children[0], AstNode::mkconst_int(1, true)); rangeNode->children.push_back(AstNode::mkconst_int(0, false)); } +} + +static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) +{ + node->type = AST_MEMORY; + if (rangeNode->type == AST_MULTIRANGE) { + for (auto *itr : rangeNode->children) + rewriteRange(itr); + } else + rewriteRange(rangeNode); node->children.push_back(rangeNode); } @@ -256,7 +265,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %token TOK_PACKAGE TOK_ENDPACKAGE TOK_PACKAGESEP %token TOK_INTERFACE TOK_ENDINTERFACE TOK_MODPORT TOK_VAR TOK_WILDCARD_CONNECT %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_WAND TOK_WOR TOK_REG TOK_LOGIC -%token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL +%token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_PLUS_ASSIGN TOK_ALWAYS TOK_INITIAL %token TOK_ALWAYS_FF TOK_ALWAYS_COMB TOK_ALWAYS_LATCH %token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT %token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR TOK_AUTOMATIC @@ -269,7 +278,8 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_PROPERTY TOK_ENUM TOK_TYPEDEF %token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY %token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_PRIORITY -%token TOK_STRUCT TOK_PACKED TOK_UNSIGNED TOK_INT TOK_BYTE TOK_SHORTINT TOK_UNION +%token TOK_STRUCT TOK_PACKED TOK_UNSIGNED TOK_INT TOK_BYTE TOK_SHORTINT TOK_UNION +%token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN %type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int %type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list @@ -298,13 +308,14 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode) %left '+' '-' %left '*' '/' '%' %left OP_POW -%right UNARY_OPS +%precedence OP_CAST +%precedence UNARY_OPS %define parse.error verbose %define parse.lac full -%nonassoc FAKE_THEN -%nonassoc TOK_ELSE +%precedence FAKE_THEN +%precedence TOK_ELSE %debug %locations @@ -331,7 +342,7 @@ design: typedef_decl design | package design | interface design | - /* empty */; + %empty; attr: { @@ -353,7 +364,7 @@ attr_opt: attr_opt ATTR_BEGIN opt_attr_list ATTR_END { SET_RULE_LOC(@$, @2, @$); }| - /* empty */; + %empty; defattr: DEFATTR_BEGIN { @@ -374,7 +385,7 @@ defattr: } DEFATTR_END; opt_attr_list: - attr_list | /* empty */; + attr_list | %empty; attr_list: attr_assign | @@ -435,7 +446,7 @@ module: mod->str = *$4; append_attr(mod, $1); delete $4; - } module_para_opt module_args_opt ';' module_body TOK_ENDMODULE { + } module_para_opt module_args_opt ';' module_body TOK_ENDMODULE opt_label { if (port_stubs.size() != 0) frontend_verilog_yyerror("Missing details for module port `%s'.", port_stubs.begin()->first.c_str()); @@ -447,13 +458,13 @@ module: }; module_para_opt: - '#' '(' { astbuf1 = nullptr; } module_para_list { if (astbuf1) delete astbuf1; } ')' | /* empty */; + '#' '(' { astbuf1 = nullptr; } module_para_list { if (astbuf1) delete astbuf1; } ')' | %empty; module_para_list: single_module_para | module_para_list ',' single_module_para; single_module_para: - /* empty */ | + %empty | attr TOK_PARAMETER { if (astbuf1) delete astbuf1; astbuf1 = new AstNode(AST_PARAMETER); @@ -469,13 +480,13 @@ single_module_para: single_param_decl; module_args_opt: - '(' ')' | /* empty */ | '(' module_args optional_comma ')'; + '(' ')' | %empty | '(' module_args optional_comma ')'; module_args: module_arg | module_args ',' module_arg; optional_comma: - ',' | /* empty */; + ',' | %empty; module_arg_opt_assignment: '=' expr { @@ -495,7 +506,7 @@ module_arg_opt_assignment: } else frontend_verilog_yyerror("SystemVerilog interface in module port list cannot have a default value."); } | - /* empty */; + %empty; module_arg: TOK_ID { @@ -556,22 +567,17 @@ package: current_ast_mod = mod; mod->str = *$4; append_attr(mod, $1); - } ';' package_body TOK_ENDPACKAGE { + } ';' package_body TOK_ENDPACKAGE opt_label { ast_stack.pop_back(); current_ast_mod = NULL; exitTypeScope(); }; package_body: - package_body package_body_stmt - | // optional - ; + package_body package_body_stmt | %empty; package_body_stmt: - typedef_decl - | localparam_decl - | param_decl - ; + typedef_decl | localparam_decl | param_decl; interface: TOK_INTERFACE { @@ -597,7 +603,7 @@ interface: }; interface_body: - interface_body interface_body_stmt |; + interface_body interface_body_stmt | %empty; interface_body_stmt: param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt | @@ -611,7 +617,7 @@ non_opt_delay: '#' '(' expr ':' expr ':' expr ')' { delete $3; delete $5; delete $7; }; delay: - non_opt_delay | /* empty */; + non_opt_delay | %empty; wire_type: { @@ -723,7 +729,7 @@ range: non_opt_range { $$ = $1; } | - /* empty */ { + %empty { $$ = NULL; }; @@ -740,7 +746,8 @@ module_body: module_body module_body_stmt | /* the following line makes the generate..endgenrate keywords optional */ module_body gen_stmt | - /* empty */; + module_body ';' | + %empty; module_body_stmt: task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt | @@ -840,28 +847,28 @@ dpi_function_arg: opt_dpi_function_args: '(' dpi_function_args ')' | - /* empty */; + %empty; dpi_function_args: dpi_function_args ',' dpi_function_arg | dpi_function_args ',' | dpi_function_arg | - /* empty */; + %empty; opt_automatic: TOK_AUTOMATIC | - /* empty */; + %empty; opt_signed: TOK_SIGNED { $$ = true; } | - /* empty */ { + %empty { $$ = false; }; task_func_args_opt: - '(' ')' | /* empty */ | '(' { + '(' ')' | %empty | '(' { albuf = nullptr; astbuf1 = nullptr; astbuf2 = nullptr; @@ -902,7 +909,7 @@ task_func_port: task_func_body: task_func_body behavioral_stmt | - /* empty */; + %empty; /*************************** specify parser ***************************/ @@ -911,7 +918,7 @@ specify_block: specify_item_list: specify_item specify_item_list | - /* empty */; + %empty; specify_item: specify_if '(' specify_edge expr TOK_SPECIFY_OPER specify_target ')' '=' specify_rise_fall ';' { @@ -1073,7 +1080,7 @@ specify_opt_triple: ',' specify_triple { $$ = $2; } | - /* empty */ { + %empty { $$ = nullptr; }; @@ -1081,7 +1088,7 @@ specify_if: TOK_IF '(' expr ')' { $$ = $3; } | - /* empty */ { + %empty { $$ = nullptr; }; @@ -1089,7 +1096,7 @@ specify_condition: TOK_SPECIFY_AND expr { $$ = $2; } | - /* empty */ { + %empty { $$ = nullptr; }; @@ -1122,7 +1129,7 @@ specify_target: specify_edge: TOK_POSEDGE { $$ = 'p'; } | TOK_NEGEDGE { $$ = 'n'; } | - { $$ = 0; }; + %empty { $$ = 0; }; specify_rise_fall: specify_triple { @@ -1229,7 +1236,7 @@ specparam_assignment: ignspec_id '=' ignspec_expr ; ignspec_opt_cond: - TOK_IF '(' ignspec_expr ')' | /* empty */; + TOK_IF '(' ignspec_expr ')' | %empty; path_declaration : simple_path_declaration ';' @@ -1280,9 +1287,7 @@ list_of_path_outputs : list_of_path_outputs ',' specify_output_terminal_descriptor ; opt_polarity_operator : - '+' - | '-' - | ; + '+' | '-' | %empty; // Good enough for the time being specify_input_terminal_descriptor : @@ -1329,36 +1334,36 @@ ignspec_id: param_signed: TOK_SIGNED { astbuf1->is_signed = true; - } | /* empty */; + } | TOK_UNSIGNED { + astbuf1->is_signed = false; + } | %empty; param_integer: TOK_INTEGER { - if (astbuf1->children.size() != 1) - frontend_verilog_yyerror("Internal error in param_integer - should not happen?"); astbuf1->children.push_back(new AstNode(AST_RANGE)); astbuf1->children.back()->children.push_back(AstNode::mkconst_int(31, true)); astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true)); astbuf1->is_signed = true; - } | /* empty */; + }; param_real: TOK_REAL { - if (astbuf1->children.size() != 1) - frontend_verilog_yyerror("Parameter already declared as integer, cannot set to real."); astbuf1->children.push_back(new AstNode(AST_REALVALUE)); - } | /* empty */; + }; param_range: range { if ($1 != NULL) { - if (astbuf1->children.size() != 1) - frontend_verilog_yyerror("integer/real parameters should not have a range."); astbuf1->children.push_back($1); } }; +param_integer_type: param_integer param_signed; +param_range_type: type_vec param_signed param_range; +param_implicit_type: param_signed param_range; + param_type: - param_signed param_integer param_real param_range | + param_integer_type | param_real | param_range_type | param_implicit_type | hierarchical_type_id { astbuf1->is_custom_type = true; astbuf1->children.push_back(new AstNode(AST_WIRETYPE)); @@ -1448,7 +1453,7 @@ enum_type: TOK_ENUM { enum_base_type: type_atom type_signing | type_vec type_signing range { if ($3) astbuf1->children.push_back($3); } - | /* nothing */ { astbuf1->is_reg = true; addRange(astbuf1); } + | %empty { astbuf1->is_reg = true; addRange(astbuf1); } ; type_atom: TOK_INTEGER { astbuf1->is_reg = true; addRange(astbuf1); } // 4-state signed @@ -1464,7 +1469,7 @@ type_vec: TOK_REG { astbuf1->is_reg = true; } // unsigned type_signing: TOK_SIGNED { astbuf1->is_signed = true; } | TOK_UNSIGNED { astbuf1->is_signed = false; } - | // optional + | %empty ; enum_name_list: enum_name_decl @@ -1481,14 +1486,14 @@ enum_name_decl: delete $1; SET_AST_NODE_LOC(node, @1, @1); delete node->children[0]; - node->children[0] = $2 ?: new AstNode(AST_NONE); + node->children[0] = $2 ? $2 : new AstNode(AST_NONE); astbuf2->children.push_back(node); } ; opt_enum_init: '=' basic_expr { $$ = $2; } // TODO: restrict this - | /* optional */ { $$ = NULL; } + | %empty { $$ = NULL; } ; enum_var_list: @@ -1529,14 +1534,14 @@ struct_union: struct_body: opt_packed '{' struct_member_list '}' ; -opt_packed: TOK_PACKED opt_signed_struct - | { frontend_verilog_yyerror("Only PACKED supported at this time"); } - ; +opt_packed: + TOK_PACKED opt_signed_struct | + %empty { frontend_verilog_yyerror("Only PACKED supported at this time"); }; opt_signed_struct: TOK_SIGNED { astbuf2->is_signed = true; } | TOK_UNSIGNED { astbuf2->is_signed = false; } - | // default is unsigned + | %empty // default is unsigned ; struct_member_list: struct_member @@ -1643,7 +1648,7 @@ wire_decl: } opt_supply_wires ';'; opt_supply_wires: - /* empty */ | + %empty | opt_supply_wires ',' TOK_ID { AstNode *wire_node = ast_stack.back()->children.at(GetSize(ast_stack.back()->children)-2)->clone(); AstNode *assign_node = ast_stack.back()->children.at(GetSize(ast_stack.back()->children)-1)->clone(); @@ -1874,18 +1879,21 @@ single_prim: } cell_parameter_list_opt: - '#' '(' cell_parameter_list ')' | /* empty */; + '#' '(' cell_parameter_list ')' | %empty; cell_parameter_list: cell_parameter | cell_parameter_list ',' cell_parameter; cell_parameter: - /* empty */ | + %empty | expr { AstNode *node = new AstNode(AST_PARASET); astbuf1->children.push_back(node); node->children.push_back($1); } | + '.' TOK_ID '(' ')' { + // just ignore empty parameters + } | '.' TOK_ID '(' expr ')' { AstNode *node = new AstNode(AST_PARASET); node->str = *$2; @@ -2038,7 +2046,7 @@ always_cond: '@' ATTR_BEGIN ')' | '@' '(' ATTR_END | '@' '*' | - /* empty */; + %empty; always_events: always_event | @@ -2068,7 +2076,7 @@ opt_label: ':' TOK_ID { $$ = $2; } | - /* empty */ { + %empty { $$ = NULL; }; @@ -2076,7 +2084,7 @@ opt_sva_label: TOK_SVA_LABEL ':' { $$ = $1; } | - /* empty */ { + %empty { $$ = NULL; }; @@ -2087,7 +2095,7 @@ opt_property: TOK_FINAL { $$ = false; } | - /* empty */ { + %empty { $$ = false; }; @@ -2334,6 +2342,46 @@ simple_behavioral_stmt: ast_stack.back()->children.push_back(node); SET_AST_NODE_LOC(node, @2, @5); append_attr(node, $1); + } | + attr lvalue TOK_XOR_ASSIGN delay expr { + AstNode *xor_node = new AstNode(AST_BIT_XOR, $2->clone(), $5); + AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, xor_node); + SET_AST_NODE_LOC(xor_node, @2, @5); + SET_AST_NODE_LOC(node, @2, @5); + ast_stack.back()->children.push_back(node); + append_attr(node, $1); + } | + attr lvalue TOK_OR_ASSIGN delay expr { + AstNode *or_node = new AstNode(AST_BIT_OR, $2->clone(), $5); + SET_AST_NODE_LOC(or_node, @2, @5); + AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, or_node); + SET_AST_NODE_LOC(node, @2, @5); + ast_stack.back()->children.push_back(node); + append_attr(node, $1); + } | + attr lvalue TOK_PLUS_ASSIGN delay expr { + AstNode *add_node = new AstNode(AST_ADD, $2->clone(), $5); + AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, add_node); + SET_AST_NODE_LOC(node, @2, @5); + SET_AST_NODE_LOC(add_node, @2, @5); + ast_stack.back()->children.push_back(node); + append_attr(node, $1); + } | + attr lvalue TOK_SUB_ASSIGN delay expr { + AstNode *sub_node = new AstNode(AST_SUB, $2->clone(), $5); + AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, sub_node); + SET_AST_NODE_LOC(node, @2, @5); + SET_AST_NODE_LOC(sub_node, @2, @5); + ast_stack.back()->children.push_back(node); + append_attr(node, $1); + } | + attr lvalue TOK_AND_ASSIGN delay expr { + AstNode *and_node = new AstNode(AST_BIT_AND, $2->clone(), $5); + AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, and_node); + SET_AST_NODE_LOC(node, @2, @5); + SET_AST_NODE_LOC(and_node, @2, @5); + ast_stack.back()->children.push_back(node); + append_attr(node, $1); }; // this production creates the obligatory if-else shift/reduce conflict @@ -2458,7 +2506,7 @@ behavioral_stmt: }; unique_case_attr: - /* empty */ { + %empty { $$ = false; } | TOK_PRIORITY case_attr { @@ -2494,11 +2542,11 @@ opt_synopsys_attr: if (ast_stack.back()->attributes.count(ID::parallel_case) == 0) ast_stack.back()->attributes[ID::parallel_case] = AstNode::mkconst_int(1, false); } | - /* empty */; + %empty; behavioral_stmt_list: behavioral_stmt_list behavioral_stmt | - /* empty */; + %empty; optional_else: TOK_ELSE { @@ -2512,11 +2560,11 @@ optional_else: } behavioral_stmt { SET_AST_NODE_LOC(ast_stack.back(), @3, @3); } | - /* empty */ %prec FAKE_THEN; + %empty %prec FAKE_THEN; case_body: case_body case_item | - /* empty */; + %empty; case_item: { @@ -2539,7 +2587,7 @@ case_item: gen_case_body: gen_case_body gen_case_item | - /* empty */; + %empty; gen_case_item: { @@ -2623,11 +2671,11 @@ lvalue_concat_list: opt_arg_list: '(' arg_list optional_comma ')' | - /* empty */; + %empty; arg_list: arg_list2 | - /* empty */; + %empty; arg_list2: single_arg | @@ -2640,7 +2688,7 @@ single_arg: module_gen_body: module_gen_body gen_stmt_or_module_body_stmt | - /* empty */; + %empty; gen_stmt_or_module_body_stmt: gen_stmt | module_body_stmt | @@ -2719,7 +2767,7 @@ gen_stmt_block: }; opt_gen_else: - TOK_ELSE gen_stmt_block | /* empty */ %prec FAKE_THEN; + TOK_ELSE gen_stmt_block | %empty %prec FAKE_THEN; expr: basic_expr { @@ -3001,6 +3049,24 @@ basic_expr: $$ = new AstNode(AST_LOGIC_NOT, $3); SET_AST_NODE_LOC($$, @1, @3); append_attr($$, $2); + } | + TOK_SIGNED OP_CAST '(' expr ')' { + if (!sv_mode) + frontend_verilog_yyerror("Static cast is only supported in SystemVerilog mode."); + $$ = new AstNode(AST_TO_SIGNED, $4); + SET_AST_NODE_LOC($$, @1, @4); + } | + TOK_UNSIGNED OP_CAST '(' expr ')' { + if (!sv_mode) + frontend_verilog_yyerror("Static cast is only supported in SystemVerilog mode."); + $$ = new AstNode(AST_TO_UNSIGNED, $4); + SET_AST_NODE_LOC($$, @1, @4); + } | + basic_expr OP_CAST '(' expr ')' { + if (!sv_mode) + frontend_verilog_yyerror("Static cast is only supported in SystemVerilog mode."); + $$ = new AstNode(AST_CAST_SIZE, $1, $4); + SET_AST_NODE_LOC($$, @1, @4); }; concat_list: diff --git a/kernel/calc.cc b/kernel/calc.cc index ae18809d3..d54ccbc10 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -275,10 +275,15 @@ RTLIL::Const RTLIL::const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const return result; } -static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool sign_ext, int direction, int result_len) +// Shift `arg1` by `arg2` bits. +// If `direction` is +1, `arg1` is shifted right by `arg2` bits; if `direction` is -1, `arg1` is shifted left by `arg2` bits. +// If `signed2` is true, `arg2` is interpreted as a signed integer; a negative `arg2` will cause a shift in the opposite direction. +// Any required bits outside the bounds of `arg1` are padded with `vacant_bits` unless `sign_ext` is true, in which case any bits outside the left +// bounds are filled with the leftmost bit of `arg1` (arithmetic shift). +static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool sign_ext, bool signed2, int direction, int result_len, RTLIL::State vacant_bits = RTLIL::State::S0) { int undef_bit_pos = -1; - BigInteger offset = const2big(arg2, false, undef_bit_pos) * direction; + BigInteger offset = const2big(arg2, signed2, undef_bit_pos) * direction; if (result_len < 0) result_len = arg1.bits.size(); @@ -290,9 +295,9 @@ static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Co for (int i = 0; i < result_len; i++) { BigInteger pos = BigInteger(i) + offset; if (pos < 0) - result.bits[i] = RTLIL::State::S0; + result.bits[i] = vacant_bits; else if (pos >= BigInteger(int(arg1.bits.size()))) - result.bits[i] = sign_ext ? arg1.bits.back() : RTLIL::State::S0; + result.bits[i] = sign_ext ? arg1.bits.back() : vacant_bits; else result.bits[i] = arg1.bits[pos.toInt()]; } @@ -304,61 +309,36 @@ RTLIL::Const RTLIL::const_shl(const RTLIL::Const &arg1, const RTLIL::Const &arg2 { RTLIL::Const arg1_ext = arg1; extend_u0(arg1_ext, result_len, signed1); - return const_shift_worker(arg1_ext, arg2, false, -1, result_len); + return const_shift_worker(arg1_ext, arg2, false, false, -1, result_len); } RTLIL::Const RTLIL::const_shr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len) { RTLIL::Const arg1_ext = arg1; extend_u0(arg1_ext, max(result_len, GetSize(arg1)), signed1); - return const_shift_worker(arg1_ext, arg2, false, +1, result_len); -} - -RTLIL::Const RTLIL::const_sshl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) -{ - if (!signed1) - return const_shl(arg1, arg2, signed1, signed2, result_len); - return const_shift_worker(arg1, arg2, true, -1, result_len); + return const_shift_worker(arg1_ext, arg2, false, false, +1, result_len); } -RTLIL::Const RTLIL::const_sshr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) +RTLIL::Const RTLIL::const_sshl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len) { - if (!signed1) - return const_shr(arg1, arg2, signed1, signed2, result_len); - return const_shift_worker(arg1, arg2, true, +1, result_len); + return const_shift_worker(arg1, arg2, signed1, false, -1, result_len); } -static RTLIL::Const const_shift_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool, bool signed2, int result_len, RTLIL::State other_bits) +RTLIL::Const RTLIL::const_sshr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len) { - int undef_bit_pos = -1; - BigInteger offset = const2big(arg2, signed2, undef_bit_pos); - - if (result_len < 0) - result_len = arg1.bits.size(); - - RTLIL::Const result(RTLIL::State::Sx, result_len); - if (undef_bit_pos >= 0) - return result; - - for (int i = 0; i < result_len; i++) { - BigInteger pos = BigInteger(i) + offset; - if (pos < 0 || pos >= BigInteger(int(arg1.bits.size()))) - result.bits[i] = other_bits; - else - result.bits[i] = arg1.bits[pos.toInt()]; - } - - return result; + return const_shift_worker(arg1, arg2, signed1, false, +1, result_len); } RTLIL::Const RTLIL::const_shift(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) { - return const_shift_shiftx(arg1, arg2, signed1, signed2, result_len, RTLIL::State::S0); + RTLIL::Const arg1_ext = arg1; + extend_u0(arg1_ext, max(result_len, GetSize(arg1)), signed1); + return const_shift_worker(arg1_ext, arg2, false, signed2, +1, result_len); } -RTLIL::Const RTLIL::const_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) +RTLIL::Const RTLIL::const_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool, bool signed2, int result_len) { - return const_shift_shiftx(arg1, arg2, signed1, signed2, result_len, RTLIL::State::Sx); + return const_shift_worker(arg1, arg2, false, signed2, +1, result_len, RTLIL::State::Sx); } RTLIL::Const RTLIL::const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) diff --git a/kernel/celledges.h b/kernel/celledges.h index 2cc297cb2..d105e4009 100644 --- a/kernel/celledges.h +++ b/kernel/celledges.h @@ -38,7 +38,7 @@ struct FwdCellEdgesDatabase : AbstractCellEdgesDatabase dict<SigBit, pool<SigBit>> db; FwdCellEdgesDatabase(SigMap &sigmap) : sigmap(sigmap) { } - void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) YS_OVERRIDE { + void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) override { SigBit from_sigbit = sigmap(cell->getPort(from_port)[from_bit]); SigBit to_sigbit = sigmap(cell->getPort(to_port)[to_bit]); db[from_sigbit].insert(to_sigbit); @@ -51,7 +51,7 @@ struct RevCellEdgesDatabase : AbstractCellEdgesDatabase dict<SigBit, pool<SigBit>> db; RevCellEdgesDatabase(SigMap &sigmap) : sigmap(sigmap) { } - void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) YS_OVERRIDE { + void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) override { SigBit from_sigbit = sigmap(cell->getPort(from_port)[from_bit]); SigBit to_sigbit = sigmap(cell->getPort(to_port)[to_bit]); db[to_sigbit].insert(from_sigbit); diff --git a/kernel/celltypes.h b/kernel/celltypes.h index db54436cb..944cb301a 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -139,8 +139,14 @@ struct CellTypes setup_type(ID($dff), {ID::CLK, ID::D}, {ID::Q}); setup_type(ID($dffe), {ID::CLK, ID::EN, ID::D}, {ID::Q}); setup_type(ID($dffsr), {ID::CLK, ID::SET, ID::CLR, ID::D}, {ID::Q}); + setup_type(ID($dffsre), {ID::CLK, ID::SET, ID::CLR, ID::D, ID::EN}, {ID::Q}); setup_type(ID($adff), {ID::CLK, ID::ARST, ID::D}, {ID::Q}); + setup_type(ID($adffe), {ID::CLK, ID::ARST, ID::D, ID::EN}, {ID::Q}); + setup_type(ID($sdff), {ID::CLK, ID::SRST, ID::D}, {ID::Q}); + setup_type(ID($sdffe), {ID::CLK, ID::SRST, ID::D, ID::EN}, {ID::Q}); + setup_type(ID($sdffce), {ID::CLK, ID::SRST, ID::D, ID::EN}, {ID::Q}); setup_type(ID($dlatch), {ID::EN, ID::D}, {ID::Q}); + setup_type(ID($adlatch), {ID::EN, ID::D, ID::ARST}, {ID::Q}); setup_type(ID($dlatchsr), {ID::EN, ID::SET, ID::CLR, ID::D}, {ID::Q}); } @@ -210,14 +216,48 @@ struct CellTypes for (auto c1 : list_np) for (auto c2 : list_np) + for (auto c3 : list_01) + for (auto c4 : list_np) + setup_type(stringf("$_DFFE_%c%c%c%c_", c1, c2, c3, c4), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}); + + for (auto c1 : list_np) + for (auto c2 : list_np) for (auto c3 : list_np) setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {ID::C, ID::S, ID::R, ID::D}, {ID::Q}); for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_np) + for (auto c4 : list_np) + setup_type(stringf("$_DFFSRE_%c%c%c%c_", c1, c2, c3, c4), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q}); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_01) + setup_type(stringf("$_SDFF_%c%c%c_", c1, c2, c3), {ID::C, ID::R, ID::D}, {ID::Q}); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_01) + for (auto c4 : list_np) + setup_type(stringf("$_SDFFE_%c%c%c%c_", c1, c2, c3, c4), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_01) + for (auto c4 : list_np) + setup_type(stringf("$_SDFFCE_%c%c%c%c_", c1, c2, c3, c4), {ID::C, ID::R, ID::D, ID::E}, {ID::Q}); + + for (auto c1 : list_np) setup_type(stringf("$_DLATCH_%c_", c1), {ID::E, ID::D}, {ID::Q}); for (auto c1 : list_np) for (auto c2 : list_np) + for (auto c3 : list_01) + setup_type(stringf("$_DLATCH_%c%c%c_", c1, c2, c3), {ID::E, ID::R, ID::D}, {ID::Q}); + + for (auto c1 : list_np) + for (auto c2 : list_np) for (auto c3 : list_np) setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {ID::E, ID::S, ID::R, ID::D}, {ID::Q}); } diff --git a/kernel/constids.inc b/kernel/constids.inc index 383d7c615..3c2ff9beb 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -158,6 +158,9 @@ X(SRC_EN) X(SRC_PEN) X(SRC_POL) X(SRC_WIDTH) +X(SRST) +X(SRST_POLARITY) +X(SRST_VALUE) X(STATE_BITS) X(STATE_NUM) X(STATE_NUM_LOG2) @@ -169,6 +172,7 @@ X(T) X(TABLE) X(techmap_autopurge) X(_TECHMAP_BITS_CONNMAP_) +X(_TECHMAP_CELLNAME_) X(_TECHMAP_CELLTYPE_) X(techmap_celltype) X(_TECHMAP_FAIL_) diff --git a/kernel/driver.cc b/kernel/driver.cc index 57ed7b8b4..b55f02837 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -267,9 +267,11 @@ int main(int argc, char **argv) printf("\n"); printf(" -s scriptfile\n"); printf(" execute the commands in the script file\n"); +#ifdef YOSYS_ENABLE_TCL printf("\n"); printf(" -c tcl_scriptfile\n"); printf(" execute the commands in the tcl script file (see 'help tcl' for details)\n"); +#endif printf("\n"); printf(" -p command\n"); printf(" execute the commands\n"); diff --git a/kernel/ff.h b/kernel/ff.h new file mode 100644 index 000000000..0aecbaa2a --- /dev/null +++ b/kernel/ff.h @@ -0,0 +1,486 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Marcelina KoÅ›cielnicka <mwk@0x04.net> + * + * 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. + * + */ + +#ifndef FF_H +#define FF_H + +#include "kernel/yosys.h" +#include "kernel/ffinit.h" + +YOSYS_NAMESPACE_BEGIN + +struct FfData { + FfInitVals *initvals; + SigSpec sig_q; + SigSpec sig_d; + SigSpec sig_clk; + SigSpec sig_en; + SigSpec sig_arst; + SigSpec sig_srst; + SigSpec sig_clr; + SigSpec sig_set; + bool has_d; + bool has_clk; + bool has_en; + bool has_srst; + bool has_arst; + bool has_sr; + bool ce_over_srst; + bool is_fine; + bool pol_clk; + bool pol_en; + bool pol_arst; + bool pol_srst; + bool pol_clr; + bool pol_set; + Const val_arst; + Const val_srst; + Const val_init; + Const val_d; + bool d_is_const; + int width; + dict<IdString, Const> attributes; + + FfData(FfInitVals *initvals, Cell *cell = nullptr) : initvals(initvals) { + width = 0; + has_d = true; + has_clk = false; + has_en = false; + has_srst = false; + has_arst = false; + has_sr = false; + ce_over_srst = false; + is_fine = false; + pol_clk = false; + pol_en = false; + pol_arst = false; + pol_srst = false; + pol_clr = false; + pol_set = false; + d_is_const = false; + + if (!cell) + return; + + sig_q = cell->getPort(ID::Q); + width = GetSize(sig_q); + attributes = cell->attributes; + + if (initvals) + val_init = (*initvals)(sig_q); + + std::string type_str = cell->type.str(); + + if (cell->type.in(ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr))) { + if (cell->type == ID($sr)) { + has_d = false; + } else { + sig_d = cell->getPort(ID::D); + } + if (!cell->type.in(ID($ff), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr))) { + has_clk = true; + sig_clk = cell->getPort(ID::CLK); + pol_clk = cell->getParam(ID::CLK_POLARITY).as_bool(); + } + if (cell->type.in(ID($dffe), ID($dffsre), ID($adffe), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch), ID($dlatchsr))) { + has_en = true; + sig_en = cell->getPort(ID::EN); + pol_en = cell->getParam(ID::EN_POLARITY).as_bool(); + } + if (cell->type.in(ID($dffsr), ID($dffsre), ID($dlatchsr), ID($sr))) { + has_sr = true; + sig_clr = cell->getPort(ID::CLR); + sig_set = cell->getPort(ID::SET); + pol_clr = cell->getParam(ID::CLR_POLARITY).as_bool(); + pol_set = cell->getParam(ID::SET_POLARITY).as_bool(); + } + if (cell->type.in(ID($adff), ID($adffe), ID($adlatch))) { + has_arst = true; + sig_arst = cell->getPort(ID::ARST); + pol_arst = cell->getParam(ID::ARST_POLARITY).as_bool(); + val_arst = cell->getParam(ID::ARST_VALUE); + } + if (cell->type.in(ID($sdff), ID($sdffe), ID($sdffce))) { + has_srst = true; + sig_srst = cell->getPort(ID::SRST); + pol_srst = cell->getParam(ID::SRST_POLARITY).as_bool(); + val_srst = cell->getParam(ID::SRST_VALUE); + ce_over_srst = cell->type == ID($sdffce); + } + } else if (cell->type == ID($_FF_)) { + is_fine = true; + sig_d = cell->getPort(ID::D); + } else if (type_str.substr(0, 5) == "$_SR_") { + is_fine = true; + has_d = false; + has_sr = true; + pol_set = type_str[5] == 'P'; + pol_clr = type_str[6] == 'P'; + sig_set = cell->getPort(ID::S); + sig_clr = cell->getPort(ID::R); + } else if (type_str.substr(0, 6) == "$_DFF_" && type_str.size() == 8) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[6] == 'P'; + sig_clk = cell->getPort(ID::C); + } else if (type_str.substr(0, 7) == "$_DFFE_" && type_str.size() == 10) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[7] == 'P'; + sig_clk = cell->getPort(ID::C); + has_en = true; + pol_en = type_str[8] == 'P'; + sig_en = cell->getPort(ID::E); + } else if (type_str.substr(0, 6) == "$_DFF_" && type_str.size() == 10) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[6] == 'P'; + sig_clk = cell->getPort(ID::C); + has_arst = true; + pol_arst = type_str[7] == 'P'; + sig_arst = cell->getPort(ID::R); + val_arst = type_str[8] == '1' ? State::S1 : State::S0; + } else if (type_str.substr(0, 7) == "$_DFFE_" && type_str.size() == 12) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[7] == 'P'; + sig_clk = cell->getPort(ID::C); + has_arst = true; + pol_arst = type_str[8] == 'P'; + sig_arst = cell->getPort(ID::R); + val_arst = type_str[9] == '1' ? State::S1 : State::S0; + has_en = true; + pol_en = type_str[10] == 'P'; + sig_en = cell->getPort(ID::E); + } else if (type_str.substr(0, 8) == "$_DFFSR_" && type_str.size() == 12) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[8] == 'P'; + sig_clk = cell->getPort(ID::C); + has_sr = true; + pol_set = type_str[9] == 'P'; + pol_clr = type_str[10] == 'P'; + sig_set = cell->getPort(ID::S); + sig_clr = cell->getPort(ID::R); + } else if (type_str.substr(0, 9) == "$_DFFSRE_" && type_str.size() == 14) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[9] == 'P'; + sig_clk = cell->getPort(ID::C); + has_sr = true; + pol_set = type_str[10] == 'P'; + pol_clr = type_str[11] == 'P'; + sig_set = cell->getPort(ID::S); + sig_clr = cell->getPort(ID::R); + has_en = true; + pol_en = type_str[12] == 'P'; + sig_en = cell->getPort(ID::E); + } else if (type_str.substr(0, 7) == "$_SDFF_" && type_str.size() == 11) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[7] == 'P'; + sig_clk = cell->getPort(ID::C); + has_srst = true; + pol_srst = type_str[8] == 'P'; + sig_srst = cell->getPort(ID::R); + val_srst = type_str[9] == '1' ? State::S1 : State::S0; + } else if (type_str.substr(0, 8) == "$_SDFFE_" && type_str.size() == 13) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[8] == 'P'; + sig_clk = cell->getPort(ID::C); + has_srst = true; + pol_srst = type_str[9] == 'P'; + sig_srst = cell->getPort(ID::R); + val_srst = type_str[10] == '1' ? State::S1 : State::S0; + has_en = true; + pol_en = type_str[11] == 'P'; + sig_en = cell->getPort(ID::E); + } else if (type_str.substr(0, 9) == "$_SDFFCE_" && type_str.size() == 14) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_clk = true; + pol_clk = type_str[9] == 'P'; + sig_clk = cell->getPort(ID::C); + has_srst = true; + pol_srst = type_str[10] == 'P'; + sig_srst = cell->getPort(ID::R); + val_srst = type_str[11] == '1' ? State::S1 : State::S0; + has_en = true; + pol_en = type_str[12] == 'P'; + sig_en = cell->getPort(ID::E); + ce_over_srst = true; + } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 11) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_en = true; + pol_en = type_str[9] == 'P'; + sig_en = cell->getPort(ID::E); + } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 13) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_en = true; + pol_en = type_str[9] == 'P'; + sig_en = cell->getPort(ID::E); + has_arst = true; + pol_arst = type_str[10] == 'P'; + sig_arst = cell->getPort(ID::R); + val_arst = type_str[11] == '1' ? State::S1 : State::S0; + } else if (type_str.substr(0, 11) == "$_DLATCHSR_" && type_str.size() == 15) { + is_fine = true; + sig_d = cell->getPort(ID::D); + has_en = true; + pol_en = type_str[11] == 'P'; + sig_en = cell->getPort(ID::E); + has_sr = true; + pol_set = type_str[12] == 'P'; + pol_clr = type_str[13] == 'P'; + sig_set = cell->getPort(ID::S); + sig_clr = cell->getPort(ID::R); + } else { + log_assert(0); + } + if (has_d && sig_d.is_fully_const()) { + d_is_const = true; + val_d = sig_d.as_const(); + if (has_en && !has_clk && !has_sr && !has_arst) { + // Plain D latches with const D treated specially. + has_en = has_d = false; + has_arst = true; + sig_arst = sig_en; + pol_arst = pol_en; + val_arst = val_d; + } + } + } + + // Returns a FF identical to this one, but only keeping bit indices from the argument. + FfData slice(const std::vector<int> &bits) { + FfData res(initvals); + res.sig_clk = sig_clk; + res.sig_en = sig_en; + res.sig_arst = sig_arst; + res.sig_srst = sig_srst; + res.has_d = has_d; + res.has_clk = has_clk; + res.has_en = has_en; + res.has_arst = has_arst; + res.has_srst = has_srst; + res.has_sr = has_sr; + res.ce_over_srst = ce_over_srst; + res.is_fine = is_fine; + res.pol_clk = pol_clk; + res.pol_en = pol_en; + res.pol_arst = pol_arst; + res.pol_srst = pol_srst; + res.pol_clr = pol_clr; + res.pol_set = pol_set; + res.attributes = attributes; + for (int i : bits) { + res.sig_q.append(sig_q[i]); + if (has_d) + res.sig_d.append(sig_d[i]); + if (has_sr) { + res.sig_clr.append(sig_clr[i]); + res.sig_set.append(sig_set[i]); + } + if (has_arst) + res.val_arst.bits.push_back(val_arst[i]); + if (has_srst) + res.val_srst.bits.push_back(val_srst[i]); + res.val_init.bits.push_back(val_init[i]); + } + res.width = GetSize(res.sig_q); + // Slicing bits out may cause D to become const. + if (has_d && res.sig_d.is_fully_const()) { + res.d_is_const = true; + res.val_d = res.sig_d.as_const(); + } + return res; + } + + void unmap_ce(Module *module) { + if (!has_en) + return; + log_assert(has_clk); + if (has_srst && ce_over_srst) + unmap_srst(module); + + if (!is_fine) { + if (pol_en) + sig_d = module->Mux(NEW_ID, sig_q, sig_d, sig_en); + else + sig_d = module->Mux(NEW_ID, sig_d, sig_q, sig_en); + } else { + if (pol_en) + sig_d = module->MuxGate(NEW_ID, sig_q, sig_d, sig_en); + else + sig_d = module->MuxGate(NEW_ID, sig_d, sig_q, sig_en); + } + has_en = false; + } + + void unmap_srst(Module *module) { + if (!has_srst) + return; + if (has_en && !ce_over_srst) + unmap_ce(module); + + if (!is_fine) { + if (pol_srst) + sig_d = module->Mux(NEW_ID, sig_d, val_srst, sig_srst); + else + sig_d = module->Mux(NEW_ID, val_srst, sig_d, sig_srst); + } else { + if (pol_srst) + sig_d = module->MuxGate(NEW_ID, sig_d, val_srst[0], sig_srst); + else + sig_d = module->MuxGate(NEW_ID, val_srst[0], sig_d, sig_srst); + } + has_srst = false; + } + + void unmap_ce_srst(Module *module) { + unmap_ce(module); + unmap_srst(module); + } + + Cell *emit(Module *module, IdString name) { + if (!width) + return nullptr; + if (!has_d && !has_sr) { + if (has_arst) { + // Convert this case to a D latch. + has_d = has_en = true; + has_arst = false; + sig_d = val_arst; + sig_en = sig_arst; + pol_en = pol_arst; + } else { + // No control inputs left. Turn into a const driver. + initvals->remove_init(sig_q); + module->connect(sig_q, val_init); + return nullptr; + } + } + initvals->set_init(sig_q, val_init); + Cell *cell; + if (!is_fine) { + if (!has_d) { + log_assert(has_sr); + cell = module->addSr(name, sig_set, sig_clr, sig_q, pol_set, pol_clr); + } else if (!has_clk && !has_en) { + log_assert(!has_arst); + log_assert(!has_srst); + log_assert(!has_sr); + cell = module->addFf(name, sig_d, sig_q); + } else if (!has_clk) { + log_assert(!has_srst); + if (has_sr) + cell = module->addDlatchsr(name, sig_en, sig_set, sig_clr, sig_d, sig_q, pol_en, pol_set, pol_clr); + else if (has_arst) + cell = module->addAdlatch(name, sig_en, sig_arst, sig_d, sig_q, val_arst, pol_en, pol_arst); + else + cell = module->addDlatch(name, sig_en, sig_d, sig_q, pol_en); + } else { + if (has_sr) { + if (has_en) + cell = module->addDffsre(name, sig_clk, sig_en, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_en, pol_set, pol_clr); + else + cell = module->addDffsr(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr); + } else if (has_arst) { + if (has_en) + cell = module->addAdffe(name, sig_clk, sig_en, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_en, pol_arst); + else + cell = module->addAdff(name, sig_clk, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_arst); + } else if (has_srst) { + if (has_en) + if (ce_over_srst) + cell = module->addSdffce(name, sig_clk, sig_en, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_en, pol_srst); + else + cell = module->addSdffe(name, sig_clk, sig_en, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_en, pol_srst); + else + cell = module->addSdff(name, sig_clk, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_srst); + } else { + if (has_en) + cell = module->addDffe(name, sig_clk, sig_en, sig_d, sig_q, pol_clk, pol_en); + else + cell = module->addDff(name, sig_clk, sig_d, sig_q, pol_clk); + } + } + } else { + if (!has_d) { + log_assert(has_sr); + cell = module->addSrGate(name, sig_set, sig_clr, sig_q, pol_set, pol_clr); + } else if (!has_clk && !has_en) { + log_assert(!has_arst); + log_assert(!has_srst); + log_assert(!has_sr); + cell = module->addFfGate(name, sig_d, sig_q); + } else if (!has_clk) { + log_assert(!has_srst); + if (has_sr) + cell = module->addDlatchsrGate(name, sig_en, sig_set, sig_clr, sig_d, sig_q, pol_en, pol_set, pol_clr); + else if (has_arst) + cell = module->addAdlatchGate(name, sig_en, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_en, pol_arst); + else + cell = module->addDlatchGate(name, sig_en, sig_d, sig_q, pol_en); + } else { + if (has_sr) { + if (has_en) + cell = module->addDffsreGate(name, sig_clk, sig_en, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_en, pol_set, pol_clr); + else + cell = module->addDffsrGate(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr); + } else if (has_arst) { + if (has_en) + cell = module->addAdffeGate(name, sig_clk, sig_en, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_en, pol_arst); + else + cell = module->addAdffGate(name, sig_clk, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_arst); + } else if (has_srst) { + if (has_en) + if (ce_over_srst) + cell = module->addSdffceGate(name, sig_clk, sig_en, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_en, pol_srst); + else + cell = module->addSdffeGate(name, sig_clk, sig_en, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_en, pol_srst); + else + cell = module->addSdffGate(name, sig_clk, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_srst); + } else { + if (has_en) + cell = module->addDffeGate(name, sig_clk, sig_en, sig_d, sig_q, pol_clk, pol_en); + else + cell = module->addDffGate(name, sig_clk, sig_d, sig_q, pol_clk); + } + } + } + cell->attributes = attributes; + return cell; + } +}; + +YOSYS_NAMESPACE_END + +#endif diff --git a/kernel/ffinit.h b/kernel/ffinit.h new file mode 100644 index 000000000..025b0c862 --- /dev/null +++ b/kernel/ffinit.h @@ -0,0 +1,141 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Marcelina KoÅ›cielnicka <mwk@0x04.net> + * + * 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. + * + */ + +#ifndef FFINIT_H +#define FFINIT_H + +#include "kernel/yosys.h" +#include "kernel/sigtools.h" + +YOSYS_NAMESPACE_BEGIN + +struct FfInitVals +{ + const SigMap *sigmap; + RTLIL::Module *module; + dict<SigBit, std::pair<State,SigBit>> initbits; + + void set(const SigMap *sigmap_, RTLIL::Module *module) + { + sigmap = sigmap_; + initbits.clear(); + for (auto wire : module->wires()) + { + if (wire->attributes.count(ID::init) == 0) + continue; + + SigSpec wirebits = (*sigmap)(wire); + Const initval = wire->attributes.at(ID::init); + + for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) + { + SigBit bit = wirebits[i]; + State val = initval[i]; + + if (val != State::S0 && val != State::S1 && bit.wire != nullptr) + continue; + + if (initbits.count(bit)) { + if (initbits.at(bit).first != val) + log_error("Conflicting init values for signal %s (%s = %s != %s).\n", + log_signal(bit), log_signal(SigBit(wire, i)), + log_signal(val), log_signal(initbits.at(bit).first)); + continue; + } + + initbits[bit] = std::make_pair(val,SigBit(wire,i)); + } + } + } + + RTLIL::State operator()(RTLIL::SigBit bit) const + { + auto it = initbits.find((*sigmap)(bit)); + if (it != initbits.end()) + return it->second.first; + else + return State::Sx; + } + + RTLIL::Const operator()(const RTLIL::SigSpec &sig) const + { + RTLIL::Const res; + for (auto bit : sig) + res.bits.push_back((*this)(bit)); + return res; + } + + void set_init(RTLIL::SigBit bit, RTLIL::State val) + { + SigBit mbit = (*sigmap)(bit); + SigBit abit = bit; + auto it = initbits.find(mbit); + if (it != initbits.end()) + abit = it->second.second; + else if (val == State::Sx) + return; + log_assert(abit.wire); + initbits[mbit] = std::make_pair(val,abit); + auto it2 = abit.wire->attributes.find(ID::init); + if (it2 != abit.wire->attributes.end()) { + it2->second[abit.offset] = val; + if (it2->second.is_fully_undef()) + abit.wire->attributes.erase(it2); + } else if (val != State::Sx) { + Const cval(State::Sx, GetSize(abit.wire)); + cval[abit.offset] = val; + abit.wire->attributes[ID::init] = cval; + } + } + + void set_init(const RTLIL::SigSpec &sig, RTLIL::Const val) + { + log_assert(GetSize(sig) == GetSize(val)); + for (int i = 0; i < GetSize(sig); i++) + set_init(sig[i], val[i]); + } + + void remove_init(RTLIL::SigBit bit) + { + set_init(bit, State::Sx); + } + + void remove_init(const RTLIL::SigSpec &sig) + { + for (auto bit : sig) + remove_init(bit); + } + + void clear() + { + initbits.clear(); + } + + FfInitVals (const SigMap *sigmap, RTLIL::Module *module) + { + set(sigmap, module); + } + + FfInitVals () {} +}; + + +YOSYS_NAMESPACE_END + +#endif diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 5c87b55f5..a523afadd 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -363,6 +363,7 @@ public: public: const_iterator() { } const_iterator operator++() { index--; return *this; } + const_iterator operator+=(int amt) { index -= amt; return *this; } bool operator<(const const_iterator &other) const { return index > other.index; } bool operator==(const const_iterator &other) const { return index == other.index; } bool operator!=(const const_iterator &other) const { return index != other.index; } @@ -380,6 +381,7 @@ public: public: iterator() { } iterator operator++() { index--; return *this; } + iterator operator+=(int amt) { index -= amt; return *this; } bool operator<(const iterator &other) const { return index > other.index; } bool operator==(const iterator &other) const { return index == other.index; } bool operator!=(const iterator &other) const { return index != other.index; } diff --git a/kernel/log.cc b/kernel/log.cc index 104bee078..c7ae873bc 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -19,7 +19,7 @@ #include "kernel/yosys.h" #include "libs/sha1/sha1.h" -#include "backends/ilang/ilang_backend.h" +#include "backends/rtlil/rtlil_backend.h" #if !defined(_WIN32) || defined(__MINGW32__) # include <sys/time.h> @@ -319,7 +319,7 @@ void log_file_info(const std::string &filename, int lineno, va_end(ap); } -YS_ATTRIBUTE(noreturn) +[[noreturn]] static void logv_error_with_prefix(const char *prefix, const char *format, va_list ap) { @@ -600,7 +600,7 @@ void log_dump_val_worker(RTLIL::State v) { const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) { std::stringstream buf; - ILANG_BACKEND::dump_sigspec(buf, sig, autoint); + RTLIL_BACKEND::dump_sigspec(buf, sig, autoint); if (string_buf.size() < 100) { string_buf.push_back(buf.str()); @@ -647,21 +647,21 @@ const char *log_id(RTLIL::IdString str) void log_module(RTLIL::Module *module, std::string indent) { std::stringstream buf; - ILANG_BACKEND::dump_module(buf, indent, module, module->design, false); + RTLIL_BACKEND::dump_module(buf, indent, module, module->design, false); log("%s", buf.str().c_str()); } void log_cell(RTLIL::Cell *cell, std::string indent) { std::stringstream buf; - ILANG_BACKEND::dump_cell(buf, indent, cell); + RTLIL_BACKEND::dump_cell(buf, indent, cell); log("%s", buf.str().c_str()); } void log_wire(RTLIL::Wire *wire, std::string indent) { std::stringstream buf; - ILANG_BACKEND::dump_wire(buf, indent, wire); + RTLIL_BACKEND::dump_wire(buf, indent, wire); log("%s", buf.str().c_str()); } diff --git a/kernel/log.h b/kernel/log.h index 516744b50..8981c4cde 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -55,7 +55,9 @@ #else # include <sys/time.h> # include <sys/resource.h> -# include <signal.h> +# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +# include <signal.h> +# endif #endif #if defined(_MSC_VER) @@ -137,7 +139,7 @@ void logv(const char *format, va_list ap); void logv_header(RTLIL::Design *design, const char *format, va_list ap); void logv_warning(const char *format, va_list ap); void logv_warning_noprefix(const char *format, va_list ap); -YS_NORETURN void logv_error(const char *format, va_list ap) YS_ATTRIBUTE(noreturn); +[[noreturn]] void logv_error(const char *format, va_list ap); void log(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); void log_header(RTLIL::Design *design, const char *format, ...) YS_ATTRIBUTE(format(printf, 2, 3)); @@ -149,17 +151,16 @@ void log_file_warning(const std::string &filename, int lineno, const char *forma void log_file_info(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); void log_warning_noprefix(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); -YS_NORETURN void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2), noreturn); -void log_file_error(const string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4), noreturn); -YS_NORETURN void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2), noreturn); +[[noreturn]] void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); +[[noreturn]] void log_file_error(const string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4)); +[[noreturn]] void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); #ifndef NDEBUG static inline bool ys_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; } -# define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0) #else static inline bool ys_debug(int = 0) { return false; } -# define log_debug(_fmt, ...) do { } while (0) #endif +# define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0) static inline void log_suppressed() { if (log_debug_suppressed && !log_make_debug) { @@ -234,7 +235,7 @@ static inline void log_assert_worker(bool cond, const char *expr, const char *fi } # define log_assert(_assert_expr_) YOSYS_NAMESPACE_PREFIX log_assert_worker(_assert_expr_, #_assert_expr_, __FILE__, __LINE__) #else -# define log_assert(_assert_expr_) +# define log_assert(_assert_expr_) do { if (0) { (void)(_assert_expr_); } } while(0) #endif #define log_abort() YOSYS_NAMESPACE_PREFIX log_error("Abort in %s:%d.\n", __FILE__, __LINE__) @@ -306,19 +307,17 @@ struct PerformanceTimer static int64_t query() { # ifdef _WIN32 return 0; -# elif defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) - struct timespec ts; - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); - return int64_t(ts.tv_sec)*1000000000 + ts.tv_nsec; # elif defined(RUSAGE_SELF) struct rusage rusage; - int64_t t; - if (getrusage(RUSAGE_SELF, &rusage) == -1) { - log_cmd_error("getrusage failed!\n"); - log_abort(); + int64_t t = 0; + for (int who : {RUSAGE_SELF, RUSAGE_CHILDREN}) { + if (getrusage(who, &rusage) == -1) { + log_cmd_error("getrusage failed!\n"); + log_abort(); + } + t += 1000000000ULL * (int64_t) rusage.ru_utime.tv_sec + (int64_t) rusage.ru_utime.tv_usec * 1000ULL; + t += 1000000000ULL * (int64_t) rusage.ru_stime.tv_sec + (int64_t) rusage.ru_stime.tv_usec * 1000ULL; } - t = 1000000000ULL * (int64_t) rusage.ru_utime.tv_sec + (int64_t) rusage.ru_utime.tv_usec * 1000ULL; - t += 1000000000ULL * (int64_t) rusage.ru_stime.tv_sec + (int64_t) rusage.ru_stime.tv_usec * 1000ULL; return t; # else # error "Don't know how to measure per-process CPU time. Need alternative method (times()/clocks()/gettimeofday()?)." @@ -369,7 +368,7 @@ static inline void log_dump_val_worker(char *v) { log("%s", v); } static inline void log_dump_val_worker(const char *v) { log("%s", v); } static inline void log_dump_val_worker(std::string v) { log("%s", v.c_str()); } static inline void log_dump_val_worker(PerformanceTimer p) { log("%f seconds", p.sec()); } -static inline void log_dump_args_worker(const char *p YS_ATTRIBUTE(unused)) { log_assert(*p == 0); } +static inline void log_dump_args_worker(const char *p) { log_assert(*p == 0); } void log_dump_val_worker(RTLIL::IdString v); void log_dump_val_worker(RTLIL::SigSpec v); void log_dump_val_worker(RTLIL::State v); diff --git a/kernel/macc.h b/kernel/macc.h index e9f6f05e9..d216e6772 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -107,10 +107,8 @@ struct Macc std::vector<RTLIL::State> config_bits = cell->getParam(ID::CONFIG).bits; int config_cursor = 0; -#ifndef NDEBUG int config_width = cell->getParam(ID::CONFIG_WIDTH).as_int(); log_assert(GetSize(config_bits) >= config_width); -#endif int num_bits = 0; if (config_bits[config_cursor++] == State::S1) num_bits |= 1; diff --git a/kernel/mem.cc b/kernel/mem.cc new file mode 100644 index 000000000..0301a913c --- /dev/null +++ b/kernel/mem.cc @@ -0,0 +1,436 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Marcelina KoÅ›cielnicka <mwk@0x04.net> + * + * 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/mem.h" + +USING_YOSYS_NAMESPACE + +void Mem::remove() { + if (cell) { + module->remove(cell); + cell = nullptr; + } + if (mem) { + module->memories.erase(mem->name); + delete mem; + mem = nullptr; + } + for (auto &port : rd_ports) { + if (port.cell) { + module->remove(port.cell); + port.cell = nullptr; + } + } + for (auto &port : wr_ports) { + if (port.cell) { + module->remove(port.cell); + port.cell = nullptr; + } + } + for (auto &init : inits) { + if (init.cell) { + module->remove(init.cell); + init.cell = nullptr; + } + } +} + +void Mem::emit() { + if (packed) { + if (mem) { + module->memories.erase(mem->name); + delete mem; + mem = nullptr; + } + if (!cell) { + if (memid.empty()) + memid = NEW_ID; + cell = module->addCell(memid, ID($mem)); + } + cell->attributes = attributes; + cell->parameters[ID::MEMID] = Const(memid.str()); + cell->parameters[ID::WIDTH] = Const(width); + cell->parameters[ID::OFFSET] = Const(start_offset); + cell->parameters[ID::SIZE] = Const(size); + cell->parameters[ID::RD_PORTS] = Const(GetSize(rd_ports)); + cell->parameters[ID::WR_PORTS] = Const(GetSize(wr_ports)); + Const rd_clk_enable, rd_clk_polarity, rd_transparent; + Const wr_clk_enable, wr_clk_polarity; + SigSpec rd_clk, rd_en, rd_addr, rd_data; + SigSpec wr_clk, wr_en, wr_addr, wr_data; + int abits = 0; + for (auto &port : rd_ports) + abits = std::max(abits, GetSize(port.addr)); + for (auto &port : wr_ports) + abits = std::max(abits, GetSize(port.addr)); + cell->parameters[ID::ABITS] = Const(abits); + for (auto &port : rd_ports) { + if (port.cell) { + module->remove(port.cell); + port.cell = nullptr; + } + rd_clk_enable.bits.push_back(State(port.clk_enable)); + rd_clk_polarity.bits.push_back(State(port.clk_polarity)); + rd_transparent.bits.push_back(State(port.transparent)); + rd_clk.append(port.clk); + log_assert(GetSize(port.clk) == 1); + rd_en.append(port.en); + log_assert(GetSize(port.en) == 1); + SigSpec addr = port.addr; + addr.extend_u0(abits, false); + rd_addr.append(addr); + log_assert(GetSize(addr) == abits); + rd_data.append(port.data); + log_assert(GetSize(port.data) == width); + } + if (rd_ports.empty()) { + rd_clk_enable = State::S0; + rd_clk_polarity = State::S0; + rd_transparent = State::S0; + } + cell->parameters[ID::RD_CLK_ENABLE] = rd_clk_enable; + cell->parameters[ID::RD_CLK_POLARITY] = rd_clk_polarity; + cell->parameters[ID::RD_TRANSPARENT] = rd_transparent; + cell->setPort(ID::RD_CLK, rd_clk); + cell->setPort(ID::RD_EN, rd_en); + cell->setPort(ID::RD_ADDR, rd_addr); + cell->setPort(ID::RD_DATA, rd_data); + for (auto &port : wr_ports) { + if (port.cell) { + module->remove(port.cell); + port.cell = nullptr; + } + wr_clk_enable.bits.push_back(State(port.clk_enable)); + wr_clk_polarity.bits.push_back(State(port.clk_polarity)); + wr_clk.append(port.clk); + log_assert(GetSize(port.clk) == 1); + wr_en.append(port.en); + log_assert(GetSize(port.en) == width); + SigSpec addr = port.addr; + addr.extend_u0(abits, false); + wr_addr.append(addr); + log_assert(GetSize(addr) == abits); + wr_data.append(port.data); + log_assert(GetSize(port.data) == width); + } + if (wr_ports.empty()) { + wr_clk_enable = State::S0; + wr_clk_polarity = State::S0; + } + cell->parameters[ID::WR_CLK_ENABLE] = wr_clk_enable; + cell->parameters[ID::WR_CLK_POLARITY] = wr_clk_polarity; + cell->setPort(ID::WR_CLK, wr_clk); + cell->setPort(ID::WR_EN, wr_en); + cell->setPort(ID::WR_ADDR, wr_addr); + cell->setPort(ID::WR_DATA, wr_data); + for (auto &init : inits) { + if (init.cell) { + module->remove(init.cell); + init.cell = nullptr; + } + } + cell->parameters[ID::INIT] = get_init_data(); + } else { + if (cell) { + module->remove(cell); + cell = nullptr; + } + if (!mem) { + if (memid.empty()) + memid = NEW_ID; + mem = new RTLIL::Memory; + mem->name = memid; + module->memories[memid] = mem; + } + mem->width = width; + mem->start_offset = start_offset; + mem->size = size; + for (auto &port : rd_ports) { + if (!port.cell) + port.cell = module->addCell(NEW_ID, ID($memrd)); + port.cell->parameters[ID::MEMID] = memid.str(); + port.cell->parameters[ID::ABITS] = GetSize(port.addr); + port.cell->parameters[ID::WIDTH] = width; + port.cell->parameters[ID::CLK_ENABLE] = port.clk_enable; + port.cell->parameters[ID::CLK_POLARITY] = port.clk_polarity; + port.cell->parameters[ID::TRANSPARENT] = port.transparent; + port.cell->setPort(ID::CLK, port.clk); + port.cell->setPort(ID::EN, port.en); + port.cell->setPort(ID::ADDR, port.addr); + port.cell->setPort(ID::DATA, port.data); + } + int idx = 0; + for (auto &port : wr_ports) { + if (!port.cell) + port.cell = module->addCell(NEW_ID, ID($memwr)); + port.cell->parameters[ID::MEMID] = memid.str(); + port.cell->parameters[ID::ABITS] = GetSize(port.addr); + port.cell->parameters[ID::WIDTH] = width; + port.cell->parameters[ID::CLK_ENABLE] = port.clk_enable; + port.cell->parameters[ID::CLK_POLARITY] = port.clk_polarity; + port.cell->parameters[ID::PRIORITY] = idx++; + port.cell->setPort(ID::CLK, port.clk); + port.cell->setPort(ID::EN, port.en); + port.cell->setPort(ID::ADDR, port.addr); + port.cell->setPort(ID::DATA, port.data); + } + idx = 0; + for (auto &init : inits) { + if (!init.cell) + init.cell = module->addCell(NEW_ID, ID($meminit)); + init.cell->parameters[ID::MEMID] = memid.str(); + init.cell->parameters[ID::ABITS] = GetSize(init.addr); + init.cell->parameters[ID::WIDTH] = width; + init.cell->parameters[ID::WORDS] = GetSize(init.data) / width; + init.cell->parameters[ID::PRIORITY] = idx++; + init.cell->setPort(ID::ADDR, init.addr); + init.cell->setPort(ID::DATA, init.data); + } + } +} + +void Mem::remove_wr_port(int idx) { + if (wr_ports[idx].cell) { + module->remove(wr_ports[idx].cell); + } + wr_ports.erase(wr_ports.begin() + idx); +} + +void Mem::remove_rd_port(int idx) { + if (rd_ports[idx].cell) { + module->remove(rd_ports[idx].cell); + } + rd_ports.erase(rd_ports.begin() + idx); +} + +void Mem::clear_inits() { + for (auto &init : inits) + if (init.cell) + module->remove(init.cell); + inits.clear(); +} + +Const Mem::get_init_data() const { + Const init_data(State::Sx, width * size); + for (auto &init : inits) { + int offset = (init.addr.as_int() - start_offset) * width; + for (int i = 0; i < GetSize(init.data); i++) + if (0 <= i+offset && i+offset < GetSize(init_data)) + init_data.bits[i+offset] = init.data.bits[i]; + } + return init_data; +} + +namespace { + + struct MemIndex { + dict<IdString, pool<Cell *>> rd_ports; + dict<IdString, pool<Cell *>> wr_ports; + dict<IdString, pool<Cell *>> inits; + MemIndex (Module *module) { + for (auto cell: module->cells()) { + if (cell->type == ID($memwr)) + wr_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); + else if (cell->type == ID($memrd)) + rd_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); + else if (cell->type == ID($meminit)) + inits[cell->parameters.at(ID::MEMID).decode_string()].insert(cell); + } + } + }; + + Mem mem_from_memory(Module *module, RTLIL::Memory *mem, const MemIndex &index) { + Mem res(module, mem->name, mem->width, mem->start_offset, mem->size); + res.packed = false; + res.mem = mem; + res.attributes = mem->attributes; + if (index.rd_ports.count(mem->name)) { + for (auto cell : index.rd_ports.at(mem->name)) { + MemRd mrd; + mrd.cell = cell; + mrd.attributes = cell->attributes; + mrd.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool(); + mrd.clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool(); + mrd.transparent = cell->parameters.at(ID::TRANSPARENT).as_bool(); + mrd.clk = cell->getPort(ID::CLK); + mrd.en = cell->getPort(ID::EN); + mrd.addr = cell->getPort(ID::ADDR); + mrd.data = cell->getPort(ID::DATA); + res.rd_ports.push_back(mrd); + } + } + if (index.wr_ports.count(mem->name)) { + std::vector<std::pair<int, MemWr>> ports; + for (auto cell : index.wr_ports.at(mem->name)) { + MemWr mwr; + mwr.cell = cell; + mwr.attributes = cell->attributes; + mwr.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool(); + mwr.clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool(); + mwr.clk = cell->getPort(ID::CLK); + mwr.en = cell->getPort(ID::EN); + mwr.addr = cell->getPort(ID::ADDR); + mwr.data = cell->getPort(ID::DATA); + ports.push_back(std::make_pair(cell->parameters.at(ID::PRIORITY).as_int(), mwr)); + } + std::sort(ports.begin(), ports.end(), [](const std::pair<int, MemWr> &a, const std::pair<int, MemWr> &b) { return a.first < b.first; }); + for (auto &it : ports) + res.wr_ports.push_back(it.second); + } + if (index.inits.count(mem->name)) { + std::vector<std::pair<int, MemInit>> inits; + for (auto cell : index.inits.at(mem->name)) { + MemInit init; + init.cell = cell; + init.attributes = cell->attributes; + auto addr = cell->getPort(ID::ADDR); + auto data = cell->getPort(ID::DATA); + if (!addr.is_fully_const()) + log_error("Non-constant address %s in memory initialization %s.\n", log_signal(addr), log_id(cell)); + if (!data.is_fully_const()) + log_error("Non-constant data %s in memory initialization %s.\n", log_signal(data), log_id(cell)); + init.addr = addr.as_const(); + init.data = data.as_const(); + inits.push_back(std::make_pair(cell->parameters.at(ID::PRIORITY).as_int(), init)); + } + std::sort(inits.begin(), inits.end(), [](const std::pair<int, MemInit> &a, const std::pair<int, MemInit> &b) { return a.first < b.first; }); + for (auto &it : inits) + res.inits.push_back(it.second); + } + return res; + } + + Mem mem_from_cell(Cell *cell) { + Mem res(cell->module, cell->parameters.at(ID::MEMID).decode_string(), + cell->parameters.at(ID::WIDTH).as_int(), + cell->parameters.at(ID::OFFSET).as_int(), + cell->parameters.at(ID::SIZE).as_int() + ); + int abits = cell->parameters.at(ID::ABITS).as_int(); + res.packed = true; + res.cell = cell; + res.attributes = cell->attributes; + Const &init = cell->parameters.at(ID::INIT); + if (!init.is_fully_undef()) { + int pos = 0; + while (pos < res.size) { + Const word = init.extract(pos * res.width, res.width, State::Sx); + if (word.is_fully_undef()) { + pos++; + } else { + int epos; + for (epos = pos; epos < res.size; epos++) { + Const eword = init.extract(epos * res.width, res.width, State::Sx); + if (eword.is_fully_undef()) + break; + } + MemInit minit; + minit.addr = res.start_offset + pos; + minit.data = init.extract(pos * res.width, (epos - pos) * res.width, State::Sx); + res.inits.push_back(minit); + pos = epos; + } + } + } + for (int i = 0; i < cell->parameters.at(ID::RD_PORTS).as_int(); i++) { + MemRd mrd; + mrd.clk_enable = cell->parameters.at(ID::RD_CLK_ENABLE).extract(i, 1).as_bool(); + mrd.clk_polarity = cell->parameters.at(ID::RD_CLK_POLARITY).extract(i, 1).as_bool(); + mrd.transparent = cell->parameters.at(ID::RD_TRANSPARENT).extract(i, 1).as_bool(); + mrd.clk = cell->getPort(ID::RD_CLK).extract(i, 1); + mrd.en = cell->getPort(ID::RD_EN).extract(i, 1); + mrd.addr = cell->getPort(ID::RD_ADDR).extract(i * abits, abits); + mrd.data = cell->getPort(ID::RD_DATA).extract(i * res.width, res.width); + res.rd_ports.push_back(mrd); + } + for (int i = 0; i < cell->parameters.at(ID::WR_PORTS).as_int(); i++) { + MemWr mwr; + mwr.clk_enable = cell->parameters.at(ID::WR_CLK_ENABLE).extract(i, 1).as_bool(); + mwr.clk_polarity = cell->parameters.at(ID::WR_CLK_POLARITY).extract(i, 1).as_bool(); + mwr.clk = cell->getPort(ID::WR_CLK).extract(i, 1); + mwr.en = cell->getPort(ID::WR_EN).extract(i * res.width, res.width); + mwr.addr = cell->getPort(ID::WR_ADDR).extract(i * abits, abits); + mwr.data = cell->getPort(ID::WR_DATA).extract(i * res.width, res.width); + res.wr_ports.push_back(mwr); + } + return res; + } + +} + +std::vector<Mem> Mem::get_all_memories(Module *module) { + std::vector<Mem> res; + MemIndex index(module); + for (auto it: module->memories) { + res.push_back(mem_from_memory(module, it.second, index)); + } + for (auto cell: module->cells()) { + if (cell->type == ID($mem)) + res.push_back(mem_from_cell(cell)); + } + return res; +} + +std::vector<Mem> Mem::get_selected_memories(Module *module) { + std::vector<Mem> res; + MemIndex index(module); + for (auto it: module->memories) { + if (module->design->selected(module, it.second)) + res.push_back(mem_from_memory(module, it.second, index)); + } + for (auto cell: module->selected_cells()) { + if (cell->type == ID($mem)) + res.push_back(mem_from_cell(cell)); + } + return res; +} + +Cell *Mem::extract_rdff(int idx) { + MemRd &port = rd_ports[idx]; + + if (!port.clk_enable) + return nullptr; + + Cell *c; + + if (port.transparent) + { + SigSpec sig_q = module->addWire(stringf("%s$rdreg[%d]$q", memid.c_str(), idx), GetSize(port.addr)); + SigSpec sig_d = port.addr; + port.addr = sig_q; + c = module->addDffe(stringf("%s$rdreg[%d]", memid.c_str(), idx), port.clk, port.en, sig_d, sig_q, port.clk_polarity, true); + } + else + { + SigSpec sig_d = module->addWire(stringf("%s$rdreg[%d]$d", memid.c_str(), idx), width); + SigSpec sig_q = port.data; + port.data = sig_d; + c = module->addDffe(stringf("%s$rdreg[%d]", memid.c_str(), idx), port.clk, port.en, sig_d, sig_q, port.clk_polarity, true); + } + + log("Extracted %s FF from read port %d of %s.%s: %s\n", port.transparent ? "addr" : "data", + idx, log_id(module), log_id(memid), log_id(c)); + + port.en = State::S1; + port.clk = State::S0; + port.clk_enable = false; + port.clk_polarity = true; + + return c; +} diff --git a/kernel/mem.h b/kernel/mem.h new file mode 100644 index 000000000..6d727e71d --- /dev/null +++ b/kernel/mem.h @@ -0,0 +1,78 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Marcelina KoÅ›cielnicka <mwk@0x04.net> + * + * 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. + * + */ + +#ifndef MEM_H +#define MEM_H + +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN + +struct MemRd { + dict<IdString, Const> attributes; + Cell *cell; + bool clk_enable, clk_polarity; + bool transparent; + SigSpec clk, en, addr, data; + MemRd() : cell(nullptr) {} +}; + +struct MemWr { + dict<IdString, Const> attributes; + Cell *cell; + bool clk_enable, clk_polarity; + SigSpec clk, en, addr, data; + MemWr() : cell(nullptr) {} +}; + +struct MemInit { + dict<IdString, Const> attributes; + Cell *cell; + Const addr; + Const data; + MemInit() : cell(nullptr) {} +}; + +struct Mem { + Module *module; + IdString memid; + dict<IdString, Const> attributes; + bool packed; + RTLIL::Memory *mem; + Cell *cell; + int width, start_offset, size; + std::vector<MemInit> inits; + std::vector<MemRd> rd_ports; + std::vector<MemWr> wr_ports; + + void remove(); + void emit(); + void remove_wr_port(int idx); + void remove_rd_port(int idx); + void clear_inits(); + Const get_init_data() const; + static std::vector<Mem> get_all_memories(Module *module); + static std::vector<Mem> get_selected_memories(Module *module); + Cell *extract_rdff(int idx); + Mem(Module *module, IdString memid, int width, int start_offset, int size) : module(module), memid(memid), packed(false), mem(nullptr), cell(nullptr), width(width), start_offset(start_offset), size(size) {} +}; + +YOSYS_NAMESPACE_END + +#endif diff --git a/kernel/modtools.h b/kernel/modtools.h index fbc5482ee..29c510059 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -158,7 +158,7 @@ struct ModIndex : public RTLIL::Monitor #endif } - void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) YS_OVERRIDE + void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) override { log_assert(module == cell->module); @@ -169,7 +169,7 @@ struct ModIndex : public RTLIL::Monitor port_add(cell, port, sig); } - void notify_connect(RTLIL::Module *mod YS_ATTRIBUTE(unused), const RTLIL::SigSig &sigsig) YS_OVERRIDE + void notify_connect(RTLIL::Module *mod, const RTLIL::SigSig &sigsig) override { log_assert(module == mod); @@ -214,13 +214,13 @@ struct ModIndex : public RTLIL::Monitor } } - void notify_connect(RTLIL::Module *mod YS_ATTRIBUTE(unused), const std::vector<RTLIL::SigSig>&) YS_OVERRIDE + void notify_connect(RTLIL::Module *mod, const std::vector<RTLIL::SigSig>&) override { log_assert(module == mod); auto_reload_module = true; } - void notify_blackout(RTLIL::Module *mod YS_ATTRIBUTE(unused)) YS_OVERRIDE + void notify_blackout(RTLIL::Module *mod) override { log_assert(module == mod); auto_reload_module = true; diff --git a/kernel/register.cc b/kernel/register.cc index 02974e534..34735a608 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -753,7 +753,7 @@ static struct CellHelpMessages { struct HelpPass : public Pass { HelpPass() : Pass("help", "display help messages") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" help ................ list all commands\n"); @@ -822,7 +822,7 @@ struct HelpPass : public Pass { fclose(f); } - void execute(std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design*) override { if (args.size() == 1) { log("\n"); @@ -926,7 +926,7 @@ struct HelpPass : public Pass { struct EchoPass : public Pass { EchoPass() : Pass("echo", "turning echoing back of commands on and off") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" echo on\n"); @@ -939,7 +939,7 @@ struct EchoPass : public Pass { log("Do not print all commands to log before executing them. (default)\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design*) override { if (args.size() > 2) cmd_error(args, 2, "Unexpected argument."); @@ -964,7 +964,7 @@ struct MinisatSatSolver : public SatSolver { MinisatSatSolver() : SatSolver("minisat") { yosys_satsolver = this; } - ezSAT *create() YS_OVERRIDE { + ezSAT *create() override { return new ezMiniSAT(); } } MinisatSatSolver; diff --git a/kernel/register.h b/kernel/register.h index 7bbcd1727..5cd849082 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -97,9 +97,9 @@ struct Frontend : Pass std::string frontend_name; Frontend(std::string name, std::string short_help = "** document me **"); - void run_register() YS_OVERRIDE; - ~Frontend() YS_OVERRIDE; - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL; + void run_register() override; + ~Frontend() override; + void execute(std::vector<std::string> args, RTLIL::Design *design) override final; virtual void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) = 0; static std::vector<std::string> next_args; @@ -113,9 +113,9 @@ struct Backend : Pass { std::string backend_name; Backend(std::string name, std::string short_help = "** document me **"); - void run_register() YS_OVERRIDE; - ~Backend() YS_OVERRIDE; - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL; + void run_register() override; + ~Backend() override; + void execute(std::vector<std::string> args, RTLIL::Design *design) override final; virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) = 0; void extra_args(std::ostream *&f, std::string &filename, std::vector<std::string> args, size_t argidx, bool bin_output = false); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ef81cac01..a9f585616 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -22,7 +22,7 @@ #include "kernel/celltypes.h" #include "frontends/verilog/verilog_frontend.h" #include "frontends/verilog/preproc.h" -#include "backends/ilang/ilang_backend.h" +#include "backends/rtlil/rtlil_backend.h" #include <string.h> #include <algorithm> @@ -54,8 +54,14 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() { ID($dff), ID($dffe), ID($dffsr), + ID($dffsre), ID($adff), + ID($adffe), + ID($sdff), + ID($sdffe), + ID($sdffce), ID($dlatch), + ID($adlatch), ID($dlatchsr), ID($_DFFE_NN_), ID($_DFFE_NP_), @@ -69,16 +75,102 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() { ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_), + ID($_DFFSRE_NNNN_), + ID($_DFFSRE_NNNP_), + ID($_DFFSRE_NNPN_), + ID($_DFFSRE_NNPP_), + ID($_DFFSRE_NPNN_), + ID($_DFFSRE_NPNP_), + ID($_DFFSRE_NPPN_), + ID($_DFFSRE_NPPP_), + ID($_DFFSRE_PNNN_), + ID($_DFFSRE_PNNP_), + ID($_DFFSRE_PNPN_), + ID($_DFFSRE_PNPP_), + ID($_DFFSRE_PPNN_), + ID($_DFFSRE_PPNP_), + ID($_DFFSRE_PPPN_), + ID($_DFFSRE_PPPP_), + ID($_DFF_N_), + ID($_DFF_P_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_N_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_), - ID($_DFF_P_), + ID($_DFFE_NN0N_), + ID($_DFFE_NN0P_), + ID($_DFFE_NN1N_), + ID($_DFFE_NN1P_), + ID($_DFFE_NP0N_), + ID($_DFFE_NP0P_), + ID($_DFFE_NP1N_), + ID($_DFFE_NP1P_), + ID($_DFFE_PN0N_), + ID($_DFFE_PN0P_), + ID($_DFFE_PN1N_), + ID($_DFFE_PN1P_), + ID($_DFFE_PP0N_), + ID($_DFFE_PP0P_), + ID($_DFFE_PP1N_), + ID($_DFFE_PP1P_), + ID($_SDFF_NN0_), + ID($_SDFF_NN1_), + ID($_SDFF_NP0_), + ID($_SDFF_NP1_), + ID($_SDFF_PN0_), + ID($_SDFF_PN1_), + ID($_SDFF_PP0_), + ID($_SDFF_PP1_), + ID($_SDFFE_NN0N_), + ID($_SDFFE_NN0P_), + ID($_SDFFE_NN1N_), + ID($_SDFFE_NN1P_), + ID($_SDFFE_NP0N_), + ID($_SDFFE_NP0P_), + ID($_SDFFE_NP1N_), + ID($_SDFFE_NP1P_), + ID($_SDFFE_PN0N_), + ID($_SDFFE_PN0P_), + ID($_SDFFE_PN1N_), + ID($_SDFFE_PN1P_), + ID($_SDFFE_PP0N_), + ID($_SDFFE_PP0P_), + ID($_SDFFE_PP1N_), + ID($_SDFFE_PP1P_), + ID($_SDFFCE_NN0N_), + ID($_SDFFCE_NN0P_), + ID($_SDFFCE_NN1N_), + ID($_SDFFCE_NN1P_), + ID($_SDFFCE_NP0N_), + ID($_SDFFCE_NP0P_), + ID($_SDFFCE_NP1N_), + ID($_SDFFCE_NP1P_), + ID($_SDFFCE_PN0N_), + ID($_SDFFCE_PN0P_), + ID($_SDFFCE_PN1N_), + ID($_SDFFCE_PN1P_), + ID($_SDFFCE_PP0N_), + ID($_SDFFCE_PP0P_), + ID($_SDFFCE_PP1N_), + ID($_SDFFCE_PP1P_), + ID($_SR_NN_), + ID($_SR_NP_), + ID($_SR_PN_), + ID($_SR_PP_), + ID($_DLATCH_N_), + ID($_DLATCH_P_), + ID($_DLATCH_NN0_), + ID($_DLATCH_NN1_), + ID($_DLATCH_NP0_), + ID($_DLATCH_NP1_), + ID($_DLATCH_PN0_), + ID($_DLATCH_PN1_), + ID($_DLATCH_PP0_), + ID($_DLATCH_PP1_), ID($_DLATCHSR_NNN_), ID($_DLATCHSR_NNP_), ID($_DLATCHSR_NPN_), @@ -87,8 +179,6 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() { ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_), - ID($_DLATCH_N_), - ID($_DLATCH_P_), ID($_FF_), }; return res; @@ -833,7 +923,7 @@ namespace { void error(int linenr) { std::stringstream buf; - ILANG_BACKEND::dump_cell(buf, " ", cell); + RTLIL_BACKEND::dump_cell(buf, " ", cell); log_error("Found error in internal cell %s%s%s (%s) at %s:%d:\n%s", module ? module->name.c_str() : "", module ? "." : "", @@ -945,7 +1035,11 @@ namespace { } if (cell->type.in(ID($shift), ID($shiftx))) { - param_bool(ID::A_SIGNED); + if (cell->type == ID($shiftx)) { + param_bool(ID::A_SIGNED, /*expected=*/false); + } else { + param_bool(ID::A_SIGNED); + } param_bool(ID::B_SIGNED); port(ID::A, param(ID::A_WIDTH)); port(ID::B, param(ID::B_WIDTH)); @@ -1139,6 +1233,21 @@ namespace { return; } + if (cell->type == ID($dffsre)) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::SET_POLARITY); + param_bool(ID::CLR_POLARITY); + param_bool(ID::EN_POLARITY); + port(ID::CLK, 1); + port(ID::EN, 1); + port(ID::SET, param(ID::WIDTH)); + port(ID::CLR, param(ID::WIDTH)); + port(ID::D, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($adff)) { param_bool(ID::CLK_POLARITY); param_bool(ID::ARST_POLARITY); @@ -1151,6 +1260,46 @@ namespace { return; } + if (cell->type == ID($sdff)) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::SRST_POLARITY); + param_bits(ID::SRST_VALUE, param(ID::WIDTH)); + port(ID::CLK, 1); + port(ID::SRST, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + + if (cell->type.in(ID($sdffe), ID($sdffce))) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::EN_POLARITY); + param_bool(ID::SRST_POLARITY); + param_bits(ID::SRST_VALUE, param(ID::WIDTH)); + port(ID::CLK, 1); + port(ID::EN, 1); + port(ID::SRST, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + + if (cell->type == ID($adffe)) { + param_bool(ID::CLK_POLARITY); + param_bool(ID::EN_POLARITY); + param_bool(ID::ARST_POLARITY); + param_bits(ID::ARST_VALUE, param(ID::WIDTH)); + port(ID::CLK, 1); + port(ID::EN, 1); + port(ID::ARST, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($dlatch)) { param_bool(ID::EN_POLARITY); port(ID::EN, 1); @@ -1160,6 +1309,18 @@ namespace { return; } + if (cell->type == ID($adlatch)) { + param_bool(ID::EN_POLARITY); + param_bool(ID::ARST_POLARITY); + param_bits(ID::ARST_VALUE, param(ID::WIDTH)); + port(ID::EN, 1); + port(ID::ARST, 1); + port(ID::D, param(ID::WIDTH)); + port(ID::Q, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($dlatchsr)) { param_bool(ID::EN_POLARITY); param_bool(ID::SET_POLARITY); @@ -1351,49 +1512,69 @@ namespace { if (cell->type == ID($_MUX8_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::E,1); port(ID::F,1); port(ID::G,1); port(ID::H,1); port(ID::S,1); port(ID::T,1); port(ID::U,1); port(ID::Y,1); check_expected(); return; } if (cell->type == ID($_MUX16_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::E,1); port(ID::F,1); port(ID::G,1); port(ID::H,1); port(ID::I,1); port(ID::J,1); port(ID::K,1); port(ID::L,1); port(ID::M,1); port(ID::N,1); port(ID::O,1); port(ID::P,1); port(ID::S,1); port(ID::T,1); port(ID::U,1); port(ID::V,1); port(ID::Y,1); check_expected(); return; } - if (cell->type == ID($_SR_NN_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_SR_NP_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_SR_PN_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_SR_PP_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } - - if (cell->type == ID($_FF_)) { port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFF_N_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); check_expected(); return; } - if (cell->type == ID($_DFF_P_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); check_expected(); return; } - - if (cell->type == ID($_DFFE_NN_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } - if (cell->type == ID($_DFFE_NP_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } - if (cell->type == ID($_DFFE_PN_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } - if (cell->type == ID($_DFFE_PP_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } - - if (cell->type == ID($_DFF_NN0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_NN1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_NP0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_NP1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_PN0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_PN1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_PP0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - if (cell->type == ID($_DFF_PP1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } - - if (cell->type == ID($_DFFSR_NNN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_NNP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_NPN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_NPP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_PNN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_PNP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_PPN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DFFSR_PPP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - - if (cell->type == ID($_DLATCH_N_)) { port(ID::E,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCH_P_)) { port(ID::E,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - - if (cell->type == ID($_DLATCHSR_NNN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_NNP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_NPN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_NPP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_PNN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_PNP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_PPN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } - if (cell->type == ID($_DLATCHSR_PPP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } + if (cell->type.in(ID($_SR_NN_), ID($_SR_NP_), ID($_SR_PN_), ID($_SR_PP_))) + { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type == ID($_FF_)) { port(ID::D,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); check_expected(); return; } + + if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } + + if (cell->type.in( + ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), + ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } + + if (cell->type.in( + ID($_DFFE_NN0N_), ID($_DFFE_NN0P_), ID($_DFFE_NN1N_), ID($_DFFE_NN1P_), + ID($_DFFE_NP0N_), ID($_DFFE_NP0P_), ID($_DFFE_NP1N_), ID($_DFFE_NP1P_), + ID($_DFFE_PN0N_), ID($_DFFE_PN0P_), ID($_DFFE_PN1N_), ID($_DFFE_PN1P_), + ID($_DFFE_PP0N_), ID($_DFFE_PP0P_), ID($_DFFE_PP1N_), ID($_DFFE_PP1P_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); port(ID::E,1); check_expected(); return; } + + if (cell->type.in( + ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), + ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_))) + { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type.in( + ID($_DFFSRE_NNNN_), ID($_DFFSRE_NNNP_), ID($_DFFSRE_NNPN_), ID($_DFFSRE_NNPP_), + ID($_DFFSRE_NPNN_), ID($_DFFSRE_NPNP_), ID($_DFFSRE_NPPN_), ID($_DFFSRE_NPPP_), + ID($_DFFSRE_PNNN_), ID($_DFFSRE_PNNP_), ID($_DFFSRE_PNPN_), ID($_DFFSRE_PNPP_), + ID($_DFFSRE_PPNN_), ID($_DFFSRE_PPNP_), ID($_DFFSRE_PPPN_), ID($_DFFSRE_PPPP_))) + { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::E,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type.in( + ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_), + ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } + + if (cell->type.in( + ID($_SDFFE_NN0N_), ID($_SDFFE_NN0P_), ID($_SDFFE_NN1N_), ID($_SDFFE_NN1P_), + ID($_SDFFE_NP0N_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1N_), ID($_SDFFE_NP1P_), + ID($_SDFFE_PN0N_), ID($_SDFFE_PN0P_), ID($_SDFFE_PN1N_), ID($_SDFFE_PN1P_), + ID($_SDFFE_PP0N_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1N_), ID($_SDFFE_PP1P_), + ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NN1P_), + ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1N_), ID($_SDFFCE_NP1P_), + ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PN1P_), + ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1N_), ID($_SDFFCE_PP1P_))) + { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); port(ID::E,1); check_expected(); return; } + + if (cell->type.in(ID($_DLATCH_N_), ID($_DLATCH_P_))) + { port(ID::E,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type.in( + ID($_DLATCH_NN0_), ID($_DLATCH_NN1_), ID($_DLATCH_NP0_), ID($_DLATCH_NP1_), + ID($_DLATCH_PN0_), ID($_DLATCH_PN1_), ID($_DLATCH_PP0_), ID($_DLATCH_PP1_))) + { port(ID::E,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } + + if (cell->type.in( + ID($_DLATCHSR_NNN_), ID($_DLATCHSR_NNP_), ID($_DLATCHSR_NPN_), ID($_DLATCHSR_NPP_), + ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_))) + { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } error(__LINE__); } @@ -2299,6 +2480,25 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, const RTLIL::SigSpec return cell; } +RTLIL::Cell* RTLIL::Module::addDffsre(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($dffsre)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::SET_POLARITY] = set_polarity; + cell->parameters[ID::CLR_POLARITY] = clr_polarity; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::SET, sig_set); + cell->setPort(ID::CLR, sig_clr); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) { @@ -2315,6 +2515,76 @@ RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, const RTLIL::SigSpec & return cell; } +RTLIL::Cell* RTLIL::Module::addAdffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($adffe)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::ARST_POLARITY] = arst_polarity; + cell->parameters[ID::ARST_VALUE] = arst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::ARST, sig_arst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const srst_value, bool clk_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($sdff)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::SRST_POLARITY] = srst_polarity; + cell->parameters[ID::SRST_VALUE] = srst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::SRST, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($sdffe)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::SRST_POLARITY] = srst_polarity; + cell->parameters[ID::SRST_VALUE] = srst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::SRST, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdffce(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($sdffce)); + cell->parameters[ID::CLK_POLARITY] = clk_polarity; + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::SRST_POLARITY] = srst_polarity; + cell->parameters[ID::SRST_VALUE] = srst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::CLK, sig_clk); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::SRST, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($dlatch)); @@ -2327,6 +2597,22 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, const RTLIL::SigSpec return cell; } +RTLIL::Cell* RTLIL::Module::addAdlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + RTLIL::Const arst_value, bool en_polarity, bool arst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($adlatch)); + cell->parameters[ID::EN_POLARITY] = en_polarity; + cell->parameters[ID::ARST_POLARITY] = arst_polarity; + cell->parameters[ID::ARST_VALUE] = arst_value; + cell->parameters[ID::WIDTH] = sig_q.size(); + cell->setPort(ID::EN, sig_en); + cell->setPort(ID::ARST, sig_arst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { @@ -2344,6 +2630,17 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, const RTLIL::SigSp return cell; } +RTLIL::Cell* RTLIL::Module::addSrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_SR_%c%c_", set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); + cell->setPort(ID::S, sig_set); + cell->setPort(ID::R, sig_clr); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($_FF_)); @@ -2387,6 +2684,20 @@ RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, const RTLIL::SigS return cell; } +RTLIL::Cell* RTLIL::Module::addDffsreGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_DFFSRE_%c%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::S, sig_set); + cell->setPort(ID::R, sig_clr); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) { @@ -2399,6 +2710,57 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, const RTLIL::SigSp return cell; } +RTLIL::Cell* RTLIL::Module::addAdffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_DFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_arst); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value, bool clk_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_SDFF_%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_srst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_SDFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_srst); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSdffceGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_SDFFCE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')); + cell->setPort(ID::C, sig_clk); + cell->setPort(ID::R, sig_srst); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')); @@ -2409,6 +2771,18 @@ RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, const RTLIL::Sig return cell; } +RTLIL::Cell* RTLIL::Module::addAdlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool arst_value, bool en_polarity, bool arst_polarity, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c%c%c_", en_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); + cell->setPort(ID::E, sig_en); + cell->setPort(ID::R, sig_arst); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->set_src_attribute(src); + return cell; +} + RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f3dc3af68..a03e8933c 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -375,6 +375,8 @@ namespace RTLIL bool in(const char *rhs) const { return *this == rhs; } bool in(const std::string &rhs) const { return *this == rhs; } bool in(const pool<IdString> &rhs) const { return rhs.count(*this) != 0; } + + bool isPublic() { return begins_with("\\"); } }; namespace ID { @@ -554,6 +556,29 @@ namespace RTLIL return *this; } + inline ObjIterator<T>& operator+=(int amt) { + log_assert(list_p != nullptr); + it += amt; + if (it == list_p->end()) { + (*refcount_p)--; + list_p = nullptr; + refcount_p = nullptr; + } + return *this; + } + + inline ObjIterator<T> operator+(int amt) { + log_assert(list_p != nullptr); + ObjIterator<T> new_obj(*this); + new_obj.it += amt; + if (new_obj.it == list_p->end()) { + (*(new_obj.refcount_p))--; + new_obj.list_p = nullptr; + new_obj.refcount_p = nullptr; + } + return new_obj; + } + inline const ObjIterator<T> operator++(int) { ObjIterator<T> result(*this); ++(*this); @@ -1061,6 +1086,13 @@ struct RTLIL::Design return selected_member(module->name, member->name); } + template<typename T1> void select(T1 *module) { + if (selection_stack.size() > 0) { + RTLIL::Selection &sel = selection_stack.back(); + sel.select(module); + } + } + template<typename T1, typename T2> void select(T1 *module, T2 *member) { if (selection_stack.size() > 0) { RTLIL::Selection &sel = selection_stack.back(); @@ -1244,8 +1276,14 @@ public: RTLIL::Cell* addDff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = ""); RTLIL::Cell* addDffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = ""); RTLIL::Cell* addDffsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDffsre (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdffce (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = ""); RTLIL::Cell* addDlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAdlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool en_polarity = true, bool arst_polarity = true, const std::string &src = ""); RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); RTLIL::Cell* addBufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = ""); @@ -1265,14 +1303,28 @@ public: RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = ""); RTLIL::Cell* addOai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = ""); + RTLIL::Cell* addSrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + const RTLIL::SigSpec &sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); RTLIL::Cell* addFfGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = ""); RTLIL::Cell* addDffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = ""); RTLIL::Cell* addDffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = ""); RTLIL::Cell* addDffsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); + RTLIL::Cell* addDffsreGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); RTLIL::Cell* addAdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAdffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool arst_value = false, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value = false, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value = false, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = ""); + RTLIL::Cell* addSdffceGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool srst_value = false, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = ""); RTLIL::Cell* addDlatchGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = ""); + RTLIL::Cell* addAdlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + bool arst_value = false, bool en_polarity = true, bool arst_polarity = true, const std::string &src = ""); RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = ""); diff --git a/kernel/satgen.cc b/kernel/satgen.cc new file mode 100644 index 000000000..2a54e78ec --- /dev/null +++ b/kernel/satgen.cc @@ -0,0 +1,1239 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> + * + * 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/satgen.h" +#include "kernel/ff.h" + +USING_YOSYS_NAMESPACE + +bool SatGen::importCell(RTLIL::Cell *cell, int timestep) +{ + bool arith_undef_handled = false; + bool is_arith_compare = cell->type.in(ID($lt), ID($le), ID($ge), ID($gt)); + + if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor)) || is_arith_compare)) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + if (is_arith_compare) + extendSignalWidth(undef_a, undef_b, cell, true); + else + extendSignalWidth(undef_a, undef_b, undef_y, cell, true); + + int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); + int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); + int undef_y_bit = ez->OR(undef_any_a, undef_any_b); + + if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) { + std::vector<int> b = importSigSpec(cell->getPort(ID::B), timestep); + undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b))); + } + + if (is_arith_compare) { + for (size_t i = 1; i < undef_y.size(); i++) + ez->SET(ez->CONST_FALSE, undef_y.at(i)); + ez->SET(undef_y_bit, undef_y.at(0)); + } else { + std::vector<int> undef_y_bits(undef_y.size(), undef_y_bit); + ez->assume(ez->vec_eq(undef_y_bits, undef_y)); + } + + arith_undef_handled = true; + } + + if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), + ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($sub))) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidth(a, b, y, cell); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + + if (cell->type.in(ID($and), ID($_AND_))) + ez->assume(ez->vec_eq(ez->vec_and(a, b), yy)); + if (cell->type == ID($_NAND_)) + ez->assume(ez->vec_eq(ez->vec_not(ez->vec_and(a, b)), yy)); + if (cell->type.in(ID($or), ID($_OR_))) + ez->assume(ez->vec_eq(ez->vec_or(a, b), yy)); + if (cell->type == ID($_NOR_)) + ez->assume(ez->vec_eq(ez->vec_not(ez->vec_or(a, b)), yy)); + if (cell->type.in(ID($xor), ID($_XOR_))) + ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy)); + if (cell->type.in(ID($xnor), ID($_XNOR_))) + ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(a, b)), yy)); + if (cell->type == ID($_ANDNOT_)) + ez->assume(ez->vec_eq(ez->vec_and(a, ez->vec_not(b)), yy)); + if (cell->type == ID($_ORNOT_)) + ez->assume(ez->vec_eq(ez->vec_or(a, ez->vec_not(b)), yy)); + if (cell->type == ID($add)) + ez->assume(ez->vec_eq(ez->vec_add(a, b), yy)); + if (cell->type == ID($sub)) + ez->assume(ez->vec_eq(ez->vec_sub(a, b), yy)); + + if (model_undef && !arith_undef_handled) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidth(undef_a, undef_b, undef_y, cell, false); + + if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_))) { + std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)); + std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b)); + std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b0))); + ez->assume(ez->vec_eq(yX, undef_y)); + } + else if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_))) { + std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a)); + std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b)); + std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b1))); + ez->assume(ez->vec_eq(yX, undef_y)); + } + else if (cell->type.in(ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_))) { + std::vector<int> yX = ez->vec_or(undef_a, undef_b); + ez->assume(ez->vec_eq(yX, undef_y)); + } + else if (cell->type == ID($_ANDNOT_)) { + std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)); + std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b)); + std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b1))); + ez->assume(ez->vec_eq(yX, undef_y)); + } + + else if (cell->type == ID($_ORNOT_)) { + std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a)); + std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b)); + std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b0))); + ez->assume(ez->vec_eq(yX, undef_y)); + } + else + log_abort(); + + undefGating(y, yy, undef_y); + } + else if (model_undef) + { + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + undefGating(y, yy, undef_y); + } + return true; + } + + if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) + { + bool aoi_mode = cell->type.in(ID($_AOI3_), ID($_AOI4_)); + bool three_mode = cell->type.in(ID($_AOI3_), ID($_OAI3_)); + + int a = importDefSigSpec(cell->getPort(ID::A), timestep).at(0); + int b = importDefSigSpec(cell->getPort(ID::B), timestep).at(0); + int c = importDefSigSpec(cell->getPort(ID::C), timestep).at(0); + int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort(ID::D), timestep).at(0); + int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0); + int yy = model_undef ? ez->literal() : y; + + if (cell->type.in(ID($_AOI3_), ID($_AOI4_))) + ez->assume(ez->IFF(ez->NOT(ez->OR(ez->AND(a, b), ez->AND(c, d))), yy)); + else + ez->assume(ez->IFF(ez->NOT(ez->AND(ez->OR(a, b), ez->OR(c, d))), yy)); + + if (model_undef) + { + int undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep).at(0); + int undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep).at(0); + int undef_c = importUndefSigSpec(cell->getPort(ID::C), timestep).at(0); + int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort(ID::D), timestep).at(0); + int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0); + + if (aoi_mode) + { + int a0 = ez->AND(ez->NOT(a), ez->NOT(undef_a)); + int b0 = ez->AND(ez->NOT(b), ez->NOT(undef_b)); + int c0 = ez->AND(ez->NOT(c), ez->NOT(undef_c)); + int d0 = ez->AND(ez->NOT(d), ez->NOT(undef_d)); + + int ab = ez->AND(a, b), cd = ez->AND(c, d); + int undef_ab = ez->AND(ez->OR(undef_a, undef_b), ez->NOT(ez->OR(a0, b0))); + int undef_cd = ez->AND(ez->OR(undef_c, undef_d), ez->NOT(ez->OR(c0, d0))); + + int ab1 = ez->AND(ab, ez->NOT(undef_ab)); + int cd1 = ez->AND(cd, ez->NOT(undef_cd)); + int yX = ez->AND(ez->OR(undef_ab, undef_cd), ez->NOT(ez->OR(ab1, cd1))); + + ez->assume(ez->IFF(yX, undef_y)); + } + else + { + int a1 = ez->AND(a, ez->NOT(undef_a)); + int b1 = ez->AND(b, ez->NOT(undef_b)); + int c1 = ez->AND(c, ez->NOT(undef_c)); + int d1 = ez->AND(d, ez->NOT(undef_d)); + + int ab = ez->OR(a, b), cd = ez->OR(c, d); + int undef_ab = ez->AND(ez->OR(undef_a, undef_b), ez->NOT(ez->OR(a1, b1))); + int undef_cd = ez->AND(ez->OR(undef_c, undef_d), ez->NOT(ez->OR(c1, d1))); + + int ab0 = ez->AND(ez->NOT(ab), ez->NOT(undef_ab)); + int cd0 = ez->AND(ez->NOT(cd), ez->NOT(undef_cd)); + int yX = ez->AND(ez->OR(undef_ab, undef_cd), ez->NOT(ez->OR(ab0, cd0))); + + ez->assume(ez->IFF(yX, undef_y)); + } + + undefGating(y, yy, undef_y); + } + + return true; + } + + if (cell->type.in(ID($_NOT_), ID($not))) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidthUnary(a, y, cell); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + ez->assume(ez->vec_eq(ez->vec_not(a), yy)); + + if (model_undef) { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidthUnary(undef_a, undef_y, cell, false); + ez->assume(ez->vec_eq(undef_a, undef_y)); + undefGating(y, yy, undef_y); + } + return true; + } + + if (cell->type.in(ID($_MUX_), ID($mux), ID($_NMUX_))) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> s = importDefSigSpec(cell->getPort(ID::S), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + if (cell->type == ID($_NMUX_)) + ez->assume(ez->vec_eq(ez->vec_not(ez->vec_ite(s.at(0), b, a)), yy)); + else + ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy)); + + if (model_undef) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID::S), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + + std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b)); + std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b)); + std::vector<int> yX = ez->vec_ite(undef_s.at(0), undef_ab, ez->vec_ite(s.at(0), undef_b, undef_a)); + ez->assume(ez->vec_eq(yX, undef_y)); + undefGating(y, yy, undef_y); + } + return true; + } + + if (cell->type == ID($pmux)) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> s = importDefSigSpec(cell->getPort(ID::S), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + + std::vector<int> tmp = a; + for (size_t i = 0; i < s.size(); i++) { + std::vector<int> part_of_b(b.begin()+i*a.size(), b.begin()+(i+1)*a.size()); + tmp = ez->vec_ite(s.at(i), part_of_b, tmp); + } + ez->assume(ez->vec_eq(tmp, yy)); + + if (model_undef) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID::S), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + + int maybe_a = ez->CONST_TRUE; + + std::vector<int> bits_set = std::vector<int>(undef_y.size(), ez->CONST_FALSE); + std::vector<int> bits_clr = std::vector<int>(undef_y.size(), ez->CONST_FALSE); + + for (size_t i = 0; i < s.size(); i++) + { + std::vector<int> part_of_b(b.begin()+i*a.size(), b.begin()+(i+1)*a.size()); + std::vector<int> part_of_undef_b(undef_b.begin()+i*a.size(), undef_b.begin()+(i+1)*a.size()); + + int maybe_s = ez->OR(s.at(i), undef_s.at(i)); + int sure_s = ez->AND(s.at(i), ez->NOT(undef_s.at(i))); + + maybe_a = ez->AND(maybe_a, ez->NOT(sure_s)); + + bits_set = ez->vec_ite(maybe_s, ez->vec_or(bits_set, ez->vec_or(part_of_b, part_of_undef_b)), bits_set); + bits_clr = ez->vec_ite(maybe_s, ez->vec_or(bits_clr, ez->vec_or(ez->vec_not(part_of_b), part_of_undef_b)), bits_clr); + } + + bits_set = ez->vec_ite(maybe_a, ez->vec_or(bits_set, ez->vec_or(bits_set, ez->vec_or(a, undef_a))), bits_set); + bits_clr = ez->vec_ite(maybe_a, ez->vec_or(bits_clr, ez->vec_or(bits_clr, ez->vec_or(ez->vec_not(a), undef_a))), bits_clr); + + ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(bits_set, bits_clr)), undef_y)); + undefGating(y, yy, undef_y); + } + return true; + } + + if (cell->type.in(ID($pos), ID($neg))) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidthUnary(a, y, cell); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + + if (cell->type == ID($pos)) { + ez->assume(ez->vec_eq(a, yy)); + } else { + std::vector<int> zero(a.size(), ez->CONST_FALSE); + ez->assume(ez->vec_eq(ez->vec_sub(zero, a), yy)); + } + + if (model_undef) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidthUnary(undef_a, undef_y, cell); + + if (cell->type == ID($pos)) { + ez->assume(ez->vec_eq(undef_a, undef_y)); + } else { + int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); + std::vector<int> undef_y_bits(undef_y.size(), undef_any_a); + ez->assume(ez->vec_eq(undef_y_bits, undef_y)); + } + + undefGating(y, yy, undef_y); + } + return true; + } + + if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + + if (cell->type == ID($reduce_and)) + ez->SET(ez->expression(ez->OpAnd, a), yy.at(0)); + if (cell->type.in(ID($reduce_or), ID($reduce_bool))) + ez->SET(ez->expression(ez->OpOr, a), yy.at(0)); + if (cell->type == ID($reduce_xor)) + ez->SET(ez->expression(ez->OpXor, a), yy.at(0)); + if (cell->type == ID($reduce_xnor)) + ez->SET(ez->NOT(ez->expression(ez->OpXor, a)), yy.at(0)); + if (cell->type == ID($logic_not)) + ez->SET(ez->NOT(ez->expression(ez->OpOr, a)), yy.at(0)); + for (size_t i = 1; i < y.size(); i++) + ez->SET(ez->CONST_FALSE, yy.at(i)); + + if (model_undef) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + int aX = ez->expression(ezSAT::OpOr, undef_a); + + if (cell->type == ID($reduce_and)) { + int a0 = ez->expression(ezSAT::OpOr, ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a))); + ez->assume(ez->IFF(ez->AND(ez->NOT(a0), aX), undef_y.at(0))); + } + else if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not))) { + int a1 = ez->expression(ezSAT::OpOr, ez->vec_and(a, ez->vec_not(undef_a))); + ez->assume(ez->IFF(ez->AND(ez->NOT(a1), aX), undef_y.at(0))); + } + else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { + ez->assume(ez->IFF(aX, undef_y.at(0))); + } else + log_abort(); + + for (size_t i = 1; i < undef_y.size(); i++) + ez->SET(ez->CONST_FALSE, undef_y.at(i)); + + undefGating(y, yy, undef_y); + } + return true; + } + + if (cell->type.in(ID($logic_and), ID($logic_or))) + { + std::vector<int> vec_a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> vec_b = importDefSigSpec(cell->getPort(ID::B), timestep); + + int a = ez->expression(ez->OpOr, vec_a); + int b = ez->expression(ez->OpOr, vec_b); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + + if (cell->type == ID($logic_and)) + ez->SET(ez->expression(ez->OpAnd, a, b), yy.at(0)); + else + ez->SET(ez->expression(ez->OpOr, a, b), yy.at(0)); + for (size_t i = 1; i < y.size(); i++) + ez->SET(ez->CONST_FALSE, yy.at(i)); + + if (model_undef) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + + int a0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_a), ez->expression(ezSAT::OpOr, undef_a))); + int b0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_b), ez->expression(ezSAT::OpOr, undef_b))); + int a1 = ez->expression(ezSAT::OpOr, ez->vec_and(vec_a, ez->vec_not(undef_a))); + int b1 = ez->expression(ezSAT::OpOr, ez->vec_and(vec_b, ez->vec_not(undef_b))); + int aX = ez->expression(ezSAT::OpOr, undef_a); + int bX = ez->expression(ezSAT::OpOr, undef_b); + + if (cell->type == ID($logic_and)) + ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a1, b1)), ez->NOT(a0), ez->NOT(b0)), undef_y.at(0)); + else if (cell->type == ID($logic_or)) + ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a0, b0)), ez->NOT(a1), ez->NOT(b1)), undef_y.at(0)); + else + log_abort(); + + for (size_t i = 1; i < undef_y.size(); i++) + ez->SET(ez->CONST_FALSE, undef_y.at(i)); + + undefGating(y, yy, undef_y); + } + return true; + } + + if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) + { + bool is_signed = cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool(); + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidth(a, b, cell); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + + if (model_undef && cell->type.in(ID($eqx), ID($nex))) { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + extendSignalWidth(undef_a, undef_b, cell, true); + a = ez->vec_or(a, undef_a); + b = ez->vec_or(b, undef_b); + } + + if (cell->type == ID($lt)) + ez->SET(is_signed ? ez->vec_lt_signed(a, b) : ez->vec_lt_unsigned(a, b), yy.at(0)); + if (cell->type == ID($le)) + ez->SET(is_signed ? ez->vec_le_signed(a, b) : ez->vec_le_unsigned(a, b), yy.at(0)); + if (cell->type.in(ID($eq), ID($eqx))) + ez->SET(ez->vec_eq(a, b), yy.at(0)); + if (cell->type.in(ID($ne), ID($nex))) + ez->SET(ez->vec_ne(a, b), yy.at(0)); + if (cell->type == ID($ge)) + ez->SET(is_signed ? ez->vec_ge_signed(a, b) : ez->vec_ge_unsigned(a, b), yy.at(0)); + if (cell->type == ID($gt)) + ez->SET(is_signed ? ez->vec_gt_signed(a, b) : ez->vec_gt_unsigned(a, b), yy.at(0)); + for (size_t i = 1; i < y.size(); i++) + ez->SET(ez->CONST_FALSE, yy.at(i)); + + if (model_undef && cell->type.in(ID($eqx), ID($nex))) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidth(undef_a, undef_b, cell, true); + + if (cell->type == ID($eqx)) + yy.at(0) = ez->AND(yy.at(0), ez->vec_eq(undef_a, undef_b)); + else + yy.at(0) = ez->OR(yy.at(0), ez->vec_ne(undef_a, undef_b)); + + for (size_t i = 0; i < y.size(); i++) + ez->SET(ez->CONST_FALSE, undef_y.at(i)); + + ez->assume(ez->vec_eq(y, yy)); + } + else if (model_undef && cell->type.in(ID($eq), ID($ne))) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidth(undef_a, undef_b, cell, true); + + int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); + int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); + int undef_any = ez->OR(undef_any_a, undef_any_b); + + std::vector<int> masked_a_bits = ez->vec_or(a, ez->vec_or(undef_a, undef_b)); + std::vector<int> masked_b_bits = ez->vec_or(b, ez->vec_or(undef_a, undef_b)); + + int masked_ne = ez->vec_ne(masked_a_bits, masked_b_bits); + int undef_y_bit = ez->AND(undef_any, ez->NOT(masked_ne)); + + for (size_t i = 1; i < undef_y.size(); i++) + ez->SET(ez->CONST_FALSE, undef_y.at(i)); + ez->SET(undef_y_bit, undef_y.at(0)); + + undefGating(y, yy, undef_y); + } + else + { + if (model_undef) { + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + undefGating(y, yy, undef_y); + } + log_assert(!model_undef || arith_undef_handled); + } + return true; + } + + if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + + int extend_bit = ez->CONST_FALSE; + + if (cell->parameters[ID::A_SIGNED].as_bool()) + extend_bit = a.back(); + + while (y.size() < a.size()) + y.push_back(ez->literal()); + while (y.size() > a.size()) + a.push_back(extend_bit); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + std::vector<int> shifted_a; + + if (cell->type.in( ID($shl), ID($sshl))) + shifted_a = ez->vec_shift_left(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); + + if (cell->type == ID($shr)) + shifted_a = ez->vec_shift_right(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); + + if (cell->type == ID($sshr)) + shifted_a = ez->vec_shift_right(a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE); + + if (cell->type.in(ID($shift), ID($shiftx))) + shifted_a = ez->vec_shift_right(a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); + + ez->assume(ez->vec_eq(shifted_a, yy)); + + if (model_undef) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + std::vector<int> undef_a_shifted; + + extend_bit = cell->type == ID($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE; + if (cell->parameters[ID::A_SIGNED].as_bool()) + extend_bit = undef_a.back(); + + while (undef_y.size() < undef_a.size()) + undef_y.push_back(ez->literal()); + while (undef_y.size() > undef_a.size()) + undef_a.push_back(extend_bit); + + if (cell->type.in(ID($shl), ID($sshl))) + undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); + + if (cell->type == ID($shr)) + undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); + + if (cell->type == ID($sshr)) + undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE); + + if (cell->type == ID($shift)) + undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); + + if (cell->type == ID($shiftx)) + undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE); + + int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); + std::vector<int> undef_all_y_bits(undef_y.size(), undef_any_b); + ez->assume(ez->vec_eq(ez->vec_or(undef_a_shifted, undef_all_y_bits), undef_y)); + undefGating(y, yy, undef_y); + } + return true; + } + + if (cell->type == ID($mul)) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidth(a, b, y, cell); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + + std::vector<int> tmp(a.size(), ez->CONST_FALSE); + for (int i = 0; i < int(a.size()); i++) + { + std::vector<int> shifted_a(a.size(), ez->CONST_FALSE); + for (int j = i; j < int(a.size()); j++) + shifted_a.at(j) = a.at(j-i); + tmp = ez->vec_ite(b.at(i), ez->vec_add(tmp, shifted_a), tmp); + } + ez->assume(ez->vec_eq(tmp, yy)); + + if (model_undef) { + log_assert(arith_undef_handled); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + undefGating(y, yy, undef_y); + } + return true; + } + + if (cell->type == ID($macc)) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + + Macc macc; + macc.from_cell(cell); + + std::vector<int> tmp(GetSize(y), ez->CONST_FALSE); + + for (auto &port : macc.ports) + { + std::vector<int> in_a = importDefSigSpec(port.in_a, timestep); + std::vector<int> in_b = importDefSigSpec(port.in_b, timestep); + + while (GetSize(in_a) < GetSize(y)) + in_a.push_back(port.is_signed && !in_a.empty() ? in_a.back() : ez->CONST_FALSE); + in_a.resize(GetSize(y)); + + if (GetSize(in_b)) + { + while (GetSize(in_b) < GetSize(y)) + in_b.push_back(port.is_signed && !in_b.empty() ? in_b.back() : ez->CONST_FALSE); + in_b.resize(GetSize(y)); + + for (int i = 0; i < GetSize(in_b); i++) { + std::vector<int> shifted_a(in_a.size(), ez->CONST_FALSE); + for (int j = i; j < int(in_a.size()); j++) + shifted_a.at(j) = in_a.at(j-i); + if (port.do_subtract) + tmp = ez->vec_ite(in_b.at(i), ez->vec_sub(tmp, shifted_a), tmp); + else + tmp = ez->vec_ite(in_b.at(i), ez->vec_add(tmp, shifted_a), tmp); + } + } + else + { + if (port.do_subtract) + tmp = ez->vec_sub(tmp, in_a); + else + tmp = ez->vec_add(tmp, in_a); + } + } + + for (int i = 0; i < GetSize(b); i++) { + std::vector<int> val(GetSize(y), ez->CONST_FALSE); + val.at(0) = b.at(i); + tmp = ez->vec_add(tmp, val); + } + + if (model_undef) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + + int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); + int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); + + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + ez->assume(ez->vec_eq(undef_y, std::vector<int>(GetSize(y), ez->OR(undef_any_a, undef_any_b)))); + + undefGating(y, tmp, undef_y); + } + else + ez->assume(ez->vec_eq(y, tmp)); + + return true; + } + + if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidth(a, b, y, cell); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + + std::vector<int> a_u, b_u; + if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) { + a_u = ez->vec_ite(a.back(), ez->vec_neg(a), a); + b_u = ez->vec_ite(b.back(), ez->vec_neg(b), b); + } else { + a_u = a; + b_u = b; + } + + std::vector<int> chain_buf = a_u; + std::vector<int> y_u(a_u.size(), ez->CONST_FALSE); + for (int i = int(a.size())-1; i >= 0; i--) + { + chain_buf.insert(chain_buf.end(), chain_buf.size(), ez->CONST_FALSE); + + std::vector<int> b_shl(i, ez->CONST_FALSE); + b_shl.insert(b_shl.end(), b_u.begin(), b_u.end()); + b_shl.insert(b_shl.end(), chain_buf.size()-b_shl.size(), ez->CONST_FALSE); + + y_u.at(i) = ez->vec_ge_unsigned(chain_buf, b_shl); + chain_buf = ez->vec_ite(y_u.at(i), ez->vec_sub(chain_buf, b_shl), chain_buf); + + chain_buf.erase(chain_buf.begin() + a_u.size(), chain_buf.end()); + } + + std::vector<int> y_tmp = ignore_div_by_zero ? yy : ez->vec_var(y.size()); + + // modulo calculation + std::vector<int> modulo_trunc; + int floored_eq_trunc; + if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) { + modulo_trunc = ez->vec_ite(a.back(), ez->vec_neg(chain_buf), chain_buf); + // floor == trunc when sgn(a) == sgn(b) or trunc == 0 + floored_eq_trunc = ez->OR(ez->IFF(a.back(), b.back()), ez->NOT(ez->expression(ezSAT::OpOr, modulo_trunc))); + } else { + modulo_trunc = chain_buf; + floored_eq_trunc = ez->CONST_TRUE; + } + + if (cell->type == ID($div)) { + if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) + ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u))); + else + ez->assume(ez->vec_eq(y_tmp, y_u)); + } else if (cell->type == ID($mod)) { + ez->assume(ez->vec_eq(y_tmp, modulo_trunc)); + } else if (cell->type == ID($divfloor)) { + if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) + ez->assume(ez->vec_eq(y_tmp, ez->vec_ite( + ez->XOR(a.back(), b.back()), + ez->vec_neg(ez->vec_ite( + ez->vec_reduce_or(modulo_trunc), + ez->vec_add(y_u, ez->vec_const_unsigned(1, y_u.size())), + y_u + )), + y_u + ))); + else + ez->assume(ez->vec_eq(y_tmp, y_u)); + } else if (cell->type == ID($modfloor)) { + ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(floored_eq_trunc, modulo_trunc, ez->vec_add(modulo_trunc, b)))); + } + + if (ignore_div_by_zero) { + ez->assume(ez->expression(ezSAT::OpOr, b)); + } else { + std::vector<int> div_zero_result; + if (cell->type.in(ID($div), ID($divfloor))) { + if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) { + std::vector<int> all_ones(y.size(), ez->CONST_TRUE); + std::vector<int> only_first_one(y.size(), ez->CONST_FALSE); + only_first_one.at(0) = ez->CONST_TRUE; + div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones); + } else { + div_zero_result.insert(div_zero_result.end(), cell->getPort(ID::A).size(), ez->CONST_TRUE); + div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE); + } + } else if (cell->type.in(ID($mod), ID($modfloor))) { + // a mod 0 = a + int copy_a_bits = min(cell->getPort(ID::A).size(), cell->getPort(ID::B).size()); + div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); + if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) + div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back()); + else + div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE); + } + ez->assume(ez->vec_eq(yy, ez->vec_ite(ez->expression(ezSAT::OpOr, b), y_tmp, div_zero_result))); + } + + if (model_undef) { + log_assert(arith_undef_handled); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + undefGating(y, yy, undef_y); + } + return true; + } + + if (cell->type == ID($lut)) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + + std::vector<int> lut; + for (auto bit : cell->getParam(ID::LUT).bits) + lut.push_back(bit == State::S1 ? ez->CONST_TRUE : ez->CONST_FALSE); + while (GetSize(lut) < (1 << GetSize(a))) + lut.push_back(ez->CONST_FALSE); + lut.resize(1 << GetSize(a)); + + if (model_undef) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> t(lut), u(GetSize(t), ez->CONST_FALSE); + + for (int i = GetSize(a)-1; i >= 0; i--) + { + std::vector<int> t0(t.begin(), t.begin() + GetSize(t)/2); + std::vector<int> t1(t.begin() + GetSize(t)/2, t.end()); + + std::vector<int> u0(u.begin(), u.begin() + GetSize(u)/2); + std::vector<int> u1(u.begin() + GetSize(u)/2, u.end()); + + t = ez->vec_ite(a[i], t1, t0); + u = ez->vec_ite(undef_a[i], ez->vec_or(ez->vec_xor(t0, t1), ez->vec_or(u0, u1)), ez->vec_ite(a[i], u1, u0)); + } + + log_assert(GetSize(t) == 1); + log_assert(GetSize(u) == 1); + undefGating(y, t, u); + ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort(ID::Y), timestep), u)); + } + else + { + std::vector<int> t = lut; + for (int i = GetSize(a)-1; i >= 0; i--) + { + std::vector<int> t0(t.begin(), t.begin() + GetSize(t)/2); + std::vector<int> t1(t.begin() + GetSize(t)/2, t.end()); + t = ez->vec_ite(a[i], t1, t0); + } + + log_assert(GetSize(t) == 1); + ez->assume(ez->vec_eq(y, t)); + } + return true; + } + + if (cell->type == ID($sop)) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0); + + int width = cell->getParam(ID::WIDTH).as_int(); + int depth = cell->getParam(ID::DEPTH).as_int(); + + vector<State> table_raw = cell->getParam(ID::TABLE).bits; + while (GetSize(table_raw) < 2*width*depth) + table_raw.push_back(State::S0); + + vector<vector<int>> table(depth); + + for (int i = 0; i < depth; i++) + for (int j = 0; j < width; j++) + { + bool pat0 = (table_raw[2*width*i + 2*j + 0] == State::S1); + bool pat1 = (table_raw[2*width*i + 2*j + 1] == State::S1); + + if (pat0 && !pat1) + table.at(i).push_back(0); + else if (!pat0 && pat1) + table.at(i).push_back(1); + else + table.at(i).push_back(-1); + } + + if (model_undef) + { + std::vector<int> products, undef_products; + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0); + + for (int i = 0; i < depth; i++) + { + std::vector<int> cmp_a, cmp_ua, cmp_b; + + for (int j = 0; j < width; j++) + if (table.at(i).at(j) >= 0) { + cmp_a.push_back(a.at(j)); + cmp_ua.push_back(undef_a.at(j)); + cmp_b.push_back(table.at(i).at(j) ? ez->CONST_TRUE : ez->CONST_FALSE); + } + + std::vector<int> masked_a = ez->vec_or(cmp_a, cmp_ua); + std::vector<int> masked_b = ez->vec_or(cmp_b, cmp_ua); + + int masked_eq = ez->vec_eq(masked_a, masked_b); + int any_undef = ez->expression(ezSAT::OpOr, cmp_ua); + + undef_products.push_back(ez->AND(any_undef, masked_eq)); + products.push_back(ez->AND(ez->NOT(any_undef), masked_eq)); + } + + int yy = ez->expression(ezSAT::OpOr, products); + ez->SET(undef_y, ez->AND(ez->NOT(yy), ez->expression(ezSAT::OpOr, undef_products))); + undefGating(y, yy, undef_y); + } + else + { + std::vector<int> products; + + for (int i = 0; i < depth; i++) + { + std::vector<int> cmp_a, cmp_b; + + for (int j = 0; j < width; j++) + if (table.at(i).at(j) >= 0) { + cmp_a.push_back(a.at(j)); + cmp_b.push_back(table.at(i).at(j) ? ez->CONST_TRUE : ez->CONST_FALSE); + } + + products.push_back(ez->vec_eq(cmp_a, cmp_b)); + } + + ez->SET(y, ez->expression(ezSAT::OpOr, products)); + } + + return true; + } + + if (cell->type == ID($fa)) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> c = importDefSigSpec(cell->getPort(ID::C), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + std::vector<int> x = importDefSigSpec(cell->getPort(ID::X), timestep); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + std::vector<int> xx = model_undef ? ez->vec_var(x.size()) : x; + + std::vector<int> t1 = ez->vec_xor(a, b); + ez->assume(ez->vec_eq(yy, ez->vec_xor(t1, c))); + + std::vector<int> t2 = ez->vec_and(a, b); + std::vector<int> t3 = ez->vec_and(c, t1); + ez->assume(ez->vec_eq(xx, ez->vec_or(t2, t3))); + + if (model_undef) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> undef_c = importUndefSigSpec(cell->getPort(ID::C), timestep); + + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID::X), timestep); + + ez->assume(ez->vec_eq(undef_y, ez->vec_or(ez->vec_or(undef_a, undef_b), undef_c))); + ez->assume(ez->vec_eq(undef_x, undef_y)); + + undefGating(y, yy, undef_y); + undefGating(x, xx, undef_x); + } + return true; + } + + if (cell->type == ID($lcu)) + { + std::vector<int> p = importDefSigSpec(cell->getPort(ID::P), timestep); + std::vector<int> g = importDefSigSpec(cell->getPort(ID::G), timestep); + std::vector<int> ci = importDefSigSpec(cell->getPort(ID::CI), timestep); + std::vector<int> co = importDefSigSpec(cell->getPort(ID::CO), timestep); + + std::vector<int> yy = model_undef ? ez->vec_var(co.size()) : co; + + for (int i = 0; i < GetSize(co); i++) + ez->SET(yy[i], ez->OR(g[i], ez->AND(p[i], i ? yy[i-1] : ci[0]))); + + if (model_undef) + { + std::vector<int> undef_p = importUndefSigSpec(cell->getPort(ID::P), timestep); + std::vector<int> undef_g = importUndefSigSpec(cell->getPort(ID::G), timestep); + std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID::CI), timestep); + std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID::CO), timestep); + + int undef_any_p = ez->expression(ezSAT::OpOr, undef_p); + int undef_any_g = ez->expression(ezSAT::OpOr, undef_g); + int undef_any_ci = ez->expression(ezSAT::OpOr, undef_ci); + int undef_co_bit = ez->OR(undef_any_p, undef_any_g, undef_any_ci); + + std::vector<int> undef_co_bits(undef_co.size(), undef_co_bit); + ez->assume(ez->vec_eq(undef_co_bits, undef_co)); + + undefGating(co, yy, undef_co); + } + return true; + } + + if (cell->type == ID($alu)) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + std::vector<int> x = importDefSigSpec(cell->getPort(ID::X), timestep); + std::vector<int> ci = importDefSigSpec(cell->getPort(ID::CI), timestep); + std::vector<int> bi = importDefSigSpec(cell->getPort(ID::BI), timestep); + std::vector<int> co = importDefSigSpec(cell->getPort(ID::CO), timestep); + + extendSignalWidth(a, b, y, cell); + extendSignalWidth(a, b, x, cell); + extendSignalWidth(a, b, co, cell); + + std::vector<int> def_y = model_undef ? ez->vec_var(y.size()) : y; + std::vector<int> def_x = model_undef ? ez->vec_var(x.size()) : x; + std::vector<int> def_co = model_undef ? ez->vec_var(co.size()) : co; + + log_assert(GetSize(y) == GetSize(x)); + log_assert(GetSize(y) == GetSize(co)); + log_assert(GetSize(ci) == 1); + log_assert(GetSize(bi) == 1); + + for (int i = 0; i < GetSize(y); i++) + { + int s1 = a.at(i), s2 = ez->XOR(b.at(i), bi.at(0)), s3 = i ? co.at(i-1) : ci.at(0); + ez->SET(def_x.at(i), ez->XOR(s1, s2)); + ez->SET(def_y.at(i), ez->XOR(def_x.at(i), s3)); + ez->SET(def_co.at(i), ez->OR(ez->AND(s1, s2), ez->AND(s1, s3), ez->AND(s2, s3))); + } + + if (model_undef) + { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID::CI), timestep); + std::vector<int> undef_bi = importUndefSigSpec(cell->getPort(ID::BI), timestep); + + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID::X), timestep); + std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID::CO), timestep); + + extendSignalWidth(undef_a, undef_b, undef_y, cell); + extendSignalWidth(undef_a, undef_b, undef_x, cell); + extendSignalWidth(undef_a, undef_b, undef_co, cell); + + std::vector<int> all_inputs_undef; + all_inputs_undef.insert(all_inputs_undef.end(), undef_a.begin(), undef_a.end()); + all_inputs_undef.insert(all_inputs_undef.end(), undef_b.begin(), undef_b.end()); + all_inputs_undef.insert(all_inputs_undef.end(), undef_ci.begin(), undef_ci.end()); + all_inputs_undef.insert(all_inputs_undef.end(), undef_bi.begin(), undef_bi.end()); + int undef_any = ez->expression(ezSAT::OpOr, all_inputs_undef); + + for (int i = 0; i < GetSize(undef_y); i++) { + ez->SET(undef_y.at(i), undef_any); + ez->SET(undef_x.at(i), ez->OR(undef_a.at(i), undef_b.at(i), undef_bi.at(0))); + ez->SET(undef_co.at(i), undef_any); + } + + undefGating(y, def_y, undef_y); + undefGating(x, def_x, undef_x); + undefGating(co, def_co, undef_co); + } + return true; + } + + if (cell->type == ID($slice)) + { + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec y = cell->getPort(ID::Y); + ez->assume(signals_eq(a.extract(cell->parameters.at(ID::OFFSET).as_int(), y.size()), y, timestep)); + return true; + } + + if (cell->type == ID($concat)) + { + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec b = cell->getPort(ID::B); + RTLIL::SigSpec y = cell->getPort(ID::Y); + + RTLIL::SigSpec ab = a; + ab.append(b); + + ez->assume(signals_eq(ab, y, timestep)); + return true; + } + + if (timestep > 0 && RTLIL::builtin_ff_cell_types().count(cell->type)) + { + FfData ff(nullptr, cell); + + // Latches and FFs with async inputs are not supported — use clk2fflogic or async2sync first. + if (!ff.has_d || ff.has_arst || ff.has_sr || (ff.has_en && !ff.has_clk)) + return false; + + if (timestep == 1) + { + initial_state.add((*sigmap)(cell->getPort(ID::Q))); + } + else + { + std::vector<int> d = importDefSigSpec(cell->getPort(ID::D), timestep-1); + std::vector<int> undef_d; + if (model_undef) + undef_d = importUndefSigSpec(cell->getPort(ID::D), timestep-1); + if (ff.has_srst && ff.has_en && ff.ce_over_srst) { + int srst = importDefSigSpec(ff.sig_srst, timestep-1).at(0); + std::vector<int> rval = importDefSigSpec(ff.val_srst, timestep-1); + int undef_srst; + std::vector<int> undef_rval; + if (model_undef) { + undef_srst = importUndefSigSpec(ff.sig_srst, timestep-1).at(0); + undef_rval = importUndefSigSpec(ff.val_srst, timestep-1); + } + if (ff.pol_srst) + std::tie(d, undef_d) = mux(srst, undef_srst, d, undef_d, rval, undef_rval); + else + std::tie(d, undef_d) = mux(srst, undef_srst, rval, undef_rval, d, undef_d); + } + if (ff.has_en) { + int en = importDefSigSpec(ff.sig_en, timestep-1).at(0); + std::vector<int> old_q = importDefSigSpec(ff.sig_q, timestep-1); + int undef_en; + std::vector<int> undef_old_q; + if (model_undef) { + undef_en = importUndefSigSpec(ff.sig_en, timestep-1).at(0); + undef_old_q = importUndefSigSpec(ff.sig_q, timestep-1); + } + if (ff.pol_en) + std::tie(d, undef_d) = mux(en, undef_en, old_q, undef_old_q, d, undef_d); + else + std::tie(d, undef_d) = mux(en, undef_en, d, undef_d, old_q, undef_old_q); + } + if (ff.has_srst && !(ff.has_en && ff.ce_over_srst)) { + int srst = importDefSigSpec(ff.sig_srst, timestep-1).at(0); + std::vector<int> rval = importDefSigSpec(ff.val_srst, timestep-1); + int undef_srst; + std::vector<int> undef_rval; + if (model_undef) { + undef_srst = importUndefSigSpec(ff.sig_srst, timestep-1).at(0); + undef_rval = importUndefSigSpec(ff.val_srst, timestep-1); + } + if (ff.pol_srst) + std::tie(d, undef_d) = mux(srst, undef_srst, d, undef_d, rval, undef_rval); + else + std::tie(d, undef_d) = mux(srst, undef_srst, rval, undef_rval, d, undef_d); + } + std::vector<int> q = importDefSigSpec(cell->getPort(ID::Q), timestep); + + std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q; + ez->assume(ez->vec_eq(d, qq)); + + if (model_undef) + { + std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID::Q), timestep); + + ez->assume(ez->vec_eq(undef_d, undef_q)); + undefGating(q, qq, undef_q); + } + } + return true; + } + + if (cell->type == ID($anyconst)) + { + if (timestep < 2) + return true; + + std::vector<int> d = importDefSigSpec(cell->getPort(ID::Y), timestep-1); + std::vector<int> q = importDefSigSpec(cell->getPort(ID::Y), timestep); + + std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q; + ez->assume(ez->vec_eq(d, qq)); + + if (model_undef) + { + std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID::Y), timestep-1); + std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID::Y), timestep); + + ez->assume(ez->vec_eq(undef_d, undef_q)); + undefGating(q, qq, undef_q); + } + return true; + } + + if (cell->type == ID($anyseq)) + { + return true; + } + + if (cell->type.in(ID($_BUF_), ID($equiv))) + { + std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidthUnary(a, y, cell); + + std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; + ez->assume(ez->vec_eq(a, yy)); + + if (model_undef) { + std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + extendSignalWidthUnary(undef_a, undef_y, cell, false); + ez->assume(ez->vec_eq(undef_a, undef_y)); + undefGating(y, yy, undef_y); + } + return true; + } + + if (cell->type == ID($initstate)) + { + auto key = make_pair(prefix, timestep); + if (initstates.count(key) == 0) + initstates[key] = false; + + std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); + log_assert(GetSize(y) == 1); + ez->SET(y[0], initstates[key] ? ez->CONST_TRUE : ez->CONST_FALSE); + + if (model_undef) { + std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + log_assert(GetSize(undef_y) == 1); + ez->SET(undef_y[0], ez->CONST_FALSE); + } + + return true; + } + + if (cell->type == ID($assert)) + { + std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); + asserts_a[pf].append((*sigmap)(cell->getPort(ID::A))); + asserts_en[pf].append((*sigmap)(cell->getPort(ID::EN))); + return true; + } + + if (cell->type == ID($assume)) + { + std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); + assumes_a[pf].append((*sigmap)(cell->getPort(ID::A))); + assumes_en[pf].append((*sigmap)(cell->getPort(ID::EN))); + return true; + } + + // Unsupported internal cell types: $pow $fsm $mem* + // .. and all sequential cells with asynchronous inputs + return false; +} diff --git a/kernel/satgen.h b/kernel/satgen.h index 3929a8708..cf2db733f 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -262,6 +262,18 @@ struct SatGen } } + std::pair<std::vector<int>, std::vector<int>> mux(int s, int undef_s, const std::vector<int> &a, const std::vector<int> &undef_a, const std::vector<int> &b, const std::vector<int> &undef_b) { + std::vector<int> res; + std::vector<int> undef_res; + res = ez->vec_ite(s, b, a); + if (model_undef) { + std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b)); + std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b)); + undef_res = ez->vec_ite(undef_s, undef_ab, ez->vec_ite(s, undef_b, undef_a)); + } + return std::make_pair(res, undef_res); + } + void undefGating(int y, int yy, int undef) { ez->assume(ez->OR(undef, ez->IFF(y, yy))); @@ -274,1171 +286,7 @@ struct SatGen initstates[key] = true; } - bool importCell(RTLIL::Cell *cell, int timestep = -1) - { - bool arith_undef_handled = false; - bool is_arith_compare = cell->type.in(ID($lt), ID($le), ID($ge), ID($gt)); - - if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor)) || is_arith_compare)) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - if (is_arith_compare) - extendSignalWidth(undef_a, undef_b, cell, true); - else - extendSignalWidth(undef_a, undef_b, undef_y, cell, true); - - int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); - int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); - int undef_y_bit = ez->OR(undef_any_a, undef_any_b); - - if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) { - std::vector<int> b = importSigSpec(cell->getPort(ID::B), timestep); - undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b))); - } - - if (is_arith_compare) { - for (size_t i = 1; i < undef_y.size(); i++) - ez->SET(ez->CONST_FALSE, undef_y.at(i)); - ez->SET(undef_y_bit, undef_y.at(0)); - } else { - std::vector<int> undef_y_bits(undef_y.size(), undef_y_bit); - ez->assume(ez->vec_eq(undef_y_bits, undef_y)); - } - - arith_undef_handled = true; - } - - if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), - ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($sub))) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidth(a, b, y, cell); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - - if (cell->type.in(ID($and), ID($_AND_))) - ez->assume(ez->vec_eq(ez->vec_and(a, b), yy)); - if (cell->type == ID($_NAND_)) - ez->assume(ez->vec_eq(ez->vec_not(ez->vec_and(a, b)), yy)); - if (cell->type.in(ID($or), ID($_OR_))) - ez->assume(ez->vec_eq(ez->vec_or(a, b), yy)); - if (cell->type == ID($_NOR_)) - ez->assume(ez->vec_eq(ez->vec_not(ez->vec_or(a, b)), yy)); - if (cell->type.in(ID($xor), ID($_XOR_))) - ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy)); - if (cell->type.in(ID($xnor), ID($_XNOR_))) - ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(a, b)), yy)); - if (cell->type == ID($_ANDNOT_)) - ez->assume(ez->vec_eq(ez->vec_and(a, ez->vec_not(b)), yy)); - if (cell->type == ID($_ORNOT_)) - ez->assume(ez->vec_eq(ez->vec_or(a, ez->vec_not(b)), yy)); - if (cell->type == ID($add)) - ez->assume(ez->vec_eq(ez->vec_add(a, b), yy)); - if (cell->type == ID($sub)) - ez->assume(ez->vec_eq(ez->vec_sub(a, b), yy)); - - if (model_undef && !arith_undef_handled) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidth(undef_a, undef_b, undef_y, cell, false); - - if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_))) { - std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)); - std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b)); - std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b0))); - ez->assume(ez->vec_eq(yX, undef_y)); - } - else if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_))) { - std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a)); - std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b)); - std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b1))); - ez->assume(ez->vec_eq(yX, undef_y)); - } - else if (cell->type.in(ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_))) { - std::vector<int> yX = ez->vec_or(undef_a, undef_b); - ez->assume(ez->vec_eq(yX, undef_y)); - } - else if (cell->type == ID($_ANDNOT_)) { - std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)); - std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b)); - std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b1))); - ez->assume(ez->vec_eq(yX, undef_y)); - } - - else if (cell->type == ID($_ORNOT_)) { - std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a)); - std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b)); - std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b0))); - ez->assume(ez->vec_eq(yX, undef_y)); - } - else - log_abort(); - - undefGating(y, yy, undef_y); - } - else if (model_undef) - { - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - undefGating(y, yy, undef_y); - } - return true; - } - - if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) - { - bool aoi_mode = cell->type.in(ID($_AOI3_), ID($_AOI4_)); - bool three_mode = cell->type.in(ID($_AOI3_), ID($_OAI3_)); - - int a = importDefSigSpec(cell->getPort(ID::A), timestep).at(0); - int b = importDefSigSpec(cell->getPort(ID::B), timestep).at(0); - int c = importDefSigSpec(cell->getPort(ID::C), timestep).at(0); - int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort(ID::D), timestep).at(0); - int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0); - int yy = model_undef ? ez->literal() : y; - - if (cell->type.in(ID($_AOI3_), ID($_AOI4_))) - ez->assume(ez->IFF(ez->NOT(ez->OR(ez->AND(a, b), ez->AND(c, d))), yy)); - else - ez->assume(ez->IFF(ez->NOT(ez->AND(ez->OR(a, b), ez->OR(c, d))), yy)); - - if (model_undef) - { - int undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep).at(0); - int undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep).at(0); - int undef_c = importUndefSigSpec(cell->getPort(ID::C), timestep).at(0); - int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort(ID::D), timestep).at(0); - int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0); - - if (aoi_mode) - { - int a0 = ez->AND(ez->NOT(a), ez->NOT(undef_a)); - int b0 = ez->AND(ez->NOT(b), ez->NOT(undef_b)); - int c0 = ez->AND(ez->NOT(c), ez->NOT(undef_c)); - int d0 = ez->AND(ez->NOT(d), ez->NOT(undef_d)); - - int ab = ez->AND(a, b), cd = ez->AND(c, d); - int undef_ab = ez->AND(ez->OR(undef_a, undef_b), ez->NOT(ez->OR(a0, b0))); - int undef_cd = ez->AND(ez->OR(undef_c, undef_d), ez->NOT(ez->OR(c0, d0))); - - int ab1 = ez->AND(ab, ez->NOT(undef_ab)); - int cd1 = ez->AND(cd, ez->NOT(undef_cd)); - int yX = ez->AND(ez->OR(undef_ab, undef_cd), ez->NOT(ez->OR(ab1, cd1))); - - ez->assume(ez->IFF(yX, undef_y)); - } - else - { - int a1 = ez->AND(a, ez->NOT(undef_a)); - int b1 = ez->AND(b, ez->NOT(undef_b)); - int c1 = ez->AND(c, ez->NOT(undef_c)); - int d1 = ez->AND(d, ez->NOT(undef_d)); - - int ab = ez->OR(a, b), cd = ez->OR(c, d); - int undef_ab = ez->AND(ez->OR(undef_a, undef_b), ez->NOT(ez->OR(a1, b1))); - int undef_cd = ez->AND(ez->OR(undef_c, undef_d), ez->NOT(ez->OR(c1, d1))); - - int ab0 = ez->AND(ez->NOT(ab), ez->NOT(undef_ab)); - int cd0 = ez->AND(ez->NOT(cd), ez->NOT(undef_cd)); - int yX = ez->AND(ez->OR(undef_ab, undef_cd), ez->NOT(ez->OR(ab0, cd0))); - - ez->assume(ez->IFF(yX, undef_y)); - } - - undefGating(y, yy, undef_y); - } - - return true; - } - - if (cell->type.in(ID($_NOT_), ID($not))) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidthUnary(a, y, cell); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - ez->assume(ez->vec_eq(ez->vec_not(a), yy)); - - if (model_undef) { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidthUnary(undef_a, undef_y, cell, false); - ez->assume(ez->vec_eq(undef_a, undef_y)); - undefGating(y, yy, undef_y); - } - return true; - } - - if (cell->type.in(ID($_MUX_), ID($mux), ID($_NMUX_))) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> s = importDefSigSpec(cell->getPort(ID::S), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - if (cell->type == ID($_NMUX_)) - ez->assume(ez->vec_eq(ez->vec_not(ez->vec_ite(s.at(0), b, a)), yy)); - else - ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy)); - - if (model_undef) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID::S), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - - std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b)); - std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b)); - std::vector<int> yX = ez->vec_ite(undef_s.at(0), undef_ab, ez->vec_ite(s.at(0), undef_b, undef_a)); - ez->assume(ez->vec_eq(yX, undef_y)); - undefGating(y, yy, undef_y); - } - return true; - } - - if (cell->type == ID($pmux)) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> s = importDefSigSpec(cell->getPort(ID::S), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - - std::vector<int> tmp = a; - for (size_t i = 0; i < s.size(); i++) { - std::vector<int> part_of_b(b.begin()+i*a.size(), b.begin()+(i+1)*a.size()); - tmp = ez->vec_ite(s.at(i), part_of_b, tmp); - } - ez->assume(ez->vec_eq(tmp, yy)); - - if (model_undef) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID::S), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - - int maybe_a = ez->CONST_TRUE; - - std::vector<int> bits_set = std::vector<int>(undef_y.size(), ez->CONST_FALSE); - std::vector<int> bits_clr = std::vector<int>(undef_y.size(), ez->CONST_FALSE); - - for (size_t i = 0; i < s.size(); i++) - { - std::vector<int> part_of_b(b.begin()+i*a.size(), b.begin()+(i+1)*a.size()); - std::vector<int> part_of_undef_b(undef_b.begin()+i*a.size(), undef_b.begin()+(i+1)*a.size()); - - int maybe_s = ez->OR(s.at(i), undef_s.at(i)); - int sure_s = ez->AND(s.at(i), ez->NOT(undef_s.at(i))); - - maybe_a = ez->AND(maybe_a, ez->NOT(sure_s)); - - bits_set = ez->vec_ite(maybe_s, ez->vec_or(bits_set, ez->vec_or(part_of_b, part_of_undef_b)), bits_set); - bits_clr = ez->vec_ite(maybe_s, ez->vec_or(bits_clr, ez->vec_or(ez->vec_not(part_of_b), part_of_undef_b)), bits_clr); - } - - bits_set = ez->vec_ite(maybe_a, ez->vec_or(bits_set, ez->vec_or(bits_set, ez->vec_or(a, undef_a))), bits_set); - bits_clr = ez->vec_ite(maybe_a, ez->vec_or(bits_clr, ez->vec_or(bits_clr, ez->vec_or(ez->vec_not(a), undef_a))), bits_clr); - - ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(bits_set, bits_clr)), undef_y)); - undefGating(y, yy, undef_y); - } - return true; - } - - if (cell->type.in(ID($pos), ID($neg))) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidthUnary(a, y, cell); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - - if (cell->type == ID($pos)) { - ez->assume(ez->vec_eq(a, yy)); - } else { - std::vector<int> zero(a.size(), ez->CONST_FALSE); - ez->assume(ez->vec_eq(ez->vec_sub(zero, a), yy)); - } - - if (model_undef) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidthUnary(undef_a, undef_y, cell); - - if (cell->type == ID($pos)) { - ez->assume(ez->vec_eq(undef_a, undef_y)); - } else { - int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); - std::vector<int> undef_y_bits(undef_y.size(), undef_any_a); - ez->assume(ez->vec_eq(undef_y_bits, undef_y)); - } - - undefGating(y, yy, undef_y); - } - return true; - } - - if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - - if (cell->type == ID($reduce_and)) - ez->SET(ez->expression(ez->OpAnd, a), yy.at(0)); - if (cell->type.in(ID($reduce_or), ID($reduce_bool))) - ez->SET(ez->expression(ez->OpOr, a), yy.at(0)); - if (cell->type == ID($reduce_xor)) - ez->SET(ez->expression(ez->OpXor, a), yy.at(0)); - if (cell->type == ID($reduce_xnor)) - ez->SET(ez->NOT(ez->expression(ez->OpXor, a)), yy.at(0)); - if (cell->type == ID($logic_not)) - ez->SET(ez->NOT(ez->expression(ez->OpOr, a)), yy.at(0)); - for (size_t i = 1; i < y.size(); i++) - ez->SET(ez->CONST_FALSE, yy.at(i)); - - if (model_undef) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - int aX = ez->expression(ezSAT::OpOr, undef_a); - - if (cell->type == ID($reduce_and)) { - int a0 = ez->expression(ezSAT::OpOr, ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a))); - ez->assume(ez->IFF(ez->AND(ez->NOT(a0), aX), undef_y.at(0))); - } - else if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not))) { - int a1 = ez->expression(ezSAT::OpOr, ez->vec_and(a, ez->vec_not(undef_a))); - ez->assume(ez->IFF(ez->AND(ez->NOT(a1), aX), undef_y.at(0))); - } - else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { - ez->assume(ez->IFF(aX, undef_y.at(0))); - } else - log_abort(); - - for (size_t i = 1; i < undef_y.size(); i++) - ez->SET(ez->CONST_FALSE, undef_y.at(i)); - - undefGating(y, yy, undef_y); - } - return true; - } - - if (cell->type.in(ID($logic_and), ID($logic_or))) - { - std::vector<int> vec_a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> vec_b = importDefSigSpec(cell->getPort(ID::B), timestep); - - int a = ez->expression(ez->OpOr, vec_a); - int b = ez->expression(ez->OpOr, vec_b); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - - if (cell->type == ID($logic_and)) - ez->SET(ez->expression(ez->OpAnd, a, b), yy.at(0)); - else - ez->SET(ez->expression(ez->OpOr, a, b), yy.at(0)); - for (size_t i = 1; i < y.size(); i++) - ez->SET(ez->CONST_FALSE, yy.at(i)); - - if (model_undef) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - - int a0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_a), ez->expression(ezSAT::OpOr, undef_a))); - int b0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_b), ez->expression(ezSAT::OpOr, undef_b))); - int a1 = ez->expression(ezSAT::OpOr, ez->vec_and(vec_a, ez->vec_not(undef_a))); - int b1 = ez->expression(ezSAT::OpOr, ez->vec_and(vec_b, ez->vec_not(undef_b))); - int aX = ez->expression(ezSAT::OpOr, undef_a); - int bX = ez->expression(ezSAT::OpOr, undef_b); - - if (cell->type == ID($logic_and)) - ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a1, b1)), ez->NOT(a0), ez->NOT(b0)), undef_y.at(0)); - else if (cell->type == ID($logic_or)) - ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a0, b0)), ez->NOT(a1), ez->NOT(b1)), undef_y.at(0)); - else - log_abort(); - - for (size_t i = 1; i < undef_y.size(); i++) - ez->SET(ez->CONST_FALSE, undef_y.at(i)); - - undefGating(y, yy, undef_y); - } - return true; - } - - if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) - { - bool is_signed = cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool(); - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidth(a, b, cell); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - - if (model_undef && cell->type.in(ID($eqx), ID($nex))) { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - extendSignalWidth(undef_a, undef_b, cell, true); - a = ez->vec_or(a, undef_a); - b = ez->vec_or(b, undef_b); - } - - if (cell->type == ID($lt)) - ez->SET(is_signed ? ez->vec_lt_signed(a, b) : ez->vec_lt_unsigned(a, b), yy.at(0)); - if (cell->type == ID($le)) - ez->SET(is_signed ? ez->vec_le_signed(a, b) : ez->vec_le_unsigned(a, b), yy.at(0)); - if (cell->type.in(ID($eq), ID($eqx))) - ez->SET(ez->vec_eq(a, b), yy.at(0)); - if (cell->type.in(ID($ne), ID($nex))) - ez->SET(ez->vec_ne(a, b), yy.at(0)); - if (cell->type == ID($ge)) - ez->SET(is_signed ? ez->vec_ge_signed(a, b) : ez->vec_ge_unsigned(a, b), yy.at(0)); - if (cell->type == ID($gt)) - ez->SET(is_signed ? ez->vec_gt_signed(a, b) : ez->vec_gt_unsigned(a, b), yy.at(0)); - for (size_t i = 1; i < y.size(); i++) - ez->SET(ez->CONST_FALSE, yy.at(i)); - - if (model_undef && cell->type.in(ID($eqx), ID($nex))) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidth(undef_a, undef_b, cell, true); - - if (cell->type == ID($eqx)) - yy.at(0) = ez->AND(yy.at(0), ez->vec_eq(undef_a, undef_b)); - else - yy.at(0) = ez->OR(yy.at(0), ez->vec_ne(undef_a, undef_b)); - - for (size_t i = 0; i < y.size(); i++) - ez->SET(ez->CONST_FALSE, undef_y.at(i)); - - ez->assume(ez->vec_eq(y, yy)); - } - else if (model_undef && cell->type.in(ID($eq), ID($ne))) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidth(undef_a, undef_b, cell, true); - - int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); - int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); - int undef_any = ez->OR(undef_any_a, undef_any_b); - - std::vector<int> masked_a_bits = ez->vec_or(a, ez->vec_or(undef_a, undef_b)); - std::vector<int> masked_b_bits = ez->vec_or(b, ez->vec_or(undef_a, undef_b)); - - int masked_ne = ez->vec_ne(masked_a_bits, masked_b_bits); - int undef_y_bit = ez->AND(undef_any, ez->NOT(masked_ne)); - - for (size_t i = 1; i < undef_y.size(); i++) - ez->SET(ez->CONST_FALSE, undef_y.at(i)); - ez->SET(undef_y_bit, undef_y.at(0)); - - undefGating(y, yy, undef_y); - } - else - { - if (model_undef) { - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - undefGating(y, yy, undef_y); - } - log_assert(!model_undef || arith_undef_handled); - } - return true; - } - - if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - - int extend_bit = ez->CONST_FALSE; - - if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID::A_SIGNED].as_bool()) - extend_bit = a.back(); - - while (y.size() < a.size()) - y.push_back(ez->literal()); - while (y.size() > a.size()) - a.push_back(extend_bit); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - std::vector<int> shifted_a; - - if (cell->type.in( ID($shl), ID($sshl))) - shifted_a = ez->vec_shift_left(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); - - if (cell->type == ID($shr)) - shifted_a = ez->vec_shift_right(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); - - if (cell->type == ID($sshr)) - shifted_a = ez->vec_shift_right(a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE); - - if (cell->type.in(ID($shift), ID($shiftx))) - shifted_a = ez->vec_shift_right(a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); - - ez->assume(ez->vec_eq(shifted_a, yy)); - - if (model_undef) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - std::vector<int> undef_a_shifted; - - extend_bit = cell->type == ID($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE; - if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID::A_SIGNED].as_bool()) - extend_bit = undef_a.back(); - - while (undef_y.size() < undef_a.size()) - undef_y.push_back(ez->literal()); - while (undef_y.size() > undef_a.size()) - undef_a.push_back(extend_bit); - - if (cell->type.in(ID($shl), ID($sshl))) - undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); - - if (cell->type == ID($shr)) - undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); - - if (cell->type == ID($sshr)) - undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE); - - if (cell->type == ID($shift)) - undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); - - if (cell->type == ID($shiftx)) - undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE); - - int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); - std::vector<int> undef_all_y_bits(undef_y.size(), undef_any_b); - ez->assume(ez->vec_eq(ez->vec_or(undef_a_shifted, undef_all_y_bits), undef_y)); - undefGating(y, yy, undef_y); - } - return true; - } - - if (cell->type == ID($mul)) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidth(a, b, y, cell); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - - std::vector<int> tmp(a.size(), ez->CONST_FALSE); - for (int i = 0; i < int(a.size()); i++) - { - std::vector<int> shifted_a(a.size(), ez->CONST_FALSE); - for (int j = i; j < int(a.size()); j++) - shifted_a.at(j) = a.at(j-i); - tmp = ez->vec_ite(b.at(i), ez->vec_add(tmp, shifted_a), tmp); - } - ez->assume(ez->vec_eq(tmp, yy)); - - if (model_undef) { - log_assert(arith_undef_handled); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - undefGating(y, yy, undef_y); - } - return true; - } - - if (cell->type == ID($macc)) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - - Macc macc; - macc.from_cell(cell); - - std::vector<int> tmp(GetSize(y), ez->CONST_FALSE); - - for (auto &port : macc.ports) - { - std::vector<int> in_a = importDefSigSpec(port.in_a, timestep); - std::vector<int> in_b = importDefSigSpec(port.in_b, timestep); - - while (GetSize(in_a) < GetSize(y)) - in_a.push_back(port.is_signed && !in_a.empty() ? in_a.back() : ez->CONST_FALSE); - in_a.resize(GetSize(y)); - - if (GetSize(in_b)) - { - while (GetSize(in_b) < GetSize(y)) - in_b.push_back(port.is_signed && !in_b.empty() ? in_b.back() : ez->CONST_FALSE); - in_b.resize(GetSize(y)); - - for (int i = 0; i < GetSize(in_b); i++) { - std::vector<int> shifted_a(in_a.size(), ez->CONST_FALSE); - for (int j = i; j < int(in_a.size()); j++) - shifted_a.at(j) = in_a.at(j-i); - if (port.do_subtract) - tmp = ez->vec_ite(in_b.at(i), ez->vec_sub(tmp, shifted_a), tmp); - else - tmp = ez->vec_ite(in_b.at(i), ez->vec_add(tmp, shifted_a), tmp); - } - } - else - { - if (port.do_subtract) - tmp = ez->vec_sub(tmp, in_a); - else - tmp = ez->vec_add(tmp, in_a); - } - } - - for (int i = 0; i < GetSize(b); i++) { - std::vector<int> val(GetSize(y), ez->CONST_FALSE); - val.at(0) = b.at(i); - tmp = ez->vec_add(tmp, val); - } - - if (model_undef) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - - int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); - int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); - - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - ez->assume(ez->vec_eq(undef_y, std::vector<int>(GetSize(y), ez->OR(undef_any_a, undef_any_b)))); - - undefGating(y, tmp, undef_y); - } - else - ez->assume(ez->vec_eq(y, tmp)); - - return true; - } - - if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidth(a, b, y, cell); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - - std::vector<int> a_u, b_u; - if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) { - a_u = ez->vec_ite(a.back(), ez->vec_neg(a), a); - b_u = ez->vec_ite(b.back(), ez->vec_neg(b), b); - } else { - a_u = a; - b_u = b; - } - - std::vector<int> chain_buf = a_u; - std::vector<int> y_u(a_u.size(), ez->CONST_FALSE); - for (int i = int(a.size())-1; i >= 0; i--) - { - chain_buf.insert(chain_buf.end(), chain_buf.size(), ez->CONST_FALSE); - - std::vector<int> b_shl(i, ez->CONST_FALSE); - b_shl.insert(b_shl.end(), b_u.begin(), b_u.end()); - b_shl.insert(b_shl.end(), chain_buf.size()-b_shl.size(), ez->CONST_FALSE); - - y_u.at(i) = ez->vec_ge_unsigned(chain_buf, b_shl); - chain_buf = ez->vec_ite(y_u.at(i), ez->vec_sub(chain_buf, b_shl), chain_buf); - - chain_buf.erase(chain_buf.begin() + a_u.size(), chain_buf.end()); - } - - std::vector<int> y_tmp = ignore_div_by_zero ? yy : ez->vec_var(y.size()); - - // modulo calculation - std::vector<int> modulo_trunc; - int floored_eq_trunc; - if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) { - modulo_trunc = ez->vec_ite(a.back(), ez->vec_neg(chain_buf), chain_buf); - // floor == trunc when sgn(a) == sgn(b) or trunc == 0 - floored_eq_trunc = ez->OR(ez->IFF(a.back(), b.back()), ez->NOT(ez->expression(ezSAT::OpOr, modulo_trunc))); - } else { - modulo_trunc = chain_buf; - floored_eq_trunc = ez->CONST_TRUE; - } - - if (cell->type == ID($div)) { - if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) - ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u))); - else - ez->assume(ez->vec_eq(y_tmp, y_u)); - } else if (cell->type == ID($mod)) { - ez->assume(ez->vec_eq(y_tmp, modulo_trunc)); - } else if (cell->type == ID($divfloor)) { - if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) - ez->assume(ez->vec_eq(y_tmp, ez->vec_ite( - ez->XOR(a.back(), b.back()), - ez->vec_neg(ez->vec_ite( - ez->vec_reduce_or(modulo_trunc), - ez->vec_add(y_u, ez->vec_const_unsigned(1, y_u.size())), - y_u - )), - y_u - ))); - else - ez->assume(ez->vec_eq(y_tmp, y_u)); - } else if (cell->type == ID($modfloor)) { - ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(floored_eq_trunc, modulo_trunc, ez->vec_add(modulo_trunc, b)))); - } - - if (ignore_div_by_zero) { - ez->assume(ez->expression(ezSAT::OpOr, b)); - } else { - std::vector<int> div_zero_result; - if (cell->type.in(ID($div), ID($divfloor))) { - if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) { - std::vector<int> all_ones(y.size(), ez->CONST_TRUE); - std::vector<int> only_first_one(y.size(), ez->CONST_FALSE); - only_first_one.at(0) = ez->CONST_TRUE; - div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones); - } else { - div_zero_result.insert(div_zero_result.end(), cell->getPort(ID::A).size(), ez->CONST_TRUE); - div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE); - } - } else if (cell->type.in(ID($mod), ID($modfloor))) { - // a mod 0 = a - int copy_a_bits = min(cell->getPort(ID::A).size(), cell->getPort(ID::B).size()); - div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); - if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) - div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back()); - else - div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE); - } - ez->assume(ez->vec_eq(yy, ez->vec_ite(ez->expression(ezSAT::OpOr, b), y_tmp, div_zero_result))); - } - - if (model_undef) { - log_assert(arith_undef_handled); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - undefGating(y, yy, undef_y); - } - return true; - } - - if (cell->type == ID($lut)) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - - std::vector<int> lut; - for (auto bit : cell->getParam(ID::LUT).bits) - lut.push_back(bit == State::S1 ? ez->CONST_TRUE : ez->CONST_FALSE); - while (GetSize(lut) < (1 << GetSize(a))) - lut.push_back(ez->CONST_FALSE); - lut.resize(1 << GetSize(a)); - - if (model_undef) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> t(lut), u(GetSize(t), ez->CONST_FALSE); - - for (int i = GetSize(a)-1; i >= 0; i--) - { - std::vector<int> t0(t.begin(), t.begin() + GetSize(t)/2); - std::vector<int> t1(t.begin() + GetSize(t)/2, t.end()); - - std::vector<int> u0(u.begin(), u.begin() + GetSize(u)/2); - std::vector<int> u1(u.begin() + GetSize(u)/2, u.end()); - - t = ez->vec_ite(a[i], t1, t0); - u = ez->vec_ite(undef_a[i], ez->vec_or(ez->vec_xor(t0, t1), ez->vec_or(u0, u1)), ez->vec_ite(a[i], u1, u0)); - } - - log_assert(GetSize(t) == 1); - log_assert(GetSize(u) == 1); - undefGating(y, t, u); - ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort(ID::Y), timestep), u)); - } - else - { - std::vector<int> t = lut; - for (int i = GetSize(a)-1; i >= 0; i--) - { - std::vector<int> t0(t.begin(), t.begin() + GetSize(t)/2); - std::vector<int> t1(t.begin() + GetSize(t)/2, t.end()); - t = ez->vec_ite(a[i], t1, t0); - } - - log_assert(GetSize(t) == 1); - ez->assume(ez->vec_eq(y, t)); - } - return true; - } - - if (cell->type == ID($sop)) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0); - - int width = cell->getParam(ID::WIDTH).as_int(); - int depth = cell->getParam(ID::DEPTH).as_int(); - - vector<State> table_raw = cell->getParam(ID::TABLE).bits; - while (GetSize(table_raw) < 2*width*depth) - table_raw.push_back(State::S0); - - vector<vector<int>> table(depth); - - for (int i = 0; i < depth; i++) - for (int j = 0; j < width; j++) - { - bool pat0 = (table_raw[2*width*i + 2*j + 0] == State::S1); - bool pat1 = (table_raw[2*width*i + 2*j + 1] == State::S1); - - if (pat0 && !pat1) - table.at(i).push_back(0); - else if (!pat0 && pat1) - table.at(i).push_back(1); - else - table.at(i).push_back(-1); - } - - if (model_undef) - { - std::vector<int> products, undef_products; - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0); - - for (int i = 0; i < depth; i++) - { - std::vector<int> cmp_a, cmp_ua, cmp_b; - - for (int j = 0; j < width; j++) - if (table.at(i).at(j) >= 0) { - cmp_a.push_back(a.at(j)); - cmp_ua.push_back(undef_a.at(j)); - cmp_b.push_back(table.at(i).at(j) ? ez->CONST_TRUE : ez->CONST_FALSE); - } - - std::vector<int> masked_a = ez->vec_or(cmp_a, cmp_ua); - std::vector<int> masked_b = ez->vec_or(cmp_b, cmp_ua); - - int masked_eq = ez->vec_eq(masked_a, masked_b); - int any_undef = ez->expression(ezSAT::OpOr, cmp_ua); - - undef_products.push_back(ez->AND(any_undef, masked_eq)); - products.push_back(ez->AND(ez->NOT(any_undef), masked_eq)); - } - - int yy = ez->expression(ezSAT::OpOr, products); - ez->SET(undef_y, ez->AND(ez->NOT(yy), ez->expression(ezSAT::OpOr, undef_products))); - undefGating(y, yy, undef_y); - } - else - { - std::vector<int> products; - - for (int i = 0; i < depth; i++) - { - std::vector<int> cmp_a, cmp_b; - - for (int j = 0; j < width; j++) - if (table.at(i).at(j) >= 0) { - cmp_a.push_back(a.at(j)); - cmp_b.push_back(table.at(i).at(j) ? ez->CONST_TRUE : ez->CONST_FALSE); - } - - products.push_back(ez->vec_eq(cmp_a, cmp_b)); - } - - ez->SET(y, ez->expression(ezSAT::OpOr, products)); - } - - return true; - } - - if (cell->type == ID($fa)) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> c = importDefSigSpec(cell->getPort(ID::C), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - std::vector<int> x = importDefSigSpec(cell->getPort(ID::X), timestep); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - std::vector<int> xx = model_undef ? ez->vec_var(x.size()) : x; - - std::vector<int> t1 = ez->vec_xor(a, b); - ez->assume(ez->vec_eq(yy, ez->vec_xor(t1, c))); - - std::vector<int> t2 = ez->vec_and(a, b); - std::vector<int> t3 = ez->vec_and(c, t1); - ez->assume(ez->vec_eq(xx, ez->vec_or(t2, t3))); - - if (model_undef) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> undef_c = importUndefSigSpec(cell->getPort(ID::C), timestep); - - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID::X), timestep); - - ez->assume(ez->vec_eq(undef_y, ez->vec_or(ez->vec_or(undef_a, undef_b), undef_c))); - ez->assume(ez->vec_eq(undef_x, undef_y)); - - undefGating(y, yy, undef_y); - undefGating(x, xx, undef_x); - } - return true; - } - - if (cell->type == ID($lcu)) - { - std::vector<int> p = importDefSigSpec(cell->getPort(ID::P), timestep); - std::vector<int> g = importDefSigSpec(cell->getPort(ID::G), timestep); - std::vector<int> ci = importDefSigSpec(cell->getPort(ID::CI), timestep); - std::vector<int> co = importDefSigSpec(cell->getPort(ID::CO), timestep); - - std::vector<int> yy = model_undef ? ez->vec_var(co.size()) : co; - - for (int i = 0; i < GetSize(co); i++) - ez->SET(yy[i], ez->OR(g[i], ez->AND(p[i], i ? yy[i-1] : ci[0]))); - - if (model_undef) - { - std::vector<int> undef_p = importUndefSigSpec(cell->getPort(ID::P), timestep); - std::vector<int> undef_g = importUndefSigSpec(cell->getPort(ID::G), timestep); - std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID::CI), timestep); - std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID::CO), timestep); - - int undef_any_p = ez->expression(ezSAT::OpOr, undef_p); - int undef_any_g = ez->expression(ezSAT::OpOr, undef_g); - int undef_any_ci = ez->expression(ezSAT::OpOr, undef_ci); - int undef_co_bit = ez->OR(undef_any_p, undef_any_g, undef_any_ci); - - std::vector<int> undef_co_bits(undef_co.size(), undef_co_bit); - ez->assume(ez->vec_eq(undef_co_bits, undef_co)); - - undefGating(co, yy, undef_co); - } - return true; - } - - if (cell->type == ID($alu)) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - std::vector<int> x = importDefSigSpec(cell->getPort(ID::X), timestep); - std::vector<int> ci = importDefSigSpec(cell->getPort(ID::CI), timestep); - std::vector<int> bi = importDefSigSpec(cell->getPort(ID::BI), timestep); - std::vector<int> co = importDefSigSpec(cell->getPort(ID::CO), timestep); - - extendSignalWidth(a, b, y, cell); - extendSignalWidth(a, b, x, cell); - extendSignalWidth(a, b, co, cell); - - std::vector<int> def_y = model_undef ? ez->vec_var(y.size()) : y; - std::vector<int> def_x = model_undef ? ez->vec_var(x.size()) : x; - std::vector<int> def_co = model_undef ? ez->vec_var(co.size()) : co; - - log_assert(GetSize(y) == GetSize(x)); - log_assert(GetSize(y) == GetSize(co)); - log_assert(GetSize(ci) == 1); - log_assert(GetSize(bi) == 1); - - for (int i = 0; i < GetSize(y); i++) - { - int s1 = a.at(i), s2 = ez->XOR(b.at(i), bi.at(0)), s3 = i ? co.at(i-1) : ci.at(0); - ez->SET(def_x.at(i), ez->XOR(s1, s2)); - ez->SET(def_y.at(i), ez->XOR(def_x.at(i), s3)); - ez->SET(def_co.at(i), ez->OR(ez->AND(s1, s2), ez->AND(s1, s3), ez->AND(s2, s3))); - } - - if (model_undef) - { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); - std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID::CI), timestep); - std::vector<int> undef_bi = importUndefSigSpec(cell->getPort(ID::BI), timestep); - - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID::X), timestep); - std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID::CO), timestep); - - extendSignalWidth(undef_a, undef_b, undef_y, cell); - extendSignalWidth(undef_a, undef_b, undef_x, cell); - extendSignalWidth(undef_a, undef_b, undef_co, cell); - - std::vector<int> all_inputs_undef; - all_inputs_undef.insert(all_inputs_undef.end(), undef_a.begin(), undef_a.end()); - all_inputs_undef.insert(all_inputs_undef.end(), undef_b.begin(), undef_b.end()); - all_inputs_undef.insert(all_inputs_undef.end(), undef_ci.begin(), undef_ci.end()); - all_inputs_undef.insert(all_inputs_undef.end(), undef_bi.begin(), undef_bi.end()); - int undef_any = ez->expression(ezSAT::OpOr, all_inputs_undef); - - for (int i = 0; i < GetSize(undef_y); i++) { - ez->SET(undef_y.at(i), undef_any); - ez->SET(undef_x.at(i), ez->OR(undef_a.at(i), undef_b.at(i), undef_bi.at(0))); - ez->SET(undef_co.at(i), undef_any); - } - - undefGating(y, def_y, undef_y); - undefGating(x, def_x, undef_x); - undefGating(co, def_co, undef_co); - } - return true; - } - - if (cell->type == ID($slice)) - { - RTLIL::SigSpec a = cell->getPort(ID::A); - RTLIL::SigSpec y = cell->getPort(ID::Y); - ez->assume(signals_eq(a.extract(cell->parameters.at(ID::OFFSET).as_int(), y.size()), y, timestep)); - return true; - } - - if (cell->type == ID($concat)) - { - RTLIL::SigSpec a = cell->getPort(ID::A); - RTLIL::SigSpec b = cell->getPort(ID::B); - RTLIL::SigSpec y = cell->getPort(ID::Y); - - RTLIL::SigSpec ab = a; - ab.append(b); - - ez->assume(signals_eq(ab, y, timestep)); - return true; - } - - if (timestep > 0 && cell->type.in(ID($ff), ID($dff), ID($_FF_), ID($_DFF_N_), ID($_DFF_P_))) - { - if (timestep == 1) - { - initial_state.add((*sigmap)(cell->getPort(ID::Q))); - } - else - { - std::vector<int> d = importDefSigSpec(cell->getPort(ID::D), timestep-1); - std::vector<int> q = importDefSigSpec(cell->getPort(ID::Q), timestep); - - std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q; - ez->assume(ez->vec_eq(d, qq)); - - if (model_undef) - { - std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID::D), timestep-1); - std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID::Q), timestep); - - ez->assume(ez->vec_eq(undef_d, undef_q)); - undefGating(q, qq, undef_q); - } - } - return true; - } - - if (cell->type == ID($anyconst)) - { - if (timestep < 2) - return true; - - std::vector<int> d = importDefSigSpec(cell->getPort(ID::Y), timestep-1); - std::vector<int> q = importDefSigSpec(cell->getPort(ID::Y), timestep); - - std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q; - ez->assume(ez->vec_eq(d, qq)); - - if (model_undef) - { - std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID::Y), timestep-1); - std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID::Y), timestep); - - ez->assume(ez->vec_eq(undef_d, undef_q)); - undefGating(q, qq, undef_q); - } - return true; - } - - if (cell->type == ID($anyseq)) - { - return true; - } - - if (cell->type.in(ID($_BUF_), ID($equiv))) - { - std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidthUnary(a, y, cell); - - std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - ez->assume(ez->vec_eq(a, yy)); - - if (model_undef) { - std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - extendSignalWidthUnary(undef_a, undef_y, cell, false); - ez->assume(ez->vec_eq(undef_a, undef_y)); - undefGating(y, yy, undef_y); - } - return true; - } - - if (cell->type == ID($initstate)) - { - auto key = make_pair(prefix, timestep); - if (initstates.count(key) == 0) - initstates[key] = false; - - std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); - log_assert(GetSize(y) == 1); - ez->SET(y[0], initstates[key] ? ez->CONST_TRUE : ez->CONST_FALSE); - - if (model_undef) { - std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); - log_assert(GetSize(undef_y) == 1); - ez->SET(undef_y[0], ez->CONST_FALSE); - } - - return true; - } - - if (cell->type == ID($assert)) - { - std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); - asserts_a[pf].append((*sigmap)(cell->getPort(ID::A))); - asserts_en[pf].append((*sigmap)(cell->getPort(ID::EN))); - return true; - } - - if (cell->type == ID($assume)) - { - std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); - assumes_a[pf].append((*sigmap)(cell->getPort(ID::A))); - assumes_en[pf].append((*sigmap)(cell->getPort(ID::EN))); - return true; - } - - // Unsupported internal cell types: $pow $lut - // .. and all sequential cells except $dff and $_DFF_[NP]_ - return false; - } + bool importCell(RTLIL::Cell *cell, int timestep = -1); }; YOSYS_NAMESPACE_END diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 2ec3dca0c..dcaf364e9 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -89,6 +89,12 @@ bool memhasher_active = false; uint32_t memhasher_rng = 123456; std::vector<void*> memhasher_store; +std::string yosys_share_dirname; +std::string yosys_abc_executable; + +void init_share_dirname(); +void init_abc_executable_name(); + void memhasher_on() { #if defined(__linux__) || defined(__FreeBSD__) @@ -523,6 +529,8 @@ void yosys_setup() if(already_setup) return; already_setup = true; + init_share_dirname(); + init_abc_executable_name(); #define X(_id) RTLIL::ID::_id = "\\" # _id; #include "kernel/constids.inc" @@ -713,7 +721,7 @@ extern Tcl_Interp *yosys_get_tcl_interp() struct TclPass : public Pass { TclPass() : Pass("tcl", "execute a TCL script file") { } - void help() YS_OVERRIDE { + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" tcl <filename> [args]\n"); @@ -730,7 +738,7 @@ struct TclPass : public Pass { log("the standard $argc and $argv variables.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *) YS_OVERRIDE { + void execute(std::vector<std::string> args, RTLIL::Design *) override { if (args.size() < 2) log_cmd_error("Missing script file.\n"); @@ -825,38 +833,74 @@ std::string proc_self_dirname() #endif #if defined(EMSCRIPTEN) || defined(__wasm) -std::string proc_share_dirname() +void init_share_dirname() { - return "/share/"; + yosys_share_dirname = "/share/"; } #else -std::string proc_share_dirname() +void init_share_dirname() { std::string proc_self_path = proc_self_dirname(); # if defined(_WIN32) && !defined(YOSYS_WIN32_UNIX_DIR) std::string proc_share_path = proc_self_path + "share\\"; - if (check_file_exists(proc_share_path, true)) - return proc_share_path; + if (check_file_exists(proc_share_path, true)) { + yosys_share_dirname = proc_share_path; + return; + } proc_share_path = proc_self_path + "..\\share\\"; - if (check_file_exists(proc_share_path, true)) - return proc_share_path; + if (check_file_exists(proc_share_path, true)) { + yosys_share_dirname = proc_share_path; + return; + } # else std::string proc_share_path = proc_self_path + "share/"; - if (check_file_exists(proc_share_path, true)) - return proc_share_path; + if (check_file_exists(proc_share_path, true)) { + yosys_share_dirname = proc_share_path; + return; + } proc_share_path = proc_self_path + "../share/" + proc_program_prefix()+ "yosys/"; - if (check_file_exists(proc_share_path, true)) - return proc_share_path; + if (check_file_exists(proc_share_path, true)) { + yosys_share_dirname = proc_share_path; + return; + } # ifdef YOSYS_DATDIR proc_share_path = YOSYS_DATDIR "/"; - if (check_file_exists(proc_share_path, true)) - return proc_share_path; + if (check_file_exists(proc_share_path, true)) { + yosys_share_dirname = proc_share_path; + return; + } # endif # endif - log_error("proc_share_dirname: unable to determine share/ directory!\n"); } #endif +void init_abc_executable_name() +{ +#ifdef ABCEXTERNAL + std::string exe_file; + if (std::getenv("ABC")) { + yosys_abc_executable = std::getenv("ABC"); + } else { + yosys_abc_executable = ABCEXTERNAL; + } +#else + yosys_abc_executable = proc_self_dirname() + proc_program_prefix()+ "yosys-abc"; +#endif +#ifdef _WIN32 +#ifndef ABCEXTERNAL + if (!check_file_exists(yosys_abc_executable + ".exe") && check_file_exists(proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc.exe")) + yosys_abc_executable = proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc"; +#endif +#endif +} + +std::string proc_share_dirname() +{ + if (yosys_share_dirname.empty()) + log_error("init_share_dirname: unable to determine share/ directory!\n"); + return yosys_share_dirname; +} + std::string proc_program_prefix() { std::string program_prefix; @@ -930,7 +974,7 @@ void run_frontend(std::string filename, std::string command, std::string *backen else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".json") == 0) command = "json"; else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".il") == 0) - command = "ilang"; + command = "rtlil"; else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".ys") == 0) command = "script"; else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".tcl") == 0) @@ -1050,8 +1094,10 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig if (command == "auto") { if (filename.size() > 2 && filename.compare(filename.size()-2, std::string::npos, ".v") == 0) command = "verilog"; + else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".sv") == 0) + command = "verilog -sv"; else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0) - command = "ilang"; + command = "rtlil"; else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".cc") == 0) command = "cxxrtl"; else if (filename.size() > 4 && filename.compare(filename.size()-4, std::string::npos, ".aig") == 0) @@ -1063,7 +1109,7 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".json") == 0) command = "json"; else if (filename == "-") - command = "ilang"; + command = "rtlil"; else if (filename.empty()) return; else @@ -1220,7 +1266,7 @@ void shell(RTLIL::Design *design) struct ShellPass : public Pass { ShellPass() : Pass("shell", "enter interactive command mode") { } - void help() YS_OVERRIDE { + void help() override { log("\n"); log(" shell\n"); log("\n"); @@ -1252,7 +1298,7 @@ struct ShellPass : public Pass { log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { + void execute(std::vector<std::string> args, RTLIL::Design *design) override { extra_args(args, 1, design, false); shell(design); } @@ -1261,7 +1307,7 @@ struct ShellPass : public Pass { #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) struct HistoryPass : public Pass { HistoryPass() : Pass("history", "show last interactive commands") { } - void help() YS_OVERRIDE { + void help() override { log("\n"); log(" history\n"); log("\n"); @@ -1270,7 +1316,7 @@ struct HistoryPass : public Pass { log("from executed scripts.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { + void execute(std::vector<std::string> args, RTLIL::Design *design) override { extra_args(args, 1, design, false); #ifdef YOSYS_ENABLE_READLINE for(HIST_ENTRY **list = history_list(); *list != NULL; list++) @@ -1285,7 +1331,7 @@ struct HistoryPass : public Pass { struct ScriptCmdPass : public Pass { ScriptCmdPass() : Pass("script", "execute commands from file or wire") { } - void help() YS_OVERRIDE { + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" script <filename> [<from_label>:<to_label>]\n"); @@ -1308,7 +1354,7 @@ struct ScriptCmdPass : public Pass { log("'-module' mode can be exited by using the 'cd' command.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool scriptwire = false; diff --git a/kernel/yosys.h b/kernel/yosys.h index c922faf26..ab6eb5f8c 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -117,11 +117,11 @@ extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *p # define PATH_MAX MAX_PATH # define isatty _isatty # define fileno _fileno -# else -// mingw includes `wingdi.h` which defines a TRANSPARENT macro -// that conflicts with X(TRANSPARENT) entry in kernel/constids.inc -# undef TRANSPARENT # endif + +// mingw and msvc include `wingdi.h` which defines a TRANSPARENT macro +// that conflicts with X(TRANSPARENT) entry in kernel/constids.inc +# undef TRANSPARENT #endif #ifndef PATH_MAX @@ -136,23 +136,20 @@ extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *p #define YOSYS_NAMESPACE_PREFIX Yosys:: #define USING_YOSYS_NAMESPACE using namespace Yosys; -#if __cplusplus >= 201103L -# define YS_OVERRIDE override -# define YS_FINAL final -#else -# define YS_OVERRIDE -# define YS_FINAL -#endif - #if defined(__GNUC__) || defined(__clang__) # define YS_ATTRIBUTE(...) __attribute__((__VA_ARGS__)) -# define YS_NORETURN #elif defined(_MSC_VER) # define YS_ATTRIBUTE(...) -# define YS_NORETURN __declspec(noreturn) #else # define YS_ATTRIBUTE(...) -# define YS_NORETURN +#endif + +#if __cplusplus >= 201703L +# define YS_MAYBE_UNUSED [[maybe_unused]]; +#elif defined(__GNUC__) || defined(__clang__) +# define YS_MAYBE_UNUSED __attribute__((__unused__)) +#else +# define YS_MAYBE_UNUSED #endif #if __cplusplus >= 201703L @@ -369,6 +366,9 @@ extern std::map<std::string, void*> loaded_python_plugins; extern std::map<std::string, std::string> loaded_plugin_aliases; void load_plugin(std::string filename, std::vector<std::string> aliases); +extern std::string yosys_share_dirname; +extern std::string yosys_abc_executable; + YOSYS_NAMESPACE_END #endif diff --git a/libs/minisat/00_PATCH_wasm.patch b/libs/minisat/00_PATCH_wasm.patch index 0bcff7d77..384930047 100644 --- a/libs/minisat/00_PATCH_wasm.patch +++ b/libs/minisat/00_PATCH_wasm.patch @@ -32,3 +32,15 @@ #endif +#endif } +--- System.cc ++++ System.cc +@@ -24,7 +24,9 @@ + OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + **************************************************************************************************/ + ++#if !defined(__wasm) + #include <signal.h> ++#endif + #include <stdio.h> + + #include "System.h" diff --git a/libs/minisat/System.cc b/libs/minisat/System.cc index 345be8c4c..807e46c69 100644 --- a/libs/minisat/System.cc +++ b/libs/minisat/System.cc @@ -24,7 +24,9 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ +#if !defined(__wasm) #include <signal.h> +#endif #include <stdio.h> #include "System.h" diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index 32c530582..d4572a88a 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -221,6 +221,26 @@ calculated signal and a constant zero with an {\tt \$and} gate). \subsection{Registers} +SR-type latches are represented by {\tt \$sr} cells. These cells have input ports +\B{SET} and \B{CLR} and an output port \B{Q}. They have the following parameters: + +\begin{itemize} +\item \B{WIDTH} \\ +The width of inputs \B{SET} and \B{CLR} and output \B{Q}. + +\item \B{SET\_POLARITY} \\ +The set input bits are active-high if this parameter has the value {\tt 1'b1} and active-low +if this parameter is {\tt 1'b0}. + +\item \B{CLR\_POLARITY} \\ +The reset input bits are active-high if this parameter has the value {\tt 1'b1} and active-low +if this parameter is {\tt 1'b0}. +\end{itemize} + +Both set and reset inputs have separate bits for every output bit. +When both the set and reset inputs of an {\tt \$sr} cell are active for a given bit +index, the reset input takes precedence. + D-type flip-flops are represented by {\tt \$dff} cells. These cells have a clock port \B{CLK}, an input port \B{D} and an output port \B{Q}. The following parameters are available for {\tt \$dff} cells: @@ -234,16 +254,6 @@ Clock is active on the positive edge if this parameter has the value {\tt 1'b1} edge if this parameter is {\tt 1'b0}. \end{itemize} -D-type flip-flops with enable are represented by {\tt \$dffe} cells. As the {\tt \$dff} -cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have a single-bit \B{EN} -input port for the enable pin and the following parameter: - -\begin{itemize} -\item \B{EN\_POLARITY} \\ -The enable input is active-high if this parameter has the value {\tt 1'b1} and active-low -if this parameter is {\tt 1'b0}. -\end{itemize} - D-type flip-flops with asynchronous reset are represented by {\tt \$adff} cells. As the {\tt \$dff} cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have a single-bit \B{ARST} input port for the reset pin and the following additional two parameters: @@ -257,35 +267,73 @@ if this parameter is {\tt 1'b0}. The state of \B{Q} will be set to this value when the reset is active. \end{itemize} -Note that the {\tt \$adff} cell can only be used when the reset value is constant. - \begin{sloppypar} Usually these cells are generated by the {\tt proc} pass using the information in the designs RTLIL::Process objects. \end{sloppypar} +D-type flip-flops with synchronous reset are represented by {\tt \$sdff} cells. As the {\tt \$dff} +cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have a single-bit \B{SRST} +input port for the reset pin and the following additional two parameters: + +\begin{itemize} +\item \B{SRST\_POLARITY} \\ +The synchronous reset is active-high if this parameter has the value {\tt 1'b1} and active-low +if this parameter is {\tt 1'b0}. + +\item \B{SRST\_VALUE} \\ +The state of \B{Q} will be set to this value when the reset is active. +\end{itemize} + +Note that the {\tt \$adff} and {\tt \$sdff} cells can only be used when the reset value is constant. + D-type flip-flops with asynchronous set and reset are represented by {\tt \$dffsr} cells. As the {\tt \$dff} cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have -a single-bit \B{SET} input port for the set pin, a single-bit \B{CLR} input port for the reset pin, -and the following two parameters: +multi-bit \B{SET} and \B{CLR} input ports and the corresponding polarity parameters, like +{\tt \$sr} cells. + +D-type flip-flops with enable are represented by {\tt \$dffe}, {\tt \$adffe}, {\tt \$dffsre}, +{\tt \$sdffe}, and {\tt \$sdffce} cells, which are enhanced variants of {\tt \$dff}, {\tt \$adff}, {\tt \$dffsr}, +{\tt \$sdff} (with reset over enable) and {\tt \$sdff} (with enable over reset) +cells, respectively. They have the same ports and parameters as their base cell. +In addition they also have a single-bit \B{EN} input port for the enable pin and the following parameter: \begin{itemize} -\item \B{SET\_POLARITY} \\ -The set input is active-high if this parameter has the value {\tt 1'b1} and active-low +\item \B{EN\_POLARITY} \\ +The enable input is active-high if this parameter has the value {\tt 1'b1} and active-low if this parameter is {\tt 1'b0}. +\end{itemize} -\item \B{CLR\_POLARITY} \\ -The reset input is active-high if this parameter has the value {\tt 1'b1} and active-low +D-type latches are represented by {\tt \$dlatch} cells. These cells have an enable port \B{EN}, +an input port \B{D}, and an output port \B{Q}. The following parameters are available for {\tt \$dlatch} cells: + +\begin{itemize} +\item \B{WIDTH} \\ +The width of input \B{D} and output \B{Q}. + +\item \B{EN\_POLARITY} \\ +The enable input is active-high if this parameter has the value {\tt 1'b1} and active-low if this parameter is {\tt 1'b0}. \end{itemize} -When both the set and reset inputs of a {\tt \$dffsr} cell are active, the reset input takes -precedence. +The latch is transparent when the \B{EN} input is active. -\begin{fixme} -Add information about {\tt \$sr} cells (set-reset flip-flops), {\tt \$dlatch} cells (d-type latches), -and {\tt \$dlatchsr} cells (d-type latches with set/reset). -\end{fixme} +D-type latches with reset are represented by {\tt \$adlatch} cells. In addition to {\tt \$dlatch} +ports and parameters, they also have a single-bit \B{ARST} input port for the reset pin and the following additional parameters: + +\begin{itemize} +\item \B{ARST\_POLARITY} \\ +The asynchronous reset is active-high if this parameter has the value {\tt 1'b1} and active-low +if this parameter is {\tt 1'b0}. + +\item \B{ARST\_VALUE} \\ +The state of \B{Q} will be set to this value when the reset is active. +\end{itemize} + +D-type latches with set and reset are represented by {\tt \$dlatchsr} cells. +In addition to {\tt \$dlatch} ports and parameters, they also have multi-bit +\B{SET} and \B{CLR} input ports and the corresponding polarity parameters, like +{\tt \$sr} cells. \subsection{Memories} \label{sec:memcells} @@ -461,6 +509,23 @@ The {\tt memory\_map} pass can be used to implement {\tt \$mem} cells as basic l Add a brief description of the {\tt \$fsm} cell type. \end{fixme} +\subsection{Specify rules} + +\begin{fixme} +Add information about {\tt \$specify2}, {\tt \$specify3}, and {\tt \$specrule} cells. +\end{fixme} + +\subsection{Formal verification cells} + +\begin{fixme} +Add information about {\tt \$assert}, {\tt \$assume}, {\tt \$live}, {\tt \$fair}, {\tt \$cover}, {\tt \$equiv}, +{\tt \$initstate}, {\tt \$anyconst}, {\tt \$anyseq}, {\tt \$allconst}, {\tt \$allseq} cells. +\end{fixme} + +\begin{fixme} +Add information about {\tt \$ff} and {\tt \$\_FF\_} cells. +\end{fixme} + \section{Gates} \label{sec:celllib_gates} @@ -475,6 +540,7 @@ source tree. \begin{tabular}[t]{ll} Verilog & Cell Type \\ \hline +\lstinline[language=Verilog]; Y = A; & {\tt \$\_BUF\_} \\ \lstinline[language=Verilog]; Y = ~A; & {\tt \$\_NOT\_} \\ \lstinline[language=Verilog]; Y = A & B; & {\tt \$\_AND\_} \\ \lstinline[language=Verilog]; Y = ~(A & B); & {\tt \$\_NAND\_} \\ @@ -484,26 +550,45 @@ Verilog & Cell Type \\ \lstinline[language=Verilog]; Y = A | ~B; & {\tt \$\_ORNOT\_} \\ \lstinline[language=Verilog]; Y = A ^ B; & {\tt \$\_XOR\_} \\ \lstinline[language=Verilog]; Y = ~(A ^ B); & {\tt \$\_XNOR\_} \\ +\lstinline[language=Verilog]; Y = ~((A & B) | C); & {\tt \$\_AOI3\_} \\ +\lstinline[language=Verilog]; Y = ~((A | B) & C); & {\tt \$\_OAI3\_} \\ +\lstinline[language=Verilog]; Y = ~((A & B) | (C & D)); & {\tt \$\_AOI4\_} \\ +\lstinline[language=Verilog]; Y = ~((A | B) & (C | D)); & {\tt \$\_OAI4\_} \\ \lstinline[language=Verilog]; Y = S ? B : A; & {\tt \$\_MUX\_} \\ -\lstinline[language=Verilog]; Y = EN ? A : 'bz; & {\tt \$\_TBUF\_} \\ +\lstinline[language=Verilog]; Y = ~(S ? B : A); & {\tt \$\_NMUX\_} \\ +(see below) & {\tt \$\_MUX4\_} \\ +(see below) & {\tt \$\_MUX8\_} \\ +(see below) & {\tt \$\_MUX16\_} \\ +\lstinline[language=Verilog]; Y = EN ? A : 1'bz; & {\tt \$\_TBUF\_} \\ \hline \lstinline[language=Verilog]; always @(negedge C) Q <= D; & {\tt \$\_DFF\_N\_} \\ \lstinline[language=Verilog]; always @(posedge C) Q <= D; & {\tt \$\_DFF\_P\_} \\ +\lstinline[language=Verilog]; always @* if (!E) Q <= D; & {\tt \$\_DLATCH\_N\_} \\ +\lstinline[language=Verilog]; always @* if (E) Q <= D; & {\tt \$\_DLATCH\_P\_} \\ \end{tabular} +\caption{Cell types for gate level logic networks (main list)} +\label{tab:CellLib_gates} +\end{table} + +\begin{table}[t] \hfil \begin{tabular}[t]{llll} $ClkEdge$ & $RstLvl$ & $RstVal$ & Cell Type \\ \hline -\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_NN0\_} \\ -\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_NN1\_} \\ -\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_NP0\_} \\ -\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_NP1\_} \\ -\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_PN0\_} \\ -\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_PN1\_} \\ -\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_PP0\_} \\ -\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_PP1\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_NN0\_}, {\tt \$\_SDFF\_NN0\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_NN1\_}, {\tt \$\_SDFF\_NN1\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_NP0\_}, {\tt \$\_SDFF\_NP0\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_NP1\_}, {\tt \$\_SDFF\_NP1\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_PN0\_}, {\tt \$\_SDFF\_PN0\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_PN1\_}, {\tt \$\_SDFF\_PN1\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_PP0\_}, {\tt \$\_SDFF\_PP0\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_PP1\_}, {\tt \$\_SDFF\_PP1\_} \\ \end{tabular} -% FIXME: the layout of this is broken and I have no idea how to fix it +\caption{Cell types for gate level logic networks (FFs with reset)} +\label{tab:CellLib_gates_adff} +\end{table} + +\begin{table}[t] \hfil \begin{tabular}[t]{lll} $ClkEdge$ & $EnLvl$ & Cell Type \\ @@ -513,7 +598,36 @@ $ClkEdge$ & $EnLvl$ & Cell Type \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PN\_} \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PP\_} \\ \end{tabular} -% FIXME: the layout of this is broken too +\caption{Cell types for gate level logic networks (FFs with enable)} +\label{tab:CellLib_gates_dffe} +\end{table} + +\begin{table}[t] +\begin{tabular}[t]{lllll} +$ClkEdge$ & $RstLvl$ & $RstVal$ & $EnLvl$ & Cell Type \\ +\hline +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_NN0N\_}, {\tt \$\_SDFFE\_NN0N\_}, {\tt \$\_SDFFCE\_NN0N\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_NN0P\_}, {\tt \$\_SDFFE\_NN0P\_}, {\tt \$\_SDFFCE\_NN0P\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_NN1N\_}, {\tt \$\_SDFFE\_NN1N\_}, {\tt \$\_SDFFCE\_NN1N\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_NN1P\_}, {\tt \$\_SDFFE\_NN1P\_}, {\tt \$\_SDFFCE\_NN1P\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_NP0N\_}, {\tt \$\_SDFFE\_NP0N\_}, {\tt \$\_SDFFCE\_NP0N\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_NP0P\_}, {\tt \$\_SDFFE\_NP0P\_}, {\tt \$\_SDFFCE\_NP0P\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_NP1N\_}, {\tt \$\_SDFFE\_NP1N\_}, {\tt \$\_SDFFCE\_NP1N\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_NP1P\_}, {\tt \$\_SDFFE\_NP1P\_}, {\tt \$\_SDFFCE\_NP1P\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PN0N\_}, {\tt \$\_SDFFE\_PN0N\_}, {\tt \$\_SDFFCE\_PN0N\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PN0P\_}, {\tt \$\_SDFFE\_PN0P\_}, {\tt \$\_SDFFCE\_PN0P\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PN1N\_}, {\tt \$\_SDFFE\_PN1N\_}, {\tt \$\_SDFFCE\_PN1N\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PN1P\_}, {\tt \$\_SDFFE\_PN1P\_}, {\tt \$\_SDFFCE\_PN1P\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PP0N\_}, {\tt \$\_SDFFE\_PP0N\_}, {\tt \$\_SDFFCE\_PP0N\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PP0P\_}, {\tt \$\_SDFFE\_PP0P\_}, {\tt \$\_SDFFCE\_PP0P\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PP1N\_}, {\tt \$\_SDFFE\_PP1N\_}, {\tt \$\_SDFFCE\_PP1N\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PP1P\_}, {\tt \$\_SDFFE\_PP1P\_}, {\tt \$\_SDFFCE\_PP1P\_} \\ +\end{tabular} +\caption{Cell types for gate level logic networks (FFs with reset and enable)} +\label{tab:CellLib_gates_adffe} +\end{table} + +\begin{table}[t] \hfil \begin{tabular}[t]{llll} $ClkEdge$ & $SetLvl$ & $RstLvl$ & Cell Type \\ @@ -527,18 +641,118 @@ $ClkEdge$ & $SetLvl$ & $RstLvl$ & Cell Type \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSR\_PPN\_} \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSR\_PPP\_} \\ \end{tabular} -\caption{Cell types for gate level logic networks} -\label{tab:CellLib_gates} +\caption{Cell types for gate level logic networks (FFs with set and reset)} +\label{tab:CellLib_gates_dffsr} +\end{table} + +\begin{table}[t] +\hfil +\begin{tabular}[t]{lllll} +$ClkEdge$ & $SetLvl$ & $RstLvl$ & $EnLvl$ & Cell Type \\ +\hline +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_NNNN\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_NNNP\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_NNPN\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_NNPP\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_NPNN\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_NPNP\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_NPPN\_} \\ +\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_NPPP\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_PNNN\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_PNNP\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_PNPN\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_PNPP\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_PPNN\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_PPNP\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_PPPN\_} \\ +\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_PPPP\_} \\ +\end{tabular} +\caption{Cell types for gate level logic networks (FFs with set and reset and enable)} +\label{tab:CellLib_gates_dffsre} +\end{table} + +\begin{table}[t] +\hfil +\begin{tabular}[t]{llll} +$EnLvl$ & $RstLvl$ & $RstVal$ & Cell Type \\ +\hline +\lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DLATCH\_NN0\_} \\ +\lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DLATCH\_NN1\_} \\ +\lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DLATCH\_NP0\_} \\ +\lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DLATCH\_NP1\_} \\ +\lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DLATCH\_PN0\_} \\ +\lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DLATCH\_PN1\_} \\ +\lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DLATCH\_PP0\_} \\ +\lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DLATCH\_PP1\_} \\ +\end{tabular} +\caption{Cell types for gate level logic networks (latches with reset)} +\label{tab:CellLib_gates_adlatch} +\end{table} + +\begin{table}[t] +\hfil +\begin{tabular}[t]{llll} +$EnLvl$ & $SetLvl$ & $RstLvl$ & Cell Type \\ +\hline +\lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DLATCHSR\_NNN\_} \\ +\lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DLATCHSR\_NNP\_} \\ +\lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DLATCHSR\_NPN\_} \\ +\lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DLATCHSR\_NPP\_} \\ +\lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DLATCHSR\_PNN\_} \\ +\lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DLATCHSR\_PNP\_} \\ +\lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DLATCHSR\_PPN\_} \\ +\lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DLATCHSR\_PPP\_} \\ +\end{tabular} +\caption{Cell types for gate level logic networks (latches with set and reset)} +\label{tab:CellLib_gates_dlatchsr} \end{table} -Table~\ref{tab:CellLib_gates} lists all cell types used for gate level logic. The cell types -{\tt \$\_NOT\_}, {\tt \$\_AND\_}, {\tt \$\_NAND\_}, {\tt \$\_ANDNOT\_}, {\tt \$\_OR\_}, {\tt \$\_NOR\_}, -{\tt \$\_ORNOT\_}, {\tt \$\_XOR\_}, {\tt \$\_XNOR\_} and {\tt \$\_MUX\_} are used to model combinatorial logic. +\begin{table}[t] +\hfil +\begin{tabular}[t]{llll} +$SetLvl$ & $RstLvl$ & Cell Type \\ +\hline +\lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_SR\_NN\_} \\ +\lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_SR\_NP\_} \\ +\lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_SR\_PN\_} \\ +\lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_SR\_PP\_} \\ +\end{tabular} +\caption{Cell types for gate level logic networks (SR latches)} +\label{tab:CellLib_gates_sr} +\end{table} + +Tables~\ref{tab:CellLib_gates}, \ref{tab:CellLib_gates_dffe}, \ref{tab:CellLib_gates_adff}, \ref{tab:CellLib_gates_adffe}, \ref{tab:CellLib_gates_dffsr}, \ref{tab:CellLib_gates_dffsre}, \ref{tab:CellLib_gates_adlatch}, \ref{tab:CellLib_gates_dlatchsr} and \ref{tab:CellLib_gates_sr} list all cell types used for gate level logic. The cell types +{\tt \$\_BUF\_}, {\tt \$\_NOT\_}, {\tt \$\_AND\_}, {\tt \$\_NAND\_}, {\tt \$\_ANDNOT\_}, +{\tt \$\_OR\_}, {\tt \$\_NOR\_}, {\tt \$\_ORNOT\_}, {\tt \$\_XOR\_}, {\tt \$\_XNOR\_}, +{\tt \$\_AOI3\_}, {\tt \$\_OAI3\_}, {\tt \$\_AOI4\_}, {\tt \$\_OAI4\_}, +{\tt \$\_MUX\_}, {\tt \$\_MUX4\_}, {\tt \$\_MUX8\_}, {\tt \$\_MUX16\_} and {\tt \$\_NMUX\_} are used to model combinatorial logic. The cell type {\tt \$\_TBUF\_} is used to model tristate logic. +The {\tt \$\_MUX4\_}, {\tt \$\_MUX8\_} and {\tt \$\_MUX16\_} cells are used to model wide muxes, and correspond to the following Verilog code: + +\begin{lstlisting}[language=Verilog] +// $_MUX4_ +assign Y = T ? (S ? D : C) : + (S ? B : A); +// $_MUX8_ +assign Y = U ? T ? (S ? H : G) : + (S ? F : E) : + T ? (S ? D : C) : + (S ? B : A); +// $_MUX16_ +assign Y = V ? U ? T ? (S ? P : O) : + (S ? N : M) : + T ? (S ? L : K) : + (S ? J : I) : + U ? T ? (S ? H : G) : + (S ? F : E) : + T ? (S ? D : C) : + (S ? B : A); +\end{lstlisting} + The cell types {\tt \$\_DFF\_N\_} and {\tt \$\_DFF\_P\_} represent d-type flip-flops. -The cell types {\tt \$\_DFFE\_NN\_}, {\tt \$\_DFFE\_NP\_}, {\tt \$\_DFFE\_PN\_} and {\tt \$\_DFFE\_PP\_} +The cell types {\tt \$\_DFFE\_[NP][NP]\_} implement d-type flip-flops with enable. The values in the table for these cell types relate to the following Verilog code template. @@ -548,8 +762,7 @@ following Verilog code template. Q <= D; \end{lstlisting} -The cell types {\tt \$\_DFF\_NN0\_}, {\tt \$\_DFF\_NN1\_}, {\tt \$\_DFF\_NP0\_}, {\tt \$\_DFF\_NP1\_}, -{\tt \$\_DFF\_PN0\_}, {\tt \$\_DFF\_PN1\_}, {\tt \$\_DFF\_PP0\_} and {\tt \$\_DFF\_PP1\_} implement +The cell types {\tt \$\_DFF\_[NP][NP][01]\_} implement d-type flip-flops with asynchronous reset. The values in the table for these cell types relate to the following Verilog code template, where \lstinline[mathescape,language=Verilog];$RstEdge$; is \lstinline[language=Verilog];posedge; if \lstinline[mathescape,language=Verilog];$RstLvl$; if \lstinline[language=Verilog];1;, and \lstinline[language=Verilog];negedge; @@ -563,8 +776,60 @@ otherwise. Q <= D; \end{lstlisting} -The cell types {\tt \$\_DFFSR\_NNN\_}, {\tt \$\_DFFSR\_NNP\_}, {\tt \$\_DFFSR\_NPN\_}, {\tt \$\_DFFSR\_NPP\_}, -{\tt \$\_DFFSR\_PNN\_}, {\tt \$\_DFFSR\_PNP\_}, {\tt \$\_DFFSR\_PPN\_} and {\tt \$\_DFFSR\_PPP\_} implement +The cell types {\tt \$\_SDFF\_[NP][NP][01]\_} implement +d-type flip-flops with synchronous reset. The values in the table for these cell types relate to the +following Verilog code template: + +\begin{lstlisting}[mathescape,language=Verilog] + always @($ClkEdge$ C) + if (R == $RstLvl$) + Q <= $RstVal$; + else + Q <= D; +\end{lstlisting} + +The cell types {\tt \$\_DFFE\_[NP][NP][01][NP]\_} implement +d-type flip-flops with asynchronous reset and enable. The values in the table for these cell types relate to the +following Verilog code template, where \lstinline[mathescape,language=Verilog];$RstEdge$; is \lstinline[language=Verilog];posedge; +if \lstinline[mathescape,language=Verilog];$RstLvl$; if \lstinline[language=Verilog];1;, and \lstinline[language=Verilog];negedge; +otherwise. + +\begin{lstlisting}[mathescape,language=Verilog] + always @($ClkEdge$ C, $RstEdge$ R) + if (R == $RstLvl$) + Q <= $RstVal$; + else if (EN == $EnLvl$) + Q <= D; +\end{lstlisting} + +The cell types {\tt \$\_SDFFE\_[NP][NP][01][NP]\_} implement d-type flip-flops +with synchronous reset and enable, with reset having priority over enable. +The values in the table for these cell types relate to the +following Verilog code template: + +\begin{lstlisting}[mathescape,language=Verilog] + always @($ClkEdge$ C) + if (R == $RstLvl$) + Q <= $RstVal$; + else if (EN == $EnLvl$) + Q <= D; +\end{lstlisting} + +The cell types {\tt \$\_SDFFCE\_[NP][NP][01][NP]\_} implement d-type flip-flops +with synchronous reset and enable, with enable having priority over reset. +The values in the table for these cell types relate to the +following Verilog code template: + +\begin{lstlisting}[mathescape,language=Verilog] + always @($ClkEdge$ C) + if (EN == $EnLvl$) + if (R == $RstLvl$) + Q <= $RstVal$; + else + Q <= D; +\end{lstlisting} + +The cell types {\tt \$\_DFFSR\_[NP][NP][NP]\_} implement d-type flip-flops with asynchronous set and reset. The values in the table for these cell types relate to the following Verilog code template, where \lstinline[mathescape,language=Verilog];$RstEdge$; is \lstinline[language=Verilog];posedge; if \lstinline[mathescape,language=Verilog];$RstLvl$; if \lstinline[language=Verilog];1;, \lstinline[language=Verilog];negedge; @@ -582,21 +847,70 @@ otherwise. Q <= D; \end{lstlisting} +The cell types {\tt \$\_DFFSRE\_[NP][NP][NP][NP]\_} implement +d-type flip-flops with asynchronous set and reset and enable. The values in the table for these cell types relate to the +following Verilog code template, where \lstinline[mathescape,language=Verilog];$RstEdge$; is \lstinline[language=Verilog];posedge; +if \lstinline[mathescape,language=Verilog];$RstLvl$; if \lstinline[language=Verilog];1;, \lstinline[language=Verilog];negedge; +otherwise, and \lstinline[mathescape,language=Verilog];$SetEdge$; is \lstinline[language=Verilog];posedge; +if \lstinline[mathescape,language=Verilog];$SetLvl$; if \lstinline[language=Verilog];1;, \lstinline[language=Verilog];negedge; +otherwise. + +\begin{lstlisting}[mathescape,language=Verilog] + always @($ClkEdge$ C, $RstEdge$ R, $SetEdge$ S) + if (R == $RstLvl$) + Q <= 0; + else if (S == $SetLvl$) + Q <= 1; + else if (E == $EnLvl$) + Q <= D; +\end{lstlisting} + +The cell types {\tt \$\_DLATCH\_N\_} and {\tt \$\_DLATCH\_P\_} represent d-type latches. + +The cell types {\tt \$\_DLATCH\_[NP][NP][01]\_} implement +d-type latches with reset. The values in the table for these cell types relate to the +following Verilog code template: + +\begin{lstlisting}[mathescape,language=Verilog] + always @* + if (R == $RstLvl$) + Q <= $RstVal$; + else if (E == $EnLvl$) + Q <= D; +\end{lstlisting} + +The cell types {\tt \$\_DLATCHSR\_[NP][NP][NP]\_} implement +d-type latches with set and reset. The values in the table for these cell types relate to the +following Verilog code template: + +\begin{lstlisting}[mathescape,language=Verilog] + always @* + if (R == $RstLvl$) + Q <= 0; + else if (S == $SetLvl$) + Q <= 1; + else if (E == $EnLvl$) + Q <= D; +\end{lstlisting} + +The cell types {\tt \$\_SR\_[NP][NP]\_} implement +sr-type latches. The values in the table for these cell types relate to the +following Verilog code template: + +\begin{lstlisting}[mathescape,language=Verilog] + always @* + if (R == $RstLvl$) + Q <= 0; + else if (S == $SetLvl$) + Q <= 1; +\end{lstlisting} + In most cases gate level logic networks are created from RTL networks using the {\tt techmap} pass. The flip-flop cells from the gate level logic network can be mapped to physical flip-flop cells from a Liberty file using the {\tt dfflibmap} pass. The combinatorial logic cells can be mapped to physical cells from a Liberty file via ABC \citeweblink{ABC} using the {\tt abc} pass. \begin{fixme} -Add information about {\tt \$assert}, {\tt \$assume}, {\tt \$live}, {\tt \$fair}, {\tt \$cover}, {\tt \$equiv}, -{\tt \$initstate}, {\tt \$anyconst}, {\tt \$anyseq}, {\tt \$allconst}, {\tt \$allseq} cells. -\end{fixme} - -\begin{fixme} -Add information about {\tt \$specify2}, {\tt \$specify3}, and {\tt \$specrule} cells. -\end{fixme} - -\begin{fixme} Add information about {\tt \$slice} and {\tt \$concat} cells. \end{fixme} @@ -607,16 +921,3 @@ Add information about {\tt \$lut} and {\tt \$sop} cells. \begin{fixme} Add information about {\tt \$alu}, {\tt \$macc}, {\tt \$fa}, and {\tt \$lcu} cells. \end{fixme} - -\begin{fixme} -Add information about {\tt \$ff} and {\tt \$\_FF\_} cells. -\end{fixme} - -\begin{fixme} -Add information about {\tt \$\_DLATCH\_?\_}, and {\tt \$\_DLATCHSR\_???\_} cells. -\end{fixme} - -\begin{fixme} -Add information about {\tt \$\_AOI3\_}, {\tt \$\_OAI3\_}, {\tt \$\_AOI4\_}, {\tt \$\_OAI4\_}, and {\tt \$\_NMUX\_} cells. -\end{fixme} - diff --git a/manual/CHAPTER_Overview.tex b/manual/CHAPTER_Overview.tex index 83cfa5cc4..ed8b4cd49 100644 --- a/manual/CHAPTER_Overview.tex +++ b/manual/CHAPTER_Overview.tex @@ -39,15 +39,15 @@ the RTL Intermediate Language (RTLIL). A more detailed description of this forma is given in the next section. There is also a text representation of the RTLIL data structure that can be -parsed using the ILANG Frontend. +parsed using the RTLIL Frontend. The design data may then be transformed using a series of passes that all operate on the RTLIL representation of the design. Finally the design in RTLIL representation is converted back to text by one of the backends, namely the Verilog Backend for generating Verilog netlists -and the ILANG Backend for writing the RTLIL data in the same format that is -understood by the ILANG Frontend. +and the RTLIL Backend for writing the RTLIL data in the same format that is +understood by the RTLIL Frontend. With the exception of the AST Frontend, which is called by the high-level HDL frontends and can't be called directly by the user, all program modules are @@ -67,13 +67,13 @@ in different stages of the synthesis. \tikzstyle{data} = [draw, fill=blue!10, ellipse, minimum height=3em, minimum width=7em, node distance=15em] \node[process] (vlog) {Verilog Frontend}; \node[process, dashed, fill=green!5] (vhdl) [right of=vlog] {VHDL Frontend}; - \node[process] (ilang) [right of=vhdl] {ILANG Frontend}; + \node[process] (ilang) [right of=vhdl] {RTLIL Frontend}; \node[data] (ast) [below of=vlog, node distance=5em, xshift=7.5em] {AST}; \node[process] (astfe) [below of=ast, node distance=5em] {AST Frontend}; \node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL}; \node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes}; \node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend}; - \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {ILANG Backend}; + \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {RTLIL Backend}; \node[process, dashed, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends}; \draw[-latex] (vlog) -- (ast); @@ -92,8 +92,7 @@ in different stages of the synthesis. \section{The RTL Intermediate Language} -All frontends, passes and backends in Yosys operate on a design in RTLIL\footnote{The {\it Language} in {\it RTL Intermediate Language} -refers to the fact, that RTLIL also has a text representation, usually referred to as {\it Intermediate Language} (ILANG).} representation. +All frontends, passes and backends in Yosys operate on a design in RTLIL representation. The only exception are the high-level frontends that use the AST representation as an intermediate step before generating RTLIL data. @@ -316,7 +315,7 @@ endmodule In this example there is no data path and therefore the RTLIL::Module generated by the frontend only contains a few RTLIL::Wire objects and an RTLIL::Process. -The RTLIL::Process in ILANG syntax: +The RTLIL::Process in RTLIL syntax: \begin{lstlisting}[numbers=left,frame=single,language=rtlil] process $proc$ff_with_en_and_async_reset.v:4$1 @@ -362,7 +361,7 @@ also contains an RTLIL::SwitchRule object (lines $3 \dots 12$). Such an object i statement as it uses a control signal ({\tt \textbackslash{}reset} in this case) to determine which of its cases should be active. The RTLIL::SwitchRule object then contains one RTLIL::CaseRule object per case. In this example there is a case\footnote{The -syntax {\tt 1'1} in the ILANG code specifies a constant with a length of one bit (the first ``1''), +syntax {\tt 1'1} in the RTLIL code specifies a constant with a length of one bit (the first ``1''), and this bit is a one (the second ``1'').} for {\tt \textbackslash{}reset == 1} that causes {\tt \$0\textbackslash{}q[0:0]} to be set (lines 4 and 5) and a default case that in turn contains a switch that sets {\tt \$0\textbackslash{}q[0:0]} to the value of {\tt \textbackslash{}d} if {\tt diff --git a/manual/CHAPTER_Prog/stubnets.cc b/manual/CHAPTER_Prog/stubnets.cc index 8123e63db..566d24b18 100644 --- a/manual/CHAPTER_Prog/stubnets.cc +++ b/manual/CHAPTER_Prog/stubnets.cc @@ -98,7 +98,7 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re // each pass contains a singleton object that is derived from Pass struct StubnetsPass : public Pass { StubnetsPass() : Pass("stubnets") { } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { // variables to mirror information from passed options bool report_bits = 0; diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex index 555ec9175..af561d01b 100644 --- a/manual/PRESENTATION_Intro.tex +++ b/manual/PRESENTATION_Intro.tex @@ -231,7 +231,7 @@ as Qflow\footnote[frame]{\url{http://opencircuitdesign.com/qflow/}} for ASIC des \node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL}; \node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes}; \node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend}; - \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {ILANG Backend}; + \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {RTLIL Backend}; \node[process, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends}; \draw[-latex] (vlog) -- (ast); @@ -484,7 +484,7 @@ Commands for design navigation and investigation: \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] cd # a shortcut for 'select -module <name>' ls # list modules or objects in modules - dump # print parts of the design in ilang format + dump # print parts of the design in RTLIL format show # generate schematics using graphviz select # modify and view the list of selected objects \end{lstlisting} @@ -502,7 +502,7 @@ Commands for executing scripts or entering interactive mode: \begin{frame}[fragile]{\subsecname{} 2/3 \hspace{0pt plus 1 filll} (excerpt)} Commands for reading and elaborating the design: \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] - read_ilang # read modules from ilang file + read_rtlil # read modules from RTLIL file read_verilog # read modules from Verilog file hierarchy # check, expand and clean up design hierarchy \end{lstlisting} @@ -534,7 +534,7 @@ Commands for writing the results: write_blif # write design to BLIF file write_btor # write design to BTOR file write_edif # write design to EDIF netlist file - write_ilang # write design to ilang file + write_rtlil # write design to RTLIL file write_spice # write design to SPICE netlist file write_verilog # write design to Verilog file \end{lstlisting} diff --git a/manual/PRESENTATION_Prog.tex b/manual/PRESENTATION_Prog.tex index a9416f82a..3b61361af 100644 --- a/manual/PRESENTATION_Prog.tex +++ b/manual/PRESENTATION_Prog.tex @@ -22,7 +22,7 @@ \node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL}; \node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes}; \node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend}; - \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {ILANG Backend}; + \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {RTLIL Backend}; \node[process, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends}; \draw[-latex] (vlog) -- (ast); @@ -105,8 +105,7 @@ For simplicity we only discuss this version of RTLIL in this presentation. \begin{frame}{\subsecname} \begin{itemize} -\item The {\tt dump} command prints the design (or parts of it) in ILANG format. This is -a text representation of RTLIL. +\item The {\tt dump} command prints the design (or parts of it) in the text representation of RTLIL. \bigskip \item The {\tt show} command visualizes how the components in the design are connected. diff --git a/manual/PRESENTATION_Prog/my_cmd.cc b/manual/PRESENTATION_Prog/my_cmd.cc index 5d9a7e13b..9cb4b8e38 100644 --- a/manual/PRESENTATION_Prog/my_cmd.cc +++ b/manual/PRESENTATION_Prog/my_cmd.cc @@ -6,7 +6,7 @@ PRIVATE_NAMESPACE_BEGIN struct MyPass : public Pass { MyPass() : Pass("my_cmd", "just a simple test") { } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log("Arguments to my_cmd:\n"); for (auto &arg : args) @@ -22,7 +22,7 @@ struct MyPass : public Pass { struct Test1Pass : public Pass { Test1Pass() : Pass("test1", "creating the absval module") { } - void execute(std::vector<std::string>, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string>, RTLIL::Design *design) override { if (design->has("\\absval") != 0) log_error("A module with the name absval already exists!\n"); @@ -49,7 +49,7 @@ struct Test1Pass : public Pass { struct Test2Pass : public Pass { Test2Pass() : Pass("test2", "demonstrating sigmap on test module") { } - void execute(std::vector<std::string>, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string>, RTLIL::Design *design) override { if (design->selection_stack.back().empty()) log_cmd_error("This command can't operator on an empty selection!\n"); diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py index fa23e3b2c..38bd6129e 100644 --- a/misc/py_wrap_generator.py +++ b/misc/py_wrap_generator.py @@ -1414,7 +1414,7 @@ class WFunction: text += ", " if len(self.args) > 0: text = text[:-2] - text += ") YS_OVERRIDE;\n" + text += ") override;\n" return text def gen_decl_hash_py(self): diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index 91f8c2add..a2f4a9100 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -116,7 +116,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n struct AddPass : public Pass { AddPass() : Pass("add", "add objects to the design") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -150,7 +150,7 @@ struct AddPass : public Pass { log("Add module[s] with the specified name[s].\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string command; std::string arg_name; diff --git a/passes/cmds/autoname.cc b/passes/cmds/autoname.cc index 50632201e..28d4012c4 100644 --- a/passes/cmds/autoname.cc +++ b/passes/cmds/autoname.cc @@ -92,7 +92,7 @@ int autoname_worker(Module *module) struct AutonamePass : public Pass { AutonamePass() : Pass("autoname", "automatically assign names to objects") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -102,7 +102,7 @@ struct AutonamePass : public Pass { log("with $-prefix).\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) diff --git a/passes/cmds/blackbox.cc b/passes/cmds/blackbox.cc index b8297cd77..08a635514 100644 --- a/passes/cmds/blackbox.cc +++ b/passes/cmds/blackbox.cc @@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN struct BlackboxPass : public Pass { BlackboxPass() : Pass("blackbox", "convert modules into blackbox modules") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -34,7 +34,7 @@ struct BlackboxPass : public Pass { log("module attribute).\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 00aac596f..81d7a34bb 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -18,15 +18,15 @@ */ #include "kernel/yosys.h" -#include "backends/ilang/ilang_backend.h" +#include "backends/rtlil/rtlil_backend.h" USING_YOSYS_NAMESPACE -using namespace ILANG_BACKEND; +using namespace RTLIL_BACKEND; PRIVATE_NAMESPACE_BEGIN struct BugpointPass : public Pass { BugpointPass() : Pass("bugpoint", "minimize testcases") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -90,7 +90,7 @@ struct BugpointPass : public Pass { design->sort(); std::ofstream f("bugpoint-case.il"); - ILANG_BACKEND::dump_design(f, design, /*only_selected=*/false, /*flag_m=*/true, /*flag_n=*/false); + RTLIL_BACKEND::dump_design(f, design, /*only_selected=*/false, /*flag_m=*/true, /*flag_n=*/false); f.close(); string yosys_cmdline = stringf("%s -qq -L bugpoint-case.log -s %s bugpoint-case.il", yosys_cmd.c_str(), script.c_str()); @@ -313,7 +313,7 @@ struct BugpointPass : public Pass { return nullptr; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string yosys_cmd = "yosys", script, grep; bool fast = false, clean = false; diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index ba29e6f4b..36febb98a 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct CheckPass : public Pass { CheckPass() : Pass("check", "check for obvious problems in the design") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -35,33 +35,31 @@ struct CheckPass : public Pass { log("\n"); log("This pass identifies the following problems in the current design:\n"); log("\n"); - log(" - combinatorial loops\n"); - log("\n"); - log(" - two or more conflicting drivers for one wire\n"); - log("\n"); - log(" - used wires that do not have a driver\n"); + log(" - combinatorial loops\n"); + log(" - two or more conflicting drivers for one wire\n"); + log(" - used wires that do not have a driver\n"); log("\n"); log("Options:\n"); log("\n"); - log(" -noinit\n"); - log(" Also check for wires which have the 'init' attribute set.\n"); + log(" -noinit\n"); + log(" also check for wires which have the 'init' attribute set\n"); log("\n"); - log(" -initdrv\n"); - log(" Also check for wires that have the 'init' attribute set and are not\n"); - log(" driven by an FF cell type.\n"); + log(" -initdrv\n"); + log(" also check for wires that have the 'init' attribute set and are not\n"); + log(" driven by an FF cell type\n"); log("\n"); - log(" -mapped\n"); - log(" Also check for internal cells that have not been mapped to cells of the\n"); - log(" target architecture.\n"); + log(" -mapped\n"); + log(" also check for internal cells that have not been mapped to cells of the\n"); + log(" target architecture\n"); log("\n"); - log(" -allow-tbuf\n"); - log(" Modify the -mapped behavior to still allow $_TBUF_ cells.\n"); + log(" -allow-tbuf\n"); + log(" modify the -mapped behavior to still allow $_TBUF_ cells\n"); log("\n"); - log(" -assert\n"); - log(" Produce a runtime error if any problems are found in the current design.\n"); + log(" -assert\n"); + log(" produce a runtime error if any problems are found in the current design\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { int counter = 0; bool noinit = false; @@ -100,10 +98,7 @@ struct CheckPass : public Pass { for (auto module : design->selected_whole_modules_warn()) { - if (module->has_processes_warn()) - continue; - - log("checking module %s..\n", log_id(module)); + log("Checking module %s...\n", log_id(module)); SigMap sigmap(module); dict<SigBit, vector<string>> wire_drivers; @@ -111,6 +106,44 @@ struct CheckPass : public Pass { pool<SigBit> used_wires; TopoSort<string> topo; + for (auto &proc_it : module->processes) + { + std::vector<RTLIL::CaseRule*> all_cases = {&proc_it.second->root_case}; + for (size_t i = 0; i < all_cases.size(); i++) { + for (auto action : all_cases[i]->actions) { + for (auto bit : sigmap(action.first)) + if (bit.wire) { + wire_drivers[bit].push_back( + stringf("action %s <= %s (case rule) in process %s", + log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); + } + for (auto bit : sigmap(action.second)) + if (bit.wire) used_wires.insert(bit); + } + for (auto switch_ : all_cases[i]->switches) { + for (auto case_ : switch_->cases) { + all_cases.push_back(case_); + for (auto compare : case_->compare) + for (auto bit : sigmap(compare)) + if (bit.wire) used_wires.insert(bit); + } + } + } + for (auto &sync : proc_it.second->syncs) { + for (auto bit : sigmap(sync->signal)) + if (bit.wire) used_wires.insert(bit); + for (auto action : sync->actions) { + for (auto bit : sigmap(action.first)) + if (bit.wire) + wire_drivers[bit].push_back( + stringf("action %s <= %s (sync rule) in process %s", + log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); + for (auto bit : sigmap(action.second)) + if (bit.wire) used_wires.insert(bit); + } + } + } + for (auto cell : module->cells()) { if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) { @@ -216,7 +249,7 @@ struct CheckPass : public Pass { } } - log("found and reported %d problems.\n", counter); + log("Found and reported %d problems.\n", counter); if (assert_mode && counter > 0) log_error("Found %d problems in 'check -assert'.\n", counter); diff --git a/passes/cmds/chformal.cc b/passes/cmds/chformal.cc index d6e7f2ccf..a1b3fbef7 100644 --- a/passes/cmds/chformal.cc +++ b/passes/cmds/chformal.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct ChformalPass : public Pass { ChformalPass() : Pass("chformal", "change formal constraints of the design") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -62,7 +62,7 @@ struct ChformalPass : public Pass { log(" change the roles of cells as indicated. these options can be combined\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool assert2assume = false; bool assume2assert = false; diff --git a/passes/cmds/chtype.cc b/passes/cmds/chtype.cc index 979aeadd4..b894f334c 100644 --- a/passes/cmds/chtype.cc +++ b/passes/cmds/chtype.cc @@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN struct ChtypePass : public Pass { ChtypePass() : Pass("chtype", "change type of cells in the design") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -40,7 +40,7 @@ struct ChtypePass : public Pass { log("\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { IdString set_type; dict<IdString, IdString> map_types; diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index 0b0868dfb..0cc6cbe52 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -43,7 +43,7 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap & struct ConnectPass : public Pass { ConnectPass() : Pass("connect", "create or remove connections") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -75,7 +75,7 @@ struct ConnectPass : public Pass { log("This command does not operate on module with processes.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { RTLIL::Module *module = nullptr; for (auto mod : design->selected_modules()) { diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 6ae7c9304..9235dda2b 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -143,7 +143,7 @@ struct ConnwrappersWorker struct ConnwrappersPass : public Pass { ConnwrappersPass() : Pass("connwrappers", "match width of input-output port pairs") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -165,7 +165,7 @@ struct ConnwrappersPass : public Pass { log("The options -signed, -unsigned, and -port can be specified multiple times.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { ConnwrappersWorker worker; diff --git a/passes/cmds/copy.cc b/passes/cmds/copy.cc index 99f1f69cf..c351065f3 100644 --- a/passes/cmds/copy.cc +++ b/passes/cmds/copy.cc @@ -26,7 +26,7 @@ PRIVATE_NAMESPACE_BEGIN struct CopyPass : public Pass { CopyPass() : Pass("copy", "copy modules in the design") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -36,7 +36,7 @@ struct CopyPass : public Pass { log("by this command.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { if (args.size() != 3) log_cmd_error("Invalid number of arguments!\n"); diff --git a/passes/cmds/cover.cc b/passes/cmds/cover.cc index 89d27c9aa..0867e3b4f 100644 --- a/passes/cmds/cover.cc +++ b/passes/cmds/cover.cc @@ -35,7 +35,7 @@ PRIVATE_NAMESPACE_BEGIN struct CoverPass : public Pass { CoverPass() : Pass("cover", "print code coverage counters") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -83,7 +83,7 @@ struct CoverPass : public Pass { log("Coverage counters are only available in Yosys for Linux.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::vector<FILE*> out_files; std::vector<std::string> patterns; diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index b124e3b0f..684fa37b0 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN struct DeletePass : public Pass { DeletePass() : Pass("delete", "delete objects in the design") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -40,7 +40,7 @@ struct DeletePass : public Pass { log("selected wires, thus 'deleting' module ports.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool flag_input = false; bool flag_output = false; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 421defe0c..2d7ba1fef 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -28,7 +28,7 @@ std::vector<RTLIL::Design*> pushed_designs; struct DesignPass : public Pass { DesignPass() : Pass("design", "save, restore and reset current design") { } - ~DesignPass() YS_OVERRIDE { + ~DesignPass() override { for (auto &it : saved_designs) delete it.second; saved_designs.clear(); @@ -36,7 +36,7 @@ struct DesignPass : public Pass { delete it; pushed_designs.clear(); } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -105,7 +105,7 @@ struct DesignPass : public Pass { log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool got_mode = false; bool reset_mode = false; diff --git a/passes/cmds/edgetypes.cc b/passes/cmds/edgetypes.cc index 58ed6457d..37c420400 100644 --- a/passes/cmds/edgetypes.cc +++ b/passes/cmds/edgetypes.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct EdgetypePass : public Pass { EdgetypePass() : Pass("edgetypes", "list all types of edges in selection") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -35,7 +35,7 @@ struct EdgetypePass : public Pass { log("is a 4-tuple of source and sink cell type and port name.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { diff --git a/passes/cmds/exec.cc b/passes/cmds/exec.cc index 7eeefe705..951fa53fc 100644 --- a/passes/cmds/exec.cc +++ b/passes/cmds/exec.cc @@ -38,7 +38,7 @@ PRIVATE_NAMESPACE_BEGIN struct ExecPass : public Pass { ExecPass() : Pass("exec", "execute commands in the operating system shell") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -71,7 +71,7 @@ struct ExecPass : public Pass { log("\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string cmd = ""; char buf[1024] = {}; diff --git a/passes/cmds/logcmd.cc b/passes/cmds/logcmd.cc index 522e1089d..12c43ecec 100644 --- a/passes/cmds/logcmd.cc +++ b/passes/cmds/logcmd.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct LogPass : public Pass { LogPass() : Pass("log", "print text and log files") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -52,7 +52,7 @@ struct LogPass : public Pass { log(" do not append a newline\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design*) override { size_t argidx; bool to_stdout = false; diff --git a/passes/cmds/logger.cc b/passes/cmds/logger.cc index c9532eced..6a9ed6036 100644 --- a/passes/cmds/logger.cc +++ b/passes/cmds/logger.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct LoggerPass : public Pass { LoggerPass() : Pass("logger", "set logger properties") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -66,7 +66,7 @@ struct LoggerPass : public Pass { log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design * design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design * design) override { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) diff --git a/passes/cmds/ltp.cc b/passes/cmds/ltp.cc index 05701710b..39ec432c2 100644 --- a/passes/cmds/ltp.cc +++ b/passes/cmds/ltp.cc @@ -141,7 +141,7 @@ struct LtpWorker struct LtpPass : public Pass { LtpPass() : Pass("ltp", "print longest topological path") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -154,7 +154,7 @@ struct LtpPass : public Pass { log(" automatically exclude FF cell types\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool noff = false; diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index 4c16b56c4..3ed19497d 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -99,7 +99,7 @@ void load_plugin(std::string, std::vector<std::string>) struct PluginPass : public Pass { PluginPass() : Pass("plugin", "load and list loaded plugins") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -117,7 +117,7 @@ struct PluginPass : public Pass { log(" List loaded plugins\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string plugin_filename; std::vector<std::string> plugin_aliases; diff --git a/passes/cmds/portlist.cc b/passes/cmds/portlist.cc index 38c4a8597..97f4bfd99 100644 --- a/passes/cmds/portlist.cc +++ b/passes/cmds/portlist.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct PortlistPass : public Pass { PortlistPass() : Pass("portlist", "list (top-level) ports") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -39,7 +39,7 @@ struct PortlistPass : public Pass { log(" print verilog blackbox module definitions instead of port lists\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool m_mode = false; diff --git a/passes/cmds/printattrs.cc b/passes/cmds/printattrs.cc index 80dbfa259..7973ac262 100644 --- a/passes/cmds/printattrs.cc +++ b/passes/cmds/printattrs.cc @@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN struct PrintAttrsPass : public Pass { PrintAttrsPass() : Pass("printattrs", "print attributes of selected objects") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -48,7 +48,7 @@ struct PrintAttrsPass : public Pass { log_assert(x.flags == RTLIL::CONST_FLAG_STRING || x.flags == RTLIL::CONST_FLAG_NONE); //intended to fail } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx = 1; extra_args(args, argidx, design); diff --git a/passes/cmds/qwp.cc b/passes/cmds/qwp.cc index b178ef951..cf0f6d0de 100644 --- a/passes/cmds/qwp.cc +++ b/passes/cmds/qwp.cc @@ -778,7 +778,7 @@ struct QwpWorker struct QwpPass : public Pass { QwpPass() : Pass("qwp", "quadratic wirelength placer") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -808,7 +808,7 @@ struct QwpPass : public Pass { log("dense matrix operations. It is only a toy-placer for small circuits.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { QwpConfig config; xorshift32_state = 123456789; diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index 7d6d84d42..f8fe715c8 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -104,7 +104,7 @@ static IdString derive_name_from_cell_output_wire(const RTLIL::Cell *cell) struct RenamePass : public Pass { RenamePass() : Pass("rename", "rename object in the design") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -152,7 +152,7 @@ struct RenamePass : public Pass { log("Rename top module.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string pattern_prefix = "_", pattern_suffix = "_"; bool flag_src = false; @@ -290,11 +290,11 @@ struct RenamePass : public Pass { dict<RTLIL::Cell *, IdString> new_cell_names; for (auto wire : module->selected_wires()) - if (wire->name[0] == '\\' && wire->port_id == 0) + if (wire->name.isPublic() && wire->port_id == 0) new_wire_names[wire] = NEW_ID; for (auto cell : module->selected_cells()) - if (cell->name[0] == '\\') + if (cell->name.isPublic()) new_cell_names[cell] = NEW_ID; for (auto &it : new_wire_names) diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc index a5ef95f02..a70dd3086 100644 --- a/passes/cmds/scatter.cc +++ b/passes/cmds/scatter.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct ScatterPass : public Pass { ScatterPass() : Pass("scatter", "add additional intermediate nets") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -41,7 +41,7 @@ struct ScatterPass : public Pass { log("Use the opt_clean command to get rid of the additional nets.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { CellTypes ct(design); extra_args(args, 1, design); diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index ad0554bae..8e7f3f990 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -218,7 +218,7 @@ struct SccWorker struct SccPass : public Pass { SccPass() : Pass("scc", "detect strongly connected components (logic loops)") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -255,7 +255,7 @@ struct SccPass : public Pass { log(" that are part of a found logic loop\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::map<std::string, std::string> setAttr; bool allCellTypes = false; diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc index 34ec0863a..9369f5312 100644 --- a/passes/cmds/scratchpad.cc +++ b/passes/cmds/scratchpad.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct ScratchpadPass : public Pass { ScratchpadPass() : Pass("scratchpad", "get/set values in the scratchpad") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -63,7 +63,7 @@ struct ScratchpadPass : public Pass { log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 13ee030a5..b4f3994a2 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1021,7 +1021,7 @@ PRIVATE_NAMESPACE_BEGIN struct SelectPass : public Pass { SelectPass() : Pass("select", "modify and view the list of selected objects") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1250,7 +1250,7 @@ struct SelectPass : public Pass { log(" select */t:SWITCH %%x:+[GATE] */t:SWITCH %%d\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool add_mode = false; bool del_mode = false; @@ -1587,7 +1587,7 @@ struct SelectPass : public Pass { struct CdPass : public Pass { CdPass() : Pass("cd", "a shortcut for 'select -module <name>'") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1613,7 +1613,7 @@ struct CdPass : public Pass { log("This is just a shortcut for 'select -clear'.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { if (args.size() != 1 && args.size() != 2) log_cmd_error("Invalid number of arguments.\n"); @@ -1693,7 +1693,7 @@ static void log_matches(const char *title, Module *module, const T &list) struct LsPass : public Pass { LsPass() : Pass("ls", "list modules or objects in modules") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1704,7 +1704,7 @@ struct LsPass : public Pass { log("When an active module is selected, this prints a list of objects in the module.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx = 1; extra_args(args, argidx, design); diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index 515f5a4ef..3a94209d4 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -56,7 +56,7 @@ static void do_setunset(dict<RTLIL::IdString, RTLIL::Const> &attrs, const std::v struct SetattrPass : public Pass { SetattrPass() : Pass("setattr", "set/unset attributes on objects") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -69,7 +69,7 @@ struct SetattrPass : public Pass { log("instead of objects within modules.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::vector<setunset_t> setunset_list; bool flag_mod = false; @@ -128,7 +128,7 @@ struct SetattrPass : public Pass { struct WbflipPass : public Pass { WbflipPass() : Pass("wbflip", "flip the whitebox attribute") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -138,7 +138,7 @@ struct WbflipPass : public Pass { log("vice-versa. Blackbox cells are not effected by this command.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -167,7 +167,7 @@ struct WbflipPass : public Pass { struct SetparamPass : public Pass { SetparamPass() : Pass("setparam", "set/unset parameters on objects") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -179,7 +179,7 @@ struct SetparamPass : public Pass { log("The -type option can be used to change the cell type of the selected cells.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { vector<setunset_t> setunset_list; string new_cell_type; @@ -219,7 +219,7 @@ struct SetparamPass : public Pass { struct ChparamPass : public Pass { ChparamPass() : Pass("chparam", "re-evaluate modules with new parameters") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -234,7 +234,7 @@ struct ChparamPass : public Pass { log("List the available parameters of the selected modules.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::vector<setunset_t> setunset_list; dict<RTLIL::IdString, RTLIL::Const> new_parameters; diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 8d973869e..cf8d76619 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -107,7 +107,7 @@ struct SetundefWorker struct SetundefPass : public Pass { SetundefPass() : Pass("setundef", "replace undef values with defined constants") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -147,7 +147,7 @@ struct SetundefPass : public Pass { log(" replace undef in cell parameters\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { int got_value = 0; bool undriven_mode = false; diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index fa922454a..0c96f8c5d 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -368,7 +368,7 @@ struct ShowWorker const char *shape = "diamond"; if (wire->port_input || wire->port_output) shape = "octagon"; - if (wire->name[0] == '\\') { + if (wire->name.isPublic()) { fprintf(f, "n%d [ shape=%s, label=\"%s\", %s, fontcolor=\"black\" ];\n", id2num(wire->name), shape, findLabel(wire->name.str()), nextColor(RTLIL::SigSpec(wire), "color=\"black\"").c_str()); @@ -587,7 +587,7 @@ struct ShowWorker struct ShowPass : public Pass { ShowPass() : Pass("show", "generate schematics using graphviz") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -605,7 +605,7 @@ struct ShowPass : public Pass { log(" generate a .dot file, or other <format> strings such as 'svg' or 'ps'\n"); log(" to generate files in other formats (this calls the 'dot' command).\n"); log("\n"); - log(" -lib <verilog_or_ilang_file>\n"); + log(" -lib <verilog_or_rtlil_file>\n"); log(" Use the specified library file for determining whether cell ports are\n"); log(" inputs or outputs. This option can be used multiple times to specify\n"); log(" more than one library.\n"); @@ -674,7 +674,7 @@ struct ShowPass : public Pass { log("the 'show' command is executed.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Generating Graphviz representation of design.\n"); log_push(); @@ -811,7 +811,7 @@ struct ShowPass : public Pass { if (f.fail()) log_error("Can't open lib file `%s'.\n", filename.c_str()); RTLIL::Design *lib = new RTLIL::Design; - Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog")); + Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : "verilog")); libs.push_back(lib); } diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index ea9e06979..0f63b91c5 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -211,7 +211,7 @@ struct SpliceWorker std::vector<Wire*> mod_wires = module->wires(); for (auto wire : mod_wires) - if ((!no_outputs && wire->port_output) || (do_wires && wire->name[0] == '\\')) { + if ((!no_outputs && wire->port_output) || (do_wires && wire->name.isPublic())) { if (!design->selected(module, wire)) continue; RTLIL::SigSpec sig = sigmap(wire); @@ -246,7 +246,7 @@ struct SpliceWorker struct SplicePass : public Pass { SplicePass() : Pass("splice", "create explicit splicing cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -287,7 +287,7 @@ struct SplicePass : public Pass { log("by selected wires are rewired.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool sel_by_cell = false; bool sel_by_wire = false; diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index 1e7dedd70..fff8a0d3e 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -59,18 +59,26 @@ struct SplitnetsWorker new_wire->port_id = wire->port_id ? wire->port_id + offset : 0; new_wire->port_input = wire->port_input; new_wire->port_output = wire->port_output; + new_wire->start_offset = wire->start_offset + offset; - if (wire->attributes.count(ID::src)) - new_wire->attributes[ID::src] = wire->attributes.at(ID::src); + auto it = wire->attributes.find(ID::src); + if (it != wire->attributes.end()) + new_wire->attributes.emplace(ID::src, it->second); - if (wire->attributes.count(ID::keep)) - new_wire->attributes[ID::keep] = wire->attributes.at(ID::keep); + it = wire->attributes.find(ID::hdlname); + if (it != wire->attributes.end()) + new_wire->attributes.emplace(ID::hdlname, it->second); - if (wire->attributes.count(ID::init)) { - Const old_init = wire->attributes.at(ID::init), new_init; + it = wire->attributes.find(ID::keep); + if (it != wire->attributes.end()) + new_wire->attributes.emplace(ID::keep, it->second); + + it = wire->attributes.find(ID::init); + if (it != wire->attributes.end()) { + Const old_init = it->second, new_init; for (int i = offset; i < offset+width; i++) new_init.bits.push_back(i < GetSize(old_init) ? old_init.bits.at(i) : State::Sx); - new_wire->attributes[ID::init] = new_init; + new_wire->attributes.emplace(ID::init, new_init); } std::vector<RTLIL::SigBit> sigvec = RTLIL::SigSpec(new_wire).to_sigbit_vector(); @@ -87,7 +95,7 @@ struct SplitnetsWorker struct SplitnetsPass : public Pass { SplitnetsPass() : Pass("splitnets", "split up multi-bit nets") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -109,7 +117,7 @@ struct SplitnetsPass : public Pass { log(" and split nets so that no driver drives only part of a net.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool flag_ports = false; bool flag_driver = false; @@ -166,12 +174,12 @@ struct SplitnetsPass : public Pass { std::map<RTLIL::Wire*, std::set<int>> split_wires_at; - for (auto &c : module->cells_) - for (auto &p : c.second->connections()) + for (auto c : module->cells()) + for (auto &p : c->connections()) { - if (!ct.cell_known(c.second->type)) + if (!ct.cell_known(c->type)) continue; - if (!ct.cell_output(c.second->type, p.first)) + if (!ct.cell_output(c->type, p.first)) continue; RTLIL::SigSpec sig = p.second; @@ -198,9 +206,8 @@ struct SplitnetsPass : public Pass { } else { - for (auto &w : module->wires_) { - RTLIL::Wire *wire = w.second; - if (wire->width > 1 && (wire->port_id == 0 || flag_ports) && design->selected(module, w.second)) + for (auto wire : module->wires()) { + if (wire->width > 1 && (wire->port_id == 0 || flag_ports) && design->selected(module, wire)) worker.splitmap[wire] = std::vector<RTLIL::SigBit>(); } diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 30436d829..0d84c73db 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -81,7 +81,7 @@ struct statdata_t for (auto wire : mod->selected_wires()) { - if (wire->name[0] == '\\') { + if (wire->name.isPublic()) { num_pub_wires++; num_pub_wire_bits += wire->width; } @@ -117,7 +117,10 @@ struct statdata_t } else if (cell_type.in(ID($mux), ID($pmux))) cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Y))); - else if (cell_type.in(ID($sr), ID($dff), ID($dffsr), ID($adff), ID($dlatch), ID($dlatchsr))) + else if (cell_type.in( + ID($sr), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), + ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), + ID($dlatch), ID($adlatch), ID($dlatchsr))) cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Q))); } @@ -282,7 +285,7 @@ void read_liberty_cellarea(dict<IdString, double> &cell_area, string liberty_fil struct StatPass : public Pass { StatPass() : Pass("stat", "print some statistics") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -308,7 +311,7 @@ struct StatPass : public Pass { log(" e.g. $add_8 for an 8 bit wide $add cell.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Printing statistics.\n"); diff --git a/passes/cmds/tee.cc b/passes/cmds/tee.cc index 1a44bdaec..60689fc82 100644 --- a/passes/cmds/tee.cc +++ b/passes/cmds/tee.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct TeePass : public Pass { TeePass() : Pass("tee", "redirect command output to file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -49,7 +49,7 @@ struct TeePass : public Pass { log(" Add/subtract INT from the -v setting for this command.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::vector<FILE*> backup_log_files, files_to_close; std::vector<std::ostream*> backup_log_streams; diff --git a/passes/cmds/torder.cc b/passes/cmds/torder.cc index 5748ff7f0..30e76081e 100644 --- a/passes/cmds/torder.cc +++ b/passes/cmds/torder.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct TorderPass : public Pass { TorderPass() : Pass("torder", "print cells in topological order") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -43,7 +43,7 @@ struct TorderPass : public Pass { log(" are not used in topological sorting. this option deactivates that.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool noautostop = false; dict<IdString, pool<IdString>> stop_db; diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc index 8446e27b3..10742c370 100644 --- a/passes/cmds/trace.cc +++ b/passes/cmds/trace.cc @@ -25,34 +25,34 @@ PRIVATE_NAMESPACE_BEGIN struct TraceMonitor : public RTLIL::Monitor { - void notify_module_add(RTLIL::Module *module) YS_OVERRIDE + void notify_module_add(RTLIL::Module *module) override { log("#TRACE# Module add: %s\n", log_id(module)); } - void notify_module_del(RTLIL::Module *module) YS_OVERRIDE + void notify_module_del(RTLIL::Module *module) override { log("#TRACE# Module delete: %s\n", log_id(module)); } - void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) YS_OVERRIDE + void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) override { log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", log_id(cell->module), log_id(cell), log_id(port), log_signal(sig), log_signal(old_sig)); } - void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) YS_OVERRIDE + void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) override { log("#TRACE# Connection in module %s: %s = %s\n", log_id(module), log_signal(sigsig.first), log_signal(sigsig.second)); } - void notify_connect(RTLIL::Module *module, const std::vector<RTLIL::SigSig> &sigsig_vec) YS_OVERRIDE + void notify_connect(RTLIL::Module *module, const std::vector<RTLIL::SigSig> &sigsig_vec) override { log("#TRACE# New connections in module %s:\n", log_id(module)); for (auto &sigsig : sigsig_vec) log("## %s = %s\n", log_signal(sigsig.first), log_signal(sigsig.second)); } - void notify_blackout(RTLIL::Module *module) YS_OVERRIDE + void notify_blackout(RTLIL::Module *module) override { log("#TRACE# Blackout in module %s:\n", log_id(module)); } @@ -60,7 +60,7 @@ struct TraceMonitor : public RTLIL::Monitor struct TracePass : public Pass { TracePass() : Pass("trace", "redirect command output to file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -70,7 +70,7 @@ struct TracePass : public Pass { log("the design in real time.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -96,7 +96,7 @@ struct TracePass : public Pass { struct DebugPass : public Pass { DebugPass() : Pass("debug", "run command with debug log messages enabled") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -105,7 +105,7 @@ struct DebugPass : public Pass { log("Execute the specified command with debug log messages enabled\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) diff --git a/passes/cmds/write_file.cc b/passes/cmds/write_file.cc index 64a762d7c..3d898a5ef 100644 --- a/passes/cmds/write_file.cc +++ b/passes/cmds/write_file.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct WriteFileFrontend : public Frontend { WriteFileFrontend() : Frontend("=write_file", "write a text to a file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -44,7 +44,7 @@ struct WriteFileFrontend : public Frontend { log(" EOT\n"); log("\n"); } - void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE + void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design*) override { bool append_mode = false; std::string output_filename; diff --git a/passes/equiv/equiv_add.cc b/passes/equiv/equiv_add.cc index cdc74b0b2..2abbb59bb 100644 --- a/passes/equiv/equiv_add.cc +++ b/passes/equiv/equiv_add.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct EquivAddPass : public Pass { EquivAddPass() : Pass("equiv_add", "add a $equiv cell") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -39,7 +39,7 @@ struct EquivAddPass : public Pass { log("This command adds $equiv cells for the ports of the specified cells.\n"); log("\n"); } - void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, Design *design) override { bool try_mode = false; diff --git a/passes/equiv/equiv_induct.cc b/passes/equiv/equiv_induct.cc index ec651193e..37aec50cd 100644 --- a/passes/equiv/equiv_induct.cc +++ b/passes/equiv/equiv_induct.cc @@ -65,8 +65,10 @@ struct EquivInductWorker int ez_a = satgen.importSigBit(bit_a, step); int ez_b = satgen.importSigBit(bit_b, step); int cond = ez->IFF(ez_a, ez_b); - if (satgen.model_undef) + if (satgen.model_undef) { + cond = ez->AND(cond, ez->NOT(satgen.importUndefSigBit(bit_b, step))); cond = ez->OR(cond, satgen.importUndefSigBit(bit_a, step)); + } ez_equal_terms.push_back(cond); } } @@ -162,7 +164,7 @@ struct EquivInductWorker struct EquivInductPass : public Pass { EquivInductPass() : Pass("equiv_induct", "proving $equiv cells using temporal induction") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -192,7 +194,7 @@ struct EquivInductPass : public Pass { log("after reset.\n"); log("\n"); } - void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, Design *design) override { int success_counter = 0; bool model_undef = false; diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index 50572ae5c..6923ae3d0 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -114,25 +114,25 @@ struct EquivMakeWorker Module *gate_clone = gate_mod->clone(); for (auto it : gold_clone->wires().to_vector()) { - if ((it->name[0] == '\\' || inames) && blacklist_names.count(it->name) == 0) + if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) wire_names.insert(it->name); gold_clone->rename(it, it->name.str() + "_gold"); } for (auto it : gold_clone->cells().to_vector()) { - if ((it->name[0] == '\\' || inames) && blacklist_names.count(it->name) == 0) + if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) cell_names.insert(it->name); gold_clone->rename(it, it->name.str() + "_gold"); } for (auto it : gate_clone->wires().to_vector()) { - if ((it->name[0] == '\\' || inames) && blacklist_names.count(it->name) == 0) + if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) wire_names.insert(it->name); gate_clone->rename(it, it->name.str() + "_gate"); } for (auto it : gate_clone->cells().to_vector()) { - if ((it->name[0] == '\\' || inames) && blacklist_names.count(it->name) == 0) + if ((it->name.isPublic() || inames) && blacklist_names.count(it->name) == 0) cell_names.insert(it->name); gate_clone->rename(it, it->name.str() + "_gate"); } @@ -466,7 +466,7 @@ struct EquivMakeWorker struct EquivMakePass : public Pass { EquivMakePass() : Pass("equiv_make", "prepare a circuit for equivalence checking") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -491,7 +491,7 @@ struct EquivMakePass : public Pass { log("checking problem. Use 'miter -equiv' if you want to create a miter circuit.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { EquivMakeWorker worker; worker.ct.setup(design); diff --git a/passes/equiv/equiv_mark.cc b/passes/equiv/equiv_mark.cc index 737de25d9..a722b5ed6 100644 --- a/passes/equiv/equiv_mark.cc +++ b/passes/equiv/equiv_mark.cc @@ -204,7 +204,7 @@ struct EquivMarkWorker struct EquivMarkPass : public Pass { EquivMarkPass() : Pass("equiv_mark", "mark equivalence checking regions") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -216,7 +216,7 @@ struct EquivMarkPass : public Pass { log("wires and cells.\n"); log("\n"); } - void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, Design *design) override { log_header(design, "Executing EQUIV_MARK pass.\n"); diff --git a/passes/equiv/equiv_miter.cc b/passes/equiv/equiv_miter.cc index 085970189..e028f806a 100644 --- a/passes/equiv/equiv_miter.cc +++ b/passes/equiv/equiv_miter.cc @@ -261,7 +261,7 @@ struct EquivMiterWorker struct EquivMiterPass : public Pass { EquivMiterPass() : Pass("equiv_miter", "extract miter from equiv circuit") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -282,7 +282,7 @@ struct EquivMiterPass : public Pass { log(" Create compare logic that handles undefs correctly\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { EquivMiterWorker worker; worker.ct.setup(design); diff --git a/passes/equiv/equiv_opt.cc b/passes/equiv/equiv_opt.cc index 7c6c2e685..4d0400448 100644 --- a/passes/equiv/equiv_opt.cc +++ b/passes/equiv/equiv_opt.cc @@ -26,7 +26,7 @@ struct EquivOptPass:public ScriptPass { EquivOptPass() : ScriptPass("equiv_opt", "prove equivalence for optimized circuit") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -68,7 +68,7 @@ struct EquivOptPass:public ScriptPass std::string command, techmap_opts, make_opts; bool assert, undef, multiclock, async2sync; - void clear_flags() YS_OVERRIDE + void clear_flags() override { command = ""; techmap_opts = ""; @@ -79,7 +79,7 @@ struct EquivOptPass:public ScriptPass async2sync = false; } - void execute(std::vector < std::string > args, RTLIL::Design * design) YS_OVERRIDE + void execute(std::vector < std::string > args, RTLIL::Design * design) override { string run_from, run_to; clear_flags(); @@ -148,7 +148,7 @@ struct EquivOptPass:public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("run_pass")) { run("hierarchy -auto-top"); diff --git a/passes/equiv/equiv_purge.cc b/passes/equiv/equiv_purge.cc index 688c20f43..a43ecec5a 100644 --- a/passes/equiv/equiv_purge.cc +++ b/passes/equiv/equiv_purge.cc @@ -35,7 +35,7 @@ struct EquivPurgeWorker { if (sig.is_wire()) { Wire *wire = sig.as_wire(); - if (wire->name[0] == '\\') { + if (wire->name.isPublic()) { if (!wire->port_output) { log(" Module output: %s (%s)\n", log_signal(wire), log_id(cellname)); wire->port_output = true; @@ -62,7 +62,7 @@ struct EquivPurgeWorker { if (sig.is_wire()) { Wire *wire = sig.as_wire(); - if (wire->name[0] == '\\') { + if (wire->name.isPublic()) { if (!wire->port_output) { log(" Module input: %s\n", log_signal(wire)); wire->port_input = true; @@ -176,7 +176,7 @@ struct EquivPurgeWorker struct EquivPurgePass : public Pass { EquivPurgePass() : Pass("equiv_purge", "purge equivalence checking module") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -187,7 +187,7 @@ struct EquivPurgePass : public Pass { log("ports as needed.\n"); log("\n"); } - void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, Design *design) override { log_header(design, "Executing EQUIV_PURGE pass.\n"); diff --git a/passes/equiv/equiv_remove.cc b/passes/equiv/equiv_remove.cc index 6daa112b5..89442308b 100644 --- a/passes/equiv/equiv_remove.cc +++ b/passes/equiv/equiv_remove.cc @@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN struct EquivRemovePass : public Pass { EquivRemovePass() : Pass("equiv_remove", "remove $equiv cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -40,7 +40,7 @@ struct EquivRemovePass : public Pass { log(" keep gate circuit\n"); log("\n"); } - void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, Design *design) override { bool mode_gold = false; bool mode_gate = false; diff --git a/passes/equiv/equiv_simple.cc b/passes/equiv/equiv_simple.cc index 4d2839f4d..408c5a793 100644 --- a/passes/equiv/equiv_simple.cc +++ b/passes/equiv/equiv_simple.cc @@ -273,7 +273,7 @@ struct EquivSimpleWorker struct EquivSimplePass : public Pass { EquivSimplePass() : Pass("equiv_simple", "try proving simple $equiv instances") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -298,7 +298,7 @@ struct EquivSimplePass : public Pass { log(" the max. number of time steps to be considered (default = 1)\n"); log("\n"); } - void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, Design *design) override { bool verbose = false, short_cones = false, model_undef = false, nogroup = false; int success_counter = 0; diff --git a/passes/equiv/equiv_status.cc b/passes/equiv/equiv_status.cc index 258e2e45b..2db44ea90 100644 --- a/passes/equiv/equiv_status.cc +++ b/passes/equiv/equiv_status.cc @@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN struct EquivStatusPass : public Pass { EquivStatusPass() : Pass("equiv_status", "print status of equivalent checking module") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -36,7 +36,7 @@ struct EquivStatusPass : public Pass { log(" produce an error if any unproven $equiv cell is found\n"); log("\n"); } - void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, Design *design) override { bool assert_mode = false; int unproven_count = 0; diff --git a/passes/equiv/equiv_struct.cc b/passes/equiv/equiv_struct.cc index 1b7bf96a8..9784225db 100644 --- a/passes/equiv/equiv_struct.cc +++ b/passes/equiv/equiv_struct.cc @@ -283,7 +283,7 @@ struct EquivStructWorker struct EquivStructPass : public Pass { EquivStructPass() : Pass("equiv_struct", "structural equivalence checking") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -314,7 +314,7 @@ struct EquivStructPass : public Pass { log(" maximum number of iterations to run before aborting\n"); log("\n"); } - void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, Design *design) override { pool<IdString> fwonly_cells({ ID($equiv) }); bool mode_icells = false; diff --git a/passes/fsm/fsm.cc b/passes/fsm/fsm.cc index c5cb338ab..21d352407 100644 --- a/passes/fsm/fsm.cc +++ b/passes/fsm/fsm.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct FsmPass : public Pass { FsmPass() : Pass("fsm", "extract and optimize finite state machines") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -68,7 +68,7 @@ struct FsmPass : public Pass { log(" passed through to fsm_recode pass\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool flag_nomap = false; bool flag_norecode = false; diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 30e9e4dad..97c575ba7 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -257,7 +257,7 @@ static void detect_fsm(RTLIL::Wire *wire) struct FsmDetectPass : public Pass { FsmDetectPass() : Pass("fsm_detect", "finding FSMs in design") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -273,7 +273,7 @@ struct FsmDetectPass : public Pass { log("'fsm_encoding' attribute to \"none\".\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing FSM_DETECT pass (finding FSMs in design).\n"); extra_args(args, 1, design); diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index ade6c17f5..d6b492af5 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -265,7 +265,7 @@ struct FsmExpand struct FsmExpandPass : public Pass { FsmExpandPass() : Pass("fsm_expand", "expand FSM cells by merging logic into it") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -279,7 +279,7 @@ struct FsmExpandPass : public Pass { log("word-wide cells. Call with -full to consider all cells for merging.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool full_mode = false; diff --git a/passes/fsm/fsm_export.cc b/passes/fsm/fsm_export.cc index c02a54ea2..be6702d7e 100644 --- a/passes/fsm/fsm_export.cc +++ b/passes/fsm/fsm_export.cc @@ -120,7 +120,7 @@ void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::st */ struct FsmExportPass : public Pass { FsmExportPass() : Pass("fsm_export", "exporting FSMs to KISS2 files") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -143,7 +143,7 @@ struct FsmExportPass : public Pass { log(" use binary state encoding as state names instead of s0, s1, ...\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { dict<RTLIL::IdString, RTLIL::Const>::iterator attr_it; std::string arg; diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 6f99886f0..082973153 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -401,7 +401,7 @@ static void extract_fsm(RTLIL::Wire *wire) struct FsmExtractPass : public Pass { FsmExtractPass() : Pass("fsm_extract", "extracting FSMs in design") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -417,7 +417,7 @@ struct FsmExtractPass : public Pass { log("'opt_clean' pass to eliminate this signal.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing FSM_EXTRACT pass (extracting FSM from design).\n"); extra_args(args, 1, design); diff --git a/passes/fsm/fsm_info.cc b/passes/fsm/fsm_info.cc index 90250f9b7..da0982bb9 100644 --- a/passes/fsm/fsm_info.cc +++ b/passes/fsm/fsm_info.cc @@ -30,7 +30,7 @@ PRIVATE_NAMESPACE_BEGIN struct FsmInfoPass : public Pass { FsmInfoPass() : Pass("fsm_info", "print information on finite state machines") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -41,7 +41,7 @@ struct FsmInfoPass : public Pass { log("pass so that this information is included in the synthesis log file.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing FSM_INFO pass (dumping all available information on FSM cells).\n"); extra_args(args, 1, design); diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 1765df092..a30d407f0 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -322,7 +322,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) struct FsmMapPass : public Pass { FsmMapPass() : Pass("fsm_map", "mapping FSMs to basic logic") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -331,7 +331,7 @@ struct FsmMapPass : public Pass { log("This pass translates FSM cells to flip-flops and logic.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing FSM_MAP pass (mapping FSMs to basic logic).\n"); extra_args(args, 1, design); diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index 89e8132d4..5fc1fb3bb 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -324,7 +324,7 @@ PRIVATE_NAMESPACE_BEGIN struct FsmOptPass : public Pass { FsmOptPass() : Pass("fsm_opt", "optimize finite state machines") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -335,7 +335,7 @@ struct FsmOptPass : public Pass { log("combination with the 'opt_clean' pass (see also 'help fsm').\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing FSM_OPT pass (simple optimizations of FSMs).\n"); extra_args(args, 1, design); diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index 7edb923b9..d4a704270 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -126,7 +126,7 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs struct FsmRecodePass : public Pass { FsmRecodePass() : Pass("fsm_recode", "recoding finite state machines") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -151,7 +151,7 @@ struct FsmRecodePass : public Pass { log(" .map <old_bitpattern> <new_bitpattern>\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { FILE *fm_set_fsm_file = NULL; FILE *encfile = NULL; diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index b4eb0f1dd..225e1feae 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -224,7 +224,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check { {".v", "verilog"}, {".sv", "verilog -sv"}, - {".il", "ilang"} + {".il", "rtlil"} }; for (auto &ext : extensions_list) @@ -558,7 +558,7 @@ RTLIL::Wire *find_implicit_port_wire(Module *module, Cell *cell, const std::stri struct HierarchyPass : public Pass { HierarchyPass() : Pass("hierarchy", "check, expand and clean up design hierarchy") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -639,7 +639,7 @@ struct HierarchyPass : public Pass { log("in the current design.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing HIERARCHY pass (managing design hierarchy).\n"); @@ -765,11 +765,13 @@ struct HierarchyPass : public Pass { top_mod = design->module(top_name); dict<RTLIL::IdString, RTLIL::Const> top_parameters; - for (auto ¶ : parameters) { - SigSpec sig_value; - if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second)) - log_cmd_error("Can't decode value '%s'!\n", para.second.c_str()); - top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const(); + if ((top_mod == nullptr && design->module(abstract_id)) || top_mod != nullptr) { + for (auto ¶ : parameters) { + SigSpec sig_value; + if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second)) + log_cmd_error("Can't decode value '%s'!\n", para.second.c_str()); + top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const(); + } } if (top_mod == nullptr && design->module(abstract_id)) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 2db7cf26b..b2826cbff 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -319,7 +319,7 @@ struct SubmodWorker struct SubmodPass : public Pass { SubmodPass() : Pass("submod", "moving part of a module to a new submodule") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -351,7 +351,7 @@ struct SubmodPass : public Pass { log(" original module with original public names.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing SUBMOD pass (moving cells to submodules as requested).\n"); log_push(); diff --git a/passes/hierarchy/uniquify.cc b/passes/hierarchy/uniquify.cc index 5dbd15a7e..3f9443a63 100644 --- a/passes/hierarchy/uniquify.cc +++ b/passes/hierarchy/uniquify.cc @@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN struct UniquifyPass : public Pass { UniquifyPass() : Pass("uniquify", "create unique copies of modules") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -41,7 +41,7 @@ struct UniquifyPass : public Pass { log("attribute set (the 'top' module is unique implicitly).\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing UNIQUIFY pass (creating unique copies of modules).\n"); diff --git a/passes/memory/memory.cc b/passes/memory/memory.cc index cee63bdd8..282517992 100644 --- a/passes/memory/memory.cc +++ b/passes/memory/memory.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct MemoryPass : public Pass { MemoryPass() : Pass("memory", "translate memories to basic cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -49,7 +49,7 @@ struct MemoryPass : public Pass { log("or multiport memory blocks if called with the -nomap option.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool flag_nomap = false; bool flag_nordff = false; diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 0898ec288..c6948fdba 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -18,6 +18,7 @@ */ #include "kernel/yosys.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -400,9 +401,11 @@ struct rules_t } }; -bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, const rules_t::match_t &match, dict<string, int> &match_properties, int mode) +bool replace_memory(Mem &orig_mem, const rules_t &rules, const rules_t::bram_t &bram, const rules_t::match_t &match, dict<string, int> &match_properties, int mode) { - Module *module = cell->module; + // We will modify ports — make a copy of the structure. + Mem mem(orig_mem); + Module *module = mem.module; auto portinfos = bram.make_portinfos(); int dup_count = 1; @@ -437,46 +440,17 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, log(" Mapping to bram type %s (variant %d):\n", log_id(bram.name), bram.variant); // bram.dump_config(); - int mem_size = cell->getParam(ID::SIZE).as_int(); - int mem_abits = cell->getParam(ID::ABITS).as_int(); - int mem_width = cell->getParam(ID::WIDTH).as_int(); - // int mem_offset = cell->getParam(ID::OFFSET).as_int(); - - bool cell_init = !SigSpec(cell->getParam(ID::INIT)).is_fully_undef(); + bool cell_init = !mem.inits.empty(); vector<Const> initdata; if (cell_init) { - Const initparam = cell->getParam(ID::INIT); - initdata.reserve(mem_size); - for (int i=0; i < mem_size; i++) - initdata.push_back(initparam.extract(mem_width*i, mem_width, State::Sx)); + Const initparam = mem.get_init_data(); + initdata.reserve(mem.size); + for (int i=0; i < mem.size; i++) + initdata.push_back(initparam.extract(mem.width*i, mem.width, State::Sx)); } - int wr_ports = cell->getParam(ID::WR_PORTS).as_int(); - auto wr_clken = SigSpec(cell->getParam(ID::WR_CLK_ENABLE)); - auto wr_clkpol = SigSpec(cell->getParam(ID::WR_CLK_POLARITY)); - wr_clken.extend_u0(wr_ports); - wr_clkpol.extend_u0(wr_ports); - - SigSpec wr_en = cell->getPort(ID::WR_EN); - SigSpec wr_clk = cell->getPort(ID::WR_CLK); - SigSpec wr_data = cell->getPort(ID::WR_DATA); - SigSpec wr_addr = cell->getPort(ID::WR_ADDR); - - int rd_ports = cell->getParam(ID::RD_PORTS).as_int(); - auto rd_clken = SigSpec(cell->getParam(ID::RD_CLK_ENABLE)); - auto rd_clkpol = SigSpec(cell->getParam(ID::RD_CLK_POLARITY)); - auto rd_transp = SigSpec(cell->getParam(ID::RD_TRANSPARENT)); - rd_clken.extend_u0(rd_ports); - rd_clkpol.extend_u0(rd_ports); - rd_transp.extend_u0(rd_ports); - - SigSpec rd_en = cell->getPort(ID::RD_EN); - SigSpec rd_clk = cell->getPort(ID::RD_CLK); - SigSpec rd_data = cell->getPort(ID::RD_DATA); - SigSpec rd_addr = cell->getPort(ID::RD_ADDR); - - if (match.shuffle_enable && bram.dbits >= portinfos.at(match.shuffle_enable - 'A').enable*2 && portinfos.at(match.shuffle_enable - 'A').enable > 0 && wr_ports > 0) + if (match.shuffle_enable && bram.dbits >= portinfos.at(match.shuffle_enable - 'A').enable*2 && portinfos.at(match.shuffle_enable - 'A').enable > 0 && !mem.wr_ports.empty()) { int bucket_size = bram.dbits / portinfos.at(match.shuffle_enable - 'A').enable; log(" Shuffle bit order to accommodate enable buckets of size %d..\n", bucket_size); @@ -487,23 +461,23 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, std::vector<SigSpec> old_wr_data; std::vector<SigSpec> old_rd_data; - for (int i = 0; i < wr_ports; i++) { - old_wr_en.push_back(wr_en.extract(i*mem_width, mem_width)); - old_wr_data.push_back(wr_data.extract(i*mem_width, mem_width)); + for (auto &port : mem.wr_ports) { + old_wr_en.push_back(port.en); + old_wr_data.push_back(port.data); } - for (int i = 0; i < rd_ports; i++) - old_rd_data.push_back(rd_data.extract(i*mem_width, mem_width)); + for (auto &port : mem.rd_ports) + old_rd_data.push_back(port.data); // analyze enable structure std::vector<SigSpec> en_order; dict<SigSpec, vector<int>> bits_wr_en; - for (int i = 0; i < mem_width; i++) { + for (int i = 0; i < mem.width; i++) { SigSpec sig; - for (int j = 0; j < wr_ports; j++) - sig.append(old_wr_en[j][i]); + for (auto &port : mem.wr_ports) + sig.append(port.en[i]); if (bits_wr_en.count(sig) == 0) en_order.push_back(sig); bits_wr_en[sig].push_back(i); @@ -518,7 +492,7 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, std::vector<int> shuffle_map; if (cell_init) - new_initdata.resize(mem_size); + new_initdata.resize(mem.size); for (auto &it : en_order) { @@ -528,29 +502,29 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, SigBit fillbit; for (int i = 0; i < GetSize(bits); i++) { - for (int j = 0; j < wr_ports; j++) { + for (int j = 0; j < GetSize(mem.wr_ports); j++) { new_wr_en[j].append(old_wr_en[j][bits[i]]); new_wr_data[j].append(old_wr_data[j][bits[i]]); fillbit = old_wr_en[j][bits[i]]; } - for (int j = 0; j < rd_ports; j++) + for (int j = 0; j < GetSize(mem.rd_ports); j++) new_rd_data[j].append(old_rd_data[j][bits[i]]); if (cell_init) { - for (int j = 0; j < mem_size; j++) + for (int j = 0; j < mem.size; j++) new_initdata[j].push_back(initdata[j][bits[i]]); } shuffle_map.push_back(bits[i]); } for (int i = 0; i < fillbits; i++) { - for (int j = 0; j < wr_ports; j++) { + for (int j = 0; j < GetSize(mem.wr_ports); j++) { new_wr_en[j].append(fillbit); new_wr_data[j].append(State::S0); } - for (int j = 0; j < rd_ports; j++) + for (int j = 0; j < GetSize(mem.rd_ports); j++) new_rd_data[j].append(State::Sx); if (cell_init) { - for (int j = 0; j < mem_size; j++) + for (int j = 0; j < mem.size; j++) new_initdata[j].push_back(State::Sx); } shuffle_map.push_back(-1); @@ -564,40 +538,38 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, // update mem_*, wr_*, and rd_* variables - mem_width = GetSize(new_wr_en.front()); - wr_en = SigSpec(0, wr_ports * mem_width); - wr_data = SigSpec(0, wr_ports * mem_width); - rd_data = SigSpec(0, rd_ports * mem_width); + mem.width = GetSize(new_wr_en.front()); - for (int i = 0; i < wr_ports; i++) { - wr_en.replace(i*mem_width, new_wr_en[i]); - wr_data.replace(i*mem_width, new_wr_data[i]); + for (int i = 0; i < GetSize(mem.wr_ports); i++) { + auto &port = mem.wr_ports[i]; + port.en = new_wr_en[i]; + port.data = new_wr_data[i]; } - for (int i = 0; i < rd_ports; i++) - rd_data.replace(i*mem_width, new_rd_data[i]); + for (int i = 0; i < GetSize(mem.rd_ports); i++) { + auto &port = mem.rd_ports[i]; + port.data = new_rd_data[i]; + } if (cell_init) { - for (int i = 0; i < mem_size; i++) + for (int i = 0; i < mem.size; i++) initdata[i] = Const(new_initdata[i]); } } // assign write ports pair<SigBit, bool> wr_clkdom; - for (int cell_port_i = 0, bram_port_i = 0; cell_port_i < wr_ports; cell_port_i++) + for (int cell_port_i = 0, bram_port_i = 0; cell_port_i < GetSize(mem.wr_ports); cell_port_i++) { - bool clken = wr_clken[cell_port_i] == State::S1; - bool clkpol = wr_clkpol[cell_port_i] == State::S1; - SigBit clksig = wr_clk[cell_port_i]; + auto &port = mem.wr_ports[cell_port_i]; - pair<SigBit, bool> clkdom(clksig, clkpol); - if (!clken) + pair<SigBit, bool> clkdom(port.clk, port.clk_polarity); + if (!port.clk_enable) clkdom = pair<SigBit, bool>(State::S1, false); wr_clkdom = clkdom; log(" Write port #%d is in clock domain %s%s.\n", cell_port_i, clkdom.second ? "" : "!", - clken ? log_signal(clkdom.first) : "~async~"); + port.clk_enable ? log_signal(clkdom.first) : "~async~"); for (; bram_port_i < GetSize(portinfos); bram_port_i++) { @@ -609,7 +581,7 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, skip_bram_wport: continue; - if (clken) { + if (port.clk_enable) { if (pi.clocks == 0) { log(" Bram port %c%d has incompatible clock type.\n", pi.group + 'A', pi.index + 1); goto skip_bram_wport; @@ -618,7 +590,7 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, log(" Bram port %c%d is in a different clock domain.\n", pi.group + 'A', pi.index + 1); goto skip_bram_wport; } - if (clock_polarities.count(pi.clkpol) && clock_polarities.at(pi.clkpol) != clkpol) { + if (clock_polarities.count(pi.clkpol) && clock_polarities.at(pi.clkpol) != port.clk_polarity) { log(" Bram port %c%d has incompatible clock polarity.\n", pi.group + 'A', pi.index + 1); goto skip_bram_wport; } @@ -631,12 +603,12 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, SigSpec sig_en; SigBit last_en_bit = State::S1; - for (int i = 0; i < mem_width; i++) { + for (int i = 0; i < mem.width; i++) { if (pi.enable && i % (bram.dbits / pi.enable) == 0) { - last_en_bit = wr_en[i + cell_port_i*mem_width]; + last_en_bit = port.en[i]; sig_en.append(last_en_bit); } - if (last_en_bit != wr_en[i + cell_port_i*mem_width]) { + if (last_en_bit != port.en[i]) { log(" Bram port %c%d has incompatible enable structure.\n", pi.group + 'A', pi.index + 1); goto skip_bram_wport; } @@ -645,7 +617,7 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, log(" Mapped to bram port %c%d.\n", pi.group + 'A', pi.index + 1); pi.mapped_port = cell_port_i; - if (clken) { + if (port.clk_enable) { clock_domains[pi.clocks] = clkdom; clock_polarities[pi.clkpol] = clkdom.second; pi.sig_clock = clkdom.first; @@ -653,8 +625,8 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, } pi.sig_en = sig_en; - pi.sig_addr = wr_addr.extract(cell_port_i*mem_abits, mem_abits); - pi.sig_data = wr_data.extract(cell_port_i*mem_width, mem_width); + pi.sig_addr = port.addr; + pi.sig_data = port.data; bram_port_i++; goto mapped_wr_port; @@ -710,23 +682,21 @@ grow_read_ports:; // assign read ports - for (int cell_port_i = 0; cell_port_i < rd_ports; cell_port_i++) + for (int cell_port_i = 0; cell_port_i < GetSize(mem.rd_ports); cell_port_i++) { - bool clken = rd_clken[cell_port_i] == State::S1; - bool clkpol = rd_clkpol[cell_port_i] == State::S1; - bool transp = rd_transp[cell_port_i] == State::S1; - SigBit clksig = rd_clk[cell_port_i]; + auto &port = mem.rd_ports[cell_port_i]; + bool transp = port.transparent; - if (wr_ports == 0) + if (mem.wr_ports.empty()) transp = false; - pair<SigBit, bool> clkdom(clksig, clkpol); - if (!clken) + pair<SigBit, bool> clkdom(port.clk, port.clk_polarity); + if (!port.clk_enable) clkdom = pair<SigBit, bool>(State::S1, false); log(" Read port #%d is in clock domain %s%s.\n", cell_port_i, clkdom.second ? "" : "!", - clken ? log_signal(clkdom.first) : "~async~"); + port.clk_enable ? log_signal(clkdom.first) : "~async~"); for (int bram_port_i = 0; bram_port_i < GetSize(portinfos); bram_port_i++) { @@ -736,7 +706,7 @@ grow_read_ports:; skip_bram_rport: continue; - if (clken) { + if (port.clk_enable) { if (pi.clocks == 0) { if (match.make_outreg) { pi.make_outreg = true; @@ -749,20 +719,20 @@ grow_read_ports:; log(" Bram port %c%d.%d is in a different clock domain.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); goto skip_bram_rport; } - if (clock_polarities.count(pi.clkpol) && clock_polarities.at(pi.clkpol) != clkpol) { + if (clock_polarities.count(pi.clkpol) && clock_polarities.at(pi.clkpol) != port.clk_polarity) { log(" Bram port %c%d.%d has incompatible clock polarity.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); goto skip_bram_rport; } - if (rd_en[cell_port_i] != State::S1 && pi.enable == 0) { + if (port.en != State::S1 && pi.enable == 0) { log(" Bram port %c%d.%d has no read enable input.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); goto skip_bram_rport; } skip_bram_rport_clkcheck: if (read_transp.count(pi.transp) && read_transp.at(pi.transp) != transp) { - if (match.make_transp && wr_ports <= 1) { + if (match.make_transp && GetSize(mem.wr_ports) <= 1) { pi.make_transp = true; if (pi.clocks != 0) { - if (wr_ports == 1 && wr_clkdom != clkdom) { + if (GetSize(mem.wr_ports) == 1 && wr_clkdom != clkdom) { log(" Bram port %c%d.%d cannot have soft transparency logic added as read and write clock domains differ.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); goto skip_bram_rport; } @@ -783,18 +753,18 @@ grow_read_ports:; log(" Mapped to bram port %c%d.%d.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); pi.mapped_port = cell_port_i; - if (clken) { + if (port.clk_enable) { clock_domains[pi.clocks] = clkdom; clock_polarities[pi.clkpol] = clkdom.second; if (!pi.make_transp) read_transp[pi.transp] = transp; pi.sig_clock = clkdom.first; - pi.sig_en = rd_en[cell_port_i]; + pi.sig_en = port.en; pi.effective_clkpol = clkdom.second; } - pi.sig_addr = rd_addr.extract(cell_port_i*mem_abits, mem_abits); - pi.sig_data = rd_data.extract(cell_port_i*mem_width, mem_width); + pi.sig_addr = port.addr; + pi.sig_data = port.data; if (grow_read_ports_cursor < cell_port_i) { grow_read_ports_cursor = cell_port_i; @@ -820,11 +790,11 @@ grow_read_ports:; match_properties["dups"] = dup_count; match_properties["waste"] = match_properties["dups"] * match_properties["bwaste"]; - int cells = ((mem_width + bram.dbits - 1) / bram.dbits) * ((mem_size + (1 << bram.abits) - 1) / (1 << bram.abits)); + int cells = ((mem.width + bram.dbits - 1) / bram.dbits) * ((mem.size + (1 << bram.abits) - 1) / (1 << bram.abits)); match_properties["efficiency"] = (100 * match_properties["bits"]) / (dup_count * cells * bram.dbits * (1 << bram.abits)); - match_properties["dcells"] = ((mem_width + bram.dbits - 1) / bram.dbits); - match_properties["acells"] = ((mem_size + (1 << bram.abits) - 1) / (1 << bram.abits)); + match_properties["dcells"] = ((mem.width + bram.dbits - 1) / bram.dbits); + match_properties["acells"] = ((mem.size + (1 << bram.abits) - 1) / (1 << bram.abits)); match_properties["cells"] = match_properties["dcells"] * match_properties["acells"] * match_properties["dups"]; log(" Updated properties: dups=%d waste=%d efficiency=%d\n", @@ -857,8 +827,8 @@ grow_read_ports:; bool exists = std::get<0>(term); IdString key = std::get<1>(term); const Const &value = std::get<2>(term); - auto it = cell->attributes.find(key); - if (it == cell->attributes.end()) { + auto it = mem.attributes.find(key); + if (it == mem.attributes.end()) { if (exists) continue; found = true; @@ -902,7 +872,7 @@ grow_read_ports:; dict<SigSpec, pair<SigSpec, SigSpec>> dout_cache; - for (int grid_d = 0; grid_d*bram.dbits < mem_width; grid_d++) + for (int grid_d = 0; grid_d*bram.dbits < mem.width; grid_d++) { SigSpec mktr_wraddr, mktr_wrdata, mktr_wrdata_q; vector<SigSpec> mktr_wren; @@ -912,14 +882,14 @@ grow_read_ports:; mktr_wrdata = module->addWire(NEW_ID, bram.dbits); mktr_wrdata_q = module->addWire(NEW_ID, bram.dbits); module->addDff(NEW_ID, make_transp_clk.first, mktr_wrdata, mktr_wrdata_q, make_transp_clk.second); - for (int grid_a = 0; grid_a*(1 << bram.abits) < mem_size; grid_a++) + for (int grid_a = 0; grid_a*(1 << bram.abits) < mem.size; grid_a++) mktr_wren.push_back(module->addWire(NEW_ID, make_transp_enbits)); } - for (int grid_a = 0; grid_a*(1 << bram.abits) < mem_size; grid_a++) + for (int grid_a = 0; grid_a*(1 << bram.abits) < mem.size; grid_a++) for (int dupidx = 0; dupidx < dup_count; dupidx++) { - Cell *c = module->addCell(module->uniquify(stringf("%s.%d.%d.%d", cell->name.c_str(), grid_d, grid_a, dupidx)), bram.name); + Cell *c = module->addCell(module->uniquify(stringf("%s.%d.%d.%d", mem.memid.c_str(), grid_d, grid_a, dupidx)), bram.name); log(" Creating %s cell at grid position <%d %d %d>: %s\n", log_id(bram.name), grid_d, grid_a, dupidx, log_id(c)); for (auto &vp : variant_params) @@ -1063,22 +1033,22 @@ grow_read_ports:; } } - module->remove(cell); + mem.remove(); return true; } -void handle_cell(Cell *cell, const rules_t &rules) +void handle_memory(Mem &mem, const rules_t &rules) { - log("Processing %s.%s:\n", log_id(cell->module), log_id(cell)); + log("Processing %s.%s:\n", log_id(mem.module), log_id(mem.memid)); - bool cell_init = !SigSpec(cell->getParam(ID::INIT)).is_fully_undef(); + bool cell_init = !mem.inits.empty(); dict<string, int> match_properties; - match_properties["words"] = cell->getParam(ID::SIZE).as_int(); - match_properties["abits"] = cell->getParam(ID::ABITS).as_int(); - match_properties["dbits"] = cell->getParam(ID::WIDTH).as_int(); - match_properties["wports"] = cell->getParam(ID::WR_PORTS).as_int(); - match_properties["rports"] = cell->getParam(ID::RD_PORTS).as_int(); + match_properties["words"] = mem.size; + match_properties["abits"] = ceil_log2(mem.size); + match_properties["dbits"] = mem.width; + match_properties["wports"] = GetSize(mem.wr_ports); + match_properties["rports"] = GetSize(mem.rd_ports); match_properties["bits"] = match_properties["words"] * match_properties["dbits"]; match_properties["ports"] = match_properties["wports"] + match_properties["rports"]; @@ -1181,8 +1151,8 @@ void handle_cell(Cell *cell, const rules_t &rules) bool exists = std::get<0>(term); IdString key = std::get<1>(term); const Const &value = std::get<2>(term); - auto it = cell->attributes.find(key); - if (it == cell->attributes.end()) { + auto it = mem.attributes.find(key); + if (it == mem.attributes.end()) { if (exists) continue; found = true; @@ -1219,7 +1189,7 @@ void handle_cell(Cell *cell, const rules_t &rules) if (or_next_if_better && i+1 == GetSize(rules.matches) && vi+1 == GetSize(rules.brams.at(match.name))) log_error("Found 'or_next_if_better' in last match rule.\n"); - if (!replace_cell(cell, rules, bram, match, match_properties, 1)) { + if (!replace_memory(mem, rules, bram, match, match_properties, 1)) { log(" Mapping to bram type %s failed.\n", log_id(match.name)); failed_brams.insert(pair<IdString, int>(bram.name, bram.variant)); goto next_match_rule; @@ -1246,12 +1216,12 @@ void handle_cell(Cell *cell, const rules_t &rules) best_rule_cache.clear(); auto &best_bram = rules.brams.at(rules.matches.at(best_rule.first).name).at(best_rule.second); - if (!replace_cell(cell, rules, best_bram, rules.matches.at(best_rule.first), match_properties, 2)) + if (!replace_memory(mem, rules, best_bram, rules.matches.at(best_rule.first), match_properties, 2)) log_error("Mapping to bram type %s (variant %d) after pre-selection failed.\n", log_id(best_bram.name), best_bram.variant); return; } - if (!replace_cell(cell, rules, bram, match, match_properties, 0)) { + if (!replace_memory(mem, rules, bram, match, match_properties, 0)) { log(" Mapping to bram type %s failed.\n", log_id(match.name)); failed_brams.insert(pair<IdString, int>(bram.name, bram.variant)); goto next_match_rule; @@ -1265,7 +1235,7 @@ void handle_cell(Cell *cell, const rules_t &rules) struct MemoryBramPass : public Pass { MemoryBramPass() : Pass("memory_bram", "map memories to block rams") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1367,7 +1337,7 @@ struct MemoryBramPass : public Pass { log("the data bits to accommodate the enable pattern of port A.\n"); log("\n"); } - void execute(vector<string> args, Design *design) YS_OVERRIDE + void execute(vector<string> args, Design *design) override { rules_t rules; @@ -1384,9 +1354,8 @@ struct MemoryBramPass : public Pass { extra_args(args, argidx, design); for (auto mod : design->selected_modules()) - for (auto cell : mod->selected_cells()) - if (cell->type == ID($mem)) - handle_cell(cell, rules); + for (auto &mem : Mem::get_selected_memories(mod)) + handle_memory(mem, rules); } } MemoryBramPass; diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index ef8b07811..ede6ca6a1 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -18,234 +18,14 @@ */ #include "kernel/yosys.h" -#include "kernel/sigtools.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -bool memcells_cmp(Cell *a, Cell *b) -{ - if (a->type == ID($memrd) && b->type == ID($memrd)) - return a->name < b->name; - if (a->type == ID($memrd) || b->type == ID($memrd)) - return (a->type == ID($memrd)) < (b->type == ID($memrd)); - return a->parameters.at(ID::PRIORITY).as_int() < b->parameters.at(ID::PRIORITY).as_int(); -} - -Cell *handle_memory(Module *module, RTLIL::Memory *memory) -{ - log("Collecting $memrd, $memwr and $meminit for memory `%s' in module `%s':\n", - memory->name.c_str(), module->name.c_str()); - - Const init_data(State::Sx, memory->size * memory->width); - SigMap sigmap(module); - - int wr_ports = 0; - SigSpec sig_wr_clk; - SigSpec sig_wr_clk_enable; - SigSpec sig_wr_clk_polarity; - SigSpec sig_wr_addr; - SigSpec sig_wr_data; - SigSpec sig_wr_en; - - int rd_ports = 0; - SigSpec sig_rd_clk; - SigSpec sig_rd_clk_enable; - SigSpec sig_rd_clk_polarity; - SigSpec sig_rd_transparent; - SigSpec sig_rd_addr; - SigSpec sig_rd_data; - SigSpec sig_rd_en; - - int addr_bits = 0; - std::vector<Cell*> memcells; - - for (auto cell : module->cells()) - if (cell->type.in(ID($memrd), ID($memwr), ID($meminit)) && memory->name == cell->parameters[ID::MEMID].decode_string()) { - SigSpec addr = sigmap(cell->getPort(ID::ADDR)); - for (int i = 0; i < GetSize(addr); i++) - if (addr[i] != State::S0) - addr_bits = std::max(addr_bits, i+1); - memcells.push_back(cell); - } - - if (memory->start_offset == 0 && addr_bits < 30 && (1 << addr_bits) < memory->size) - memory->size = 1 << addr_bits; - - if (memory->start_offset >= 0) - addr_bits = std::min(addr_bits, ceil_log2(memory->size + memory->start_offset)); - - addr_bits = std::max(addr_bits, 1); - - if (memcells.empty()) { - log(" no cells found. removing memory.\n"); - return nullptr; - } - - std::sort(memcells.begin(), memcells.end(), memcells_cmp); - - for (auto cell : memcells) - { - log(" %s (%s)\n", log_id(cell), log_id(cell->type)); - - if (cell->type == ID($meminit)) - { - SigSpec addr = sigmap(cell->getPort(ID::ADDR)); - SigSpec data = sigmap(cell->getPort(ID::DATA)); - - if (!addr.is_fully_const()) - log_error("Non-constant address %s in memory initialization %s.\n", log_signal(addr), log_id(cell)); - if (!data.is_fully_const()) - log_error("Non-constant data %s in memory initialization %s.\n", log_signal(data), log_id(cell)); - - int offset = (addr.as_int() - memory->start_offset) * memory->width; - - if (offset < 0 || offset + GetSize(data) > GetSize(init_data)) - log_warning("Address %s in memory initialization %s is out-of-bounds.\n", log_signal(addr), log_id(cell)); - - for (int i = 0; i < GetSize(data); i++) - if (0 <= i+offset && i+offset < GetSize(init_data)) - init_data.bits[i+offset] = data[i].data; - - continue; - } - - if (cell->type == ID($memwr)) - { - SigSpec clk = sigmap(cell->getPort(ID::CLK)); - SigSpec clk_enable = SigSpec(cell->parameters[ID::CLK_ENABLE]); - SigSpec clk_polarity = SigSpec(cell->parameters[ID::CLK_POLARITY]); - SigSpec addr = sigmap(cell->getPort(ID::ADDR)); - SigSpec data = sigmap(cell->getPort(ID::DATA)); - SigSpec en = sigmap(cell->getPort(ID::EN)); - - if (!en.is_fully_zero()) - { - clk.extend_u0(1, false); - clk_enable.extend_u0(1, false); - clk_polarity.extend_u0(1, false); - addr.extend_u0(addr_bits, false); - data.extend_u0(memory->width, false); - en.extend_u0(memory->width, false); - - sig_wr_clk.append(clk); - sig_wr_clk_enable.append(clk_enable); - sig_wr_clk_polarity.append(clk_polarity); - sig_wr_addr.append(addr); - sig_wr_data.append(data); - sig_wr_en.append(en); - - wr_ports++; - } - continue; - } - - if (cell->type == ID($memrd)) - { - SigSpec clk = sigmap(cell->getPort(ID::CLK)); - SigSpec clk_enable = SigSpec(cell->parameters[ID::CLK_ENABLE]); - SigSpec clk_polarity = SigSpec(cell->parameters[ID::CLK_POLARITY]); - SigSpec transparent = SigSpec(cell->parameters[ID::TRANSPARENT]); - SigSpec addr = sigmap(cell->getPort(ID::ADDR)); - SigSpec data = sigmap(cell->getPort(ID::DATA)); - SigSpec en = sigmap(cell->getPort(ID::EN)); - - if (!en.is_fully_zero()) - { - clk.extend_u0(1, false); - clk_enable.extend_u0(1, false); - clk_polarity.extend_u0(1, false); - transparent.extend_u0(1, false); - addr.extend_u0(addr_bits, false); - data.extend_u0(memory->width, false); - - sig_rd_clk.append(clk); - sig_rd_clk_enable.append(clk_enable); - sig_rd_clk_polarity.append(clk_polarity); - sig_rd_transparent.append(transparent); - sig_rd_addr.append(addr); - sig_rd_data.append(data); - sig_rd_en.append(en); - - rd_ports++; - } - continue; - } - } - - std::stringstream sstr; - sstr << "$mem$" << memory->name.str() << "$" << (autoidx++); - - Cell *mem = module->addCell(sstr.str(), ID($mem)); - mem->parameters[ID::MEMID] = Const(memory->name.str()); - mem->parameters[ID::WIDTH] = Const(memory->width); - mem->parameters[ID::OFFSET] = Const(memory->start_offset); - mem->parameters[ID::SIZE] = Const(memory->size); - mem->parameters[ID::ABITS] = Const(addr_bits); - mem->parameters[ID::INIT] = init_data; - - log_assert(sig_wr_clk.size() == wr_ports); - log_assert(sig_wr_clk_enable.size() == wr_ports && sig_wr_clk_enable.is_fully_const()); - log_assert(sig_wr_clk_polarity.size() == wr_ports && sig_wr_clk_polarity.is_fully_const()); - log_assert(sig_wr_addr.size() == wr_ports * addr_bits); - log_assert(sig_wr_data.size() == wr_ports * memory->width); - log_assert(sig_wr_en.size() == wr_ports * memory->width); - - mem->parameters[ID::WR_PORTS] = Const(wr_ports); - mem->parameters[ID::WR_CLK_ENABLE] = wr_ports ? sig_wr_clk_enable.as_const() : State::S0; - mem->parameters[ID::WR_CLK_POLARITY] = wr_ports ? sig_wr_clk_polarity.as_const() : State::S0; - - mem->setPort(ID::WR_CLK, sig_wr_clk); - mem->setPort(ID::WR_ADDR, sig_wr_addr); - mem->setPort(ID::WR_DATA, sig_wr_data); - mem->setPort(ID::WR_EN, sig_wr_en); - - log_assert(sig_rd_clk.size() == rd_ports); - log_assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const()); - log_assert(sig_rd_clk_polarity.size() == rd_ports && sig_rd_clk_polarity.is_fully_const()); - log_assert(sig_rd_addr.size() == rd_ports * addr_bits); - log_assert(sig_rd_data.size() == rd_ports * memory->width); - - mem->parameters[ID::RD_PORTS] = Const(rd_ports); - mem->parameters[ID::RD_CLK_ENABLE] = rd_ports ? sig_rd_clk_enable.as_const() : State::S0; - mem->parameters[ID::RD_CLK_POLARITY] = rd_ports ? sig_rd_clk_polarity.as_const() : State::S0; - mem->parameters[ID::RD_TRANSPARENT] = rd_ports ? sig_rd_transparent.as_const() : State::S0; - - mem->setPort(ID::RD_CLK, sig_rd_clk); - mem->setPort(ID::RD_ADDR, sig_rd_addr); - mem->setPort(ID::RD_DATA, sig_rd_data); - mem->setPort(ID::RD_EN, sig_rd_en); - - // Copy attributes from RTLIL memory to $mem - for (auto attr : memory->attributes) - mem->attributes[attr.first] = attr.second; - - for (auto c : memcells) - module->remove(c); - - return mem; -} - -static void handle_module(Design *design, Module *module) -{ - std::vector<pair<Cell*, IdString>> finqueue; - - for (auto &mem_it : module->memories) - if (design->selected(module, mem_it.second)) { - Cell *c = handle_memory(module, mem_it.second); - finqueue.push_back(pair<Cell*, IdString>(c, mem_it.first)); - } - for (auto &it : finqueue) { - delete module->memories.at(it.second); - module->memories.erase(it.second); - if (it.first) - module->rename(it.first, it.second); - } -} - struct MemoryCollectPass : public Pass { MemoryCollectPass() : Pass("memory_collect", "creating multi-port memory cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -255,11 +35,17 @@ struct MemoryCollectPass : public Pass { log("memory cells.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing MEMORY_COLLECT pass (generating $mem cells).\n"); extra_args(args, 1, design); - for (auto module : design->selected_modules()) - handle_module(design, module); + for (auto module : design->selected_modules()) { + for (auto &mem : Mem::get_selected_memories(module)) { + if (!mem.packed) { + mem.packed = true; + mem.emit(); + } + } + } } } MemoryCollectPass; diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 726a5c1ff..4adcb462e 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -20,6 +20,7 @@ #include <algorithm> #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/ffinit.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -34,66 +35,158 @@ struct MemoryDffWorker dict<SigBit, int> sigbit_users_count; dict<SigSpec, Cell*> mux_cells_a, mux_cells_b; pool<Cell*> forward_merged_dffs, candidate_dffs; - pool<SigBit> init_bits; + FfInitVals initvals; MemoryDffWorker(Module *module) : module(module), sigmap(module) { - for (auto wire : module->wires()) { - if (wire->attributes.count(ID::init) == 0) - continue; - SigSpec sig = sigmap(wire); - Const initval = wire->attributes.at(ID::init); - for (int i = 0; i < GetSize(sig) && i < GetSize(initval); i++) - if (initval[i] == State::S0 || initval[i] == State::S1) - init_bits.insert(sig[i]); - } + initvals.set(&sigmap, module); } - bool find_sig_before_dff(RTLIL::SigSpec &sig, RTLIL::SigSpec &clk, bool &clk_polarity, bool after = false) + bool find_sig_before_dff(RTLIL::SigSpec &sig, RTLIL::SigSpec &clk, bool &clk_polarity) { sigmap.apply(sig); + dict<SigBit, SigBit> cache; + for (auto &bit : sig) { + if (cache.count(bit)) { + bit = cache[bit]; + continue; + } + if (bit.wire == NULL) continue; - if (!after && init_bits.count(sigmap(bit))) + if (initvals(bit) != State::Sx) return false; for (auto cell : dff_cells) { - if (after && forward_merged_dffs.count(cell)) + SigSpec this_clk = cell->getPort(ID::CLK); + bool this_clk_polarity = cell->parameters[ID::CLK_POLARITY].as_bool(); + + if (invbits.count(this_clk)) { + this_clk = invbits.at(this_clk); + this_clk_polarity = !this_clk_polarity; + } + + if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) { + if (this_clk != clk) + continue; + if (this_clk_polarity != clk_polarity) + continue; + } + + RTLIL::SigSpec q_norm = cell->getPort(ID::Q); + sigmap.apply(q_norm); + + RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(ID::D)); + if (d.size() != 1) + continue; + + if (cell->type == ID($sdffce)) { + SigSpec rval = cell->parameters[ID::SRST_VALUE]; + SigSpec rbit = q_norm.extract(bit, &rval); + if (cell->parameters[ID::SRST_POLARITY].as_bool()) + d = module->Mux(NEW_ID, d, rbit, cell->getPort(ID::SRST)); + else + d = module->Mux(NEW_ID, rbit, d, cell->getPort(ID::SRST)); + } + + if (cell->type.in(ID($dffe), ID($sdffe), ID($sdffce))) { + if (cell->parameters[ID::EN_POLARITY].as_bool()) + d = module->Mux(NEW_ID, bit, d, cell->getPort(ID::EN)); + else + d = module->Mux(NEW_ID, d, bit, cell->getPort(ID::EN)); + } + + if (cell->type.in(ID($sdff), ID($sdffe))) { + SigSpec rval = cell->parameters[ID::SRST_VALUE]; + SigSpec rbit = q_norm.extract(bit, &rval); + if (cell->parameters[ID::SRST_POLARITY].as_bool()) + d = module->Mux(NEW_ID, d, rbit, cell->getPort(ID::SRST)); + else + d = module->Mux(NEW_ID, rbit, d, cell->getPort(ID::SRST)); + } + + cache[bit] = d; + bit = d; + clk = this_clk; + clk_polarity = this_clk_polarity; + candidate_dffs.insert(cell); + goto replaced_this_bit; + } + + return false; + replaced_this_bit:; + } + + return true; + } + + bool find_sig_after_dffe(RTLIL::SigSpec &sig, RTLIL::SigSpec &clk, bool &clk_polarity, RTLIL::SigSpec &en, bool &en_polarity) + { + sigmap.apply(sig); + + for (auto &bit : sig) + { + if (bit.wire == NULL) + continue; + + for (auto cell : dff_cells) + { + if (forward_merged_dffs.count(cell)) + continue; + if (!cell->type.in(ID($dff), ID($dffe))) continue; SigSpec this_clk = cell->getPort(ID::CLK); bool this_clk_polarity = cell->parameters[ID::CLK_POLARITY].as_bool(); + SigSpec this_en = State::S1; + bool this_en_polarity = true; + + if (cell->type == ID($dffe)) { + this_en = cell->getPort(ID::EN); + this_en_polarity = cell->parameters[ID::EN_POLARITY].as_bool(); + } if (invbits.count(this_clk)) { this_clk = invbits.at(this_clk); this_clk_polarity = !this_clk_polarity; } + if (invbits.count(this_en)) { + this_en = invbits.at(this_en); + this_en_polarity = !this_en_polarity; + } + if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) { if (this_clk != clk) continue; if (this_clk_polarity != clk_polarity) continue; + if (this_en != en) + continue; + if (this_en_polarity != en_polarity) + continue; } - RTLIL::SigSpec q_norm = cell->getPort(after ? ID::D : ID::Q); + RTLIL::SigSpec q_norm = cell->getPort(ID::D); sigmap.apply(q_norm); - RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(after ? ID::Q : ID::D)); + RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(ID::Q)); if (d.size() != 1) continue; - if (after && init_bits.count(d)) + if (initvals(d) != State::Sx) return false; bit = d; clk = this_clk; clk_polarity = this_clk_polarity; + en = this_en; + en_polarity = this_en_polarity; candidate_dffs.insert(cell); goto replaced_this_bit; } @@ -161,7 +254,7 @@ struct MemoryDffWorker RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size()); for (auto cell : module->cells()) - if (cell->type == ID($dff)) { + if (cell->type.in(ID($dff), ID($dffe))) { RTLIL::SigSpec new_q = cell->getPort(ID::Q); new_q.replace(sig, new_sig); cell->setPort(ID::Q, new_q); @@ -173,8 +266,10 @@ struct MemoryDffWorker log("Checking cell `%s' in module `%s': ", cell->name.c_str(), module->name.c_str()); bool clk_polarity = 0; + bool en_polarity = 0; RTLIL::SigSpec clk_data = RTLIL::SigSpec(RTLIL::State::Sx); + RTLIL::SigSpec en_data; RTLIL::SigSpec sig_data = cell->getPort(ID::DATA); for (auto bit : sigmap(sig_data)) @@ -198,9 +293,14 @@ struct MemoryDffWorker if (sigbit_users_count[bit] > 1) goto skip_ff_after_read_merging; - if (find_sig_before_dff(sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx) && + if (find_sig_after_dffe(sig_data, clk_data, clk_polarity, en_data, en_polarity) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx) && std::all_of(check_q.begin(), check_q.end(), [&](const SigSpec &cq) {return cq == sig_data; })) { + if (en_data != State::S1 || !en_polarity) { + if (!en_polarity) + en_data = module->LogicNot(NEW_ID, en_data); + en.append(en_data); + } disconnect_dff(sig_data); cell->setPort(ID::CLK, clk_data); cell->setPort(ID::EN, en.size() > 1 ? module->ReduceAnd(NEW_ID, en) : en); @@ -214,11 +314,13 @@ struct MemoryDffWorker } else { - if (find_sig_before_dff(sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx)) + if (find_sig_after_dffe(sig_data, clk_data, clk_polarity, en_data, en_polarity) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx)) { + if (!en_polarity) + en_data = module->LogicNot(NEW_ID, en_data); disconnect_dff(sig_data); cell->setPort(ID::CLK, clk_data); - cell->setPort(ID::EN, State::S1); + cell->setPort(ID::EN, en_data); cell->setPort(ID::DATA, sig_data); cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1); cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity); @@ -256,7 +358,7 @@ struct MemoryDffWorker } for (auto cell : module->cells()) { - if (cell->type == ID($dff)) + if (cell->type.in(ID($dff), ID($dffe), ID($sdff), ID($sdffe), ID($sdffce))) dff_cells.push_back(cell); if (cell->type == ID($mux)) { mux_cells_a[sigmap(cell->getPort(ID::A))] = cell; @@ -291,7 +393,7 @@ struct MemoryDffWorker struct MemoryDffPass : public Pass { MemoryDffPass() : Pass("memory_dff", "merge input/output DFFs into memories") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -305,7 +407,7 @@ struct MemoryDffPass : public Pass { log(" do not merge registers on read ports\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool flag_wr_only = false; diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 9d455f55b..032b8fbbd 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -19,6 +19,7 @@ #include "kernel/register.h" #include "kernel/log.h" +#include "kernel/mem.h" #include <sstream> #include <set> #include <stdlib.h> @@ -97,35 +98,26 @@ struct MemoryMapWorker return bit.wire; } - void handle_cell(RTLIL::Cell *cell) + void handle_memory(Mem &mem) { std::set<int> static_ports; std::map<int, RTLIL::SigSpec> static_cells_map; - int wr_ports = cell->parameters[ID::WR_PORTS].as_int(); - int rd_ports = cell->parameters[ID::RD_PORTS].as_int(); - - int mem_size = cell->parameters[ID::SIZE].as_int(); - int mem_width = cell->parameters[ID::WIDTH].as_int(); - int mem_offset = cell->parameters[ID::OFFSET].as_int(); - int mem_abits = cell->parameters[ID::ABITS].as_int(); - - SigSpec init_data = cell->getParam(ID::INIT); - init_data.extend_u0(mem_size*mem_width, true); + SigSpec init_data = mem.get_init_data(); // delete unused memory cell - if (wr_ports == 0 && rd_ports == 0) { - module->remove(cell); + if (mem.rd_ports.empty()) { + mem.remove(); return; } - // check if attributes allow us to infer FFRAM for this cell + // check if attributes allow us to infer FFRAM for this memory for (const auto &attr : attributes) { - if (cell->attributes.count(attr.first)) { - const auto &cell_attr = cell->attributes[attr.first]; + if (mem.attributes.count(attr.first)) { + const auto &cell_attr = mem.attributes[attr.first]; if (attr.second.empty()) { - log("Not mapping memory cell %s in module %s (attribute %s is set).\n", - cell->name.c_str(), module->name.c_str(), attr.first.c_str()); + log("Not mapping memory %s in module %s (attribute %s is set).\n", + mem.memid.c_str(), module->name.c_str(), attr.first.c_str()); return; } @@ -138,11 +130,11 @@ struct MemoryMapWorker } if (!found) { if (cell_attr.flags & RTLIL::CONST_FLAG_STRING) { - log("Not mapping memory cell %s in module %s (attribute %s is set to \"%s\").\n", - cell->name.c_str(), module->name.c_str(), attr.first.c_str(), cell_attr.decode_string().c_str()); + log("Not mapping memory %s in module %s (attribute %s is set to \"%s\").\n", + mem.memid.c_str(), module->name.c_str(), attr.first.c_str(), cell_attr.decode_string().c_str()); } else { - log("Not mapping memory cell %s in module %s (attribute %s is set to %d).\n", - cell->name.c_str(), module->name.c_str(), attr.first.c_str(), cell_attr.as_int()); + log("Not mapping memory %s in module %s (attribute %s is set to %d).\n", + mem.memid.c_str(), module->name.c_str(), attr.first.c_str(), cell_attr.as_int()); } return; } @@ -150,82 +142,75 @@ struct MemoryMapWorker } // all write ports must share the same clock - RTLIL::SigSpec clocks = cell->getPort(ID::WR_CLK); - RTLIL::Const clocks_pol = cell->parameters[ID::WR_CLK_POLARITY]; - RTLIL::Const clocks_en = cell->parameters[ID::WR_CLK_ENABLE]; - clocks_pol.bits.resize(wr_ports); - clocks_en.bits.resize(wr_ports); RTLIL::SigSpec refclock; - RTLIL::State refclock_pol = RTLIL::State::Sx; - for (int i = 0; i < clocks.size(); i++) { - RTLIL::SigSpec wr_en = cell->getPort(ID::WR_EN).extract(i * mem_width, mem_width); - if (wr_en.is_fully_const() && !wr_en.as_bool()) { + bool refclock_pol = false; + for (int i = 0; i < GetSize(mem.wr_ports); i++) { + auto &port = mem.wr_ports[i]; + if (port.en.is_fully_const() && !port.en.as_bool()) { static_ports.insert(i); continue; } - if (clocks_en.bits[i] != RTLIL::State::S1) { - RTLIL::SigSpec wr_addr = cell->getPort(ID::WR_ADDR).extract(i*mem_abits, mem_abits); - RTLIL::SigSpec wr_data = cell->getPort(ID::WR_DATA).extract(i*mem_width, mem_width); - if (wr_addr.is_fully_const()) { - // FIXME: Actually we should check for wr_en.is_fully_const() also and - // create a $adff cell with this ports wr_en input as reset pin when wr_en + if (!port.clk_enable) { + if (port.addr.is_fully_const()) { + // FIXME: Actually we should check for port.en.is_fully_const() also and + // create a $adff cell with this ports port.en input as reset pin when port.en // is not a simple static 1. - static_cells_map[wr_addr.as_int() - mem_offset] = wr_data; + static_cells_map[port.addr.as_int() - mem.start_offset] = port.data; static_ports.insert(i); continue; } - log("Not mapping memory cell %s in module %s (write port %d has no clock).\n", - cell->name.c_str(), module->name.c_str(), i); + log("Not mapping memory %s in module %s (write port %d has no clock).\n", + mem.memid.c_str(), module->name.c_str(), i); return; } if (refclock.size() == 0) { - refclock = clocks.extract(i, 1); - refclock_pol = clocks_pol.bits[i]; + refclock = port.clk; + refclock_pol = port.clk_polarity; } - if (clocks.extract(i, 1) != refclock || clocks_pol.bits[i] != refclock_pol) { - log("Not mapping memory cell %s in module %s (write clock %d is incompatible with other clocks).\n", - cell->name.c_str(), module->name.c_str(), i); + if (port.clk != refclock || port.clk_polarity != refclock_pol) { + log("Not mapping memory %s in module %s (write clock %d is incompatible with other clocks).\n", + mem.memid.c_str(), module->name.c_str(), i); return; } } - log("Mapping memory cell %s in module %s:\n", cell->name.c_str(), module->name.c_str()); + log("Mapping memory %s in module %s:\n", mem.memid.c_str(), module->name.c_str()); std::vector<RTLIL::SigSpec> data_reg_in; std::vector<RTLIL::SigSpec> data_reg_out; int count_static = 0; - for (int i = 0; i < mem_size; i++) + for (int i = 0; i < mem.size; i++) { if (static_cells_map.count(i) > 0) { - data_reg_in.push_back(RTLIL::SigSpec(RTLIL::State::Sz, mem_width)); + data_reg_in.push_back(RTLIL::SigSpec(RTLIL::State::Sz, mem.width)); data_reg_out.push_back(static_cells_map[i]); count_static++; } else { - RTLIL::Cell *c = module->addCell(genid(cell->name, "", i), ID($dff)); - c->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH]; - if (clocks_pol.bits.size() > 0) { - c->parameters[ID::CLK_POLARITY] = RTLIL::Const(clocks_pol.bits[0]); - c->setPort(ID::CLK, clocks.extract(0, 1)); + RTLIL::Cell *c = module->addCell(genid(mem.memid, "", i), ID($dff)); + c->parameters[ID::WIDTH] = mem.width; + if (GetSize(refclock) != 0) { + c->parameters[ID::CLK_POLARITY] = RTLIL::Const(refclock_pol); + c->setPort(ID::CLK, refclock); } else { c->parameters[ID::CLK_POLARITY] = RTLIL::Const(RTLIL::State::S1); c->setPort(ID::CLK, RTLIL::SigSpec(RTLIL::State::S0)); } - RTLIL::Wire *w_in = module->addWire(genid(cell->name, "", i, "$d"), mem_width); + RTLIL::Wire *w_in = module->addWire(genid(mem.memid, "", i, "$d"), mem.width); data_reg_in.push_back(RTLIL::SigSpec(w_in)); c->setPort(ID::D, data_reg_in.back()); - std::string w_out_name = stringf("%s[%d]", cell->parameters[ID::MEMID].decode_string().c_str(), i); + std::string w_out_name = stringf("%s[%d]", mem.memid.c_str(), i); if (module->wires_.count(w_out_name) > 0) - w_out_name = genid(cell->name, "", i, "$q"); + w_out_name = genid(mem.memid, "", i, "$q"); - RTLIL::Wire *w_out = module->addWire(w_out_name, mem_width); - SigSpec w_init = init_data.extract(i*mem_width, mem_width); + 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(); @@ -235,76 +220,39 @@ struct MemoryMapWorker } } - log(" created %d $dff cells and %d static cells of width %d.\n", mem_size-count_static, count_static, mem_width); + log(" created %d $dff cells and %d static cells of width %d.\n", mem.size-count_static, count_static, mem.width); int count_dff = 0, count_mux = 0, count_wrmux = 0; - for (int i = 0; i < cell->parameters[ID::RD_PORTS].as_int(); i++) + int abits = ceil_log2(mem.size); + for (int i = 0; i < GetSize(mem.rd_ports); i++) { - RTLIL::SigSpec rd_addr = cell->getPort(ID::RD_ADDR).extract(i*mem_abits, mem_abits); + auto &port = mem.rd_ports[i]; + if (mem.extract_rdff(i)) + count_dff++; + RTLIL::SigSpec rd_addr = port.addr; + rd_addr.extend_u0(abits, false); - if (mem_offset) - rd_addr = module->Sub(NEW_ID, rd_addr, SigSpec(mem_offset, GetSize(rd_addr))); + if (mem.start_offset) + rd_addr = module->Sub(NEW_ID, rd_addr, SigSpec(mem.start_offset, abits)); std::vector<RTLIL::SigSpec> rd_signals; - rd_signals.push_back(cell->getPort(ID::RD_DATA).extract(i*mem_width, mem_width)); - - if (cell->parameters[ID::RD_CLK_ENABLE].bits[i] == RTLIL::State::S1) - { - RTLIL::Cell *dff_cell = nullptr; - - if (cell->parameters[ID::RD_TRANSPARENT].bits[i] == RTLIL::State::S1) - { - dff_cell = module->addCell(genid(cell->name, "$rdreg", i), ID($dff)); - dff_cell->parameters[ID::WIDTH] = RTLIL::Const(mem_abits); - dff_cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(cell->parameters[ID::RD_CLK_POLARITY].bits[i]); - dff_cell->setPort(ID::CLK, cell->getPort(ID::RD_CLK).extract(i, 1)); - dff_cell->setPort(ID::D, rd_addr); - count_dff++; - - RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits); - - dff_cell->setPort(ID::Q, RTLIL::SigSpec(w)); - rd_addr = RTLIL::SigSpec(w); - } - else - { - dff_cell = module->addCell(genid(cell->name, "$rdreg", i), ID($dff)); - dff_cell->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH]; - dff_cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(cell->parameters[ID::RD_CLK_POLARITY].bits[i]); - dff_cell->setPort(ID::CLK, cell->getPort(ID::RD_CLK).extract(i, 1)); - dff_cell->setPort(ID::Q, rd_signals.back()); - count_dff++; - - RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$d"), mem_width); - - rd_signals.clear(); - rd_signals.push_back(RTLIL::SigSpec(w)); - dff_cell->setPort(ID::D, rd_signals.back()); - } - - SigBit en_bit = cell->getPort(ID::RD_EN).extract(i); - if (en_bit != State::S1) { - SigSpec new_d = module->Mux(genid(cell->name, "$rdenmux", i), - dff_cell->getPort(ID::Q), dff_cell->getPort(ID::D), en_bit); - dff_cell->setPort(ID::D, new_d); - } - } + rd_signals.push_back(port.data); - for (int j = 0; j < mem_abits; j++) + for (int j = 0; j < abits; j++) { std::vector<RTLIL::SigSpec> next_rd_signals; for (size_t k = 0; k < rd_signals.size(); k++) { - RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), ID($mux)); - c->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH]; + RTLIL::Cell *c = module->addCell(genid(mem.memid, "$rdmux", i, "", j, "", k), ID($mux)); + c->parameters[ID::WIDTH] = mem.width; c->setPort(ID::Y, rd_signals[k]); - c->setPort(ID::S, rd_addr.extract(mem_abits-j-1, 1)); + c->setPort(ID::S, rd_addr.extract(abits-j-1, 1)); count_mux++; - c->setPort(ID::A, module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width)); - c->setPort(ID::B, module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width)); + c->setPort(ID::A, module->addWire(genid(mem.memid, "$rdmux", i, "", j, "", k, "$a"), mem.width)); + c->setPort(ID::B, module->addWire(genid(mem.memid, "$rdmux", i, "", j, "", k, "$b"), mem.width)); next_rd_signals.push_back(c->getPort(ID::A)); next_rd_signals.push_back(c->getPort(ID::B)); @@ -313,38 +261,37 @@ struct MemoryMapWorker next_rd_signals.swap(rd_signals); } - for (int j = 0; j < mem_size; j++) + for (int j = 0; j < mem.size; j++) module->connect(RTLIL::SigSig(rd_signals[j], data_reg_out[j])); } log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux); - for (int i = 0; i < mem_size; i++) + for (int i = 0; i < mem.size; i++) { if (static_cells_map.count(i) > 0) continue; RTLIL::SigSpec sig = data_reg_out[i]; - for (int j = 0; j < cell->parameters[ID::WR_PORTS].as_int(); j++) + for (int j = 0; j < GetSize(mem.wr_ports); j++) { - RTLIL::SigSpec wr_addr = cell->getPort(ID::WR_ADDR).extract(j*mem_abits, mem_abits); - RTLIL::SigSpec wr_data = cell->getPort(ID::WR_DATA).extract(j*mem_width, mem_width); - RTLIL::SigSpec wr_en = cell->getPort(ID::WR_EN).extract(j*mem_width, mem_width); + auto &port = mem.wr_ports[j]; + RTLIL::SigSpec wr_addr = port.addr; - if (mem_offset) - wr_addr = module->Sub(NEW_ID, wr_addr, SigSpec(mem_offset, GetSize(wr_addr))); + if (mem.start_offset) + wr_addr = module->Sub(NEW_ID, wr_addr, SigSpec(mem.start_offset, GetSize(wr_addr))); - RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(i, mem_abits)); + RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(i, GetSize(wr_addr))); int wr_offset = 0; - while (wr_offset < wr_en.size()) + while (wr_offset < port.en.size()) { int wr_width = 1; - RTLIL::SigSpec wr_bit = wr_en.extract(wr_offset, 1); + RTLIL::SigSpec wr_bit = port.en.extract(wr_offset, 1); - while (wr_offset + wr_width < wr_en.size()) { - RTLIL::SigSpec next_wr_bit = wr_en.extract(wr_offset + wr_width, 1); + while (wr_offset + wr_width < port.en.size()) { + RTLIL::SigSpec next_wr_bit = port.en.extract(wr_offset + wr_width, 1); if (next_wr_bit != wr_bit) break; wr_width++; @@ -354,7 +301,7 @@ struct MemoryMapWorker if (wr_bit != State::S1) { - RTLIL::Cell *c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), ID($and)); + RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wren", i, "", j, "", wr_offset), ID($and)); c->parameters[ID::A_SIGNED] = RTLIL::Const(0); c->parameters[ID::B_SIGNED] = RTLIL::Const(0); c->parameters[ID::A_WIDTH] = RTLIL::Const(1); @@ -363,17 +310,17 @@ struct MemoryMapWorker c->setPort(ID::A, w); c->setPort(ID::B, wr_bit); - w = module->addWire(genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y")); + w = module->addWire(genid(mem.memid, "$wren", i, "", j, "", wr_offset, "$y")); c->setPort(ID::Y, RTLIL::SigSpec(w)); } - RTLIL::Cell *c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), ID($mux)); + RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wrmux", i, "", j, "", wr_offset), ID($mux)); c->parameters[ID::WIDTH] = wr_width; c->setPort(ID::A, sig.extract(wr_offset, wr_width)); - c->setPort(ID::B, wr_data.extract(wr_offset, wr_width)); + c->setPort(ID::B, port.data.extract(wr_offset, wr_width)); c->setPort(ID::S, RTLIL::SigSpec(w)); - w = module->addWire(genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"), wr_width); + w = module->addWire(genid(mem.memid, "$wrmux", i, "", j, "", wr_offset, "$y"), wr_width); c->setPort(ID::Y, w); sig.replace(wr_offset, w); @@ -387,23 +334,19 @@ struct MemoryMapWorker log(" write interface: %d write mux blocks.\n", count_wrmux); - module->remove(cell); + mem.remove(); } void run() { - std::vector<RTLIL::Cell*> cells; - for (auto cell : module->selected_cells()) - if (cell->type == ID($mem)) - cells.push_back(cell); - for (auto cell : cells) - handle_cell(cell); + for (auto &mem : Mem::get_selected_memories(module)) + handle_memory(mem); } }; struct MemoryMapPass : public Pass { MemoryMapPass() : Pass("memory_map", "translate multiport memories to basic cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -425,12 +368,12 @@ struct MemoryMapPass : public Pass { log(" for -attr, ignore case of <value>.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool attr_icase = false; dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes; - log_header(design, "Executing MEMORY_MAP pass (converting $mem cells to logic and flip-flops).\n"); + log_header(design, "Executing MEMORY_MAP pass (converting memories to logic and flip-flops).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) diff --git a/passes/memory/memory_memx.cc b/passes/memory/memory_memx.cc index 5d5f61c7d..02e00cf30 100644 --- a/passes/memory/memory_memx.cc +++ b/passes/memory/memory_memx.cc @@ -28,7 +28,7 @@ PRIVATE_NAMESPACE_BEGIN struct MemoryMemxPass : public Pass { MemoryMemxPass() : Pass("memory_memx", "emulate vlog sim behavior for mem ports") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -38,7 +38,7 @@ struct MemoryMemxPass : public Pass { log("behavior for out-of-bounds memory reads and writes.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing MEMORY_MEMX pass (converting $mem cells to logic and flip-flops).\n"); extra_args(args, 1, design); diff --git a/passes/memory/memory_nordff.cc b/passes/memory/memory_nordff.cc index 487785397..a4fdcfc38 100644 --- a/passes/memory/memory_nordff.cc +++ b/passes/memory/memory_nordff.cc @@ -19,13 +19,14 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct MemoryNordffPass : public Pass { MemoryNordffPass() : Pass("memory_nordff", "extract read port FFs from memories") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -35,9 +36,9 @@ struct MemoryNordffPass : public Pass { log("similar to what one would get from calling memory_dff with -nordff.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { - log_header(design, "Executing MEMORY_NORDFF pass (extracting $dff cells from $mem).\n"); + log_header(design, "Executing MEMORY_NORDFF pass (extracting $dff cells from memories).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -50,70 +51,15 @@ struct MemoryNordffPass : public Pass { extra_args(args, argidx, design); for (auto module : design->selected_modules()) - for (auto cell : vector<Cell*>(module->selected_cells())) + for (auto &mem : Mem::get_selected_memories(module)) { - if (cell->type != ID($mem)) - continue; + bool changed = false; + for (int i = 0; i < GetSize(mem.rd_ports); i++) + if (mem.extract_rdff(i)) + changed = true; - int rd_ports = cell->getParam(ID::RD_PORTS).as_int(); - int abits = cell->getParam(ID::ABITS).as_int(); - int width = cell->getParam(ID::WIDTH).as_int(); - - SigSpec rd_addr = cell->getPort(ID::RD_ADDR); - SigSpec rd_data = cell->getPort(ID::RD_DATA); - SigSpec rd_clk = cell->getPort(ID::RD_CLK); - SigSpec rd_en = cell->getPort(ID::RD_EN); - Const rd_clk_enable = cell->getParam(ID::RD_CLK_ENABLE); - Const rd_clk_polarity = cell->getParam(ID::RD_CLK_POLARITY); - - for (int i = 0; i < rd_ports; i++) - { - bool clk_enable = rd_clk_enable[i] == State::S1; - - if (clk_enable) - { - bool clk_polarity = cell->getParam(ID::RD_CLK_POLARITY)[i] == State::S1; - bool transparent = cell->getParam(ID::RD_TRANSPARENT)[i] == State::S1; - - SigSpec clk = cell->getPort(ID::RD_CLK)[i] ; - SigSpec en = cell->getPort(ID::RD_EN)[i]; - Cell *c; - - if (transparent) - { - SigSpec sig_q = module->addWire(NEW_ID, abits); - SigSpec sig_d = rd_addr.extract(abits * i, abits); - rd_addr.replace(abits * i, sig_q); - if (en != State::S1) - sig_d = module->Mux(NEW_ID, sig_q, sig_d, en); - c = module->addDff(NEW_ID, clk, sig_d, sig_q, clk_polarity); - } - else - { - SigSpec sig_d = module->addWire(NEW_ID, width); - SigSpec sig_q = rd_data.extract(width * i, width); - rd_data.replace(width *i, sig_d); - if (en != State::S1) - sig_d = module->Mux(NEW_ID, sig_q, sig_d, en); - c = module->addDff(NEW_ID, clk, sig_d, sig_q, clk_polarity); - } - - log("Extracted %s FF from read port %d of %s.%s: %s\n", transparent ? "addr" : "data", - i, log_id(module), log_id(cell), log_id(c)); - } - - rd_en[i] = State::S1; - rd_clk[i] = State::S0; - rd_clk_enable[i] = State::S0; - rd_clk_polarity[i] = State::S1; - } - - cell->setPort(ID::RD_ADDR, rd_addr); - cell->setPort(ID::RD_DATA, rd_data); - cell->setPort(ID::RD_CLK, rd_clk); - cell->setPort(ID::RD_EN, rd_en); - cell->setParam(ID::RD_CLK_ENABLE, rd_clk_enable); - cell->setParam(ID::RD_CLK_POLARITY, rd_clk_polarity); + if (changed) + mem.emit(); } } } MemoryNordffPass; diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index e11958bd6..7315aeae1 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -734,7 +734,7 @@ struct MemoryShareWorker struct MemorySharePass : public Pass { MemorySharePass() : Pass("memory_share", "consolidate memory ports") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -760,7 +760,7 @@ struct MemorySharePass : public Pass { log("optimizations) such as \"share\" and \"opt_merge\".\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells).\n"); extra_args(args, 1, design); MemoryShareWorker msw(design); diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index 8d284edcd..16b57d9c3 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -17,117 +17,15 @@ * */ -#include "kernel/register.h" -#include "kernel/log.h" -#include <sstream> -#include <algorithm> -#include <stdlib.h> +#include "kernel/yosys.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) -{ - log("Creating $memrd and $memwr for memory `%s' in module `%s':\n", - memory->name.c_str(), module->name.c_str()); - - RTLIL::IdString mem_name = RTLIL::escape_id(memory->parameters.at(ID::MEMID).decode_string()); - - while (module->memories.count(mem_name) != 0) - mem_name = mem_name.str() + stringf("_%d", autoidx++); - - RTLIL::Memory *mem = new RTLIL::Memory; - mem->name = mem_name; - mem->width = memory->parameters.at(ID::WIDTH).as_int(); - mem->start_offset = memory->parameters.at(ID::OFFSET).as_int(); - mem->size = memory->parameters.at(ID::SIZE).as_int(); - module->memories[mem_name] = mem; - - int abits = memory->parameters.at(ID::ABITS).as_int(); - int num_rd_ports = memory->parameters.at(ID::RD_PORTS).as_int(); - int num_wr_ports = memory->parameters.at(ID::WR_PORTS).as_int(); - - for (int i = 0; i < num_rd_ports; i++) - { - RTLIL::Cell *cell = module->addCell(NEW_ID, ID($memrd)); - cell->parameters[ID::MEMID] = mem_name.str(); - cell->parameters[ID::ABITS] = memory->parameters.at(ID::ABITS); - cell->parameters[ID::WIDTH] = memory->parameters.at(ID::WIDTH); - cell->parameters[ID::CLK_ENABLE] = RTLIL::SigSpec(memory->parameters.at(ID::RD_CLK_ENABLE)).extract(i, 1).as_const(); - cell->parameters[ID::CLK_POLARITY] = RTLIL::SigSpec(memory->parameters.at(ID::RD_CLK_POLARITY)).extract(i, 1).as_const(); - cell->parameters[ID::TRANSPARENT] = RTLIL::SigSpec(memory->parameters.at(ID::RD_TRANSPARENT)).extract(i, 1).as_const(); - cell->setPort(ID::CLK, memory->getPort(ID::RD_CLK).extract(i, 1)); - cell->setPort(ID::EN, memory->getPort(ID::RD_EN).extract(i, 1)); - cell->setPort(ID::ADDR, memory->getPort(ID::RD_ADDR).extract(i*abits, abits)); - cell->setPort(ID::DATA, memory->getPort(ID::RD_DATA).extract(i*mem->width, mem->width)); - } - - for (int i = 0; i < num_wr_ports; i++) - { - RTLIL::Cell *cell = module->addCell(NEW_ID, ID($memwr)); - cell->parameters[ID::MEMID] = mem_name.str(); - cell->parameters[ID::ABITS] = memory->parameters.at(ID::ABITS); - cell->parameters[ID::WIDTH] = memory->parameters.at(ID::WIDTH); - cell->parameters[ID::CLK_ENABLE] = RTLIL::SigSpec(memory->parameters.at(ID::WR_CLK_ENABLE)).extract(i, 1).as_const(); - cell->parameters[ID::CLK_POLARITY] = RTLIL::SigSpec(memory->parameters.at(ID::WR_CLK_POLARITY)).extract(i, 1).as_const(); - cell->parameters[ID::PRIORITY] = i; - cell->setPort(ID::CLK, memory->getPort(ID::WR_CLK).extract(i, 1)); - cell->setPort(ID::EN, memory->getPort(ID::WR_EN).extract(i*mem->width, mem->width)); - cell->setPort(ID::ADDR, memory->getPort(ID::WR_ADDR).extract(i*abits, abits)); - cell->setPort(ID::DATA, memory->getPort(ID::WR_DATA).extract(i*mem->width, mem->width)); - } - - Const initval = memory->parameters.at(ID::INIT); - RTLIL::Cell *last_init_cell = nullptr; - SigSpec last_init_data; - int last_init_addr=0; - - for (int i = 0; i < GetSize(initval) && i/mem->width < (1 << abits); i += mem->width) { - Const val = initval.extract(i, mem->width, State::Sx); - for (auto bit : val.bits) - if (bit != State::Sx) - goto found_non_undef_initval; - continue; - found_non_undef_initval: - if (last_init_cell && last_init_addr+1 == i/mem->width) { - last_init_cell->parameters[ID::WORDS] = last_init_cell->parameters[ID::WORDS].as_int() + 1; - last_init_data.append(val); - last_init_addr++; - } else { - if (last_init_cell) - last_init_cell->setPort(ID::DATA, last_init_data); - RTLIL::Cell *cell = module->addCell(NEW_ID, ID($meminit)); - cell->parameters[ID::MEMID] = mem_name.str(); - cell->parameters[ID::ABITS] = memory->parameters.at(ID::ABITS); - cell->parameters[ID::WIDTH] = memory->parameters.at(ID::WIDTH); - cell->parameters[ID::WORDS] = 1; - cell->parameters[ID::PRIORITY] = i/mem->width; - cell->setPort(ID::ADDR, SigSpec(i/mem->width, abits)); - last_init_cell = cell; - last_init_addr = i/mem->width; - last_init_data = val; - } - } - - if (last_init_cell) - last_init_cell->setPort(ID::DATA, last_init_data); - - module->remove(memory); -} - -void handle_module(RTLIL::Design *design, RTLIL::Module *module) -{ - std::vector<RTLIL::IdString> memcells; - for (auto cell : module->cells()) - if (cell->type == ID($mem) && design->selected(module, cell)) - memcells.push_back(cell->name); - for (auto &it : memcells) - handle_memory(module, module->cell(it)); -} - struct MemoryUnpackPass : public Pass { MemoryUnpackPass() : Pass("memory_unpack", "unpack multi-port memory cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -137,11 +35,17 @@ struct MemoryUnpackPass : public Pass { log("$memwr cells. It is the counterpart to the memory_collect pass.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing MEMORY_UNPACK pass (generating $memrd/$memwr cells form $mem cells).\n"); extra_args(args, 1, design); - for (auto module : design->selected_modules()) - handle_module(design, module); + for (auto module : design->selected_modules()) { + for (auto &mem : Mem::get_selected_memories(module)) { + if (mem.packed) { + mem.packed = false; + mem.emit(); + } + } + } } } MemoryUnpackPass; diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index 3133927bb..4ae9b8895 100644 --- a/passes/opt/Makefile.inc +++ b/passes/opt/Makefile.inc @@ -4,7 +4,7 @@ OBJS += passes/opt/opt_merge.o OBJS += passes/opt/opt_mem.o OBJS += passes/opt/opt_muxtree.o OBJS += passes/opt/opt_reduce.o -OBJS += passes/opt/opt_rmdff.o +OBJS += passes/opt/opt_dff.o OBJS += passes/opt/opt_share.o OBJS += passes/opt/opt_clean.o OBJS += passes/opt/opt_expr.o diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index 9df49ab3c..aa5f82437 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -326,7 +326,7 @@ struct MuxpackWorker struct MuxpackPass : public Pass { MuxpackPass() : Pass("muxpack", "$mux/$pmux cascades to $pmux") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -341,7 +341,7 @@ struct MuxpackPass : public Pass { log("certain that their select inputs are mutually exclusive.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing MUXPACK pass ($mux cell cascades to $pmux).\n"); diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc index 396819883..4b052d9a2 100644 --- a/passes/opt/opt.cc +++ b/passes/opt/opt.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct OptPass : public Pass { OptPass() : Pass("opt", "perform simple optimizations") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -37,42 +37,43 @@ struct OptPass : public Pass { log("a series of trivial optimizations and cleanups. This pass executes the other\n"); log("passes in the following order:\n"); log("\n"); - log(" opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc]\n"); + log(" opt_expr [-mux_undef] [-mux_bool] [-undriven] [-noclkinv] [-fine] [-full] [-keepdc]\n"); log(" opt_merge [-share_all] -nomux\n"); log("\n"); log(" do\n"); log(" opt_muxtree\n"); log(" opt_reduce [-fine] [-full]\n"); log(" opt_merge [-share_all]\n"); - log(" opt_share (-full only)\n"); - log(" opt_rmdff [-keepdc] [-sat]\n"); + log(" opt_share (-full only)\n"); + log(" opt_dff [-nodffe] [-nosdff] [-keepdc] [-sat] (except when called with -noff)\n"); log(" opt_clean [-purge]\n"); - log(" opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc]\n"); + log(" opt_expr [-mux_undef] [-mux_bool] [-undriven] [-noclkinv] [-fine] [-full] [-keepdc]\n"); log(" while <changed design>\n"); log("\n"); log("When called with -fast the following script is used instead:\n"); log("\n"); log(" do\n"); - log(" opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc]\n"); + log(" opt_expr [-mux_undef] [-mux_bool] [-undriven] [-noclkinv] [-fine] [-full] [-keepdc]\n"); log(" opt_merge [-share_all]\n"); - log(" opt_rmdff [-keepdc] [-sat]\n"); + log(" opt_dff [-nodffe] [-nosdff] [-keepdc] [-sat] (except when called with -noff)\n"); log(" opt_clean [-purge]\n"); - log(" while <changed design in opt_rmdff>\n"); + log(" while <changed design in opt_dff>\n"); log("\n"); log("Note: Options in square brackets (such as [-keepdc]) are passed through to\n"); log("the opt_* commands when given to 'opt'.\n"); log("\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string opt_clean_args; std::string opt_expr_args; std::string opt_reduce_args; std::string opt_merge_args; - std::string opt_rmdff_args; + std::string opt_dff_args; bool opt_share = false; bool fast_mode = false; + bool noff_mode = false; log_header(design, "Executing OPT pass (performing simple optimizations).\n"); log_push(); @@ -95,8 +96,8 @@ struct OptPass : public Pass { opt_expr_args += " -undriven"; continue; } - if (args[argidx] == "-clkinv") { - opt_expr_args += " -clkinv"; + if (args[argidx] == "-noclkinv") { + opt_expr_args += " -noclkinv"; continue; } if (args[argidx] == "-fine") { @@ -112,11 +113,19 @@ struct OptPass : public Pass { } if (args[argidx] == "-keepdc") { opt_expr_args += " -keepdc"; - opt_rmdff_args += " -keepdc"; + opt_dff_args += " -keepdc"; + continue; + } + if (args[argidx] == "-nodffe") { + opt_dff_args += " -nodffe"; + continue; + } + if (args[argidx] == "-nosdff") { + opt_dff_args += " -nosdff"; continue; } if (args[argidx] == "-sat") { - opt_rmdff_args += " -sat"; + opt_dff_args += " -sat"; continue; } if (args[argidx] == "-share_all") { @@ -127,6 +136,10 @@ struct OptPass : public Pass { fast_mode = true; continue; } + if (args[argidx] == "-noff") { + noff_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -137,7 +150,8 @@ struct OptPass : public Pass { Pass::call(design, "opt_expr" + opt_expr_args); Pass::call(design, "opt_merge" + opt_merge_args); design->scratchpad_unset("opt.did_something"); - Pass::call(design, "opt_rmdff" + opt_rmdff_args); + if (!noff_mode) + Pass::call(design, "opt_dff" + opt_dff_args); if (design->scratchpad_get_bool("opt.did_something") == false) break; Pass::call(design, "opt_clean" + opt_clean_args); @@ -156,7 +170,8 @@ struct OptPass : public Pass { Pass::call(design, "opt_merge" + opt_merge_args); if (opt_share) Pass::call(design, "opt_share"); - Pass::call(design, "opt_rmdff" + opt_rmdff_args); + if (!noff_mode) + Pass::call(design, "opt_dff" + opt_dff_args); Pass::call(design, "opt_clean" + opt_clean_args); Pass::call(design, "opt_expr" + opt_expr_args); if (design->scratchpad_get_bool("opt.did_something") == false) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index f7de02164..883374cf6 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -59,6 +59,11 @@ struct keep_cache_t found_keep = true; break; } + for (auto wire : module->wires()) + if (wire->get_bool_attribute(ID::keep)) { + found_keep = true; + break; + } cache[module] = found_keep; } @@ -67,7 +72,7 @@ struct keep_cache_t bool query(Cell *cell, bool ignore_specify = false) { - if (cell->type.in(ID($memwr), ID($meminit), ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) + if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) return true; if (!ignore_specify && cell->type.in(ID($specify2), ID($specify3), ID($specrule))) @@ -90,6 +95,8 @@ int count_rm_cells, count_rm_wires; void rmunused_module_cells(Module *module, bool verbose) { SigMap sigmap(module); + dict<IdString, pool<Cell*>> mem2cells; + pool<IdString> mem_unused; pool<Cell*> queue, unused; pool<SigBit> used_raw_bits; dict<SigBit, pool<Cell*>> wire2driver; @@ -103,6 +110,17 @@ void rmunused_module_cells(Module *module, bool verbose) } } + for (auto &it : module->memories) { + mem_unused.insert(it.first); + } + + for (Cell *cell : module->cells()) { + if (cell->type.in(ID($memwr), ID($meminit))) { + IdString mem_id = cell->getParam(ID::MEMID).decode_string(); + mem2cells[mem_id].insert(cell); + } + } + for (auto &it : module->cells_) { Cell *cell = it.second; for (auto &it2 : cell->connections()) { @@ -140,17 +158,33 @@ void rmunused_module_cells(Module *module, bool verbose) while (!queue.empty()) { pool<SigBit> bits; - for (auto cell : queue) - for (auto &it : cell->connections()) - if (!ct_all.cell_known(cell->type) || ct_all.cell_input(cell->type, it.first)) - for (auto bit : sigmap(it.second)) - bits.insert(bit); + pool<IdString> mems; + for (auto cell : queue) { + for (auto &it : cell->connections()) + if (!ct_all.cell_known(cell->type) || ct_all.cell_input(cell->type, it.first)) + for (auto bit : sigmap(it.second)) + bits.insert(bit); + + if (cell->type == ID($memrd)) { + IdString mem_id = cell->getParam(ID::MEMID).decode_string(); + if (mem_unused.count(mem_id)) { + mem_unused.erase(mem_id); + mems.insert(mem_id); + } + } + } queue.clear(); + for (auto bit : bits) for (auto c : wire2driver[bit]) if (unused.count(c)) queue.insert(c), unused.erase(c); + + for (auto mem : mems) + for (auto c : mem2cells[mem]) + if (unused.count(c)) + queue.insert(c), unused.erase(c); } unused.sort(RTLIL::sort_by_name_id<RTLIL::Cell>()); @@ -163,6 +197,14 @@ void rmunused_module_cells(Module *module, bool verbose) count_rm_cells++; } + for (auto it : mem_unused) + { + if (verbose) + log_debug(" removing unused memory `%s'.\n", it.c_str()); + delete module->memories.at(it); + module->memories.erase(it); + } + for (auto &it : module->cells_) { Cell *cell = it.second; for (auto &it2 : cell->connections()) { @@ -202,7 +244,7 @@ bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool ®s, SigPoo if ((w1->port_input && w1->port_output) != (w2->port_input && w2->port_output)) return !(w2->port_input && w2->port_output); - if (w1->name[0] == '\\' && w2->name[0] == '\\') { + if (w1->name.isPublic() && w2->name.isPublic()) { if (regs.check(s1) != regs.check(s2)) return regs.check(s2); if (direct_wires.count(w1) != direct_wires.count(w2)) @@ -215,7 +257,7 @@ bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool ®s, SigPoo return w2->port_output; if (w1->name[0] != w2->name[0]) - return w2->name[0] == '\\'; + return w2->name.isPublic(); int attrs1 = count_nontrivial_wire_attrs(w1); int attrs2 = count_nontrivial_wire_attrs(w2); @@ -526,7 +568,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool struct OptCleanPass : public Pass { OptCleanPass() : Pass("opt_clean", "remove unused cells and wires") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -543,7 +585,7 @@ struct OptCleanPass : public Pass { log(" also remove internal nets if they have a public name\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool purge_mode = false; @@ -592,7 +634,7 @@ struct OptCleanPass : public Pass { struct CleanPass : public Pass { CleanPass() : Pass("clean", "remove unused cells and wires") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -607,7 +649,7 @@ struct CleanPass : public Pass { log("in -purge mode between the commands.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool purge_mode = false; diff --git a/passes/opt/opt_demorgan.cc b/passes/opt/opt_demorgan.cc index 4bc82815b..f0fa86f42 100644 --- a/passes/opt/opt_demorgan.cc +++ b/passes/opt/opt_demorgan.cc @@ -169,7 +169,7 @@ void demorgan_worker( struct OptDemorganPass : public Pass { OptDemorganPass() : Pass("opt_demorgan", "Optimize reductions with DeMorgan equivalents") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -179,7 +179,7 @@ struct OptDemorganPass : public Pass { log("overall gate count of the circuit\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing OPT_DEMORGAN pass (push inverters through $reduce_* cells).\n"); diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc new file mode 100644 index 000000000..a47071a30 --- /dev/null +++ b/passes/opt/opt_dff.cc @@ -0,0 +1,875 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> + * Copyright (C) 2020 Marcelina KoÅ›cielnicka <mwk@0x04.net> + * + * 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/log.h" +#include "kernel/register.h" +#include "kernel/rtlil.h" +#include "kernel/satgen.h" +#include "kernel/sigtools.h" +#include "kernel/ffinit.h" +#include "kernel/ff.h" +#include "passes/techmap/simplemap.h" +#include <stdio.h> +#include <stdlib.h> + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct OptDffOptions +{ + bool nosdff; + bool nodffe; + bool simple_dffe; + bool sat; + bool keepdc; +}; + +struct OptDffWorker +{ + const OptDffOptions &opt; + + Module *module; + typedef std::pair<RTLIL::Cell*, int> cell_int_t; + SigMap sigmap; + FfInitVals initvals; + dict<SigBit, int> bitusers; + dict<SigBit, cell_int_t> bit2mux; + dict<SigBit, RTLIL::Cell*> bit2driver; + + typedef std::map<RTLIL::SigBit, bool> pattern_t; + typedef std::set<pattern_t> patterns_t; + typedef std::pair<RTLIL::SigBit, bool> ctrl_t; + typedef std::set<ctrl_t> ctrls_t; + + ezSatPtr ez; + SatGen satgen; + pool<Cell*> sat_cells; + + // Used as a queue. + std::vector<Cell *> dff_cells; + + OptDffWorker(const OptDffOptions &opt, Module *mod) : opt(opt), module(mod), sigmap(mod), initvals(&sigmap, mod), ez(), satgen(ez.get(), &sigmap) { + // Gathering three kinds of information here for every sigmapped SigBit: + // + // - bitusers: how many users it has (muxes will only be merged into FFs if this is 1, making the FF the only user) + // - bit2mux: the mux cell and bit index that drives it, if any + // - bit2driver: the cell driving it, if any + + for (auto wire : module->wires()) + { + if (wire->port_output) + for (auto bit : sigmap(wire)) + bitusers[bit]++; + } + + for (auto cell : module->cells()) { + if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) { + RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y)); + for (int i = 0; i < GetSize(sig_y); i++) + bit2mux[sig_y[i]] = cell_int_t(cell, i); + } + + for (auto conn : cell->connections()) { + bool is_output = cell->output(conn.first); + if (is_output) { + for (auto bit : sigmap(conn.second)) + bit2driver[bit] = cell; + } + if (!is_output || !cell->known()) { + for (auto bit : sigmap(conn.second)) + bitusers[bit]++; + } + } + + if (module->design->selected(module, cell) && RTLIL::builtin_ff_cell_types().count(cell->type)) + dff_cells.push_back(cell); + } + + } + + std::function<void(Cell*)> sat_import_cell = [&](Cell *c) { + if (!sat_cells.insert(c).second) + return; + if (!satgen.importCell(c)) + return; + for (auto &conn : c->connections()) { + if (!c->input(conn.first)) + continue; + for (auto bit : sigmap(conn.second)) + if (bit2driver.count(bit)) + sat_import_cell(bit2driver.at(bit)); + } + }; + + State combine_const(State a, State b) { + if (a == State::Sx && !opt.keepdc) + return b; + if (b == State::Sx && !opt.keepdc) + return a; + if (a == b) + return a; + return State::Sm; + } + + patterns_t find_muxtree_feedback_patterns(RTLIL::SigBit d, RTLIL::SigBit q, pattern_t path) + { + patterns_t ret; + + if (d == q) { + ret.insert(path); + return ret; + } + + if (bit2mux.count(d) == 0 || bitusers[d] > 1) + return ret; + + cell_int_t mbit = bit2mux.at(d); + RTLIL::SigSpec sig_a = sigmap(mbit.first->getPort(ID::A)); + RTLIL::SigSpec sig_b = sigmap(mbit.first->getPort(ID::B)); + RTLIL::SigSpec sig_s = sigmap(mbit.first->getPort(ID::S)); + int width = GetSize(sig_a), index = mbit.second; + + for (int i = 0; i < GetSize(sig_s); i++) + if (path.count(sig_s[i]) && path.at(sig_s[i])) + { + ret = find_muxtree_feedback_patterns(sig_b[i*width + index], q, path); + + if (sig_b[i*width + index] == q) { + RTLIL::SigSpec s = mbit.first->getPort(ID::B); + s[i*width + index] = RTLIL::Sx; + mbit.first->setPort(ID::B, s); + } + + return ret; + } + + pattern_t path_else = path; + + for (int i = 0; i < GetSize(sig_s); i++) + { + if (path.count(sig_s[i])) + continue; + + pattern_t path_this = path; + path_else[sig_s[i]] = false; + path_this[sig_s[i]] = true; + + for (auto &pat : find_muxtree_feedback_patterns(sig_b[i*width + index], q, path_this)) + ret.insert(pat); + + if (sig_b[i*width + index] == q) { + RTLIL::SigSpec s = mbit.first->getPort(ID::B); + s[i*width + index] = RTLIL::Sx; + mbit.first->setPort(ID::B, s); + } + } + + for (auto &pat : find_muxtree_feedback_patterns(sig_a[index], q, path_else)) + ret.insert(pat); + + if (sig_a[index] == q) { + RTLIL::SigSpec s = mbit.first->getPort(ID::A); + s[index] = RTLIL::Sx; + mbit.first->setPort(ID::A, s); + } + + return ret; + } + + void simplify_patterns(patterns_t&) + { + // TBD + } + + ctrl_t make_patterns_logic(const patterns_t &patterns, const ctrls_t &ctrls, bool make_gates) + { + if (patterns.empty() && GetSize(ctrls) == 1) { + return *ctrls.begin(); + } + + RTLIL::SigSpec or_input; + + for (auto pat : patterns) + { + RTLIL::SigSpec s1, s2; + for (auto it : pat) { + s1.append(it.first); + s2.append(it.second); + } + + RTLIL::SigSpec y = module->addWire(NEW_ID); + RTLIL::Cell *c = module->addNe(NEW_ID, s1, s2, y); + + if (make_gates) { + simplemap(module, c); + module->remove(c); + } + + or_input.append(y); + } + for (auto item : ctrls) { + if (item.second) + or_input.append(item.first); + else if (make_gates) + or_input.append(module->NotGate(NEW_ID, item.first)); + else + or_input.append(module->Not(NEW_ID, item.first)); + } + + if (GetSize(or_input) == 0) + return ctrl_t(State::S1, true); + + if (GetSize(or_input) == 1) + return ctrl_t(or_input, true); + + RTLIL::SigSpec y = module->addWire(NEW_ID); + RTLIL::Cell *c = module->addReduceAnd(NEW_ID, or_input, y); + + if (make_gates) { + simplemap(module, c); + module->remove(c); + } + + return ctrl_t(y, true); + } + + ctrl_t combine_resets(const ctrls_t &ctrls, bool make_gates) + { + if (GetSize(ctrls) == 1) { + return *ctrls.begin(); + } + + RTLIL::SigSpec or_input; + + bool final_pol = false; + for (auto item : ctrls) { + if (item.second) + final_pol = true; + } + + for (auto item : ctrls) { + if (item.second == final_pol) + or_input.append(item.first); + else if (make_gates) + or_input.append(module->NotGate(NEW_ID, item.first)); + else + or_input.append(module->Not(NEW_ID, item.first)); + } + + RTLIL::SigSpec y = module->addWire(NEW_ID); + RTLIL::Cell *c = final_pol ? module->addReduceOr(NEW_ID, or_input, y) : module->addReduceAnd(NEW_ID, or_input, y); + + if (make_gates) { + simplemap(module, c); + module->remove(c); + } + + return ctrl_t(y, final_pol); + } + + bool run() { + // We have all the information we need, and the list of FFs to process as well. Do it. + bool did_something = false; + while (!dff_cells.empty()) { + Cell *cell = dff_cells.back(); + dff_cells.pop_back(); + // Break down the FF into pieces. + FfData ff(&initvals, cell); + bool changed = false; + + if (!ff.width) { + module->remove(cell); + did_something = true; + continue; + } + + if (ff.has_sr) { + bool sr_removed = false; + std::vector<int> keep_bits; + // Check for always-active S/R bits. + for (int i = 0; i < ff.width; i++) { + if (ff.sig_clr[i] == (ff.pol_clr ? State::S1 : State::S0) || (!opt.keepdc && ff.sig_clr[i] == State::Sx)) { + // Always-active clear — connect Q bit to 0. + initvals.remove_init(ff.sig_q[i]); + module->connect(ff.sig_q[i], State::S0); + log("Handling always-active CLR at position %d on %s (%s) from module %s (changing to const driver).\n", + i, log_id(cell), log_id(cell->type), log_id(module)); + sr_removed = true; + } else if (ff.sig_set[i] == (ff.pol_set ? State::S1 : State::S0) || (!opt.keepdc && ff.sig_set[i] == State::Sx)) { + // Always-active set — connect Q bit to 1 if clear inactive, 0 if reset active. + initvals.remove_init(ff.sig_q[i]); + if (!ff.pol_clr) { + module->connect(ff.sig_q[i], ff.sig_clr[i]); + } else if (ff.is_fine) { + module->addNotGate(NEW_ID, ff.sig_q[i], ff.sig_clr[i]); + } else { + module->addNot(NEW_ID, ff.sig_q[i], ff.sig_clr[i]); + } + log("Handling always-active SET at position %d on %s (%s) from module %s (changing to combinatorial circuit).\n", + i, log_id(cell), log_id(cell->type), log_id(module)); + sr_removed = true; + } else { + keep_bits.push_back(i); + } + } + if (sr_removed) { + if (keep_bits.empty()) { + module->remove(cell); + did_something = true; + continue; + } + ff = ff.slice(keep_bits); + changed = true; + } + + if (ff.pol_clr ? ff.sig_clr.is_fully_zero() : ff.sig_clr.is_fully_ones()) { + // CLR is useless, try to kill it. + bool failed = false; + for (int i = 0; i < ff.width; i++) + if (ff.sig_set[i] != ff.sig_set[0]) + failed = true; + if (!failed) { + log("Removing never-active CLR on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_sr = false; + ff.has_arst = true; + ff.pol_arst = ff.pol_set; + ff.sig_arst = ff.sig_set[0]; + ff.val_arst = Const(State::S1, ff.width); + changed = true; + } + } else if (ff.pol_set ? ff.sig_set.is_fully_zero() : ff.sig_set.is_fully_ones()) { + // SET is useless, try to kill it. + bool failed = false; + for (int i = 0; i < ff.width; i++) + if (ff.sig_clr[i] != ff.sig_clr[0]) + failed = true; + if (!failed) { + log("Removing never-active SET on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_sr = false; + ff.has_arst = true; + ff.pol_arst = ff.pol_clr; + ff.sig_arst = ff.sig_clr[0]; + ff.val_arst = Const(State::S0, ff.width); + changed = true; + } + } else if (ff.pol_clr == ff.pol_set) { + // Try a more complex conversion to plain async reset. + State val_neutral = ff.pol_set ? State::S0 : State::S1; + Const val_arst; + SigSpec sig_arst; + if (ff.sig_clr[0] == val_neutral) + sig_arst = ff.sig_set[0]; + else + sig_arst = ff.sig_clr[0]; + bool failed = false; + for (int i = 0; i < ff.width; i++) { + if (ff.sig_clr[i] == sig_arst && ff.sig_set[i] == val_neutral) + val_arst.bits.push_back(State::S0); + else if (ff.sig_set[i] == sig_arst && ff.sig_clr[i] == val_neutral) + val_arst.bits.push_back(State::S1); + else + failed = true; + } + if (!failed) { + log("Converting CLR/SET to ARST on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_sr = false; + ff.has_arst = true; + ff.val_arst = val_arst; + ff.sig_arst = sig_arst; + ff.pol_arst = ff.pol_clr; + changed = true; + } + } + } + + if (ff.has_arst) { + if (ff.sig_arst == (ff.pol_arst ? State::S0 : State::S1)) { + // Always-inactive reset — remove. + log("Removing never-active ARST on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_arst = false; + changed = true; + } else if (ff.sig_arst == (ff.pol_arst ? State::S1 : State::S0) || (!opt.keepdc && ff.sig_arst == State::Sx)) { + // Always-active async reset — change to const driver. + log("Handling always-active ARST on %s (%s) from module %s (changing to const driver).\n", + log_id(cell), log_id(cell->type), log_id(module)); + initvals.remove_init(ff.sig_q); + module->remove(cell); + module->connect(ff.sig_q, ff.val_arst); + did_something = true; + continue; + } + } + + if (ff.has_srst) { + if (ff.sig_srst == (ff.pol_srst ? State::S0 : State::S1)) { + // Always-inactive reset — remove. + log("Removing never-active SRST on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_srst = false; + changed = true; + } else if (ff.sig_srst == (ff.pol_srst ? State::S1 : State::S0) || (!opt.keepdc && ff.sig_srst == State::Sx)) { + // Always-active sync reset — connect to D instead. + log("Handling always-active SRST on %s (%s) from module %s (changing to const D).\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_srst = false; + if (!ff.ce_over_srst) + ff.has_en = false; + ff.sig_d = ff.val_d = ff.val_srst; + ff.d_is_const = true; + changed = true; + } + } + + if (ff.has_en) { + if (ff.sig_en == (ff.pol_en ? State::S0 : State::S1) || (!opt.keepdc && ff.sig_en == State::Sx)) { + // Always-inactive enable — remove. + if (ff.has_clk && ff.has_srst && !ff.ce_over_srst) { + log("Handling never-active EN on %s (%s) from module %s (connecting SRST instead).\n", + log_id(cell), log_id(cell->type), log_id(module)); + // FF with sync reset — connect the sync reset to D instead. + ff.pol_en = ff.pol_srst; + ff.sig_en = ff.sig_srst; + ff.has_srst = false; + ff.sig_d = ff.val_d = ff.val_srst; + ff.d_is_const = true; + changed = true; + } else { + 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 const-input D latch, SR latch, or a const driver). + ff.has_d = ff.has_en = ff.has_clk = false; + changed = true; + } + } else if (ff.sig_en == (ff.pol_en ? State::S1 : State::S0)) { + // Always-active enable. + if (ff.has_clk) { + // For FF, just remove the useless enable. + log("Removing always-active EN on %s (%s) from module %s.\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_en = false; + changed = true; + } else { + // For latches, make a comb circuit, nuke the latch. + log("Handling always-active EN on %s (%s) from module %s (changing to combinatorial circuit).\n", + log_id(cell), log_id(cell->type), log_id(module)); + initvals.remove_init(ff.sig_q); + module->remove(cell); + if (ff.has_sr) { + SigSpec tmp; + if (ff.is_fine) { + if (ff.pol_set) + tmp = module->MuxGate(NEW_ID, ff.sig_d, State::S1, ff.sig_set); + else + tmp = module->MuxGate(NEW_ID, State::S1, ff.sig_d, ff.sig_set); + if (ff.pol_clr) + module->addMuxGate(NEW_ID, tmp, State::S0, ff.sig_clr, ff.sig_q); + else + module->addMuxGate(NEW_ID, State::S0, tmp, ff.sig_clr, ff.sig_q); + } else { + if (ff.pol_set) + tmp = module->Or(NEW_ID, ff.sig_d, ff.sig_set); + else + tmp = module->Or(NEW_ID, ff.sig_d, module->Not(NEW_ID, ff.sig_set)); + if (ff.pol_clr) + module->addAnd(NEW_ID, tmp, module->Not(NEW_ID, ff.sig_clr), ff.sig_q); + else + module->addAnd(NEW_ID, tmp, ff.sig_clr, ff.sig_q); + } + } else if (ff.has_arst) { + if (ff.is_fine) { + if (ff.pol_arst) + module->addMuxGate(NEW_ID, ff.sig_d, ff.val_arst[0], ff.sig_arst, ff.sig_q); + else + module->addMuxGate(NEW_ID, ff.val_arst[0], ff.sig_d, ff.sig_arst, ff.sig_q); + } else { + if (ff.pol_arst) + module->addMux(NEW_ID, ff.sig_d, ff.val_arst, ff.sig_arst, ff.sig_q); + else + module->addMux(NEW_ID, ff.val_arst, ff.sig_d, ff.sig_arst, ff.sig_q); + } + } else { + module->connect(ff.sig_q, ff.sig_d); + } + did_something = true; + continue; + } + } + } + + if (ff.has_clk) { + if (ff.sig_clk.is_fully_const()) { + // Const clock — 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 const CLK on %s (%s) from module %s (removing D path).\n", + log_id(cell), log_id(cell->type), log_id(module)); + ff.has_d = ff.has_en = ff.has_clk = ff.has_srst = false; + changed = true; + } + } + + if (ff.has_d && ff.sig_d == ff.sig_q) { + // Q wrapped back to D, can be removed. + if (ff.has_clk && ff.has_srst) { + // FF with sync reset — connect the sync reset to D instead. + log("Handling D = Q on %s (%s) from module %s (conecting SRST instead).\n", + log_id(cell), log_id(cell->type), log_id(module)); + if (ff.has_en && ff.ce_over_srst) { + if (!ff.pol_en) { + if (ff.is_fine) + ff.sig_en = module->NotGate(NEW_ID, ff.sig_en); + else + ff.sig_en = module->Not(NEW_ID, ff.sig_en); + } + if (!ff.pol_srst) { + if (ff.is_fine) + ff.sig_srst = module->NotGate(NEW_ID, ff.sig_srst); + else + ff.sig_srst = module->Not(NEW_ID, ff.sig_srst); + } + if (ff.is_fine) + ff.sig_en = module->AndGate(NEW_ID, ff.sig_en, ff.sig_srst); + else + ff.sig_en = module->And(NEW_ID, ff.sig_en, ff.sig_srst); + ff.pol_en = true; + } else { + ff.pol_en = ff.pol_srst; + ff.sig_en = ff.sig_srst; + } + ff.has_en = true; + ff.has_srst = false; + ff.sig_d = ff.val_d = ff.val_srst; + ff.d_is_const = true; + changed = true; + } else { + // 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)); + ff.has_d = ff.has_en = ff.has_clk = false; + changed = true; + } + } + + // Now check if any bit can be replaced by a constant. + pool<int> removed_sigbits; + for (int i = 0; i < ff.width; i++) { + State val = ff.val_init[i]; + if (ff.has_arst) + val = combine_const(val, ff.val_arst[i]); + if (ff.has_srst) + val = combine_const(val, ff.val_srst[i]); + if (ff.has_sr) { + if (ff.sig_clr[i] != (ff.pol_clr ? State::S0 : State::S1)) + val = combine_const(val, State::S0); + if (ff.sig_set[i] != (ff.pol_set ? State::S0 : State::S1)) + val = combine_const(val, State::S1); + } + if (val == State::Sm) + continue; + if (ff.has_d) { + if (!ff.sig_d[i].wire) { + val = combine_const(val, ff.sig_d[i].data); + if (val == State::Sm) + continue; + } else { + if (!opt.sat) + continue; + // For each register bit, try to prove that it cannot change from the initial value. If so, remove it + if (!bit2driver.count(ff.sig_d[i])) + continue; + if (val != State::S0 && val != State::S1) + continue; + + sat_import_cell(bit2driver.at(ff.sig_d[i])); + + int init_sat_pi = satgen.importSigSpec(val).front(); + int q_sat_pi = satgen.importSigBit(ff.sig_q[i]); + int d_sat_pi = satgen.importSigBit(ff.sig_d[i]); + + // Try to find out whether the register bit can change under some circumstances + bool counter_example_found = ez->solve(ez->IFF(q_sat_pi, init_sat_pi), ez->NOT(ez->IFF(d_sat_pi, init_sat_pi))); + + // If the register bit cannot change, we can replace it with a constant + if (counter_example_found) + continue; + } + } + log("Setting constant %d-bit at position %d on %s (%s) from module %s.\n", val ? 1 : 0, + i, log_id(cell), log_id(cell->type), log_id(module)); + + initvals.remove_init(ff.sig_q[i]); + module->connect(ff.sig_q[i], val); + removed_sigbits.insert(i); + } + if (!removed_sigbits.empty()) { + std::vector<int> keep_bits; + for (int i = 0; i < ff.width; i++) + if (!removed_sigbits.count(i)) + keep_bits.push_back(i); + if (keep_bits.empty()) { + module->remove(cell); + did_something = true; + continue; + } + ff = ff.slice(keep_bits); + changed = true; + } + + // 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_arst && !ff.has_sr && (!ff.has_srst || !ff.has_en || ff.ce_over_srst) && !opt.nosdff) { + // Try to merge sync resets. + std::map<ctrls_t, std::vector<int>> groups; + std::vector<int> remaining_indices; + Const val_srst; + + for (int i = 0 ; i < ff.width; i++) { + ctrls_t resets; + State reset_val = State::Sx; + if (ff.has_srst) + reset_val = ff.val_srst[i]; + while (bit2mux.count(ff.sig_d[i]) && bitusers[ff.sig_d[i]] == 1) { + cell_int_t mbit = bit2mux.at(ff.sig_d[i]); + if (GetSize(mbit.first->getPort(ID::S)) != 1) + break; + SigBit s = mbit.first->getPort(ID::S); + SigBit a = mbit.first->getPort(ID::A)[mbit.second]; + SigBit b = mbit.first->getPort(ID::B)[mbit.second]; + // Workaround for funny memory WE pattern. + if ((a == State::S0 || a == State::S1) && (b == State::S0 || b == State::S1)) + break; + if ((b == State::S0 || b == State::S1) && (b == reset_val || reset_val == State::Sx)) { + // This is better handled by CE pattern. + if (a == ff.sig_q[i]) + break; + reset_val = b.data; + resets.insert(ctrl_t(s, true)); + ff.sig_d[i] = a; + } else if ((a == State::S0 || a == State::S1) && (a == reset_val || reset_val == State::Sx)) { + // This is better handled by CE pattern. + if (b == ff.sig_q[i]) + break; + reset_val = a.data; + resets.insert(ctrl_t(s, false)); + ff.sig_d[i] = b; + } else { + break; + } + } + + if (!resets.empty()) { + if (ff.has_srst) + resets.insert(ctrl_t(ff.sig_srst, ff.pol_srst)); + groups[resets].push_back(i); + } else + remaining_indices.push_back(i); + val_srst.bits.push_back(reset_val); + } + + for (auto &it : groups) { + FfData new_ff = ff.slice(it.second); + new_ff.val_srst = Const(); + for (int i = 0; i < new_ff.width; i++) { + int j = it.second[i]; + new_ff.val_srst.bits.push_back(val_srst[j]); + } + ctrl_t srst = combine_resets(it.first, ff.is_fine); + + new_ff.has_srst = true; + new_ff.sig_srst = srst.first; + new_ff.pol_srst = srst.second; + if (new_ff.has_en) + new_ff.ce_over_srst = true; + Cell *new_cell = new_ff.emit(module, NEW_ID); + if (new_cell) + dff_cells.push_back(new_cell); + log("Adding SRST signal on %s (%s) from module %s (D = %s, Q = %s, rval = %s).\n", + log_id(cell), log_id(cell->type), log_id(module), log_signal(new_ff.sig_d), log_signal(new_ff.sig_q), log_signal(new_ff.val_srst)); + } + + if (remaining_indices.empty()) { + module->remove(cell); + did_something = true; + continue; + } else if (GetSize(remaining_indices) != ff.width) { + ff = ff.slice(remaining_indices); + changed = true; + } + } + if ((!ff.has_srst || !ff.has_en || !ff.ce_over_srst) && !opt.nodffe) { + // Try to merge enables. + std::map<std::pair<patterns_t, ctrls_t>, std::vector<int>> groups; + std::vector<int> remaining_indices; + + for (int i = 0 ; i < ff.width; i++) { + // First, eat up as many simple muxes as possible. + ctrls_t enables; + while (bit2mux.count(ff.sig_d[i]) && bitusers[ff.sig_d[i]] == 1) { + cell_int_t mbit = bit2mux.at(ff.sig_d[i]); + if (GetSize(mbit.first->getPort(ID::S)) != 1) + break; + SigBit s = mbit.first->getPort(ID::S); + SigBit a = mbit.first->getPort(ID::A)[mbit.second]; + SigBit b = mbit.first->getPort(ID::B)[mbit.second]; + if (a == ff.sig_q[i]) { + enables.insert(ctrl_t(s, true)); + ff.sig_d[i] = b; + } else if (b == ff.sig_q[i]) { + enables.insert(ctrl_t(s, false)); + ff.sig_d[i] = a; + } else { + break; + } + } + + patterns_t patterns; + if (!opt.simple_dffe) + patterns = find_muxtree_feedback_patterns(ff.sig_d[i], ff.sig_q[i], pattern_t()); + if (!patterns.empty() || !enables.empty()) { + if (ff.has_en) + enables.insert(ctrl_t(ff.sig_en, ff.pol_en)); + simplify_patterns(patterns); + groups[std::make_pair(patterns, enables)].push_back(i); + } else + remaining_indices.push_back(i); + } + + for (auto &it : groups) { + FfData new_ff = ff.slice(it.second); + ctrl_t en = make_patterns_logic(it.first.first, it.first.second, ff.is_fine); + + new_ff.has_en = true; + new_ff.sig_en = en.first; + new_ff.pol_en = en.second; + new_ff.ce_over_srst = false; + Cell *new_cell = new_ff.emit(module, NEW_ID); + if (new_cell) + dff_cells.push_back(new_cell); + log("Adding EN signal on %s (%s) from module %s (D = %s, Q = %s).\n", + log_id(cell), log_id(cell->type), log_id(module), log_signal(new_ff.sig_d), log_signal(new_ff.sig_q)); + } + + if (remaining_indices.empty()) { + module->remove(cell); + did_something = true; + continue; + } else if (GetSize(remaining_indices) != ff.width) { + ff = ff.slice(remaining_indices); + changed = true; + } + } + } + + if (changed) { + // Rebuild the FF. + IdString name = cell->name; + module->remove(cell); + ff.emit(module, name); + did_something = true; + } + } + return did_something; + } +}; + +struct OptDffPass : public Pass { + OptDffPass() : Pass("opt_dff", "perform DFF optimizations") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" opt_dff [-nodffe] [-nosdff] [-keepdc] [-sat] [selection]\n"); + log("\n"); + log("This pass converts flip-flops to a more suitable type by merging clock enables\n"); + log("and synchronous reset multiplexers, removing unused control inputs, or potentially\n"); + log("removes the flip-flop altogether, converting it to a constant driver.\n"); + log("\n"); + log(" -nodffe\n"); + log(" disables dff -> dffe conversion, and other transforms recognizing clock enable\n"); + log("\n"); + log(" -nosdff\n"); + log(" disables dff -> sdff conversion, and other transforms recognizing sync resets\n"); + log("\n"); + log(" -simple-dffe\n"); + log(" only enables clock enable recognition transform for obvious cases\n"); + log("\n"); + log(" -sat\n"); + log(" additionally invoke SAT solver to detect and remove flip-flops (with\n"); + log(" non-constant inputs) that can also be replaced with a constant driver\n"); + log("\n"); + log(" -keepdc\n"); + log(" some optimizations change the behavior of the circuit with respect to\n"); + log(" don't-care bits. for example in 'a+0' a single x-bit in 'a' will cause\n"); + log(" all result bits to be set to x. this behavior changes when 'a+0' is\n"); + log(" replaced by 'a'. the -keepdc option disables all such optimizations.\n"); + log("\n"); + } + + void execute(std::vector<std::string> args, RTLIL::Design *design) override + { + log_header(design, "Executing OPT_DFF pass (perform DFF optimizations).\n"); + OptDffOptions opt; + opt.nodffe = false; + opt.nosdff = false; + opt.simple_dffe = false; + opt.keepdc = false; + opt.sat = false; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-nodffe") { + opt.nodffe = true; + continue; + } + if (args[argidx] == "-nosdff") { + opt.nosdff = true; + continue; + } + if (args[argidx] == "-simple-dffe") { + opt.simple_dffe = true; + continue; + } + if (args[argidx] == "-keepdc") { + opt.keepdc = true; + continue; + } + if (args[argidx] == "-sat") { + opt.sat = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + bool did_something = false; + for (auto mod : design->selected_modules()) { + OptDffWorker worker(opt, mod); + if (worker.run()) + did_something = true; + } + + if (did_something) + design->scratchpad_set_bool("opt.did_something", true); + } +} OptDffPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index e5b8bda95..e36e4419d 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -117,7 +117,7 @@ void replace_undriven(RTLIL::Module *module, const CellTypes &ct) } void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, - const std::string &info YS_ATTRIBUTE(unused), IdString out_port, RTLIL::SigSpec out_val) + const std::string &info, IdString out_port, RTLIL::SigSpec out_val) { RTLIL::SigSpec Y = cell->getPort(out_port); out_val.extend_u0(Y.size(), false); @@ -416,7 +416,7 @@ int get_onehot_bit_index(RTLIL::SigSpec signal) return bit_index; } -void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool, bool do_fine, bool keepdc, bool clkinv) +void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool, bool do_fine, bool keepdc, bool noclkinv) { if (!design->selected(module)) return; @@ -465,17 +465,23 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons #define ACTION_DO(_p_, _s_) do { cover("opt.opt_expr.action_" S__LINE__); replace_cell(assign_map, module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) #define ACTION_DO_Y(_v_) ACTION_DO(ID::Y, RTLIL::SigSpec(RTLIL::State::S ## _v_)) - if (clkinv) + if (!noclkinv) { - if (cell->type.in(ID($dff), ID($dffe), ID($dffsr), ID($adff), ID($fsm), ID($memrd), ID($memwr))) + if (cell->type.in(ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), ID($fsm), ID($memrd), ID($memwr))) handle_polarity_inv(cell, ID::CLK, ID::CLK_POLARITY, assign_map, invert_map); - if (cell->type.in(ID($sr), ID($dffsr), ID($dlatchsr))) { + if (cell->type.in(ID($sr), ID($dffsr), ID($dffsre), ID($dlatchsr))) { handle_polarity_inv(cell, ID::SET, ID::SET_POLARITY, assign_map, invert_map); handle_polarity_inv(cell, ID::CLR, ID::CLR_POLARITY, assign_map, invert_map); } - if (cell->type.in(ID($dffe), ID($dlatch), ID($dlatchsr))) + if (cell->type.in(ID($adff), ID($adffe), ID($adlatch))) + handle_polarity_inv(cell, ID::ARST, ID::ARST_POLARITY, assign_map, invert_map); + + if (cell->type.in(ID($sdff), ID($sdffe), ID($sdffce))) + handle_polarity_inv(cell, ID::SRST, ID::SRST_POLARITY, assign_map, invert_map); + + if (cell->type.in(ID($dffe), ID($adffe), ID($sdffe), ID($sdffce), ID($dffsre), ID($dlatch), ID($adlatch), ID($dlatchsr))) handle_polarity_inv(cell, ID::EN, ID::EN_POLARITY, assign_map, invert_map); handle_clkpol_celltype_swap(cell, "$_SR_N?_", "$_SR_P?_", ID::S, assign_map, invert_map); @@ -489,12 +495,35 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons handle_clkpol_celltype_swap(cell, "$_DFF_N??_", "$_DFF_P??_", ID::C, assign_map, invert_map); handle_clkpol_celltype_swap(cell, "$_DFF_?N?_", "$_DFF_?P?_", ID::R, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DFFE_N???_", "$_DFFE_P???_", ID::C, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DFFE_?N??_", "$_DFFE_?P??_", ID::R, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DFFE_???N_", "$_DFFE_???P_", ID::E, assign_map, invert_map); + + handle_clkpol_celltype_swap(cell, "$_SDFF_N??_", "$_SDFF_P??_", ID::C, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_SDFF_?N?_", "$_SDFF_?P?_", ID::R, assign_map, invert_map); + + handle_clkpol_celltype_swap(cell, "$_SDFFE_N???_", "$_SDFFE_P???_", ID::C, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_SDFFE_?N??_", "$_SDFFE_?P??_", ID::R, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_SDFFE_???N_", "$_SDFFE_???P_", ID::E, assign_map, invert_map); + + handle_clkpol_celltype_swap(cell, "$_SDFFCE_N???_", "$_SDFFCE_P???_", ID::C, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_SDFFCE_?N??_", "$_SDFFCE_?P??_", ID::R, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_SDFFCE_???N_", "$_SDFFCE_???P_", ID::E, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DFFSR_N??_", "$_DFFSR_P??_", ID::C, assign_map, invert_map); handle_clkpol_celltype_swap(cell, "$_DFFSR_?N?_", "$_DFFSR_?P?_", ID::S, assign_map, invert_map); handle_clkpol_celltype_swap(cell, "$_DFFSR_??N_", "$_DFFSR_??P_", ID::R, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DFFSRE_N???_", "$_DFFSRE_P???_", ID::C, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DFFSRE_?N??_", "$_DFFSRE_?P??_", ID::S, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DFFSRE_??N?_", "$_DFFSRE_??P?_", ID::R, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DFFSRE_???N_", "$_DFFSRE_???P_", ID::E, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DLATCH_N_", "$_DLATCH_P_", ID::E, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DLATCH_N??_", "$_DLATCH_P??_", ID::E, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DLATCH_?N?_", "$_DLATCH_?P?_", ID::R, assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DLATCHSR_N??_", "$_DLATCHSR_P??_", ID::E, assign_map, invert_map); handle_clkpol_celltype_swap(cell, "$_DLATCHSR_?N?_", "$_DLATCHSR_?P?_", ID::S, assign_map, invert_map); handle_clkpol_celltype_swap(cell, "$_DLATCHSR_??N_", "$_DLATCHSR_??P_", ID::R, assign_map, invert_map); @@ -575,7 +604,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($xnor), ID($_XNOR_))) { cover("opt.opt_expr.const_xnor"); // For consistency since simplemap does $xnor -> $_XOR_ + $_NOT_ - int width = cell->getParam(ID::Y_WIDTH).as_int(); + int width = GetSize(cell->getPort(ID::Y)); replace_cell(assign_map, module, cell, "const_xnor", ID::Y, SigSpec(RTLIL::State::S1, width)); goto next_cell; } @@ -1567,6 +1596,14 @@ skip_identity: log_debug("Removing low %d A and %d B bits from cell `%s' in module `%s'.\n", a_zeros, b_zeros, cell->name.c_str(), module->name.c_str()); + if (y_zeros >= GetSize(sig_y)) { + module->connect(sig_y, RTLIL::SigSpec(0, GetSize(sig_y))); + module->remove(cell); + + did_something = true; + goto next_cell; + } + if (a_zeros) { cell->setPort(ID::A, sig_a.extract_end(a_zeros)); cell->parameters[ID::A_WIDTH] = GetSize(sig_a) - a_zeros; @@ -2009,7 +2046,7 @@ skip_alu_split: struct OptExprPass : public Pass { OptExprPass() : Pass("opt_expr", "perform const folding and simple expression rewriting") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -2027,8 +2064,8 @@ struct OptExprPass : public Pass { log(" -undriven\n"); log(" replace undriven nets with undef (x) constants\n"); log("\n"); - log(" -clkinv\n"); - log(" optimize clock inverters by changing FF types\n"); + log(" -noclkinv\n"); + log(" do not optimize clock inverters by changing FF types\n"); log("\n"); log(" -fine\n"); log(" perform fine-grain optimizations\n"); @@ -2043,12 +2080,12 @@ struct OptExprPass : public Pass { log(" replaced by 'a'. the -keepdc option disables all such optimizations.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool mux_undef = false; bool mux_bool = false; bool undriven = false; - bool clkinv = false; + bool noclkinv = false; bool do_fine = false; bool keepdc = false; @@ -2069,8 +2106,8 @@ struct OptExprPass : public Pass { undriven = true; continue; } - if (args[argidx] == "-clkinv") { - clkinv = true; + if (args[argidx] == "-noclkinv") { + noclkinv = true; continue; } if (args[argidx] == "-fine") { @@ -2107,12 +2144,12 @@ struct OptExprPass : public Pass { do { do { did_something = false; - replace_const_cells(design, module, false /* consume_x */, mux_undef, mux_bool, do_fine, keepdc, clkinv); + replace_const_cells(design, module, false /* consume_x */, mux_undef, mux_bool, do_fine, keepdc, noclkinv); if (did_something) design->scratchpad_set_bool("opt.did_something", true); } while (did_something); if (!keepdc) - replace_const_cells(design, module, true /* consume_x */, mux_undef, mux_bool, do_fine, keepdc, clkinv); + replace_const_cells(design, module, true /* consume_x */, mux_undef, mux_bool, do_fine, keepdc, noclkinv); if (did_something) design->scratchpad_set_bool("opt.did_something", true); } while (did_something); diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index 12927d052..07a91af8a 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -520,7 +520,7 @@ static void split(std::vector<std::string> &tokens, const std::string &text, cha struct OptLutPass : public Pass { OptLutPass() : Pass("opt_lut", "optimize LUT cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -538,7 +538,7 @@ struct OptLutPass : public Pass { log(" only perform the first N combines, then stop. useful for debugging.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing OPT_LUT pass (optimize LUTs).\n"); diff --git a/passes/opt/opt_lut_ins.cc b/passes/opt/opt_lut_ins.cc index 1d32e84bb..bb40e1e55 100644 --- a/passes/opt/opt_lut_ins.cc +++ b/passes/opt/opt_lut_ins.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct OptLutInsPass : public Pass { OptLutInsPass() : Pass("opt_lut_ins", "discard unused LUT inputs") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -42,7 +42,7 @@ struct OptLutInsPass : public Pass { log(" to the given technology. Valid values are: xilinx, ecp5, gowin.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing OPT_LUT_INS pass (discard unused LUT inputs).\n"); string techname; diff --git a/passes/opt/opt_mem.cc b/passes/opt/opt_mem.cc index ff9c06453..49a0ac51a 100644 --- a/passes/opt/opt_mem.cc +++ b/passes/opt/opt_mem.cc @@ -19,85 +19,14 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -struct OptMemWorker -{ - RTLIL::Design *design; - RTLIL::Module *module; - SigMap sigmap; - bool restart; - - dict<IdString, vector<IdString>> memrd, memwr, meminit; - pool<IdString> remove_mem, remove_cells; - - OptMemWorker(RTLIL::Module *module) : design(module->design), module(module), sigmap(module), restart(false) - { - for (auto &it : module->memories) - { - memrd[it.first]; - memwr[it.first]; - meminit[it.first]; - } - - for (auto cell : module->cells()) - { - if (cell->type == ID($memrd)) { - IdString id = cell->getParam(ID::MEMID).decode_string(); - memrd.at(id).push_back(cell->name); - } - - if (cell->type == ID($memwr)) { - IdString id = cell->getParam(ID::MEMID).decode_string(); - memwr.at(id).push_back(cell->name); - } - - if (cell->type == ID($meminit)) { - IdString id = cell->getParam(ID::MEMID).decode_string(); - meminit.at(id).push_back(cell->name); - } - } - } - - ~OptMemWorker() - { - for (auto it : remove_mem) - { - for (auto cell_name : memrd[it]) - module->remove(module->cell(cell_name)); - for (auto cell_name : memwr[it]) - module->remove(module->cell(cell_name)); - for (auto cell_name : meminit[it]) - module->remove(module->cell(cell_name)); - - delete module->memories.at(it); - module->memories.erase(it); - } - - for (auto cell_name : remove_cells) - module->remove(module->cell(cell_name)); - } - - int run(RTLIL::Memory *mem) - { - if (restart || remove_mem.count(mem->name)) - return 0; - - if (memwr.at(mem->name).empty() && meminit.at(mem->name).empty()) { - log("Removing memory %s.%s with no write ports or init data.\n", log_id(module), log_id(mem)); - remove_mem.insert(mem->name); - return 1; - } - - return 0; - } -}; - struct OptMemPass : public Pass { OptMemPass() : Pass("opt_mem", "optimize memories") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -106,7 +35,7 @@ struct OptMemPass : public Pass { log("This pass performs various optimizations on memories in the design.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing OPT_MEM pass (optimize memories).\n"); @@ -122,15 +51,11 @@ struct OptMemPass : public Pass { int total_count = 0; for (auto module : design->selected_modules()) { - while (1) { - int cnt = 0; - OptMemWorker worker(module); - for (auto &it : module->memories) - if (module->selected(it.second)) - cnt += worker.run(it.second); - if (!cnt && !worker.restart) - break; - total_count += cnt; + for (auto &mem : Mem::get_selected_memories(module)) { + if (mem.wr_ports.empty() && mem.inits.empty()) { + mem.remove(); + total_count++; + } } } diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index d845926fc..9086943dc 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -173,9 +173,7 @@ struct OptMergeWorker for (const auto &it : cell1->connections_) { if (cell1->output(it.first)) { - if (it.first == ID::Q && (cell1->type.begins_with("$dff") || cell1->type.begins_with("$dlatch") || - cell1->type.begins_with("$_DFF") || cell1->type.begins_with("$_DLATCH") || cell1->type.begins_with("$_SR_") || - cell1->type.in(ID($adff), ID($sr), ID($ff), ID($_FF_)))) { + if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell1->type)) { // For the 'Q' output of state elements, // use the (* init *) attribute value auto &sig1 = conn1[it.first]; @@ -298,9 +296,7 @@ struct OptMergeWorker module->connect(RTLIL::SigSig(it.second, other_sig)); assign_map.add(it.second, other_sig); - if (it.first == ID::Q && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") || - cell->type.begins_with("$_DFF") || cell->type.begins_with("$_DLATCH") || cell->type.begins_with("$_SR_") || - cell->type.in(ID($adff), ID($sr), ID($ff), ID($_FF_)))) { + if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell->type)) { for (auto c : it.second.chunks()) { auto jt = c.wire->attributes.find(ID::init); if (jt == c.wire->attributes.end()) @@ -326,7 +322,7 @@ struct OptMergeWorker struct OptMergePass : public Pass { OptMergePass() : Pass("opt_merge", "consolidate identical cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -342,7 +338,7 @@ struct OptMergePass : public Pass { log(" Operate on all cell types, not just built-in types.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing OPT_MERGE pass (detect identical cells).\n"); diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index d076addae..67b283e11 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -473,7 +473,7 @@ struct OptMuxtreeWorker struct OptMuxtreePass : public Pass { OptMuxtreePass() : Pass("opt_muxtree", "eliminate dead trees in multiplexer trees") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -486,7 +486,7 @@ struct OptMuxtreePass : public Pass { log("This pass only operates on completely selected modules without processes.\n"); log("\n"); } - void execute(vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing OPT_MUXTREE pass (detect dead branches in mux trees).\n"); extra_args(args, 1, design); diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index f640f50a0..28de9ceb6 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -332,7 +332,7 @@ struct OptReduceWorker struct OptReducePass : public Pass { OptReducePass() : Pass("opt_reduce", "simplify large MUXes and AND/OR gates") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -353,7 +353,7 @@ struct OptReducePass : public Pass { log(" alias for -fine\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool do_fine = false; diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc deleted file mode 100644 index 81326a417..000000000 --- a/passes/opt/opt_rmdff.cc +++ /dev/null @@ -1,711 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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/log.h" -#include "kernel/register.h" -#include "kernel/rtlil.h" -#include "kernel/satgen.h" -#include "kernel/sigtools.h" -#include <stdio.h> -#include <stdlib.h> - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -SigMap assign_map, dff_init_map; -SigSet<RTLIL::Cell*> mux_drivers; -dict<SigBit, RTLIL::Cell*> bit2driver; -dict<SigBit, pool<SigBit>> init_attributes; - -bool keepdc; -bool sat; - -void remove_init_attr(SigSpec sig) -{ - for (auto bit : assign_map(sig)) - if (init_attributes.count(bit)) - for (auto wbit : init_attributes.at(bit)) - wbit.wire->attributes.at(ID::init)[wbit.offset] = State::Sx; -} - -bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) -{ - SigSpec sig_set, sig_clr; - State pol_set, pol_clr; - - if (cell->hasPort(ID::S)) - sig_set = cell->getPort(ID::S); - - if (cell->hasPort(ID::R)) - sig_clr = cell->getPort(ID::R); - - if (cell->hasPort(ID::SET)) - sig_set = cell->getPort(ID::SET); - - if (cell->hasPort(ID::CLR)) - sig_clr = cell->getPort(ID::CLR); - - log_assert(GetSize(sig_set) == GetSize(sig_clr)); - - if (cell->type.begins_with("$_DFFSR_")) { - pol_set = cell->type[9] == 'P' ? State::S1 : State::S0; - pol_clr = cell->type[10] == 'P' ? State::S1 : State::S0; - } else - if (cell->type.begins_with("$_DLATCHSR_")) { - pol_set = cell->type[12] == 'P' ? State::S1 : State::S0; - pol_clr = cell->type[13] == 'P' ? State::S1 : State::S0; - } else - if (cell->type.in(ID($dffsr), ID($dlatchsr))) { - pol_set = cell->parameters[ID::SET_POLARITY].as_bool() ? State::S1 : State::S0; - pol_clr = cell->parameters[ID::CLR_POLARITY].as_bool() ? State::S1 : State::S0; - } else - log_abort(); - - State npol_set = pol_set == State::S0 ? State::S1 : State::S0; - State npol_clr = pol_clr == State::S0 ? State::S1 : State::S0; - - SigSpec sig_d = cell->getPort(ID::D); - SigSpec sig_q = cell->getPort(ID::Q); - - bool did_something = false; - bool proper_sr = false; - bool used_pol_set = false; - bool used_pol_clr = false; - bool hasreset = false; - Const reset_val; - SigSpec sig_reset; - - for (int i = 0; i < GetSize(sig_set); i++) - { - SigBit s = sig_set[i], c = sig_clr[i]; - - if (s != npol_set || c != npol_clr) - hasreset = true; - - if (s == pol_set || c == pol_clr) - { - log("Constantly %s Q bit %s for SR cell %s (%s) from module %s.\n", - s == pol_set ? "set" : "cleared", log_signal(sig_q[i]), - log_id(cell), log_id(cell->type), log_id(mod)); - - remove_init_attr(sig_q[i]); - mod->connect(sig_q[i], s == pol_set ? State::S1 : State::S0); - sig_set.remove(i); - sig_clr.remove(i); - sig_d.remove(i); - sig_q.remove(i--); - did_something = true; - continue; - } - if (sig_reset.empty() && s.wire != nullptr) sig_reset = s; - if (sig_reset.empty() && c.wire != nullptr) sig_reset = c; - - if (s.wire != nullptr && s != sig_reset) proper_sr = true; - if (c.wire != nullptr && c != sig_reset) proper_sr = true; - - if ((s.wire == nullptr) != (c.wire == nullptr)) { - if (s.wire != nullptr) used_pol_set = true; - if (c.wire != nullptr) used_pol_clr = true; - reset_val.bits.push_back(c.wire == nullptr ? State::S1 : State::S0); - } else - proper_sr = true; - } - - if (!hasreset) - proper_sr = false; - - if (GetSize(sig_set) == 0) - { - log("Removing %s (%s) from module %s.\n", log_id(cell), log_id(cell->type), log_id(mod)); - mod->remove(cell); - return true; - } - - if (cell->type.in(ID($dffsr), ID($dlatchsr))) - { - cell->setParam(ID::WIDTH, GetSize(sig_d)); - cell->setPort(ID::SET, sig_set); - cell->setPort(ID::CLR, sig_clr); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - } - else - { - cell->setPort(ID::S, sig_set); - cell->setPort(ID::R, sig_clr); - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, sig_q); - } - - if (proper_sr) - return did_something; - - if (used_pol_set && used_pol_clr && pol_set != pol_clr) - return did_something; - - if (cell->type == ID($dlatchsr)) - return did_something; - - State unified_pol = used_pol_set ? pol_set : pol_clr; - - if (cell->type == ID($dffsr)) - { - if (hasreset) - { - log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$adff", log_id(mod)); - - cell->type = ID($adff); - cell->setParam(ID::ARST_POLARITY, unified_pol); - cell->setParam(ID::ARST_VALUE, reset_val); - cell->setPort(ID::ARST, sig_reset); - - cell->unsetParam(ID::SET_POLARITY); - cell->unsetParam(ID::CLR_POLARITY); - cell->unsetPort(ID::SET); - cell->unsetPort(ID::CLR); - } - else - { - log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$dff", log_id(mod)); - - cell->type = ID($dff); - cell->unsetParam(ID::SET_POLARITY); - cell->unsetParam(ID::CLR_POLARITY); - cell->unsetPort(ID::SET); - cell->unsetPort(ID::CLR); - } - - return true; - } - - if (!hasreset) - { - IdString new_type; - - if (cell->type.begins_with("$_DFFSR_")) - new_type = stringf("$_DFF_%c_", cell->type[8]); - else if (cell->type.begins_with("$_DLATCHSR_")) - new_type = stringf("$_DLATCH_%c_", cell->type[11]); - else - log_abort(); - - log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), log_id(new_type), log_id(mod)); - - cell->type = new_type; - cell->unsetPort(ID::S); - cell->unsetPort(ID::R); - - return true; - } - - return did_something; -} - -bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch) -{ - SigSpec sig_e; - State on_state, off_state; - - if (dlatch->type == ID($dlatch)) { - sig_e = assign_map(dlatch->getPort(ID::EN)); - on_state = dlatch->getParam(ID::EN_POLARITY).as_bool() ? State::S1 : State::S0; - off_state = dlatch->getParam(ID::EN_POLARITY).as_bool() ? State::S0 : State::S1; - } else - if (dlatch->type == ID($_DLATCH_P_)) { - sig_e = assign_map(dlatch->getPort(ID::E)); - on_state = State::S1; - off_state = State::S0; - } else - if (dlatch->type == ID($_DLATCH_N_)) { - sig_e = assign_map(dlatch->getPort(ID::E)); - on_state = State::S0; - off_state = State::S1; - } else - log_abort(); - - if (sig_e == off_state) - { - RTLIL::Const val_init; - for (auto bit : dff_init_map(dlatch->getPort(ID::Q))) - val_init.bits.push_back(bit.wire == NULL ? bit.data : State::Sx); - mod->connect(dlatch->getPort(ID::Q), val_init); - goto delete_dlatch; - } - - if (sig_e == on_state) - { - mod->connect(dlatch->getPort(ID::Q), dlatch->getPort(ID::D)); - goto delete_dlatch; - } - - return false; - -delete_dlatch: - log("Removing %s (%s) from module %s.\n", log_id(dlatch), log_id(dlatch->type), log_id(mod)); - remove_init_attr(dlatch->getPort(ID::Q)); - mod->remove(dlatch); - return true; -} - -bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) -{ - RTLIL::SigSpec sig_d, sig_q, sig_c, sig_r, sig_e; - RTLIL::Const val_cp, val_rp, val_rv, val_ep; - - if (dff->type == ID($_FF_)) { - sig_d = dff->getPort(ID::D); - sig_q = dff->getPort(ID::Q); - } - else if (dff->type == ID($_DFF_N_) || dff->type == ID($_DFF_P_)) { - sig_d = dff->getPort(ID::D); - sig_q = dff->getPort(ID::Q); - sig_c = dff->getPort(ID::C); - val_cp = RTLIL::Const(dff->type == ID($_DFF_P_), 1); - } - else if (dff->type.begins_with("$_DFF_") && dff->type.compare(9, 1, "_") == 0 && - (dff->type[6] == 'N' || dff->type[6] == 'P') && - (dff->type[7] == 'N' || dff->type[7] == 'P') && - (dff->type[8] == '0' || dff->type[8] == '1')) { - sig_d = dff->getPort(ID::D); - sig_q = dff->getPort(ID::Q); - sig_c = dff->getPort(ID::C); - sig_r = dff->getPort(ID::R); - val_cp = RTLIL::Const(dff->type[6] == 'P', 1); - val_rp = RTLIL::Const(dff->type[7] == 'P', 1); - val_rv = RTLIL::Const(dff->type[8] == '1', 1); - } - else if (dff->type.begins_with("$_DFFE_") && dff->type.compare(9, 1, "_") == 0 && - (dff->type[7] == 'N' || dff->type[7] == 'P') && - (dff->type[8] == 'N' || dff->type[8] == 'P')) { - sig_d = dff->getPort(ID::D); - sig_q = dff->getPort(ID::Q); - sig_c = dff->getPort(ID::C); - sig_e = dff->getPort(ID::E); - val_cp = RTLIL::Const(dff->type[7] == 'P', 1); - val_ep = RTLIL::Const(dff->type[8] == 'P', 1); - } - else if (dff->type == ID($ff)) { - sig_d = dff->getPort(ID::D); - sig_q = dff->getPort(ID::Q); - } - else if (dff->type == ID($dff)) { - sig_d = dff->getPort(ID::D); - sig_q = dff->getPort(ID::Q); - sig_c = dff->getPort(ID::CLK); - val_cp = RTLIL::Const(dff->parameters[ID::CLK_POLARITY].as_bool(), 1); - } - else if (dff->type == ID($dffe)) { - sig_e = dff->getPort(ID::EN); - sig_d = dff->getPort(ID::D); - sig_q = dff->getPort(ID::Q); - sig_c = dff->getPort(ID::CLK); - val_cp = RTLIL::Const(dff->parameters[ID::CLK_POLARITY].as_bool(), 1); - val_ep = RTLIL::Const(dff->parameters[ID::EN_POLARITY].as_bool(), 1); - } - else if (dff->type == ID($adff)) { - sig_d = dff->getPort(ID::D); - sig_q = dff->getPort(ID::Q); - sig_c = dff->getPort(ID::CLK); - sig_r = dff->getPort(ID::ARST); - val_cp = RTLIL::Const(dff->parameters[ID::CLK_POLARITY].as_bool(), 1); - val_rp = RTLIL::Const(dff->parameters[ID::ARST_POLARITY].as_bool(), 1); - val_rv = dff->parameters[ID::ARST_VALUE]; - } - else - log_abort(); - - assign_map.apply(sig_d); - assign_map.apply(sig_q); - assign_map.apply(sig_c); - assign_map.apply(sig_r); - - bool has_init = false; - RTLIL::Const val_init; - for (auto bit : dff_init_map(sig_q).to_sigbit_vector()) { - if (bit.wire == NULL || keepdc) - has_init = true; - val_init.bits.push_back(bit.wire == NULL ? bit.data : RTLIL::State::Sx); - } - - if (dff->type.in(ID($ff), ID($dff)) && mux_drivers.has(sig_d)) { - std::set<RTLIL::Cell*> muxes; - mux_drivers.find(sig_d, muxes); - for (auto mux : muxes) { - RTLIL::SigSpec sig_a = assign_map(mux->getPort(ID::A)); - RTLIL::SigSpec sig_b = assign_map(mux->getPort(ID::B)); - if (sig_a == sig_q && sig_b.is_fully_const() && (!has_init || val_init == sig_b.as_const())) { - mod->connect(sig_q, sig_b); - goto delete_dff; - } - if (sig_b == sig_q && sig_a.is_fully_const() && (!has_init || val_init == sig_a.as_const())) { - mod->connect(sig_q, sig_a); - goto delete_dff; - } - } - } - - // If clock is driven by a constant and (i) no reset signal - // (ii) Q has no initial value - // (iii) initial value is same as reset value - if (!sig_c.empty() && sig_c.is_fully_const() && (!sig_r.size() || !has_init || val_init == val_rv)) { - if (val_rv.bits.size() == 0) - val_rv = val_init; - // Q is permanently reset value or initial value - mod->connect(sig_q, val_rv); - goto delete_dff; - } - - // If D is fully undefined and reset signal present and (i) Q has no initial value - // (ii) initial value is same as reset value - if (sig_d.is_fully_undef() && sig_r.size() && (!has_init || val_init == val_rv)) { - // Q is permanently reset value - mod->connect(sig_q, val_rv); - goto delete_dff; - } - - // If D is fully undefined and no reset signal and Q has an initial value - if (sig_d.is_fully_undef() && !sig_r.size() && has_init) { - // Q is permanently initial value - mod->connect(sig_q, val_init); - goto delete_dff; - } - - // If D is fully constant and (i) no reset signal - // (ii) reset value is same as constant D - // and (a) has no initial value - // (b) initial value same as constant D - if (sig_d.is_fully_const() && (!sig_r.size() || val_rv == sig_d.as_const()) && (!has_init || val_init == sig_d.as_const())) { - // Q is permanently D - mod->connect(sig_q, sig_d); - goto delete_dff; - } - - // If D input is same as Q output and (i) no reset signal - // (ii) no initial signal - // (iii) initial value is same as reset value - if (sig_d == sig_q && (sig_r.empty() || !has_init || val_init == val_rv)) { - // Q is permanently reset value or initial value - if (sig_r.size()) - mod->connect(sig_q, val_rv); - else if (has_init) - mod->connect(sig_q, val_init); - goto delete_dff; - } - - // If reset signal is present, and is fully constant - if (!sig_r.empty() && sig_r.is_fully_const()) - { - // If reset value is permanently active or if reset is undefined - if (sig_r == val_rp || sig_r.is_fully_undef()) { - // Q is permanently reset value - mod->connect(sig_q, val_rv); - goto delete_dff; - } - - log("Removing unused reset from %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod)); - - if (dff->type == ID($adff)) { - dff->type = ID($dff); - dff->unsetPort(ID::ARST); - dff->unsetParam(ID::ARST_POLARITY); - dff->unsetParam(ID::ARST_VALUE); - return true; - } - - log_assert(dff->type.begins_with("$_DFF_")); - dff->type = stringf("$_DFF_%c_", + dff->type[6]); - dff->unsetPort(ID::R); - } - - // If enable signal is present, and is fully constant - if (!sig_e.empty() && sig_e.is_fully_const()) - { - // If enable value is permanently inactive - if (sig_e != val_ep) { - // Q is permanently initial value - mod->connect(sig_q, val_init); - goto delete_dff; - } - - log("Removing unused enable from %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod)); - - if (dff->type == ID($dffe)) { - dff->type = ID($dff); - dff->unsetPort(ID::EN); - dff->unsetParam(ID::EN_POLARITY); - return true; - } - - log_assert(dff->type.begins_with("$_DFFE_")); - dff->type = stringf("$_DFF_%c_", + dff->type[7]); - dff->unsetPort(ID::E); - } - - if (sat && has_init && (!sig_r.size() || val_init == val_rv)) - { - bool removed_sigbits = false; - - ezSatPtr ez; - SatGen satgen(ez.get(), &assign_map); - pool<Cell*> sat_cells; - - std::function<void(Cell*)> sat_import_cell = [&](Cell *c) { - if (!sat_cells.insert(c).second) - return; - if (!satgen.importCell(c)) - return; - for (auto &conn : c->connections()) { - if (!c->input(conn.first)) - continue; - for (auto bit : assign_map(conn.second)) - if (bit2driver.count(bit)) - sat_import_cell(bit2driver.at(bit)); - } - }; - - // For each register bit, try to prove that it cannot change from the initial value. If so, remove it - for (int position = 0; position < GetSize(sig_d); position += 1) { - RTLIL::SigBit q_sigbit = sig_q[position]; - RTLIL::SigBit d_sigbit = sig_d[position]; - - if ((!q_sigbit.wire) || (!d_sigbit.wire)) - continue; - - if (!bit2driver.count(d_sigbit)) - continue; - - sat_import_cell(bit2driver.at(d_sigbit)); - - RTLIL::State sigbit_init_val = val_init[position]; - if (sigbit_init_val != State::S0 && sigbit_init_val != State::S1) - continue; - - int init_sat_pi = satgen.importSigSpec(sigbit_init_val).front(); - int q_sat_pi = satgen.importSigBit(q_sigbit); - int d_sat_pi = satgen.importSigBit(d_sigbit); - - // Try to find out whether the register bit can change under some circumstances - bool counter_example_found = ez->solve(ez->IFF(q_sat_pi, init_sat_pi), ez->NOT(ez->IFF(d_sat_pi, init_sat_pi))); - - // If the register bit cannot change, we can replace it with a constant - if (!counter_example_found) - { - log("Setting constant %d-bit at position %d on %s (%s) from module %s.\n", sigbit_init_val ? 1 : 0, - position, log_id(dff), log_id(dff->type), log_id(mod)); - - SigSpec tmp = dff->getPort(ID::D); - tmp[position] = sigbit_init_val; - dff->setPort(ID::D, tmp); - - removed_sigbits = true; - } - } - - if (removed_sigbits) { - handle_dff(mod, dff); - return true; - } - } - - - return false; - -delete_dff: - log("Removing %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod)); - remove_init_attr(dff->getPort(ID::Q)); - mod->remove(dff); - - for (auto &entry : bit2driver) - if (entry.second == dff) - bit2driver.erase(entry.first); - - return true; -} - -struct OptRmdffPass : public Pass { - OptRmdffPass() : Pass("opt_rmdff", "remove DFFs with constant inputs") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" opt_rmdff [-keepdc] [-sat] [selection]\n"); - log("\n"); - log("This pass identifies flip-flops with constant inputs and replaces them with\n"); - log("a constant driver.\n"); - log("\n"); - log(" -sat\n"); - log(" additionally invoke SAT solver to detect and remove flip-flops (with \n"); - log(" non-constant inputs) that can also be replaced with a constant driver\n"); - log("\n"); - } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE - { - int total_count = 0, total_initdrv = 0; - log_header(design, "Executing OPT_RMDFF pass (remove dff with constant values).\n"); - - keepdc = false; - sat = false; - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-keepdc") { - keepdc = true; - continue; - } - if (args[argidx] == "-sat") { - sat = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - for (auto module : design->selected_modules()) { - pool<SigBit> driven_bits; - dict<SigBit, State> init_bits; - - assign_map.set(module); - dff_init_map.set(module); - mux_drivers.clear(); - bit2driver.clear(); - init_attributes.clear(); - - for (auto wire : module->wires()) - { - if (wire->attributes.count(ID::init) != 0) { - Const initval = wire->attributes.at(ID::init); - for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) - if (initval[i] == State::S0 || initval[i] == State::S1) - dff_init_map.add(SigBit(wire, i), initval[i]); - for (int i = 0; i < GetSize(wire); i++) { - SigBit wire_bit(wire, i), mapped_bit = assign_map(wire_bit); - if (mapped_bit.wire) { - init_attributes[mapped_bit].insert(wire_bit); - if (i < GetSize(initval)) - init_bits[mapped_bit] = initval[i]; - } - } - } - - if (wire->port_input) { - for (auto bit : assign_map(wire)) - driven_bits.insert(bit); - } - } - - std::vector<RTLIL::IdString> dff_list; - std::vector<RTLIL::IdString> dffsr_list; - std::vector<RTLIL::IdString> dlatch_list; - for (auto cell : module->cells()) - { - for (auto &conn : cell->connections()) { - bool is_output = cell->output(conn.first); - if (is_output || !cell->known()) - for (auto bit : assign_map(conn.second)) { - if (is_output) - bit2driver[bit] = cell; - driven_bits.insert(bit); - } - } - - if (cell->type.in(ID($mux), ID($pmux))) { - if (cell->getPort(ID::A).size() == cell->getPort(ID::B).size()) - mux_drivers.insert(assign_map(cell->getPort(ID::Y)), cell); - continue; - } - - if (!design->selected(module, cell)) - continue; - - if (cell->type.in(ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), - ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_), ID($dffsr), - ID($_DLATCHSR_NNN_), ID($_DLATCHSR_NNP_), ID($_DLATCHSR_NPN_), ID($_DLATCHSR_NPP_), - ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_), ID($dlatchsr))) - dffsr_list.push_back(cell->name); - - if (cell->type.in(ID($_FF_), ID($_DFF_N_), ID($_DFF_P_), - ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_), - ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), - ID($ff), ID($dff), ID($dffe), ID($adff))) - dff_list.push_back(cell->name); - - if (cell->type.in(ID($dlatch), ID($_DLATCH_P_), ID($_DLATCH_N_))) - dlatch_list.push_back(cell->name); - } - - for (auto &id : dffsr_list) { - if (module->cell(id) != nullptr && - handle_dffsr(module, module->cells_[id])) - total_count++; - } - - for (auto &id : dff_list) { - if (module->cell(id) != nullptr && - handle_dff(module, module->cells_[id])) - total_count++; - } - - for (auto &id : dlatch_list) { - if (module->cell(id) != nullptr && - handle_dlatch(module, module->cells_[id])) - total_count++; - } - - SigSpec const_init_sigs; - - for (auto bit : init_bits) - if (!driven_bits.count(bit.first)) - const_init_sigs.append(bit.first); - - const_init_sigs.sort_and_unify(); - - for (SigSpec sig : const_init_sigs.chunks()) - { - Const val; - - for (auto bit : sig) - val.bits.push_back(init_bits.at(bit)); - - log("Promoting init spec %s = %s to constant driver in module %s.\n", - log_signal(sig), log_signal(val), log_id(module)); - - module->connect(sig, val); - remove_init_attr(sig); - total_initdrv++; - } - } - - assign_map.clear(); - mux_drivers.clear(); - bit2driver.clear(); - init_attributes.clear(); - - if (total_count || total_initdrv) - design->scratchpad_set_bool("opt.did_something", true); - - if (total_initdrv) - log("Promoted %d init specs to constant drivers.\n", total_initdrv); - - if (total_count) - log("Replaced %d DFF cells.\n", total_count); - } -} OptRmdffPass; - -PRIVATE_NAMESPACE_END diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index cbace7bac..53296699c 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -30,8 +30,6 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -SigMap assign_map; - struct OpMuxConn { RTLIL::SigSpec sig; RTLIL::Cell *mux; @@ -157,9 +155,9 @@ bool decode_port_signed(RTLIL::Cell *cell, RTLIL::IdString port_name) return false; } -ExtSigSpec decode_port(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sigmap) +ExtSigSpec decode_port(RTLIL::Cell *cell, RTLIL::IdString port_name, const SigMap &sigmap) { - auto sig = (*sigmap)(cell->getPort(port_name)); + auto sig = sigmap(cell->getPort(port_name)); RTLIL::SigSpec sign = decode_port_sign(cell, port_name); RTLIL::IdString semantics = decode_port_semantics(cell, port_name); @@ -169,7 +167,7 @@ ExtSigSpec decode_port(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sig return ExtSigSpec(sig, sign, is_signed, semantics); } -void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<OpMuxConn> &ports, const ExtSigSpec &operand) +void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<OpMuxConn> &ports, const ExtSigSpec &operand, const SigMap &sigmap) { std::vector<ExtSigSpec> muxed_operands; int max_width = 0; @@ -177,10 +175,10 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< auto op = p.op; RTLIL::IdString muxed_port_name = ID::A; - if (decode_port(op, ID::A, &assign_map) == operand) + if (decode_port(op, ID::A, sigmap) == operand) muxed_port_name = ID::B; - auto operand = decode_port(op, muxed_port_name, &assign_map); + auto operand = decode_port(op, muxed_port_name, sigmap); if (operand.sig.size() > max_width) max_width = operand.sig.size(); @@ -190,11 +188,13 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< auto shared_op = ports[0].op; if (std::any_of(muxed_operands.begin(), muxed_operands.end(), [&](ExtSigSpec &op) { return op.sign != muxed_operands[0].sign; })) - max_width = std::max(max_width, shared_op->getParam(ID::Y_WIDTH).as_int()); - + max_width = std::max(max_width, shared_op->getParam(ID::Y_WIDTH).as_int()); - for (auto &operand : muxed_operands) + for (auto &operand : muxed_operands) { operand.sig.extend_u0(max_width, operand.is_signed); + if (operand.sign != muxed_operands[0].sign) + operand = ExtSigSpec(module->Neg(NEW_ID, operand.sig, operand.is_signed)); + } for (const auto& p : ports) { auto op = p.op; @@ -203,61 +203,58 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< module->remove(op); } - for (auto &muxed_op : muxed_operands) - if (muxed_op.sign != muxed_operands[0].sign) - muxed_op = ExtSigSpec(module->Neg(NEW_ID, muxed_op.sig, muxed_op.is_signed)); - - RTLIL::SigSpec mux_y = mux->getPort(ID::Y); RTLIL::SigSpec mux_a = mux->getPort(ID::A); RTLIL::SigSpec mux_b = mux->getPort(ID::B); RTLIL::SigSpec mux_s = mux->getPort(ID::S); + int conn_width = ports[0].sig.size(); + int conn_mux_offset = ports[0].mux_port_offset; + int conn_op_offset = ports[0].op_outsig_offset; + RTLIL::SigSpec shared_pmux_a = RTLIL::Const(RTLIL::State::Sx, max_width); RTLIL::SigSpec shared_pmux_b; RTLIL::SigSpec shared_pmux_s; - int conn_width = ports[0].sig.size(); - int conn_offset = ports[0].mux_port_offset; - - shared_op->setPort(ID::Y, shared_op->getPort(ID::Y).extract(0, conn_width)); + // Make a new wire to avoid false equivalence with whatever the former shared output was connected to. + Wire *new_out = module->addWire(NEW_ID, conn_op_offset + conn_width); + SigSpec new_sig_out = SigSpec(new_out, conn_op_offset, conn_width); - if (mux->type == ID($pmux)) { - shared_pmux_s = RTLIL::SigSpec(); - - for (const auto &p : ports) { + for (int i = 0; i < GetSize(ports); i++) { + auto &p = ports[i]; + auto &op = muxed_operands[i]; + if (p.mux_port_id == GetSize(mux_s)) { + shared_pmux_a = op.sig; + mux_a.replace(conn_mux_offset, new_sig_out); + } else { shared_pmux_s.append(mux_s[p.mux_port_id]); - mux_b.replace(p.mux_port_id * mux_a.size() + conn_offset, shared_op->getPort(ID::Y)); + shared_pmux_b.append(op.sig); + mux_b.replace(p.mux_port_id * mux_a.size() + conn_mux_offset, new_sig_out); } - } else { - shared_pmux_s = RTLIL::SigSpec{mux_s, module->Not(NEW_ID, mux_s)}; - mux_a.replace(conn_offset, shared_op->getPort(ID::Y)); - mux_b.replace(conn_offset, shared_op->getPort(ID::Y)); } mux->setPort(ID::A, mux_a); mux->setPort(ID::B, mux_b); - mux->setPort(ID::Y, mux_y); mux->setPort(ID::S, mux_s); - for (const auto &op : muxed_operands) - shared_pmux_b.append(op.sig); - - auto mux_to_oper = module->Pmux(NEW_ID, shared_pmux_a, shared_pmux_b, shared_pmux_s); + SigSpec mux_to_oper; + if (GetSize(shared_pmux_s) == 1) { + mux_to_oper = module->Mux(NEW_ID, shared_pmux_a, shared_pmux_b, shared_pmux_s); + } else { + mux_to_oper = module->Pmux(NEW_ID, shared_pmux_a, shared_pmux_b, shared_pmux_s); + } if (shared_op->type.in(ID($alu))) { - RTLIL::SigSpec alu_x = shared_op->getPort(ID::X); - RTLIL::SigSpec alu_co = shared_op->getPort(ID::CO); - - shared_op->setPort(ID::X, alu_x.extract(0, conn_width)); - shared_op->setPort(ID::CO, alu_co.extract(0, conn_width)); + shared_op->setPort(ID::X, module->addWire(NEW_ID, GetSize(new_sig_out))); + shared_op->setPort(ID::CO, module->addWire(NEW_ID, GetSize(new_sig_out))); } bool is_fine = shared_op->type.in(FINE_BITWISE_OPS); + shared_op->setPort(ID::Y, new_out); if (!is_fine) - shared_op->setParam(ID::Y_WIDTH, conn_width); + shared_op->setParam(ID::Y_WIDTH, GetSize(new_out)); - if (decode_port(shared_op, ID::A, &assign_map) == operand) { + if (decode_port(shared_op, ID::A, sigmap) == operand) { shared_op->setPort(ID::B, mux_to_oper); if (!is_fine) shared_op->setParam(ID::B_WIDTH, max_width); @@ -275,17 +272,7 @@ typedef struct { } merged_op_t; -template <typename T> void remove_val(std::vector<T> &v, const std::vector<T> &vals) -{ - auto val_iter = vals.rbegin(); - for (auto i = v.rbegin(); i != v.rend(); ++i) - if ((val_iter != vals.rend()) && (*i == *val_iter)) { - v.erase(i.base() - 1); - ++val_iter; - } -} - -void check_muxed_operands(std::vector<const OpMuxConn *> &ports, const ExtSigSpec &shared_operand) +void check_muxed_operands(std::vector<const OpMuxConn *> &ports, const ExtSigSpec &shared_operand, const SigMap &sigmap) { auto it = ports.begin(); ExtSigSpec seed; @@ -295,11 +282,11 @@ void check_muxed_operands(std::vector<const OpMuxConn *> &ports, const ExtSigSpe auto op = p->op; RTLIL::IdString muxed_port_name = ID::A; - if (decode_port(op, ID::A, &assign_map) == shared_operand) { + if (decode_port(op, ID::A, sigmap) == shared_operand) { muxed_port_name = ID::B; } - auto operand = decode_port(op, muxed_port_name, &assign_map); + auto operand = decode_port(op, muxed_port_name, sigmap); if (seed.empty()) seed = operand; @@ -312,7 +299,7 @@ void check_muxed_operands(std::vector<const OpMuxConn *> &ports, const ExtSigSpe } } -ExtSigSpec find_shared_operand(const OpMuxConn* seed, std::vector<const OpMuxConn *> &ports, const std::map<ExtSigSpec, std::set<RTLIL::Cell *>> &operand_to_users) +ExtSigSpec find_shared_operand(const OpMuxConn* seed, std::vector<const OpMuxConn *> &ports, const std::map<ExtSigSpec, std::set<RTLIL::Cell *>> &operand_to_users, const SigMap &sigmap) { std::set<RTLIL::Cell *> ops_using_operand; std::set<RTLIL::Cell *> ops_set; @@ -324,7 +311,7 @@ ExtSigSpec find_shared_operand(const OpMuxConn* seed, std::vector<const OpMuxCon auto op_a = seed->op; for (RTLIL::IdString port_name : {ID::A, ID::B}) { - oper = decode_port(op_a, port_name, &assign_map); + oper = decode_port(op_a, port_name, sigmap); auto operand_users = operand_to_users.at(oper); if (operand_users.size() == 1) @@ -345,135 +332,9 @@ ExtSigSpec find_shared_operand(const OpMuxConn* seed, std::vector<const OpMuxCon return ExtSigSpec(); } -dict<RTLIL::SigSpec, OpMuxConn> find_valid_op_mux_conns(RTLIL::Module *module, dict<RTLIL::SigBit, RTLIL::SigSpec> &op_outbit_to_outsig, - dict<RTLIL::SigSpec, RTLIL::Cell *> outsig_to_operator, - dict<RTLIL::SigBit, RTLIL::SigSpec> &op_aux_to_outsig) -{ - dict<RTLIL::SigSpec, int> op_outsig_user_track; - dict<RTLIL::SigSpec, OpMuxConn> op_mux_conn_map; - - std::function<void(RTLIL::SigSpec)> remove_outsig = [&](RTLIL::SigSpec outsig) { - for (auto op_outbit : outsig) - op_outbit_to_outsig.erase(op_outbit); - - if (op_mux_conn_map.count(outsig)) - op_mux_conn_map.erase(outsig); - }; - - std::function<void(RTLIL::SigBit)> remove_outsig_from_aux_bit = [&](RTLIL::SigBit auxbit) { - auto aux_outsig = op_aux_to_outsig.at(auxbit); - auto op = outsig_to_operator.at(aux_outsig); - auto op_outsig = assign_map(op->getPort(ID::Y)); - remove_outsig(op_outsig); - - for (auto aux_outbit : aux_outsig) - op_aux_to_outsig.erase(aux_outbit); - }; - - std::function<void(RTLIL::Cell *)> find_op_mux_conns = [&](RTLIL::Cell *mux) { - RTLIL::SigSpec sig; - int mux_port_size; - - if (mux->type.in(ID($mux), ID($_MUX_))) { - mux_port_size = mux->getPort(ID::A).size(); - sig = RTLIL::SigSpec{mux->getPort(ID::B), mux->getPort(ID::A)}; - } else { - mux_port_size = mux->getPort(ID::A).size(); - sig = mux->getPort(ID::B); - } - - auto mux_insig = assign_map(sig); - - for (int i = 0; i < mux_insig.size(); ++i) { - if (op_aux_to_outsig.count(mux_insig[i])) { - remove_outsig_from_aux_bit(mux_insig[i]); - continue; - } - - if (!op_outbit_to_outsig.count(mux_insig[i])) - continue; - - auto op_outsig = op_outbit_to_outsig.at(mux_insig[i]); - - if (op_mux_conn_map.count(op_outsig)) { - remove_outsig(op_outsig); - continue; - } - - int mux_port_id = i / mux_port_size; - int mux_port_offset = i % mux_port_size; - - int op_outsig_offset; - for (op_outsig_offset = 0; op_outsig[op_outsig_offset] != mux_insig[i]; ++op_outsig_offset) - ; - - int j = op_outsig_offset; - do { - if (!op_outbit_to_outsig.count(mux_insig[i])) - break; - - if (op_outbit_to_outsig.at(mux_insig[i]) != op_outsig) - break; - - ++i; - ++j; - } while ((i / mux_port_size == mux_port_id) && (j < op_outsig.size())); - - int op_conn_width = j - op_outsig_offset; - OpMuxConn inp = { - op_outsig.extract(op_outsig_offset, op_conn_width), - mux, - outsig_to_operator.at(op_outsig), - mux_port_id, - mux_port_offset, - op_outsig_offset, - }; - - op_mux_conn_map[op_outsig] = inp; - - --i; - } - }; - - std::function<void(RTLIL::SigSpec)> remove_connected_ops = [&](RTLIL::SigSpec sig) { - auto mux_insig = assign_map(sig); - for (auto outbit : mux_insig) { - if (op_aux_to_outsig.count(outbit)) { - remove_outsig_from_aux_bit(outbit); - continue; - } - - if (!op_outbit_to_outsig.count(outbit)) - continue; - - remove_outsig(op_outbit_to_outsig.at(outbit)); - } - }; - - for (auto cell : module->cells()) { - if (cell->type.in(ID($mux), ID($_MUX_), ID($pmux))) { - remove_connected_ops(cell->getPort(ID::S)); - find_op_mux_conns(cell); - } else { - for (auto &conn : cell->connections()) - if (cell->input(conn.first)) - remove_connected_ops(conn.second); - } - } - - for (auto w : module->wires()) { - if (!w->port_output) - continue; - - remove_connected_ops(w); - } - - return op_mux_conn_map; -} - struct OptSharePass : public Pass { OptSharePass() : Pass("opt_share", "merge mutually exclusive cells of the same type that share an input signal") {} - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -488,44 +349,53 @@ struct OptSharePass : public Pass { log("multiplexing its output to multiplexing the non-shared input signals.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing OPT_SHARE pass.\n"); extra_args(args, 1, design); for (auto module : design->selected_modules()) { - assign_map.clear(); - assign_map.set(module); + SigMap sigmap(module); + + dict<RTLIL::SigBit, int> bit_users; + + for (auto cell : module->cells()) + for (auto conn : cell->connections()) + for (auto bit : conn.second) + bit_users[sigmap(bit)]++; + + for (auto wire : module->wires()) + if (wire->port_id != 0) + for (auto bit : SigSpec(wire)) + bit_users[sigmap(bit)]++; std::map<ExtSigSpec, std::set<RTLIL::Cell *>> operand_to_users; - dict<RTLIL::SigSpec, RTLIL::Cell *> outsig_to_operator; - dict<RTLIL::SigBit, RTLIL::SigSpec> op_outbit_to_outsig; - dict<RTLIL::SigBit, RTLIL::SigSpec> op_aux_to_outsig; + dict<RTLIL::SigBit, std::pair<RTLIL::Cell *, int>> op_outbit_to_outsig; bool any_shared_operands = false; - std::vector<ExtSigSpec> op_insigs; - for (auto cell : module->cells()) { + for (auto cell : module->selected_cells()) { if (!cell_supported(cell)) continue; + bool skip = false; if (cell->type == ID($alu)) { for (RTLIL::IdString port_name : {ID::X, ID::CO}) { - auto mux_insig = assign_map(cell->getPort(port_name)); - outsig_to_operator[mux_insig] = cell; - for (auto outbit : mux_insig) - op_aux_to_outsig[outbit] = mux_insig; + for (auto outbit : sigmap(cell->getPort(port_name))) + if (bit_users[outbit] > 1) + skip = true; } } - auto mux_insig = assign_map(cell->getPort(ID::Y)); - outsig_to_operator[mux_insig] = cell; - for (auto outbit : mux_insig) - op_outbit_to_outsig[outbit] = mux_insig; + if (skip) + continue; + + auto mux_insig = sigmap(cell->getPort(ID::Y)); + for (int i = 0; i < GetSize(mux_insig); i++) + op_outbit_to_outsig[mux_insig[i]] = std::make_pair(cell, i); for (RTLIL::IdString port_name : {ID::A, ID::B}) { - auto op_insig = decode_port(cell, port_name, &assign_map); - op_insigs.push_back(op_insig); + auto op_insig = decode_port(cell, port_name, sigmap); operand_to_users[op_insig].insert(cell); if (operand_to_users[op_insig].size() > 1) any_shared_operands = true; @@ -537,34 +407,79 @@ struct OptSharePass : public Pass { // Operator outputs need to be exclusively connected to the $mux inputs in order to be mergeable. Hence we count to // how many points are operator output bits connected. - dict<RTLIL::SigSpec, OpMuxConn> op_mux_conn_map = - find_valid_op_mux_conns(module, op_outbit_to_outsig, outsig_to_operator, op_aux_to_outsig); + std::vector<merged_op_t> merged_ops; - // Group op connections connected to same ports of the same $mux. Sort them in ascending order of their port offset - dict<RTLIL::Cell*, std::vector<std::set<OpMuxConn>>> mux_port_op_conns; - for (auto& val: op_mux_conn_map) { - OpMuxConn p = val.second; - auto& mux_port_conns = mux_port_op_conns[p.mux]; + for (auto mux : module->selected_cells()) { + if (!mux->type.in(ID($mux), ID($_MUX_), ID($pmux))) + continue; - if (mux_port_conns.size() == 0) { - int mux_port_num; + int mux_port_size = GetSize(mux->getPort(ID::A)); + int mux_port_num = GetSize(mux->getPort(ID::S)) + 1; - if (p.mux->type.in(ID($mux), ID($_MUX_))) - mux_port_num = 2; - else - mux_port_num = p.mux->getPort(ID::S).size(); + RTLIL::SigSpec mux_insig = sigmap(RTLIL::SigSpec{mux->getPort(ID::B), mux->getPort(ID::A)}); + std::vector<std::set<OpMuxConn>> mux_port_conns(mux_port_num); + int found = 0; - mux_port_conns.resize(mux_port_num); - } + for (int mux_port_id = 0; mux_port_id < mux_port_num; mux_port_id++) { + SigSpec mux_insig; + if (mux_port_id == mux_port_num - 1) { + mux_insig = sigmap(mux->getPort(ID::A)); + } else { + mux_insig = sigmap(mux->getPort(ID::B).extract(mux_port_id * mux_port_size, mux_port_size)); + } - mux_port_conns[p.mux_port_id].insert(p); - } + for (int mux_port_offset = 0; mux_port_offset < mux_port_size; ++mux_port_offset) { + if (!op_outbit_to_outsig.count(mux_insig[mux_port_offset])) + continue; - std::vector<merged_op_t> merged_ops; - for (auto& val: mux_port_op_conns) { + RTLIL::Cell *cell; + int op_outsig_offset; + std::tie(cell, op_outsig_offset) = op_outbit_to_outsig.at(mux_insig[mux_port_offset]); + SigSpec op_outsig = sigmap(cell->getPort(ID::Y)); + int op_outsig_size = GetSize(op_outsig); + int op_conn_width = 0; + + while (mux_port_offset + op_conn_width < mux_port_size && + op_outsig_offset + op_conn_width < op_outsig_size && + mux_insig[mux_port_offset + op_conn_width] == op_outsig[op_outsig_offset + op_conn_width]) + op_conn_width++; + + log_assert(op_conn_width >= 1); + + bool skip = false; + for (int i = 0; i < op_outsig_size; i++) { + int expected = 1; + if (i >= op_outsig_offset && i < op_outsig_offset + op_conn_width) + expected = 2; + if (bit_users[op_outsig[i]] != expected) + skip = true; + } + if (skip) { + mux_port_offset += op_conn_width; + mux_port_offset--; + continue; + } + + OpMuxConn inp = { + op_outsig.extract(op_outsig_offset, op_conn_width), + mux, + cell, + mux_port_id, + mux_port_offset, + op_outsig_offset, + }; + + mux_port_conns[mux_port_id].insert(inp); + + mux_port_offset += op_conn_width; + mux_port_offset--; - RTLIL::Cell* cell = val.first; - auto &mux_port_conns = val.second; + found++; + } + } + + if (found < 2) + continue; const OpMuxConn *seed = NULL; @@ -612,12 +527,12 @@ struct OptSharePass : public Pass { continue; // Filter mergeable connections whose ops share an operand with seed connection's op - auto shared_operand = find_shared_operand(seed, mergeable_conns, operand_to_users); + auto shared_operand = find_shared_operand(seed, mergeable_conns, operand_to_users, sigmap); if (shared_operand.empty()) continue; - check_muxed_operands(mergeable_conns, shared_operand); + check_muxed_operands(mergeable_conns, shared_operand, sigmap); if (mergeable_conns.size() < 2) continue; @@ -631,7 +546,7 @@ struct OptSharePass : public Pass { seed = NULL; - merged_ops.push_back(merged_op_t{cell, merged_ports, shared_operand}); + merged_ops.push_back(merged_op_t{mux, merged_ports, shared_operand}); design->scratchpad_set_bool("opt.did_something", true); } @@ -647,7 +562,7 @@ struct OptSharePass : public Pass { log(" %s\n", log_id(op.op)); log("\n"); - merge_operators(module, shared.mux, shared.ports, shared.shared_operand); + merge_operators(module, shared.mux, shared.ports, shared.shared_operand, sigmap); } } } diff --git a/passes/opt/pmux2shiftx.cc b/passes/opt/pmux2shiftx.cc index 11b80b6b3..f3b1fd377 100644 --- a/passes/opt/pmux2shiftx.cc +++ b/passes/opt/pmux2shiftx.cc @@ -19,6 +19,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/ffinit.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -30,7 +31,7 @@ struct OnehotDatabase bool verbose = false; bool initialized = false; - pool<SigBit> init_ones; + FfInitVals initvals; dict<SigSpec, pool<SigSpec>> sig_sources_db; dict<SigSpec, bool> sig_onehot_cache; pool<SigSpec> recursion_guard; @@ -44,30 +45,20 @@ struct OnehotDatabase log_assert(!initialized); initialized = true; - for (auto wire : module->wires()) - { - auto it = wire->attributes.find(ID::init); - if (it == wire->attributes.end()) - continue; - - auto &val = it->second; - int width = std::max(GetSize(wire), GetSize(val)); - - for (int i = 0; i < width; i++) - if (val[i] == State::S1) - init_ones.insert(sigmap(SigBit(wire, i))); - } + initvals.set(&sigmap, module); for (auto cell : module->cells()) { vector<SigSpec> inputs; SigSpec output; - if (cell->type.in(ID($adff), ID($dff), ID($dffe), ID($dlatch), ID($ff))) + if (cell->type.in(ID($adff), ID($adffe), ID($dff), ID($dffe), ID($sdff), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch), ID($ff))) { output = cell->getPort(ID::Q); - if (cell->type == ID($adff)) + if (cell->type.in(ID($adff), ID($adffe), ID($adlatch))) inputs.push_back(cell->getParam(ID::ARST_VALUE)); + if (cell->type.in(ID($sdff), ID($sdffe), ID($sdffce))) + inputs.push_back(cell->getParam(ID::SRST_VALUE)); inputs.push_back(cell->getPort(ID::D)); } @@ -117,7 +108,7 @@ struct OnehotDatabase bool found_init_ones = false; for (auto bit : sig) { - if (init_ones.count(bit)) { + if (initvals(bit) == State::S1) { if (found_init_ones) { if (verbose) log("%*s - non-onehot init value\n", indent, ""); @@ -198,7 +189,7 @@ struct OnehotDatabase struct Pmux2ShiftxPass : public Pass { Pmux2ShiftxPass() : Pass("pmux2shiftx", "transform $pmux cells to $shiftx cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -225,7 +216,7 @@ struct Pmux2ShiftxPass : public Pass { log(" disable $sub inference for \"range decoders\"\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { int min_density = 50; int min_choices = 3; @@ -737,7 +728,7 @@ struct Pmux2ShiftxPass : public Pass { struct OnehotPass : public Pass { OnehotPass() : Pass("onehot", "optimize $eq cells for onehot signals") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -749,7 +740,7 @@ struct OnehotPass : public Pass { log(" verbose output\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool verbose = false; bool verbose_onehot = false; diff --git a/passes/opt/rmports.cc b/passes/opt/rmports.cc index 32363dd68..99a2a61c8 100644 --- a/passes/opt/rmports.cc +++ b/passes/opt/rmports.cc @@ -28,7 +28,7 @@ PRIVATE_NAMESPACE_BEGIN struct RmportsPassPass : public Pass { RmportsPassPass() : Pass("rmports", "remove module ports with no connections") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -39,7 +39,7 @@ struct RmportsPassPass : public Pass { log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing RMPORTS pass (remove ports with no connections).\n"); diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 988253edf..f7848e01d 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -1444,7 +1444,7 @@ struct ShareWorker struct SharePass : public Pass { SharePass() : Pass("share", "perform sat-based resource sharing") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1476,7 +1476,7 @@ struct SharePass : public Pass { log(" Only perform the first N merges, then stop. This is useful for debugging.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { ShareWorkerConfig config; diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index f60f2f8a8..a216f36d4 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -20,6 +20,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/modtools.h" +#include "kernel/ffinit.h" USING_YOSYS_NAMESPACE @@ -39,7 +40,8 @@ struct WreduceConfig ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), ID($add), ID($sub), ID($mul), // ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow), ID($mux), ID($pmux), - ID($dff), ID($adff) + ID($dff), ID($dffe), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), + ID($dlatch), ID($adlatch), }); } }; @@ -53,8 +55,7 @@ struct WreduceWorker std::set<Cell*, IdString::compare_ptr_by_name<Cell>> work_queue_cells; std::set<SigBit> work_queue_bits; pool<SigBit> keep_bits; - dict<SigBit, State> init_bits; - pool<SigBit> remove_init_bits; + FfInitVals initvals; WreduceWorker(WreduceConfig *config, Module *module) : config(config), module(module), mi(module) { } @@ -143,8 +144,8 @@ struct WreduceWorker SigSpec sig_d = mi.sigmap(cell->getPort(ID::D)); SigSpec sig_q = mi.sigmap(cell->getPort(ID::Q)); - bool is_adff = (cell->type == ID($adff)); - Const initval, arst_value; + bool has_reset = false; + Const initval = initvals(sig_q), rst_value; int width_before = GetSize(sig_q); @@ -152,35 +153,31 @@ struct WreduceWorker return; if (cell->parameters.count(ID::ARST_VALUE)) { - arst_value = cell->parameters[ID::ARST_VALUE]; + rst_value = cell->parameters[ID::ARST_VALUE]; + has_reset = true; + } else if (cell->parameters.count(ID::SRST_VALUE)) { + rst_value = cell->parameters[ID::SRST_VALUE]; + has_reset = true; } bool zero_ext = sig_d[GetSize(sig_d)-1] == State::S0; bool sign_ext = !zero_ext; - for (int i = 0; i < GetSize(sig_q); i++) { - SigBit bit = sig_q[i]; - if (init_bits.count(bit)) - initval.bits.push_back(init_bits.at(bit)); - else - initval.bits.push_back(State::Sx); - } - for (int i = GetSize(sig_q)-1; i >= 0; i--) { if (zero_ext && sig_d[i] == State::S0 && (initval[i] == State::S0 || initval[i] == State::Sx) && - (!is_adff || i >= GetSize(arst_value) || arst_value[i] == State::S0 || arst_value[i] == State::Sx)) { + (!has_reset || i >= GetSize(rst_value) || rst_value[i] == State::S0 || rst_value[i] == State::Sx)) { module->connect(sig_q[i], State::S0); - remove_init_bits.insert(sig_q[i]); + initvals.remove_init(sig_q[i]); sig_d.remove(i); sig_q.remove(i); continue; } if (sign_ext && i > 0 && sig_d[i] == sig_d[i-1] && initval[i] == initval[i-1] && - (!is_adff || i >= GetSize(arst_value) || arst_value[i] == arst_value[i-1])) { + (!has_reset || i >= GetSize(rst_value) || rst_value[i] == rst_value[i-1])) { module->connect(sig_q[i], sig_q[i-1]); - remove_init_bits.insert(sig_q[i]); + initvals.remove_init(sig_q[i]); sig_d.remove(i); sig_q.remove(i); continue; @@ -190,7 +187,7 @@ struct WreduceWorker if (info == nullptr) return; if (!info->is_output && GetSize(info->ports) == 1 && !keep_bits.count(mi.sigmap(sig_q[i]))) { - remove_init_bits.insert(sig_q[i]); + initvals.remove_init(sig_q[i]); sig_d.remove(i); sig_q.remove(i); zero_ext = false; @@ -221,8 +218,11 @@ struct WreduceWorker // Narrow ARST_VALUE parameter to new size. if (cell->parameters.count(ID::ARST_VALUE)) { - arst_value.bits.resize(GetSize(sig_q)); - cell->setParam(ID::ARST_VALUE, arst_value); + rst_value.bits.resize(GetSize(sig_q)); + cell->setParam(ID::ARST_VALUE, rst_value); + } else if (cell->parameters.count(ID::SRST_VALUE)) { + rst_value.bits.resize(GetSize(sig_q)); + cell->setParam(ID::SRST_VALUE, rst_value); } cell->setPort(ID::D, sig_d); @@ -272,7 +272,7 @@ struct WreduceWorker if (cell->type.in(ID($mux), ID($pmux))) return run_cell_mux(cell); - if (cell->type.in(ID($dff), ID($adff))) + if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch))) return run_cell_dff(cell); SigSpec sig = mi.sigmap(cell->getPort(ID::Y)); @@ -401,18 +401,12 @@ struct WreduceWorker { // create a copy as mi.sigmap will be updated as we process the module SigMap init_attr_sigmap = mi.sigmap; + initvals.set(&init_attr_sigmap, module); for (auto w : module->wires()) { if (w->get_bool_attribute(ID::keep)) for (auto bit : mi.sigmap(w)) keep_bits.insert(bit); - if (w->attributes.count(ID::init)) { - Const initval = w->attributes.at(ID::init); - SigSpec initsig = init_attr_sigmap(w); - int width = std::min(GetSize(initval), GetSize(initsig)); - for (int i = 0; i < width; i++) - init_bits[initsig[i]] = initval[i]; - } } for (auto c : module->selected_cells()) @@ -461,28 +455,12 @@ struct WreduceWorker module->connect(nw, SigSpec(w).extract(0, GetSize(nw))); module->swap_names(w, nw); } - - if (!remove_init_bits.empty()) { - for (auto w : module->wires()) { - if (w->attributes.count(ID::init)) { - Const initval = w->attributes.at(ID::init); - Const new_initval(State::Sx, GetSize(w)); - SigSpec initsig = init_attr_sigmap(w); - int width = std::min(GetSize(initval), GetSize(initsig)); - for (int i = 0; i < width; i++) { - if (!remove_init_bits.count(initsig[i])) - new_initval[i] = initval[i]; - } - w->attributes.at(ID::init) = new_initval; - } - } - } } }; struct WreducePass : public Pass { WreducePass() : Pass("wreduce", "reduce the word size of operations if possible") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -505,7 +483,7 @@ struct WreducePass : public Pass { log(" Do not optimize explicit don't-care values.\n"); log("\n"); } - void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, Design *design) override { WreduceConfig config; bool opt_memx = false; diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index 1a57bef7d..c6bbc386a 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -36,7 +36,6 @@ $(eval $(call add_extra_objs,passes/pmgen/peepopt_pm.h)) PEEPOPT_PATTERN = passes/pmgen/peepopt_shiftmul.pmg PEEPOPT_PATTERN += passes/pmgen/peepopt_muldiv.pmg -PEEPOPT_PATTERN += passes/pmgen/peepopt_dffmux.pmg passes/pmgen/peepopt_pm.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN) $(P) mkdir -p passes/pmgen && $(PYTHON_EXECUTABLE) $< -o $@ -p peepopt $(filter-out $<,$^) diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc index f16cc4a0b..c46f5d58f 100644 --- a/passes/pmgen/ice40_dsp.cc +++ b/passes/pmgen/ice40_dsp.cc @@ -31,15 +31,15 @@ void create_ice40_dsp(ice40_dsp_pm &pm) log("Checking %s.%s for iCE40 DSP inference.\n", log_id(pm.module), log_id(st.mul)); - log_debug("ffA: %s %s %s\n", log_id(st.ffA, "--"), log_id(st.ffAholdmux, "--"), log_id(st.ffArstmux, "--")); - log_debug("ffB: %s %s %s\n", log_id(st.ffB, "--"), log_id(st.ffBholdmux, "--"), log_id(st.ffBrstmux, "--")); - log_debug("ffCD: %s %s\n", log_id(st.ffCD, "--"), log_id(st.ffCDholdmux, "--")); + log_debug("ffA: %s\n", log_id(st.ffA, "--")); + log_debug("ffB: %s\n", log_id(st.ffB, "--")); + log_debug("ffCD: %s\n", log_id(st.ffCD, "--")); log_debug("mul: %s\n", log_id(st.mul, "--")); log_debug("ffFJKG: %s\n", log_id(st.ffFJKG, "--")); log_debug("ffH: %s\n", log_id(st.ffH, "--")); log_debug("add: %s\n", log_id(st.add, "--")); log_debug("mux: %s\n", log_id(st.mux, "--")); - log_debug("ffO: %s %s %s\n", log_id(st.ffO, "--"), log_id(st.ffOholdmux, "--"), log_id(st.ffOrstmux, "--")); + log_debug("ffO: %s\n", log_id(st.ffO, "--")); log_debug("\n"); if (GetSize(st.sigA) > 16) { @@ -97,16 +97,16 @@ void create_ice40_dsp(ice40_dsp_pm &pm) cell->setParam(ID(D_REG), st.ffCD ? State::S1 : State::S0); SigSpec AHOLD, BHOLD, CDHOLD; - if (st.ffAholdmux) - AHOLD = st.ffAholdpol ? st.ffAholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffAholdmux->getPort(ID::S)); + if (st.ffA && st.ffA->hasPort(ID::EN)) + AHOLD = st.ffA->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffA->getPort(ID::EN)) : st.ffA->getPort(ID::EN); else AHOLD = State::S0; - if (st.ffBholdmux) - BHOLD = st.ffBholdpol ? st.ffBholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffBholdmux->getPort(ID::S)); + if (st.ffB && st.ffB->hasPort(ID::EN)) + BHOLD = st.ffB->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffB->getPort(ID::EN)) : st.ffB->getPort(ID::EN); else BHOLD = State::S0; - if (st.ffCDholdmux) - CDHOLD = st.ffCDholdpol ? st.ffCDholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffCDholdmux->getPort(ID::S)); + if (st.ffCD && st.ffCD->hasPort(ID::EN)) + CDHOLD = st.ffCD->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffCD->getPort(ID::EN)) : st.ffCD->getPort(ID::EN); else CDHOLD = State::S0; cell->setPort(ID(AHOLD), AHOLD); @@ -115,12 +115,12 @@ void create_ice40_dsp(ice40_dsp_pm &pm) cell->setPort(ID(DHOLD), CDHOLD); SigSpec IRSTTOP, IRSTBOT; - if (st.ffArstmux) - IRSTTOP = st.ffArstpol ? st.ffArstmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffArstmux->getPort(ID::S)); + if (st.ffA && st.ffA->hasPort(ID::ARST)) + IRSTTOP = st.ffA->getParam(ID::ARST_POLARITY).as_bool() ? st.ffA->getPort(ID::ARST) : pm.module->Not(NEW_ID, st.ffA->getPort(ID::ARST)); else IRSTTOP = State::S0; - if (st.ffBrstmux) - IRSTBOT = st.ffBrstpol ? st.ffBrstmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffBrstmux->getPort(ID::S)); + if (st.ffB && st.ffB->hasPort(ID::ARST)) + IRSTBOT = st.ffB->getParam(ID::ARST_POLARITY).as_bool() ? st.ffB->getPort(ID::ARST) : pm.module->Not(NEW_ID, st.ffB->getPort(ID::ARST)); else IRSTBOT = State::S0; cell->setPort(ID(IRSTTOP), IRSTTOP); @@ -207,16 +207,16 @@ void create_ice40_dsp(ice40_dsp_pm &pm) } SigSpec OHOLD; - if (st.ffOholdmux) - OHOLD = st.ffOholdpol ? st.ffOholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffOholdmux->getPort(ID::S)); + if (st.ffO && st.ffO->hasPort(ID::EN)) + OHOLD = st.ffO->getParam(ID::EN_POLARITY).as_bool() ? pm.module->Not(NEW_ID, st.ffO->getPort(ID::EN)) : st.ffO->getPort(ID::EN); else OHOLD = State::S0; cell->setPort(ID(OHOLDTOP), OHOLD); cell->setPort(ID(OHOLDBOT), OHOLD); SigSpec ORST; - if (st.ffOrstmux) - ORST = st.ffOrstpol ? st.ffOrstmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffOrstmux->getPort(ID::S)); + if (st.ffO && st.ffO->hasPort(ID::ARST)) + ORST = st.ffO->getParam(ID::ARST_POLARITY).as_bool() ? st.ffO->getPort(ID::ARST) : pm.module->Not(NEW_ID, st.ffO->getPort(ID::ARST)); else ORST = State::S0; cell->setPort(ID(ORSTTOP), ORST); @@ -228,6 +228,8 @@ void create_ice40_dsp(ice40_dsp_pm &pm) acc_reset = st.mux->getPort(ID::S); else acc_reset = pm.module->Not(NEW_ID, st.mux->getPort(ID::S)); + } else if (st.ffO && st.ffO->hasPort(ID::SRST)) { + acc_reset = st.ffO->getParam(ID::SRST_POLARITY).as_bool() ? st.ffO->getPort(ID::SRST) : pm.module->Not(NEW_ID, st.ffO->getPort(ID::SRST)); } cell->setPort(ID(OLOADTOP), acc_reset); cell->setPort(ID(OLOADBOT), acc_reset); @@ -275,7 +277,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm) struct Ice40DspPass : public Pass { Ice40DspPass() : Pass("ice40_dsp", "iCE40: map multipliers") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -294,7 +296,7 @@ struct Ice40DspPass : public Pass { log("the accumulator to an arbitrary value can be inferred to use the {C,D} input.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing ICE40_DSP pass (map multipliers).\n"); diff --git a/passes/pmgen/ice40_dsp.pmg b/passes/pmgen/ice40_dsp.pmg index 2456a49dc..7a01cbd51 100644 --- a/passes/pmgen/ice40_dsp.pmg +++ b/passes/pmgen/ice40_dsp.pmg @@ -6,20 +6,16 @@ state <SigSpec> sigA sigB sigCD sigH sigO state <Cell*> add mux state <IdString> addAB muxAB -state <bool> ffAholdpol ffBholdpol ffCDholdpol ffOholdpol -state <bool> ffArstpol ffBrstpol ffCDrstpol ffOrstpol - -state <Cell*> ffA ffAholdmux ffArstmux ffB ffBholdmux ffBrstmux ffCD ffCDholdmux -state <Cell*> ffFJKG ffH ffO ffOholdmux ffOrstmux +state <Cell*> ffA ffB ffCD +state <Cell*> ffFJKG ffH ffO // subpattern +state <bool> argSdff state <SigSpec> argQ argD -state <bool> ffholdpol ffrstpol -state <int> ffoffset udata <SigSpec> dffD dffQ udata <SigBit> dffclock -udata <Cell*> dff dffholdmux dffrstmux -udata <bool> dffholdpol dffrstpol dffclock_pol +udata <Cell*> dff +udata <bool> dffclock_pol match mul select mul->type.in($mul, \SB_MAC16) @@ -64,7 +60,7 @@ code sigA sigB sigH log_assert(nusers(O.extract_end(i)) <= 1); endcode -code argQ ffA ffAholdmux ffArstmux ffAholdpol ffArstpol sigA clock clock_pol +code argQ ffA sigA clock clock_pol if (mul->type != \SB_MAC16 || !param(mul, \A_REG).as_bool()) { argQ = sigA; subpattern(in_dffe); @@ -72,20 +68,12 @@ code argQ ffA ffAholdmux ffArstmux ffAholdpol ffArstpol sigA clock clock_pol ffA = dff; clock = dffclock; clock_pol = dffclock_pol; - if (dffrstmux) { - ffArstmux = dffrstmux; - ffArstpol = dffrstpol; - } - if (dffholdmux) { - ffAholdmux = dffholdmux; - ffAholdpol = dffholdpol; - } sigA = dffD; } } endcode -code argQ ffB ffBholdmux ffBrstmux ffBholdpol ffBrstpol sigB clock clock_pol +code argQ ffB sigB clock clock_pol if (mul->type != \SB_MAC16 || !param(mul, \B_REG).as_bool()) { argQ = sigB; subpattern(in_dffe); @@ -93,47 +81,44 @@ code argQ ffB ffBholdmux ffBrstmux ffBholdpol ffBrstpol sigB clock clock_pol ffB = dff; clock = dffclock; clock_pol = dffclock_pol; - if (dffrstmux) { - ffBrstmux = dffrstmux; - ffBrstpol = dffrstpol; - } - if (dffholdmux) { - ffBholdmux = dffholdmux; - ffBholdpol = dffholdpol; - } sigB = dffD; } } endcode -code argD ffFJKG sigH clock clock_pol +code argD argSdff ffFJKG sigH clock clock_pol if (nusers(sigH) == 2 && (mul->type != \SB_MAC16 || (!param(mul, \TOP_8x8_MULT_REG).as_bool() && !param(mul, \BOT_8x8_MULT_REG).as_bool() && !param(mul, \PIPELINE_16x16_MULT_REG1).as_bool() && !param(mul, \PIPELINE_16x16_MULT_REG1).as_bool()))) { argD = sigH; + argSdff = false; subpattern(out_dffe); if (dff) { // F/J/K/G do not have a CE-like (hold) input - if (dffholdmux) + if (dff->hasPort(\EN)) goto reject_ffFJKG; // Reset signal of F/J (IRSTTOP) and K/G (IRSTBOT) // shared with A and B - if ((ffArstmux != NULL) != (dffrstmux != NULL)) - goto reject_ffFJKG; - if ((ffBrstmux != NULL) != (dffrstmux != NULL)) - goto reject_ffFJKG; - if (ffArstmux) { - if (port(ffArstmux, \S) != port(dffrstmux, \S)) - goto reject_ffFJKG; - if (ffArstpol != dffrstpol) + if (ffA) { + if (ffA->hasPort(\ARST) != dff->hasPort(\ARST)) goto reject_ffFJKG; + if (ffA->hasPort(\ARST)) { + if (port(ffA, \ARST) != port(dff, \ARST)) + goto reject_ffFJKG; + if (param(ffA, \ARST_POLARITY) != param(dff, \ARST_POLARITY)) + goto reject_ffFJKG; + } } - if (ffBrstmux) { - if (port(ffBrstmux, \S) != port(dffrstmux, \S)) - goto reject_ffFJKG; - if (ffBrstpol != dffrstpol) + if (ffB) { + if (ffB->hasPort(\ARST) != dff->hasPort(\ARST)) goto reject_ffFJKG; + if (ffB->hasPort(\ARST)) { + if (port(ffB, \ARST) != port(dff, \ARST)) + goto reject_ffFJKG; + if (param(ffB, \ARST_POLARITY) != param(dff, \ARST_POLARITY)) + goto reject_ffFJKG; + } } ffFJKG = dff; @@ -146,23 +131,24 @@ reject_ffFJKG: ; } endcode -code argD ffH sigH sigO clock clock_pol +code argD argSdff ffH sigH sigO clock clock_pol if (ffFJKG && nusers(sigH) == 2 && (mul->type != \SB_MAC16 || !param(mul, \PIPELINE_16x16_MULT_REG2).as_bool())) { argD = sigH; + argSdff = false; subpattern(out_dffe); if (dff) { // H does not have a CE-like (hold) input - if (dffholdmux) + if (dff->hasPort(\EN)) goto reject_ffH; // Reset signal of H (IRSTBOT) shared with B - if ((ffBrstmux != NULL) != (dffrstmux != NULL)) + if (ffB->hasPort(\ARST) != dff->hasPort(\ARST)) goto reject_ffH; - if (ffBrstmux) { - if (port(ffBrstmux, \S) != port(dffrstmux, \S)) + if (ffB->hasPort(\ARST)) { + if (port(ffB, \ARST) != port(dff, \ARST)) goto reject_ffH; - if (ffBrstpol != dffrstpol) + if (param(ffB, \ARST_POLARITY) != param(dff, \ARST_POLARITY)) goto reject_ffH; } @@ -226,7 +212,7 @@ code sigO sigO = port(mux, \Y); endcode -code argD ffO ffOholdmux ffOrstmux ffOholdpol ffOrstpol sigO sigCD clock clock_pol cd_signed o_lo +code argD argSdff ffO sigO sigCD clock clock_pol cd_signed o_lo if (mul->type != \SB_MAC16 || // Ensure that register is not already used ((param(mul, \TOPOUTPUT_SELECT).as_int() != 1 && param(mul, \BOTOUTPUT_SELECT).as_int() != 1) && @@ -238,6 +224,7 @@ code argD ffO ffOholdmux ffOrstmux ffOholdpol ffOrstpol sigO sigCD clock clock_p // First try entire sigO if (nusers(sigO) == 2) { argD = sigO; + argSdff = !mux; subpattern(out_dffe); } @@ -245,6 +232,7 @@ code argD ffO ffOholdmux ffOrstmux ffOholdpol ffOrstpol sigO sigCD clock clock_p if (!dff && GetSize(sigO) > 16) { argD = sigO.extract(0, 16); if (nusers(argD) == 2) { + argSdff = !mux; subpattern(out_dffe); o_lo = dff; } @@ -254,14 +242,6 @@ code argD ffO ffOholdmux ffOrstmux ffOholdpol ffOrstpol sigO sigCD clock clock_p ffO = dff; clock = dffclock; clock_pol = dffclock_pol; - if (dffrstmux) { - ffOrstmux = dffrstmux; - ffOrstpol = dffrstpol; - } - if (dffholdmux) { - ffOholdmux = dffholdmux; - ffOholdpol = dffholdpol; - } sigO.replace(sigO.extract(0, GetSize(dffQ)), dffQ); } @@ -274,38 +254,43 @@ code argD ffO ffOholdmux ffOrstmux ffOholdpol ffOrstpol sigO sigCD clock clock_p sigCD = port(mux, muxAB == \B ? \A : \B); cd_signed = add && param(add, \A_SIGNED).as_bool() && param(add, \B_SIGNED).as_bool(); + } else if (dff && dff->hasPort(\SRST)) { + if (sigCD != sigO) + reject; + sigCD = param(dff, \SRST_VALUE); + + cd_signed = add && param(add, \A_SIGNED).as_bool() && param(add, \B_SIGNED).as_bool(); } } endcode -code argQ ffCD ffCDholdmux ffCDholdpol ffCDrstpol sigCD clock clock_pol +code argQ ffCD sigCD clock clock_pol if (!sigCD.empty() && sigCD != sigO && (mul->type != \SB_MAC16 || (!param(mul, \C_REG).as_bool() && !param(mul, \D_REG).as_bool()))) { argQ = sigCD; subpattern(in_dffe); if (dff) { - if (dffholdmux) { - ffCDholdmux = dffholdmux; - ffCDholdpol = dffholdpol; - } - // Reset signal of C (IRSTTOP) and D (IRSTBOT) // shared with A and B - if ((ffArstmux != NULL) != (dffrstmux != NULL)) - goto reject_ffCD; - if ((ffBrstmux != NULL) != (dffrstmux != NULL)) - goto reject_ffCD; - if (ffArstmux) { - if (port(ffArstmux, \S) != port(dffrstmux, \S)) - goto reject_ffCD; - if (ffArstpol != dffrstpol) + if (ffA) { + if (ffA->hasPort(\ARST) != dff->hasPort(\ARST)) goto reject_ffCD; + if (ffA->hasPort(\ARST)) { + if (port(ffA, \ARST) != port(dff, \ARST)) + goto reject_ffCD; + if (param(ffA, \ARST_POLARITY) != param(dff, \ARST_POLARITY)) + goto reject_ffCD; + } } - if (ffBrstmux) { - if (port(ffBrstmux, \S) != port(dffrstmux, \S)) - goto reject_ffCD; - if (ffBrstpol != dffrstpol) + if (ffB) { + if (ffB->hasPort(\ARST) != dff->hasPort(\ARST)) goto reject_ffCD; + if (ffB->hasPort(\ARST)) { + if (port(ffB, \ARST) != port(dff, \ARST)) + goto reject_ffCD; + if (param(ffB, \ARST_POLARITY) != param(dff, \ARST_POLARITY)) + goto reject_ffCD; + } } ffCD = dff; @@ -347,7 +332,7 @@ code endcode match ff - select ff->type.in($dff) + select ff->type.in($dff, $dffe) // DSP48E1 does not support clock inversion select param(ff, \CLK_POLARITY).as_bool() @@ -357,8 +342,6 @@ match ff // Check that the rest of argQ is present filter GetSize(port(ff, \Q)) >= offset + GetSize(argQ) filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ - - set ffoffset offset endmatch code argQ argD @@ -378,72 +361,13 @@ code argQ argD argD = port(ff, \D); argQ = Q; dffD.replace(argQ, argD); - // Only search for ffrstmux if dffD only - // has two (ff, ffrstmux) users - if (nusers(dffD) > 2) - argD = SigSpec(); } endcode -match ffrstmux - if false /* TODO: ice40 resets are actually async */ - - if !argD.empty() - select ffrstmux->type.in($mux) - index <SigSpec> port(ffrstmux, \Y) === argD - - choice <IdString> BA {\B, \A} - // DSP48E1 only supports reset to zero - select port(ffrstmux, BA).is_fully_zero() - - define <bool> pol (BA == \B) - set ffrstpol pol - semioptional -endmatch - -code argD - if (ffrstmux) { - dffrstmux = ffrstmux; - dffrstpol = ffrstpol; - argD = port(ffrstmux, ffrstpol ? \A : \B); - dffD.replace(port(ffrstmux, \Y), argD); - - // Only search for ffholdmux if argQ has at - // least 3 users (ff, <upstream>, ffrstmux) and - // dffD only has two (ff, ffrstmux) - if (!(nusers(argQ) >= 3 && nusers(dffD) == 2)) - argD = SigSpec(); - } - else - dffrstmux = nullptr; -endcode - -match ffholdmux - if !argD.empty() - select ffholdmux->type.in($mux) - index <SigSpec> port(ffholdmux, \Y) === argD - choice <IdString> BA {\B, \A} - index <SigSpec> port(ffholdmux, BA) === argQ - define <bool> pol (BA == \B) - set ffholdpol pol - semioptional -endmatch - -code argD - if (ffholdmux) { - dffholdmux = ffholdmux; - dffholdpol = ffholdpol; - argD = port(ffholdmux, ffholdpol ? \A : \B); - dffD.replace(port(ffholdmux, \Y), argD); - } - else - dffholdmux = nullptr; -endcode - // ####################### subpattern out_dffe -arg argD argQ clock clock_pol +arg argD argSdff argQ clock clock_pol code dff = nullptr; @@ -452,101 +376,19 @@ code reject; endcode -match ffholdmux - select ffholdmux->type.in($mux) - // ffholdmux output must have two users: ffholdmux and ff.D - select nusers(port(ffholdmux, \Y)) == 2 - - choice <IdString> BA {\B, \A} - // keep-last-value net must have at least three users: ffholdmux, ff, downstream sink(s) - select nusers(port(ffholdmux, BA)) >= 3 - - slice offset GetSize(port(ffholdmux, \Y)) - define <IdString> AB (BA == \B ? \A : \B) - index <SigBit> port(ffholdmux, AB)[offset] === argD[0] - - // Check that the rest of argD is present - filter GetSize(port(ffholdmux, AB)) >= offset + GetSize(argD) - filter port(ffholdmux, AB).extract(offset, GetSize(argD)) == argD - - set ffoffset offset - define <bool> pol (BA == \B) - set ffholdpol pol - - semioptional -endmatch - -code argD argQ - dffholdmux = ffholdmux; - if (ffholdmux) { - SigSpec AB = port(ffholdmux, ffholdpol ? \A : \B); - SigSpec Y = port(ffholdmux, \Y); - argQ = argD; - argD.replace(AB, Y); - argQ.replace(AB, port(ffholdmux, ffholdpol ? \B : \A)); - - dffholdmux = ffholdmux; - dffholdpol = ffholdpol; - } -endcode - -match ffrstmux - if false /* TODO: ice40 resets are actually async */ - - select ffrstmux->type.in($mux) - // ffrstmux output must have two users: ffrstmux and ff.D - select nusers(port(ffrstmux, \Y)) == 2 - - choice <IdString> BA {\B, \A} - // DSP48E1 only supports reset to zero - select port(ffrstmux, BA).is_fully_zero() - - slice offset GetSize(port(ffrstmux, \Y)) - define <IdString> AB (BA == \B ? \A : \B) - index <SigBit> port(ffrstmux, AB)[offset] === argD[0] - - // Check that offset is consistent - filter !ffholdmux || ffoffset == offset - // Check that the rest of argD is present - filter GetSize(port(ffrstmux, AB)) >= offset + GetSize(argD) - filter port(ffrstmux, AB).extract(offset, GetSize(argD)) == argD - - set ffoffset offset - define <bool> pol (AB == \A) - set ffrstpol pol - - semioptional -endmatch - -code argD argQ - dffrstmux = ffrstmux; - if (ffrstmux) { - SigSpec AB = port(ffrstmux, ffrstpol ? \A : \B); - SigSpec Y = port(ffrstmux, \Y); - argD.replace(AB, Y); - - dffrstmux = ffrstmux; - dffrstpol = ffrstpol; - } -endcode - match ff - select ff->type.in($dff) + select ff->type.in($dff, $dffe, $sdff, $sdffce) // SB_MAC16 does not support clock inversion select param(ff, \CLK_POLARITY).as_bool() slice offset GetSize(port(ff, \D)) index <SigBit> port(ff, \D)[offset] === argD[0] - // Check that offset is consistent - filter (!ffholdmux && !ffrstmux) || ffoffset == offset + // Only allow sync reset if requested. + filter argSdff || ff->type.in($dff, $dffe) // Check that the rest of argD is present filter GetSize(port(ff, \D)) >= offset + GetSize(argD) filter port(ff, \D).extract(offset, GetSize(argD)) == argD - // Check that FF.Q is connected to CE-mux - filter !ffholdmux || port(ff, \Q).extract(offset, GetSize(argQ)) == argQ - - set ffoffset offset endmatch code argQ @@ -559,10 +401,8 @@ code argQ } SigSpec D = port(ff, \D); SigSpec Q = port(ff, \Q); - if (!ffholdmux) { - argQ = argD; - argQ.replace(D, Q); - } + argQ = argD; + argQ.replace(D, Q); for (auto c : argQ.chunks()) { Const init = c.wire->attributes.at(\init, State::Sx); @@ -575,7 +415,4 @@ code argQ dffclock = port(ff, \CLK); dffclock_pol = param(ff, \CLK_POLARITY).as_bool(); } - // No enable/reset mux possible without flop - else if (dffholdmux || dffrstmux) - reject; endcode diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc index 97d2008c2..e234906ad 100644 --- a/passes/pmgen/ice40_wrapcarry.cc +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -72,7 +72,7 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm) struct Ice40WrapCarryPass : public Pass { Ice40WrapCarryPass() : Pass("ice40_wrapcarry", "iCE40: wrap carries") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -91,7 +91,7 @@ struct Ice40WrapCarryPass : public Pass { log(" including restoring their attributes.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool unwrap = false; diff --git a/passes/pmgen/peepopt.cc b/passes/pmgen/peepopt.cc index 4379ce1e6..a9c62fcf6 100644 --- a/passes/pmgen/peepopt.cc +++ b/passes/pmgen/peepopt.cc @@ -32,7 +32,7 @@ pool<SigBit> rminitbits; struct PeepoptPass : public Pass { PeepoptPass() : Pass("peepopt", "collection of peephole optimizers") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -41,7 +41,7 @@ struct PeepoptPass : public Pass { log("This pass applies a collection of peephole optimizers to the current design.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string genmode; @@ -67,8 +67,6 @@ struct PeepoptPass : public Pass { GENERATE_PATTERN(peepopt_pm, shiftmul); else if (genmode == "muldiv") GENERATE_PATTERN(peepopt_pm, muldiv); - else if (genmode == "dffmux") - GENERATE_PATTERN(peepopt_pm, dffmux); else log_abort(); return; @@ -106,7 +104,6 @@ struct PeepoptPass : public Pass { pm.run_shiftmul(); pm.run_muldiv(); - pm.run_dffmux(); for (auto w : module->wires()) { auto it = w->attributes.find(ID::init); diff --git a/passes/pmgen/peepopt_dffmux.pmg b/passes/pmgen/peepopt_dffmux.pmg deleted file mode 100644 index 0069b0570..000000000 --- a/passes/pmgen/peepopt_dffmux.pmg +++ /dev/null @@ -1,171 +0,0 @@ -pattern dffmux - -state <IdString> cemuxAB rstmuxBA -state <SigSpec> sigD - -match dff - select dff->type == $dff - select GetSize(port(dff, \D)) > 1 -endmatch - -code sigD - sigD = port(dff, \D); -endcode - -match rstmux - select rstmux->type == $mux - select GetSize(port(rstmux, \Y)) > 1 - index <SigSpec> port(rstmux, \Y) === sigD - choice <IdString> BA {\B, \A} - select port(rstmux, BA).is_fully_const() - set rstmuxBA BA - semioptional -endmatch - -code sigD - if (rstmux) - sigD = port(rstmux, rstmuxBA == \B ? \A : \B); -endcode - -match cemux - select cemux->type == $mux - select GetSize(port(cemux, \Y)) > 1 - index <SigSpec> port(cemux, \Y) === sigD - choice <IdString> AB {\A, \B} - index <SigSpec> port(cemux, AB) === port(dff, \Q) - set cemuxAB AB - semioptional -endmatch - -code - if (!cemux && !rstmux) - reject; -endcode - -code - Const rst; - SigSpec D; - if (cemux) { - D = port(cemux, cemuxAB == \A ? \B : \A); - if (rstmux) - rst = port(rstmux, rstmuxBA).as_const(); - else - rst = Const(State::Sx, GetSize(D)); - } - else { - log_assert(rstmux); - D = port(rstmux, rstmuxBA == \B ? \A : \B); - rst = port(rstmux, rstmuxBA).as_const(); - } - SigSpec Q = port(dff, \Q); - int width = GetSize(D); - - SigSpec dffD = dff->getPort(\D); - SigSpec dffQ = dff->getPort(\Q); - - Const initval; - for (auto b : Q) { - auto it = initbits.find(b); - initval.bits.push_back(it == initbits.end() ? State::Sx : it->second); - } - - auto cmpx = [=](State lhs, State rhs) { - if (lhs == State::Sx || rhs == State::Sx) - return true; - return lhs == rhs; - }; - - int i = width-1; - while (i > 1) { - if (D[i] != D[i-1]) - break; - if (!cmpx(rst[i], rst[i-1])) - break; - if (!cmpx(initval[i], initval[i-1])) - break; - if (!cmpx(rst[i], initval[i])) - break; - rminitbits.insert(Q[i]); - module->connect(Q[i], Q[i-1]); - i--; - } - if (i < width-1) { - did_something = true; - if (cemux) { - SigSpec ceA = cemux->getPort(\A); - SigSpec ceB = cemux->getPort(\B); - SigSpec ceY = cemux->getPort(\Y); - ceA.remove(i, width-1-i); - ceB.remove(i, width-1-i); - ceY.remove(i, width-1-i); - cemux->setPort(\A, ceA); - cemux->setPort(\B, ceB); - cemux->setPort(\Y, ceY); - cemux->fixup_parameters(); - blacklist(cemux); - } - if (rstmux) { - SigSpec rstA = rstmux->getPort(\A); - SigSpec rstB = rstmux->getPort(\B); - SigSpec rstY = rstmux->getPort(\Y); - rstA.remove(i, width-1-i); - rstB.remove(i, width-1-i); - rstY.remove(i, width-1-i); - rstmux->setPort(\A, rstA); - rstmux->setPort(\B, rstB); - rstmux->setPort(\Y, rstY); - rstmux->fixup_parameters(); - blacklist(rstmux); - } - dffD.remove(i, width-1-i); - dffQ.remove(i, width-1-i); - dff->setPort(\D, dffD); - dff->setPort(\Q, dffQ); - dff->fixup_parameters(); - blacklist(dff); - - log("dffcemux pattern in %s: dff=%s, cemux=%s, rstmux=%s; removed top %d bits.\n", log_id(module), log_id(dff), log_id(cemux, "n/a"), log_id(rstmux, "n/a"), width-1-i); - width = i+1; - } - if (cemux) { - SigSpec ceA = cemux->getPort(\A); - SigSpec ceB = cemux->getPort(\B); - SigSpec ceY = cemux->getPort(\Y); - - int count = 0; - for (int i = width-1; i >= 0; i--) { - if (D[i].wire) - continue; - if (cmpx(rst[i], D[i].data) && cmpx(initval[i], D[i].data)) { - count++; - rminitbits.insert(Q[i]); - module->connect(Q[i], D[i]); - ceA.remove(i); - ceB.remove(i); - ceY.remove(i); - dffD.remove(i); - dffQ.remove(i); - } - } - if (count > 0) - { - did_something = true; - - cemux->setPort(\A, ceA); - cemux->setPort(\B, ceB); - cemux->setPort(\Y, ceY); - cemux->fixup_parameters(); - blacklist(cemux); - - dff->setPort(\D, dffD); - dff->setPort(\Q, dffQ); - dff->fixup_parameters(); - blacklist(dff); - - log("dffcemux pattern in %s: dff=%s, cemux=%s, rstmux=%s; removed %d constant bits.\n", log_id(module), log_id(dff), log_id(cemux), log_id(rstmux, "n/a"), count); - } - } - - if (did_something) - accept; -endcode diff --git a/passes/pmgen/peepopt_muldiv.pmg b/passes/pmgen/peepopt_muldiv.pmg index 7cad759d0..a4e232342 100644 --- a/passes/pmgen/peepopt_muldiv.pmg +++ b/passes/pmgen/peepopt_muldiv.pmg @@ -1,16 +1,18 @@ pattern muldiv state <SigSpec> t x y +state <bool> is_signed match mul select mul->type == $mul select GetSize(port(mul, \A)) + GetSize(port(mul, \B)) <= GetSize(port(mul, \Y)) endmatch -code t x y +code t x y is_signed t = port(mul, \Y); x = port(mul, \A); y = port(mul, \B); + is_signed = param(mul, \A_SIGNED).as_bool(); branch; std::swap(x, y); endcode @@ -19,6 +21,7 @@ match div select div->type.in($div) index <SigSpec> port(div, \A) === t index <SigSpec> port(div, \B) === x + filter param(div, \A_SIGNED).as_bool() == is_signed endmatch code diff --git a/passes/pmgen/peepopt_shiftmul.pmg b/passes/pmgen/peepopt_shiftmul.pmg index d4748ae19..d71fbf744 100644 --- a/passes/pmgen/peepopt_shiftmul.pmg +++ b/passes/pmgen/peepopt_shiftmul.pmg @@ -31,22 +31,18 @@ match mul select mul->type.in($mul) select port(mul, \A).is_fully_const() || port(mul, \B).is_fully_const() index <SigSpec> port(mul, \Y) === shamt + filter !param(mul, \A_SIGNED).as_bool() endmatch code { IdString const_factor_port = port(mul, \A).is_fully_const() ? \A : \B; - IdString const_factor_signed = const_factor_port == \A ? \A_SIGNED : \B_SIGNED; Const const_factor_cnst = port(mul, const_factor_port).as_const(); int const_factor = const_factor_cnst.as_int(); if (GetSize(const_factor_cnst) == 0) reject; - if (const_factor_cnst.bits[GetSize(const_factor_cnst)-1] != State::S0 && - param(mul, const_factor_signed).as_bool()) - reject; - if (GetSize(const_factor_cnst) > 20) reject; diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index df0ffaff2..592a26fa6 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -589,7 +589,7 @@ with open(outfile, "w") as f: if block["type"] in ("match", "code"): print(" // {}".format(block["src"]), file=f) - print(" void block_{}(int recursion YS_ATTRIBUTE(unused)) {{".format(index), file=f) + print(" void block_{}(int recursion YS_MAYBE_UNUSED) {{".format(index), file=f) current_pattern, current_subpattern = block["pattern"] if block["type"] == "final": @@ -636,17 +636,17 @@ with open(outfile, "w") as f: for s in sorted(const_st): t = state_types[current_pattern][s] if t.endswith("*"): - print(" {} const &{} YS_ATTRIBUTE(unused) = st_{}.{};".format(t, s, current_pattern, s), file=f) + print(" {} const &{} YS_MAYBE_UNUSED = st_{}.{};".format(t, s, current_pattern, s), file=f) else: - print(" const {} &{} YS_ATTRIBUTE(unused) = st_{}.{};".format(t, s, current_pattern, s), file=f) + print(" const {} &{} YS_MAYBE_UNUSED = st_{}.{};".format(t, s, current_pattern, s), file=f) for s in sorted(nonconst_st): t = state_types[current_pattern][s] - print(" {} &{} YS_ATTRIBUTE(unused) = st_{}.{};".format(t, s, current_pattern, s), file=f) + print(" {} &{} YS_MAYBE_UNUSED = st_{}.{};".format(t, s, current_pattern, s), file=f) for u in sorted(udata_types[current_pattern].keys()): t = udata_types[current_pattern][u] - print(" {} &{} YS_ATTRIBUTE(unused) = ud_{}.{};".format(t, u, current_pattern, u), file=f) + print(" {} &{} YS_MAYBE_UNUSED = ud_{}.{};".format(t, u, current_pattern, u), file=f) if len(restore_st): print("", file=f) @@ -676,7 +676,7 @@ with open(outfile, "w") as f: print("", file=f) print("rollback_label:", file=f) - print(" YS_ATTRIBUTE(unused);", file=f) + print(" YS_MAYBE_UNUSED;", file=f) if len(block["fcode"]): print("#define accept do { accept_cnt++; on_accept(); } while(0)", file=f) @@ -684,7 +684,7 @@ with open(outfile, "w") as f: for line in block["fcode"]: print(" " + line, file=f) print("finish_label:", file=f) - print(" YS_ATTRIBUTE(unused);", file=f) + print(" YS_MAYBE_UNUSED;", file=f) print("#undef accept", file=f) print("#undef finish", file=f) @@ -733,13 +733,13 @@ with open(outfile, "w") as f: valueidx = 1 for item in block["setup"]: if item[0] == "slice": - print(" const int &{} YS_ATTRIBUTE(unused) = std::get<{}>(cells[_pmg_idx]);".format(item[1], valueidx), file=f) + print(" const int &{} YS_MAYBE_UNUSED = std::get<{}>(cells[_pmg_idx]);".format(item[1], valueidx), file=f) valueidx += 1 if item[0] == "choice": - print(" const {} &{} YS_ATTRIBUTE(unused) = std::get<{}>(cells[_pmg_idx]);".format(item[1], item[2], valueidx), file=f) + print(" const {} &{} YS_MAYBE_UNUSED = std::get<{}>(cells[_pmg_idx]);".format(item[1], item[2], valueidx), file=f) valueidx += 1 if item[0] == "define": - print(" const {} &{} YS_ATTRIBUTE(unused) = std::get<{}>(cells[_pmg_idx]);".format(item[1], item[2], valueidx), file=f) + print(" const {} &{} YS_MAYBE_UNUSED = std::get<{}>(cells[_pmg_idx]);".format(item[1], item[2], valueidx), file=f) valueidx += 1 print(" if (blacklist_cells.count({})) continue;".format(block["cell"]), file=f) for expr in block["filter"]: diff --git a/passes/pmgen/test_pmgen.cc b/passes/pmgen/test_pmgen.cc index 9cfad03ef..7b2938ddf 100644 --- a/passes/pmgen/test_pmgen.cc +++ b/passes/pmgen/test_pmgen.cc @@ -118,7 +118,7 @@ void opt_eqpmux(test_pmgen_pm &pm) struct TestPmgenPass : public Pass { TestPmgenPass() : Pass("test_pmgen", "test pass for pmgen") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -239,7 +239,7 @@ struct TestPmgenPass : public Pass { log_cmd_error("Unknown pattern: %s\n", pattern.c_str()); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { if (GetSize(args) > 1) { diff --git a/passes/pmgen/xilinx_dsp.cc b/passes/pmgen/xilinx_dsp.cc index f1f4b4206..cf7703d36 100644 --- a/passes/pmgen/xilinx_dsp.cc +++ b/passes/pmgen/xilinx_dsp.cc @@ -263,17 +263,17 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) log("Analysing %s.%s for Xilinx DSP packing.\n", log_id(pm.module), log_id(st.dsp)); log_debug("preAdd: %s\n", log_id(st.preAdd, "--")); - log_debug("ffAD: %s %s %s\n", log_id(st.ffAD, "--"), log_id(st.ffADcemux, "--"), log_id(st.ffADrstmux, "--")); - log_debug("ffA2: %s %s %s\n", log_id(st.ffA2, "--"), log_id(st.ffA2cemux, "--"), log_id(st.ffA2rstmux, "--")); - log_debug("ffA1: %s %s %s\n", log_id(st.ffA1, "--"), log_id(st.ffA1cemux, "--"), log_id(st.ffA1rstmux, "--")); - log_debug("ffB2: %s %s %s\n", log_id(st.ffB2, "--"), log_id(st.ffB2cemux, "--"), log_id(st.ffB2rstmux, "--")); - log_debug("ffB1: %s %s %s\n", log_id(st.ffB1, "--"), log_id(st.ffB1cemux, "--"), log_id(st.ffB1rstmux, "--")); - log_debug("ffD: %s %s %s\n", log_id(st.ffD, "--"), log_id(st.ffDcemux, "--"), log_id(st.ffDrstmux, "--")); + log_debug("ffAD: %s\n", log_id(st.ffAD, "--")); + log_debug("ffA2: %s\n", log_id(st.ffA2, "--")); + log_debug("ffA1: %s\n", log_id(st.ffA1, "--")); + log_debug("ffB2: %s\n", log_id(st.ffB2, "--")); + log_debug("ffB1: %s\n", log_id(st.ffB1, "--")); + log_debug("ffD: %s\n", log_id(st.ffD, "--")); log_debug("dsp: %s\n", log_id(st.dsp, "--")); - log_debug("ffM: %s %s %s\n", log_id(st.ffM, "--"), log_id(st.ffMcemux, "--"), log_id(st.ffMrstmux, "--")); + log_debug("ffM: %s\n", log_id(st.ffM, "--")); log_debug("postAdd: %s\n", log_id(st.postAdd, "--")); log_debug("postAddMux: %s\n", log_id(st.postAddMux, "--")); - log_debug("ffP: %s %s %s\n", log_id(st.ffP, "--"), log_id(st.ffPcemux, "--"), log_id(st.ffPrstmux, "--")); + log_debug("ffP: %s\n", log_id(st.ffP, "--")); log_debug("overflow: %s\n", log_id(st.overflow, "--")); Cell *cell = st.dsp; @@ -291,9 +291,10 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) cell->setPort(ID(INMODE), Const::from_string("00100")); if (st.ffAD) { - if (st.ffADcemux) { - SigSpec S = st.ffADcemux->getPort(ID::S); - cell->setPort(ID(CEAD), st.ffADcepol ? S : pm.module->Not(NEW_ID, S)); + if (st.ffAD->type.in(ID($dffe), ID($sdffe))) { + bool pol = st.ffAD->getParam(ID::EN_POLARITY).as_bool(); + SigSpec S = st.ffAD->getPort(ID::EN); + cell->setPort(ID(CEAD), pol ? S : pm.module->Not(NEW_ID, S)); } else cell->setPort(ID(CEAD), State::S1); @@ -363,30 +364,24 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) { cell->setPort(ID::CLK, st.clock); - auto f = [&pm,cell](SigSpec &A, Cell* ff, Cell* cemux, bool cepol, IdString ceport, Cell* rstmux, bool rstpol, IdString rstport) { + auto f = [&pm,cell](SigSpec &A, Cell* ff, IdString ceport, IdString rstport) { SigSpec D = ff->getPort(ID::D); SigSpec Q = pm.sigmap(ff->getPort(ID::Q)); if (!A.empty()) A.replace(Q, D); - if (rstmux) { - SigSpec Y = rstmux->getPort(ID::Y); - SigSpec AB = rstmux->getPort(rstpol ? ID::A : ID::B); - if (!A.empty()) - A.replace(Y, AB); - if (rstport != IdString()) { - SigSpec S = rstmux->getPort(ID::S); - cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S)); + if (rstport != IdString()) { + if (ff->type.in(ID($sdff), ID($sdffe))) { + SigSpec srst = ff->getPort(ID::SRST); + bool rstpol = ff->getParam(ID::SRST_POLARITY).as_bool(); + cell->setPort(rstport, rstpol ? srst : pm.module->Not(NEW_ID, srst)); + } else { + cell->setPort(rstport, State::S0); } } - else if (rstport != IdString()) - cell->setPort(rstport, State::S0); - if (cemux) { - SigSpec Y = cemux->getPort(ID::Y); - SigSpec BA = cemux->getPort(cepol ? ID::B : ID::A); - SigSpec S = cemux->getPort(ID::S); - if (!A.empty()) - A.replace(Y, BA); - cell->setPort(ceport, cepol ? S : pm.module->Not(NEW_ID, S)); + if (ff->type.in(ID($dffe), ID($sdffe))) { + SigSpec ce = ff->getPort(ID::EN); + bool cepol = ff->getParam(ID::EN_POLARITY).as_bool(); + cell->setPort(ceport, cepol ? ce : pm.module->Not(NEW_ID, ce)); } else cell->setPort(ceport, State::S1); @@ -404,9 +399,9 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) if (st.ffA2) { SigSpec A = cell->getPort(ID::A); - f(A, st.ffA2, st.ffA2cemux, st.ffA2cepol, ID(CEA2), st.ffA2rstmux, st.ffArstpol, ID(RSTA)); + f(A, st.ffA2, ID(CEA2), ID(RSTA)); if (st.ffA1) { - f(A, st.ffA1, st.ffA1cemux, st.ffA1cepol, ID(CEA1), st.ffA1rstmux, st.ffArstpol, IdString()); + f(A, st.ffA1, ID(CEA1), IdString()); cell->setParam(ID(AREG), 2); cell->setParam(ID(ACASCREG), 2); } @@ -419,9 +414,9 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) } if (st.ffB2) { SigSpec B = cell->getPort(ID::B); - f(B, st.ffB2, st.ffB2cemux, st.ffB2cepol, ID(CEB2), st.ffB2rstmux, st.ffBrstpol, ID(RSTB)); + f(B, st.ffB2, ID(CEB2), ID(RSTB)); if (st.ffB1) { - f(B, st.ffB1, st.ffB1cemux, st.ffB1cepol, ID(CEB1), st.ffB1rstmux, st.ffBrstpol, IdString()); + f(B, st.ffB1, ID(CEB1), IdString()); cell->setParam(ID(BREG), 2); cell->setParam(ID(BCASCREG), 2); } @@ -434,20 +429,20 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm) } if (st.ffD) { SigSpec D = cell->getPort(ID::D); - f(D, st.ffD, st.ffDcemux, st.ffDcepol, ID(CED), st.ffDrstmux, st.ffDrstpol, ID(RSTD)); + f(D, st.ffD, ID(CED), ID(RSTD)); pm.add_siguser(D, cell); cell->setPort(ID::D, D); cell->setParam(ID(DREG), 1); } if (st.ffM) { SigSpec M; // unused - f(M, st.ffM, st.ffMcemux, st.ffMcepol, ID(CEM), st.ffMrstmux, st.ffMrstpol, ID(RSTM)); + f(M, st.ffM, ID(CEM), ID(RSTM)); st.ffM->connections_.at(ID::Q).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM))); cell->setParam(ID(MREG), State::S1); } if (st.ffP) { SigSpec P; // unused - f(P, st.ffP, st.ffPcemux, st.ffPcepol, ID(CEP), st.ffPrstmux, st.ffPrstpol, ID(RSTP)); + f(P, st.ffP, ID(CEP), ID(RSTP)); st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP))); cell->setParam(ID(PREG), State::S1); } @@ -495,16 +490,16 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) log("Analysing %s.%s for Xilinx DSP48A/DSP48A1 packing.\n", log_id(pm.module), log_id(st.dsp)); log_debug("preAdd: %s\n", log_id(st.preAdd, "--")); - log_debug("ffA1: %s %s %s\n", log_id(st.ffA1, "--"), log_id(st.ffA1cemux, "--"), log_id(st.ffA1rstmux, "--")); - log_debug("ffA0: %s %s %s\n", log_id(st.ffA0, "--"), log_id(st.ffA0cemux, "--"), log_id(st.ffA0rstmux, "--")); - log_debug("ffB1: %s %s %s\n", log_id(st.ffB1, "--"), log_id(st.ffB1cemux, "--"), log_id(st.ffB1rstmux, "--")); - log_debug("ffB0: %s %s %s\n", log_id(st.ffB0, "--"), log_id(st.ffB0cemux, "--"), log_id(st.ffB0rstmux, "--")); - log_debug("ffD: %s %s %s\n", log_id(st.ffD, "--"), log_id(st.ffDcemux, "--"), log_id(st.ffDrstmux, "--")); + log_debug("ffA1: %s\n", log_id(st.ffA1, "--")); + log_debug("ffA0: %s\n", log_id(st.ffA0, "--")); + log_debug("ffB1: %s\n", log_id(st.ffB1, "--")); + log_debug("ffB0: %s\n", log_id(st.ffB0, "--")); + log_debug("ffD: %s\n", log_id(st.ffD, "--")); log_debug("dsp: %s\n", log_id(st.dsp, "--")); - log_debug("ffM: %s %s %s\n", log_id(st.ffM, "--"), log_id(st.ffMcemux, "--"), log_id(st.ffMrstmux, "--")); + log_debug("ffM: %s\n", log_id(st.ffM, "--")); log_debug("postAdd: %s\n", log_id(st.postAdd, "--")); log_debug("postAddMux: %s\n", log_id(st.postAddMux, "--")); - log_debug("ffP: %s %s %s\n", log_id(st.ffP, "--"), log_id(st.ffPcemux, "--"), log_id(st.ffPrstmux, "--")); + log_debug("ffP: %s\n", log_id(st.ffP, "--")); Cell *cell = st.dsp; SigSpec &opmode = cell->connections_.at(ID(OPMODE)); @@ -556,30 +551,24 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) { cell->setPort(ID::CLK, st.clock); - auto f = [&pm,cell](SigSpec &A, Cell* ff, Cell* cemux, bool cepol, IdString ceport, Cell* rstmux, bool rstpol, IdString rstport) { + auto f = [&pm,cell](SigSpec &A, Cell* ff, IdString ceport, IdString rstport) { SigSpec D = ff->getPort(ID::D); SigSpec Q = pm.sigmap(ff->getPort(ID::Q)); if (!A.empty()) A.replace(Q, D); - if (rstmux) { - SigSpec Y = rstmux->getPort(ID::Y); - SigSpec AB = rstmux->getPort(rstpol ? ID::A : ID::B); - if (!A.empty()) - A.replace(Y, AB); - if (rstport != IdString()) { - SigSpec S = rstmux->getPort(ID::S); - cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S)); + if (rstport != IdString()) { + if (ff->type.in(ID($sdff), ID($sdffe))) { + SigSpec srst = ff->getPort(ID::SRST); + bool rstpol = ff->getParam(ID::SRST_POLARITY).as_bool(); + cell->setPort(rstport, rstpol ? srst : pm.module->Not(NEW_ID, srst)); + } else { + cell->setPort(rstport, State::S0); } } - else if (rstport != IdString()) - cell->setPort(rstport, State::S0); - if (cemux) { - SigSpec Y = cemux->getPort(ID::Y); - SigSpec BA = cemux->getPort(cepol ? ID::B : ID::A); - SigSpec S = cemux->getPort(ID::S); - if (!A.empty()) - A.replace(Y, BA); - cell->setPort(ceport, cepol ? S : pm.module->Not(NEW_ID, S)); + if (ff->type.in(ID($dffe), ID($sdffe))) { + SigSpec ce = ff->getPort(ID::EN); + bool cepol = ff->getParam(ID::EN_POLARITY).as_bool(); + cell->setPort(ceport, cepol ? ce : pm.module->Not(NEW_ID, ce)); } else cell->setPort(ceport, State::S1); @@ -598,11 +587,11 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) if (st.ffA0 || st.ffA1) { SigSpec A = cell->getPort(ID::A); if (st.ffA1) { - f(A, st.ffA1, st.ffA1cemux, st.ffAcepol, ID(CEA), st.ffA1rstmux, st.ffArstpol, ID(RSTA)); + f(A, st.ffA1, ID(CEA), ID(RSTA)); cell->setParam(ID(A1REG), 1); } if (st.ffA0) { - f(A, st.ffA0, st.ffA0cemux, st.ffAcepol, ID(CEA), st.ffA0rstmux, st.ffArstpol, ID(RSTA)); + f(A, st.ffA0, ID(CEA), ID(RSTA)); cell->setParam(ID(A0REG), 1); } pm.add_siguser(A, cell); @@ -611,11 +600,11 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) if (st.ffB0 || st.ffB1) { SigSpec B = cell->getPort(ID::B); if (st.ffB1) { - f(B, st.ffB1, st.ffB1cemux, st.ffBcepol, ID(CEB), st.ffB1rstmux, st.ffBrstpol, ID(RSTB)); + f(B, st.ffB1, ID(CEB), ID(RSTB)); cell->setParam(ID(B1REG), 1); } if (st.ffB0) { - f(B, st.ffB0, st.ffB0cemux, st.ffBcepol, ID(CEB), st.ffB0rstmux, st.ffBrstpol, ID(RSTB)); + f(B, st.ffB0, ID(CEB), ID(RSTB)); cell->setParam(ID(B0REG), 1); } pm.add_siguser(B, cell); @@ -623,20 +612,20 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm) } if (st.ffD) { SigSpec D = cell->getPort(ID::D); - f(D, st.ffD, st.ffDcemux, st.ffDcepol, ID(CED), st.ffDrstmux, st.ffDrstpol, ID(RSTD)); + f(D, st.ffD, ID(CED), ID(RSTD)); pm.add_siguser(D, cell); cell->setPort(ID::D, D); cell->setParam(ID(DREG), 1); } if (st.ffM) { SigSpec M; // unused - f(M, st.ffM, st.ffMcemux, st.ffMcepol, ID(CEM), st.ffMrstmux, st.ffMrstpol, ID(RSTM)); + f(M, st.ffM, ID(CEM), ID(RSTM)); st.ffM->connections_.at(ID::Q).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM))); cell->setParam(ID(MREG), State::S1); } if (st.ffP) { SigSpec P; // unused - f(P, st.ffP, st.ffPcemux, st.ffPcepol, ID(CEP), st.ffPrstmux, st.ffPrstpol, ID(RSTP)); + f(P, st.ffP, ID(CEP), ID(RSTP)); st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP))); cell->setParam(ID(PREG), State::S1); } @@ -677,7 +666,7 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm) auto &st = pm.st_xilinx_dsp_packC; log_debug("Analysing %s.%s for Xilinx DSP packing (CREG).\n", log_id(pm.module), log_id(st.dsp)); - log_debug("ffC: %s %s %s\n", log_id(st.ffC, "--"), log_id(st.ffCcemux, "--"), log_id(st.ffCrstmux, "--")); + log_debug("ffC: %s\n", log_id(st.ffC, "--")); Cell *cell = st.dsp; @@ -685,30 +674,24 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm) { cell->setPort(ID::CLK, st.clock); - auto f = [&pm,cell](SigSpec &A, Cell* ff, Cell* cemux, bool cepol, IdString ceport, Cell* rstmux, bool rstpol, IdString rstport) { + auto f = [&pm,cell](SigSpec &A, Cell* ff, IdString ceport, IdString rstport) { SigSpec D = ff->getPort(ID::D); SigSpec Q = pm.sigmap(ff->getPort(ID::Q)); if (!A.empty()) A.replace(Q, D); - if (rstmux) { - SigSpec Y = rstmux->getPort(ID::Y); - SigSpec AB = rstmux->getPort(rstpol ? ID::A : ID::B); - if (!A.empty()) - A.replace(Y, AB); - if (rstport != IdString()) { - SigSpec S = rstmux->getPort(ID::S); - cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S)); + if (rstport != IdString()) { + if (ff->type.in(ID($sdff), ID($sdffe))) { + SigSpec srst = ff->getPort(ID::SRST); + bool rstpol = ff->getParam(ID::SRST_POLARITY).as_bool(); + cell->setPort(rstport, rstpol ? srst : pm.module->Not(NEW_ID, srst)); + } else { + cell->setPort(rstport, State::S0); } } - else if (rstport != IdString()) - cell->setPort(rstport, State::S0); - if (cemux) { - SigSpec Y = cemux->getPort(ID::Y); - SigSpec BA = cemux->getPort(cepol ? ID::B : ID::A); - SigSpec S = cemux->getPort(ID::S); - if (!A.empty()) - A.replace(Y, BA); - cell->setPort(ceport, cepol ? S : pm.module->Not(NEW_ID, S)); + if (ff->type.in(ID($dffe), ID($sdffe))) { + SigSpec ce = ff->getPort(ID::EN); + bool cepol = ff->getParam(ID::EN_POLARITY).as_bool(); + cell->setPort(ceport, cepol ? ce : pm.module->Not(NEW_ID, ce)); } else cell->setPort(ceport, State::S1); @@ -726,7 +709,7 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm) if (st.ffC) { SigSpec C = cell->getPort(ID::C); - f(C, st.ffC, st.ffCcemux, st.ffCcepol, ID(CEC), st.ffCrstmux, st.ffCrstpol, ID(RSTC)); + f(C, st.ffC, ID(CEC), ID(RSTC)); pm.add_siguser(C, cell); cell->setPort(ID::C, C); cell->setParam(ID(CREG), 1); @@ -744,7 +727,7 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm) struct XilinxDspPass : public Pass { XilinxDspPass() : Pass("xilinx_dsp", "Xilinx: pack resources into DSPs") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -785,7 +768,7 @@ struct XilinxDspPass : public Pass { log(" default: xc7\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing XILINX_DSP pass (pack resources into DSPs).\n"); diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg index d40f073c9..0cd23c09d 100644 --- a/passes/pmgen/xilinx_dsp.pmg +++ b/passes/pmgen/xilinx_dsp.pmg @@ -2,9 +2,7 @@ // forms the `xilinx_dsp` pass described in xilinx_dsp.cc // At a high level, it works as follows: // ( 1) Starting from a DSP48E1 cell -// ( 2) Match the driver of the 'A' input to a possible $dff cell (ADREG) -// (attached to at most two $mux cells that implement clock-enable or -// reset functionality, using a subpattern discussed below) +// ( 2) Match the driver of the 'A' input to a possible $sdffe cell (ADREG) // If ADREG matched, treat 'A' input as input of ADREG // ( 3) Match the driver of the 'A' and 'D' inputs for a possible $add cell // (pre-adder) @@ -44,7 +42,7 @@ // DSP48E1 cells inferred from multiply operations by Yosys, as well as for // user instantiations that may already contain the cells being packed... // (though the latter is currently untested) -// - Since the $dff-with-optional-clock-enable-or-reset-mux pattern is used +// - Since the $sdffe pattern is used // for each *REG match, it has been factored out into two subpatterns: // in_dffe and out_dffe located at the bottom of this file. // - Matching for pattern detector features is currently incomplete. For @@ -57,20 +55,15 @@ pattern xilinx_dsp_pack state <SigBit> clock state <SigSpec> sigA sigB sigC sigD sigM sigP state <IdString> postAddAB postAddMuxAB -state <bool> ffA1cepol ffA2cepol ffADcepol ffB1cepol ffB2cepol ffDcepol ffMcepol ffPcepol -state <bool> ffArstpol ffADrstpol ffBrstpol ffDrstpol ffMrstpol ffPrstpol -state <Cell*> ffAD ffADcemux ffADrstmux ffA1 ffA1cemux ffA1rstmux ffA2 ffA2cemux ffA2rstmux -state <Cell*> ffB1 ffB1cemux ffB1rstmux ffB2 ffB2cemux ffB2rstmux -state <Cell*> ffD ffDcemux ffDrstmux ffM ffMcemux ffMrstmux ffP ffPcemux ffPrstmux +state <Cell*> ffAD ffA1 ffA2 +state <Cell*> ffB1 ffB2 +state <Cell*> ffD ffM ffP // Variables used for subpatterns state <SigSpec> argQ argD -state <bool> ffcepol ffrstpol -state <int> ffoffset udata <SigSpec> dffD dffQ udata <SigBit> dffclock -udata <Cell*> dff dffcemux dffrstmux -udata <bool> dffcepol dffrstpol +udata <Cell*> dff // (1) Starting from a DSP48E1 cell match dsp @@ -115,25 +108,15 @@ code sigA sigB sigC sigD sigM clock clock = port(dsp, \CLK, SigBit()); endcode -// (2) Match the driver of the 'A' input to a possible $dff cell (ADREG) -// (attached to at most two $mux cells that implement clock-enable or -// reset functionality, using a subpattern discussed above) +// (2) Match the driver of the 'A' input to a possible $sdffe cell (ADREG) // If matched, treat 'A' input as input of ADREG -code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock +code argQ ffAD sigA clock if (param(dsp, \ADREG).as_int() == 0) { argQ = sigA; subpattern(in_dffe); if (dff) { ffAD = dff; clock = dffclock; - if (dffrstmux) { - ffADrstmux = dffrstmux; - ffADrstpol = dffrstpol; - } - if (dffcemux) { - ffADcemux = dffcemux; - ffADcepol = dffcepol; - } sigA = dffD; } } @@ -172,7 +155,7 @@ endcode // (4) If pre-adder was present, find match 'A' input for A2REG // If pre-adder was not present, move ADREG to A2REG // Then match 'A' input for A1REG -code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock ffA2 ffA2cemux ffA2rstmux ffA2cepol ffArstpol ffA1 ffA1cemux ffA1rstmux ffA1cepol +code argQ ffAD sigA clock ffA2 ffA1 // Only search for ffA2 if there was a pre-adder // (otherwise ffA2 would have been matched as ffAD) if (preAdd) { @@ -182,14 +165,6 @@ code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock ffA2 ffA2cem if (dff) { ffA2 = dff; clock = dffclock; - if (dffrstmux) { - ffA2rstmux = dffrstmux; - ffArstpol = dffrstpol; - } - if (dffcemux) { - ffA2cepol = dffcepol; - ffA2cemux = dffcemux; - } sigA = dffD; } } @@ -197,12 +172,8 @@ code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock ffA2 ffA2cem // And if there wasn't a pre-adder, // move AD register to A else if (ffAD) { - log_assert(!ffA2 && !ffA2cemux && !ffA2rstmux); + log_assert(!ffA2); std::swap(ffA2, ffAD); - std::swap(ffA2cemux, ffADcemux); - std::swap(ffA2rstmux, ffADrstmux); - ffA2cepol = ffADcepol; - ffArstpol = ffADrstpol; } // Now attempt to match A1 @@ -210,23 +181,23 @@ code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock ffA2 ffA2cem argQ = sigA; subpattern(in_dffe); if (dff) { - if ((ffA2rstmux != nullptr) ^ (dffrstmux != nullptr)) + if (dff->type != ffA2->type) goto ffA1_end; - if (dffrstmux) { - if (ffArstpol != dffrstpol) + if (dff->type.in($sdff, $sdffe, $sdffce)) { + if (param(dff, \SRST_POLARITY) != param(ffA2, \SRST_POLARITY)) goto ffA1_end; - if (port(ffA2rstmux, \S) != port(dffrstmux, \S)) + if (port(dff, \SRST) != port(ffA2, \SRST)) + goto ffA1_end; + } + if (dff->type.in($dffe, $sdffe, $sdffce)) { + if (param(dff, \EN_POLARITY) != param(ffA2, \EN_POLARITY)) + goto ffA1_end; + if (port(dff, \EN) != port(ffA2, \EN)) goto ffA1_end; - ffA1rstmux = dffrstmux; } ffA1 = dff; clock = dffclock; - - if (dffcemux) { - ffA1cemux = dffcemux; - ffA1cepol = dffcepol; - } sigA = dffD; ffA1_end: ; @@ -236,21 +207,13 @@ endcode // (5) Match 'B' input for B2REG // If B2REG, then match 'B' input for B1REG -code argQ ffB2 ffB2cemux ffB2rstmux ffB2cepol ffBrstpol sigB clock ffB1 ffB1cemux ffB1rstmux ffB1cepol +code argQ ffB2 sigB clock ffB1 if (param(dsp, \BREG).as_int() == 0) { argQ = sigB; subpattern(in_dffe); if (dff) { ffB2 = dff; clock = dffclock; - if (dffrstmux) { - ffB2rstmux = dffrstmux; - ffBrstpol = dffrstpol; - } - if (dffcemux) { - ffB2cemux = dffcemux; - ffB2cepol = dffcepol; - } sigB = dffD; // Now attempt to match B1 @@ -258,23 +221,23 @@ code argQ ffB2 ffB2cemux ffB2rstmux ffB2cepol ffBrstpol sigB clock ffB1 ffB1cemu argQ = sigB; subpattern(in_dffe); if (dff) { - if ((ffB2rstmux != nullptr) ^ (dffrstmux != nullptr)) + if (dff->type != ffB2->type) goto ffB1_end; - if (dffrstmux) { - if (ffBrstpol != dffrstpol) + if (dff->type.in($sdff, $sdffe, $sdffce)) { + if (param(dff, \SRST_POLARITY) != param(ffB2, \SRST_POLARITY)) + goto ffB1_end; + if (port(dff, \SRST) != port(ffB2, \SRST)) + goto ffB1_end; + } + if (dff->type.in($dffe, $sdffe, $sdffce)) { + if (param(dff, \EN_POLARITY) != param(ffB2, \EN_POLARITY)) goto ffB1_end; - if (port(ffB2rstmux, \S) != port(dffrstmux, \S)) + if (port(dff, \EN) != port(ffB2, \EN)) goto ffB1_end; - ffB1rstmux = dffrstmux; } ffB1 = dff; clock = dffclock; - - if (dffcemux) { - ffB1cemux = dffcemux; - ffB1cepol = dffcepol; - } sigB = dffD; ffB1_end: ; @@ -286,42 +249,26 @@ ffB1_end: ; endcode // (6) Match 'D' input for DREG -code argQ ffD ffDcemux ffDrstmux ffDcepol ffDrstpol sigD clock +code argQ ffD sigD clock if (param(dsp, \DREG).as_int() == 0) { argQ = sigD; subpattern(in_dffe); if (dff) { ffD = dff; clock = dffclock; - if (dffrstmux) { - ffDrstmux = dffrstmux; - ffDrstpol = dffrstpol; - } - if (dffcemux) { - ffDcemux = dffcemux; - ffDcepol = dffcepol; - } sigD = dffD; } } endcode // (7) Match 'P' output that exclusively drives an MREG -code argD ffM ffMcemux ffMrstmux ffMcepol ffMrstpol sigM sigP clock +code argD ffM sigM sigP clock if (param(dsp, \MREG).as_int() == 0 && nusers(sigM) == 2) { argD = sigM; subpattern(out_dffe); if (dff) { ffM = dff; clock = dffclock; - if (dffrstmux) { - ffMrstmux = dffrstmux; - ffMrstpol = dffrstpol; - } - if (dffcemux) { - ffMcemux = dffcemux; - ffMcepol = dffcepol; - } sigM = dffQ; } } @@ -340,9 +287,7 @@ match postAdd select postAdd->type.in($add) select GetSize(port(postAdd, \Y)) <= 48 choice <IdString> AB {\A, \B} - select nusers(port(postAdd, AB)) <= 3 - filter ffMcemux || nusers(port(postAdd, AB)) == 2 - filter !ffMcemux || nusers(port(postAdd, AB)) == 3 + select nusers(port(postAdd, AB)) == 2 index <SigBit> port(postAdd, AB)[0] === sigP[0] filter GetSize(port(postAdd, AB)) >= GetSize(sigP) @@ -362,25 +307,14 @@ code sigC sigP endcode // (9) Match 'P' output that exclusively drives a PREG -code argD ffP ffPcemux ffPrstmux ffPcepol ffPrstpol sigP clock +code argD ffP sigP clock if (param(dsp, \PREG).as_int() == 0) { - int users = 2; - // If ffMcemux and no postAdd new-value net must have three users: ffMcemux, ffM and ffPcemux - if (ffMcemux && !postAdd) users++; - if (nusers(sigP) == users) { + if (nusers(sigP) == 2) { argD = sigP; subpattern(out_dffe); if (dff) { ffP = dff; clock = dffclock; - if (dffrstmux) { - ffPrstmux = dffrstmux; - ffPrstpol = dffrstpol; - } - if (dffcemux) { - ffPcemux = dffcemux; - ffPcepol = dffcepol; - } sigP = dffQ; } } @@ -441,22 +375,9 @@ endcode // ####################### // Subpattern for matching against input registers, based on knowledge of the -// 'Q' input. Typically, identifying registers with clock-enable and reset -// capability would be a task would be handled by other Yosys passes such as -// dff2dffe, but since DSP inference happens much before this, these patterns -// have to be manually identified. -// At a high level: -// (1) Starting from a $dff cell that (partially or fully) drives the given -// 'Q' argument -// (2) Match for a $mux cell implementing synchronous reset semantics --- -// one that exclusively drives the 'D' input of the $dff, with one of its -// $mux inputs being fully zero -// (3) Match for a $mux cell implement clock enable semantics --- one that -// exclusively drives the 'D' input of the $dff (or the other input of -// the reset $mux) and where one of this $mux's inputs is connected to -// the 'Q' output of the $dff +// 'Q' input. subpattern in_dffe -arg argD argQ clock +arg argQ clock code dff = nullptr; @@ -479,13 +400,14 @@ code } endcode -// (1) Starting from a $dff cell that (partially or fully) drives the given -// 'Q' argument match ff - select ff->type.in($dff) + select ff->type.in($dff, $dffe, $sdff, $sdffe) // DSP48E1 does not support clock inversion select param(ff, \CLK_POLARITY).as_bool() + // Check that reset value, if present, is fully 0. + filter ff->type.in($dff, $dffe) || param(ff, \SRST_VALUE).is_fully_zero() + slice offset GetSize(port(ff, \D)) index <SigBit> port(ff, \Q)[offset] === argQ[0] @@ -494,82 +416,16 @@ match ff filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ filter clock == SigBit() || port(ff, \CLK) == clock - - set ffoffset offset endmatch -code argQ argD +code argQ SigSpec Q = port(ff, \Q); dff = ff; dffclock = port(ff, \CLK); dffD = argQ; - argD = port(ff, \D); + SigSpec D = port(ff, \D); argQ = Q; - dffD.replace(argQ, argD); - // Only search for ffrstmux if dffD only - // has two (ff, ffrstmux) users - if (nusers(dffD) > 2) - argD = SigSpec(); -endcode - -// (2) Match for a $mux cell implementing synchronous reset semantics --- -// exclusively drives the 'D' input of the $dff, with one of the $mux -// inputs being fully zero -match ffrstmux - if !argD.empty() - select ffrstmux->type.in($mux) - index <SigSpec> port(ffrstmux, \Y) === argD - - choice <IdString> BA {\B, \A} - // DSP48E1 only supports reset to zero - select port(ffrstmux, BA).is_fully_zero() - - define <bool> pol (BA == \B) - set ffrstpol pol - semioptional -endmatch - -code argD - if (ffrstmux) { - dffrstmux = ffrstmux; - dffrstpol = ffrstpol; - argD = port(ffrstmux, ffrstpol ? \A : \B); - dffD.replace(port(ffrstmux, \Y), argD); - - // Only search for ffcemux if argQ has at - // least 3 users (ff, <upstream>, ffrstmux) and - // dffD only has two (ff, ffrstmux) - if (!(nusers(argQ) >= 3 && nusers(dffD) == 2)) - argD = SigSpec(); - } - else - dffrstmux = nullptr; -endcode - -// (3) Match for a $mux cell implement clock enable semantics --- one that -// exclusively drives the 'D' input of the $dff (or the other input of -// the reset $mux) and where one of this $mux's inputs is connected to -// the 'Q' output of the $dff -match ffcemux - if !argD.empty() - select ffcemux->type.in($mux) - index <SigSpec> port(ffcemux, \Y) === argD - choice <IdString> AB {\A, \B} - index <SigSpec> port(ffcemux, AB) === argQ - define <bool> pol (AB == \A) - set ffcepol pol - semioptional -endmatch - -code argD - if (ffcemux) { - dffcemux = ffcemux; - dffcepol = ffcepol; - argD = port(ffcemux, ffcepol ? \B : \A); - dffD.replace(port(ffcemux, \Y), argD); - } - else - dffcemux = nullptr; + dffD.replace(argQ, D); endcode // ####################### @@ -597,119 +453,26 @@ code reject; endcode -// (1) Starting from an optional $mux cell that implements clock enable -// semantics --- one where the given 'D' argument (partially or fully) -// drives one of its two inputs -match ffcemux - select ffcemux->type.in($mux) - // ffcemux output must have two users: ffcemux and ff.D - select nusers(port(ffcemux, \Y)) == 2 - - choice <IdString> AB {\A, \B} - // keep-last-value net must have at least three users: ffcemux, ff, downstream sink(s) - select nusers(port(ffcemux, AB)) >= 3 - - slice offset GetSize(port(ffcemux, \Y)) - define <IdString> BA (AB == \A ? \B : \A) - index <SigBit> port(ffcemux, BA)[offset] === argD[0] - - // Check that the rest of argD is present - filter GetSize(port(ffcemux, BA)) >= offset + GetSize(argD) - filter port(ffcemux, BA).extract(offset, GetSize(argD)) == argD - - set ffoffset offset - define <bool> pol (AB == \A) - set ffcepol pol - - semioptional -endmatch - -code argD argQ - dffcemux = ffcemux; - if (ffcemux) { - SigSpec BA = port(ffcemux, ffcepol ? \B : \A); - SigSpec Y = port(ffcemux, \Y); - argQ = argD; - argD.replace(BA, Y); - argQ.replace(BA, port(ffcemux, ffcepol ? \A : \B)); - - dffcemux = ffcemux; - dffcepol = ffcepol; - } -endcode - -// (2) Starting from, or continuing onto, another optional $mux cell that -// implements synchronous reset semantics --- one where the given 'D' -// argument (or the clock enable $mux output) drives one of its two inputs -// and where the other input is fully zero -match ffrstmux - select ffrstmux->type.in($mux) - // ffrstmux output must have two users: ffrstmux and ff.D - select nusers(port(ffrstmux, \Y)) == 2 - - choice <IdString> BA {\B, \A} - // DSP48E1 only supports reset to zero - select port(ffrstmux, BA).is_fully_zero() - - slice offset GetSize(port(ffrstmux, \Y)) - define <IdString> AB (BA == \B ? \A : \B) - index <SigBit> port(ffrstmux, AB)[offset] === argD[0] - - // Check that offset is consistent - filter !ffcemux || ffoffset == offset - // Check that the rest of argD is present - filter GetSize(port(ffrstmux, AB)) >= offset + GetSize(argD) - filter port(ffrstmux, AB).extract(offset, GetSize(argD)) == argD - - set ffoffset offset - define <bool> pol (AB == \A) - set ffrstpol pol - - semioptional -endmatch - -code argD argQ - dffrstmux = ffrstmux; - if (ffrstmux) { - SigSpec AB = port(ffrstmux, ffrstpol ? \A : \B); - SigSpec Y = port(ffrstmux, \Y); - argD.replace(AB, Y); - - dffrstmux = ffrstmux; - dffrstpol = ffrstpol; - } -endcode - -// (3) Match for a $dff cell (whose 'D' input is the 'D' argument, or the -// output of the previous clock enable or reset $mux cells) match ff - select ff->type.in($dff) + select ff->type.in($dff, $dffe, $sdff, $sdffe) // DSP48E1 does not support clock inversion select param(ff, \CLK_POLARITY).as_bool() slice offset GetSize(port(ff, \D)) index <SigBit> port(ff, \D)[offset] === argD[0] - // Check that offset is consistent - filter (!ffcemux && !ffrstmux) || ffoffset == offset // Check that the rest of argD is present filter GetSize(port(ff, \D)) >= offset + GetSize(argD) filter port(ff, \D).extract(offset, GetSize(argD)) == argD - // Check that FF.Q is connected to CE-mux - filter !ffcemux || port(ff, \Q).extract(offset, GetSize(argQ)) == argQ filter clock == SigBit() || port(ff, \CLK) == clock - - set ffoffset offset endmatch code argQ SigSpec D = port(ff, \D); SigSpec Q = port(ff, \Q); - if (!ffcemux) { - argQ = argD; - argQ.replace(D, Q); - } + argQ = argD; + argQ.replace(D, Q); // Abandon matches when 'Q' has a non-zero init attribute set // (not supported by DSP48E1) diff --git a/passes/pmgen/xilinx_dsp48a.pmg b/passes/pmgen/xilinx_dsp48a.pmg index 16f5e598d..dce1b61b0 100644 --- a/passes/pmgen/xilinx_dsp48a.pmg +++ b/passes/pmgen/xilinx_dsp48a.pmg @@ -4,8 +4,6 @@ // At a high level, it works as follows: // ( 1) Starting from a DSP48A/DSP48A1 cell // ( 2) Match the driver of the 'B' input to a possible $dff cell (B1REG) -// (attached to at most two $mux cells that implement clock-enable or -// reset functionality, using a subpattern discussed below) // If B1REG matched, treat 'B' input as input of B1REG // ( 3) Match the driver of the 'B' and 'D' inputs for a possible $add cell // (pre-adder) @@ -40,20 +38,15 @@ pattern xilinx_dsp48a_pack state <SigBit> clock state <SigSpec> sigA sigB sigC sigD sigM sigP state <IdString> postAddAB postAddMuxAB -state <bool> ffAcepol ffBcepol ffDcepol ffMcepol ffPcepol -state <bool> ffArstpol ffBrstpol ffDrstpol ffMrstpol ffPrstpol -state <Cell*> ffA0 ffA0cemux ffA0rstmux ffA1 ffA1cemux ffA1rstmux -state <Cell*> ffB0 ffB0cemux ffB0rstmux ffB1 ffB1cemux ffB1rstmux -state <Cell*> ffD ffDcemux ffDrstmux ffM ffMcemux ffMrstmux ffP ffPcemux ffPrstmux +state <Cell*> ffA0 ffA1 +state <Cell*> ffB0 ffB1 +state <Cell*> ffD ffM ffP // Variables used for subpatterns state <SigSpec> argQ argD -state <bool> ffcepol ffrstpol -state <int> ffoffset udata <SigSpec> dffD dffQ udata <SigBit> dffclock -udata <Cell*> dff dffcemux dffrstmux -udata <bool> dffcepol dffrstpol +udata <Cell*> dff // (1) Starting from a DSP48A/DSP48A1 cell match dsp @@ -98,21 +91,13 @@ endcode // (attached to at most two $mux cells that implement clock-enable or // reset functionality, using a subpattern discussed above) // If matched, treat 'B' input as input of B1REG -code argQ ffB1 ffB1cemux ffB1rstmux ffBcepol ffBrstpol sigB clock +code argQ ffB1 sigB clock if (param(dsp, \B1REG).as_int() == 0 && param(dsp, \B0REG).as_int() == 0 && port(dsp, \OPMODE, SigSpec()).extract(4, 1).is_fully_zero()) { argQ = sigB; subpattern(in_dffe); if (dff) { ffB1 = dff; clock = dffclock; - if (dffrstmux) { - ffB1rstmux = dffrstmux; - ffBrstpol = dffrstpol; - } - if (dffcemux) { - ffB1cemux = dffcemux; - ffBcepol = dffcepol; - } sigB = dffD; } } @@ -147,41 +132,29 @@ code sigB sigD endcode // (4) Match 'B' input for B0REG -code argQ ffB0 ffB0cemux ffB0rstmux ffBcepol ffBrstpol sigB clock +code argQ ffB0 sigB clock if (param(dsp, \B0REG).as_int() == 0) { argQ = sigB; subpattern(in_dffe); if (dff) { if (ffB1) { - if ((ffB1rstmux != nullptr) ^ (dffrstmux != nullptr)) + if (dff->type != ffB1->type) goto ffB0_end; - if ((ffB1cemux != nullptr) ^ (dffcemux != nullptr)) - goto ffB0_end; - if (dffrstmux) { - if (ffBrstpol != dffrstpol) + if (dff->type.in($sdff, $sdffe, $sdffce)) { + if (param(dff, \SRST_POLARITY) != param(ffB1, \SRST_POLARITY)) goto ffB0_end; - if (port(ffB1rstmux, \S) != port(dffrstmux, \S)) + if (port(dff, \SRST) != port(ffB1, \SRST)) goto ffB0_end; - ffB0rstmux = dffrstmux; } - if (dffcemux) { - if (ffBcepol != dffcepol) + if (dff->type.in($dffe, $sdffe, $sdffce)) { + if (param(dff, \EN_POLARITY) != param(ffB1, \EN_POLARITY)) goto ffB0_end; - if (port(ffB1cemux, \S) != port(dffcemux, \S)) + if (port(dff, \EN) != port(ffB1, \EN)) goto ffB0_end; - ffB0cemux = dffcemux; } } ffB0 = dff; clock = dffclock; - if (dffrstmux) { - ffB0rstmux = dffrstmux; - ffBrstpol = dffrstpol; - } - if (dffcemux) { - ffB0cemux = dffcemux; - ffBcepol = dffcepol; - } sigB = dffD; } } @@ -190,21 +163,13 @@ endcode // (5) Match 'A' input for A1REG // If A1REG, then match 'A' input for A0REG -code argQ ffA1 ffA1cemux ffA1rstmux ffAcepol ffArstpol sigA clock ffA0 ffA0cemux ffA0rstmux +code argQ ffA1 sigA clock ffA0 if (param(dsp, \A0REG).as_int() == 0 && param(dsp, \A1REG).as_int() == 0) { argQ = sigA; subpattern(in_dffe); if (dff) { ffA1 = dff; clock = dffclock; - if (dffrstmux) { - ffA1rstmux = dffrstmux; - ffArstpol = dffrstpol; - } - if (dffcemux) { - ffA1cemux = dffcemux; - ffAcepol = dffcepol; - } sigA = dffD; // Now attempt to match A0 @@ -212,32 +177,23 @@ code argQ ffA1 ffA1cemux ffA1rstmux ffAcepol ffArstpol sigA clock ffA0 ffA0cemux argQ = sigA; subpattern(in_dffe); if (dff) { - if ((ffA1rstmux != nullptr) ^ (dffrstmux != nullptr)) + if (dff->type != ffA1->type) goto ffA0_end; - if ((ffA1cemux != nullptr) ^ (dffcemux != nullptr)) - goto ffA0_end; - if (dffrstmux) { - if (ffArstpol != dffrstpol) + if (dff->type.in($sdff, $sdffe, $sdffce)) { + if (param(dff, \SRST_POLARITY) != param(ffA1, \SRST_POLARITY)) goto ffA0_end; - if (port(ffA1rstmux, \S) != port(dffrstmux, \S)) + if (port(dff, \SRST) != port(ffA1, \SRST)) goto ffA0_end; - ffA0rstmux = dffrstmux; } - if (dffcemux) { - if (ffAcepol != dffcepol) + if (dff->type.in($dffe, $sdffe, $sdffce)) { + if (param(dff, \EN_POLARITY) != param(ffA1, \EN_POLARITY)) goto ffA0_end; - if (port(ffA1cemux, \S) != port(dffcemux, \S)) + if (port(dff, \EN) != port(ffA1, \EN)) goto ffA0_end; - ffA0cemux = dffcemux; } ffA0 = dff; clock = dffclock; - - if (dffcemux) { - ffA0cemux = dffcemux; - ffAcepol = dffcepol; - } sigA = dffD; ffA0_end: ; @@ -249,42 +205,26 @@ ffA0_end: ; endcode // (6) Match 'D' input for DREG -code argQ ffD ffDcemux ffDrstmux ffDcepol ffDrstpol sigD clock +code argQ ffD sigD clock if (param(dsp, \DREG).as_int() == 0) { argQ = sigD; subpattern(in_dffe); if (dff) { ffD = dff; clock = dffclock; - if (dffrstmux) { - ffDrstmux = dffrstmux; - ffDrstpol = dffrstpol; - } - if (dffcemux) { - ffDcemux = dffcemux; - ffDcepol = dffcepol; - } sigD = dffD; } } endcode // (7) Match 'P' output that exclusively drives an MREG -code argD ffM ffMcemux ffMrstmux ffMcepol ffMrstpol sigM sigP clock +code argD ffM sigM sigP clock if (param(dsp, \MREG).as_int() == 0 && nusers(sigM) == 2) { argD = sigM; subpattern(out_dffe); if (dff) { ffM = dff; clock = dffclock; - if (dffrstmux) { - ffMrstmux = dffrstmux; - ffMrstpol = dffrstpol; - } - if (dffcemux) { - ffMcemux = dffcemux; - ffMcepol = dffcepol; - } sigM = dffQ; } } @@ -303,9 +243,7 @@ match postAdd select postAdd->type.in($add) select GetSize(port(postAdd, \Y)) <= 48 choice <IdString> AB {\A, \B} - select nusers(port(postAdd, AB)) <= 3 - filter ffMcemux || nusers(port(postAdd, AB)) == 2 - filter !ffMcemux || nusers(port(postAdd, AB)) == 3 + select nusers(port(postAdd, AB)) == 2 index <SigBit> port(postAdd, AB)[0] === sigP[0] filter GetSize(port(postAdd, AB)) >= GetSize(sigP) @@ -325,25 +263,14 @@ code sigC sigP endcode // (9) Match 'P' output that exclusively drives a PREG -code argD ffP ffPcemux ffPrstmux ffPcepol ffPrstpol sigP clock +code argD ffP sigP clock if (param(dsp, \PREG).as_int() == 0) { - int users = 2; - // If ffMcemux and no postAdd new-value net must have three users: ffMcemux, ffM and ffPcemux - if (ffMcemux && !postAdd) users++; - if (nusers(sigP) == users) { + if (nusers(sigP) == 2) { argD = sigP; subpattern(out_dffe); if (dff) { ffP = dff; clock = dffclock; - if (dffrstmux) { - ffPrstmux = dffrstmux; - ffPrstpol = dffrstpol; - } - if (dffcemux) { - ffPcemux = dffcemux; - ffPcepol = dffcepol; - } sigP = dffQ; } } @@ -387,26 +314,13 @@ endcode // ####################### // Subpattern for matching against input registers, based on knowledge of the -// 'Q' input. Typically, identifying registers with clock-enable and reset -// capability would be a task would be handled by other Yosys passes such as -// dff2dffe, but since DSP inference happens much before this, these patterns -// have to be manually identified. -// At a high level: -// (1) Starting from a $dff cell that (partially or fully) drives the given -// 'Q' argument -// (2) Match for a $mux cell implementing synchronous reset semantics --- -// one that exclusively drives the 'D' input of the $dff, with one of its -// $mux inputs being fully zero -// (3) Match for a $mux cell implement clock enable semantics --- one that -// exclusively drives the 'D' input of the $dff (or the other input of -// the reset $mux) and where one of this $mux's inputs is connected to -// the 'Q' output of the $dff +// 'Q' input. subpattern in_dffe -arg argD argQ clock +arg argQ clock code dff = nullptr; - if (GetSize(argQ) == 0) + if (argQ.empty()) reject; for (const auto &c : argQ.chunks()) { // Abandon matches when 'Q' is a constant @@ -425,13 +339,14 @@ code } endcode -// (1) Starting from a $dff cell that (partially or fully) drives the given -// 'Q' argument match ff - select ff->type.in($dff) + select ff->type.in($dff, $dffe, $sdff, $sdffe) // DSP48E1 does not support clock inversion select param(ff, \CLK_POLARITY).as_bool() + // Check that reset value, if present, is fully 0. + filter ff->type.in($dff, $dffe) || param(ff, \SRST_VALUE).is_fully_zero() + slice offset GetSize(port(ff, \D)) index <SigBit> port(ff, \Q)[offset] === argQ[0] @@ -440,82 +355,16 @@ match ff filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ filter clock == SigBit() || port(ff, \CLK) == clock - - set ffoffset offset endmatch -code argQ argD +code argQ SigSpec Q = port(ff, \Q); dff = ff; dffclock = port(ff, \CLK); dffD = argQ; - argD = port(ff, \D); + SigSpec D = port(ff, \D); argQ = Q; - dffD.replace(argQ, argD); - // Only search for ffrstmux if dffD only - // has two (ff, ffrstmux) users - if (nusers(dffD) > 2) - argD = SigSpec(); -endcode - -// (2) Match for a $mux cell implementing synchronous reset semantics --- -// exclusively drives the 'D' input of the $dff, with one of the $mux -// inputs being fully zero -match ffrstmux - if !argD.empty() - select ffrstmux->type.in($mux) - index <SigSpec> port(ffrstmux, \Y) === argD - - choice <IdString> BA {\B, \A} - // DSP48E1 only supports reset to zero - select port(ffrstmux, BA).is_fully_zero() - - define <bool> pol (BA == \B) - set ffrstpol pol - semioptional -endmatch - -code argD - if (ffrstmux) { - dffrstmux = ffrstmux; - dffrstpol = ffrstpol; - argD = port(ffrstmux, ffrstpol ? \A : \B); - dffD.replace(port(ffrstmux, \Y), argD); - - // Only search for ffcemux if argQ has at - // least 3 users (ff, <upstream>, ffrstmux) and - // dffD only has two (ff, ffrstmux) - if (!(nusers(argQ) >= 3 && nusers(dffD) == 2)) - argD = SigSpec(); - } - else - dffrstmux = nullptr; -endcode - -// (3) Match for a $mux cell implement clock enable semantics --- one that -// exclusively drives the 'D' input of the $dff (or the other input of -// the reset $mux) and where one of this $mux's inputs is connected to -// the 'Q' output of the $dff -match ffcemux - if !argD.empty() - select ffcemux->type.in($mux) - index <SigSpec> port(ffcemux, \Y) === argD - choice <IdString> AB {\A, \B} - index <SigSpec> port(ffcemux, AB) === argQ - define <bool> pol (AB == \A) - set ffcepol pol - semioptional -endmatch - -code argD - if (ffcemux) { - dffcemux = ffcemux; - dffcepol = ffcepol; - argD = port(ffcemux, ffcepol ? \B : \A); - dffD.replace(port(ffcemux, \Y), argD); - } - else - dffcemux = nullptr; + dffD.replace(argQ, D); endcode // ####################### @@ -543,119 +392,26 @@ code reject; endcode -// (1) Starting from an optional $mux cell that implements clock enable -// semantics --- one where the given 'D' argument (partially or fully) -// drives one of its two inputs -match ffcemux - select ffcemux->type.in($mux) - // ffcemux output must have two users: ffcemux and ff.D - select nusers(port(ffcemux, \Y)) == 2 - - choice <IdString> AB {\A, \B} - // keep-last-value net must have at least three users: ffcemux, ff, downstream sink(s) - select nusers(port(ffcemux, AB)) >= 3 - - slice offset GetSize(port(ffcemux, \Y)) - define <IdString> BA (AB == \A ? \B : \A) - index <SigBit> port(ffcemux, BA)[offset] === argD[0] - - // Check that the rest of argD is present - filter GetSize(port(ffcemux, BA)) >= offset + GetSize(argD) - filter port(ffcemux, BA).extract(offset, GetSize(argD)) == argD - - set ffoffset offset - define <bool> pol (AB == \A) - set ffcepol pol - - semioptional -endmatch - -code argD argQ - dffcemux = ffcemux; - if (ffcemux) { - SigSpec BA = port(ffcemux, ffcepol ? \B : \A); - SigSpec Y = port(ffcemux, \Y); - argQ = argD; - argD.replace(BA, Y); - argQ.replace(BA, port(ffcemux, ffcepol ? \A : \B)); - - dffcemux = ffcemux; - dffcepol = ffcepol; - } -endcode - -// (2) Starting from, or continuing onto, another optional $mux cell that -// implements synchronous reset semantics --- one where the given 'D' -// argument (or the clock enable $mux output) drives one of its two inputs -// and where the other input is fully zero -match ffrstmux - select ffrstmux->type.in($mux) - // ffrstmux output must have two users: ffrstmux and ff.D - select nusers(port(ffrstmux, \Y)) == 2 - - choice <IdString> BA {\B, \A} - // DSP48E1 only supports reset to zero - select port(ffrstmux, BA).is_fully_zero() - - slice offset GetSize(port(ffrstmux, \Y)) - define <IdString> AB (BA == \B ? \A : \B) - index <SigBit> port(ffrstmux, AB)[offset] === argD[0] - - // Check that offset is consistent - filter !ffcemux || ffoffset == offset - // Check that the rest of argD is present - filter GetSize(port(ffrstmux, AB)) >= offset + GetSize(argD) - filter port(ffrstmux, AB).extract(offset, GetSize(argD)) == argD - - set ffoffset offset - define <bool> pol (AB == \A) - set ffrstpol pol - - semioptional -endmatch - -code argD argQ - dffrstmux = ffrstmux; - if (ffrstmux) { - SigSpec AB = port(ffrstmux, ffrstpol ? \A : \B); - SigSpec Y = port(ffrstmux, \Y); - argD.replace(AB, Y); - - dffrstmux = ffrstmux; - dffrstpol = ffrstpol; - } -endcode - -// (3) Match for a $dff cell (whose 'D' input is the 'D' argument, or the -// output of the previous clock enable or reset $mux cells) match ff - select ff->type.in($dff) + select ff->type.in($dff, $dffe, $sdff, $sdffe) // DSP48E1 does not support clock inversion select param(ff, \CLK_POLARITY).as_bool() slice offset GetSize(port(ff, \D)) index <SigBit> port(ff, \D)[offset] === argD[0] - // Check that offset is consistent - filter (!ffcemux && !ffrstmux) || ffoffset == offset // Check that the rest of argD is present filter GetSize(port(ff, \D)) >= offset + GetSize(argD) filter port(ff, \D).extract(offset, GetSize(argD)) == argD - // Check that FF.Q is connected to CE-mux - filter !ffcemux || port(ff, \Q).extract(offset, GetSize(argQ)) == argQ filter clock == SigBit() || port(ff, \CLK) == clock - - set ffoffset offset endmatch code argQ SigSpec D = port(ff, \D); SigSpec Q = port(ff, \Q); - if (!ffcemux) { - argQ = argD; - argQ.replace(D, Q); - } + argQ = argD; + argQ.replace(D, Q); // Abandon matches when 'Q' has a non-zero init attribute set // (not supported by DSP48E1) diff --git a/passes/pmgen/xilinx_dsp_CREG.pmg b/passes/pmgen/xilinx_dsp_CREG.pmg index 42d4d1b9b..95379771a 100644 --- a/passes/pmgen/xilinx_dsp_CREG.pmg +++ b/passes/pmgen/xilinx_dsp_CREG.pmg @@ -26,17 +26,14 @@ pattern xilinx_dsp_packC udata <std::function<SigSpec(const SigSpec&)>> unextend state <SigBit> clock state <SigSpec> sigC sigP -state <bool> ffCcepol ffCrstpol -state <Cell*> ffC ffCcemux ffCrstmux +state <Cell*> ffC // Variables used for subpatterns state <SigSpec> argQ argD -state <bool> ffcepol ffrstpol state <int> ffoffset udata <SigSpec> dffD dffQ udata <SigBit> dffclock -udata <Cell*> dff dffcemux dffrstmux -udata <bool> dffcepol dffrstpol +udata <Cell*> dff // (1) Starting from a DSP48* cell that (a) doesn't have a CREG already, // and (b) uses the 'C' port @@ -80,20 +77,12 @@ endcode // (2) Match the driver of the 'C' input to a possible $dff cell (CREG) // (attached to at most two $mux cells that implement clock-enable or // reset functionality, using the in_dffe subpattern) -code argQ ffC ffCcemux ffCrstmux ffCcepol ffCrstpol sigC clock +code argQ ffC sigC clock argQ = sigC; subpattern(in_dffe); if (dff) { ffC = dff; clock = dffclock; - if (dffrstmux) { - ffCrstmux = dffrstmux; - ffCrstpol = dffrstpol; - } - if (dffcemux) { - ffCcemux = dffcemux; - ffCcepol = dffcepol; - } sigC = dffD; } endcode @@ -106,25 +95,14 @@ endcode // ####################### // Subpattern for matching against input registers, based on knowledge of the -// 'Q' input. Typically, identifying registers with clock-enable and reset -// capability would be a task would be handled by other Yosys passes such as -// dff2dffe, but since DSP inference happens much before this, these patterns -// have to be manually identified. -// At a high level: -// (1) Starting from a $dff cell that (partially or fully) drives the given -// 'Q' argument -// (2) Match for a $mux cell implementing synchronous reset semantics --- -// one that exclusively drives the 'D' input of the $dff, with one of its -// $mux inputs being fully zero -// (3) Match for a $mux cell implement clock enable semantics --- one that -// exclusively drives the 'D' input of the $dff (or the other input of -// the reset $mux) and where one of this $mux's inputs is connected to -// the 'Q' output of the $dff +// 'Q' input. subpattern in_dffe -arg argD argQ clock +arg argQ clock code dff = nullptr; + if (argQ.empty()) + reject; for (const auto &c : argQ.chunks()) { // Abandon matches when 'Q' is a constant if (!c.wire) @@ -135,19 +113,21 @@ code // Abandon matches when 'Q' has a non-zero init attribute set // (not supported by DSP48E1) Const init = c.wire->attributes.at(\init, Const()); - for (auto b : init.extract(c.offset, c.width)) - if (b != State::Sx && b != State::S0) - reject; + if (!init.empty()) + for (auto b : init.extract(c.offset, c.width)) + if (b != State::Sx && b != State::S0) + reject; } endcode -// (1) Starting from a $dff cell that (partially or fully) drives the given -// 'Q' argument match ff - select ff->type.in($dff) + select ff->type.in($dff, $dffe, $sdff, $sdffe) // DSP48E1 does not support clock inversion select param(ff, \CLK_POLARITY).as_bool() + // Check that reset value, if present, is fully 0. + filter ff->type.in($dff, $dffe) || param(ff, \SRST_VALUE).is_fully_zero() + slice offset GetSize(port(ff, \D)) index <SigBit> port(ff, \Q)[offset] === argQ[0] @@ -156,80 +136,14 @@ match ff filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ filter clock == SigBit() || port(ff, \CLK) == clock - - set ffoffset offset endmatch -code argQ argD +code argQ SigSpec Q = port(ff, \Q); dff = ff; dffclock = port(ff, \CLK); dffD = argQ; - argD = port(ff, \D); + SigSpec D = port(ff, \D); argQ = Q; - dffD.replace(argQ, argD); - // Only search for ffrstmux if dffD only - // has two (ff, ffrstmux) users - if (nusers(dffD) > 2) - argD = SigSpec(); -endcode - -// (2) Match for a $mux cell implementing synchronous reset semantics --- -// exclusively drives the 'D' input of the $dff, with one of the $mux -// inputs being fully zero -match ffrstmux - if !argD.empty() - select ffrstmux->type.in($mux) - index <SigSpec> port(ffrstmux, \Y) === argD - - choice <IdString> BA {\B, \A} - // DSP48E1 only supports reset to zero - select port(ffrstmux, BA).is_fully_zero() - - define <bool> pol (BA == \B) - set ffrstpol pol - semioptional -endmatch - -code argD - if (ffrstmux) { - dffrstmux = ffrstmux; - dffrstpol = ffrstpol; - argD = port(ffrstmux, ffrstpol ? \A : \B); - dffD.replace(port(ffrstmux, \Y), argD); - - // Only search for ffcemux if argQ has at - // least 3 users (ff, <upstream>, ffrstmux) and - // dffD only has two (ff, ffrstmux) - if (!(nusers(argQ) >= 3 && nusers(dffD) == 2)) - argD = SigSpec(); - } - else - dffrstmux = nullptr; -endcode - -// (3) Match for a $mux cell implement clock enable semantics --- one that -// exclusively drives the 'D' input of the $dff (or the other input of -// the reset $mux) and where one of this $mux's inputs is connected to -// the 'Q' output of the $dff -match ffcemux - if !argD.empty() - select ffcemux->type.in($mux) - index <SigSpec> port(ffcemux, \Y) === argD - choice <IdString> AB {\A, \B} - index <SigSpec> port(ffcemux, AB) === argQ - define <bool> pol (AB == \A) - set ffcepol pol - semioptional -endmatch - -code argD - if (ffcemux) { - dffcemux = ffcemux; - dffcepol = ffcepol; - argD = port(ffcemux, ffcepol ? \B : \A); - dffD.replace(port(ffcemux, \Y), argD); - } - else - dffcemux = nullptr; + dffD.replace(argQ, D); endcode diff --git a/passes/pmgen/xilinx_dsp_cascade.pmg b/passes/pmgen/xilinx_dsp_cascade.pmg index 8babb88e6..06601554c 100644 --- a/passes/pmgen/xilinx_dsp_cascade.pmg +++ b/passes/pmgen/xilinx_dsp_cascade.pmg @@ -51,12 +51,10 @@ state <int> AREG BREG // Variables used for subpatterns state <SigSpec> argQ argD -state <bool> ffcepol ffrstpol state <int> ffoffset udata <SigSpec> dffD dffQ udata <SigBit> dffclock -udata <Cell*> dff dffcemux dffrstmux -udata <bool> dffcepol dffrstpol +udata <Cell*> dff code #define MAX_DSP_CASCADE 20 @@ -254,9 +252,9 @@ code argQ clock AREG clock = port(prev, \CLK); subpattern(in_dffe); if (dff) { - if (!dffrstmux && port(prev, \RSTA, State::S0) != State::S0) + if (!dff->type.in($sdff, $sdffe) && port(prev, \RSTA, State::S0) != State::S0) goto reject_AREG; - if (dffrstmux && port(dffrstmux, \S) != port(prev, \RSTA, State::S0)) + if (dff->type.in($sdff, $sdffe) && (port(dff, \SRST) != port(prev, \RSTA, State::S0) || !param(dff, \SRST_POLARITY).as_bool())) goto reject_AREG; IdString CEA; if (param(prev, \AREG) == 1) @@ -264,9 +262,9 @@ code argQ clock AREG else if (param(prev, \AREG) == 2) CEA = \CEA1; else log_abort(); - if (!dffcemux && port(prev, CEA, State::S0) != State::S1) + if (!dff->type.in($dffe, $sdffe) && port(prev, CEA, State::S0) != State::S1) goto reject_AREG; - if (dffcemux && port(dffcemux, \S) != port(prev, CEA, State::S0)) + if (dff->type.in($dffe, $sdffe) && (port(dff, \EN) != port(prev, CEA, State::S0) || !param(dff, \EN_POLARITY).as_bool())) goto reject_AREG; if (dffD == unextend(port(prev, \A))) AREG = 1; @@ -295,9 +293,9 @@ code argQ clock BREG clock = port(prev, \CLK); subpattern(in_dffe); if (dff) { - if (!dffrstmux && port(prev, \RSTB, State::S0) != State::S0) + if (!dff->type.in($sdff, $sdffe) && port(prev, \RSTB, State::S0) != State::S0) goto reject_BREG; - if (dffrstmux && port(dffrstmux, \S) != port(prev, \RSTB, State::S0)) + if (dff->type.in($sdff, $sdffe) && (port(dff, \SRST) != port(prev, \RSTB, State::S0) || !param(dff, \SRST_POLARITY).as_bool())) goto reject_BREG; IdString CEB; if (next->type.in(\DSP48A, \DSP48A1)) @@ -310,9 +308,9 @@ code argQ clock BREG else log_abort(); } else log_abort(); - if (!dffcemux && port(prev, CEB, State::S0) != State::S1) + if (!dff->type.in($dffe, $sdffe) && port(prev, CEB, State::S0) != State::S1) goto reject_BREG; - if (dffcemux && port(dffcemux, \S) != port(prev, CEB, State::S0)) + if (dff->type.in($dffe, $sdffe) && (port(dff, \EN) != port(prev, CEB, State::S0) || !param(dff, \EN_POLARITY).as_bool())) goto reject_BREG; if (dffD == unextend(port(prev, \B))) { if (next->type.in(\DSP48A, \DSP48A1) && param(prev, \B0REG) != 0) @@ -357,25 +355,14 @@ endcode // ####################### // Subpattern for matching against input registers, based on knowledge of the -// 'Q' input. Typically, identifying registers with clock-enable and reset -// capability would be a task would be handled by other Yosys passes such as -// dff2dffe, but since DSP inference happens much before this, these patterns -// have to be manually identified. -// At a high level: -// (1) Starting from a $dff cell that (partially or fully) drives the given -// 'Q' argument -// (2) Match for a $mux cell implementing synchronous reset semantics --- -// one that exclusively drives the 'D' input of the $dff, with one of its -// $mux inputs being fully zero -// (3) Match for a $mux cell implement clock enable semantics --- one that -// exclusively drives the 'D' input of the $dff (or the other input of -// the reset $mux) and where one of this $mux's inputs is connected to -// the 'Q' output of the $dff +// 'Q' input. subpattern in_dffe -arg argD argQ clock +arg argQ clock code dff = nullptr; + if (argQ.empty()) + reject; for (const auto &c : argQ.chunks()) { // Abandon matches when 'Q' is a constant if (!c.wire) @@ -386,19 +373,21 @@ code // Abandon matches when 'Q' has a non-zero init attribute set // (not supported by DSP48E1) Const init = c.wire->attributes.at(\init, Const()); - for (auto b : init.extract(c.offset, c.width)) - if (b != State::Sx && b != State::S0) - reject; + if (!init.empty()) + for (auto b : init.extract(c.offset, c.width)) + if (b != State::Sx && b != State::S0) + reject; } endcode -// (1) Starting from a $dff cell that (partially or fully) drives the given -// 'Q' argument match ff - select ff->type.in($dff) + select ff->type.in($dff, $dffe, $sdff, $sdffe) // DSP48E1 does not support clock inversion select param(ff, \CLK_POLARITY).as_bool() + // Check that reset value, if present, is fully 0. + filter ff->type.in($dff, $dffe) || param(ff, \SRST_VALUE).is_fully_zero() + slice offset GetSize(port(ff, \D)) index <SigBit> port(ff, \Q)[offset] === argQ[0] @@ -407,80 +396,14 @@ match ff filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ filter clock == SigBit() || port(ff, \CLK) == clock - - set ffoffset offset endmatch -code argQ argD +code argQ SigSpec Q = port(ff, \Q); dff = ff; dffclock = port(ff, \CLK); dffD = argQ; - argD = port(ff, \D); + SigSpec D = port(ff, \D); argQ = Q; - dffD.replace(argQ, argD); - // Only search for ffrstmux if dffD only - // has two (ff, ffrstmux) users - if (nusers(dffD) > 2) - argD = SigSpec(); -endcode - -// (2) Match for a $mux cell implementing synchronous reset semantics --- -// exclusively drives the 'D' input of the $dff, with one of the $mux -// inputs being fully zero -match ffrstmux - if !argD.empty() - select ffrstmux->type.in($mux) - index <SigSpec> port(ffrstmux, \Y) === argD - - choice <IdString> BA {\B, \A} - // DSP48E1 only supports reset to zero - select port(ffrstmux, BA).is_fully_zero() - - define <bool> pol (BA == \B) - set ffrstpol pol - semioptional -endmatch - -code argD - if (ffrstmux) { - dffrstmux = ffrstmux; - dffrstpol = ffrstpol; - argD = port(ffrstmux, ffrstpol ? \A : \B); - dffD.replace(port(ffrstmux, \Y), argD); - - // Only search for ffcemux if argQ has at - // least 3 users (ff, <upstream>, ffrstmux) and - // dffD only has two (ff, ffrstmux) - if (!(nusers(argQ) >= 3 && nusers(dffD) == 2)) - argD = SigSpec(); - } - else - dffrstmux = nullptr; -endcode - -// (3) Match for a $mux cell implement clock enable semantics --- one that -// exclusively drives the 'D' input of the $dff (or the other input of -// the reset $mux) and where one of this $mux's inputs is connected to -// the 'Q' output of the $dff -match ffcemux - if !argD.empty() - select ffcemux->type.in($mux) - index <SigSpec> port(ffcemux, \Y) === argD - choice <IdString> AB {\A, \B} - index <SigSpec> port(ffcemux, AB) === argQ - define <bool> pol (AB == \A) - set ffcepol pol - semioptional -endmatch - -code argD - if (ffcemux) { - dffcemux = ffcemux; - dffcepol = ffcepol; - argD = port(ffcemux, ffcepol ? \B : \A); - dffD.replace(port(ffcemux, \Y), argD); - } - else - dffcemux = nullptr; + dffD.replace(argQ, D); endcode diff --git a/passes/pmgen/xilinx_srl.cc b/passes/pmgen/xilinx_srl.cc index b99653fb3..1410850c7 100644 --- a/passes/pmgen/xilinx_srl.cc +++ b/passes/pmgen/xilinx_srl.cc @@ -188,7 +188,7 @@ void run_variable(xilinx_srl_pm &pm) struct XilinxSrlPass : public Pass { XilinxSrlPass() : Pass("xilinx_srl", "Xilinx shift register extraction") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -212,7 +212,7 @@ struct XilinxSrlPass : public Pass { log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing XILINX_SRL pass (Xilinx shift register extraction).\n"); diff --git a/passes/proc/proc.cc b/passes/proc/proc.cc index a5b4a3112..09cf0af82 100644 --- a/passes/proc/proc.cc +++ b/passes/proc/proc.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct ProcPass : public Pass { ProcPass() : Pass("proc", "translate processes to netlists") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -50,6 +50,9 @@ struct ProcPass : public Pass { log("\n"); log("The following options are supported:\n"); log("\n"); + log(" -nomux\n"); + log(" Will omit the proc_mux pass.\n"); + log("\n"); log(" -global_arst [!]<netname>\n"); log(" This option is passed through to proc_arst.\n"); log("\n"); @@ -58,10 +61,11 @@ struct ProcPass : public Pass { log(" executed in -ifx mode.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string global_arst; bool ifxmode = false; + bool nomux = false; log_header(design, "Executing PROC pass (convert processes to netlists).\n"); log_push(); @@ -69,6 +73,10 @@ struct ProcPass : public Pass { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-nomux") { + nomux = true; + continue; + } if (args[argidx] == "-global_arst" && argidx+1 < args.size()) { global_arst = args[++argidx]; continue; @@ -90,7 +98,8 @@ struct ProcPass : public Pass { Pass::call(design, "proc_arst"); else Pass::call(design, "proc_arst -global_arst " + global_arst); - Pass::call(design, ifxmode ? "proc_mux -ifx" : "proc_mux"); + if (!nomux) + Pass::call(design, ifxmode ? "proc_mux -ifx" : "proc_mux"); Pass::call(design, "proc_dlatch"); Pass::call(design, "proc_dff"); Pass::call(design, "proc_clean"); diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index e400fcb72..16db461b2 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -203,7 +203,7 @@ restart_proc_arst: struct ProcArstPass : public Pass { ProcArstPass() : Pass("proc_arst", "detect asynchronous resets") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -221,7 +221,7 @@ struct ProcArstPass : public Pass { log(" in the 'init' attribute on the net.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string global_arst; bool global_arst_neg = false; diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 114c6ab03..5e78b7316 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -166,7 +166,7 @@ void proc_clean(RTLIL::Module *mod, RTLIL::Process *proc, int &total_count, bool struct ProcCleanPass : public Pass { ProcCleanPass() : Pass("proc_clean", "remove empty parts of processes") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -179,7 +179,7 @@ struct ProcCleanPass : public Pass { log("if it contains only empty structures.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { int total_count = 0; bool quiet = false; diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 59cc5bd65..e320a72a6 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -370,7 +370,7 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) struct ProcDffPass : public Pass { ProcDffPass() : Pass("proc_dff", "extract flip-flops from processes") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -380,7 +380,7 @@ struct ProcDffPass : public Pass { log("d-type flip-flop cells.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing PROC_DFF pass (convert process syncs to FFs).\n"); diff --git a/passes/proc/proc_dlatch.cc b/passes/proc/proc_dlatch.cc index c9da1d1e3..7b8c05b21 100644 --- a/passes/proc/proc_dlatch.cc +++ b/passes/proc/proc_dlatch.cc @@ -19,6 +19,7 @@ #include "kernel/register.h" #include "kernel/sigtools.h" +#include "kernel/ffinit.h" #include "kernel/consteval.h" #include "kernel/log.h" #include <sstream> @@ -32,6 +33,7 @@ struct proc_dlatch_db_t { Module *module; SigMap sigmap; + FfInitVals initvals; pool<Cell*> generated_dlatches; dict<Cell*, vector<SigBit>> mux_srcbits; @@ -40,6 +42,8 @@ struct proc_dlatch_db_t proc_dlatch_db_t(Module *module) : module(module), sigmap(module) { + initvals.set(&sigmap, module); + for (auto cell : module->cells()) { if (cell->type.in(ID($mux), ID($pmux))) @@ -69,9 +73,11 @@ struct proc_dlatch_db_t } for (auto wire : module->wires()) + { if (wire->port_input) for (auto bit : sigmap(wire)) sigusers[bit]++; + } } bool quickcheck(const SigSpec &haystack, const SigSpec &needle) @@ -393,6 +399,13 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) else log("No latch inferred for signal `%s.%s' from process `%s.%s'.\n", db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str()); + for (auto &bit : lhs) { + State val = db.initvals(bit); + if (db.initvals(bit) != State::Sx) { + log("Removing init bit %s for non-memory siginal `%s.%s` in process `%s.%s`.\n", log_signal(val), db.module->name.c_str(), log_signal(bit), db.module->name.c_str(), proc->name.c_str()); + } + db.initvals.remove_init(bit); + } db.module->connect(lhs, rhs); offset += chunk.width; } @@ -434,7 +447,7 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) struct ProcDlatchPass : public Pass { ProcDlatchPass() : Pass("proc_dlatch", "extract latches from processes") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -444,7 +457,7 @@ struct ProcDlatchPass : public Pass { log("d-type latches.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing PROC_DLATCH pass (convert process syncs to latches).\n"); diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index dc00019aa..eb323038d 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -86,7 +86,7 @@ void proc_init(RTLIL::Module *mod, SigMap &sigmap, RTLIL::Process *proc) struct ProcInitPass : public Pass { ProcInitPass() : Pass("proc_init", "convert initial block to init attributes") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -97,7 +97,7 @@ struct ProcInitPass : public Pass { log("respective wire.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing PROC_INIT pass (extract init attributes).\n"); diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 867ba1698..d20f34534 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -438,7 +438,7 @@ void proc_mux(RTLIL::Module *mod, RTLIL::Process *proc, bool ifxmode) struct ProcMuxPass : public Pass { ProcMuxPass() : Pass("proc_mux", "convert decision trees to multiplexers") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -452,7 +452,7 @@ struct ProcMuxPass : public Pass { log(" 'case' expressions and 'if' conditions.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool ifxmode = false; log_header(design, "Executing PROC_MUX pass (convert decision trees to multiplexers).\n"); diff --git a/passes/proc/proc_prune.cc b/passes/proc/proc_prune.cc index 8d11447f6..bd122b91f 100644 --- a/passes/proc/proc_prune.cc +++ b/passes/proc/proc_prune.cc @@ -125,7 +125,7 @@ struct PruneWorker struct ProcPrunePass : public Pass { ProcPrunePass() : Pass("proc_prune", "remove redundant assignments") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -135,7 +135,7 @@ struct ProcPrunePass : public Pass { log("a later assignment to the same signal and removes them.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { int total_removed_count = 0, total_promoted_count = 0; log_header(design, "Executing PROC_PRUNE pass (remove redundant assignments in processes).\n"); diff --git a/passes/proc/proc_rmdead.cc b/passes/proc/proc_rmdead.cc index 6afaf25d1..ee91637ca 100644 --- a/passes/proc/proc_rmdead.cc +++ b/passes/proc/proc_rmdead.cc @@ -70,7 +70,7 @@ void proc_rmdead(RTLIL::SwitchRule *sw, int &counter, int &full_case_counter) struct ProcRmdeadPass : public Pass { ProcRmdeadPass() : Pass("proc_rmdead", "eliminate dead trees in decision trees") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -79,7 +79,7 @@ struct ProcRmdeadPass : public Pass { log("This pass identifies unreachable branches in decision trees and removes them.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing PROC_RMDEAD pass (remove dead branches from decision trees).\n"); diff --git a/passes/sat/assertpmux.cc b/passes/sat/assertpmux.cc index 5bf2296ab..e9a10465e 100644 --- a/passes/sat/assertpmux.cc +++ b/passes/sat/assertpmux.cc @@ -181,7 +181,7 @@ struct AssertpmuxWorker struct AssertpmuxPass : public Pass { AssertpmuxPass() : Pass("assertpmux", "adds asserts for parallel muxes") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -199,7 +199,7 @@ struct AssertpmuxPass : public Pass { log(" additional constraint and check the $pmux condition always.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool flag_noinit = false; bool flag_always = false; diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index e344e2b5b..3fa5a614c 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -19,13 +19,15 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/ffinit.h" +#include "kernel/ff.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct Async2syncPass : public Pass { Async2syncPass() : Pass("async2sync", "convert async FF inputs to sync circuits") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -42,7 +44,7 @@ struct Async2syncPass : public Pass { log("Currently only $adff, $dffsr, and $dlatch cells are supported by this pass.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { // bool flag_noinit = false; @@ -62,169 +64,183 @@ struct Async2syncPass : public Pass { for (auto module : design->selected_modules()) { SigMap sigmap(module); - dict<SigBit, State> initbits; - pool<SigBit> del_initbits; - - for (auto wire : module->wires()) - if (wire->attributes.count(ID::init) > 0) - { - Const initval = wire->attributes.at(ID::init); - SigSpec initsig = sigmap(wire); - - for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++) - if (initval[i] == State::S0 || initval[i] == State::S1) - initbits[initsig[i]] = initval[i]; - } + FfInitVals initvals(&sigmap, module); for (auto cell : vector<Cell*>(module->selected_cells())) { - if (cell->type.in(ID($adff))) - { - // bool clk_pol = cell->parameters[ID::CLK_POLARITY].as_bool(); - bool arst_pol = cell->parameters[ID::ARST_POLARITY].as_bool(); - Const arst_val = cell->parameters[ID::ARST_VALUE]; - - // SigSpec sig_clk = cell->getPort(ID::CLK); - SigSpec sig_arst = cell->getPort(ID::ARST); - SigSpec sig_d = cell->getPort(ID::D); - SigSpec sig_q = cell->getPort(ID::Q); - - log("Replacing %s.%s (%s): ARST=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(sig_arst), log_signal(sig_d), log_signal(sig_q)); - - Const init_val; - for (int i = 0; i < GetSize(sig_q); i++) { - SigBit bit = sigmap(sig_q[i]); - init_val.bits.push_back(initbits.count(bit) ? initbits.at(bit) : State::Sx); - del_initbits.insert(bit); - } + if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + continue; - Wire *new_d = module->addWire(NEW_ID, GetSize(sig_d)); - Wire *new_q = module->addWire(NEW_ID, GetSize(sig_q)); - new_q->attributes[ID::init] = init_val; + FfData ff(&initvals, cell); - if (arst_pol) { - module->addMux(NEW_ID, sig_d, arst_val, sig_arst, new_d); - module->addMux(NEW_ID, new_q, arst_val, sig_arst, sig_q); - } else { - module->addMux(NEW_ID, arst_val, sig_d, sig_arst, new_d); - module->addMux(NEW_ID, arst_val, new_q, sig_arst, sig_q); - } - - cell->setPort(ID::D, new_d); - cell->setPort(ID::Q, new_q); - cell->unsetPort(ID::ARST); - cell->unsetParam(ID::ARST_POLARITY); - cell->unsetParam(ID::ARST_VALUE); - cell->type = ID($dff); + // Skip for $_FF_ and $ff cells. + if (ff.has_d && !ff.has_clk && !ff.has_en) continue; - } - if (cell->type.in(ID($dffsr))) + if (ff.has_clk) { - // bool clk_pol = cell->parameters[ID::CLK_POLARITY].as_bool(); - bool set_pol = cell->parameters[ID::SET_POLARITY].as_bool(); - bool clr_pol = cell->parameters[ID::CLR_POLARITY].as_bool(); - - // SigSpec sig_clk = cell->getPort(ID::CLK); - SigSpec sig_set = cell->getPort(ID::SET); - SigSpec sig_clr = cell->getPort(ID::CLR); - SigSpec sig_d = cell->getPort(ID::D); - SigSpec sig_q = cell->getPort(ID::Q); - - log("Replacing %s.%s (%s): SET=%s, CLR=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(sig_set), log_signal(sig_clr), log_signal(sig_d), log_signal(sig_q)); - - Const init_val; - for (int i = 0; i < GetSize(sig_q); i++) { - SigBit bit = sigmap(sig_q[i]); - init_val.bits.push_back(initbits.count(bit) ? initbits.at(bit) : State::Sx); - del_initbits.insert(bit); + if (!ff.has_sr && !ff.has_arst) + continue; + + if (ff.has_sr) { + ff.unmap_ce_srst(module); + + log("Replacing %s.%s (%s): SET=%s, CLR=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_d), log_signal(ff.sig_q)); + + initvals.remove_init(ff.sig_q); + + Wire *new_d = module->addWire(NEW_ID, ff.width); + Wire *new_q = module->addWire(NEW_ID, ff.width); + + SigSpec sig_set = ff.sig_set; + SigSpec sig_clr = ff.sig_clr; + + if (!ff.pol_set) { + if (!ff.is_fine) + sig_set = module->Not(NEW_ID, sig_set); + else + sig_set = module->NotGate(NEW_ID, sig_set); + } + + if (ff.pol_clr) { + if (!ff.is_fine) + sig_clr = module->Not(NEW_ID, sig_clr); + else + sig_clr = module->NotGate(NEW_ID, sig_clr); + } + + if (!ff.is_fine) { + SigSpec tmp = module->Or(NEW_ID, ff.sig_d, sig_set); + module->addAnd(NEW_ID, tmp, sig_clr, new_d); + + tmp = module->Or(NEW_ID, new_q, sig_set); + module->addAnd(NEW_ID, tmp, sig_clr, ff.sig_q); + } else { + SigSpec tmp = module->OrGate(NEW_ID, ff.sig_d, sig_set); + module->addAndGate(NEW_ID, tmp, sig_clr, new_d); + + tmp = module->OrGate(NEW_ID, new_q, sig_set); + module->addAndGate(NEW_ID, tmp, sig_clr, ff.sig_q); + } + + ff.sig_d = new_d; + ff.sig_q = new_q; + ff.has_sr = false; + } else if (ff.has_arst) { + ff.unmap_srst(module); + + log("Replacing %s.%s (%s): ARST=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_arst), log_signal(ff.sig_d), log_signal(ff.sig_q)); + + initvals.remove_init(ff.sig_q); + + Wire *new_q = module->addWire(NEW_ID, ff.width); + + if (ff.pol_arst) { + if (!ff.is_fine) + module->addMux(NEW_ID, new_q, ff.val_arst, ff.sig_arst, ff.sig_q); + else + module->addMuxGate(NEW_ID, new_q, ff.val_arst[0], ff.sig_arst, ff.sig_q); + } else { + if (!ff.is_fine) + module->addMux(NEW_ID, ff.val_arst, new_q, ff.sig_arst, ff.sig_q); + else + module->addMuxGate(NEW_ID, ff.val_arst[0], new_q, ff.sig_arst, ff.sig_q); + } + + ff.sig_q = new_q; + ff.has_arst = false; + ff.has_srst = true; + ff.val_srst = ff.val_arst; + ff.sig_srst = ff.sig_arst; + ff.pol_srst = ff.pol_arst; } - - Wire *new_d = module->addWire(NEW_ID, GetSize(sig_d)); - Wire *new_q = module->addWire(NEW_ID, GetSize(sig_q)); - new_q->attributes[ID::init] = init_val; - - if (!set_pol) - sig_set = module->Not(NEW_ID, sig_set); - - if (clr_pol) - sig_clr = module->Not(NEW_ID, sig_clr); - - SigSpec tmp = module->Or(NEW_ID, sig_d, sig_set); - module->addAnd(NEW_ID, tmp, sig_clr, new_d); - - tmp = module->Or(NEW_ID, new_q, sig_set); - module->addAnd(NEW_ID, tmp, sig_clr, sig_q); - - cell->setPort(ID::D, new_d); - cell->setPort(ID::Q, new_q); - cell->unsetPort(ID::SET); - cell->unsetPort(ID::CLR); - cell->unsetParam(ID::SET_POLARITY); - cell->unsetParam(ID::CLR_POLARITY); - cell->type = ID($dff); - continue; } - - if (cell->type.in(ID($dlatch))) + else { - bool en_pol = cell->parameters[ID::EN_POLARITY].as_bool(); - - SigSpec sig_en = cell->getPort(ID::EN); - SigSpec sig_d = cell->getPort(ID::D); - SigSpec sig_q = cell->getPort(ID::Q); - + // Latch. log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), - log_signal(sig_en), log_signal(sig_d), log_signal(sig_q)); - - Const init_val; - for (int i = 0; i < GetSize(sig_q); i++) { - SigBit bit = sigmap(sig_q[i]); - init_val.bits.push_back(initbits.count(bit) ? initbits.at(bit) : State::Sx); - del_initbits.insert(bit); + log_signal(ff.sig_en), log_signal(ff.sig_d), log_signal(ff.sig_q)); + + initvals.remove_init(ff.sig_q); + + Wire *new_q = module->addWire(NEW_ID, ff.width); + Wire *new_d; + + if (ff.has_d) { + new_d = module->addWire(NEW_ID, ff.width); + if (ff.pol_en) { + if (!ff.is_fine) + module->addMux(NEW_ID, new_q, ff.sig_d, ff.sig_en, new_d); + else + module->addMuxGate(NEW_ID, new_q, ff.sig_d, ff.sig_en, new_d); + } else { + if (!ff.is_fine) + module->addMux(NEW_ID, ff.sig_d, new_q, ff.sig_en, new_d); + else + module->addMuxGate(NEW_ID, ff.sig_d, new_q, ff.sig_en, new_d); + } + } else { + new_d = new_q; } - Wire *new_q = module->addWire(NEW_ID, GetSize(sig_q)); - new_q->attributes[ID::init] = init_val; - - if (en_pol) { - module->addMux(NEW_ID, new_q, sig_d, sig_en, sig_q); + if (ff.has_sr) { + SigSpec sig_set = ff.sig_set; + SigSpec sig_clr = ff.sig_clr; + + if (!ff.pol_set) { + if (!ff.is_fine) + sig_set = module->Not(NEW_ID, sig_set); + else + sig_set = module->NotGate(NEW_ID, sig_set); + } + + if (ff.pol_clr) { + if (!ff.is_fine) + sig_clr = module->Not(NEW_ID, sig_clr); + else + sig_clr = module->NotGate(NEW_ID, sig_clr); + } + + if (!ff.is_fine) { + SigSpec tmp = module->Or(NEW_ID, new_d, sig_set); + module->addAnd(NEW_ID, tmp, sig_clr, ff.sig_q); + } else { + SigSpec tmp = module->OrGate(NEW_ID, new_d, sig_set); + module->addAndGate(NEW_ID, tmp, sig_clr, ff.sig_q); + } + } else if (ff.has_arst) { + if (ff.pol_arst) { + if (!ff.is_fine) + module->addMux(NEW_ID, new_d, ff.val_arst, ff.sig_arst, ff.sig_q); + else + module->addMuxGate(NEW_ID, new_d, ff.val_arst[0], ff.sig_arst, ff.sig_q); + } else { + if (!ff.is_fine) + module->addMux(NEW_ID, ff.val_arst, new_d, ff.sig_arst, ff.sig_q); + else + module->addMuxGate(NEW_ID, ff.val_arst[0], new_d, ff.sig_arst, ff.sig_q); + } } else { - module->addMux(NEW_ID, sig_d, new_q, sig_en, sig_q); + module->connect(ff.sig_q, new_d); } - cell->setPort(ID::D, sig_q); - cell->setPort(ID::Q, new_q); - cell->unsetPort(ID::EN); - cell->unsetParam(ID::EN_POLARITY); - cell->type = ID($ff); - continue; + ff.sig_d = new_d; + ff.sig_q = new_q; + ff.has_en = false; + ff.has_arst = false; + ff.has_sr = false; + ff.has_d = true; } - } - for (auto wire : module->wires()) - if (wire->attributes.count(ID::init) > 0) - { - bool delete_initattr = true; - Const initval = wire->attributes.at(ID::init); - SigSpec initsig = sigmap(wire); - - for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++) - if (del_initbits.count(initsig[i]) > 0) - initval[i] = State::Sx; - else if (initval[i] != State::Sx) - delete_initattr = false; - - if (delete_initattr) - wire->attributes.erase(ID::init); - else - wire->attributes.at(ID::init) = initval; - } + IdString name = cell->name; + module->remove(cell); + ff.emit(module, name); + } } } } Async2syncPass; diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index 1e155e52c..cbf7c5435 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -19,13 +19,16 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/ffinit.h" +#include "kernel/ff.h" +#include "kernel/mem.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct Clk2fflogicPass : public Pass { Clk2fflogicPass() : Pass("clk2fflogic", "convert clocked FFs to generic $ff cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -36,7 +39,31 @@ struct Clk2fflogicPass : public Pass { log("multiple clocks.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + SigSpec wrap_async_control(Module *module, SigSpec sig, bool polarity) { + Wire *past_sig = module->addWire(NEW_ID, GetSize(sig)); + module->addFf(NEW_ID, sig, past_sig); + if (polarity) + sig = module->Or(NEW_ID, sig, past_sig); + else + sig = module->And(NEW_ID, sig, past_sig); + if (polarity) + return sig; + else + return module->Not(NEW_ID, sig); + } + SigSpec wrap_async_control_gate(Module *module, SigSpec sig, bool polarity) { + Wire *past_sig = module->addWire(NEW_ID); + module->addFfGate(NEW_ID, sig, past_sig); + if (polarity) + sig = module->OrGate(NEW_ID, sig, past_sig); + else + sig = module->AndGate(NEW_ID, sig, past_sig); + if (polarity) + return sig; + else + return module->NotGate(NEW_ID, sig); + } + void execute(std::vector<std::string> args, RTLIL::Design *design) override { // bool flag_noinit = false; @@ -56,348 +83,173 @@ struct Clk2fflogicPass : public Pass { for (auto module : design->selected_modules()) { SigMap sigmap(module); - dict<SigBit, State> initbits; - pool<SigBit> del_initbits; - - for (auto wire : module->wires()) - if (wire->attributes.count(ID::init) > 0) - { - Const initval = wire->attributes.at(ID::init); - SigSpec initsig = sigmap(wire); + FfInitVals initvals(&sigmap, module); - for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++) - if (initval[i] == State::S0 || initval[i] == State::S1) - initbits[initsig[i]] = initval[i]; + for (auto &mem : Mem::get_selected_memories(module)) + { + for (int i = 0; i < GetSize(mem.rd_ports); i++) { + auto &port = mem.rd_ports[i]; + if (port.clk_enable) + log_error("Read port %d of memory %s.%s is clocked. This is not supported by \"clk2fflogic\"! " + "Call \"memory\" with -nordff to avoid this error.\n", i, log_id(mem.memid), log_id(module)); } - for (auto cell : vector<Cell*>(module->selected_cells())) - { - if (cell->type.in(ID($mem))) + for (int i = 0; i < GetSize(mem.wr_ports); i++) { - int abits = cell->getParam(ID::ABITS).as_int(); - int width = cell->getParam(ID::WIDTH).as_int(); - int rd_ports = cell->getParam(ID::RD_PORTS).as_int(); - int wr_ports = cell->getParam(ID::WR_PORTS).as_int(); - - for (int i = 0; i < rd_ports; i++) { - if (cell->getParam(ID::RD_CLK_ENABLE).extract(i).as_bool()) - log_error("Read port %d of memory %s.%s is clocked. This is not supported by \"clk2fflogic\"! " - "Call \"memory\" with -nordff to avoid this error.\n", i, log_id(cell), log_id(module)); - } - - Const wr_clk_en_param = cell->getParam(ID::WR_CLK_ENABLE); - Const wr_clk_pol_param = cell->getParam(ID::WR_CLK_POLARITY); - - SigSpec wr_clk_port = cell->getPort(ID::WR_CLK); - SigSpec wr_en_port = cell->getPort(ID::WR_EN); - SigSpec wr_addr_port = cell->getPort(ID::WR_ADDR); - SigSpec wr_data_port = cell->getPort(ID::WR_DATA); - - for (int wport = 0; wport < wr_ports; wport++) - { - bool clken = wr_clk_en_param[wport] == State::S1; - bool clkpol = wr_clk_pol_param[wport] == State::S1; - - if (!clken) - continue; + auto &port = mem.wr_ports[i]; - SigBit clk = wr_clk_port[wport]; - SigSpec en = wr_en_port.extract(wport*width, width); - SigSpec addr = wr_addr_port.extract(wport*abits, abits); - SigSpec data = wr_data_port.extract(wport*width, width); - - log("Modifying write port %d on memory %s.%s: CLK=%s, A=%s, D=%s\n", - wport, log_id(module), log_id(cell), log_signal(clk), - log_signal(addr), log_signal(data)); - - Wire *past_clk = module->addWire(NEW_ID); - past_clk->attributes[ID::init] = clkpol ? State::S1 : State::S0; - module->addFf(NEW_ID, clk, past_clk); - - SigSpec clock_edge_pattern; - - if (clkpol) { - clock_edge_pattern.append(State::S0); - clock_edge_pattern.append(State::S1); - } else { - clock_edge_pattern.append(State::S1); - clock_edge_pattern.append(State::S0); - } + if (!port.clk_enable) + continue; - SigSpec clock_edge = module->Eqx(NEW_ID, {clk, SigSpec(past_clk)}, clock_edge_pattern); + log("Modifying write port %d on memory %s.%s: CLK=%s, A=%s, D=%s\n", + i, log_id(module), log_id(mem.memid), log_signal(port.clk), + log_signal(port.addr), log_signal(port.data)); - SigSpec en_q = module->addWire(NEW_ID, GetSize(en)); - module->addFf(NEW_ID, en, en_q); - - SigSpec addr_q = module->addWire(NEW_ID, GetSize(addr)); - module->addFf(NEW_ID, addr, addr_q); - - SigSpec data_q = module->addWire(NEW_ID, GetSize(data)); - module->addFf(NEW_ID, data, data_q); + Wire *past_clk = module->addWire(NEW_ID); + past_clk->attributes[ID::init] = port.clk_polarity ? State::S1 : State::S0; + module->addFf(NEW_ID, port.clk, past_clk); - wr_clk_port[wport] = State::S0; - wr_en_port.replace(wport*width, module->Mux(NEW_ID, Const(0, GetSize(en_q)), en_q, clock_edge)); - wr_addr_port.replace(wport*abits, addr_q); - wr_data_port.replace(wport*width, data_q); + SigSpec clock_edge_pattern; - wr_clk_en_param[wport] = State::S0; - wr_clk_pol_param[wport] = State::S0; + if (port.clk_polarity) { + clock_edge_pattern.append(State::S0); + clock_edge_pattern.append(State::S1); + } else { + clock_edge_pattern.append(State::S1); + clock_edge_pattern.append(State::S0); } - cell->setParam(ID::WR_CLK_ENABLE, wr_clk_en_param); - cell->setParam(ID::WR_CLK_POLARITY, wr_clk_pol_param); + SigSpec clock_edge = module->Eqx(NEW_ID, {port.clk, SigSpec(past_clk)}, clock_edge_pattern); - cell->setPort(ID::WR_CLK, wr_clk_port); - cell->setPort(ID::WR_EN, wr_en_port); - cell->setPort(ID::WR_ADDR, wr_addr_port); - cell->setPort(ID::WR_DATA, wr_data_port); - } - - if (cell->type.in(ID($dlatch), ID($dlatchsr))) - { - bool enpol = cell->parameters[ID::EN_POLARITY].as_bool(); + SigSpec en_q = module->addWire(NEW_ID, GetSize(port.en)); + module->addFf(NEW_ID, port.en, en_q); - SigSpec sig_en = cell->getPort(ID::EN); - SigSpec sig_d = cell->getPort(ID::D); - SigSpec sig_q = cell->getPort(ID::Q); + SigSpec addr_q = module->addWire(NEW_ID, GetSize(port.addr)); + module->addFf(NEW_ID, port.addr, addr_q); - log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(sig_en), log_signal(sig_d), log_signal(sig_q)); + SigSpec data_q = module->addWire(NEW_ID, GetSize(port.data)); + module->addFf(NEW_ID, port.data, data_q); - Wire *past_q = module->addWire(NEW_ID, GetSize(sig_q)); - module->addFf(NEW_ID, sig_q, past_q); + port.clk = State::S0; + port.en = module->Mux(NEW_ID, Const(0, GetSize(en_q)), en_q, clock_edge); + port.addr = addr_q; + port.data = data_q; - if (cell->type == ID($dlatch)) - { - if (enpol) - module->addMux(NEW_ID, past_q, sig_d, sig_en, sig_q); - else - module->addMux(NEW_ID, sig_d, past_q, sig_en, sig_q); - } - else - { - SigSpec t; - if (enpol) - t = module->Mux(NEW_ID, past_q, sig_d, sig_en); - else - t = module->Mux(NEW_ID, sig_d, past_q, sig_en); + port.clk_enable = false; + port.clk_polarity = false; + } - SigSpec s = cell->getPort(ID::SET); - if (!cell->parameters[ID::SET_POLARITY].as_bool()) - s = module->Not(NEW_ID, s); - t = module->Or(NEW_ID, t, s); + mem.emit(); + } - SigSpec c = cell->getPort(ID::CLR); - if (cell->parameters[ID::CLR_POLARITY].as_bool()) - c = module->Not(NEW_ID, c); - module->addAnd(NEW_ID, t, c, sig_q); - } + for (auto cell : vector<Cell*>(module->selected_cells())) + { + SigSpec qval; + if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + FfData ff(&initvals, cell); - Const initval; - bool assign_initval = false; - for (int i = 0; i < GetSize(sig_d); i++) { - SigBit qbit = sigmap(sig_q[i]); - if (initbits.count(qbit)) { - initval.bits.push_back(initbits.at(qbit)); - del_initbits.insert(qbit); - } else - initval.bits.push_back(State::Sx); - if (initval.bits.back() != State::Sx) - assign_initval = true; + if (ff.has_d && !ff.has_clk && !ff.has_en) { + // Already a $ff or $_FF_ cell. + continue; } - if (assign_initval) - past_q->attributes[ID::init] = initval; - - module->remove(cell); - continue; - } - - bool word_dff = cell->type.in(ID($dff), ID($adff), ID($dffsr)); - if (word_dff || cell->type.in(ID($_DFF_N_), ID($_DFF_P_), - ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_PP0_), ID($_DFF_PP1_), ID($_DFF_PN0_), ID($_DFF_PN1_), - ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), - ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_))) - { - bool clkpol; - SigSpec clk; - if (word_dff) { - clkpol = cell->parameters[ID::CLK_POLARITY].as_bool(); - clk = cell->getPort(ID::CLK); - } - else { - if (cell->type.in(ID($_DFF_P_), ID($_DFF_N_), - ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_PP0_), ID($_DFF_PP1_), ID($_DFF_PN0_), ID($_DFF_PN1_))) - clkpol = cell->type[6] == 'P'; - else if (cell->type.in(ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), - ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_))) - clkpol = cell->type[8] == 'P'; - else log_abort(); - clk = cell->getPort(ID::C); + Wire *past_q = module->addWire(NEW_ID, ff.width); + if (!ff.is_fine) { + module->addFf(NEW_ID, ff.sig_q, past_q); + } else { + module->addFfGate(NEW_ID, ff.sig_q, past_q); } + if (!ff.val_init.is_fully_undef()) + initvals.set_init(past_q, ff.val_init); - Wire *past_clk = module->addWire(NEW_ID); - past_clk->attributes[ID::init] = clkpol ? State::S1 : State::S0; - - if (word_dff) - module->addFf(NEW_ID, clk, past_clk); - else - module->addFfGate(NEW_ID, clk, past_clk); + if (ff.has_clk) { + ff.unmap_ce_srst(module); - SigSpec sig_d = cell->getPort(ID::D); - SigSpec sig_q = cell->getPort(ID::Q); + Wire *past_clk = module->addWire(NEW_ID); + initvals.set_init(past_clk, ff.pol_clk ? State::S1 : State::S0); - log("Replacing %s.%s (%s): CLK=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(clk), log_signal(sig_d), log_signal(sig_q)); + if (!ff.is_fine) + module->addFf(NEW_ID, ff.sig_clk, past_clk); + else + module->addFfGate(NEW_ID, ff.sig_clk, past_clk); - SigSpec clock_edge_pattern; + log("Replacing %s.%s (%s): CLK=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_clk), log_signal(ff.sig_d), log_signal(ff.sig_q)); - if (clkpol) { - clock_edge_pattern.append(State::S0); - clock_edge_pattern.append(State::S1); - } else { - clock_edge_pattern.append(State::S1); - clock_edge_pattern.append(State::S0); - } - - SigSpec clock_edge = module->Eqx(NEW_ID, {clk, SigSpec(past_clk)}, clock_edge_pattern); + SigSpec clock_edge_pattern; - Wire *past_d = module->addWire(NEW_ID, GetSize(sig_d)); - Wire *past_q = module->addWire(NEW_ID, GetSize(sig_q)); - if (word_dff) { - module->addFf(NEW_ID, sig_d, past_d); - module->addFf(NEW_ID, sig_q, past_q); - } - else { - module->addFfGate(NEW_ID, sig_d, past_d); - module->addFfGate(NEW_ID, sig_q, past_q); - } + if (ff.pol_clk) { + clock_edge_pattern.append(State::S0); + clock_edge_pattern.append(State::S1); + } else { + clock_edge_pattern.append(State::S1); + clock_edge_pattern.append(State::S0); + } - if (cell->type == ID($adff)) - { - SigSpec arst = cell->getPort(ID::ARST); - SigSpec qval = module->Mux(NEW_ID, past_q, past_d, clock_edge); - Const rstval = cell->parameters[ID::ARST_VALUE]; + SigSpec clock_edge = module->Eqx(NEW_ID, {ff.sig_clk, SigSpec(past_clk)}, clock_edge_pattern); - Wire *past_arst = module->addWire(NEW_ID); - module->addFf(NEW_ID, arst, past_arst); - if (cell->parameters[ID::ARST_POLARITY].as_bool()) - arst = module->LogicOr(NEW_ID, arst, past_arst); + Wire *past_d = module->addWire(NEW_ID, ff.width); + if (!ff.is_fine) + module->addFf(NEW_ID, ff.sig_d, past_d); else - arst = module->LogicAnd(NEW_ID, arst, past_arst); + module->addFfGate(NEW_ID, ff.sig_d, past_d); - if (cell->parameters[ID::ARST_POLARITY].as_bool()) - module->addMux(NEW_ID, qval, rstval, arst, sig_q); - else - module->addMux(NEW_ID, rstval, qval, arst, sig_q); - } - else - if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_PP0_), ID($_DFF_PP1_), ID($_DFF_PN0_), ID($_DFF_PN1_))) - { - SigSpec arst = cell->getPort(ID::R); - SigSpec qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge); - SigBit rstval = (cell->type[8] == '1'); - - Wire *past_arst = module->addWire(NEW_ID); - module->addFfGate(NEW_ID, arst, past_arst); - if (cell->type[7] == 'P') - arst = module->OrGate(NEW_ID, arst, past_arst); - else - arst = module->AndGate(NEW_ID, arst, past_arst); + if (!ff.val_init.is_fully_undef()) + initvals.set_init(past_d, ff.val_init); - if (cell->type[7] == 'P') - module->addMuxGate(NEW_ID, qval, rstval, arst, sig_q); + if (!ff.is_fine) + qval = module->Mux(NEW_ID, past_q, past_d, clock_edge); else - module->addMuxGate(NEW_ID, rstval, qval, arst, sig_q); - } - else - if (cell->type == ID($dffsr)) - { - SigSpec qval = module->Mux(NEW_ID, past_q, past_d, clock_edge); - SigSpec setval = cell->getPort(ID::SET); - SigSpec clrval = cell->getPort(ID::CLR); + qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge); + } else if (ff.has_d) { - if (!cell->parameters[ID::SET_POLARITY].as_bool()) - setval = module->Not(NEW_ID, setval); + log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_en), log_signal(ff.sig_d), log_signal(ff.sig_q)); - if (cell->parameters[ID::CLR_POLARITY].as_bool()) - clrval = module->Not(NEW_ID, clrval); + SigSpec sig_en = wrap_async_control(module, ff.sig_en, ff.pol_en); - qval = module->Or(NEW_ID, qval, setval); - module->addAnd(NEW_ID, qval, clrval, sig_q); - } - else - if (cell->type.in(ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), - ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_))) - { - SigSpec qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge); - SigSpec setval = cell->getPort(ID::S); - SigSpec clrval = cell->getPort(ID::R); - - if (cell->type[9] != 'P') - setval = module->Not(NEW_ID, setval); - - if (cell->type[10] == 'P') - clrval = module->Not(NEW_ID, clrval); + if (!ff.is_fine) + qval = module->Mux(NEW_ID, past_q, ff.sig_d, sig_en); + else + qval = module->MuxGate(NEW_ID, past_q, ff.sig_d, sig_en); + } else { - qval = module->OrGate(NEW_ID, qval, setval); - module->addAndGate(NEW_ID, qval, clrval, sig_q); - } - else if (cell->type == ID($dff)) - { - module->addMux(NEW_ID, past_q, past_d, clock_edge, sig_q); - } - else - { - module->addMuxGate(NEW_ID, past_q, past_d, clock_edge, sig_q); - } + log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); - Const initval; - bool assign_initval = false; - for (int i = 0; i < GetSize(sig_d); i++) { - SigBit qbit = sigmap(sig_q[i]); - if (initbits.count(qbit)) { - initval.bits.push_back(initbits.at(qbit)); - del_initbits.insert(qbit); - } else - initval.bits.push_back(State::Sx); - if (initval.bits.back() != State::Sx) - assign_initval = true; + qval = past_q; } - if (assign_initval) { - past_d->attributes[ID::init] = initval; - past_q->attributes[ID::init] = initval; + if (ff.has_sr) { + SigSpec setval = wrap_async_control(module, ff.sig_set, ff.pol_set); + SigSpec clrval = wrap_async_control(module, ff.sig_clr, ff.pol_clr); + if (!ff.is_fine) { + clrval = module->Not(NEW_ID, clrval); + qval = module->Or(NEW_ID, qval, setval); + module->addAnd(NEW_ID, qval, clrval, ff.sig_q); + } else { + clrval = module->NotGate(NEW_ID, clrval); + qval = module->OrGate(NEW_ID, qval, setval); + module->addAndGate(NEW_ID, qval, clrval, ff.sig_q); + } + } else if (ff.has_arst) { + SigSpec arst = wrap_async_control(module, ff.sig_arst, ff.pol_arst); + if (!ff.is_fine) + module->addMux(NEW_ID, qval, ff.val_arst, arst, ff.sig_q); + else + module->addMuxGate(NEW_ID, qval, ff.val_arst[0], arst, ff.sig_q); + } else { + module->connect(ff.sig_q, qval); } + initvals.remove_init(ff.sig_q); module->remove(cell); continue; } } - - for (auto wire : module->wires()) - if (wire->attributes.count(ID::init) > 0) - { - bool delete_initattr = true; - Const initval = wire->attributes.at(ID::init); - SigSpec initsig = sigmap(wire); - - for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++) - if (del_initbits.count(initsig[i]) > 0) - initval[i] = State::Sx; - else if (initval[i] != State::Sx) - delete_initattr = false; - - if (delete_initattr) - wire->attributes.erase(ID::init); - else - wire->attributes.at(ID::init) = initval; - } } } diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index 26cc69211..6fc267d51 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct CutpointPass : public Pass { CutpointPass() : Pass("cutpoint", "adds formal cut points to the design") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -38,7 +38,7 @@ struct CutpointPass : public Pass { log(" $anyseq cell and drive the cutpoint net from that\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool flag_undef = false; @@ -126,15 +126,16 @@ struct CutpointPass : public Pass { } vector<Wire*> rewrite_wires; - for (auto wire : module->wires()) { - if (!wire->port_input) - continue; - int bit_count = 0; - for (auto &bit : sigmap(wire)) - if (cutpoint_bits.count(bit)) - bit_count++; - if (bit_count) - rewrite_wires.push_back(wire); + for (auto id : module->ports) { + RTLIL::Wire *wire = module->wire(id); + if (wire->port_input) { + int bit_count = 0; + for (auto &bit : sigmap(wire)) + if (cutpoint_bits.count(bit)) + bit_count++; + if (bit_count) + rewrite_wires.push_back(wire); + } } for (auto wire : rewrite_wires) { diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index f910ea80d..085e7c5b8 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -359,7 +359,7 @@ struct VlogHammerReporter struct EvalPass : public Pass { EvalPass() : Pass("eval", "evaluate the circuit given an input") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -382,7 +382,7 @@ struct EvalPass : public Pass { log(" then all output ports of the current module are used.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::vector<std::pair<std::string, std::string>> sets; std::vector<std::string> shows, tables; diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 80ab82cd5..2c65821cf 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -217,7 +217,7 @@ RTLIL::Wire *add_new_wire(RTLIL::Module *module, RTLIL::IdString name, int width struct ExposePass : public Pass { ExposePass() : Pass("expose", "convert internal signals to module ports") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -254,7 +254,7 @@ struct ExposePass : public Pass { log(" designator for the exposed signal.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool flag_shared = false; bool flag_evert = false; @@ -281,11 +281,15 @@ struct ExposePass : public Pass { flag_dff = true; continue; } - if (args[argidx] == "-cut" && !flag_input) { + if (args[argidx] == "-cut") { + if (flag_input) + log_cmd_error("Options -cut and -input are mutually exclusive.\n"); flag_cut = true; continue; } - if (args[argidx] == "-input" && !flag_cut) { + if (args[argidx] == "-input") { + if (flag_cut) + log_cmd_error("Options -cut and -input are mutually exclusive.\n"); flag_input = true; continue; } @@ -445,6 +449,8 @@ struct ExposePass : public Pass { SigMap out_to_in_map; + std::map<RTLIL::Wire*, RTLIL::IdString> wire_map; + for (auto w : module->wires()) { if (flag_shared) { @@ -462,8 +468,7 @@ struct ExposePass : public Pass { if (!w->port_input) { w->port_input = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name)); - RTLIL::Wire *in_wire = module->addWire(NEW_ID, GetSize(w)); - out_to_in_map.add(w, in_wire); + wire_map[w] = NEW_ID; } } else @@ -474,15 +479,19 @@ struct ExposePass : public Pass { } if (flag_cut) { - RTLIL::Wire *in_wire = add_new_wire(module, w->name.str() + sep + "i", w->width); - in_wire->port_input = true; - out_to_in_map.add(sigmap(w), in_wire); + wire_map[w] = w->name.str() + sep + "i"; } } } if (flag_input) { + for (auto &wm : wire_map) + { + RTLIL::Wire *in_wire = module->addWire(wm.second, GetSize(wm.first)); + out_to_in_map.add(wm.first, in_wire); + } + for (auto cell : module->cells()) { if (!ct.cell_known(cell->type)) continue; @@ -497,6 +506,13 @@ struct ExposePass : public Pass { if (flag_cut) { + for (auto &wm : wire_map) + { + RTLIL::Wire *in_wire = add_new_wire(module, wm.second, wm.first->width); + in_wire->port_input = true; + out_to_in_map.add(sigmap(wm.first), in_wire); + } + for (auto cell : module->cells()) { if (!ct.cell_known(cell->type)) continue; diff --git a/passes/sat/fmcombine.cc b/passes/sat/fmcombine.cc index 5066485aa..cb49edac3 100644 --- a/passes/sat/fmcombine.cc +++ b/passes/sat/fmcombine.cc @@ -114,8 +114,7 @@ struct FmcombineWorker Cell *gold = import_prim_cell(cell, "_gold"); Cell *gate = import_prim_cell(cell, "_gate"); if (opts.initeq) { - if (cell->type.in(ID($ff), ID($dff), ID($dffe), - ID($dffsr), ID($adff), ID($dlatch), ID($dlatchsr))) { + if (RTLIL::builtin_ff_cell_types().count(cell->type)) { SigSpec gold_q = gold->getPort(ID::Q); SigSpec gate_q = gate->getPort(ID::Q); SigSpec en = module->Initstate(NEW_ID); @@ -235,7 +234,7 @@ struct FmcombineWorker struct FmcombinePass : public Pass { FmcombinePass() : Pass("fmcombine", "combine two instances of a cell into one") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -272,7 +271,7 @@ struct FmcombinePass : public Pass { log("If none of -fwd, -bwd, and -nop is given, then -fwd is used as default.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { opts_t opts; Module *module = nullptr; diff --git a/passes/sat/fminit.cc b/passes/sat/fminit.cc index 555a28dc6..c72e62548 100644 --- a/passes/sat/fminit.cc +++ b/passes/sat/fminit.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct FminitPass : public Pass { FminitPass() : Pass("fminit", "set init values/sequences for formal") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -47,7 +47,7 @@ struct FminitPass : public Pass { log(" Set clock for init sequences\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { vector<pair<string, vector<string>>> initdata; vector<pair<string, string>> setdata; diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 5dfd7bd3f..762edfdfb 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -760,7 +760,7 @@ struct FreduceWorker struct FreducePass : public Pass { FreducePass() : Pass("freduce", "perform functional reduction") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -791,7 +791,7 @@ struct FreducePass : public Pass { log("circuit that is analyzed.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { reduce_counter = 0; reduce_stop_at = 0; diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index aeece9b94..fe4a819f3 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -354,7 +354,7 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL struct MiterPass : public Pass { MiterPass() : Pass("miter", "automatically create a miter circuit") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -398,7 +398,7 @@ struct MiterPass : public Pass { log(" call 'flatten -wb; opt_expr -keepdc -undriven;;' on the miter circuit.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { if (args.size() > 1 && args[1] == "-equiv") { create_miter_equiv(this, args, design); diff --git a/passes/sat/mutate.cc b/passes/sat/mutate.cc index af8ffca9e..95e0e0944 100644 --- a/passes/sat/mutate.cc +++ b/passes/sat/mutate.cc @@ -439,7 +439,7 @@ void mutate_list(Design *design, const mutate_opts_t &opts, const string &filena dict<SigBit, int> bit_user_cnt; for (auto wire : module->wires()) { - if (wire->name[0] == '\\' && wire->attributes.count(ID::src)) + if (wire->name.isPublic() && wire->attributes.count(ID::src)) sigmap.add(wire); } @@ -468,7 +468,7 @@ void mutate_list(Design *design, const mutate_opts_t &opts, const string &filena } if (!bit.wire->name[0] != !sigbit.wire->name[0]) { - if (bit.wire->name[0] == '\\') + if (bit.wire->name.isPublic()) sigmap.add(bit); continue; } @@ -493,7 +493,7 @@ void mutate_list(Design *design, const mutate_opts_t &opts, const string &filena entry.src.insert(s); SigBit bit = sigmap(conn.second[i]); - if (bit.wire && bit.wire->name[0] == '\\' && (cell->output(conn.first) || bit_user_cnt[bit] == 1)) { + if (bit.wire && bit.wire->name.isPublic() && (cell->output(conn.first) || bit_user_cnt[bit] == 1)) { for (auto &s : bit.wire->get_strpool_attribute(ID::src)) entry.src.insert(s); entry.wire = bit.wire->name; @@ -726,7 +726,7 @@ void mutate_cnot(Design *design, const mutate_opts_t &opts, bool one) struct MutatePass : public Pass { MutatePass() : Pass("mutate", "generate or apply design mutations") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -790,7 +790,7 @@ struct MutatePass : public Pass { log(" Ignored. (They are generated by -list for documentation purposes.)\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { mutate_opts_t opts; string filename; diff --git a/passes/sat/qbfsat.cc b/passes/sat/qbfsat.cc index d6dbf8ef4..6db7d4b64 100644 --- a/passes/sat/qbfsat.cc +++ b/passes/sat/qbfsat.cc @@ -1,4 +1,4 @@ -/* +/* -*- c++ -*- * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2020 Alberto Gonzalez <boqwxp@airmail.cc> @@ -18,137 +18,20 @@ */ #include "kernel/yosys.h" -#include "kernel/celltypes.h" #include "kernel/consteval.h" -#include "kernel/log.h" -#include "kernel/rtlil.h" -#include "kernel/register.h" -#include <algorithm> +#include "qbfsat.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -struct QbfSolutionType { - std::vector<std::string> stdout_lines; - dict<std::string, std::string> hole_to_value; - bool sat; - bool unknown; //true if neither 'sat' nor 'unsat' - - QbfSolutionType() : sat(false), unknown(true) {} -}; - -struct QbfSolveOptions { - bool specialize, specialize_from_file, write_solution, nocleanup, dump_final_smt2, assume_outputs, assume_neg; - bool nooptimize, nobisection; - bool sat, unsat, show_smtbmc; - enum Solver{Z3, Yices, CVC4} solver; - int timeout; - std::string specialize_soln_file; - std::string write_soln_soln_file; - std::string dump_final_smt2_file; - size_t argidx; - QbfSolveOptions() : specialize(false), specialize_from_file(false), write_solution(false), - nocleanup(false), dump_final_smt2(false), assume_outputs(false), assume_neg(false), - nooptimize(false), nobisection(false), sat(false), unsat(false), show_smtbmc(false), - solver(Yices), timeout(0), argidx(0) {}; -}; - -std::string get_solver_name(const QbfSolveOptions &opt) { - if (opt.solver == opt.Solver::Z3) - return "z3"; - else if (opt.solver == opt.Solver::Yices) - return "yices"; - else if (opt.solver == opt.Solver::CVC4) - return "cvc4"; +static inline unsigned int difference(unsigned int a, unsigned int b) { + if (a < b) + return b - a; else - log_cmd_error("unknown solver specified.\n"); - return ""; + return a - b; } -void recover_solution(QbfSolutionType &sol) { - YS_REGEX_TYPE sat_regex = YS_REGEX_COMPILE("Status: PASSED"); - YS_REGEX_TYPE unsat_regex = YS_REGEX_COMPILE("Solver Error.*model is not available"); - YS_REGEX_TYPE unsat_regex2 = YS_REGEX_COMPILE("Status: FAILED"); - YS_REGEX_TYPE timeout_regex = YS_REGEX_COMPILE("No solution found! \\(timeout\\)"); - YS_REGEX_TYPE timeout_regex2 = YS_REGEX_COMPILE("No solution found! \\(interrupted\\)"); - YS_REGEX_TYPE unknown_regex = YS_REGEX_COMPILE("No solution found! \\(unknown\\)"); - YS_REGEX_TYPE unknown_regex2 = YS_REGEX_COMPILE("Unexpected EOF response from solver"); - YS_REGEX_TYPE memout_regex = YS_REGEX_COMPILE("Solver Error:.*error \"out of memory\""); - YS_REGEX_TYPE hole_value_regex = YS_REGEX_COMPILE_WITH_SUBS("Value for anyconst in [a-zA-Z0-9_]* \\(([^:]*:[^\\)]*)\\): (.*)"); -#ifndef NDEBUG - YS_REGEX_TYPE hole_loc_regex = YS_REGEX_COMPILE("[^:]*:[0-9]+.[0-9]+-[0-9]+.[0-9]+"); - YS_REGEX_TYPE hole_val_regex = YS_REGEX_COMPILE("[0-9]+"); -#endif - YS_REGEX_MATCH_TYPE m; - bool sat_regex_found = false; - bool unsat_regex_found = false; - dict<std::string, bool> hole_value_recovered; - for (const std::string &x : sol.stdout_lines) { - if(YS_REGEX_NS::regex_search(x, m, hole_value_regex)) { - std::string loc = m[1].str(); - std::string val = m[2].str(); -#ifndef NDEBUG - log_assert(YS_REGEX_NS::regex_search(loc, hole_loc_regex)); - log_assert(YS_REGEX_NS::regex_search(val, hole_val_regex)); -#endif - sol.hole_to_value[loc] = val; - } - else if (YS_REGEX_NS::regex_search(x, sat_regex)) { - sat_regex_found = true; - sol.sat = true; - sol.unknown = false; - } - else if (YS_REGEX_NS::regex_search(x, unsat_regex)) { - unsat_regex_found = true; - sol.sat = false; - sol.unknown = false; - } - else if (YS_REGEX_NS::regex_search(x, memout_regex)) { - sol.unknown = true; - log_warning("solver ran out of memory\n"); - } - else if (YS_REGEX_NS::regex_search(x, timeout_regex)) { - sol.unknown = true; - log_warning("solver timed out\n"); - } - else if (YS_REGEX_NS::regex_search(x, timeout_regex2)) { - sol.unknown = true; - log_warning("solver timed out\n"); - } - else if (YS_REGEX_NS::regex_search(x, unknown_regex)) { - sol.unknown = true; - log_warning("solver returned \"unknown\"\n"); - } - else if (YS_REGEX_NS::regex_search(x, unsat_regex2)) { - unsat_regex_found = true; - sol.sat = false; - sol.unknown = false; - } - else if (YS_REGEX_NS::regex_search(x, unknown_regex2)) { - sol.unknown = true; - } - } -#ifndef NDEBUG - log_assert(!sol.unknown && sol.sat? sat_regex_found : true); - log_assert(!sol.unknown && !sol.sat? unsat_regex_found : true); -#endif -} - -dict<std::string, std::string> get_hole_loc_name_map(RTLIL::Module *module, const QbfSolutionType &sol) { - dict<std::string, std::string> hole_loc_to_name; - for (auto cell : module->cells()) { - std::string cell_src = cell->get_src_attribute(); - auto pos = sol.hole_to_value.find(cell_src); - if (pos != sol.hole_to_value.end() && cell->type.in("$anyconst", "$anyseq")) { - log_assert(hole_loc_to_name.find(pos->first) == hole_loc_to_name.end()); - hole_loc_to_name[pos->first] = cell->getPort(ID::Y).as_wire()->name.str(); - } - } - - return hole_loc_to_name; -} - -pool<std::string> validate_design_and_get_inputs(RTLIL::Module *module, const QbfSolveOptions &opt) { +pool<std::string> validate_design_and_get_inputs(RTLIL::Module *module, bool assume_outputs) { bool found_input = false; bool found_hole = false; bool found_1bit_output = false; @@ -176,133 +59,108 @@ pool<std::string> validate_design_and_get_inputs(RTLIL::Module *module, const Qb log_cmd_error("Did not find any existentially-quantified variables. Use 'sat' instead.\n"); if (!found_1bit_output && !found_assert_assume) log_cmd_error("Did not find any single-bit outputs or $assert/$assume cells. Is this a miter circuit?\n"); - if (!found_assert_assume && !opt.assume_outputs) + if (!found_assert_assume && !assume_outputs) log_cmd_error("Did not find any $assert/$assume cells. Single-bit outputs were found, but `-assume-outputs` was not specified.\n"); return input_wires; } -void write_solution(RTLIL::Module *module, const QbfSolutionType &sol, const std::string &file) { - std::ofstream fout(file.c_str()); - if (!fout) - log_cmd_error("could not open solution file for writing.\n"); +void specialize_from_file(RTLIL::Module *module, const std::string &file) { + YS_REGEX_TYPE hole_bit_assn_regex = YS_REGEX_COMPILE_WITH_SUBS("^(.+) ([0-9]+) ([^ ]+) \\[([0-9]+)] = ([01])$"); + YS_REGEX_TYPE hole_assn_regex = YS_REGEX_COMPILE_WITH_SUBS("^(.+) ([0-9]+) ([^ ]+) = ([01])$"); //if no index specified + YS_REGEX_MATCH_TYPE bit_m, m; + dict<pool<std::string>, RTLIL::Cell*> anyconst_loc_to_cell; + dict<RTLIL::SigBit, RTLIL::State> hole_assignments; - dict<std::string, std::string> hole_loc_to_name = get_hole_loc_name_map(module, sol); - for(auto &x : sol.hole_to_value) - fout << hole_loc_to_name[x.first] << "=" << x.second << std::endl; -} + for (auto cell : module->cells()) + if (cell->type == "$anyconst") + anyconst_loc_to_cell[cell->get_strpool_attribute(ID::src)] = cell; -void specialize_from_file(RTLIL::Module *module, const std::string &file) { - YS_REGEX_TYPE hole_assn_regex = YS_REGEX_COMPILE_WITH_SUBS("^(.*)=([01]+)$"); - YS_REGEX_MATCH_TYPE m; - pool<RTLIL::Cell *> anyconsts_to_remove; - dict<std::string, std::string> hole_name_to_value; std::ifstream fin(file.c_str()); if (!fin) log_cmd_error("could not read solution file.\n"); std::string buf; while (std::getline(fin, buf)) { - log_assert(YS_REGEX_NS::regex_search(buf, m, hole_assn_regex)); - std::string hole_name = m[1].str(); - std::string hole_value = m[2].str(); - hole_name_to_value[hole_name] = hole_value; + bool bit_assn = true; + if (!YS_REGEX_NS::regex_search(buf, bit_m, hole_bit_assn_regex)) { + bit_assn = false; + if (!YS_REGEX_NS::regex_search(buf, m, hole_assn_regex)) + log_cmd_error("solution file is not formatted correctly: \"%s\"\n", buf.c_str()); + } + + std::string hole_loc = bit_assn? bit_m[1].str() : m[1].str(); + unsigned int hole_bit = bit_assn? atoi(bit_m[2].str().c_str()) : atoi(m[2].str().c_str()); + std::string hole_name = bit_assn? bit_m[3].str() : m[3].str(); + unsigned int hole_offset = bit_assn? atoi(bit_m[4].str().c_str()) : 0; + RTLIL::State hole_value = bit_assn? (atoi(bit_m[5].str().c_str()) == 1? RTLIL::State::S1 : RTLIL::State::S0) + : (atoi(m[4].str().c_str()) == 1? RTLIL::State::S1 : RTLIL::State::S0); + + //We have two options to identify holes. First, try to match wire names. If we can't find a matching wire, + //then try to find a cell with a matching location. + RTLIL::SigBit hole_sigbit; + if (module->wire(hole_name) != nullptr) { + RTLIL::Wire *hole_wire = module->wire(hole_name); + hole_sigbit = RTLIL::SigSpec(hole_wire)[hole_offset]; + } else { + auto locs = split_tokens(hole_loc, "|"); + pool<std::string> hole_loc_pool(locs.begin(), locs.end()); + auto hole_cell_it = anyconst_loc_to_cell.find(hole_loc_pool); + if (hole_cell_it == anyconst_loc_to_cell.end()) + log_cmd_error("cannot find matching wire name or $anyconst cell location for hole spec \"%s\"\n", buf.c_str()); + + RTLIL::Cell *hole_cell = hole_cell_it->second; + hole_sigbit = hole_cell->getPort(ID::Y)[hole_bit]; + } + hole_assignments[hole_sigbit] = hole_value; } - for (auto cell : module->cells()) - if (cell->type == "$anyconst") { - auto anyconst_port_y = cell->getPort(ID::Y).as_wire(); - if (anyconst_port_y == nullptr) - continue; - if (hole_name_to_value.find(anyconst_port_y->name.str()) != hole_name_to_value.end()) - anyconsts_to_remove.insert(cell); - } - for (auto cell : anyconsts_to_remove) - module->remove(cell); + for (auto &it : anyconst_loc_to_cell) + module->remove(it.second); - for (auto &it : hole_name_to_value) { - std::string hole_name = it.first; - std::string hole_value = it.second; - RTLIL::Wire *wire = module->wire(hole_name); -#ifndef NDEBUG - log_assert(wire != nullptr); - log_assert(wire->width > 0 && GetSize(hole_value) == wire->width); -#endif - - log("Specializing %s from file with %s = %d'b%s.\n", module->name.c_str(), hole_name.c_str(), wire->width, hole_value.c_str()); - std::vector<RTLIL::SigBit> value_bv; - value_bv.reserve(wire->width); - for (char c : hole_value) - value_bv.emplace_back(c == '1'? RTLIL::S1 : RTLIL::S0); - std::reverse(value_bv.begin(), value_bv.end()); - module->connect(wire, value_bv); + for (auto &it : hole_assignments) { + RTLIL::SigSpec lhs(it.first); + RTLIL::SigSpec rhs(it.second); + log("Specializing %s from file with %s = %d.\n", module->name.c_str(), log_signal(it.first), it.second == RTLIL::State::S1? 1 : 0); + module->connect(lhs, rhs); } } void specialize(RTLIL::Module *module, const QbfSolutionType &sol, bool quiet = false) { - dict<std::string, std::string> hole_loc_to_name = get_hole_loc_name_map(module, sol); + auto hole_loc_idx_to_sigbit = sol.get_hole_loc_idx_sigbit_map(module); pool<RTLIL::Cell *> anyconsts_to_remove; for (auto cell : module->cells()) if (cell->type == "$anyconst") - if (hole_loc_to_name.find(cell->get_src_attribute()) != hole_loc_to_name.end()) + if (hole_loc_idx_to_sigbit.find(std::make_pair(cell->get_strpool_attribute(ID::src), 0)) != hole_loc_idx_to_sigbit.end()) anyconsts_to_remove.insert(cell); for (auto cell : anyconsts_to_remove) module->remove(cell); for (auto &it : sol.hole_to_value) { - std::string hole_loc = it.first; - std::string hole_value = it.second; - -#ifndef NDEBUG - auto pos = hole_loc_to_name.find(hole_loc); - log_assert(pos != hole_loc_to_name.end()); -#endif - - std::string hole_name = hole_loc_to_name[hole_loc]; - RTLIL::Wire *wire = module->wire(hole_name); -#ifndef NDEBUG - log_assert(wire != nullptr); - log_assert(wire->width > 0 && GetSize(hole_value) == wire->width); -#endif - - if (!quiet) - log("Specializing %s with %s = %d'b%s.\n", module->name.c_str(), hole_name.c_str(), wire->width, hole_value.c_str()); - std::vector<RTLIL::SigBit> value_bv; - value_bv.reserve(wire->width); - for (char c : hole_value) - value_bv.emplace_back(c == '1'? RTLIL::S1 : RTLIL::S0); - std::reverse(value_bv.begin(), value_bv.end()); - module->connect(wire, value_bv); - } -} - -void dump_model(RTLIL::Module *module, const QbfSolutionType &sol) { - log("Satisfiable model:\n"); - dict<std::string, std::string> hole_loc_to_name = get_hole_loc_name_map(module, sol); - for (auto &it : sol.hole_to_value) { - std::string hole_loc = it.first; + pool<std::string> hole_loc = it.first; std::string hole_value = it.second; -#ifndef NDEBUG - auto pos = hole_loc_to_name.find(hole_loc); - log_assert(pos != hole_loc_to_name.end()); -#endif - - std::string hole_name = hole_loc_to_name[hole_loc]; - log("\t%s = %lu'b%s\n", hole_name.c_str(), hole_value.size(), hole_value.c_str()); - std::vector<RTLIL::SigBit> value_bv; - value_bv.reserve(hole_value.size()); - for (char c : hole_value) - value_bv.emplace_back(c == '1'? RTLIL::S1 : RTLIL::S0); - std::reverse(value_bv.begin(), value_bv.end()); + for (unsigned int i = 0; i < hole_value.size(); ++i) { + int bit_idx = GetSize(hole_value) - 1 - i; + auto it = hole_loc_idx_to_sigbit.find(std::make_pair(hole_loc, i)); + log_assert(it != hole_loc_idx_to_sigbit.end()); + + RTLIL::SigBit hole_sigbit = it->second; + log_assert(hole_sigbit.wire != nullptr); + log_assert(hole_value[bit_idx] == '0' || hole_value[bit_idx] == '1'); + RTLIL::SigSpec lhs(hole_sigbit.wire, hole_sigbit.offset, 1); + RTLIL::State hole_bit_val = hole_value[bit_idx] == '1'? RTLIL::State::S1 : RTLIL::State::S0; + if (!quiet) + log("Specializing %s with %s = %d.\n", module->name.c_str(), log_signal(hole_sigbit), hole_bit_val == RTLIL::State::S0? 0 : 1) +; + module->connect(lhs, hole_bit_val); + } } } void allconstify_inputs(RTLIL::Module *module, const pool<std::string> &input_wires) { for (auto &n : input_wires) { RTLIL::Wire *input = module->wire(n); -#ifndef NDEBUG log_assert(input != nullptr); -#endif RTLIL::Cell *allconst = module->addCell("$allconst$" + n, "$allconst"); allconst->setParam(ID(WIDTH), input->width); @@ -314,7 +172,7 @@ void allconstify_inputs(RTLIL::Module *module, const pool<std::string> &input_wi module->fixup_ports(); } -void assume_miter_outputs(RTLIL::Module *module, const QbfSolveOptions &opt) { +void assume_miter_outputs(RTLIL::Module *module, bool assume_neg) { std::vector<RTLIL::Wire *> wires_to_assume; for (auto w : module->wires()) if (w->port_output && w->width == 1) @@ -329,7 +187,7 @@ void assume_miter_outputs(RTLIL::Module *module, const QbfSolveOptions &opt) { log("\n"); } - if (opt.assume_neg) { + if (assume_neg) { for (unsigned int i = 0; i < wires_to_assume.size(); ++i) { RTLIL::SigSpec n_wire = module->LogicNot(wires_to_assume[i]->name.str() + "__n__qbfsat", wires_to_assume[i], false, wires_to_assume[i]->get_src_attribute()); wires_to_assume[i] = n_wire.as_wire(); @@ -349,9 +207,7 @@ void assume_miter_outputs(RTLIL::Module *module, const QbfSolveOptions &opt) { wires_to_assume.swap(buf); } -#ifndef NDEBUG log_assert(wires_to_assume.size() == 1); -#endif module->addAssume("$assume_qbfsat_miter_outputs", wires_to_assume[0], RTLIL::S1); } @@ -359,10 +215,17 @@ QbfSolutionType call_qbf_solver(RTLIL::Module *mod, const QbfSolveOptions &opt, //Execute and capture stdout from `yosys-smtbmc -s z3 -t 1 -g --binary [--dump-smt2 <file>]` QbfSolutionType ret; const std::string yosys_smtbmc_exe = proc_self_dirname() + "yosys-smtbmc"; - const std::string smt2_command = "write_smt2 -stbv -wires " + tempdir_name + "/problem" + (iter_num != 0? stringf("%d", iter_num) : "") + ".smt2"; const std::string smtbmc_warning = "z3: WARNING:"; - const std::string smtbmc_cmd = yosys_smtbmc_exe + " -s " + (get_solver_name(opt)) + (opt.timeout != 0? stringf(" --timeout %d", opt.timeout) : "") + " -t 1 -g --binary " + (opt.dump_final_smt2? "--dump-smt2 " + opt.dump_final_smt2_file + " " : "") + tempdir_name + "/problem" + (iter_num != 0? stringf("%d", iter_num) : "") + ".smt2 2>&1"; - + const std::string smtbmc_cmd = stringf("%s -s %s %s -t 1 -g --binary %s %s/problem%d.smt2 2>&1", + yosys_smtbmc_exe.c_str(), opt.get_solver_name().c_str(), + (opt.timeout != 0? stringf("--timeout %d", opt.timeout) : "").c_str(), + (opt.dump_final_smt2? "--dump-smt2 " + opt.dump_final_smt2_file : "").c_str(), + tempdir_name.c_str(), iter_num); + + std::string smt2_command = "write_smt2 -stbv -wires "; + for (auto &solver_opt : opt.solver_options) + smt2_command += stringf("-solver-option %s %s ", solver_opt.first.c_str(), solver_opt.second.c_str()); + smt2_command += stringf("%s/problem%d.smt2", tempdir_name.c_str(), iter_num); Pass::call(mod->design, smt2_command); auto process_line = [&ret, &smtbmc_warning, &opt, &quiet](const std::string &line) { @@ -376,45 +239,59 @@ QbfSolutionType call_qbf_solver(RTLIL::Module *mod, const QbfSolveOptions &opt, }; log_header(mod->design, "Solving QBF-SAT problem.\n"); if (!quiet) log("Launching \"%s\".\n", smtbmc_cmd.c_str()); + int64_t begin = PerformanceTimer::query(); run_command(smtbmc_cmd, process_line); + int64_t end = PerformanceTimer::query(); + ret.solver_time = (end - begin) / 1e9f; + if (!quiet) log("Solver finished in %.3f seconds.\n", ret.solver_time); - recover_solution(ret); + ret.recover_solution(); return ret; } QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) { QbfSolutionType ret, best_soln; - const std::string tempdir_name = make_temp_dir("/tmp/yosys-z3-XXXXXX"); + const std::string tempdir_name = make_temp_dir("/tmp/yosys-qbfsat-XXXXXX"); RTLIL::Module *module = mod; RTLIL::Design *design = module->design; std::string module_name = module->name.str(); - RTLIL::Wire *wire_to_optimize = nullptr; - RTLIL::IdString wire_to_optimize_name; + RTLIL::IdString wire_to_optimize_name = ""; bool maximize = false; log_assert(module->design != nullptr); Pass::call(design, "design -push-copy"); //Replace input wires with wires assigned $allconst cells: - pool<std::string> input_wires = validate_design_and_get_inputs(module, opt); + pool<std::string> input_wires = validate_design_and_get_inputs(module, opt.assume_outputs); allconstify_inputs(module, input_wires); if (opt.assume_outputs) - assume_miter_outputs(module, opt); + assume_miter_outputs(module, opt.assume_neg); //Find the wire to be optimized, if any: - for (auto wire : module->wires()) - if (wire->get_bool_attribute("\\maximize") || wire->get_bool_attribute("\\minimize")) - wire_to_optimize = wire; - if (wire_to_optimize != nullptr) { - wire_to_optimize_name = wire_to_optimize->name; - maximize = wire_to_optimize->get_bool_attribute("\\maximize"); + for (auto wire : module->wires()) { + if (wire->get_bool_attribute("\\maximize") || wire->get_bool_attribute("\\minimize")) { + wire_to_optimize_name = wire->name; + maximize = wire->get_bool_attribute("\\maximize"); + if (opt.nooptimize) { + if (maximize) + wire->set_bool_attribute("\\maximize", false); + else + wire->set_bool_attribute("\\minimize", false); + } + } } - if (opt.nobisection || opt.nooptimize) { - if (wire_to_optimize != nullptr && opt.nooptimize) { - wire_to_optimize->set_bool_attribute("\\maximize", false); - wire_to_optimize->set_bool_attribute("\\minimize", false); - } + //If -O1 or -O2 was specified, use ABC to simplify the problem: + if (opt.oflag == opt.OptimizationLevel::O1) + Pass::call(module->design, "abc -g AND,NAND,OR,NOR,XOR,XNOR,MUX,NMUX -script +print_stats;strash;print_stats;drwsat;print_stats;fraig;print_stats;refactor,-N,10,-lz;print_stats;&get,-n;&dch,-pem;&nf;&put " + mod->name.str()); + else if (opt.oflag == opt.OptimizationLevel::O2) + Pass::call(module->design, "abc -g AND,NAND,OR,NOR,XOR,XNOR,MUX,NMUX -script +print_stats;strash;print_stats;drwsat;print_stats;dch,-S,1000000,-C,100000,-p;print_stats;fraig;print_stats;refactor,-N,15,-lz;print_stats;dc2,-pbl;print_stats;drwsat;print_stats;&get,-n;&dch,-pem;&nf;&put " + mod->name.str()); + if (opt.oflag != opt.OptimizationLevel::O0) { + Pass::call(module->design, "techmap"); + Pass::call(module->design, "opt"); + } + + if (opt.nobisection || opt.nooptimize || wire_to_optimize_name == "") { ret = call_qbf_solver(module, opt, tempdir_name, false, 0); } else { //Do the iterated bisection method: @@ -423,11 +300,12 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) { unsigned int failure = 0; unsigned int cur_thresh = 0; - log_assert(wire_to_optimize != nullptr); - log("%s wire \"%s\".\n", (maximize? "Maximizing" : "Minimizing"), log_signal(wire_to_optimize)); + log_assert(wire_to_optimize_name != ""); + log_assert(module->wire(wire_to_optimize_name) != nullptr); + log("%s wire \"%s\".\n", (maximize? "Maximizing" : "Minimizing"), wire_to_optimize_name.c_str()); //If maximizing, grow until we get a failure. Then bisect success and failure. - while (failure == 0 || success - failure > 1) { + while (failure == 0 || difference(success, failure) > 1) { Pass::call(design, "design -push-copy"); log_header(design, "Preparing QBF-SAT problem.\n"); @@ -465,8 +343,9 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) { //sometimes this happens if we get an 'unknown' or timeout if (!maximize && success < failure) break; - else if (maximize && success > failure) + else if (maximize && failure != 0 && success > failure) break; + } else { //Treat 'unknown' as UNSAT failure = cur_thresh; @@ -479,8 +358,12 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) { } iter_num++; - cur_thresh = (maximize && failure == 0)? 2 * success //growth - : (success + failure) / 2; //bisection + if (maximize && failure == 0 && success == 0) + cur_thresh = 2; + else if (maximize && failure == 0) + cur_thresh = 2 * success; //growth + else //if (!maximize || failure != 0) + cur_thresh = (success + failure) / 2; //bisection } if (success != 0 || failure != 0) { log("Wire %s is %s at %d.\n", wire_to_optimize_name.c_str(), (maximize? "maximized" : "minimized"), success); @@ -539,6 +422,13 @@ QbfSolveOptions parse_args(const std::vector<std::string> &args) { } continue; } + else if (args[opt.argidx] == "-solver-option") { + if (args.size() <= opt.argidx + 2) + log_cmd_error("solver option name and value not fully specified.\n"); + opt.solver_options.emplace(args[opt.argidx+1], args[opt.argidx+2]); + opt.argidx += 2; + continue; + } else if (args[opt.argidx] == "-timeout") { if (args.size() <= opt.argidx + 1) log_cmd_error("timeout not specified.\n"); @@ -552,6 +442,22 @@ QbfSolveOptions parse_args(const std::vector<std::string> &args) { } continue; } + else if (args[opt.argidx].substr(0, 2) == "-O" && args[opt.argidx].size() == 3) { + switch (args[opt.argidx][2]) { + case '0': + opt.oflag = opt.OptimizationLevel::O0; + break; + case '1': + opt.oflag = opt.OptimizationLevel::O1; + break; + case '2': + opt.oflag = opt.OptimizationLevel::O2; + break; + default: + log_cmd_error("unknown argument %s\n", args[opt.argidx].c_str()); + } + continue; + } else if (args[opt.argidx] == "-sat") { opt.sat = true; continue; @@ -594,36 +500,9 @@ QbfSolveOptions parse_args(const std::vector<std::string> &args) { return opt; } -void print_proof_failed() -{ - log("\n"); - log(" ______ ___ ___ _ _ _ _ \n"); - log(" (_____ \\ / __) / __) (_) | | | |\n"); - log(" _____) )___ ___ ___ _| |__ _| |__ _____ _| | _____ __| | |\n"); - log(" | ____/ ___) _ \\ / _ (_ __) (_ __|____ | | || ___ |/ _ |_|\n"); - log(" | | | | | |_| | |_| || | | | / ___ | | || ____( (_| |_ \n"); - log(" |_| |_| \\___/ \\___/ |_| |_| \\_____|_|\\_)_____)\\____|_|\n"); - log("\n"); -} - -void print_qed() -{ - log("\n"); - log(" /$$$$$$ /$$$$$$$$ /$$$$$$$ \n"); - log(" /$$__ $$ | $$_____/ | $$__ $$ \n"); - log(" | $$ \\ $$ | $$ | $$ \\ $$ \n"); - log(" | $$ | $$ | $$$$$ | $$ | $$ \n"); - log(" | $$ | $$ | $$__/ | $$ | $$ \n"); - log(" | $$/$$ $$ | $$ | $$ | $$ \n"); - log(" | $$$$$$/ /$$| $$$$$$$$ /$$| $$$$$$$//$$\n"); - log(" \\____ $$$|__/|________/|__/|_______/|__/\n"); - log(" \\__/ \n"); - log("\n"); -} - struct QbfSatPass : public Pass { QbfSatPass() : Pass("qbfsat", "solve a 2QBF-SAT problem in the circuit") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -662,9 +541,17 @@ struct QbfSatPass : public Pass { log("\n"); log(" -solver <solver>\n"); log(" Use a particular solver. Choose one of: \"z3\", \"yices\", and \"cvc4\".\n"); + log(" (default: yices)\n"); + log("\n"); + log(" -solver-option <name> <value>\n"); + log(" Set the specified solver option in the SMT-LIBv2 problem file.\n"); log("\n"); log(" -timeout <value>\n"); log(" Set the per-iteration timeout in seconds.\n"); + log(" (default: no timeout)\n"); + log("\n"); + log(" -O0, -O1, -O2\n"); + log(" Control the use of ABC to simplify the QBF-SAT problem before solving.\n"); log("\n"); log(" -sat\n"); log(" Generate an error if the solver does not return \"sat\".\n"); @@ -690,7 +577,7 @@ struct QbfSatPass : public Pass { log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing QBFSAT pass (solving QBF-SAT problems in the circuit).\n"); QbfSolveOptions opt = parse_args(args); @@ -719,12 +606,12 @@ struct QbfSatPass : public Pass { else if (ret.sat) { print_qed(); if (opt.write_solution) { - write_solution(module, ret, opt.write_soln_soln_file); + ret.write_solution(module, opt.write_soln_soln_file); } if (opt.specialize) { specialize(module, ret); } else { - dump_model(module, ret); + ret.dump_model(module); } if (opt.unsat) log_cmd_error("expected problem to be UNSAT\n"); diff --git a/passes/sat/qbfsat.h b/passes/sat/qbfsat.h new file mode 100644 index 000000000..c96c6f818 --- /dev/null +++ b/passes/sat/qbfsat.h @@ -0,0 +1,253 @@ +/* -*- c++ -*- + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Alberto Gonzalez <boqwxp@airmail.cc> + * + * 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. + * + */ + +#ifndef QBFSAT_H +#define QBFSAT_H + +#include "kernel/yosys.h" +#include <numeric> + +YOSYS_NAMESPACE_BEGIN + +struct QbfSolveOptions { + bool specialize = false, specialize_from_file = false, write_solution = false, nocleanup = false; + bool dump_final_smt2 = false, assume_outputs = false, assume_neg = false, nooptimize = false; + bool nobisection = false, sat = false, unsat = false, show_smtbmc = false; + enum Solver{Z3, Yices, CVC4} solver = Yices; + enum OptimizationLevel{O0, O1, O2} oflag = O0; + dict<std::string, std::string> solver_options; + int timeout = 0; + std::string specialize_soln_file = ""; + std::string write_soln_soln_file = ""; + std::string dump_final_smt2_file = ""; + size_t argidx = 0; + + std::string get_solver_name() const { + if (solver == Solver::Z3) + return "z3"; + else if (solver == Solver::Yices) + return "yices"; + else if (solver == Solver::CVC4) + return "cvc4"; + + log_cmd_error("unknown solver specified.\n"); + return ""; + } +}; + +struct QbfSolutionType { + std::vector<std::string> stdout_lines = {}; + dict<pool<std::string>, std::string> hole_to_value = {}; + double solver_time = 0; + bool sat = false; + bool unknown = true; //true if neither 'sat' nor 'unsat' + + dict<std::pair<pool<std::string>, int>, RTLIL::SigBit> get_hole_loc_idx_sigbit_map(RTLIL::Module *module) const { + dict<std::pair<pool<std::string>, int>, RTLIL::SigBit> hole_loc_idx_to_sigbit; + pool<RTLIL::SigBit> anyconst_sigbits; + dict<RTLIL::SigBit, RTLIL::SigBit> anyconst_sigbit_to_wire_sigbit; + + for (auto cell : module->cells()) { + pool<std::string> cell_src = cell->get_strpool_attribute(ID::src); + auto pos = hole_to_value.find(cell_src); + if (pos != hole_to_value.end() && cell->type.in("$anyconst", "$anyseq")) { + RTLIL::SigSpec port_y = cell->getPort(ID::Y); + for (int i = GetSize(port_y) - 1; i >= 0; --i) { + hole_loc_idx_to_sigbit[std::make_pair(pos->first, i)] = port_y[i]; + anyconst_sigbits.insert(port_y[i]); + } + } + } + + for (auto &conn : module->connections()) { + auto lhs = conn.first; + auto rhs = conn.second; + for (auto i = 0; i < GetSize(rhs); ++i) { + if (anyconst_sigbits[rhs[i]]) { + auto pos = anyconst_sigbit_to_wire_sigbit.find(rhs[i]); + if (pos != anyconst_sigbit_to_wire_sigbit.end()) + log_cmd_error("conflicting names for hole $anyconst sigbit %s\n", log_signal(rhs[i])); + anyconst_sigbit_to_wire_sigbit[rhs[i]] = lhs[i]; + } + } + } + + for (auto &it : hole_loc_idx_to_sigbit) { + auto pos = anyconst_sigbit_to_wire_sigbit.find(it.second); + if (pos != anyconst_sigbit_to_wire_sigbit.end()) + it.second = pos->second; + } + + return hole_loc_idx_to_sigbit; + } + + void dump_model(RTLIL::Module *module) const { + log("Satisfiable model:\n"); + auto hole_loc_idx_to_sigbit = get_hole_loc_idx_sigbit_map(module); + for (auto &it : hole_to_value) { + pool<std::string> hole_loc = it.first; + std::string hole_value = it.second; + + for (unsigned int i = 0; i < hole_value.size(); ++i) { + int bit_idx = GetSize(hole_value) - 1 - i; + auto it = hole_loc_idx_to_sigbit.find(std::make_pair(hole_loc, i)); + log_assert(it != hole_loc_idx_to_sigbit.end()); + + RTLIL::SigBit hole_sigbit = it->second; + log("\t%s = 1'b%c\n", log_signal(hole_sigbit), hole_value[bit_idx]); + } + } + } + + void write_solution(RTLIL::Module *module, const std::string &file) const { + std::ofstream fout(file.c_str()); + if (!fout) + log_cmd_error("could not open solution file for writing.\n"); + + //There is a question here: How exactly shall we identify holes? + //There are at least two reasonable options: + //1. By the source location of the $anyconst cells + //2. By the name(s) of the wire(s) connected to each SigBit of the $anyconst cell->getPort(ID::Y) SigSpec. + // + //Option 1 has the benefit of being very precise. There is very limited potential for confusion, as long + //as the source attribute has been set. However, if the source attribute is not set, this won't work. + //More importantly, we want to have the ability to port hole assignments to other modules with compatible + //hole names and widths. Obviously in those cases source locations of the $anyconst cells will not match. + // + //Option 2 has the benefits previously described, but wire names can be changed automatically by + //optimization or techmapping passes, especially when (ex/im)porting from BLIF for optimization with ABC. + // + //The approach taken here is to allow both options. We write the assignment information for each bit of + //the solution on a separate line. Each line is of one of two forms: + // + //location bit name = value + //location bit name [offset] = value + // + //where '[', ']', and '=' are literal symbols, "location" is the $anyconst cell source location attribute, + //"bit" is the index of the $anyconst cell, "name" is the `wire->name` field of the SigBit corresponding + //to the current bit of the $anyconst cell->getPort(ID::Y), "offset" is the `offset` field of that same + //SigBit, and "value", which is either '0' or '1', represents the assignment for that bit. + auto hole_loc_idx_to_sigbit = get_hole_loc_idx_sigbit_map(module); + for (auto &x : hole_to_value) { + std::string src_as_str = std::accumulate(x.first.begin(), x.first.end(), std::string(), [](const std::string &a, const std::string &b){return a + "|" + b;}); + for (auto i = 0; i < GetSize(x.second); ++i) + fout << src_as_str.c_str() << " " << i << " " << log_signal(hole_loc_idx_to_sigbit[std::make_pair(x.first, i)]) << " = " << x.second[GetSize(x.second) - 1 - i] << std::endl; + } + } + + void recover_solution() { + YS_REGEX_TYPE sat_regex = YS_REGEX_COMPILE("Status: PASSED"); + YS_REGEX_TYPE unsat_regex = YS_REGEX_COMPILE("Solver Error.*model is not available"); + YS_REGEX_TYPE unsat_regex2 = YS_REGEX_COMPILE("Status: FAILED"); + YS_REGEX_TYPE timeout_regex = YS_REGEX_COMPILE("No solution found! \\(timeout\\)"); + YS_REGEX_TYPE timeout_regex2 = YS_REGEX_COMPILE("No solution found! \\(interrupted\\)"); + YS_REGEX_TYPE unknown_regex = YS_REGEX_COMPILE("No solution found! \\(unknown\\)"); + YS_REGEX_TYPE unknown_regex2 = YS_REGEX_COMPILE("Unexpected EOF response from solver"); + YS_REGEX_TYPE memout_regex = YS_REGEX_COMPILE("Solver Error:.*error \"out of memory\""); + YS_REGEX_TYPE hole_value_regex = YS_REGEX_COMPILE_WITH_SUBS("Value for anyconst in [a-zA-Z0-9_]* \\(([^:]*:[^\\)]*)\\): (.*)"); +#ifndef NDEBUG + YS_REGEX_TYPE hole_loc_regex = YS_REGEX_COMPILE("[^:]*:[0-9]+.[0-9]+-[0-9]+.[0-9]+"); + YS_REGEX_TYPE hole_val_regex = YS_REGEX_COMPILE("[0-9]+"); +#endif + YS_REGEX_MATCH_TYPE m; + bool sat_regex_found = false; + bool unsat_regex_found = false; + dict<std::string, bool> hole_value_recovered; + for (const std::string &x : stdout_lines) { + if(YS_REGEX_NS::regex_search(x, m, hole_value_regex)) { + std::string loc = m[1].str(); + std::string val = m[2].str(); +#ifndef NDEBUG + log_assert(YS_REGEX_NS::regex_search(loc, hole_loc_regex)); + log_assert(YS_REGEX_NS::regex_search(val, hole_val_regex)); +#endif + auto locs = split_tokens(loc, "|"); + pool<std::string> loc_pool(locs.begin(), locs.end()); + hole_to_value[loc_pool] = val; + } + else if (YS_REGEX_NS::regex_search(x, sat_regex)) { + sat_regex_found = true; + sat = true; + unknown = false; + } + else if (YS_REGEX_NS::regex_search(x, unsat_regex)) { + unsat_regex_found = true; + sat = false; + unknown = false; + } + else if (YS_REGEX_NS::regex_search(x, memout_regex)) { + unknown = true; + log_warning("solver ran out of memory\n"); + } + else if (YS_REGEX_NS::regex_search(x, timeout_regex)) { + unknown = true; + log_warning("solver timed out\n"); + } + else if (YS_REGEX_NS::regex_search(x, timeout_regex2)) { + unknown = true; + log_warning("solver timed out\n"); + } + else if (YS_REGEX_NS::regex_search(x, unknown_regex)) { + unknown = true; + log_warning("solver returned \"unknown\"\n"); + } + else if (YS_REGEX_NS::regex_search(x, unsat_regex2)) { + unsat_regex_found = true; + sat = false; + unknown = false; + } + else if (YS_REGEX_NS::regex_search(x, unknown_regex2)) { + unknown = true; + } + } + log_assert(!unknown && sat? sat_regex_found : true); + log_assert(!unknown && !sat? unsat_regex_found : true); + } +}; + +void print_proof_failed() +{ + log("\n"); + log(" ______ ___ ___ _ _ _ _ \n"); + log(" (_____ \\ / __) / __) (_) | | | |\n"); + log(" _____) )___ ___ ___ _| |__ _| |__ _____ _| | _____ __| | |\n"); + log(" | ____/ ___) _ \\ / _ (_ __) (_ __|____ | | || ___ |/ _ |_|\n"); + log(" | | | | | |_| | |_| || | | | / ___ | | || ____( (_| |_ \n"); + log(" |_| |_| \\___/ \\___/ |_| |_| \\_____|_|\\_)_____)\\____|_|\n"); + log("\n"); +} + +void print_qed() +{ + log("\n"); + log(" /$$$$$$ /$$$$$$$$ /$$$$$$$ \n"); + log(" /$$__ $$ | $$_____/ | $$__ $$ \n"); + log(" | $$ \\ $$ | $$ | $$ \\ $$ \n"); + log(" | $$ | $$ | $$$$$ | $$ | $$ \n"); + log(" | $$ | $$ | $$__/ | $$ | $$ \n"); + log(" | $$/$$ $$ | $$ | $$ | $$ \n"); + log(" | $$$$$$/ /$$| $$$$$$$$ /$$| $$$$$$$//$$\n"); + log(" \\____ $$$|__/|________/|__/|_______/|__/\n"); + log(" \\__/ \n"); + log("\n"); +} + +YOSYS_NAMESPACE_END + +#endif diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 6acdbc800..9fdac6147 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -256,13 +256,13 @@ struct SatHelper { RTLIL::SigSpec big_lhs, big_rhs; - for (auto &it : module->wires_) + for (auto wire : module->wires()) { - if (it.second->attributes.count(ID::init) == 0) + if (wire->attributes.count(ID::init) == 0) continue; - RTLIL::SigSpec lhs = sigmap(it.second); - RTLIL::SigSpec rhs = it.second->attributes.at(ID::init); + RTLIL::SigSpec lhs = sigmap(wire); + RTLIL::SigSpec rhs = wire->attributes.at(ID::init); log_assert(lhs.size() == rhs.size()); RTLIL::SigSpec removed_bits; @@ -893,7 +893,7 @@ void print_qed() struct SatPass : public Pass { SatPass() : Pass("sat", "solve a SAT problem in the circuit") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1060,7 +1060,7 @@ struct SatPass : public Pass { log(" Like -falsify but do not return an error for timeouts.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::vector<std::pair<std::string, std::string>> sets, sets_init, prove, prove_x; std::map<int, std::vector<std::pair<std::string, std::string>>> sets_at; @@ -1365,7 +1365,7 @@ struct SatPass : public Pass { if (show_public) { for (auto wire : module->wires()) - if (wire->name[0] == '\\') + if (wire->name.isPublic()) shows.push_back(wire->name.str()); } diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 03ca42cf3..3ba66bd33 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -20,6 +20,9 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +#include "kernel/mem.h" + +#include <ctime> USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -62,6 +65,7 @@ struct SimInstance pool<SigBit> dirty_bits; pool<Cell*> dirty_cells; + pool<IdString> dirty_memories; pool<SimInstance*, hash_ptr_ops> dirty_children; struct ff_state_t @@ -72,16 +76,20 @@ struct SimInstance struct mem_state_t { - Const past_wr_clk; - Const past_wr_en; - Const past_wr_addr; - Const past_wr_data; + Mem *mem; + std::vector<Const> past_wr_clk; + std::vector<Const> past_wr_en; + std::vector<Const> past_wr_addr; + std::vector<Const> past_wr_data; Const data; }; dict<Cell*, ff_state_t> ff_database; - dict<Cell*, mem_state_t> mem_database; + dict<IdString, mem_state_t> mem_database; pool<Cell*> formal_database; + dict<Cell*, IdString> mem_cells; + + std::vector<Mem> memories; dict<Wire*, pair<int, Const>> vcd_database; @@ -118,6 +126,19 @@ struct SimInstance } } + memories = Mem::get_all_memories(module); + for (auto &mem : memories) { + auto &mdb = mem_database[mem.memid]; + mdb.mem = &mem; + for (auto &port : mem.wr_ports) { + mdb.past_wr_clk.push_back(Const(State::Sx)); + mdb.past_wr_en.push_back(Const(State::Sx, GetSize(port.en))); + mdb.past_wr_addr.push_back(Const(State::Sx, GetSize(port.addr))); + mdb.past_wr_data.push_back(Const(State::Sx, GetSize(port.data))); + } + mdb.data = mem.get_init_data(); + } + for (auto cell : module->cells()) { Module *mod = module->design->module(cell->type); @@ -143,27 +164,10 @@ struct SimInstance ff_database[cell] = ff; } - if (cell->type == ID($mem)) + if (cell->type.in(ID($mem), ID($meminit), ID($memwr), ID($memrd))) { - mem_state_t mem; - - mem.past_wr_clk = Const(State::Sx, GetSize(cell->getPort(ID::WR_CLK))); - mem.past_wr_en = Const(State::Sx, GetSize(cell->getPort(ID::WR_EN))); - mem.past_wr_addr = Const(State::Sx, GetSize(cell->getPort(ID::WR_ADDR))); - mem.past_wr_data = Const(State::Sx, GetSize(cell->getPort(ID::WR_DATA))); - - mem.data = cell->getParam(ID::INIT); - int sz = cell->getParam(ID::SIZE).as_int() * cell->getParam(ID::WIDTH).as_int(); - - if (GetSize(mem.data) > sz) - mem.data.bits.resize(sz); - - while (GetSize(mem.data) < sz) - mem.data.bits.push_back(State::Sx); - - mem_database[cell] = mem; + mem_cells[cell] = cell->parameters.at(ID::MEMID).decode_string(); } - if (cell->type.in(ID($assert), ID($cover), ID($assume))) { formal_database.insert(cell); } @@ -185,7 +189,8 @@ struct SimInstance for (auto &it : mem_database) { mem_state_t &mem = it.second; - zinit(mem.past_wr_en); + for (auto &val : mem.past_wr_en) + zinit(val); zinit(mem.data); } } @@ -256,37 +261,9 @@ struct SimInstance if (formal_database.count(cell)) return; - if (mem_database.count(cell)) + if (mem_cells.count(cell)) { - mem_state_t &mem = mem_database.at(cell); - - int num_rd_ports = cell->getParam(ID::RD_PORTS).as_int(); - - int size = cell->getParam(ID::SIZE).as_int(); - int offset = cell->getParam(ID::OFFSET).as_int(); - int abits = cell->getParam(ID::ABITS).as_int(); - int width = cell->getParam(ID::WIDTH).as_int(); - - if (cell->getParam(ID::RD_CLK_ENABLE).as_bool()) - log_error("Memory %s.%s has clocked read ports. Run 'memory' with -nordff.\n", log_id(module), log_id(cell)); - - SigSpec rd_addr_sig = cell->getPort(ID::RD_ADDR); - SigSpec rd_data_sig = cell->getPort(ID::RD_DATA); - - for (int port_idx = 0; port_idx < num_rd_ports; port_idx++) - { - Const addr = get_state(rd_addr_sig.extract(port_idx*abits, abits)); - Const data = Const(State::Sx, width); - - if (addr.is_fully_def()) { - int index = addr.as_int() - offset; - if (index >= 0 && index < size) - data = mem.data.extract(index*width, width); - } - - set_state(rd_data_sig.extract(port_idx*width, width), data); - } - + dirty_memories.insert(mem_cells[cell]); return; } @@ -349,6 +326,29 @@ struct SimInstance log_error("Unsupported cell type: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); } + void update_memory(IdString id) { + auto &mdb = mem_database[id]; + auto &mem = *mdb.mem; + + for (int port_idx = 0; port_idx < GetSize(mem.rd_ports); port_idx++) + { + auto &port = mem.rd_ports[port_idx]; + Const addr = get_state(port.addr); + Const data = Const(State::Sx, mem.width); + + if (port.clk_enable) + log_error("Memory %s.%s has clocked read ports. Run 'memory' with -nordff.\n", log_id(module), log_id(mem.memid)); + + if (addr.is_fully_def()) { + int index = addr.as_int() - mem.start_offset; + if (index >= 0 && index < mem.size) + data = mdb.data.extract(index*mem.width, mem.width); + } + + set_state(port.data, data); + } + } + void update_ph1() { pool<Cell*> queue_cells; @@ -380,6 +380,10 @@ struct SimInstance continue; } + for (auto &memid : dirty_memories) + update_memory(memid); + dirty_memories.clear(); + for (auto wire : queue_outports) if (instance->hasPort(wire->name)) { Const value = get_state(wire); @@ -423,50 +427,40 @@ struct SimInstance for (auto &it : mem_database) { - Cell *cell = it.first; - mem_state_t &mem = it.second; - - int num_wr_ports = cell->getParam(ID::WR_PORTS).as_int(); + mem_state_t &mdb = it.second; + auto &mem = *mdb.mem; - int size = cell->getParam(ID::SIZE).as_int(); - int offset = cell->getParam(ID::OFFSET).as_int(); - int abits = cell->getParam(ID::ABITS).as_int(); - int width = cell->getParam(ID::WIDTH).as_int(); - - Const wr_clk_enable = cell->getParam(ID::WR_CLK_ENABLE); - Const wr_clk_polarity = cell->getParam(ID::WR_CLK_POLARITY); - Const current_wr_clk = get_state(cell->getPort(ID::WR_CLK)); - - for (int port_idx = 0; port_idx < num_wr_ports; port_idx++) + for (int port_idx = 0; port_idx < GetSize(mem.wr_ports); port_idx++) { + auto &port = mem.wr_ports[port_idx]; Const addr, data, enable; - if (wr_clk_enable[port_idx] == State::S0) + if (!port.clk_enable) { - addr = get_state(cell->getPort(ID::WR_ADDR).extract(port_idx*abits, abits)); - data = get_state(cell->getPort(ID::WR_DATA).extract(port_idx*width, width)); - enable = get_state(cell->getPort(ID::WR_EN).extract(port_idx*width, width)); + addr = get_state(port.addr); + data = get_state(port.data); + enable = get_state(port.en); } else { - if (wr_clk_polarity[port_idx] == State::S1 ? - (mem.past_wr_clk[port_idx] == State::S1 || current_wr_clk[port_idx] != State::S1) : - (mem.past_wr_clk[port_idx] == State::S0 || current_wr_clk[port_idx] != State::S0)) + if (port.clk_polarity ? + (mdb.past_wr_clk[port_idx] == State::S1 || get_state(port.clk) != State::S1) : + (mdb.past_wr_clk[port_idx] == State::S0 || get_state(port.clk) != State::S0)) continue; - addr = mem.past_wr_addr.extract(port_idx*abits, abits); - data = mem.past_wr_data.extract(port_idx*width, width); - enable = mem.past_wr_en.extract(port_idx*width, width); + addr = mdb.past_wr_addr[port_idx]; + data = mdb.past_wr_data[port_idx]; + enable = mdb.past_wr_en[port_idx]; } if (addr.is_fully_def()) { - int index = addr.as_int() - offset; - if (index >= 0 && index < size) - for (int i = 0; i < width; i++) - if (enable[i] == State::S1 && mem.data.bits.at(index*width+i) != data[i]) { - mem.data.bits.at(index*width+i) = data[i]; - dirty_cells.insert(cell); + int index = addr.as_int() - mem.start_offset; + if (index >= 0 && index < mem.size) + for (int i = 0; i < mem.width; i++) + if (enable[i] == State::S1 && mdb.data.bits.at(index*mem.width+i) != data[i]) { + mdb.data.bits.at(index*mem.width+i) = data[i]; + dirty_memories.insert(mem.memid); did_something = true; } } @@ -497,13 +491,15 @@ struct SimInstance for (auto &it : mem_database) { - Cell *cell = it.first; mem_state_t &mem = it.second; - mem.past_wr_clk = get_state(cell->getPort(ID::WR_CLK)); - mem.past_wr_en = get_state(cell->getPort(ID::WR_EN)); - mem.past_wr_addr = get_state(cell->getPort(ID::WR_ADDR)); - mem.past_wr_data = get_state(cell->getPort(ID::WR_DATA)); + for (int i = 0; i < GetSize(mem.mem->wr_ports); i++) { + auto &port = mem.mem->wr_ports[i]; + mem.past_wr_clk[i] = get_state(port.clk); + mem.past_wr_en[i] = get_state(port.en); + mem.past_wr_addr[i] = get_state(port.addr); + mem.past_wr_data[i] = get_state(port.data); + } } for (auto cell : formal_database) @@ -558,17 +554,13 @@ struct SimInstance for (auto &it : mem_database) { - Cell *cell = it.first; mem_state_t &mem = it.second; - Const initval = mem.data; - - while (GetSize(initval) >= 2) { - if (initval[GetSize(initval)-1] != State::Sx) break; - if (initval[GetSize(initval)-2] != State::Sx) break; - initval.bits.pop_back(); - } - - cell->setParam(ID::INIT, initval); + mem.mem->clear_inits(); + MemInit minit; + minit.addr = mem.mem->start_offset; + minit.data = mem.data; + mem.mem->inits.push_back(minit); + mem.mem->emit(); } for (auto it : children) @@ -630,6 +622,7 @@ struct SimWorker : SimShared SimInstance *top = nullptr; std::ofstream vcdfile; pool<IdString> clock, clockn, reset, resetn; + std::string timescale; ~SimWorker() { @@ -641,6 +634,17 @@ struct SimWorker : SimShared if (!vcdfile.is_open()) return; + vcdfile << stringf("$version %s $end\n", yosys_version_str); + + std::time_t t = std::time(nullptr); + char mbstr[255]; + if (std::strftime(mbstr, sizeof(mbstr), "%c", std::localtime(&t))) { + vcdfile << stringf("$date ") << mbstr << stringf(" $end\n"); + } + + if (!timescale.empty()) + vcdfile << stringf("$timescale %s $end\n", timescale.c_str()); + int id = 1; top->write_vcd_header(vcdfile, id); @@ -751,7 +755,7 @@ struct SimWorker : SimShared struct SimPass : public Pass { SimPass() : Pass("sim", "simulate the circuit") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -780,6 +784,9 @@ struct SimPass : public Pass { log(" -zinit\n"); log(" zero-initialize all uninitialized regs and memories\n"); log("\n"); + log(" -timescale <string>\n"); + log(" include the specified timescale declaration in the vcd\n"); + log("\n"); log(" -n <integer>\n"); log(" number of cycles to simulate (default: 20)\n"); log("\n"); @@ -793,7 +800,7 @@ struct SimPass : public Pass { log(" enable debug output\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { SimWorker worker; int numcycles = 20; @@ -803,7 +810,9 @@ struct SimPass : public Pass { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-vcd" && argidx+1 < args.size()) { - worker.vcdfile.open(args[++argidx].c_str()); + std::string vcd_filename = args[++argidx]; + rewrite_filename(vcd_filename); + worker.vcdfile.open(vcd_filename.c_str()); continue; } if (args[argidx] == "-n" && argidx+1 < args.size()) { @@ -830,6 +839,10 @@ struct SimPass : public Pass { worker.resetn.insert(RTLIL::escape_id(args[++argidx])); continue; } + if (args[argidx] == "-timescale" && argidx+1 < args.size()) { + worker.timescale = args[++argidx]; + continue; + } if (args[argidx] == "-a") { worker.hide_internal = false; continue; diff --git a/passes/sat/supercover.cc b/passes/sat/supercover.cc index ba44f02d8..aacc044fb 100644 --- a/passes/sat/supercover.cc +++ b/passes/sat/supercover.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct SupercoverPass : public Pass { SupercoverPass() : Pass("supercover", "add hi/lo cover cells for each wire bit") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -35,7 +35,7 @@ struct SupercoverPass : public Pass { log("checking for a hi signal level and one checking for lo level.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { // bool flag_noinit = false; diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index a54b4913d..035699603 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -27,7 +27,6 @@ OBJS += passes/techmap/extract_fa.o OBJS += passes/techmap/extract_counter.o OBJS += passes/techmap/extract_reduce.o OBJS += passes/techmap/alumacc.o -OBJS += passes/techmap/dff2dffe.o OBJS += passes/techmap/dffinit.o OBJS += passes/techmap/pmuxtree.o OBJS += passes/techmap/muxcover.o @@ -41,7 +40,8 @@ OBJS += passes/techmap/insbuf.o OBJS += passes/techmap/attrmvcp.o OBJS += passes/techmap/attrmap.o OBJS += passes/techmap/zinit.o -OBJS += passes/techmap/dff2dffs.o +OBJS += passes/techmap/dfflegalize.o +OBJS += passes/techmap/dffunmap.o OBJS += passes/techmap/flowmap.o OBJS += passes/techmap/extractinv.o endif diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index fae8b2426..192e39372 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -44,6 +44,7 @@ #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +#include "kernel/ffinit.h" #include "kernel/cost.h" #include "kernel/log.h" #include <stdlib.h> @@ -111,7 +112,7 @@ SigMap assign_map; RTLIL::Module *module; std::vector<gate_t> signal_list; std::map<RTLIL::SigBit, int> signal_map; -std::map<RTLIL::SigBit, RTLIL::State> signal_init; +FfInitVals initvals; pool<std::string> enabled_gates; bool recover_init, cmos_cost; @@ -133,10 +134,7 @@ int map_signal(RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, gate.in4 = -1; gate.is_port = false; gate.bit = bit; - if (signal_init.count(bit)) - gate.init = signal_init.at(bit); - else - gate.init = State::Sx; + gate.init = initvals(bit); signal_list.push_back(gate); signal_map[bit] = gate.id; } @@ -1276,7 +1274,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin struct AbcPass : public Pass { AbcPass() : Pass("abc", "use ABC for technology mapping") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1460,7 +1458,7 @@ struct AbcPass : public Pass { log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing ABC pass (technology mapping using ABC).\n"); log_push(); @@ -1468,15 +1466,11 @@ struct AbcPass : public Pass { assign_map.clear(); signal_list.clear(); signal_map.clear(); - signal_init.clear(); + initvals.clear(); pi_map.clear(); po_map.clear(); -#ifdef ABCEXTERNAL - std::string exe_file = ABCEXTERNAL; -#else - std::string exe_file = proc_self_dirname() + proc_program_prefix() + "yosys-abc"; -#endif + std::string exe_file = yosys_abc_executable; std::string script_file, liberty_file, constr_file, clk_str; std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1"; bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; @@ -1491,13 +1485,6 @@ struct AbcPass : public Pass { enabled_gates.clear(); cmos_cost = false; -#ifdef _WIN32 -#ifndef ABCEXTERNAL - if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\" + proc_program_prefix()+ "yosys-abc.exe")) - exe_file = proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc"; -#endif -#endif - // get arguments from scratchpad first, then override by command arguments std::string lut_arg, luts_arg, g_arg; exe_file = design->scratchpad_get_string("abc.exe", exe_file /* inherit default value if not set */); @@ -1854,24 +1841,7 @@ struct AbcPass : public Pass { } assign_map.set(mod); - signal_init.clear(); - - for (Wire *wire : mod->wires()) - if (wire->attributes.count(ID::init)) { - SigSpec initsig = assign_map(wire); - Const initval = wire->attributes.at(ID::init); - for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++) - switch (initval[i]) { - case State::S0: - signal_init[initsig[i]] = State::S0; - break; - case State::S1: - signal_init[initsig[i]] = State::S1; - break; - default: - break; - } - } + initvals.set(&assign_map, mod); if (!dff_mode || !clk_str.empty()) { abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, @@ -2028,7 +1998,7 @@ struct AbcPass : public Pass { assign_map.clear(); signal_list.clear(); signal_map.clear(); - signal_init.clear(); + initvals.clear(); pi_map.clear(); po_map.clear(); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 06097a6f7..7d017ac40 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -36,7 +36,7 @@ PRIVATE_NAMESPACE_BEGIN struct Abc9Pass : public ScriptPass { Abc9Pass() : ScriptPass("abc9", "use ABC9 for technology mapping") { } - void on_register() YS_OVERRIDE + void on_register() override { RTLIL::constpad["abc9.script.default"] = "+&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -v; &mfs"; RTLIL::constpad["abc9.script.default.area"] = "+&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -a -v; &mfs"; @@ -81,7 +81,7 @@ struct Abc9Pass : public ScriptPass "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} {R} -v; &save; &load;"\ "&mfs"; } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -184,7 +184,7 @@ struct Abc9Pass : public ScriptPass int maxlut; std::string box_file; - void clear_flags() YS_OVERRIDE + void clear_flags() override { exe_cmd.str(""); exe_cmd << "abc9_exe"; @@ -195,7 +195,7 @@ struct Abc9Pass : public ScriptPass box_file = ""; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string run_from, run_to; clear_flags(); @@ -272,7 +272,7 @@ struct Abc9Pass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("check")) { if (help_mode) @@ -294,8 +294,8 @@ struct Abc9Pass : public ScriptPass run("design -load $abc9_map"); run("proc"); run("wbflip"); - run("techmap"); - run("opt"); + run("techmap -wb -map %$abc9 -map +/techmap.v A:abc9_flop"); + run("opt -nodffe -nosdff"); if (dff_mode || help_mode) { if (!help_mode) active_design->scratchpad_unset("abc9_ops.prep_dff_submod.did_something"); diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc index 0bf547921..b916b049d 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -293,7 +293,7 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe struct Abc9ExePass : public Pass { Abc9ExePass() : Pass("abc9_exe", "use ABC9 for technology mapping") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -375,15 +375,11 @@ struct Abc9ExePass : public Pass { log("[1] http://www.eecs.berkeley.edu/~alanmi/abc/\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing ABC9_EXE pass (technology mapping using ABC9).\n"); -#ifdef ABCEXTERNAL - std::string exe_file = ABCEXTERNAL; -#else - std::string exe_file = proc_self_dirname() + proc_program_prefix()+ "yosys-abc"; -#endif + std::string exe_file = yosys_abc_executable; std::string script_file, clk_str, box_file, lut_file; std::string delay_target, lutin_shared = "-S 1", wire_delay; std::string tempdir_name; @@ -396,13 +392,6 @@ struct Abc9ExePass : public Pass { show_tempdir = true; #endif -#ifdef _WIN32 -#ifndef ABCEXTERNAL - if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc.exe")) - exe_file = proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc"; -#endif -#endif - std::string lut_arg, luts_arg; exe_file = design->scratchpad_get_string("abc9.exe", exe_file /* inherit default value if not set */); script_file = design->scratchpad_get_string("abc9.script", script_file); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 873c37b9a..98d0207c4 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -741,7 +741,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff) if (ys_debug(1)) toposort.analyze_loops = true; - bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); + bool no_loops = toposort.sort(); if (ys_debug(1)) { unsigned i = 0; @@ -1453,7 +1453,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) for (auto driver_cell : bit_drivers.at(it.first)) for (auto user_cell : it.second) toposort.edge(driver_cell, user_cell); - bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); + bool no_loops = toposort.sort(); log_assert(no_loops); for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { @@ -1530,7 +1530,7 @@ clone_lut: struct Abc9OpsPass : public Pass { Abc9OpsPass() : Pass("abc9_ops", "helper functions for ABC9") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1614,7 +1614,7 @@ struct Abc9OpsPass : public Pass { log(" inputs and outputs.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing ABC9_OPS pass (helper functions for ABC9).\n"); diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index 2ecb2f35a..ce151c7f3 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct AigmapPass : public Pass { AigmapPass() : Pass("aigmap", "map logic to and-inverter-graph circuit") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -43,7 +43,7 @@ struct AigmapPass : public Pass { log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool nand_mode = false, select_mode = false; diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index 1925145d3..b16e9750e 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -550,7 +550,7 @@ struct AlumaccWorker struct AlumaccPass : public Pass { AlumaccPass() : Pass("alumacc", "extract ALU and MACC cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -560,7 +560,7 @@ struct AlumaccPass : public Pass { log("and $macc cells.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing ALUMACC pass (create $alu and $macc cells).\n"); diff --git a/passes/techmap/attrmap.cc b/passes/techmap/attrmap.cc index 5f30817d4..8643543c8 100644 --- a/passes/techmap/attrmap.cc +++ b/passes/techmap/attrmap.cc @@ -81,7 +81,7 @@ struct AttrmapAction { struct AttrmapTocase : AttrmapAction { string name; - bool apply(IdString &id, Const&) YS_OVERRIDE { + bool apply(IdString &id, Const&) override { if (match_name(name, id, true)) id = RTLIL::escape_id(name); return true; @@ -90,7 +90,7 @@ struct AttrmapTocase : AttrmapAction { struct AttrmapRename : AttrmapAction { string old_name, new_name; - bool apply(IdString &id, Const&) YS_OVERRIDE { + bool apply(IdString &id, Const&) override { if (match_name(old_name, id)) id = RTLIL::escape_id(new_name); return true; @@ -101,7 +101,7 @@ struct AttrmapMap : AttrmapAction { bool imap; string old_name, new_name; string old_value, new_value; - bool apply(IdString &id, Const &val) YS_OVERRIDE { + bool apply(IdString &id, Const &val) override { if (match_name(old_name, id) && match_value(old_value, val, true)) { id = RTLIL::escape_id(new_name); val = make_value(new_value); @@ -113,7 +113,7 @@ struct AttrmapMap : AttrmapAction { struct AttrmapRemove : AttrmapAction { bool has_value; string name, value; - bool apply(IdString &id, Const &val) YS_OVERRIDE { + bool apply(IdString &id, Const &val) override { return !(match_name(name, id) && (!has_value || match_value(value, val))); } }; @@ -221,7 +221,7 @@ bool parse_attrmap_paramap_options(size_t &argidx, std::vector<std::string> &arg struct AttrmapPass : public Pass { AttrmapPass() : Pass("attrmap", "renaming attributes") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -241,7 +241,7 @@ struct AttrmapPass : public Pass { log(" -imap keep=\"false\" keep=0 -remove keep=0\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing ATTRMAP pass (move or copy attributes).\n"); @@ -301,7 +301,7 @@ struct AttrmapPass : public Pass { struct ParamapPass : public Pass { ParamapPass() : Pass("paramap", "renaming cell parameters") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -317,7 +317,7 @@ struct ParamapPass : public Pass { log(" paramap -tocase INIT t:LUT4\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing PARAMAP pass (move or copy cell parameters).\n"); diff --git a/passes/techmap/attrmvcp.cc b/passes/techmap/attrmvcp.cc index e59aa6518..b3202c587 100644 --- a/passes/techmap/attrmvcp.cc +++ b/passes/techmap/attrmvcp.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct AttrmvcpPass : public Pass { AttrmvcpPass() : Pass("attrmvcp", "move or copy attributes from wires to driving cells") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" attrmvcp [options] [selection]\n"); @@ -53,7 +53,7 @@ struct AttrmvcpPass : public Pass { log(" multiple times.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing ATTRMVCP pass (move or copy attributes).\n"); diff --git a/passes/techmap/clkbufmap.cc b/passes/techmap/clkbufmap.cc index 3f4b6aa66..1cbd12e3d 100644 --- a/passes/techmap/clkbufmap.cc +++ b/passes/techmap/clkbufmap.cc @@ -2,7 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * Copyright (C) 2019 Marcin Kościelnicki <mwk@0x04.net> + * Copyright (C) 2019 Marcelina Kościelnicka <mwk@0x04.net> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -34,33 +34,34 @@ void split_portname_pair(std::string &port1, std::string &port2) } struct ClkbufmapPass : public Pass { - ClkbufmapPass() : Pass("clkbufmap", "insert global buffers on clock networks") { } - void help() YS_OVERRIDE + ClkbufmapPass() : Pass("clkbufmap", "insert clock buffers on clock networks") { } + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" clkbufmap [options] [selection]\n"); log("\n"); - log("Inserts global buffers between nets connected to clock inputs and their drivers.\n"); + log("Inserts clock buffers between nets connected to clock inputs and their drivers.\n"); log("\n"); log("In the absence of any selection, all wires without the 'clkbuf_inhibit'\n"); - log("attribute will be considered for global buffer insertion.\n"); + log("attribute will be considered for clock buffer insertion.\n"); log("Alternatively, to consider all wires without the 'buffer_type' attribute set to\n"); log("'none' or 'bufr' one would specify:\n"); log(" 'w:* a:buffer_type=none a:buffer_type=bufr %%u %%d'\n"); log("as the selection.\n"); log("\n"); log(" -buf <celltype> <portname_out>:<portname_in>\n"); - log(" Specifies the cell type to use for the global buffers\n"); + log(" Specifies the cell type to use for the clock buffers\n"); log(" and its port names. The first port will be connected to\n"); log(" the clock network sinks, and the second will be connected\n"); - log(" to the actual clock source. This option is required.\n"); + log(" to the actual clock source.\n"); log("\n"); log(" -inpad <celltype> <portname_out>:<portname_in>\n"); log(" If specified, a PAD cell of the given type is inserted on\n"); log(" clock nets that are also top module's inputs (in addition\n"); - log(" to the global buffer).\n"); + log(" to the clock buffer, if any).\n"); log("\n"); + log("At least one of -buf or -inpad should be specified.\n"); } void module_queue(Design *design, Module *module, std::vector<Module *> &modules_sorted, pool<Module *> &modules_processed) { @@ -76,9 +77,9 @@ struct ClkbufmapPass : public Pass { modules_processed.insert(module); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { - log_header(design, "Executing CLKBUFMAP pass (inserting global clock buffers).\n"); + log_header(design, "Executing CLKBUFMAP pass (inserting clock buffers).\n"); std::string buf_celltype, buf_portname, buf_portname2; std::string inpad_celltype, inpad_portname, inpad_portname2; @@ -109,8 +110,8 @@ struct ClkbufmapPass : public Pass { extra_args(args, argidx, design); } - if (buf_celltype.empty()) - log_error("The -buf option is required.\n"); + if (buf_celltype.empty() && inpad_celltype.empty()) + log_error("Either the -buf option or -inpad option is required.\n"); // Cell type, port name, bit index. pool<pair<IdString, pair<IdString, int>>> sink_ports; @@ -118,6 +119,16 @@ struct ClkbufmapPass : public Pass { dict<pair<IdString, pair<IdString, int>>, pair<IdString, int>> inv_ports_out; dict<pair<IdString, pair<IdString, int>>, pair<IdString, int>> inv_ports_in; + // If true, use both ther -buf and -inpad cell for input ports that are clocks. + bool buffer_inputs = true; + + Module *inpad_mod = design->module(RTLIL::escape_id(inpad_celltype)); + if (inpad_mod) { + Wire *buf_wire = inpad_mod->wire(RTLIL::escape_id(buf_portname)); + if (buf_wire && buf_wire->get_bool_attribute(ID::clkbuf_driver)) + buffer_inputs = false; + } + // Process submodules before module using them. std::vector<Module *> modules_sorted; pool<Module *> modules_processed; @@ -242,19 +253,30 @@ struct ClkbufmapPass : public Pass { // Clock network not yet buffered, driven by one of // our cells or a top-level input -- buffer it. - log("Inserting %s on %s.%s[%d].\n", buf_celltype.c_str(), log_id(module), log_id(wire), i); - RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(buf_celltype)); - Wire *iwire = module->addWire(NEW_ID); - cell->setPort(RTLIL::escape_id(buf_portname), mapped_wire_bit); - cell->setPort(RTLIL::escape_id(buf_portname2), iwire); - if (wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute(ID::top)) { + Wire *iwire = nullptr; + RTLIL::Cell *cell = nullptr; + bool is_input = wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute(ID::top); + if (!buf_celltype.empty() && (!is_input || buffer_inputs)) { + log("Inserting %s on %s.%s[%d].\n", buf_celltype.c_str(), log_id(module), log_id(wire), i); + cell = module->addCell(NEW_ID, RTLIL::escape_id(buf_celltype)); + iwire = module->addWire(NEW_ID); + cell->setPort(RTLIL::escape_id(buf_portname), mapped_wire_bit); + cell->setPort(RTLIL::escape_id(buf_portname2), iwire); + } + if (is_input) { log("Inserting %s on %s.%s[%d].\n", inpad_celltype.c_str(), log_id(module), log_id(wire), i); RTLIL::Cell *cell2 = module->addCell(NEW_ID, RTLIL::escape_id(inpad_celltype)); - cell2->setPort(RTLIL::escape_id(inpad_portname), iwire); + if (iwire) { + cell2->setPort(RTLIL::escape_id(inpad_portname), iwire); + } else { + cell2->setPort(RTLIL::escape_id(inpad_portname), mapped_wire_bit); + cell = cell2; + } iwire = module->addWire(NEW_ID); cell2->setPort(RTLIL::escape_id(inpad_portname2), iwire); } - buffered_bits[mapped_wire_bit] = make_pair(cell, iwire); + if (iwire) + buffered_bits[mapped_wire_bit] = make_pair(cell, iwire); if (wire->port_input) { input_bits.insert(i); diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc index a7dce9c81..9a23cb90e 100644 --- a/passes/techmap/deminout.cc +++ b/passes/techmap/deminout.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct DeminoutPass : public Pass { DeminoutPass() : Pass("deminout", "demote inout ports to input or output") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" deminout [options] [selection]\n"); @@ -33,7 +33,7 @@ struct DeminoutPass : public Pass { log("\"Demote\" inout ports to input or output ports, if possible.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing DEMINOUT pass (demote inout ports to input or output).\n"); diff --git a/passes/techmap/dff2dffe.cc b/passes/techmap/dff2dffe.cc deleted file mode 100644 index aa9bbfe17..000000000 --- a/passes/techmap/dff2dffe.cc +++ /dev/null @@ -1,414 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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" -#include "kernel/celltypes.h" -#include "passes/techmap/simplemap.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct Dff2dffeWorker -{ - const dict<IdString, IdString> &direct_dict; - - RTLIL::Module *module; - SigMap sigmap; - CellTypes ct; - - typedef std::pair<RTLIL::Cell*, int> cell_int_t; - std::map<RTLIL::SigBit, cell_int_t> bit2mux; - std::vector<RTLIL::Cell*> dff_cells; - std::map<RTLIL::SigBit, int> bitusers; - - typedef std::map<RTLIL::SigBit, bool> pattern_t; - typedef std::set<pattern_t> patterns_t; - - - Dff2dffeWorker(RTLIL::Module *module, const dict<IdString, IdString> &direct_dict) : - direct_dict(direct_dict), module(module), sigmap(module), ct(module->design) - { - for (auto wire : module->wires()) { - if (wire->port_output) - for (auto bit : sigmap(wire)) - bitusers[bit]++; - } - - for (auto cell : module->cells()) { - if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) { - RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y)); - for (int i = 0; i < GetSize(sig_y); i++) - bit2mux[sig_y[i]] = cell_int_t(cell, i); - } - if (direct_dict.empty()) { - if (cell->type.in(ID($dff), ID($_DFF_N_), ID($_DFF_P_))) - dff_cells.push_back(cell); - } else { - if (direct_dict.count(cell->type)) - dff_cells.push_back(cell); - } - for (auto conn : cell->connections()) { - if (ct.cell_output(cell->type, conn.first)) - continue; - for (auto bit : sigmap(conn.second)) - bitusers[bit]++; - } - } - } - - patterns_t find_muxtree_feedback_patterns(RTLIL::SigBit d, RTLIL::SigBit q, pattern_t path) - { - patterns_t ret; - - if (d == q) { - ret.insert(path); - return ret; - } - - if (bit2mux.count(d) == 0 || bitusers[d] > 1) - return ret; - - cell_int_t mux_cell_int = bit2mux.at(d); - RTLIL::SigSpec sig_a = sigmap(mux_cell_int.first->getPort(ID::A)); - RTLIL::SigSpec sig_b = sigmap(mux_cell_int.first->getPort(ID::B)); - RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort(ID::S)); - int width = GetSize(sig_a), index = mux_cell_int.second; - - for (int i = 0; i < GetSize(sig_s); i++) - if (path.count(sig_s[i]) && path.at(sig_s[i])) - { - ret = find_muxtree_feedback_patterns(sig_b[i*width + index], q, path); - - if (sig_b[i*width + index] == q) { - RTLIL::SigSpec s = mux_cell_int.first->getPort(ID::B); - s[i*width + index] = RTLIL::Sx; - mux_cell_int.first->setPort(ID::B, s); - } - - return ret; - } - - pattern_t path_else = path; - - for (int i = 0; i < GetSize(sig_s); i++) - { - if (path.count(sig_s[i])) - continue; - - pattern_t path_this = path; - path_else[sig_s[i]] = false; - path_this[sig_s[i]] = true; - - for (auto &pat : find_muxtree_feedback_patterns(sig_b[i*width + index], q, path_this)) - ret.insert(pat); - - if (sig_b[i*width + index] == q) { - RTLIL::SigSpec s = mux_cell_int.first->getPort(ID::B); - s[i*width + index] = RTLIL::Sx; - mux_cell_int.first->setPort(ID::B, s); - } - } - - for (auto &pat : find_muxtree_feedback_patterns(sig_a[index], q, path_else)) - ret.insert(pat); - - if (sig_a[index] == q) { - RTLIL::SigSpec s = mux_cell_int.first->getPort(ID::A); - s[index] = RTLIL::Sx; - mux_cell_int.first->setPort(ID::A, s); - } - - return ret; - } - - void simplify_patterns(patterns_t&) - { - // TBD - } - - RTLIL::SigSpec make_patterns_logic(patterns_t patterns, bool make_gates) - { - RTLIL::SigSpec or_input; - - for (auto pat : patterns) - { - RTLIL::SigSpec s1, s2; - for (auto it : pat) { - s1.append(it.first); - s2.append(it.second); - } - - RTLIL::SigSpec y = module->addWire(NEW_ID); - RTLIL::Cell *c = module->addNe(NEW_ID, s1, s2, y); - - if (make_gates) { - simplemap(module, c); - module->remove(c); - } - - or_input.append(y); - } - - if (GetSize(or_input) == 0) - return State::S1; - - if (GetSize(or_input) == 1) - return or_input; - - RTLIL::SigSpec y = module->addWire(NEW_ID); - RTLIL::Cell *c = module->addReduceAnd(NEW_ID, or_input, y); - - if (make_gates) { - simplemap(module, c); - module->remove(c); - } - - return y; - } - - void handle_dff_cell(RTLIL::Cell *dff_cell) - { - RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort(ID::D)); - RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort(ID::Q)); - - std::map<patterns_t, std::set<int>> grouped_patterns; - std::set<int> remaining_indices; - - for (int i = 0 ; i < GetSize(sig_d); i++) { - patterns_t patterns = find_muxtree_feedback_patterns(sig_d[i], sig_q[i], pattern_t()); - if (!patterns.empty()) { - simplify_patterns(patterns); - grouped_patterns[patterns].insert(i); - } else - remaining_indices.insert(i); - } - - for (auto &it : grouped_patterns) { - RTLIL::SigSpec new_sig_d, new_sig_q; - for (int i : it.second) { - new_sig_d.append(sig_d[i]); - new_sig_q.append(sig_q[i]); - } - if (!direct_dict.empty()) { - log(" converting %s cell %s to %s for %s -> %s.\n", log_id(dff_cell->type), log_id(dff_cell), log_id(direct_dict.at(dff_cell->type)), log_signal(new_sig_d), log_signal(new_sig_q)); - dff_cell->setPort(ID::E, make_patterns_logic(it.first, true)); - dff_cell->type = direct_dict.at(dff_cell->type); - } else - if (dff_cell->type == ID($dff)) { - RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort(ID::CLK), make_patterns_logic(it.first, false), - new_sig_d, new_sig_q, dff_cell->getParam(ID::CLK_POLARITY).as_bool(), true); - log(" created $dffe cell %s for %s -> %s.\n", log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q)); - } else { - RTLIL::Cell *new_cell = module->addDffeGate(NEW_ID, dff_cell->getPort(ID::C), make_patterns_logic(it.first, true), - new_sig_d, new_sig_q, dff_cell->type == ID($_DFF_P_), true); - log(" created %s cell %s for %s -> %s.\n", log_id(new_cell->type), log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q)); - } - } - - if (!direct_dict.empty()) - return; - - if (remaining_indices.empty()) { - log(" removing now obsolete cell %s.\n", log_id(dff_cell)); - module->remove(dff_cell); - } else if (GetSize(remaining_indices) != GetSize(sig_d)) { - log(" removing %d now obsolete bits from cell %s.\n", GetSize(sig_d) - GetSize(remaining_indices), log_id(dff_cell)); - RTLIL::SigSpec new_sig_d, new_sig_q; - for (int i : remaining_indices) { - new_sig_d.append(sig_d[i]); - new_sig_q.append(sig_q[i]); - } - dff_cell->setPort(ID::D, new_sig_d); - dff_cell->setPort(ID::Q, new_sig_q); - dff_cell->setParam(ID::WIDTH, GetSize(remaining_indices)); - } - } - - void run() - { - log("Transforming FF to FF+Enable cells in module %s:\n", log_id(module)); - for (auto dff_cell : dff_cells) { - // log("Handling candidate %s:\n", log_id(dff_cell)); - handle_dff_cell(dff_cell); - } - } -}; - -struct Dff2dffePass : public Pass { - Dff2dffePass() : Pass("dff2dffe", "transform $dff cells to $dffe cells") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" dff2dffe [options] [selection]\n"); - log("\n"); - log("This pass transforms $dff cells driven by a tree of multiplexers with one or\n"); - log("more feedback paths to $dffe cells. It also works on gate-level cells such as\n"); - log("$_DFF_P_, $_DFF_N_ and $_MUX_.\n"); - log("\n"); - log(" -unmap\n"); - log(" operate in the opposite direction: replace $dffe cells with combinations\n"); - log(" of $dff and $mux cells. the options below are ignored in unmap mode.\n"); - log("\n"); - log(" -unmap-mince N\n"); - log(" Same as -unmap but only unmap $dffe where the clock enable port\n"); - log(" signal is used by less $dffe than the specified number\n"); - log("\n"); - log(" -direct <internal_gate_type> <external_gate_type>\n"); - log(" map directly to external gate type. <internal_gate_type> can\n"); - log(" be any internal gate-level FF cell (except $_DFFE_??_). the\n"); - log(" <external_gate_type> is the cell type name for a cell with an\n"); - log(" identical interface to the <internal_gate_type>, except it\n"); - log(" also has an high-active enable port 'E'.\n"); - log(" Usually <external_gate_type> is an intermediate cell type\n"); - log(" that is then translated to the final type using 'techmap'.\n"); - log("\n"); - log(" -direct-match <pattern>\n"); - log(" like -direct for all DFF cell types matching the expression.\n"); - log(" this will use $__DFFE_* as <external_gate_type> matching the\n"); - log(" internal gate type $_DFF_*_, and $__DFFSE_* for those matching\n"); - log(" $_DFFS_*_, except for $_DFF_[NP]_, which is converted to \n"); - log(" $_DFFE_[NP]_.\n"); - log("\n"); - } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing DFF2DFFE pass (transform $dff to $dffe where applicable).\n"); - - bool unmap_mode = false; - int min_ce_use = -1; - dict<IdString, IdString> direct_dict; - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-unmap") { - unmap_mode = true; - continue; - } - if (args[argidx] == "-unmap-mince" && argidx + 1 < args.size()) { - unmap_mode = true; - min_ce_use = atoi(args[++argidx].c_str()); - continue; - } - if (args[argidx] == "-direct" && argidx + 2 < args.size()) { - string direct_from = RTLIL::escape_id(args[++argidx]); - string direct_to = RTLIL::escape_id(args[++argidx]); - direct_dict[direct_from] = direct_to; - continue; - } - if (args[argidx] == "-direct-match" && argidx + 1 < args.size()) { - bool found_match = false; - const char *pattern = args[++argidx].c_str(); - if (patmatch(pattern, "$_DFF_P_" )) found_match = true, direct_dict[ID($_DFF_P_) ] = ID($_DFFE_PP_); - if (patmatch(pattern, "$_DFF_N_" )) found_match = true, direct_dict[ID($_DFF_N_) ] = ID($_DFFE_NP_); - if (patmatch(pattern, "$_DFF_NN0_")) found_match = true, direct_dict[ID($_DFF_NN0_)] = ID($__DFFE_NN0); - if (patmatch(pattern, "$_DFF_NN1_")) found_match = true, direct_dict[ID($_DFF_NN1_)] = ID($__DFFE_NN1); - if (patmatch(pattern, "$_DFF_NP0_")) found_match = true, direct_dict[ID($_DFF_NP0_)] = ID($__DFFE_NP0); - if (patmatch(pattern, "$_DFF_NP1_")) found_match = true, direct_dict[ID($_DFF_NP1_)] = ID($__DFFE_NP1); - if (patmatch(pattern, "$_DFF_PN0_")) found_match = true, direct_dict[ID($_DFF_PN0_)] = ID($__DFFE_PN0); - if (patmatch(pattern, "$_DFF_PN1_")) found_match = true, direct_dict[ID($_DFF_PN1_)] = ID($__DFFE_PN1); - if (patmatch(pattern, "$_DFF_PP0_")) found_match = true, direct_dict[ID($_DFF_PP0_)] = ID($__DFFE_PP0); - if (patmatch(pattern, "$_DFF_PP1_")) found_match = true, direct_dict[ID($_DFF_PP1_)] = ID($__DFFE_PP1); - - if (patmatch(pattern, "$__DFFS_NN0_")) found_match = true, direct_dict[ID($__DFFS_NN0_)] = ID($__DFFSE_NN0); - if (patmatch(pattern, "$__DFFS_NN1_")) found_match = true, direct_dict[ID($__DFFS_NN1_)] = ID($__DFFSE_NN1); - if (patmatch(pattern, "$__DFFS_NP0_")) found_match = true, direct_dict[ID($__DFFS_NP0_)] = ID($__DFFSE_NP0); - if (patmatch(pattern, "$__DFFS_NP1_")) found_match = true, direct_dict[ID($__DFFS_NP1_)] = ID($__DFFSE_NP1); - if (patmatch(pattern, "$__DFFS_PN0_")) found_match = true, direct_dict[ID($__DFFS_PN0_)] = ID($__DFFSE_PN0); - if (patmatch(pattern, "$__DFFS_PN1_")) found_match = true, direct_dict[ID($__DFFS_PN1_)] = ID($__DFFSE_PN1); - if (patmatch(pattern, "$__DFFS_PP0_")) found_match = true, direct_dict[ID($__DFFS_PP0_)] = ID($__DFFSE_PP0); - if (patmatch(pattern, "$__DFFS_PP1_")) found_match = true, direct_dict[ID($__DFFS_PP1_)] = ID($__DFFSE_PP1); - if (!found_match) - log_cmd_error("No cell types matched pattern '%s'.\n", pattern); - continue; - } - break; - } - extra_args(args, argidx, design); - - if (!direct_dict.empty()) { - log("Selected cell types for direct conversion:\n"); - for (auto &it : direct_dict) - log(" %s -> %s\n", log_id(it.first), log_id(it.second)); - } - - for (auto mod : design->selected_modules()) - if (!mod->has_processes_warn()) - { - if (unmap_mode) { - SigMap sigmap(mod); - for (auto cell : mod->selected_cells()) { - if (cell->type == ID($dffe)) { - if (min_ce_use >= 0) { - int ce_use = 0; - for (auto cell_other : mod->selected_cells()) { - if (cell_other->type != cell->type) - continue; - if (sigmap(cell->getPort(ID::EN)) == sigmap(cell_other->getPort(ID::EN))) - ce_use++; - } - if (ce_use >= min_ce_use) - continue; - } - - RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort(ID::D))); - mod->addDff(NEW_ID, cell->getPort(ID::CLK), tmp, cell->getPort(ID::Q), cell->getParam(ID::CLK_POLARITY).as_bool()); - if (cell->getParam(ID::EN_POLARITY).as_bool()) - mod->addMux(NEW_ID, cell->getPort(ID::Q), cell->getPort(ID::D), cell->getPort(ID::EN), tmp); - else - mod->addMux(NEW_ID, cell->getPort(ID::D), cell->getPort(ID::Q), cell->getPort(ID::EN), tmp); - mod->remove(cell); - continue; - } - if (cell->type.begins_with("$_DFFE_")) { - if (min_ce_use >= 0) { - int ce_use = 0; - for (auto cell_other : mod->selected_cells()) { - if (cell_other->type != cell->type) - continue; - if (sigmap(cell->getPort(ID::E)) == sigmap(cell_other->getPort(ID::E))) - ce_use++; - } - if (ce_use >= min_ce_use) - continue; - } - - bool clk_pol = cell->type.compare(7, 1, "P") == 0; - bool en_pol = cell->type.compare(8, 1, "P") == 0; - RTLIL::SigSpec tmp = mod->addWire(NEW_ID); - mod->addDff(NEW_ID, cell->getPort(ID::C), tmp, cell->getPort(ID::Q), clk_pol); - if (en_pol) - mod->addMux(NEW_ID, cell->getPort(ID::Q), cell->getPort(ID::D), cell->getPort(ID::E), tmp); - else - mod->addMux(NEW_ID, cell->getPort(ID::D), cell->getPort(ID::Q), cell->getPort(ID::E), tmp); - mod->remove(cell); - continue; - } - } - continue; - } - - Dff2dffeWorker worker(mod, direct_dict); - worker.run(); - } - } -} Dff2dffePass; - -PRIVATE_NAMESPACE_END diff --git a/passes/techmap/dff2dffs.cc b/passes/techmap/dff2dffs.cc deleted file mode 100644 index c155297d9..000000000 --- a/passes/techmap/dff2dffs.cc +++ /dev/null @@ -1,165 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * Copyright (C) 2018 David Shah <dave@ds0.me> - * - * 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 Dff2dffsPass : public Pass { - Dff2dffsPass() : Pass("dff2dffs", "process sync set/reset with SR over CE priority") { } - void help() YS_OVERRIDE - { - log("\n"); - log(" dff2dffs [options] [selection]\n"); - log("\n"); - log("Merge synchronous set/reset $_MUX_ cells to create $__DFFS_[NP][NP][01], to be run before\n"); - log("dff2dffe for SR over CE priority.\n"); - log("\n"); - log(" -match-init\n"); - log(" Disallow merging synchronous set/reset that has polarity opposite of the\n"); - log(" output wire's init attribute (if any).\n"); - log("\n"); - } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing dff2dffs pass (merge synchronous set/reset into FF cells).\n"); - - bool match_init = false; - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - // if (args[argidx] == "-singleton") { - // singleton_mode = true; - // continue; - // } - if (args[argidx] == "-match-init") { - match_init = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - pool<IdString> dff_types; - dff_types.insert(ID($_DFF_N_)); - dff_types.insert(ID($_DFF_P_)); - - for (auto module : design->selected_modules()) - { - log("Merging set/reset $_MUX_ cells into DFFs in %s.\n", log_id(module)); - - SigMap sigmap(module); - dict<SigBit, Cell*> sr_muxes; - vector<Cell*> ff_cells; - - for (auto cell : module->selected_cells()) - { - if (dff_types.count(cell->type)) { - ff_cells.push_back(cell); - continue; - } - - if (cell->type != ID($_MUX_)) - continue; - - SigBit bit_a = sigmap(cell->getPort(ID::A)); - SigBit bit_b = sigmap(cell->getPort(ID::B)); - - if (bit_a.wire == nullptr || bit_b.wire == nullptr) - sr_muxes[sigmap(cell->getPort(ID::Y))] = cell; - } - - for (auto cell : ff_cells) - { - SigSpec sig_d = cell->getPort(ID::D); - - if (GetSize(sig_d) < 1) - continue; - - SigBit bit_d = sigmap(sig_d[0]); - - if (sr_muxes.count(bit_d) == 0) - continue; - - Cell *mux_cell = sr_muxes.at(bit_d); - SigBit bit_a = sigmap(mux_cell->getPort(ID::A)); - SigBit bit_b = sigmap(mux_cell->getPort(ID::B)); - SigBit bit_s = sigmap(mux_cell->getPort(ID::S)); - - SigBit sr_val, sr_sig; - bool invert_sr; - sr_sig = bit_s; - if (bit_a.wire == nullptr) { - bit_d = bit_b; - sr_val = bit_a; - invert_sr = true; - } else { - log_assert(bit_b.wire == nullptr); - bit_d = bit_a; - sr_val = bit_b; - invert_sr = false; - } - - if (match_init) { - SigBit bit_q = cell->getPort(ID::Q); - if (bit_q.wire) { - auto it = bit_q.wire->attributes.find(ID::init); - if (it != bit_q.wire->attributes.end()) { - auto init_val = it->second[bit_q.offset]; - if (init_val == State::S1 && sr_val != State::S1) - continue; - if (init_val == State::S0 && sr_val != State::S0) - continue; - } - } - } - - log(" Merging %s (A=%s, B=%s, S=%s) into %s (%s).\n", log_id(mux_cell), - log_signal(bit_a), log_signal(bit_b), log_signal(bit_s), log_id(cell), log_id(cell->type)); - - if (sr_val == State::S1) { - if (cell->type == ID($_DFF_N_)) { - if (invert_sr) cell->type = ID($__DFFS_NN1_); - else cell->type = ID($__DFFS_NP1_); - } else { - log_assert(cell->type == ID($_DFF_P_)); - if (invert_sr) cell->type = ID($__DFFS_PN1_); - else cell->type = ID($__DFFS_PP1_); - } - } else { - if (cell->type == ID($_DFF_N_)) { - if (invert_sr) cell->type = ID($__DFFS_NN0_); - else cell->type = ID($__DFFS_NP0_); - } else { - log_assert(cell->type == ID($_DFF_P_)); - if (invert_sr) cell->type = ID($__DFFS_PN0_); - else cell->type = ID($__DFFS_PP0_); - } - } - cell->setPort(ID::R, sr_sig); - cell->setPort(ID::D, bit_d); - } - } - } -} Dff2dffsPass; - -PRIVATE_NAMESPACE_END diff --git a/passes/techmap/dffinit.cc b/passes/techmap/dffinit.cc index 35645582b..44af043db 100644 --- a/passes/techmap/dffinit.cc +++ b/passes/techmap/dffinit.cc @@ -19,13 +19,14 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/ffinit.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct DffinitPass : public Pass { DffinitPass() : Pass("dffinit", "set INIT param on FF cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -54,7 +55,7 @@ struct DffinitPass : public Pass { log(" the already defined initial value.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing DFFINIT pass (set INIT param on FF cells).\n"); @@ -94,29 +95,10 @@ struct DffinitPass : public Pass { for (auto module : design->selected_modules()) { SigMap sigmap(module); - dict<SigBit, State> init_bits; - pool<SigBit> cleanup_bits; - pool<SigBit> used_bits; - - for (auto wire : module->selected_wires()) { - if (wire->attributes.count(ID::init)) { - Const value = wire->attributes.at(ID::init); - for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++) - if (value[i] != State::Sx) - init_bits[sigmap(SigBit(wire, i))] = value[i]; - } - if (wire->port_output) - for (auto bit : sigmap(wire)) - used_bits.insert(bit); - } + FfInitVals initvals(&sigmap, module); for (auto cell : module->selected_cells()) { - for (auto it : cell->connections()) - if (!cell->known() || cell->input(it.first)) - for (auto bit : sigmap(it.second)) - used_bits.insert(bit); - if (ff_types.count(cell->type) == 0) continue; @@ -131,17 +113,18 @@ struct DffinitPass : public Pass { if (cell->hasParam(it.second)) value = cell->getParam(it.second); + Const initval = initvals(sig); + initvals.remove_init(sig); for (int i = 0; i < GetSize(sig); i++) { - if (init_bits.count(sig[i]) == 0) + if (initval[i] == State::Sx) continue; while (GetSize(value.bits) <= i) value.bits.push_back(State::S0); - if (noreinit && value.bits[i] != State::Sx && value.bits[i] != init_bits.at(sig[i])) + if (noreinit && value.bits[i] != State::Sx && value.bits[i] != initval[i]) log_error("Trying to assign a different init value for %s.%s.%s which technically " "have a conflicted init value.\n", log_id(module), log_id(cell), log_id(it.second)); - value.bits[i] = init_bits.at(sig[i]); - cleanup_bits.insert(sig[i]); + value.bits[i] = initval[i]; } if (highlow_mode && GetSize(value) != 0) { @@ -161,23 +144,6 @@ struct DffinitPass : public Pass { } } } - - for (auto wire : module->selected_wires()) - if (wire->attributes.count(ID::init)) { - Const &value = wire->attributes.at(ID::init); - bool do_cleanup = true; - for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++) { - SigBit bit = sigmap(SigBit(wire, i)); - if (cleanup_bits.count(bit) || !used_bits.count(bit)) - value[i] = State::Sx; - else if (value[i] != State::Sx) - do_cleanup = false; - } - if (do_cleanup) { - log("Removing init attribute from wire %s.%s.\n", log_id(module), log_id(wire)); - wire->attributes.erase(ID::init); - } - } } } } DffinitPass; diff --git a/passes/techmap/dfflegalize.cc b/passes/techmap/dfflegalize.cc new file mode 100644 index 000000000..c1e7e557d --- /dev/null +++ b/passes/techmap/dfflegalize.cc @@ -0,0 +1,1323 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Marcelina Kościelnicka <mwk@0x04.net> + * + * 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" +#include "kernel/ffinit.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +enum FfType { + FF_DFF, + FF_DFFE, + FF_ADFF0, + FF_ADFF1, + FF_ADFFE0, + FF_ADFFE1, + FF_DFFSR, + FF_DFFSRE, + FF_SDFF0, + FF_SDFF1, + FF_SDFFE0, + FF_SDFFE1, + FF_SDFFCE0, + FF_SDFFCE1, + FF_SR, + FF_DLATCH, + FF_ADLATCH0, + FF_ADLATCH1, + FF_DLATCHSR, + NUM_FFTYPES, +}; + +enum FfNeg { + NEG_R = 0x1, + NEG_S = 0x2, + NEG_E = 0x4, + NEG_C = 0x8, + NUM_NEG = 0x10, +}; + +enum FfInit { + INIT_X = 0x1, + INIT_0 = 0x2, + INIT_1 = 0x4, +}; + +struct DffLegalizePass : public Pass { + DffLegalizePass() : Pass("dfflegalize", "convert FFs to types supported by the target") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" dfflegalize [options] [selection]\n"); + log("\n"); + log("Converts FFs to types supported by the target.\n"); + log("\n"); + log(" -cell <cell_type_pattern> <init_values>\n"); + log(" specifies a supported group of FF cells. <cell_type_pattern>\n"); + log(" is a yosys internal fine cell name, where ? characters can be\n"); + log(" as a wildcard matching any character. <init_values> specifies\n"); + log(" which initialization values these FF cells can support, and can\n"); + log(" be one of:\n"); + log("\n"); + log(" - x (no init value supported)\n"); + log(" - 0\n"); + log(" - 1\n"); + log(" - r (init value has to match reset value, only for some FF types)\n"); + log(" - 01 (both 0 and 1 supported).\n"); + log("\n"); + log(" -mince <num>\n"); + log(" specifies a minimum number of FFs that should be using any given\n"); + log(" clock enable signal. If a clock enable signal doesn't meet this\n"); + log(" threshold, it is unmapped into soft logic.\n"); + log("\n"); + log(" -minsrst <num>\n"); + log(" specifies a minimum number of FFs that should be using any given\n"); + log(" sync set/reset signal. If a sync set/reset signal doesn't meet this\n"); + log(" threshold, it is unmapped into soft logic.\n"); + log("\n"); + log("The following cells are supported by this pass (ie. will be ingested,\n"); + log("and can be specified as allowed targets):\n"); + log("\n"); + log("- $_DFF_[NP]_\n"); + log("- $_DFFE_[NP][NP]_\n"); + log("- $_DFF_[NP][NP][01]_\n"); + log("- $_DFFE_[NP][NP][01][NP]_\n"); + log("- $_DFFSR_[NP][NP][NP]_\n"); + log("- $_DFFSRE_[NP][NP][NP][NP]_\n"); + log("- $_SDFF_[NP][NP][01]_\n"); + log("- $_SDFFE_[NP][NP][01][NP]_\n"); + log("- $_SDFFCE_[NP][NP][01][NP]_\n"); + log("- $_SR_[NP][NP]_\n"); + log("- $_DLATCH_[NP]_\n"); + log("- $_DLATCH_[NP][NP][01]_\n"); + log("- $_DLATCHSR_[NP][NP][NP]_\n"); + log("\n"); + log("The following transformations are performed by this pass:"); + log("\n"); + log("- upconversion from a less capable cell to a more capable cell, if the less"); + log(" capable cell is not supported (eg. dff -> dffe, or adff -> dffsr)"); + log("\n"); + log("- unmapping FFs with clock enable (due to unsupported cell type or -mince)"); + log("\n"); + log("- unmapping FFs with sync reset (due to unsupported cell type or -minsrst)"); + log("\n"); + log("- adding inverters on the control pins (due to unsupported polarity)"); + log("\n"); + log("- adding inverters on the D and Q pins and inverting the init/reset values\n"); + log(" (due to unsupported init or reset value)"); + log("\n"); + log("- converting sr into adlatch (by tying D to 1 and using E as set input)"); + log("\n"); + log("- emulating unsupported dffsr cell by adff + adff + sr + mux"); + log("\n"); + log("- emulating unsupported dlatchsr cell by adlatch + adlatch + sr + mux"); + log("\n"); + log("- emulating adff when the (reset, init) value combination is unsupported by\n"); + log(" dff + adff + dlatch + mux"); + log("\n"); + log("- emulating adlatch when the (reset, init) value combination is unsupported by\n"); + log("- dlatch + adlatch + dlatch + mux"); + log("\n"); + log("If the pass is unable to realize a given cell type (eg. adff when only plain dff"); + log("is available), an error is raised."); + } + + // Table of all supported cell types. + // First index in the array is one of the FF_* values, second + // index is the set of negative-polarity inputs (OR of NEG_* + // values), and the value is the set of supported init values + // (OR of INIT_* values). + int supported_cells_neg[NUM_FFTYPES][NUM_NEG]; + // Aggregated table ignoring signal polarity. + int supported_cells[NUM_FFTYPES]; + // Aggregated for all *dff* cells. + int supported_dff; + // Aggregated for all dffsr* cells. + int supported_dffsr; + // Aggregated for all adff* cells. + int supported_adff0; + int supported_adff1; + // Aggregated for all sdff* cells. + int supported_sdff0; + int supported_sdff1; + // Aggregated for all ways to obtain a SR latch. + int supported_sr; + // Aggregated for all *dlatch* cells. + int supported_dlatch; + + int mince; + int minsrst; + + dict<SigBit, int> ce_used; + dict<SigBit, int> srst_used; + + SigMap sigmap; + FfInitVals initvals; + + int flip_initmask(int mask) { + int res = mask & INIT_X; + if (mask & INIT_0) + res |= INIT_1; + if (mask & INIT_1) + res |= INIT_0; + return res; + } + + void handle_ff(Cell *cell) { + std::string type_str = cell->type.str(); + + FfType ff_type; + int ff_neg = 0; + SigSpec sig_d; + SigSpec sig_q; + SigSpec sig_c; + SigSpec sig_e; + SigSpec sig_r; + SigSpec sig_s; + bool has_srst = false; + + if (cell->hasPort(ID::D)) + sig_d = cell->getPort(ID::D); + if (cell->hasPort(ID::Q)) + sig_q = cell->getPort(ID::Q); + if (cell->hasPort(ID::C)) + sig_c = cell->getPort(ID::C); + if (cell->hasPort(ID::E)) + sig_e = cell->getPort(ID::E); + if (cell->hasPort(ID::R)) + sig_r = cell->getPort(ID::R); + if (cell->hasPort(ID::S)) + sig_s = cell->getPort(ID::S); + + if (type_str.substr(0, 5) == "$_SR_") { + ff_type = FF_SR; + if (type_str[5] == 'N') + ff_neg |= NEG_S; + if (type_str[6] == 'N') + ff_neg |= NEG_R; + } else if (type_str.substr(0, 6) == "$_DFF_" && type_str.size() == 8) { + ff_type = FF_DFF; + if (type_str[6] == 'N') + ff_neg |= NEG_C; + } else if (type_str.substr(0, 7) == "$_DFFE_" && type_str.size() == 10) { + ff_type = FF_DFFE; + if (type_str[7] == 'N') + ff_neg |= NEG_C; + if (type_str[8] == 'N') + ff_neg |= NEG_E; + } else if (type_str.substr(0, 6) == "$_DFF_" && type_str.size() == 10) { + ff_type = type_str[8] == '1' ? FF_ADFF1 : FF_ADFF0; + if (type_str[6] == 'N') + ff_neg |= NEG_C; + if (type_str[7] == 'N') + ff_neg |= NEG_R; + } else if (type_str.substr(0, 7) == "$_DFFE_" && type_str.size() == 12) { + ff_type = type_str[9] == '1' ? FF_ADFFE1 : FF_ADFFE0; + if (type_str[7] == 'N') + ff_neg |= NEG_C; + if (type_str[8] == 'N') + ff_neg |= NEG_R; + if (type_str[10] == 'N') + ff_neg |= NEG_E; + } else if (type_str.substr(0, 8) == "$_DFFSR_" && type_str.size() == 12) { + ff_type = FF_DFFSR; + if (type_str[8] == 'N') + ff_neg |= NEG_C; + if (type_str[9] == 'N') + ff_neg |= NEG_S; + if (type_str[10] == 'N') + ff_neg |= NEG_R; + } else if (type_str.substr(0, 9) == "$_DFFSRE_" && type_str.size() == 14) { + ff_type = FF_DFFSRE; + if (type_str[9] == 'N') + ff_neg |= NEG_C; + if (type_str[10] == 'N') + ff_neg |= NEG_S; + if (type_str[11] == 'N') + ff_neg |= NEG_R; + if (type_str[12] == 'N') + ff_neg |= NEG_E; + } else if (type_str.substr(0, 7) == "$_SDFF_" && type_str.size() == 11) { + ff_type = type_str[9] == '1' ? FF_SDFF1 : FF_SDFF0; + if (type_str[7] == 'N') + ff_neg |= NEG_C; + if (type_str[8] == 'N') + ff_neg |= NEG_R; + has_srst = true; + } else if (type_str.substr(0, 8) == "$_SDFFE_" && type_str.size() == 13) { + ff_type = type_str[10] == '1' ? FF_SDFFE1 : FF_SDFFE0; + if (type_str[8] == 'N') + ff_neg |= NEG_C; + if (type_str[9] == 'N') + ff_neg |= NEG_R; + if (type_str[11] == 'N') + ff_neg |= NEG_E; + has_srst = true; + } else if (type_str.substr(0, 9) == "$_SDFFCE_" && type_str.size() == 14) { + ff_type = type_str[11] == '1' ? FF_SDFFCE1 : FF_SDFFCE0; + if (type_str[9] == 'N') + ff_neg |= NEG_C; + if (type_str[10] == 'N') + ff_neg |= NEG_R; + if (type_str[12] == 'N') + ff_neg |= NEG_E; + has_srst = true; + } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 11) { + ff_type = FF_DLATCH; + if (type_str[9] == 'N') + ff_neg |= NEG_E; + } else if (type_str.substr(0, 9) == "$_DLATCH_" && type_str.size() == 13) { + ff_type = type_str[11] == '1' ? FF_ADLATCH1 : FF_ADLATCH0; + if (type_str[9] == 'N') + ff_neg |= NEG_E; + if (type_str[10] == 'N') + ff_neg |= NEG_R; + } else if (type_str.substr(0, 11) == "$_DLATCHSR_" && type_str.size() == 15) { + ff_type = FF_DLATCHSR; + if (type_str[11] == 'N') + ff_neg |= NEG_E; + if (type_str[12] == 'N') + ff_neg |= NEG_S; + if (type_str[13] == 'N') + ff_neg |= NEG_R; + } else { + log_warning("Ignoring unknown ff type %s [%s.%s].\n", log_id(cell->type), log_id(cell->module->name), log_id(cell->name)); + return; + } + + State initval = initvals(sig_q[0]); + + FfInit initmask = INIT_X; + if (initval == State::S0) + initmask = INIT_0; + else if (initval == State::S1) + initmask = INIT_1; + const char *reason; + + bool kill_ce = mince && GetSize(sig_c) && GetSize(sig_e) && sig_e[0].wire && ce_used[sig_e[0]] < mince; + bool kill_srst = minsrst && has_srst && sig_r[0].wire && srst_used[sig_r[0]] < minsrst; + + while (!(supported_cells[ff_type] & initmask) || kill_ce || kill_srst) { + // Well, cell is not directly supported. Decide how to deal with it. + + if (ff_type == FF_DFF || ff_type == FF_DFFE) { + if (kill_ce) { + ff_type = FF_DFF; + goto unmap_enable; + } + if (!(supported_dff & initmask)) { + // This init value is not supported at all... + if (supported_dff & flip_initmask(initmask)) { + // The other one is, though. Negate D, Q, and init. +flip_dqi: + if (initval == State::S0) { + initval = State::S1; + initmask = INIT_1; + } else if (initval == State::S1) { + initval = State::S0; + initmask = INIT_0; + } + if (ff_type != FF_SR) + sig_d = cell->module->NotGate(NEW_ID, sig_d[0]); + SigBit new_q = SigSpec(cell->module->addWire(NEW_ID))[0]; + cell->module->addNotGate(NEW_ID, new_q, sig_q[0]); + initvals.remove_init(sig_q[0]); + initvals.set_init(new_q, initval); + sig_q = new_q; + continue; + } + if (!supported_dff) + reason = "dffs are not supported"; + else + reason = "initialized dffs are not supported"; + goto error; + } + + // Some DFF is supported with this init val. Just pick a type. + if (ff_type == FF_DFF) { + // Try adding a set or reset pin. + for (auto new_type: {FF_SDFF0, FF_SDFF1, FF_ADFF0, FF_ADFF1}) + if (supported_cells[new_type] & initmask) { + ff_type = new_type; + sig_r = State::S0; + goto cell_ok; + } + // Try adding both. + if (supported_cells[FF_DFFSR] & initmask) { + ff_type = FF_DFFSR; + sig_r = State::S0; + sig_s = State::S0; + break; + } + // Nope. Will need to add enable and go the DFFE route. + sig_e = State::S1; + if (supported_cells[FF_DFFE] & initmask) { + ff_type = FF_DFFE; + break; + } + } + // Try adding a set or reset pin. + for (auto new_type: {FF_SDFFE0, FF_SDFFE1, FF_SDFFCE0, FF_SDFFCE1, FF_ADFFE0, FF_ADFFE1}) + if (supported_cells[new_type] & initmask) { + ff_type = new_type; + sig_r = State::S0; + goto cell_ok; + } + // Try adding both. + if (supported_cells[FF_DFFSRE] & initmask) { + ff_type = FF_DFFSRE; + sig_r = State::S0; + sig_s = State::S0; + break; + } + + // Seems that no DFFs with enable are supported. + // The enable input needs to be unmapped. + // This should not be reached if we started from plain DFF. + log_assert(ff_type == FF_DFFE); + ff_type = FF_DFF; +unmap_enable: + if (ff_neg & NEG_E) + sig_d = cell->module->MuxGate(NEW_ID, sig_d[0], sig_q[0], sig_e[0]); + else + sig_d = cell->module->MuxGate(NEW_ID, sig_q[0], sig_d[0], sig_e[0]); + ff_neg &= ~NEG_E; + sig_e = SigSpec(); + kill_ce = false; + // Now try again as plain DFF. + continue; + } else if (ff_type == FF_ADFF0 || ff_type == FF_ADFF1 || ff_type == FF_ADFFE0 || ff_type == FF_ADFFE1) { + bool has_set = ff_type == FF_ADFF1 || ff_type == FF_ADFFE1; + bool has_en = ff_type == FF_ADFFE0 || ff_type == FF_ADFFE1; + if (kill_ce) { + ff_type = has_set ? FF_ADFF1 : FF_ADFF0; + goto unmap_enable; + } + if (!has_en && (supported_cells[has_set ? FF_ADFFE1 : FF_ADFFE0] & initmask)) { + // Just add enable. + sig_e = State::S1; + ff_type = has_set ? FF_ADFFE1 : FF_ADFFE0; + break; + } + if (supported_cells[has_en ? FF_DFFSRE : FF_DFFSR] & initmask) { +adff_to_dffsr: + // Throw in a set/reset, retry in DFFSR/DFFSRE branch. + if (has_set) { + sig_s = sig_r; + sig_r = State::S0; + if (ff_neg & NEG_R) { + ff_neg &= ~NEG_R; + ff_neg |= NEG_S; + } + } else { + sig_s = State::S0; + } + if (has_en) + ff_type = FF_DFFSRE; + else + ff_type = FF_DFFSR; + continue; + } + if (has_en && (supported_cells[has_set ? FF_ADFF1 : FF_ADFF0] & initmask)) { + // Unmap enable. + ff_type = has_set ? FF_ADFF1 : FF_ADFF0; + goto unmap_enable; + } + if (supported_dffsr & initmask) { + goto adff_to_dffsr; + } + log_assert(!((has_set ? supported_adff1 : supported_adff0) & initmask)); + // Alright, so this particular combination of initval and + // resetval is not natively supported. First, try flipping + // them both to see whether this helps. + int flipmask = flip_initmask(initmask); + if ((has_set ? supported_adff0 : supported_adff1) & flipmask) { + // Checks out, do it. + ff_type = has_en ? (has_set ? FF_ADFFE0 : FF_ADFFE1) : (has_set ? FF_ADFF0 : FF_ADFF1); + goto flip_dqi; + } + + if (!supported_adff0 && !supported_adff1) { + reason = "dffs with async set or reset are not supported"; + goto error; + } + if (!(supported_dff & ~INIT_X)) { + reason = "initialized dffs are not supported"; + goto error; + } + // If we got here, initialized dff is supported, but not this + // particular reset+init combination (nor its negation). + // The only hope left is breaking down to adff + dff + dlatch + mux. + if (!(supported_dlatch & ~INIT_X)) { + reason = "unsupported initial value and async reset value combination"; + goto error; + } + + // If we have to unmap enable anyway, do it before breakdown. + if (has_en && !supported_cells[FF_ADFFE0] && !supported_cells[FF_ADFFE1]) { + ff_type = has_set ? FF_ADFF1 : FF_ADFF0; + goto unmap_enable; + } + + log_warning("Emulating mismatched async reset and init with several FFs and a mux for %s.%s\n", log_id(cell->module->name), log_id(cell->name)); + initvals.remove_init(sig_q[0]); + Wire *adff_q = cell->module->addWire(NEW_ID); + Wire *dff_q = cell->module->addWire(NEW_ID); + Wire *sel_q = cell->module->addWire(NEW_ID); + initvals.set_init(SigBit(dff_q, 0), initval); + initvals.set_init(SigBit(sel_q, 0), State::S0); + Cell *cell_dff; + Cell *cell_adff; + Cell *cell_sel; + if (!has_en) { + cell_dff = cell->module->addDffGate(NEW_ID, sig_c, sig_d, dff_q, !(ff_neg & NEG_C)); + cell_adff = cell->module->addAdffGate(NEW_ID, sig_c, sig_r, sig_d, adff_q, has_set, !(ff_neg & NEG_C), !(ff_neg & NEG_R)); + } else { + cell_dff = cell->module->addDffeGate(NEW_ID, sig_c, sig_e, sig_d, dff_q, !(ff_neg & NEG_C), !(ff_neg & NEG_E)); + cell_adff = cell->module->addAdffeGate(NEW_ID, sig_c, sig_e, sig_r, sig_d, adff_q, has_set, !(ff_neg & NEG_C), !(ff_neg & NEG_E), !(ff_neg & NEG_R)); + } + cell_sel = cell->module->addDlatchGate(NEW_ID, sig_r, State::S1, sel_q, !(ff_neg & NEG_R)); + cell->module->addMuxGate(NEW_ID, dff_q, adff_q, sel_q, sig_q); + + // Bye, cell. + cell->module->remove(cell); + handle_ff(cell_dff); + handle_ff(cell_adff); + handle_ff(cell_sel); + return; + } else if (ff_type == FF_DFFSR || ff_type == FF_DFFSRE) { + if (kill_ce) { + ff_type = FF_DFFSR; + goto unmap_enable; + } + // First, see if mapping/unmapping enable will help. + if (supported_cells[FF_DFFSRE] & initmask) { + ff_type = FF_DFFSRE; + sig_e = State::S1; + break; + } + if (supported_cells[FF_DFFSR] & initmask) { + ff_type = FF_DFFSR; + goto unmap_enable; + } + if (supported_dffsr & flip_initmask(initmask)) { +flip_dqisr:; + log_warning("Flipping D/Q/init and inserting set/reset fixup to handle init value on %s.%s [%s]\n", log_id(cell->module->name), log_id(cell->name), log_id(cell->type)); + SigSpec new_r; + bool neg_r = (ff_neg & NEG_R); + bool neg_s = (ff_neg & NEG_S); + if (!(ff_neg & NEG_S)) { + if (!(ff_neg & NEG_R)) + new_r = cell->module->AndnotGate(NEW_ID, sig_s, sig_r); + else + new_r = cell->module->AndGate(NEW_ID, sig_s, sig_r); + } else { + if (!(ff_neg & NEG_R)) + new_r = cell->module->OrGate(NEW_ID, sig_s, sig_r); + else + new_r = cell->module->OrnotGate(NEW_ID, sig_s, sig_r); + } + ff_neg &= ~(NEG_R | NEG_S); + if (neg_r) + ff_neg |= NEG_S; + if (neg_s) + ff_neg |= NEG_R; + sig_s = sig_r; + sig_r = new_r; + goto flip_dqi; + } + // No native DFFSR. However, if we can conjure + // a SR latch and ADFF, it can still be emulated. + int flipmask = flip_initmask(initmask); + bool init0 = true; + bool init1 = true; + State initsel = State::Sx; + if (((supported_adff0 & initmask) || (supported_adff1 & flipmask)) && ((supported_adff1 & initmask) || (supported_adff0 & flipmask)) && supported_sr) { + // OK + } else if (((supported_adff0 & initmask) || (supported_adff1 & flipmask)) && (supported_sr & INIT_0)) { + init1 = false; + initsel = State::S0; + } else if (((supported_adff1 & initmask) || (supported_adff0 & flipmask)) && (supported_sr & INIT_1)) { + init0 = false; + initsel = State::S1; + } else if (((supported_adff0 & initmask) || (supported_adff1 & flipmask)) && (supported_sr & INIT_1)) { + init1 = false; + initsel = State::S0; + } else if (((supported_adff1 & initmask) || (supported_adff0 & flipmask)) && (supported_sr & INIT_0)) { + init0 = false; + initsel = State::S1; + } else { + if (!supported_dffsr) + reason = "dffs with async set and reset are not supported"; + else + reason = "initialized dffs with async set and reset are not supported"; + goto error; + } + + // If we have to unmap enable anyway, do it before breakdown. + if (ff_type == FF_DFFSRE && !supported_cells[FF_ADFFE0] && !supported_cells[FF_ADFFE1]) { + ff_type = FF_DFFSR; + goto unmap_enable; + } + + log_warning("Emulating async set + reset with several FFs and a mux for %s.%s\n", log_id(cell->module->name), log_id(cell->name)); + initvals.remove_init(sig_q[0]); + Wire *adff0_q = cell->module->addWire(NEW_ID); + Wire *adff1_q = cell->module->addWire(NEW_ID); + Wire *sel_q = cell->module->addWire(NEW_ID); + if (init0) + initvals.set_init(SigBit(adff0_q, 0), initval); + if (init1) + initvals.set_init(SigBit(adff1_q, 0), initval); + initvals.set_init(SigBit(sel_q, 0), initsel); + Cell *cell_adff0; + Cell *cell_adff1; + Cell *cell_sel; + if (ff_type == FF_DFFSR) { + cell_adff0 = cell->module->addAdffGate(NEW_ID, sig_c, sig_r, sig_d, adff0_q, false, !(ff_neg & NEG_C), !(ff_neg & NEG_R)); + cell_adff1 = cell->module->addAdffGate(NEW_ID, sig_c, sig_s, sig_d, adff1_q, true, !(ff_neg & NEG_C), !(ff_neg & NEG_S)); + } else { + cell_adff0 = cell->module->addAdffeGate(NEW_ID, sig_c, sig_e, sig_r, sig_d, adff0_q, false, !(ff_neg & NEG_C), !(ff_neg & NEG_E), !(ff_neg & NEG_R)); + cell_adff1 = cell->module->addAdffeGate(NEW_ID, sig_c, sig_e, sig_s, sig_d, adff1_q, true, !(ff_neg & NEG_C), !(ff_neg & NEG_E), !(ff_neg & NEG_S)); + } + cell_sel = cell->module->addSrGate(NEW_ID, sig_s, sig_r, sel_q, !(ff_neg & NEG_S), !(ff_neg & NEG_R)); + cell->module->addMuxGate(NEW_ID, adff0_q, adff1_q, sel_q, sig_q); + + // Bye, cell. + cell->module->remove(cell); + handle_ff(cell_adff0); + handle_ff(cell_adff1); + handle_ff(cell_sel); + return; + } else if (ff_type == FF_SR) { + if (supported_cells[FF_ADLATCH0] & initmask || supported_cells[FF_ADLATCH1] & flip_initmask(initmask)) { + // Convert to ADLATCH0. May get converted to ADLATCH1. + ff_type = FF_ADLATCH0; + sig_e = sig_s; + sig_d = State::S1; + if (ff_neg & NEG_S) { + ff_neg &= ~NEG_S; + ff_neg |= NEG_E; + } + continue; + } else if (supported_cells[FF_DLATCHSR] & initmask) { + // Upgrade to DLATCHSR. + ff_type = FF_DLATCHSR; + sig_e = State::S0; + sig_d = State::Sx; + break; + } else if (supported_dffsr & initmask) { + // Upgrade to DFFSR. May get further upgraded to DFFSRE. + ff_type = FF_DFFSR; + sig_c = State::S0; + sig_d = State::Sx; + continue; + } else if (supported_sr & flip_initmask(initmask)) { + goto flip_dqisr; + } else { + if (!supported_sr) + reason = "sr latches are not supported"; + else + reason = "initialized sr latches are not supported"; + goto error; + } + } else if (ff_type == FF_DLATCH) { + if (!(supported_dlatch & initmask)) { + // This init value is not supported at all... + if (supported_dlatch & flip_initmask(initmask)) + goto flip_dqi; + + if ((sig_d == State::S0 && (supported_adff0 & initmask)) || + (sig_d == State::S1 && (supported_adff1 & initmask)) || + (sig_d == State::S0 && (supported_adff1 & flip_initmask(initmask))) || + (sig_d == State::S1 && (supported_adff0 & flip_initmask(initmask))) + ) { + // Special case: const-D dlatch can be converted into adff with const clock. + ff_type = (sig_d == State::S0) ? FF_ADFF0 : FF_ADFF1; + if (ff_neg & NEG_E) { + ff_neg &= ~NEG_E; + ff_neg |= NEG_R; + } + sig_r = sig_e; + sig_d = State::Sx; + sig_c = State::S1; + continue; + } + + if (!supported_dlatch) + reason = "dlatch are not supported"; + else + reason = "initialized dlatch are not supported"; + goto error; + } + + // Some DLATCH is supported with this init val. Just pick a type. + if (supported_cells[FF_ADLATCH0] & initmask) { + ff_type = FF_ADLATCH0; + sig_r = State::S0; + break; + } + if (supported_cells[FF_ADLATCH1] & initmask) { + ff_type = FF_ADLATCH1; + sig_r = State::S0; + break; + } + if (supported_cells[FF_DLATCHSR] & initmask) { + ff_type = FF_DLATCHSR; + sig_r = State::S0; + sig_s = State::S0; + break; + } + log_assert(0); + } else if (ff_type == FF_ADLATCH0 || ff_type == FF_ADLATCH1) { + if (supported_cells[FF_DLATCHSR] & initmask) { + if (ff_type == FF_ADLATCH1) { + sig_s = sig_r; + sig_r = State::S0; + if (ff_neg & NEG_R) { + ff_neg &= ~NEG_R; + ff_neg |= NEG_S; + } + } else { + sig_s = State::S0; + } + ff_type = FF_DLATCHSR; + break; + } + FfType flip_type = ff_type == FF_ADLATCH0 ? FF_ADLATCH1 : FF_ADLATCH0; + if ((supported_cells[flip_type] | supported_cells[FF_DLATCHSR]) & flip_initmask(initmask)) { + ff_type = flip_type; + goto flip_dqi; + } + + if (!supported_cells[FF_ADLATCH0] && !supported_cells[FF_ADLATCH1] && !supported_cells[FF_DLATCHSR]) { + reason = "dlatch with async set or reset are not supported"; + goto error; + } + if (!(supported_dlatch & ~INIT_X)) { + reason = "initialized dlatch are not supported"; + goto error; + } + + if (!(supported_dlatch & ~INIT_X)) { + reason = "initialized dlatch are not supported"; + goto error; + } + // If we got here, initialized dlatch is supported, but not this + // particular reset+init combination (nor its negation). + // The only hope left is breaking down to adff + dff + dlatch + mux. + + log_warning("Emulating mismatched async reset and init with several latches and a mux for %s.%s\n", log_id(cell->module->name), log_id(cell->name)); + initvals.remove_init(sig_q[0]); + Wire *adlatch_q = cell->module->addWire(NEW_ID); + Wire *dlatch_q = cell->module->addWire(NEW_ID); + Wire *sel_q = cell->module->addWire(NEW_ID); + initvals.set_init(SigBit(dlatch_q, 0), initval); + initvals.set_init(SigBit(sel_q, 0), State::S0); + Cell *cell_dlatch; + Cell *cell_adlatch; + Cell *cell_sel; + cell_dlatch = cell->module->addDlatchGate(NEW_ID, sig_e, sig_d, dlatch_q, !(ff_neg & NEG_E)); + cell_adlatch = cell->module->addAdlatchGate(NEW_ID, sig_e, sig_r, sig_d, adlatch_q, ff_type == FF_ADLATCH1, !(ff_neg & NEG_E), !(ff_neg & NEG_R)); + cell_sel = cell->module->addDlatchGate(NEW_ID, sig_r, State::S1, sel_q, !(ff_neg & NEG_R)); + cell->module->addMuxGate(NEW_ID, dlatch_q, adlatch_q, sel_q, sig_q); + + // Bye, cell. + cell->module->remove(cell); + handle_ff(cell_dlatch); + handle_ff(cell_adlatch); + handle_ff(cell_sel); + return; + } else if (ff_type == FF_DLATCHSR) { + if (supported_cells[FF_DLATCHSR] & flip_initmask(initmask)) { + goto flip_dqisr; + } + // No native DFFSR. However, if we can conjure + // a SR latch and ADFF, it can still be emulated. + int flipmask = flip_initmask(initmask); + bool init0 = true; + bool init1 = true; + State initsel = State::Sx; + if (((supported_cells[FF_ADLATCH0] & initmask) || (supported_cells[FF_ADLATCH1] & flipmask)) && ((supported_cells[FF_ADLATCH1] & initmask) || (supported_cells[FF_ADLATCH0] & flipmask)) && supported_sr) { + // OK + } else if (((supported_cells[FF_ADLATCH0] & initmask) || (supported_cells[FF_ADLATCH1] & flipmask)) && (supported_sr & INIT_0)) { + init1 = false; + initsel = State::S0; + } else if (((supported_cells[FF_ADLATCH1] & initmask) || (supported_cells[FF_ADLATCH0] & flipmask)) && (supported_sr & INIT_1)) { + init0 = false; + initsel = State::S1; + } else if (((supported_cells[FF_ADLATCH0] & initmask) || (supported_cells[FF_ADLATCH1] & flipmask)) && (supported_sr & INIT_1)) { + init1 = false; + initsel = State::S0; + } else if (((supported_cells[FF_ADLATCH1] & initmask) || (supported_cells[FF_ADLATCH0] & flipmask)) && (supported_sr & INIT_0)) { + init0 = false; + initsel = State::S1; + } else { + if (!supported_cells[FF_DLATCHSR]) + reason = "dlatch with async set and reset are not supported"; + else + reason = "initialized dlatch with async set and reset are not supported"; + goto error; + } + + log_warning("Emulating async set + reset with several latches and a mux for %s.%s\n", log_id(cell->module->name), log_id(cell->name)); + initvals.remove_init(sig_q[0]); + Wire *adlatch0_q = cell->module->addWire(NEW_ID); + Wire *adlatch1_q = cell->module->addWire(NEW_ID); + Wire *sel_q = cell->module->addWire(NEW_ID); + if (init0) + initvals.set_init(SigBit(adlatch0_q, 0), initval); + if (init1) + initvals.set_init(SigBit(adlatch1_q, 0), initval); + initvals.set_init(SigBit(sel_q, 0), initsel); + Cell *cell_adlatch0; + Cell *cell_adlatch1; + Cell *cell_sel; + cell_adlatch0 = cell->module->addAdlatchGate(NEW_ID, sig_e, sig_r, sig_d, adlatch0_q, false, !(ff_neg & NEG_E), !(ff_neg & NEG_R)); + cell_adlatch1 = cell->module->addAdlatchGate(NEW_ID, sig_e, sig_s, sig_d, adlatch1_q, true, !(ff_neg & NEG_E), !(ff_neg & NEG_S)); + cell_sel = cell->module->addSrGate(NEW_ID, sig_s, sig_r, sel_q, !(ff_neg & NEG_S), !(ff_neg & NEG_R)); + cell->module->addMuxGate(NEW_ID, adlatch0_q, adlatch1_q, sel_q, sig_q); + + // Bye, cell. + cell->module->remove(cell); + handle_ff(cell_adlatch0); + handle_ff(cell_adlatch1); + handle_ff(cell_sel); + return; + } else if (ff_type == FF_SDFF0 || ff_type == FF_SDFF1 || ff_type == FF_SDFFE0 || ff_type == FF_SDFFE1 || ff_type == FF_SDFFCE0 || ff_type == FF_SDFFCE1) { + bool has_set = ff_type == FF_SDFF1 || ff_type == FF_SDFFE1 || ff_type == FF_SDFFCE1; + bool has_en = ff_type == FF_SDFFE0 || ff_type == FF_SDFFE1; + bool has_ce = ff_type == FF_SDFFCE0 || ff_type == FF_SDFFCE1; + + if (has_en) { + if (kill_ce || kill_srst) { + ff_type = has_set ? FF_SDFF1 : FF_SDFF0; + goto unmap_enable; + } + } else if (has_ce) { + if (kill_ce || kill_srst) + goto unmap_srst; + } else { + log_assert(!kill_ce); + if (kill_srst) + goto unmap_srst; + } + + if (!has_ce) { + if (!has_en && (supported_cells[has_set ? FF_SDFFE1 : FF_SDFFE0] & initmask)) { + // Just add enable. + sig_e = State::S1; + ff_type = has_set ? FF_SDFFE1 : FF_SDFFE0; + break; + } + if (!has_en && (supported_cells[has_set ? FF_SDFFCE1 : FF_SDFFCE0] & initmask)) { + // Just add enable. + sig_e = State::S1; + ff_type = has_set ? FF_SDFFCE1 : FF_SDFFCE0; + break; + } + if (has_en && (supported_cells[has_set ? FF_SDFFCE1 : FF_SDFFCE0] & initmask)) { + // Convert sdffe to sdffce + if (!(ff_neg & NEG_E)) { + if (!(ff_neg & NEG_R)) + sig_e = cell->module->OrGate(NEW_ID, sig_e, sig_r); + else + sig_e = cell->module->OrnotGate(NEW_ID, sig_e, sig_r); + } else { + if (!(ff_neg & NEG_R)) + sig_e = cell->module->AndnotGate(NEW_ID, sig_e, sig_r); + else + sig_e = cell->module->AndGate(NEW_ID, sig_e, sig_r); + } + ff_type = has_set ? FF_SDFFCE1 : FF_SDFFCE0; + break; + } + if (has_en && (supported_cells[has_set ? FF_SDFF1 : FF_SDFF0] & initmask)) { + // Unmap enable. + ff_type = has_set ? FF_SDFF1 : FF_SDFF0; + goto unmap_enable; + } + log_assert(!((has_set ? supported_sdff1 : supported_sdff0) & initmask)); + } else { + if ((has_set ? supported_sdff1 : supported_sdff0) & initmask) { + // Convert sdffce to sdffe, which may be further converted to sdff. + if (!(ff_neg & NEG_R)) { + if (!(ff_neg & NEG_E)) + sig_r = cell->module->AndGate(NEW_ID, sig_r, sig_e); + else + sig_r = cell->module->AndnotGate(NEW_ID, sig_r, sig_e); + } else { + if (!(ff_neg & NEG_E)) + sig_r = cell->module->OrnotGate(NEW_ID, sig_r, sig_e); + else + sig_r = cell->module->OrGate(NEW_ID, sig_r, sig_e); + } + ff_type = has_set ? FF_SDFFE1 : FF_SDFFE0; + continue; + } + } + // Alright, so this particular combination of initval and + // resetval is not natively supported. First, try flipping + // them both to see whether this helps. + if ((has_set ? supported_sdff0 : supported_sdff1) & flip_initmask(initmask)) { + // Checks out, do it. + ff_type = has_ce ? (has_set ? FF_SDFFCE0 : FF_SDFFCE1) : has_en ? (has_set ? FF_SDFFE0 : FF_SDFFE1) : (has_set ? FF_SDFF0 : FF_SDFF1); + goto flip_dqi; + } + + // Nope. No way to get SDFF* of the right kind, so unmap it. + // For SDFFE, the enable has to be unmapped first. + if (has_en) { + ff_type = has_set ? FF_SDFF1 : FF_SDFF0; + goto unmap_enable; + } +unmap_srst: + if (has_ce) + ff_type = FF_DFFE; + else + ff_type = FF_DFF; + if (ff_neg & NEG_R) + sig_d = cell->module->MuxGate(NEW_ID, has_set ? State::S1 : State::S0, sig_d[0], sig_r[0]); + else + sig_d = cell->module->MuxGate(NEW_ID, sig_d[0], has_set ? State::S1 : State::S0, sig_r[0]); + ff_neg &= ~NEG_R; + sig_r = SigSpec(); + kill_srst = false; + continue; + } else { + log_assert(0); + } + } +cell_ok: + + if (!(supported_cells_neg[ff_type][ff_neg] & initmask)) { + // Cell is supported, but not with those polarities. + // Will need to add some inverters. + + // Find the smallest value that xored with the neg mask + // results in a supported one — this results in preferentially + // inverting resets before clocks, etc. + int xneg; + for (xneg = 0; xneg < NUM_NEG; xneg++) + if (supported_cells_neg[ff_type][ff_neg ^ xneg] & initmask) + break; + log_assert(xneg < NUM_NEG); + if (xneg & NEG_R) + sig_r = cell->module->NotGate(NEW_ID, sig_r[0]); + if (xneg & NEG_S) + sig_s = cell->module->NotGate(NEW_ID, sig_s[0]); + if (xneg & NEG_E) + sig_e = cell->module->NotGate(NEW_ID, sig_e[0]); + if (xneg & NEG_C) + sig_c = cell->module->NotGate(NEW_ID, sig_c[0]); + ff_neg ^= xneg; + } + + cell->unsetPort(ID::D); + cell->unsetPort(ID::Q); + cell->unsetPort(ID::C); + cell->unsetPort(ID::E); + cell->unsetPort(ID::S); + cell->unsetPort(ID::R); + switch (ff_type) { + case FF_DFF: + cell->type = IdString(stringf("$_DFF_%c_", + (ff_neg & NEG_C) ? 'N' : 'P' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::C, sig_c); + break; + case FF_DFFE: + cell->type = IdString(stringf("$_DFFE_%c%c_", + (ff_neg & NEG_C) ? 'N' : 'P', + (ff_neg & NEG_E) ? 'N' : 'P' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::C, sig_c); + cell->setPort(ID::E, sig_e); + break; + case FF_ADFF0: + case FF_ADFF1: + cell->type = IdString(stringf("$_DFF_%c%c%c_", + (ff_neg & NEG_C) ? 'N' : 'P', + (ff_neg & NEG_R) ? 'N' : 'P', + (ff_type == FF_ADFF1) ? '1' : '0' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::C, sig_c); + cell->setPort(ID::R, sig_r); + break; + case FF_ADFFE0: + case FF_ADFFE1: + cell->type = IdString(stringf("$_DFFE_%c%c%c%c_", + (ff_neg & NEG_C) ? 'N' : 'P', + (ff_neg & NEG_R) ? 'N' : 'P', + (ff_type == FF_ADFFE1) ? '1' : '0', + (ff_neg & NEG_E) ? 'N' : 'P' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::C, sig_c); + cell->setPort(ID::E, sig_e); + cell->setPort(ID::R, sig_r); + break; + case FF_DFFSR: + cell->type = IdString(stringf("$_DFFSR_%c%c%c_", + (ff_neg & NEG_C) ? 'N' : 'P', + (ff_neg & NEG_S) ? 'N' : 'P', + (ff_neg & NEG_R) ? 'N' : 'P' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::C, sig_c); + cell->setPort(ID::S, sig_s); + cell->setPort(ID::R, sig_r); + break; + case FF_DFFSRE: + cell->type = IdString(stringf("$_DFFSRE_%c%c%c%c_", + (ff_neg & NEG_C) ? 'N' : 'P', + (ff_neg & NEG_S) ? 'N' : 'P', + (ff_neg & NEG_R) ? 'N' : 'P', + (ff_neg & NEG_E) ? 'N' : 'P' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::C, sig_c); + cell->setPort(ID::E, sig_e); + cell->setPort(ID::S, sig_s); + cell->setPort(ID::R, sig_r); + break; + case FF_SDFF0: + case FF_SDFF1: + cell->type = IdString(stringf("$_SDFF_%c%c%c_", + (ff_neg & NEG_C) ? 'N' : 'P', + (ff_neg & NEG_R) ? 'N' : 'P', + (ff_type == FF_SDFF1) ? '1' : '0' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::C, sig_c); + cell->setPort(ID::R, sig_r); + break; + case FF_SDFFE0: + case FF_SDFFE1: + cell->type = IdString(stringf("$_SDFFE_%c%c%c%c_", + (ff_neg & NEG_C) ? 'N' : 'P', + (ff_neg & NEG_R) ? 'N' : 'P', + (ff_type == FF_SDFFE1) ? '1' : '0', + (ff_neg & NEG_E) ? 'N' : 'P' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::C, sig_c); + cell->setPort(ID::E, sig_e); + cell->setPort(ID::R, sig_r); + break; + case FF_SDFFCE0: + case FF_SDFFCE1: + cell->type = IdString(stringf("$_SDFFCE_%c%c%c%c_", + (ff_neg & NEG_C) ? 'N' : 'P', + (ff_neg & NEG_R) ? 'N' : 'P', + (ff_type == FF_SDFFCE1) ? '1' : '0', + (ff_neg & NEG_E) ? 'N' : 'P' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::C, sig_c); + cell->setPort(ID::E, sig_e); + cell->setPort(ID::R, sig_r); + break; + case FF_DLATCH: + cell->type = IdString(stringf("$_DLATCH_%c_", + (ff_neg & NEG_E) ? 'N' : 'P' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::E, sig_e); + break; + case FF_ADLATCH0: + case FF_ADLATCH1: + cell->type = IdString(stringf("$_DLATCH_%c%c%c_", + (ff_neg & NEG_E) ? 'N' : 'P', + (ff_neg & NEG_R) ? 'N' : 'P', + (ff_type == FF_ADLATCH1) ? '1' : '0' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::E, sig_e); + cell->setPort(ID::R, sig_r); + break; + case FF_DLATCHSR: + cell->type = IdString(stringf("$_DLATCHSR_%c%c%c_", + (ff_neg & NEG_E) ? 'N' : 'P', + (ff_neg & NEG_S) ? 'N' : 'P', + (ff_neg & NEG_R) ? 'N' : 'P' + )); + cell->setPort(ID::D, sig_d); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::E, sig_e); + cell->setPort(ID::S, sig_s); + cell->setPort(ID::R, sig_r); + break; + case FF_SR: + cell->type = IdString(stringf("$_SR_%c%c_", + (ff_neg & NEG_S) ? 'N' : 'P', + (ff_neg & NEG_R) ? 'N' : 'P' + )); + cell->setPort(ID::Q, sig_q); + cell->setPort(ID::S, sig_s); + cell->setPort(ID::R, sig_r); + break; + default: + log_assert(0); + } + return; + +error: + log_error("FF %s.%s (type %s) cannot be legalized: %s\n", log_id(cell->module->name), log_id(cell->name), log_id(cell->type), reason); + } + + void execute(std::vector<std::string> args, RTLIL::Design *design) override + { + + log_header(design, "Executing DFFLEGALIZE pass (convert FFs to types supported by the target).\n"); + + for (int i = 0; i < NUM_FFTYPES; i++) { + for (int j = 0; j < NUM_NEG; j++) + supported_cells_neg[i][j] = 0; + supported_cells[i] = 0; + } + mince = 0; + minsrst = 0; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-cell" && argidx + 2 < args.size()) { + std::string celltype = args[++argidx]; + std::string inittype = args[++argidx]; + enum FfType ff_type[2] = {NUM_FFTYPES, NUM_FFTYPES}; + char pol_c = 0; + char pol_e = 0; + char pol_s = 0; + char pol_r = 0; + char srval = 0; + if (celltype.substr(0, 5) == "$_SR_" && celltype.size() == 8 && celltype[7] == '_') { + ff_type[0] = FF_SR; + pol_s = celltype[5]; + pol_r = celltype[6]; + } else if (celltype.substr(0, 6) == "$_DFF_" && celltype.size() == 8 && celltype[7] == '_') { + ff_type[0] = FF_DFF; + pol_c = celltype[6]; + } else if (celltype.substr(0, 7) == "$_DFFE_" && celltype.size() == 10 && celltype[9] == '_') { + ff_type[0] = FF_DFFE; + pol_c = celltype[7]; + pol_e = celltype[8]; + } else if (celltype.substr(0, 6) == "$_DFF_" && celltype.size() == 10 && celltype[9] == '_') { + ff_type[0] = FF_ADFF0; + ff_type[1] = FF_ADFF1; + pol_c = celltype[6]; + pol_r = celltype[7]; + srval = celltype[8]; + } else if (celltype.substr(0, 7) == "$_DFFE_" && celltype.size() == 12 && celltype[11] == '_') { + ff_type[0] = FF_ADFFE0; + ff_type[1] = FF_ADFFE1; + pol_c = celltype[7]; + pol_r = celltype[8]; + srval = celltype[9]; + pol_e = celltype[10]; + } else if (celltype.substr(0, 8) == "$_DFFSR_" && celltype.size() == 12 && celltype[11] == '_') { + ff_type[0] = FF_DFFSR; + pol_c = celltype[8]; + pol_s = celltype[9]; + pol_r = celltype[10]; + } else if (celltype.substr(0, 9) == "$_DFFSRE_" && celltype.size() == 14 && celltype[13] == '_') { + ff_type[0] = FF_DFFSRE; + pol_c = celltype[9]; + pol_s = celltype[10]; + pol_r = celltype[11]; + pol_e = celltype[12]; + } else if (celltype.substr(0, 7) == "$_SDFF_" && celltype.size() == 11 && celltype[10] == '_') { + ff_type[0] = FF_SDFF0; + ff_type[1] = FF_SDFF1; + pol_c = celltype[7]; + pol_r = celltype[8]; + srval = celltype[9]; + } else if (celltype.substr(0, 8) == "$_SDFFE_" && celltype.size() == 13 && celltype[12] == '_') { + ff_type[0] = FF_SDFFE0; + ff_type[1] = FF_SDFFE1; + pol_c = celltype[8]; + pol_r = celltype[9]; + srval = celltype[10]; + pol_e = celltype[11]; + } else if (celltype.substr(0, 9) == "$_SDFFCE_" && celltype.size() == 14 && celltype[13] == '_') { + ff_type[0] = FF_SDFFCE0; + ff_type[1] = FF_SDFFCE1; + pol_c = celltype[9]; + pol_r = celltype[10]; + srval = celltype[11]; + pol_e = celltype[12]; + } else if (celltype.substr(0, 9) == "$_DLATCH_" && celltype.size() == 11 && celltype[10] == '_') { + ff_type[0] = FF_DLATCH; + pol_e = celltype[9]; + } else if (celltype.substr(0, 9) == "$_DLATCH_" && celltype.size() == 13 && celltype[12] == '_') { + ff_type[0] = FF_ADLATCH0; + ff_type[1] = FF_ADLATCH1; + pol_e = celltype[9]; + pol_r = celltype[10]; + srval = celltype[11]; + } else if (celltype.substr(0, 11) == "$_DLATCHSR_" && celltype.size() == 15 && celltype[14] == '_') { + ff_type[0] = FF_DLATCHSR; + pol_e = celltype[11]; + pol_s = celltype[12]; + pol_r = celltype[13]; + } else { +unrecognized: + log_error("unrecognized cell type %s.\n", celltype.c_str()); + } + int mask = 0; + int match = 0; + for (auto pair : { + std::make_pair(pol_c, NEG_C), + std::make_pair(pol_e, NEG_E), + std::make_pair(pol_s, NEG_S), + std::make_pair(pol_r, NEG_R), + }) { + if (pair.first == 'N') { + mask |= pair.second; + match |= pair.second; + } else if (pair.first == 'P' || pair.first == 0) { + mask |= pair.second; + } else if (pair.first != '?') { + goto unrecognized; + } + } + if (srval == '0') { + ff_type[1] = NUM_FFTYPES; + } else if (srval == '1') { + ff_type[0] = NUM_FFTYPES; + } else if (srval != 0 && srval != '?') { + goto unrecognized; + } + for (int i = 0; i < 2; i++) { + if (ff_type[i] == NUM_FFTYPES) + continue; + int initmask; + if (inittype == "x") { + initmask = INIT_X; + } else if (inittype == "0") { + initmask = INIT_X | INIT_0; + } else if (inittype == "1") { + initmask = INIT_X | INIT_1; + } else if (inittype == "r") { + if (srval == 0) + log_error("init type r not valid for cell type %s.\n", celltype.c_str()); + if (i == 0) + initmask = INIT_X | INIT_0; + else + initmask = INIT_X | INIT_1; + } else if (inittype == "01") { + initmask = INIT_X | INIT_0 | INIT_1; + } else { + log_error("unrecognized init type %s for cell type %s.\n", inittype.c_str(), celltype.c_str()); + } + for (int neg = 0; neg < NUM_NEG; neg++) + if ((neg & mask) == match) + supported_cells_neg[ff_type[i]][neg] |= initmask; + supported_cells[ff_type[i]] |= initmask; + } + continue; + } else if (args[argidx] == "-mince" && argidx + 1 < args.size()) { + mince = atoi(args[++argidx].c_str()); + continue; + } else if (args[argidx] == "-minsrst" && argidx + 1 < args.size()) { + minsrst = atoi(args[++argidx].c_str()); + continue; + } + break; + } + extra_args(args, argidx, design); + supported_dffsr = supported_cells[FF_DFFSR] | supported_cells[FF_DFFSRE]; + supported_adff0 = supported_cells[FF_ADFF0] | supported_cells[FF_ADFFE0] | supported_dffsr; + supported_adff1 = supported_cells[FF_ADFF1] | supported_cells[FF_ADFFE1] | supported_dffsr; + supported_sdff0 = supported_cells[FF_SDFF0] | supported_cells[FF_SDFFE0] | supported_cells[FF_SDFFCE0]; + supported_sdff1 = supported_cells[FF_SDFF1] | supported_cells[FF_SDFFE1] | supported_cells[FF_SDFFCE1]; + supported_dff = supported_cells[FF_DFF] | supported_cells[FF_DFFE] | supported_dffsr | supported_adff0 | supported_adff1 | supported_sdff0 | supported_sdff1; + supported_sr = supported_dffsr | supported_cells[FF_DLATCHSR] | supported_cells[FF_SR] | supported_cells[FF_ADLATCH0] | flip_initmask(supported_cells[FF_ADLATCH1]); + supported_dlatch = supported_cells[FF_DLATCH] | supported_cells[FF_ADLATCH0] | supported_cells[FF_ADLATCH1] | supported_cells[FF_DLATCHSR]; + + for (auto module : design->selected_modules()) + { + sigmap.set(module); + initvals.set(&sigmap, module); + + if (mince || minsrst) { + ce_used.clear(); + srst_used.clear(); + + for (auto cell : module->cells()) { + if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + continue; + + if (cell->hasPort(ID::C) && cell->hasPort(ID::E)) { + SigSpec sig = cell->getPort(ID::E); + // Do not count const enable signals. + if (GetSize(sig) == 1 && sig[0].wire) + ce_used[sig[0]]++; + } + if (cell->type.str().substr(0, 6) == "$_SDFF") { + SigSpec sig = cell->getPort(ID::R); + // Do not count const srst signals. + if (GetSize(sig) == 1 && sig[0].wire) + srst_used[sig[0]]++; + } + } + } + + // First gather FF cells, then iterate over them later. + // We may need to split an FF into several cells. + std::vector<Cell *> ff_cells; + + for (auto cell : module->selected_cells()) + { + // Early exit for non-FFs. + if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + continue; + + ff_cells.push_back(cell); + } + + for (auto cell: ff_cells) + handle_ff(cell); + } + + sigmap.clear(); + initvals.clear(); + ce_used.clear(); + srst_used.clear(); + } +} DffLegalizePass; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index aa344cf8a..78a6f1c0d 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -115,7 +115,7 @@ static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, return false; } -static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, bool prepare_mode) +static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval) { LibertyAst *best_cell = nullptr; std::map<std::string, char> best_cell_ports; @@ -222,21 +222,12 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has if (best_cell != nullptr) { log(" cell %s (%sinv, pins=%d, area=%.2f) is a direct match for cell type %s.\n", best_cell->args[0].c_str(), best_cell_noninv ? "non" : "", best_cell_pins, best_cell_area, cell_type.c_str()); - if (prepare_mode) { - cell_mappings[cell_type].cell_name = cell_type; - cell_mappings[cell_type].ports["C"] = 'C'; - if (has_reset) - cell_mappings[cell_type].ports["R"] = 'R'; - cell_mappings[cell_type].ports["D"] = 'D'; - cell_mappings[cell_type].ports["Q"] = 'Q'; - } else { - cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]); - cell_mappings[cell_type].ports = best_cell_ports; - } + cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]); + cell_mappings[cell_type].ports = best_cell_ports; } } -static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol, bool prepare_mode) +static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol) { LibertyAst *best_cell = nullptr; std::map<std::string, char> best_cell_ports; @@ -339,141 +330,12 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool if (best_cell != nullptr) { log(" cell %s (%sinv, pins=%d, area=%.2f) is a direct match for cell type %s.\n", best_cell->args[0].c_str(), best_cell_noninv ? "non" : "", best_cell_pins, best_cell_area, cell_type.c_str()); - if (prepare_mode) { - cell_mappings[cell_type].cell_name = cell_type; - cell_mappings[cell_type].ports["C"] = 'C'; - cell_mappings[cell_type].ports["S"] = 'S'; - cell_mappings[cell_type].ports["R"] = 'R'; - cell_mappings[cell_type].ports["D"] = 'D'; - cell_mappings[cell_type].ports["Q"] = 'Q'; - } else { - cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]); - cell_mappings[cell_type].ports = best_cell_ports; - } + cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]); + cell_mappings[cell_type].ports = best_cell_ports; } } -static bool expand_cellmap_worker(std::string from, std::string to, std::string inv) -{ - if (cell_mappings.count(to) > 0) - return false; - - log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str()); - cell_mappings[to].cell_name = cell_mappings[from].cell_name; - cell_mappings[to].ports = cell_mappings[from].ports; - - for (auto &it : cell_mappings[to].ports) { - char cmp_ch = it.second; - if ('a' <= cmp_ch && cmp_ch <= 'z') - cmp_ch -= 'a' - 'A'; - if (inv.find(cmp_ch) == std::string::npos) - continue; - if ('a' <= it.second && it.second <= 'z') - it.second -= 'a' - 'A'; - else if ('A' <= it.second && it.second <= 'Z') - it.second += 'a' - 'A'; - } - return true; -} - -static bool expand_cellmap(std::string pattern, std::string inv) -{ - std::vector<std::pair<std::string, std::string>> from_to_list; - bool return_status = false; - - for (auto &it : cell_mappings) { - std::string from = it.first.str(), to = it.first.str(); - if (from.size() != pattern.size()) - continue; - for (size_t i = 0; i < from.size(); i++) { - if (pattern[i] == '*') { - to[i] = from[i] == 'P' ? 'N' : - from[i] == 'N' ? 'P' : - from[i] == '1' ? '0' : - from[i] == '0' ? '1' : '*'; - } else - if (pattern[i] != '?' && pattern[i] != from[i]) - goto pattern_failed; - } - from_to_list.push_back(std::pair<std::string, std::string>(from, to)); - pattern_failed:; - } - - for (auto &it : from_to_list) - return_status = return_status || expand_cellmap_worker(it.first, it.second, inv); - return return_status; -} - -static void map_sr_to_arst(IdString from, IdString to) -{ - if (!cell_mappings.count(from) || cell_mappings.count(to) > 0) - return; - - char from_clk_pol YS_ATTRIBUTE(unused) = from[8]; - char from_set_pol = from[9]; - char from_clr_pol = from[10]; - char to_clk_pol YS_ATTRIBUTE(unused) = to[6]; - char to_rst_pol YS_ATTRIBUTE(unused) = to[7]; - char to_rst_val = to[8]; - - log_assert(from_clk_pol == to_clk_pol); - log_assert(to_rst_pol == from_set_pol && to_rst_pol == from_clr_pol); - - log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str()); - cell_mappings[to].cell_name = cell_mappings[from].cell_name; - cell_mappings[to].ports = cell_mappings[from].ports; - - for (auto &it : cell_mappings[to].ports) - { - bool is_set_pin = it.second == 'S' || it.second == 's'; - bool is_clr_pin = it.second == 'R' || it.second == 'r'; - - if (!is_set_pin && !is_clr_pin) - continue; - - if ((to_rst_val == '0' && is_set_pin) || (to_rst_val == '1' && is_clr_pin)) - { - // this is the unused set/clr pin -- deactivate it - if (is_set_pin) - it.second = (from_set_pol == 'P') == (it.second == 'S') ? '0' : '1'; - else - it.second = (from_clr_pol == 'P') == (it.second == 'R') ? '0' : '1'; - } - else - { - // this is the used set/clr pin -- rename it to 'reset' - if (it.second == 'S') - it.second = 'R'; - if (it.second == 's') - it.second = 'r'; - } - } -} - -static void map_adff_to_dff(IdString from, IdString to) -{ - if (!cell_mappings.count(from) || cell_mappings.count(to) > 0) - return; - - char from_clk_pol YS_ATTRIBUTE(unused) = from[6]; - char from_rst_pol = from[7]; - char to_clk_pol YS_ATTRIBUTE(unused) = to[6]; - - log_assert(from_clk_pol == to_clk_pol); - - log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str()); - cell_mappings[to].cell_name = cell_mappings[from].cell_name; - cell_mappings[to].ports = cell_mappings[from].ports; - - for (auto &it : cell_mappings[to].ports) { - if (it.second == 'S' || it.second == 'R') - it.second = from_rst_pol == 'P' ? '0' : '1'; - if (it.second == 's' || it.second == 'r') - it.second = from_rst_pol == 'P' ? '1' : '0'; - } -} - -static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare_mode) +static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) { log("Mapping DFF cells in module `%s':\n", module->name.c_str()); @@ -499,7 +361,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare module->remove(cell); cell_mapping &cm = cell_mappings[cell_type]; - RTLIL::Cell *new_cell = module->addCell(cell_name, prepare_mode ? cm.cell_name : cm.cell_name); + RTLIL::Cell *new_cell = module->addCell(cell_name, cm.cell_name); new_cell->set_src_attribute(src); @@ -549,10 +411,10 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare struct DfflibmapPass : public Pass { DfflibmapPass() : Pass("dfflibmap", "technology mapping of flip-flops") { } - void help() YS_OVERRIDE + void help() override { log("\n"); - log(" dfflibmap [-prepare] -liberty <file> [selection]\n"); + log(" dfflibmap [-prepare] [-map-only] [-info] -liberty <file> [selection]\n"); log("\n"); log("Map internal flip-flop cells to the flip-flop cells in the technology\n"); log("library specified in the given liberty file.\n"); @@ -562,15 +424,27 @@ struct DfflibmapPass : public Pass { log("\n"); log("When called with -prepare, this command will convert the internal FF cells\n"); log("to the internal cell types that best match the cells found in the given\n"); - log("liberty file.\n"); + log("liberty file, but won't actually map them to the target cells.\n"); + log("\n"); + log("When called with -map-only, this command will only map internal cell\n"); + log("types that are already of exactly the right type to match the target\n"); + log("cells, leaving remaining internal cells untouched.\n"); + log("\n"); + log("When called with -info, this command will only print the target cell\n"); + log("list, along with their associated internal cell types, and the arguments"); + log("that would be passed to the dfflegalize pass. The design will not be\n"); + log("changed.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing DFFLIBMAP pass (mapping DFF cells to sequential cells from liberty file).\n"); + log_push(); std::string liberty_file; bool prepare_mode = false; + bool map_only_mode = false; + bool info_mode = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -585,10 +459,28 @@ struct DfflibmapPass : public Pass { prepare_mode = true; continue; } + if (arg == "-map-only") { + map_only_mode = true; + continue; + } + if (arg == "-info") { + info_mode = true; + continue; + } break; } extra_args(args, argidx, design); + int modes = 0; + if (prepare_mode) + modes++; + if (map_only_mode) + modes++; + if (info_mode) + modes++; + if (modes > 1) + log_cmd_error("Only one of -prepare, -map-only, or -info options should be given!\n"); + if (liberty_file.empty()) log_cmd_error("Missing `-liberty liberty_file' option!\n"); @@ -599,74 +491,49 @@ struct DfflibmapPass : public Pass { LibertyParser libparser(f); f.close(); - find_cell(libparser.ast, ID($_DFF_N_), false, false, false, false, prepare_mode); - find_cell(libparser.ast, ID($_DFF_P_), true, false, false, false, prepare_mode); - - find_cell(libparser.ast, ID($_DFF_NN0_), false, true, false, false, prepare_mode); - find_cell(libparser.ast, ID($_DFF_NN1_), false, true, false, true, prepare_mode); - find_cell(libparser.ast, ID($_DFF_NP0_), false, true, true, false, prepare_mode); - find_cell(libparser.ast, ID($_DFF_NP1_), false, true, true, true, prepare_mode); - find_cell(libparser.ast, ID($_DFF_PN0_), true, true, false, false, prepare_mode); - find_cell(libparser.ast, ID($_DFF_PN1_), true, true, false, true, prepare_mode); - find_cell(libparser.ast, ID($_DFF_PP0_), true, true, true, false, prepare_mode); - find_cell(libparser.ast, ID($_DFF_PP1_), true, true, true, true, prepare_mode); - - find_cell_sr(libparser.ast, ID($_DFFSR_NNN_), false, false, false, prepare_mode); - find_cell_sr(libparser.ast, ID($_DFFSR_NNP_), false, false, true, prepare_mode); - find_cell_sr(libparser.ast, ID($_DFFSR_NPN_), false, true, false, prepare_mode); - find_cell_sr(libparser.ast, ID($_DFFSR_NPP_), false, true, true, prepare_mode); - find_cell_sr(libparser.ast, ID($_DFFSR_PNN_), true, false, false, prepare_mode); - find_cell_sr(libparser.ast, ID($_DFFSR_PNP_), true, false, true, prepare_mode); - find_cell_sr(libparser.ast, ID($_DFFSR_PPN_), true, true, false, prepare_mode); - find_cell_sr(libparser.ast, ID($_DFFSR_PPP_), true, true, true, prepare_mode); - - // try to implement as many cells as possible just by inverting - // the SET and RESET pins. If necessary, implement cell types - // by inverting both D and Q. Only invert clock pins if there - // is no other way of implementing the cell. - while (1) - { - if (expand_cellmap("$_DFF_?*?_", "R") || - expand_cellmap("$_DFFSR_?*?_", "S") || - expand_cellmap("$_DFFSR_??*_", "R")) - continue; - - if (expand_cellmap("$_DFF_??*_", "DQ")) - continue; - - if (expand_cellmap("$_DFF_*_", "C") || - expand_cellmap("$_DFF_*??_", "C") || - expand_cellmap("$_DFFSR_*??_", "C")) - continue; - - break; - } - - map_sr_to_arst(ID($_DFFSR_NNN_), ID($_DFF_NN0_)); - map_sr_to_arst(ID($_DFFSR_NNN_), ID($_DFF_NN1_)); - map_sr_to_arst(ID($_DFFSR_NPP_), ID($_DFF_NP0_)); - map_sr_to_arst(ID($_DFFSR_NPP_), ID($_DFF_NP1_)); - map_sr_to_arst(ID($_DFFSR_PNN_), ID($_DFF_PN0_)); - map_sr_to_arst(ID($_DFFSR_PNN_), ID($_DFF_PN1_)); - map_sr_to_arst(ID($_DFFSR_PPP_), ID($_DFF_PP0_)); - map_sr_to_arst(ID($_DFFSR_PPP_), ID($_DFF_PP1_)); - - map_adff_to_dff(ID($_DFF_NN0_), ID($_DFF_N_)); - map_adff_to_dff(ID($_DFF_NN1_), ID($_DFF_N_)); - map_adff_to_dff(ID($_DFF_NP0_), ID($_DFF_N_)); - map_adff_to_dff(ID($_DFF_NP1_), ID($_DFF_N_)); - map_adff_to_dff(ID($_DFF_PN0_), ID($_DFF_P_)); - map_adff_to_dff(ID($_DFF_PN1_), ID($_DFF_P_)); - map_adff_to_dff(ID($_DFF_PP0_), ID($_DFF_P_)); - map_adff_to_dff(ID($_DFF_PP1_), ID($_DFF_P_)); + find_cell(libparser.ast, ID($_DFF_N_), false, false, false, false); + find_cell(libparser.ast, ID($_DFF_P_), true, false, false, false); + + find_cell(libparser.ast, ID($_DFF_NN0_), false, true, false, false); + find_cell(libparser.ast, ID($_DFF_NN1_), false, true, false, true); + find_cell(libparser.ast, ID($_DFF_NP0_), false, true, true, false); + find_cell(libparser.ast, ID($_DFF_NP1_), false, true, true, true); + find_cell(libparser.ast, ID($_DFF_PN0_), true, true, false, false); + find_cell(libparser.ast, ID($_DFF_PN1_), true, true, false, true); + find_cell(libparser.ast, ID($_DFF_PP0_), true, true, true, false); + find_cell(libparser.ast, ID($_DFF_PP1_), true, true, true, true); + + find_cell_sr(libparser.ast, ID($_DFFSR_NNN_), false, false, false); + find_cell_sr(libparser.ast, ID($_DFFSR_NNP_), false, false, true); + find_cell_sr(libparser.ast, ID($_DFFSR_NPN_), false, true, false); + find_cell_sr(libparser.ast, ID($_DFFSR_NPP_), false, true, true); + find_cell_sr(libparser.ast, ID($_DFFSR_PNN_), true, false, false); + find_cell_sr(libparser.ast, ID($_DFFSR_PNP_), true, false, true); + find_cell_sr(libparser.ast, ID($_DFFSR_PPN_), true, true, false); + find_cell_sr(libparser.ast, ID($_DFFSR_PPP_), true, true, true); log(" final dff cell mappings:\n"); logmap_all(); - for (auto module : design->selected_modules()) - if (!module->get_blackbox_attribute()) - dfflibmap(design, module, prepare_mode); + if (!map_only_mode) { + std::string dfflegalize_cmd = "dfflegalize"; + for (auto it : cell_mappings) + dfflegalize_cmd += stringf(" -cell %s 01", it.first.c_str()); + dfflegalize_cmd += " t:$_DFF* t:$_SDFF*"; + if (info_mode) { + log("dfflegalize command line: %s\n", dfflegalize_cmd.c_str()); + } else { + Pass::call(design, dfflegalize_cmd); + } + } + + if (!prepare_mode && !info_mode) { + for (auto module : design->selected_modules()) + if (!module->get_blackbox_attribute()) + dfflibmap(design, module); + } + log_pop(); cell_mappings.clear(); } } DfflibmapPass; diff --git a/passes/techmap/dffunmap.cc b/passes/techmap/dffunmap.cc new file mode 100644 index 000000000..fb107ff75 --- /dev/null +++ b/passes/techmap/dffunmap.cc @@ -0,0 +1,107 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Marcelina Kościelnicka <mwk@0x04.net> + * + * 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" +#include "kernel/ff.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct DffunmapPass : public Pass { + DffunmapPass() : Pass("dffunmap", "unmap clock enable and synchronous reset from FFs") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" dffunmap [options] [selection]\n"); + log("\n"); + log("This pass transforms FF types with clock enable and/or synchronous reset into\n"); + log("their base type (with neither clock enable nor sync reset) by emulating the clock\n"); + log("enable and synchronous reset with multiplexers on the cell input.\n"); + log("\n"); + log(" -ce-only\n"); + log(" unmap only clock enables, leave synchronous resets alone.\n"); + log("\n"); + log(" -srst-only\n"); + log(" unmap only synchronous resets, leave clock enables alone.\n"); + log("\n"); + } + void execute(std::vector<std::string> args, RTLIL::Design *design) override + { + log_header(design, "Executing DFFUNMAP pass (unmap clock enable and synchronous reset from FFs).\n"); + + bool ce_only = false; + bool srst_only = false; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-ce-only") { + ce_only = true; + continue; + } + if (args[argidx] == "-srst-only") { + srst_only = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (ce_only && srst_only) + log_cmd_error("Options -ce-only and -srst-only are mutually exclusive!\n"); + + for (auto mod : design->selected_modules()) + { + SigMap sigmap(mod); + FfInitVals initvals(&sigmap, mod); + + for (auto cell : mod->selected_cells()) + { + if (!RTLIL::builtin_ff_cell_types().count(cell->type)) + continue; + + FfData ff(&initvals, cell); + IdString name = cell->name; + + if (!ff.has_clk) + continue; + + if (ce_only) { + if (!ff.has_en) + continue; + ff.unmap_ce(mod); + } else if (srst_only) { + if (!ff.has_srst) + continue; + ff.unmap_srst(mod); + } else { + if (!ff.has_en && !ff.has_srst) + continue; + ff.unmap_ce_srst(mod); + } + + mod->remove(cell); + ff.emit(mod, name); + } + } + } +} DffunmapPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index f29044790..f5966fac0 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -345,7 +345,7 @@ bool compareSortNeedleList(RTLIL::Module *left, RTLIL::Module *right) struct ExtractPass : public Pass { ExtractPass() : Pass("extract", "find subcircuits and replace them with cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -354,7 +354,7 @@ struct ExtractPass : public Pass { log("\n"); log("This pass looks for subcircuits that are isomorphic to any of the modules\n"); log("in the given map file and replaces them with instances of this modules. The\n"); - log("map file can be a Verilog source file (*.v) or an ilang file (*.il).\n"); + log("map file can be a Verilog source file (*.v) or an RTLIL source file (*.il).\n"); log("\n"); log(" -map <map_file>\n"); log(" use the modules in this file as reference. This option can be used\n"); @@ -409,7 +409,7 @@ struct ExtractPass : public Pass { log("the following options are to be used instead of the -map option.\n"); log("\n"); log(" -mine <out_file>\n"); - log(" mine for frequent subcircuits and write them to the given ilang file\n"); + log(" mine for frequent subcircuits and write them to the given RTLIL file\n"); log("\n"); log(" -mine_cells_span <min> <max>\n"); log(" only mine for subcircuits with the specified number of cells\n"); @@ -433,7 +433,7 @@ struct ExtractPass : public Pass { log("See 'help techmap' for a pass that does the opposite thing.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing EXTRACT pass (map subcircuits to cells).\n"); log_push(); @@ -578,7 +578,7 @@ struct ExtractPass : public Pass { } if (map_filenames.empty() && mine_outfile.empty()) - log_cmd_error("Missing option -map <verilog_or_ilang_file> or -mine <output_ilang_file>.\n"); + log_cmd_error("Missing option -map <verilog_or_rtlil_file> or -mine <output_rtlil_file>.\n"); RTLIL::Design *map = nullptr; @@ -606,7 +606,7 @@ struct ExtractPass : public Pass { delete map; log_cmd_error("Can't open map file `%s'.\n", filename.c_str()); } - Frontend::frontend_call(map, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog")); + Frontend::frontend_call(map, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : "verilog")); f.close(); if (filename.size() <= 3 || filename.compare(filename.size()-3, std::string::npos, ".il") != 0) { @@ -744,7 +744,7 @@ struct ExtractPass : public Pass { f.open(mine_outfile.c_str(), std::ofstream::trunc); if (f.fail()) log_error("Can't open output file `%s'.\n", mine_outfile.c_str()); - Backend::backend_call(map, &f, mine_outfile, "ilang"); + Backend::backend_call(map, &f, mine_outfile, "rtlil"); f.close(); } diff --git a/passes/techmap/extract_counter.cc b/passes/techmap/extract_counter.cc index 68b338143..56b2ea584 100644 --- a/passes/techmap/extract_counter.cc +++ b/passes/techmap/extract_counter.cc @@ -760,7 +760,7 @@ void counter_worker( struct ExtractCounterPass : public Pass { ExtractCounterPass() : Pass("extract_counter", "Extract GreenPak4 counter cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -788,18 +788,18 @@ struct ExtractCounterPass : public Pass { log("\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing EXTRACT_COUNTER pass (find counters in netlist).\n"); pool<RTLIL::IdString> _parallel_cells; CounterExtractionSettings settings { - .parallel_cells = _parallel_cells, - .maxwidth = 64, - .minwidth = 2, - .allow_arst = true, - .allowed_dirs = 0, + _parallel_cells, // parallel_cells + 64, // maxwidth + 2, // minwidth + true, // allow_arst + 0, // allowed_dirs }; size_t argidx; diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc index 9023d8687..3fcff01c3 100644 --- a/passes/techmap/extract_fa.cc +++ b/passes/techmap/extract_fa.cc @@ -539,7 +539,7 @@ struct ExtractFaWorker struct ExtractFaPass : public Pass { ExtractFaPass() : Pass("extract_fa", "find and extract full/half adders") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -561,7 +561,7 @@ struct ExtractFaPass : public Pass { log(" Verbose output\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { ExtractFaConfig config; diff --git a/passes/techmap/extract_reduce.cc b/passes/techmap/extract_reduce.cc index 2d63e413f..07b4200cc 100644 --- a/passes/techmap/extract_reduce.cc +++ b/passes/techmap/extract_reduce.cc @@ -34,7 +34,7 @@ struct ExtractReducePass : public Pass ExtractReducePass() : Pass("extract_reduce", "converts gate chains into $reduce_* cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -63,7 +63,7 @@ struct ExtractReducePass : public Pass (cell->type == ID($_XOR_) && gt == GateType::Xor); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing EXTRACT_REDUCE pass.\n"); log_push(); diff --git a/passes/techmap/extractinv.cc b/passes/techmap/extractinv.cc index 269fe5c6c..11463380c 100644 --- a/passes/techmap/extractinv.cc +++ b/passes/techmap/extractinv.cc @@ -2,7 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * Copyright (C) 2019 Marcin Kościelnicki <mwk@0x04.net> + * Copyright (C) 2019 Marcelina Kościelnicka <mwk@0x04.net> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -35,7 +35,7 @@ void split_portname_pair(std::string &port1, std::string &port2) struct ExtractinvPass : public Pass { ExtractinvPass() : Pass("extractinv", "extract explicit inverter cells for invertible cell pins") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -57,7 +57,7 @@ struct ExtractinvPass : public Pass { log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing EXTRACTINV pass (extracting pin inverters).\n"); diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc index a03226f9f..08978f446 100644 --- a/passes/techmap/flatten.cc +++ b/passes/techmap/flatten.cc @@ -152,15 +152,14 @@ struct FlattenWorker // Attach port connections of the flattened cell - SigMap tpl_sigmap(tpl); pool<SigBit> tpl_driven; for (auto tpl_cell : tpl->cells()) for (auto &tpl_conn : tpl_cell->connections()) if (tpl_cell->output(tpl_conn.first)) - for (auto bit : tpl_sigmap(tpl_conn.second)) + for (auto bit : tpl_conn.second) tpl_driven.insert(bit); for (auto &tpl_conn : tpl->connections()) - for (auto bit : tpl_sigmap(tpl_conn.first)) + for (auto bit : tpl_conn.first) tpl_driven.insert(bit); SigMap sigmap(module); @@ -190,7 +189,7 @@ struct FlattenWorker } else { SigSpec sig_tpl = tpl_wire, sig_mod = port_it.second; for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) { - if (tpl_driven.count(tpl_sigmap(sig_tpl[i]))) { + if (tpl_driven.count(sig_tpl[i])) { new_conn.first.append(sig_mod[i]); new_conn.second.append(sig_tpl[i]); } else { @@ -253,7 +252,7 @@ struct FlattenWorker struct FlattenPass : public Pass { FlattenPass() : Pass("flatten", "flatten design") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -270,7 +269,7 @@ struct FlattenPass : public Pass { log(" Ignore the 'whitebox' attribute on cell implementations.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing FLATTEN pass (flatten design).\n"); log_push(); diff --git a/passes/techmap/flowmap.cc b/passes/techmap/flowmap.cc index 72947237b..dfdbe6b88 100644 --- a/passes/techmap/flowmap.cc +++ b/passes/techmap/flowmap.cc @@ -1470,7 +1470,7 @@ static void split(std::vector<std::string> &tokens, const std::string &text, cha struct FlowmapPass : public Pass { FlowmapPass() : Pass("flowmap", "pack LUTs with FlowMap") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1511,7 +1511,7 @@ struct FlowmapPass : public Pass { log(" explain decisions performed during depth relaxation.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { int order = 3; int minlut = 1; diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index 5aeb5ea79..b808a8d8e 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -55,7 +55,7 @@ void hilomap_worker(RTLIL::SigSpec &sig) struct HilomapPass : public Pass { HilomapPass() : Pass("hilomap", "technology mapping of constant hi- and/or lo-drivers") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" hilomap [options] [selection]\n"); @@ -74,7 +74,7 @@ struct HilomapPass : public Pass { log(" each constant bit.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing HILOMAP pass (mapping to constant drivers).\n"); diff --git a/passes/techmap/insbuf.cc b/passes/techmap/insbuf.cc index 0686c0f2b..a3b5b698d 100644 --- a/passes/techmap/insbuf.cc +++ b/passes/techmap/insbuf.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct InsbufPass : public Pass { InsbufPass() : Pass("insbuf", "insert buffer cells for connected wires") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" insbuf [options] [selection]\n"); @@ -37,7 +37,7 @@ struct InsbufPass : public Pass { log(" call to \"clean\" will remove all $_BUF_ in the design.)\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing INSBUF pass (insert buffer cells for connected wires).\n"); diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index a18d02652..e8530a034 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -34,7 +34,7 @@ void split_portname_pair(std::string &port1, std::string &port2) struct IopadmapPass : public Pass { IopadmapPass() : Pass("iopadmap", "technology mapping of i/o pads (or buffers)") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" iopadmap [options] [selection]\n"); @@ -97,7 +97,7 @@ struct IopadmapPass : public Pass { modules_processed.insert(module); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing IOPADMAP pass (mapping inputs/outputs to IO-PAD cells).\n"); diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc index 703bf6ff6..f56eff3e5 100644 --- a/passes/techmap/lut2mux.cc +++ b/passes/techmap/lut2mux.cc @@ -56,7 +56,7 @@ int lut2mux(Cell *cell) struct Lut2muxPass : public Pass { Lut2muxPass() : Pass("lut2mux", "convert $lut to $_MUX_") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -65,7 +65,7 @@ struct Lut2muxPass : public Pass { log("This pass converts $lut cells to $_MUX_ gates.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing LUT2MUX pass (convert $lut to $_MUX_).\n"); diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc index 3bb929009..43f2d97f5 100644 --- a/passes/techmap/maccmap.cc +++ b/passes/techmap/maccmap.cc @@ -365,7 +365,7 @@ PRIVATE_NAMESPACE_BEGIN struct MaccmapPass : public Pass { MaccmapPass() : Pass("maccmap", "mapping macc cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -375,7 +375,7 @@ struct MaccmapPass : public Pass { log("is used then the $macc cell is mapped to $add, $sub, etc. cells instead.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool unmap_mode = false; diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index bd049d86d..24109b579 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -623,7 +623,7 @@ struct MuxcoverWorker struct MuxcoverPass : public Pass { MuxcoverPass() : Pass("muxcover", "cover trees of MUX cells with wider MUXes") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -656,7 +656,7 @@ struct MuxcoverPass : public Pass { log(" than <N> different signals.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing MUXCOVER pass (mapping to wider MUXes).\n"); diff --git a/passes/techmap/nlutmap.cc b/passes/techmap/nlutmap.cc index 798d82248..e1ebfcad8 100644 --- a/passes/techmap/nlutmap.cc +++ b/passes/techmap/nlutmap.cc @@ -129,7 +129,7 @@ struct NlutmapWorker struct NlutmapPass : public Pass { NlutmapPass() : Pass("nlutmap", "map to LUTs of different sizes") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -149,7 +149,7 @@ struct NlutmapPass : public Pass { log("to generic logic gates ($_AND_, etc.).\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { NlutmapConfig config; diff --git a/passes/techmap/pmuxtree.cc b/passes/techmap/pmuxtree.cc index 2810b7f2d..b937d3fb0 100644 --- a/passes/techmap/pmuxtree.cc +++ b/passes/techmap/pmuxtree.cc @@ -67,7 +67,7 @@ static SigSpec recursive_mux_generator(Module *module, const SigSpec &sig_data, struct PmuxtreePass : public Pass { PmuxtreePass() : Pass("pmuxtree", "transform $pmux cells to trees of $mux cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -76,7 +76,7 @@ struct PmuxtreePass : public Pass { log("This pass transforms $pmux cells to trees of $mux cells.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing PMUXTREE pass.\n"); diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index d7a381e0a..b971068f7 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -19,6 +19,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/ffinit.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -100,9 +101,8 @@ struct ShregmapWorker int dff_count, shreg_count; pool<Cell*> remove_cells; - pool<SigBit> remove_init; - dict<SigBit, bool> sigbit_init; + FfInitVals initvals; dict<SigBit, Cell*> sigbit_chain_next; dict<SigBit, Cell*> sigbit_chain_prev; pool<SigBit> sigbit_with_non_chain_users; @@ -116,16 +116,6 @@ struct ShregmapWorker for (auto bit : sigmap(wire)) sigbit_with_non_chain_users.insert(bit); } - - if (wire->attributes.count(ID::init)) { - SigSpec initsig = sigmap(wire); - Const initval = wire->attributes.at(ID::init); - for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++) - if (initval[i] == State::S0 && !opts.zinit) - sigbit_init[initsig[i]] = false; - else if (initval[i] == State::S1) - sigbit_init[initsig[i]] = true; - } } for (auto cell : module->cells()) @@ -137,8 +127,9 @@ struct ShregmapWorker SigBit d_bit = sigmap(cell->getPort(d_port).as_bit()); SigBit q_bit = sigmap(cell->getPort(q_port).as_bit()); + State initval = initvals(q_bit); - if (opts.init || sigbit_init.count(q_bit) == 0) + if (opts.init || initval == State::Sx || (opts.zinit && initval == State::S0)) { auto r = sigbit_chain_next.insert(std::make_pair(d_bit, cell)); if (!r.second) { @@ -310,22 +301,17 @@ struct ShregmapWorker if (opts.init) { vector<State> initval; for (int i = depth-1; i >= 0; i--) { - SigBit bit = sigmap(chain[cursor+i]->getPort(q_port).as_bit()); - if (sigbit_init.count(bit) == 0) - initval.push_back(State::Sx); - else if (sigbit_init.at(bit)) - initval.push_back(State::S1); - else - initval.push_back(State::S0); - remove_init.insert(bit); + SigBit bit = chain[cursor+i]->getPort(q_port).as_bit(); + initval.push_back(initvals(bit)); + initvals.remove_init(bit); } first_cell->setParam(ID::INIT, initval); } if (opts.zinit) for (int i = depth-1; i >= 0; i--) { - SigBit bit = sigmap(chain[cursor+i]->getPort(q_port).as_bit()); - remove_init.insert(bit); + SigBit bit = chain[cursor+i]->getPort(q_port).as_bit(); + initvals.remove_init(bit); } if (opts.params) @@ -364,22 +350,6 @@ struct ShregmapWorker for (auto cell : remove_cells) module->remove(cell); - for (auto wire : module->wires()) - { - if (wire->attributes.count(ID::init) == 0) - continue; - - SigSpec initsig = sigmap(wire); - Const &initval = wire->attributes.at(ID::init); - - for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++) - if (remove_init.count(initsig[i])) - initval[i] = State::Sx; - - if (SigSpec(initval).is_fully_undef()) - wire->attributes.erase(ID::init); - } - remove_cells.clear(); sigbit_chain_next.clear(); sigbit_chain_prev.clear(); @@ -389,6 +359,7 @@ struct ShregmapWorker ShregmapWorker(Module *module, const ShregmapOptions &opts) : module(module), sigmap(module), opts(opts), dff_count(0), shreg_count(0) { + initvals.set(&sigmap, module); make_sigbit_chain_next_prev(); find_chain_start_cells(); @@ -403,7 +374,7 @@ struct ShregmapWorker struct ShregmapPass : public Pass { ShregmapPass() : Pass("shregmap", "map shift registers") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -461,7 +432,7 @@ struct ShregmapPass : public Pass { log(" map to greenpak4 shift registers.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { ShregmapOptions opts; string clkpol, enpol; diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 214157a64..b9d337da4 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -474,29 +474,93 @@ void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) } } -void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell) +void simplemap_dffsre(RTLIL::Module *module, RTLIL::Cell *cell) { int width = cell->parameters.at(ID::WIDTH).as_int(); char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N'; - char rst_pol = cell->parameters.at(ID::ARST_POLARITY).as_bool() ? 'P' : 'N'; + char set_pol = cell->parameters.at(ID::SET_POLARITY).as_bool() ? 'P' : 'N'; + char clr_pol = cell->parameters.at(ID::CLR_POLARITY).as_bool() ? 'P' : 'N'; + char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N'; - std::vector<RTLIL::State> rst_val = cell->parameters.at(ID::ARST_VALUE).bits; + RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK); + RTLIL::SigSpec sig_s = cell->getPort(ID::SET); + RTLIL::SigSpec sig_r = cell->getPort(ID::CLR); + RTLIL::SigSpec sig_e = cell->getPort(ID::EN); + RTLIL::SigSpec sig_d = cell->getPort(ID::D); + RTLIL::SigSpec sig_q = cell->getPort(ID::Q); + + IdString gate_type = stringf("$_DFFSRE_%c%c%c%c_", clk_pol, set_pol, clr_pol, en_pol); + + for (int i = 0; i < width; i++) { + RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); + gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); + gate->setPort(ID::C, sig_clk); + gate->setPort(ID::S, sig_s[i]); + gate->setPort(ID::R, sig_r[i]); + gate->setPort(ID::E, sig_e); + gate->setPort(ID::D, sig_d[i]); + gate->setPort(ID::Q, sig_q[i]); + } +} + +void simplemap_adff_sdff(RTLIL::Module *module, RTLIL::Cell *cell) +{ + int width = cell->parameters.at(ID::WIDTH).as_int(); + bool is_async = cell->type == ID($adff); + char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N'; + char rst_pol = cell->parameters.at(is_async ? ID::ARST_POLARITY : ID::SRST_POLARITY).as_bool() ? 'P' : 'N'; + const char *type = is_async ? "DFF" : "SDFF"; + + std::vector<RTLIL::State> rst_val = cell->parameters.at(is_async ? ID::ARST_VALUE : ID::SRST_VALUE).bits; while (int(rst_val.size()) < width) rst_val.push_back(RTLIL::State::S0); RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK); - RTLIL::SigSpec sig_rst = cell->getPort(ID::ARST); + RTLIL::SigSpec sig_rst = cell->getPort(is_async ? ID::ARST : ID::SRST); + RTLIL::SigSpec sig_d = cell->getPort(ID::D); + RTLIL::SigSpec sig_q = cell->getPort(ID::Q); + + IdString gate_type_0 = stringf("$_%s_%c%c0_", type, clk_pol, rst_pol); + IdString gate_type_1 = stringf("$_%s_%c%c1_", type, clk_pol, rst_pol); + + for (int i = 0; i < width; i++) { + RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0); + gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); + gate->setPort(ID::C, sig_clk); + gate->setPort(ID::R, sig_rst); + gate->setPort(ID::D, sig_d[i]); + gate->setPort(ID::Q, sig_q[i]); + } +} + +void simplemap_adffe_sdffe_sdffce(RTLIL::Module *module, RTLIL::Cell *cell) +{ + int width = cell->parameters.at(ID::WIDTH).as_int(); + bool is_async = cell->type == ID($adffe); + char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N'; + char rst_pol = cell->parameters.at(is_async ? ID::ARST_POLARITY : ID::SRST_POLARITY).as_bool() ? 'P' : 'N'; + char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N'; + const char *type = is_async ? "DFFE" : cell->type == ID($sdffe) ? "SDFFE" : "SDFFCE"; + + std::vector<RTLIL::State> rst_val = cell->parameters.at(is_async ? ID::ARST_VALUE : ID::SRST_VALUE).bits; + while (int(rst_val.size()) < width) + rst_val.push_back(RTLIL::State::S0); + + RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK); + RTLIL::SigSpec sig_rst = cell->getPort(is_async ? ID::ARST : ID::SRST); + RTLIL::SigSpec sig_e = cell->getPort(ID::EN); RTLIL::SigSpec sig_d = cell->getPort(ID::D); RTLIL::SigSpec sig_q = cell->getPort(ID::Q); - IdString gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol); - IdString gate_type_1 = stringf("$_DFF_%c%c1_", clk_pol, rst_pol); + IdString gate_type_0 = stringf("$_%s_%c%c0%c_", type, clk_pol, rst_pol, en_pol); + IdString gate_type_1 = stringf("$_%s_%c%c1%c_", type, clk_pol, rst_pol, en_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0); gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->setPort(ID::C, sig_clk); gate->setPort(ID::R, sig_rst); + gate->setPort(ID::E, sig_e); gate->setPort(ID::D, sig_d[i]); gate->setPort(ID::Q, sig_q[i]); } @@ -522,6 +586,60 @@ void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) } } +void simplemap_adlatch(RTLIL::Module *module, RTLIL::Cell *cell) +{ + int width = cell->parameters.at(ID::WIDTH).as_int(); + char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N'; + char rst_pol = cell->parameters.at(ID::ARST_POLARITY).as_bool() ? 'P' : 'N'; + + std::vector<RTLIL::State> rst_val = cell->parameters.at(ID::ARST_VALUE).bits; + while (int(rst_val.size()) < width) + rst_val.push_back(RTLIL::State::S0); + + RTLIL::SigSpec sig_en = cell->getPort(ID::EN); + RTLIL::SigSpec sig_rst = cell->getPort(ID::ARST); + RTLIL::SigSpec sig_d = cell->getPort(ID::D); + RTLIL::SigSpec sig_q = cell->getPort(ID::Q); + + IdString gate_type_0 = stringf("$_DLATCH_%c%c0_", en_pol, rst_pol); + IdString gate_type_1 = stringf("$_DLATCH_%c%c1_", en_pol, rst_pol); + + for (int i = 0; i < width; i++) { + RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0); + gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); + gate->setPort(ID::E, sig_en); + gate->setPort(ID::R, sig_rst); + gate->setPort(ID::D, sig_d[i]); + gate->setPort(ID::Q, sig_q[i]); + } +} + +void simplemap_dlatchsr(RTLIL::Module *module, RTLIL::Cell *cell) +{ + int width = cell->parameters.at(ID::WIDTH).as_int(); + char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N'; + char set_pol = cell->parameters.at(ID::SET_POLARITY).as_bool() ? 'P' : 'N'; + char clr_pol = cell->parameters.at(ID::CLR_POLARITY).as_bool() ? 'P' : 'N'; + + RTLIL::SigSpec sig_en = cell->getPort(ID::EN); + RTLIL::SigSpec sig_s = cell->getPort(ID::SET); + RTLIL::SigSpec sig_r = cell->getPort(ID::CLR); + RTLIL::SigSpec sig_d = cell->getPort(ID::D); + RTLIL::SigSpec sig_q = cell->getPort(ID::Q); + + IdString gate_type = stringf("$_DLATCHSR_%c%c%c_", en_pol, set_pol, clr_pol); + + for (int i = 0; i < width; i++) { + RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); + gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); + gate->setPort(ID::E, sig_en); + gate->setPort(ID::S, sig_s[i]); + gate->setPort(ID::R, sig_r[i]); + gate->setPort(ID::D, sig_d[i]); + gate->setPort(ID::Q, sig_q[i]); + } +} + void simplemap_get_mappers(dict<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers) { mappers[ID($not)] = simplemap_not; @@ -553,8 +671,15 @@ void simplemap_get_mappers(dict<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> mappers[ID($dff)] = simplemap_dff; mappers[ID($dffe)] = simplemap_dffe; mappers[ID($dffsr)] = simplemap_dffsr; - mappers[ID($adff)] = simplemap_adff; + mappers[ID($dffsre)] = simplemap_dffsre; + mappers[ID($adff)] = simplemap_adff_sdff; + mappers[ID($sdff)] = simplemap_adff_sdff; + mappers[ID($adffe)] = simplemap_adffe_sdffe_sdffce; + mappers[ID($sdffe)] = simplemap_adffe_sdffe_sdffce; + mappers[ID($sdffce)] = simplemap_adffe_sdffe_sdffce; mappers[ID($dlatch)] = simplemap_dlatch; + mappers[ID($adlatch)] = simplemap_adlatch; + mappers[ID($dlatchsr)] = simplemap_dlatchsr; } void simplemap(RTLIL::Module *module, RTLIL::Cell *cell) @@ -575,7 +700,7 @@ PRIVATE_NAMESPACE_BEGIN struct SimplemapPass : public Pass { SimplemapPass() : Pass("simplemap", "mapping simple coarse-grain cells") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -587,10 +712,10 @@ struct SimplemapPass : public Pass { log(" $not, $pos, $and, $or, $xor, $xnor\n"); log(" $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor, $reduce_bool\n"); log(" $logic_not, $logic_and, $logic_or, $mux, $tribuf\n"); - log(" $sr, $ff, $dff, $dffsr, $adff, $dlatch\n"); + log(" $sr, $ff, $dff, $dffe, $dffsr, $dffsre, $adff, $adffe, $sdff, $sdffe, $sdffce, $dlatch, $adlatch, $dlatchsr\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing SIMPLEMAP pass (map simple cells to gate primitives).\n"); extra_args(args, 1, design); diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 535db9465..d43737c8d 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -20,6 +20,7 @@ #include "kernel/yosys.h" #include "kernel/utils.h" #include "kernel/sigtools.h" +#include "kernel/ffinit.h" #include "libs/sha1/sha1.h" #include <stdlib.h> @@ -232,16 +233,14 @@ struct TechmapWorker } } - SigMap tpl_sigmap(tpl); pool<SigBit> tpl_written_bits; - for (auto tpl_cell : tpl->cells()) for (auto &conn : tpl_cell->connections()) if (tpl_cell->output(conn.first)) - for (auto bit : tpl_sigmap(conn.second)) + for (auto bit : conn.second) tpl_written_bits.insert(bit); for (auto &conn : tpl->connections()) - for (auto bit : tpl_sigmap(conn.first)) + for (auto bit : conn.first) tpl_written_bits.insert(bit); SigMap port_signal_map; @@ -279,7 +278,7 @@ struct TechmapWorker SigSpec sig_tpl = w, sig_tpl_pf = w, sig_mod = it.second; apply_prefix(cell->name, sig_tpl_pf, module); for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) { - if (tpl_written_bits.count(tpl_sigmap(sig_tpl[i]))) { + if (tpl_written_bits.count(sig_tpl[i])) { c.first.append(sig_mod[i]); c.second.append(sig_tpl_pf[i]); } else { @@ -328,8 +327,9 @@ struct TechmapWorker for (auto tpl_cell : tpl->cells()) { IdString c_name = tpl_cell->name; + bool techmap_replace_cell = (c_name == ID::_TECHMAP_REPLACE_); - if (c_name == ID::_TECHMAP_REPLACE_) + if (techmap_replace_cell) c_name = orig_cell_name; else if (tpl_cell->name.begins_with("\\_TECHMAP_REPLACE_.")) c_name = stringf("%s%s", orig_cell_name.c_str(), c_name.c_str() + strlen("\\_TECHMAP_REPLACE_")); @@ -384,7 +384,7 @@ struct TechmapWorker if (c->attributes.count(ID::src)) c->add_strpool_attribute(ID::src, extra_src_attrs); - if (c_name == ID::_TECHMAP_REPLACE_) + if (techmap_replace_cell) for (auto attr : cell->attributes) if (!c->attributes.count(attr.first)) c->attributes[attr.first] = attr.second; @@ -425,18 +425,7 @@ struct TechmapWorker LogMakeDebugHdl mkdebug; SigMap sigmap(module); - - dict<SigBit, State> init_bits; - pool<SigBit> remove_init_bits; - - for (auto wire : module->wires()) { - if (wire->attributes.count(ID::init)) { - Const value = wire->attributes.at(ID::init); - for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++) - if (value[i] != State::Sx) - init_bits[sigmap(SigBit(wire, i))] = value[i]; - } - } + FfInitVals initvals(&sigmap, module); TopoSort<RTLIL::Cell*, IdString::compare_ptr_by_name<RTLIL::Cell>> cells; dict<RTLIL::Cell*, pool<RTLIL::SigBit>> cell_to_inbit; @@ -642,6 +631,8 @@ struct TechmapWorker if (tpl->avail_parameters.count(ID::_TECHMAP_CELLTYPE_) != 0) parameters.emplace(ID::_TECHMAP_CELLTYPE_, RTLIL::unescape_id(cell->type)); + if (tpl->avail_parameters.count(ID::_TECHMAP_CELLNAME_) != 0) + parameters.emplace(ID::_TECHMAP_CELLNAME_, RTLIL::unescape_id(cell->name)); for (auto &conn : cell->connections()) { if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", log_id(conn.first))) != 0) { @@ -658,15 +649,7 @@ struct TechmapWorker parameters.emplace(stringf("\\_TECHMAP_CONSTVAL_%s_", log_id(conn.first)), RTLIL::SigSpec(v).as_const()); } if (tpl->avail_parameters.count(stringf("\\_TECHMAP_WIREINIT_%s_", log_id(conn.first))) != 0) { - auto sig = sigmap(conn.second); - RTLIL::Const value(State::Sx, sig.size()); - for (int i = 0; i < sig.size(); i++) { - auto it = init_bits.find(sig[i]); - if (it != init_bits.end()) { - value[i] = it->second; - } - } - parameters.emplace(stringf("\\_TECHMAP_WIREINIT_%s_", log_id(conn.first)), value); + parameters.emplace(stringf("\\_TECHMAP_WIREINIT_%s_", log_id(conn.first)), initvals(conn.second)); } } @@ -816,11 +799,31 @@ struct TechmapWorker } } + // Handle outputs first, as these cannot be remapped. + for (auto &conn : cell->connections()) + { + Wire *twire = tpl->wire(conn.first); + if (!twire->port_output) + continue; + + for (int i = 0; i < GetSize(conn.second); i++) { + RTLIL::SigBit bit = sigmap(conn.second[i]); + RTLIL::SigBit tplbit(twire, i); + cellbits_to_tplbits[bit] = tplbit; + } + } + + // Now handle inputs, remapping as necessary. for (auto &conn : cell->connections()) + { + Wire *twire = tpl->wire(conn.first); + if (twire->port_output) + continue; + for (int i = 0; i < GetSize(conn.second); i++) { RTLIL::SigBit bit = sigmap(conn.second[i]); - RTLIL::SigBit tplbit(tpl->wire(conn.first), i); + RTLIL::SigBit tplbit(twire, i); if (bit.wire == nullptr) { @@ -835,6 +838,7 @@ struct TechmapWorker else cellbits_to_tplbits[bit] = tplbit; } + } RTLIL::SigSig port_conn; for (auto &it : port_connmap) { @@ -911,7 +915,7 @@ struct TechmapWorker auto sig = sigmap(it->second); for (int i = 0; i < sig.size(); i++) if (val[i] == State::S1) - remove_init_bits.insert(sig[i]); + initvals.remove_init(sig[i]); } } } @@ -960,25 +964,6 @@ struct TechmapWorker handled_cells.insert(cell); } - if (!remove_init_bits.empty()) { - for (auto wire : module->wires()) - if (wire->attributes.count(ID::init)) { - Const &value = wire->attributes.at(ID::init); - bool do_cleanup = true; - for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++) { - SigBit bit = sigmap(SigBit(wire, i)); - if (remove_init_bits.count(bit)) - value[i] = State::Sx; - else if (value[i] != State::Sx) - do_cleanup = false; - } - if (do_cleanup) { - log("Removing init attribute from wire %s.%s.\n", log_id(module), log_id(wire)); - wire->attributes.erase(ID::init); - } - } - } - if (log_continue) { log_header(design, "Continuing TECHMAP pass.\n"); log_continue = false; @@ -991,14 +976,14 @@ struct TechmapWorker struct TechmapPass : public Pass { TechmapPass() : Pass("techmap", "generic technology mapper") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" techmap [-map filename] [selection]\n"); log("\n"); log("This pass implements a very simple technology mapper that replaces cells in\n"); - log("the design with implementations given in form of a Verilog or ilang source\n"); + log("the design with implementations given in form of a Verilog or RTLIL source\n"); log("file.\n"); log("\n"); log(" -map filename\n"); @@ -1041,7 +1026,9 @@ struct TechmapPass : public Pass { log("\n"); log("When a module in the map file has the 'techmap_celltype' attribute set, it will\n"); log("match cells with a type that match the text value of this attribute. Otherwise\n"); - log("the module name will be used to match the cell.\n"); + log("the module name will be used to match the cell. Multiple space-separated cell\n"); + log("types can be listed, and wildcards using [] will be expanded (ie. \"$_DFF_[PN]_\"\n"); + log("is the same as \"$_DFF_P_ $_DFF_N_\").\n"); log("\n"); log("When a module in the map file has the 'techmap_simplemap' attribute set, techmap\n"); log("will use 'simplemap' (see 'help simplemap') to map cells matching the module.\n"); @@ -1110,6 +1097,10 @@ struct TechmapPass : public Pass { log(" When a parameter with this name exists, it will be set to the type name\n"); log(" of the cell that matches the module.\n"); log("\n"); + log(" _TECHMAP_CELLNAME_\n"); + log(" When a parameter with this name exists, it will be set to the name\n"); + log(" of the cell that matches the module.\n"); + log("\n"); log(" _TECHMAP_CONSTMSK_<port-name>_\n"); log(" _TECHMAP_CONSTVAL_<port-name>_\n"); log(" When this pair of parameters is available in a module for a port, then\n"); @@ -1151,7 +1142,7 @@ struct TechmapPass : public Pass { log("essentially techmap but using the design itself as map library).\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing TECHMAP pass (map to technology primitives).\n"); log_push(); @@ -1219,7 +1210,7 @@ struct TechmapPass : public Pass { if (!map->module(mod->name)) map->add(mod->clone()); } else { - Frontend::frontend_call(map, nullptr, fn, (fn.size() > 3 && fn.compare(fn.size()-3, std::string::npos, ".il") == 0 ? "ilang" : verilog_frontend)); + Frontend::frontend_call(map, nullptr, fn, (fn.size() > 3 && fn.compare(fn.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : verilog_frontend)); } } @@ -1229,8 +1220,27 @@ struct TechmapPass : public Pass { for (auto module : map->modules()) { if (module->attributes.count(ID::techmap_celltype) && !module->attributes.at(ID::techmap_celltype).bits.empty()) { char *p = strdup(module->attributes.at(ID::techmap_celltype).decode_string().c_str()); - for (char *q = strtok(p, " \t\r\n"); q; q = strtok(nullptr, " \t\r\n")) - celltypeMap[RTLIL::escape_id(q)].insert(module->name); + for (char *q = strtok(p, " \t\r\n"); q; q = strtok(nullptr, " \t\r\n")) { + std::vector<std::string> queue; + queue.push_back(q); + while (!queue.empty()) { + std::string name = queue.back(); + queue.pop_back(); + auto pos = name.find('['); + if (pos == std::string::npos) { + // No further expansion. + celltypeMap[RTLIL::escape_id(name)].insert(module->name); + } else { + // Expand [] in this name. + auto epos = name.find(']', pos); + if (epos == std::string::npos) + log_error("Malformed techmap_celltype pattern %s\n", q); + for (size_t i = pos + 1; i < epos; i++) { + queue.push_back(name.substr(0, pos) + name[i] + name.substr(epos + 1, std::string::npos)); + } + } + } + } free(p); } else { IdString module_name = module->name.begins_with("\\$") ? @@ -1238,8 +1248,15 @@ struct TechmapPass : public Pass { celltypeMap[module_name].insert(module->name); } } - for (auto &i : celltypeMap) + log_debug("Cell type mappings to use:\n"); + for (auto &i : celltypeMap) { i.second.sort(RTLIL::sort_by_id_str()); + std::string maps = ""; + for (auto &map : i.second) + maps += stringf(" %s", log_id(map)); + log_debug(" %s:%s\n", log_id(i.first), maps.c_str()); + } + log_debug("\n"); for (auto module : design->modules()) worker.module_queue.insert(module); diff --git a/passes/techmap/tribuf.cc b/passes/techmap/tribuf.cc index 90f3a9d6f..79ddb4bd7 100644 --- a/passes/techmap/tribuf.cc +++ b/passes/techmap/tribuf.cc @@ -143,7 +143,7 @@ struct TribufWorker { struct TribufPass : public Pass { TribufPass() : Pass("tribuf", "infer tri-state buffers") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -160,7 +160,7 @@ struct TribufPass : public Pass { log(" to non-tristate logic. this option implies -merge.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { TribufConfig config; diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index 74604ba3b..e3b4ae573 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -19,13 +19,14 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/ffinit.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct ZinitPass : public Pass { ZinitPass() : Pass("zinit", "add inverters so all FF are zero-initialized") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -37,7 +38,7 @@ struct ZinitPass : public Pass { log(" also add zero initialization to uninitialized FFs\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool all_mode = false; @@ -57,54 +58,35 @@ struct ZinitPass : public Pass { for (auto module : design->selected_modules()) { SigMap sigmap(module); - dict<SigBit, std::pair<State,SigBit>> initbits; - - for (auto wire : module->selected_wires()) - { - if (wire->attributes.count(ID::init) == 0) - continue; - - SigSpec wirebits = sigmap(wire); - Const initval = wire->attributes.at(ID::init); - - for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) - { - SigBit bit = wirebits[i]; - State val = initval[i]; - - if (val != State::S0 && val != State::S1 && bit.wire != nullptr) - continue; - - if (initbits.count(bit)) { - if (initbits.at(bit).first != val) - log_error("Conflicting init values for signal %s (%s = %s != %s).\n", - log_signal(bit), log_signal(SigBit(wire, i)), - log_signal(val), log_signal(initbits.at(bit).first)); - continue; - } - - initbits[bit] = std::make_pair(val,SigBit(wire,i)); - } - } + FfInitVals initvals(&sigmap, module); pool<IdString> dff_types = { // FIXME: It would appear that supporting // $dffsr/$_DFFSR_* would require a new // cell type where S has priority over R - ID($ff), ID($dff), ID($dffe), /*ID($dffsr),*/ ID($adff), + ID($ff), ID($dff), ID($dffe), /*ID($dffsr),*/ ID($adff), ID($adffe), + ID($sdff), ID($sdffe), ID($sdffce), ID($_FF_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), /*ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_),*/ ID($_DFF_N_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), ID($_DFF_P_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_), // Async set/reset - ID($__DFFE_NN0), ID($__DFFE_NN1), ID($__DFFE_NP0), ID($__DFFE_NP1), - ID($__DFFE_PN0), ID($__DFFE_PN1), ID($__DFFE_PP0), ID($__DFFE_PP1), + ID($_DFFE_NN0P_), ID($_DFFE_NN1P_), ID($_DFFE_NP0P_), ID($_DFFE_NP1P_), + ID($_DFFE_PN0P_), ID($_DFFE_PN1P_), ID($_DFFE_PP0P_), ID($_DFFE_PP1P_), + ID($_DFFE_NN0N_), ID($_DFFE_NN1N_), ID($_DFFE_NP0N_), ID($_DFFE_NP1N_), + ID($_DFFE_PN0N_), ID($_DFFE_PN1N_), ID($_DFFE_PP0N_), ID($_DFFE_PP1N_), // Sync set/reset - ID($__DFFS_NN0_), ID($__DFFS_NN1_), ID($__DFFS_NP0_), ID($__DFFS_NP1_), - ID($__DFFS_PN0_), ID($__DFFS_PN1_), ID($__DFFS_PP0_), ID($__DFFS_PP1_), - ID($__DFFSE_NN0), ID($__DFFSE_NN1), ID($__DFFSE_NP0), ID($__DFFSE_NP1), - ID($__DFFSE_PN0), ID($__DFFSE_PN1), ID($__DFFSE_PP0), ID($__DFFSE_PP1) + ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_), + ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_), + ID($_SDFFE_NN0P_), ID($_SDFFE_NN1P_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1P_), + ID($_SDFFE_PN0P_), ID($_SDFFE_PN1P_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1P_), + ID($_SDFFE_NN0N_), ID($_SDFFE_NN1N_), ID($_SDFFE_NP0N_), ID($_SDFFE_NP1N_), + ID($_SDFFE_PN0N_), ID($_SDFFE_PN1N_), ID($_SDFFE_PP0N_), ID($_SDFFE_PP1N_), + ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1P_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1P_), + ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1P_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1P_), + ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP1N_), + ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP1N_) }; for (auto cell : module->selected_cells()) @@ -118,46 +100,48 @@ struct ZinitPass : public Pass { if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1) continue; - Const initval; + Const initval = initvals(sig_q); + Const newval = initval; + initvals.remove_init(sig_q); - for (int i = 0; i < GetSize(sig_q); i++) { - if (initbits.count(sig_q[i])) { - const auto &d = initbits.at(sig_q[i]); - initval.bits.push_back(d.first); - const auto &b = d.second; - b.wire->attributes.at(ID::init)[b.offset] = State::Sx; - } else - initval.bits.push_back(all_mode ? State::S0 : State::Sx); - } - - Wire *initwire = module->addWire(NEW_ID, GetSize(initval)); - initwire->attributes[ID::init] = initval; + Wire *initwire = module->addWire(NEW_ID, GetSize(sig_q)); for (int i = 0; i < GetSize(initwire); i++) if (initval[i] == State::S1) { sig_d[i] = module->NotGate(NEW_ID, sig_d[i]); module->addNotGate(NEW_ID, SigSpec(initwire, i), sig_q[i]); - initwire->attributes[ID::init][i] = State::S0; + newval[i] = State::S0; } else { module->connect(sig_q[i], SigSpec(initwire, i)); + if (all_mode) + newval[i] = State::S0; } + initvals.set_init(initwire, newval); + log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type), log_signal(sig_q), log_signal(initval)); cell->setPort(ID::D, sig_d); cell->setPort(ID::Q, initwire); - if (cell->type == ID($adff)) { + if (cell->type.in(ID($adff), ID($adffe))) { auto val = cell->getParam(ID::ARST_VALUE); for (int i = 0; i < GetSize(initwire); i++) if (initval[i] == State::S1) val[i] = (val[i] == State::S1 ? State::S0 : State::S1); cell->setParam(ID::ARST_VALUE, std::move(val)); } + else if (cell->type.in(ID($sdff), ID($sdffe), ID($sdffce))) { + auto val = cell->getParam(ID::SRST_VALUE); + for (int i = 0; i < GetSize(initwire); i++) + if (initval[i] == State::S1) + val[i] = (val[i] == State::S1 ? State::S0 : State::S1); + cell->setParam(ID::SRST_VALUE, std::move(val)); + } else if (initval == State::S1) { std::string t = cell->type.str(); if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), @@ -165,15 +149,29 @@ struct ZinitPass : public Pass { { t[8] = (t[8] == '0' ? '1' : '0'); } - else if (cell->type.in(ID($__DFFE_NN0), ID($__DFFE_NN1), ID($__DFFE_NP0), ID($__DFFE_NP1), - ID($__DFFE_PN0), ID($__DFFE_PN1), ID($__DFFE_PP0), ID($__DFFE_PP1), - ID($__DFFS_NN0_), ID($__DFFS_NN1_), ID($__DFFS_NP0_), ID($__DFFS_NP1_), - ID($__DFFS_PN0_), ID($__DFFS_PN1_), ID($__DFFS_PP0_), ID($__DFFS_PP1_))) + else if (cell->type.in(ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_), + ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_))) + { + t[9] = (t[9] == '0' ? '1' : '0'); + } + else if (cell->type.in(ID($_DFFE_NN0P_), ID($_DFFE_NN1P_), ID($_DFFE_NP0P_), ID($_DFFE_NP1P_), + ID($_DFFE_PN0P_), ID($_DFFE_PN1P_), ID($_DFFE_PP0P_), ID($_DFFE_PP1P_), + ID($_DFFE_NN0N_), ID($_DFFE_NN1N_), ID($_DFFE_NP0N_), ID($_DFFE_NP1N_), + ID($_DFFE_PN0N_), ID($_DFFE_PN1N_), ID($_DFFE_PP0N_), ID($_DFFE_PP1N_))) + { + t[9] = (t[9] == '0' ? '1' : '0'); + } + else if (cell->type.in(ID($_SDFFE_NN0P_), ID($_SDFFE_NN1P_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1P_), + ID($_SDFFE_PN0P_), ID($_SDFFE_PN1P_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1P_), + ID($_SDFFE_NN0N_), ID($_SDFFE_NN1N_), ID($_SDFFE_NP0N_), ID($_SDFFE_NP1N_), + ID($_SDFFE_PN0N_), ID($_SDFFE_PN1N_), ID($_SDFFE_PP0N_), ID($_SDFFE_PP1N_))) { t[10] = (t[10] == '0' ? '1' : '0'); } - else if (cell->type.in(ID($__DFFSE_NN0), ID($__DFFSE_NN1), ID($__DFFSE_NP0), ID($__DFFSE_NP1), - ID($__DFFSE_PN0), ID($__DFFSE_PN1), ID($__DFFSE_PP0), ID($__DFFSE_PP1))) + else if (cell->type.in(ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1P_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1P_), + ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1P_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1P_), + ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP1N_), + ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP1N_))) { t[11] = (t[11] == '0' ? '1' : '0'); } diff --git a/passes/tests/test_abcloop.cc b/passes/tests/test_abcloop.cc index 894610e2b..ac31e36f1 100644 --- a/passes/tests/test_abcloop.cc +++ b/passes/tests/test_abcloop.cc @@ -132,7 +132,7 @@ static void test_abcloop() SatGen satgen(ez.get(), &sigmap); for (auto c : module->cells()) { - bool ok YS_ATTRIBUTE(unused) = satgen.importCell(c); + bool ok = satgen.importCell(c); log_assert(ok); } @@ -171,7 +171,7 @@ static void test_abcloop() } log("Found viable UUT after %d cycles:\n", create_cycles); - Pass::call(design, "write_ilang"); + Pass::call(design, "write_rtlil"); Pass::call(design, "abc"); log("\n"); @@ -182,7 +182,7 @@ static void test_abcloop() SatGen satgen(ez.get(), &sigmap); for (auto c : module->cells()) { - bool ok YS_ATTRIBUTE(unused) = satgen.importCell(c); + bool ok = satgen.importCell(c); log_assert(ok); } @@ -244,7 +244,7 @@ static void test_abcloop() struct TestAbcloopPass : public Pass { TestAbcloopPass() : Pass("test_abcloop", "automatically test handling of loops in abc command") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -259,7 +259,7 @@ struct TestAbcloopPass : public Pass { log(" use this value as rng seed value (default = unix time).\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design*) override { int num_iter = 100; xorshift32_state = 0; diff --git a/passes/tests/test_autotb.cc b/passes/tests/test_autotb.cc index 19f21493d..4ab46014d 100644 --- a/passes/tests/test_autotb.cc +++ b/passes/tests/test_autotb.cc @@ -327,7 +327,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter, int s struct TestAutotbBackend : public Backend { TestAutotbBackend() : Backend("=test_autotb", "generate simple test benches") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -360,7 +360,7 @@ struct TestAutotbBackend : public Backend { log(" the current system time.\n"); log("\n"); } - void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { int num_iter = 1000; int seed = 0; diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index c6801007d..616981f32 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -264,6 +264,14 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, cell->setPort(ID::Y, wire); } + if (cell_type.in(ID($shiftx))) { + cell->parameters[ID::A_SIGNED] = false; + } + + if (cell_type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) { + cell->parameters[ID::B_SIGNED] = false; + } + if (muxdiv && cell_type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) { auto b_not_zero = module->ReduceBool(NEW_ID, cell->getPort(ID::B)); auto div_out = module->addWire(NEW_ID, GetSize(cell->getPort(ID::Y))); @@ -652,7 +660,7 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: struct TestCellPass : public Pass { TestCellPass() : Pass("test_cell", "automatically test the implementation of a cell type") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -670,12 +678,12 @@ struct TestCellPass : public Pass { log(" -s {positive_integer}\n"); log(" use this value as rng seed value (default = unix time).\n"); log("\n"); - log(" -f {ilang_file}\n"); - log(" don't generate circuits. instead load the specified ilang file.\n"); + log(" -f {rtlil_file}\n"); + log(" don't generate circuits. instead load the specified RTLIL file.\n"); log("\n"); log(" -w {filename_prefix}\n"); log(" don't test anything. just generate the circuits and write them\n"); - log(" to ilang files with the specified prefix\n"); + log(" to RTLIL files with the specified prefix\n"); log("\n"); log(" -map {filename}\n"); log(" pass this option to techmap.\n"); @@ -712,11 +720,11 @@ struct TestCellPass : public Pass { log(" create a Verilog test bench to test simlib and write_verilog\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design*) override { int num_iter = 100; std::string techmap_cmd = "techmap -assert"; - std::string ilang_file, write_prefix; + std::string rtlil_file, write_prefix; xorshift32_state = 0; std::ofstream vlog_file; bool muxdiv = false; @@ -742,7 +750,7 @@ struct TestCellPass : public Pass { continue; } if (args[argidx] == "-f" && argidx+1 < GetSize(args)) { - ilang_file = args[++argidx]; + rtlil_file = args[++argidx]; num_iter = 1; continue; } @@ -902,10 +910,10 @@ struct TestCellPass : public Pass { selected_cell_types.push_back(args[argidx]); } - if (!ilang_file.empty()) { + if (!rtlil_file.empty()) { if (!selected_cell_types.empty()) log_cmd_error("Do not specify any cell types when using -f.\n"); - selected_cell_types.push_back("ilang"); + selected_cell_types.push_back(ID(rtlil)); } if (selected_cell_types.empty()) @@ -917,12 +925,12 @@ struct TestCellPass : public Pass { for (int i = 0; i < num_iter; i++) { RTLIL::Design *design = new RTLIL::Design; - if (cell_type == "ilang") - Frontend::frontend_call(design, NULL, std::string(), "ilang " + ilang_file); + if (cell_type == ID(rtlil)) + Frontend::frontend_call(design, NULL, std::string(), "rtlil " + rtlil_file); else create_gold_module(design, cell_type, cell_types.at(cell_type), constmode, muxdiv); if (!write_prefix.empty()) { - Pass::call(design, stringf("write_ilang %s_%s_%05d.il", write_prefix.c_str(), cell_type.c_str()+1, i)); + Pass::call(design, stringf("write_rtlil %s_%s_%05d.il", write_prefix.c_str(), cell_type.c_str()+1, i)); } else if (edges) { Pass::call(design, "dump gold"); run_edges_test(design, verbose); diff --git a/techlibs/achronix/synth_achronix.cc b/techlibs/achronix/synth_achronix.cc index 262a5e700..b203828d2 100644 --- a/techlibs/achronix/synth_achronix.cc +++ b/techlibs/achronix/synth_achronix.cc @@ -28,7 +28,7 @@ PRIVATE_NAMESPACE_BEGIN struct SynthAchronixPass : public ScriptPass { SynthAchronixPass() : ScriptPass("synth_achronix", "synthesis for Acrhonix Speedster22i FPGAs.") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -63,7 +63,7 @@ struct SynthAchronixPass : public ScriptPass { string top_opt, family_opt, vout_file; bool retime, flatten; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; vout_file = ""; @@ -71,7 +71,7 @@ struct SynthAchronixPass : public ScriptPass { flatten = true; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -118,7 +118,7 @@ struct SynthAchronixPass : public ScriptPass { log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("begin")) { @@ -144,12 +144,12 @@ struct SynthAchronixPass : public ScriptPass { run("opt -fast -mux_undef -undriven -fine -full"); run("memory_map"); run("opt -undriven -fine"); - run("dff2dffe -direct-match $_DFF_*"); run("opt -fine"); run("techmap -map +/techmap.v"); run("opt -full"); run("clean -purge"); run("setundef -undriven -zero"); + run("dfflegalize -cell $_DFF_P_ x"); if (retime || help_mode) run("abc -markgroups -dff -D 1", "(only if -retime)"); } diff --git a/techlibs/anlogic/anlogic_eqn.cc b/techlibs/anlogic/anlogic_eqn.cc index e4fa4413f..e5fbc186f 100644 --- a/techlibs/anlogic/anlogic_eqn.cc +++ b/techlibs/anlogic/anlogic_eqn.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct AnlogicEqnPass : public Pass { AnlogicEqnPass() : Pass("anlogic_eqn", "Anlogic: Calculate equations for luts") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" anlogic_eqn [selection]\n"); @@ -63,7 +63,7 @@ struct AnlogicEqnPass : public Pass { return Const(eqn); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing ANLOGIC_EQN pass (calculate equations for luts).\n"); diff --git a/techlibs/anlogic/anlogic_fixcarry.cc b/techlibs/anlogic/anlogic_fixcarry.cc index f8e70260c..c7dfe3c05 100644 --- a/techlibs/anlogic/anlogic_fixcarry.cc +++ b/techlibs/anlogic/anlogic_fixcarry.cc @@ -98,7 +98,7 @@ static void fix_carry_chain(Module *module) struct AnlogicCarryFixPass : public Pass { AnlogicCarryFixPass() : Pass("anlogic_fixcarry", "Anlogic: fix carry chain") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -107,7 +107,7 @@ struct AnlogicCarryFixPass : public Pass { log("Add Anlogic adders to fix carry chain if needed.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing anlogic_fixcarry pass (fix invalid carry chain).\n"); diff --git a/techlibs/anlogic/cells_map.v b/techlibs/anlogic/cells_map.v index 0bcea9856..d9f264ab1 100644 --- a/techlibs/anlogic/cells_map.v +++ b/techlibs/anlogic/cells_map.v @@ -1,31 +1,17 @@ -module \$_DFF_N_ (input D, C, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(1'b0)); endmodule -module \$_DFF_P_ (input D, C, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(1'b0)); endmodule +module \$_DFFE_PN0P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C) ,.ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PN1P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("SET"), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP0P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP1P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("SET"), .SRMUX("SR"), . SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_NN_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(E), .sr(1'b0)); endmodule -module \$_DFFE_NP_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(E), .sr(1'b0)); endmodule -module \$_DFFE_PN_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(1'b0)); endmodule -module \$_DFFE_PP_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(1'b0)); endmodule +module \$_SDFFE_PN0P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C) ,.ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PN1P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("SET"), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP0P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP1P_ (input D, C, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("SET"), .SRMUX("SR"), . SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFF_NN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_NP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C) , .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), . SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule - -module \$_DLATCH_N_ (E, D, Q); - wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; - input E, D; - output Q = !E ? D : Q; -endmodule - -module \$_DLATCH_P_ (E, D, Q); - wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; - input E, D; - output Q = E ? D : Q; -endmodule +module \$_DLATCH_NN0_ (input D, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("LATCH"), .REGSET("RESET"), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(E) ,.ce(1'b1), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DLATCH_NN1_ (input D, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("LATCH"), .REGSET("SET"), .SRMUX("INV"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(E), .ce(1'b1), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DLATCH_NP0_ (input D, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("LATCH"), .REGSET("RESET"), .SRMUX("SR"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(E), .ce(1'b1), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DLATCH_NP1_ (input D, R, E, output Q); AL_MAP_SEQ #(.DFFMODE("LATCH"), .REGSET("SET"), .SRMUX("SR"), . SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(E), .ce(1'b1), .sr(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule `ifndef NO_LUT module \$lut (A, Y); diff --git a/techlibs/anlogic/cells_sim.v b/techlibs/anlogic/cells_sim.v index 0fba43572..e8ecf4f03 100644 --- a/techlibs/anlogic/cells_sim.v +++ b/techlibs/anlogic/cells_sim.v @@ -10,9 +10,6 @@ module AL_MAP_SEQ ( parameter SRMUX = "SR"; //SR/INV parameter SRMODE = "SYNC"; //SYNC/ASYNC - wire clk_ce; - assign clk_ce = ce ? clk : 1'b0; - wire srmux; generate case (SRMUX) @@ -20,7 +17,7 @@ module AL_MAP_SEQ ( "INV": assign srmux = ~sr; default: assign srmux = sr; endcase - endgenerate + endgenerate wire regset; generate @@ -34,43 +31,45 @@ module AL_MAP_SEQ ( initial q = regset; generate - if (DFFMODE == "FF") + if (DFFMODE == "FF") begin - if (SRMODE == "ASYNC") + if (SRMODE == "ASYNC") begin - always @(posedge clk_ce, posedge srmux) + always @(posedge clk, posedge srmux) if (srmux) q <= regset; - else - q <= d; - end + else if (ce) + q <= d; + end else begin - always @(posedge clk_ce) + always @(posedge clk) if (srmux) q <= regset; - else - q <= d; + else if (ce) + q <= d; end end else begin // DFFMODE == "LATCH" - if (SRMODE == "ASYNC") + if (SRMODE == "ASYNC") begin - always @(clk_ce, srmux) + always @* if (srmux) q <= regset; - else - q <= d; - end + else if (~clk & ce) + q <= d; + end else begin - always @(clk_ce) - if (srmux) - q <= regset; - else - q <= d; + always @* + if (~clk) begin + if (srmux) + q <= regset; + else if (ce) + q <= d; + end end end endgenerate diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index 791dc922f..d953fae5e 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -30,7 +30,7 @@ struct SynthAnlogicPass : public ScriptPass { SynthAnlogicPass() : ScriptPass("synth_anlogic", "synthesis for Anlogic FPGAs") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -72,7 +72,7 @@ struct SynthAnlogicPass : public ScriptPass string top_opt, edif_file, json_file; bool flatten, retime, nolutram; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; edif_file = ""; @@ -82,7 +82,7 @@ struct SynthAnlogicPass : public ScriptPass nolutram = false; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -137,7 +137,7 @@ struct SynthAnlogicPass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("begin")) { @@ -182,8 +182,8 @@ struct SynthAnlogicPass : public ScriptPass if (check_label("map_ffs")) { + run("dfflegalize -cell $_DFFE_P??P_ r -cell $_SDFFE_P??P_ r -cell $_DLATCH_N??_ r"); run("techmap -D NO_LUT -map +/anlogic/cells_map.v"); - run("dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit"); run("opt_expr -mux_undef"); run("simplemap"); } diff --git a/techlibs/common/abc9_map.v b/techlibs/common/abc9_map.v index 6ed90b5f5..b00e0e6a8 100644 --- a/techlibs/common/abc9_map.v +++ b/techlibs/common/abc9_map.v @@ -1,5 +1,5 @@ `ifdef DFF -(* techmap_celltype = "$_DFF_N_ $_DFF_P_" *) +(* techmap_celltype = "$_DFF_[PN]_" *) module $_DFF_x_(input C, D, output Q); parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; parameter _TECHMAP_CELLTYPE_ = ""; diff --git a/techlibs/common/gen_fine_ffs.py b/techlibs/common/gen_fine_ffs.py index 0abe48f61..5d331e767 100644 --- a/techlibs/common/gen_fine_ffs.py +++ b/techlibs/common/gen_fine_ffs.py @@ -108,6 +108,31 @@ endmodule """ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- +//- $_DFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q) +//- +//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity {V:reset|set} and {E:negative|positive} +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - {R:0|1} - | {V:0|1} +//- d {C:\\|/} - {E:0|1} | d +//- - - - - | q +//- +module \$_DFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @({C:neg|pos}edge C or {R:neg|pos}edge R) begin + if (R == {R:0|1}) + Q <= {V:0|1}; + else if (E == {E:0|1}) + Q <= D; +end +endmodule +""", +""" +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- //- $_DFFSR_{C:N|P}{S:N|P}{R:N|P}_ (C, S, R, D, Q) //- //- A {C:negative|positive} edge D-type flip-flop with {S:negative|positive} polarity set and {R:negative|positive} @@ -136,6 +161,110 @@ endmodule """ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- +//- $_DFFSRE_{C:N|P}{S:N|P}{R:N|P}{E:N|P}_ (C, S, R, E, D, Q) +//- +//- A {C:negative|positive} edge D-type flip-flop with {S:negative|positive} polarity set, {R:negative|positive} +//- polarity reset and {E:negative|positive} polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - {R:0|1} - - | 0 +//- - {S:0|1} - - - | 1 +//- {C:\\|/} - - {E:0|1} d | d +//- - - - - - | q +//- +module \$_DFFSRE_{C:N|P}{S:N|P}{R:N|P}{E:N|P}_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @({C:neg|pos}edge C, {S:neg|pos}edge S, {R:neg|pos}edge R) begin + if (R == {R:0|1}) + Q <= 0; + else if (S == {S:0|1}) + Q <= 1; + else if (E == {E:0|1}) + Q <= D; +end +endmodule +""", +""" +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFF_{C:N|P}{R:N|P}{V:0|1}_ (D, C, R, Q) +//- +//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity synchronous {V:reset|set}. +//- +//- Truth table: D C R | Q +//- -------+--- +//- - {C:\\|/} {R:0|1} | {V:0|1} +//- d {C:\\|/} - | d +//- - - - | q +//- +module \$_SDFF_{C:N|P}{R:N|P}{V:0|1}_ (D, C, R, Q); +input D, C, R; +output reg Q; +always @({C:neg|pos}edge C) begin + if (R == {R:0|1}) + Q <= {V:0|1}; + else + Q <= D; +end +endmodule +""", +""" +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q) +//- +//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity synchronous {V:reset|set} and {E:negative|positive} +//- polarity clock enable (with {V:reset|set} having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - {C:\\|/} {R:0|1} - | {V:0|1} +//- d {C:\\|/} - {E:0|1} | d +//- - - - - | q +//- +module \$_SDFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @({C:neg|pos}edge C) begin + if (R == {R:0|1}) + Q <= {V:0|1}; + else if (E == {E:0|1}) + Q <= D; +end +endmodule +""", +""" +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q) +//- +//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity synchronous {V:reset|set} and {E:negative|positive} +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - {C:\\|/} {R:0|1} {E:0|1} | {V:0|1} +//- d {C:\\|/} - {E:0|1} | d +//- - - - - | q +//- +module \$_SDFFCE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @({C:neg|pos}edge C) begin + if (E == {E:0|1}) begin + if (R == {R:0|1}) + Q <= {V:0|1}; + else + Q <= D; + end +end +endmodule +""", +""" +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- //- $_DLATCH_{E:N|P}_ (E, D, Q) //- //- A {E:negative|positive} enable D-type latch. @@ -157,6 +286,30 @@ endmodule """ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- +//- $_DLATCH_{E:N|P}{R:N|P}{V:0|1}_ (E, R, D, Q) +//- +//- A {E:negative|positive} enable D-type latch with {R:negative|positive} polarity {V:reset|set}. +//- +//- Truth table: E R D | Q +//- -------+--- +//- - {R:0|1} - | {V:0|1} +//- {E:0|1} - d | d +//- - - - | q +//- +module \$_DLATCH_{E:N|P}{R:N|P}{V:0|1}_ (E, R, D, Q); +input E, R, D; +output reg Q; +always @* begin + if (R == {R:0|1}) + Q <= {V:0|1}; + else if (E == {E:0|1}) + Q <= D; +end +endmodule +""", +""" +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- //- $_DLATCHSR_{E:N|P}{S:N|P}{R:N|P}_ (E, S, R, D, Q) //- //- A {E:negative|positive} enable D-type latch with {S:negative|positive} polarity set and {R:negative|positive} diff --git a/techlibs/common/prep.cc b/techlibs/common/prep.cc index cdd21c3b3..93b0910d6 100644 --- a/techlibs/common/prep.cc +++ b/techlibs/common/prep.cc @@ -29,7 +29,7 @@ struct PrepPass : public ScriptPass { PrepPass() : ScriptPass("prep", "generic synthesis script") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -81,7 +81,7 @@ struct PrepPass : public ScriptPass string top_module, fsm_opts; bool autotop, flatten, ifxmode, memxmode, nomemmode, nokeepdc, nordff; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_module.clear(); @@ -94,7 +94,7 @@ struct PrepPass : public ScriptPass nordff = true; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; @@ -163,7 +163,7 @@ struct PrepPass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("begin")) @@ -192,7 +192,7 @@ struct PrepPass : public ScriptPass run(nokeepdc ? "opt_expr" : "opt_expr -keepdc"); run("opt_clean"); run("check"); - run(nokeepdc ? "opt" : "opt -keepdc"); + run(nokeepdc ? "opt -noff" : "opt -noff -keepdc"); if (!ifxmode) { if (help_mode) run("wreduce -keepdc [-memx]"); @@ -208,7 +208,7 @@ struct PrepPass : public ScriptPass run("opt_clean"); run("memory_collect"); } - run(nokeepdc ? "opt -fast" : "opt -keepdc -fast"); + run(nokeepdc ? "opt -noff -fast" : "opt -noff -keepdc -fast"); } if (check_label("check")) diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 157e8d23b..27ef44232 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -870,6 +870,390 @@ endmodule // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- +//- $_DFFE_NN0N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity reset and negative +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 0 - | 0 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_DFFE_NN0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C or negedge R) begin + if (R == 0) + Q <= 0; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_NN0P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity reset and positive +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 0 - | 0 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_DFFE_NN0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C or negedge R) begin + if (R == 0) + Q <= 0; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_NN1N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity set and negative +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 0 - | 1 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_DFFE_NN1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C or negedge R) begin + if (R == 0) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_NN1P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity set and positive +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 0 - | 1 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_DFFE_NN1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C or negedge R) begin + if (R == 0) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_NP0N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity reset and negative +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 1 - | 0 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_DFFE_NP0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C or posedge R) begin + if (R == 1) + Q <= 0; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_NP0P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity reset and positive +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 1 - | 0 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_DFFE_NP0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C or posedge R) begin + if (R == 1) + Q <= 0; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_NP1N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity set and negative +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 1 - | 1 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_DFFE_NP1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C or posedge R) begin + if (R == 1) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_NP1P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity set and positive +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 1 - | 1 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_DFFE_NP1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C or posedge R) begin + if (R == 1) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_PN0N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity reset and negative +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 0 - | 0 +//- d / - 0 | d +//- - - - - | q +//- +module \$_DFFE_PN0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C or negedge R) begin + if (R == 0) + Q <= 0; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_PN0P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity reset and positive +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 0 - | 0 +//- d / - 1 | d +//- - - - - | q +//- +module \$_DFFE_PN0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C or negedge R) begin + if (R == 0) + Q <= 0; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_PN1N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity set and negative +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 0 - | 1 +//- d / - 0 | d +//- - - - - | q +//- +module \$_DFFE_PN1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C or negedge R) begin + if (R == 0) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_PN1P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity set and positive +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 0 - | 1 +//- d / - 1 | d +//- - - - - | q +//- +module \$_DFFE_PN1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C or negedge R) begin + if (R == 0) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_PP0N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity reset and negative +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 1 - | 0 +//- d / - 0 | d +//- - - - - | q +//- +module \$_DFFE_PP0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C or posedge R) begin + if (R == 1) + Q <= 0; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_PP0P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity reset and positive +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 1 - | 0 +//- d / - 1 | d +//- - - - - | q +//- +module \$_DFFE_PP0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C or posedge R) begin + if (R == 1) + Q <= 0; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_PP1N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity set and negative +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 1 - | 1 +//- d / - 0 | d +//- - - - - | q +//- +module \$_DFFE_PP1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C or posedge R) begin + if (R == 1) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFE_PP1P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity set and positive +//- polarity clock enable. +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - - 1 - | 1 +//- d / - 1 | d +//- - - - - | q +//- +module \$_DFFE_PP1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C or posedge R) begin + if (R == 1) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- //- $_DFFSR_NNN_ (C, S, R, D, Q) //- //- A negative edge D-type flip-flop with negative polarity set and negative @@ -1086,6 +1470,1422 @@ endmodule // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- +//- $_DFFSRE_NNNN_ (C, S, R, E, D, Q) +//- +//- A negative edge D-type flip-flop with negative polarity set, negative +//- polarity reset and negative polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 0 - - | 0 +//- - 0 - - - | 1 +//- \ - - 0 d | d +//- - - - - - | q +//- +module \$_DFFSRE_NNNN_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(negedge C, negedge S, negedge R) begin + if (R == 0) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_NNNP_ (C, S, R, E, D, Q) +//- +//- A negative edge D-type flip-flop with negative polarity set, negative +//- polarity reset and positive polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 0 - - | 0 +//- - 0 - - - | 1 +//- \ - - 1 d | d +//- - - - - - | q +//- +module \$_DFFSRE_NNNP_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(negedge C, negedge S, negedge R) begin + if (R == 0) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_NNPN_ (C, S, R, E, D, Q) +//- +//- A negative edge D-type flip-flop with negative polarity set, positive +//- polarity reset and negative polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 1 - - | 0 +//- - 0 - - - | 1 +//- \ - - 0 d | d +//- - - - - - | q +//- +module \$_DFFSRE_NNPN_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(negedge C, negedge S, posedge R) begin + if (R == 1) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_NNPP_ (C, S, R, E, D, Q) +//- +//- A negative edge D-type flip-flop with negative polarity set, positive +//- polarity reset and positive polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 1 - - | 0 +//- - 0 - - - | 1 +//- \ - - 1 d | d +//- - - - - - | q +//- +module \$_DFFSRE_NNPP_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(negedge C, negedge S, posedge R) begin + if (R == 1) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_NPNN_ (C, S, R, E, D, Q) +//- +//- A negative edge D-type flip-flop with positive polarity set, negative +//- polarity reset and negative polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 0 - - | 0 +//- - 1 - - - | 1 +//- \ - - 0 d | d +//- - - - - - | q +//- +module \$_DFFSRE_NPNN_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(negedge C, posedge S, negedge R) begin + if (R == 0) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_NPNP_ (C, S, R, E, D, Q) +//- +//- A negative edge D-type flip-flop with positive polarity set, negative +//- polarity reset and positive polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 0 - - | 0 +//- - 1 - - - | 1 +//- \ - - 1 d | d +//- - - - - - | q +//- +module \$_DFFSRE_NPNP_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(negedge C, posedge S, negedge R) begin + if (R == 0) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_NPPN_ (C, S, R, E, D, Q) +//- +//- A negative edge D-type flip-flop with positive polarity set, positive +//- polarity reset and negative polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 1 - - | 0 +//- - 1 - - - | 1 +//- \ - - 0 d | d +//- - - - - - | q +//- +module \$_DFFSRE_NPPN_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(negedge C, posedge S, posedge R) begin + if (R == 1) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_NPPP_ (C, S, R, E, D, Q) +//- +//- A negative edge D-type flip-flop with positive polarity set, positive +//- polarity reset and positive polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 1 - - | 0 +//- - 1 - - - | 1 +//- \ - - 1 d | d +//- - - - - - | q +//- +module \$_DFFSRE_NPPP_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(negedge C, posedge S, posedge R) begin + if (R == 1) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_PNNN_ (C, S, R, E, D, Q) +//- +//- A positive edge D-type flip-flop with negative polarity set, negative +//- polarity reset and negative polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 0 - - | 0 +//- - 0 - - - | 1 +//- / - - 0 d | d +//- - - - - - | q +//- +module \$_DFFSRE_PNNN_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(posedge C, negedge S, negedge R) begin + if (R == 0) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_PNNP_ (C, S, R, E, D, Q) +//- +//- A positive edge D-type flip-flop with negative polarity set, negative +//- polarity reset and positive polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 0 - - | 0 +//- - 0 - - - | 1 +//- / - - 1 d | d +//- - - - - - | q +//- +module \$_DFFSRE_PNNP_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(posedge C, negedge S, negedge R) begin + if (R == 0) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_PNPN_ (C, S, R, E, D, Q) +//- +//- A positive edge D-type flip-flop with negative polarity set, positive +//- polarity reset and negative polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 1 - - | 0 +//- - 0 - - - | 1 +//- / - - 0 d | d +//- - - - - - | q +//- +module \$_DFFSRE_PNPN_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(posedge C, negedge S, posedge R) begin + if (R == 1) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_PNPP_ (C, S, R, E, D, Q) +//- +//- A positive edge D-type flip-flop with negative polarity set, positive +//- polarity reset and positive polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 1 - - | 0 +//- - 0 - - - | 1 +//- / - - 1 d | d +//- - - - - - | q +//- +module \$_DFFSRE_PNPP_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(posedge C, negedge S, posedge R) begin + if (R == 1) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_PPNN_ (C, S, R, E, D, Q) +//- +//- A positive edge D-type flip-flop with positive polarity set, negative +//- polarity reset and negative polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 0 - - | 0 +//- - 1 - - - | 1 +//- / - - 0 d | d +//- - - - - - | q +//- +module \$_DFFSRE_PPNN_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(posedge C, posedge S, negedge R) begin + if (R == 0) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_PPNP_ (C, S, R, E, D, Q) +//- +//- A positive edge D-type flip-flop with positive polarity set, negative +//- polarity reset and positive polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 0 - - | 0 +//- - 1 - - - | 1 +//- / - - 1 d | d +//- - - - - - | q +//- +module \$_DFFSRE_PPNP_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(posedge C, posedge S, negedge R) begin + if (R == 0) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_PPPN_ (C, S, R, E, D, Q) +//- +//- A positive edge D-type flip-flop with positive polarity set, positive +//- polarity reset and negative polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 1 - - | 0 +//- - 1 - - - | 1 +//- / - - 0 d | d +//- - - - - - | q +//- +module \$_DFFSRE_PPPN_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(posedge C, posedge S, posedge R) begin + if (R == 1) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSRE_PPPP_ (C, S, R, E, D, Q) +//- +//- A positive edge D-type flip-flop with positive polarity set, positive +//- polarity reset and positive polarity clock enable. +//- +//- Truth table: C S R E D | Q +//- -----------+--- +//- - - 1 - - | 0 +//- - 1 - - - | 1 +//- / - - 1 d | d +//- - - - - - | q +//- +module \$_DFFSRE_PPPP_ (C, S, R, E, D, Q); +input C, S, R, E, D; +output reg Q; +always @(posedge C, posedge S, posedge R) begin + if (R == 1) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFF_NN0_ (D, C, R, Q) +//- +//- A negative edge D-type flip-flop with negative polarity synchronous reset. +//- +//- Truth table: D C R | Q +//- -------+--- +//- - \ 0 | 0 +//- d \ - | d +//- - - - | q +//- +module \$_SDFF_NN0_ (D, C, R, Q); +input D, C, R; +output reg Q; +always @(negedge C) begin + if (R == 0) + Q <= 0; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFF_NN1_ (D, C, R, Q) +//- +//- A negative edge D-type flip-flop with negative polarity synchronous set. +//- +//- Truth table: D C R | Q +//- -------+--- +//- - \ 0 | 1 +//- d \ - | d +//- - - - | q +//- +module \$_SDFF_NN1_ (D, C, R, Q); +input D, C, R; +output reg Q; +always @(negedge C) begin + if (R == 0) + Q <= 1; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFF_NP0_ (D, C, R, Q) +//- +//- A negative edge D-type flip-flop with positive polarity synchronous reset. +//- +//- Truth table: D C R | Q +//- -------+--- +//- - \ 1 | 0 +//- d \ - | d +//- - - - | q +//- +module \$_SDFF_NP0_ (D, C, R, Q); +input D, C, R; +output reg Q; +always @(negedge C) begin + if (R == 1) + Q <= 0; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFF_NP1_ (D, C, R, Q) +//- +//- A negative edge D-type flip-flop with positive polarity synchronous set. +//- +//- Truth table: D C R | Q +//- -------+--- +//- - \ 1 | 1 +//- d \ - | d +//- - - - | q +//- +module \$_SDFF_NP1_ (D, C, R, Q); +input D, C, R; +output reg Q; +always @(negedge C) begin + if (R == 1) + Q <= 1; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFF_PN0_ (D, C, R, Q) +//- +//- A positive edge D-type flip-flop with negative polarity synchronous reset. +//- +//- Truth table: D C R | Q +//- -------+--- +//- - / 0 | 0 +//- d / - | d +//- - - - | q +//- +module \$_SDFF_PN0_ (D, C, R, Q); +input D, C, R; +output reg Q; +always @(posedge C) begin + if (R == 0) + Q <= 0; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFF_PN1_ (D, C, R, Q) +//- +//- A positive edge D-type flip-flop with negative polarity synchronous set. +//- +//- Truth table: D C R | Q +//- -------+--- +//- - / 0 | 1 +//- d / - | d +//- - - - | q +//- +module \$_SDFF_PN1_ (D, C, R, Q); +input D, C, R; +output reg Q; +always @(posedge C) begin + if (R == 0) + Q <= 1; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFF_PP0_ (D, C, R, Q) +//- +//- A positive edge D-type flip-flop with positive polarity synchronous reset. +//- +//- Truth table: D C R | Q +//- -------+--- +//- - / 1 | 0 +//- d / - | d +//- - - - | q +//- +module \$_SDFF_PP0_ (D, C, R, Q); +input D, C, R; +output reg Q; +always @(posedge C) begin + if (R == 1) + Q <= 0; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFF_PP1_ (D, C, R, Q) +//- +//- A positive edge D-type flip-flop with positive polarity synchronous set. +//- +//- Truth table: D C R | Q +//- -------+--- +//- - / 1 | 1 +//- d / - | d +//- - - - | q +//- +module \$_SDFF_PP1_ (D, C, R, Q); +input D, C, R; +output reg Q; +always @(posedge C) begin + if (R == 1) + Q <= 1; + else + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_NN0N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity synchronous reset and negative +//- polarity clock enable (with reset having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 0 - | 0 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_SDFFE_NN0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (R == 0) + Q <= 0; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_NN0P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity synchronous reset and positive +//- polarity clock enable (with reset having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 0 - | 0 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_SDFFE_NN0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (R == 0) + Q <= 0; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_NN1N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity synchronous set and negative +//- polarity clock enable (with set having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 0 - | 1 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_SDFFE_NN1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (R == 0) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_NN1P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity synchronous set and positive +//- polarity clock enable (with set having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 0 - | 1 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_SDFFE_NN1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (R == 0) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_NP0N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity synchronous reset and negative +//- polarity clock enable (with reset having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 1 - | 0 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_SDFFE_NP0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (R == 1) + Q <= 0; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_NP0P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity synchronous reset and positive +//- polarity clock enable (with reset having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 1 - | 0 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_SDFFE_NP0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (R == 1) + Q <= 0; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_NP1N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity synchronous set and negative +//- polarity clock enable (with set having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 1 - | 1 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_SDFFE_NP1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (R == 1) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_NP1P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity synchronous set and positive +//- polarity clock enable (with set having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 1 - | 1 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_SDFFE_NP1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (R == 1) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_PN0N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity synchronous reset and negative +//- polarity clock enable (with reset having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 0 - | 0 +//- d / - 0 | d +//- - - - - | q +//- +module \$_SDFFE_PN0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (R == 0) + Q <= 0; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_PN0P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity synchronous reset and positive +//- polarity clock enable (with reset having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 0 - | 0 +//- d / - 1 | d +//- - - - - | q +//- +module \$_SDFFE_PN0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (R == 0) + Q <= 0; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_PN1N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity synchronous set and negative +//- polarity clock enable (with set having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 0 - | 1 +//- d / - 0 | d +//- - - - - | q +//- +module \$_SDFFE_PN1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (R == 0) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_PN1P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity synchronous set and positive +//- polarity clock enable (with set having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 0 - | 1 +//- d / - 1 | d +//- - - - - | q +//- +module \$_SDFFE_PN1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (R == 0) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_PP0N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity synchronous reset and negative +//- polarity clock enable (with reset having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 1 - | 0 +//- d / - 0 | d +//- - - - - | q +//- +module \$_SDFFE_PP0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (R == 1) + Q <= 0; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_PP0P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity synchronous reset and positive +//- polarity clock enable (with reset having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 1 - | 0 +//- d / - 1 | d +//- - - - - | q +//- +module \$_SDFFE_PP0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (R == 1) + Q <= 0; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_PP1N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity synchronous set and negative +//- polarity clock enable (with set having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 1 - | 1 +//- d / - 0 | d +//- - - - - | q +//- +module \$_SDFFE_PP1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (R == 1) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFE_PP1P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity synchronous set and positive +//- polarity clock enable (with set having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 1 - | 1 +//- d / - 1 | d +//- - - - - | q +//- +module \$_SDFFE_PP1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (R == 1) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_NN0N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity synchronous reset and negative +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 0 0 | 0 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_SDFFCE_NN0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (E == 0) begin + if (R == 0) + Q <= 0; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_NN0P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity synchronous reset and positive +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 0 1 | 0 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_SDFFCE_NN0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (E == 1) begin + if (R == 0) + Q <= 0; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_NN1N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity synchronous set and negative +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 0 0 | 1 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_SDFFCE_NN1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (E == 0) begin + if (R == 0) + Q <= 1; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_NN1P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with negative polarity synchronous set and positive +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 0 1 | 1 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_SDFFCE_NN1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (E == 1) begin + if (R == 0) + Q <= 1; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_NP0N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity synchronous reset and negative +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 1 0 | 0 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_SDFFCE_NP0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (E == 0) begin + if (R == 1) + Q <= 0; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_NP0P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity synchronous reset and positive +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 1 1 | 0 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_SDFFCE_NP0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (E == 1) begin + if (R == 1) + Q <= 0; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_NP1N_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity synchronous set and negative +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 1 0 | 1 +//- d \ - 0 | d +//- - - - - | q +//- +module \$_SDFFCE_NP1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (E == 0) begin + if (R == 1) + Q <= 1; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_NP1P_ (D, C, R, E, Q) +//- +//- A negative edge D-type flip-flop with positive polarity synchronous set and positive +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - \ 1 1 | 1 +//- d \ - 1 | d +//- - - - - | q +//- +module \$_SDFFCE_NP1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(negedge C) begin + if (E == 1) begin + if (R == 1) + Q <= 1; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_PN0N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity synchronous reset and negative +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 0 0 | 0 +//- d / - 0 | d +//- - - - - | q +//- +module \$_SDFFCE_PN0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (E == 0) begin + if (R == 0) + Q <= 0; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_PN0P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity synchronous reset and positive +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 0 1 | 0 +//- d / - 1 | d +//- - - - - | q +//- +module \$_SDFFCE_PN0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (E == 1) begin + if (R == 0) + Q <= 0; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_PN1N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity synchronous set and negative +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 0 0 | 1 +//- d / - 0 | d +//- - - - - | q +//- +module \$_SDFFCE_PN1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (E == 0) begin + if (R == 0) + Q <= 1; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_PN1P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with negative polarity synchronous set and positive +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 0 1 | 1 +//- d / - 1 | d +//- - - - - | q +//- +module \$_SDFFCE_PN1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (E == 1) begin + if (R == 0) + Q <= 1; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_PP0N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity synchronous reset and negative +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 1 0 | 0 +//- d / - 0 | d +//- - - - - | q +//- +module \$_SDFFCE_PP0N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (E == 0) begin + if (R == 1) + Q <= 0; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_PP0P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity synchronous reset and positive +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 1 1 | 0 +//- d / - 1 | d +//- - - - - | q +//- +module \$_SDFFCE_PP0P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (E == 1) begin + if (R == 1) + Q <= 0; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_PP1N_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity synchronous set and negative +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 1 0 | 1 +//- d / - 0 | d +//- - - - - | q +//- +module \$_SDFFCE_PP1N_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (E == 0) begin + if (R == 1) + Q <= 1; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_SDFFCE_PP1P_ (D, C, R, E, Q) +//- +//- A positive edge D-type flip-flop with positive polarity synchronous set and positive +//- polarity clock enable (with clock enable having priority). +//- +//- Truth table: D C R E | Q +//- ---------+--- +//- - / 1 1 | 1 +//- d / - 1 | d +//- - - - - | q +//- +module \$_SDFFCE_PP1P_ (D, C, R, E, Q); +input D, C, R, E; +output reg Q; +always @(posedge C) begin + if (E == 1) begin + if (R == 1) + Q <= 1; + else + Q <= D; + end +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- //- $_DLATCH_N_ (E, D, Q) //- //- A negative enable D-type latch. @@ -1126,6 +2926,190 @@ endmodule // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- +//- $_DLATCH_NN0_ (E, R, D, Q) +//- +//- A negative enable D-type latch with negative polarity reset. +//- +//- Truth table: E R D | Q +//- -------+--- +//- - 0 - | 0 +//- 0 - d | d +//- - - - | q +//- +module \$_DLATCH_NN0_ (E, R, D, Q); +input E, R, D; +output reg Q; +always @* begin + if (R == 0) + Q <= 0; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCH_NN1_ (E, R, D, Q) +//- +//- A negative enable D-type latch with negative polarity set. +//- +//- Truth table: E R D | Q +//- -------+--- +//- - 0 - | 1 +//- 0 - d | d +//- - - - | q +//- +module \$_DLATCH_NN1_ (E, R, D, Q); +input E, R, D; +output reg Q; +always @* begin + if (R == 0) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCH_NP0_ (E, R, D, Q) +//- +//- A negative enable D-type latch with positive polarity reset. +//- +//- Truth table: E R D | Q +//- -------+--- +//- - 1 - | 0 +//- 0 - d | d +//- - - - | q +//- +module \$_DLATCH_NP0_ (E, R, D, Q); +input E, R, D; +output reg Q; +always @* begin + if (R == 1) + Q <= 0; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCH_NP1_ (E, R, D, Q) +//- +//- A negative enable D-type latch with positive polarity set. +//- +//- Truth table: E R D | Q +//- -------+--- +//- - 1 - | 1 +//- 0 - d | d +//- - - - | q +//- +module \$_DLATCH_NP1_ (E, R, D, Q); +input E, R, D; +output reg Q; +always @* begin + if (R == 1) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCH_PN0_ (E, R, D, Q) +//- +//- A positive enable D-type latch with negative polarity reset. +//- +//- Truth table: E R D | Q +//- -------+--- +//- - 0 - | 0 +//- 1 - d | d +//- - - - | q +//- +module \$_DLATCH_PN0_ (E, R, D, Q); +input E, R, D; +output reg Q; +always @* begin + if (R == 0) + Q <= 0; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCH_PN1_ (E, R, D, Q) +//- +//- A positive enable D-type latch with negative polarity set. +//- +//- Truth table: E R D | Q +//- -------+--- +//- - 0 - | 1 +//- 1 - d | d +//- - - - | q +//- +module \$_DLATCH_PN1_ (E, R, D, Q); +input E, R, D; +output reg Q; +always @* begin + if (R == 0) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCH_PP0_ (E, R, D, Q) +//- +//- A positive enable D-type latch with positive polarity reset. +//- +//- Truth table: E R D | Q +//- -------+--- +//- - 1 - | 0 +//- 1 - d | d +//- - - - | q +//- +module \$_DLATCH_PP0_ (E, R, D, Q); +input E, R, D; +output reg Q; +always @* begin + if (R == 1) + Q <= 0; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCH_PP1_ (E, R, D, Q) +//- +//- A positive enable D-type latch with positive polarity set. +//- +//- Truth table: E R D | Q +//- -------+--- +//- - 1 - | 1 +//- 1 - d | d +//- - - - | q +//- +module \$_DLATCH_PP1_ (E, R, D, Q); +input E, R, D; +output reg Q; +always @* begin + if (R == 1) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- //- $_DLATCHSR_NNN_ (E, S, R, D, Q) //- //- A negative enable D-type latch with negative polarity set and negative diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 125b8e013..e94884025 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -480,10 +480,18 @@ input [B_WIDTH-1:0] B; output [Y_WIDTH-1:0] Y; generate - if (B_SIGNED) begin:BLOCK1 - assign Y = $signed(B) < 0 ? A << -B : A >> B; - end else begin:BLOCK2 - assign Y = A >> B; + if (A_SIGNED) begin:BLOCK1 + if (B_SIGNED) begin:BLOCK2 + assign Y = $signed(B) < 0 ? $signed(A) << -B : $signed(A) >> B; + end else begin:BLOCK3 + assign Y = $signed(A) >> B; + end + end else begin:BLOCK4 + if (B_SIGNED) begin:BLOCK5 + assign Y = $signed(B) < 0 ? A << -B : A >> B; + end else begin:BLOCK6 + assign Y = A >> B; + end end endgenerate @@ -1822,6 +1830,39 @@ endgenerate endmodule +// -------------------------------------------------------- + +module \$dffsre (CLK, SET, CLR, EN, D, Q); + +parameter WIDTH = 0; +parameter CLK_POLARITY = 1'b1; +parameter SET_POLARITY = 1'b1; +parameter CLR_POLARITY = 1'b1; +parameter EN_POLARITY = 1'b1; + +input CLK, EN; +input [WIDTH-1:0] SET, CLR, D; +output reg [WIDTH-1:0] Q; + +wire pos_clk = CLK == CLK_POLARITY; +wire [WIDTH-1:0] pos_set = SET_POLARITY ? SET : ~SET; +wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR; + +genvar i; +generate + for (i = 0; i < WIDTH; i = i+1) begin:bitslices + always @(posedge pos_set[i], posedge pos_clr[i], posedge pos_clk) + if (pos_clr[i]) + Q[i] <= 0; + else if (pos_set[i]) + Q[i] <= 1; + else if (EN == EN_POLARITY) + Q[i] <= D[i]; + end +endgenerate + +endmodule + `endif // -------------------------------------------------------- @@ -1849,6 +1890,107 @@ endmodule // -------------------------------------------------------- +module \$sdff (CLK, SRST, D, Q); + +parameter WIDTH = 0; +parameter CLK_POLARITY = 1'b1; +parameter SRST_POLARITY = 1'b1; +parameter SRST_VALUE = 0; + +input CLK, SRST; +input [WIDTH-1:0] D; +output reg [WIDTH-1:0] Q; +wire pos_clk = CLK == CLK_POLARITY; +wire pos_srst = SRST == SRST_POLARITY; + +always @(posedge pos_clk) begin + if (pos_srst) + Q <= SRST_VALUE; + else + Q <= D; +end + +endmodule + +// -------------------------------------------------------- + +module \$adffe (CLK, ARST, EN, D, Q); + +parameter WIDTH = 0; +parameter CLK_POLARITY = 1'b1; +parameter EN_POLARITY = 1'b1; +parameter ARST_POLARITY = 1'b1; +parameter ARST_VALUE = 0; + +input CLK, ARST, EN; +input [WIDTH-1:0] D; +output reg [WIDTH-1:0] Q; +wire pos_clk = CLK == CLK_POLARITY; +wire pos_arst = ARST == ARST_POLARITY; + +always @(posedge pos_clk, posedge pos_arst) begin + if (pos_arst) + Q <= ARST_VALUE; + else if (EN == EN_POLARITY) + Q <= D; +end + +endmodule + +// -------------------------------------------------------- + +module \$sdffe (CLK, SRST, EN, D, Q); + +parameter WIDTH = 0; +parameter CLK_POLARITY = 1'b1; +parameter EN_POLARITY = 1'b1; +parameter SRST_POLARITY = 1'b1; +parameter SRST_VALUE = 0; + +input CLK, SRST, EN; +input [WIDTH-1:0] D; +output reg [WIDTH-1:0] Q; +wire pos_clk = CLK == CLK_POLARITY; +wire pos_srst = SRST == SRST_POLARITY; + +always @(posedge pos_clk) begin + if (pos_srst) + Q <= SRST_VALUE; + else if (EN == EN_POLARITY) + Q <= D; +end + +endmodule + +// -------------------------------------------------------- + +module \$sdffce (CLK, SRST, EN, D, Q); + +parameter WIDTH = 0; +parameter CLK_POLARITY = 1'b1; +parameter EN_POLARITY = 1'b1; +parameter SRST_POLARITY = 1'b1; +parameter SRST_VALUE = 0; + +input CLK, SRST, EN; +input [WIDTH-1:0] D; +output reg [WIDTH-1:0] Q; +wire pos_clk = CLK == CLK_POLARITY; +wire pos_srst = SRST == SRST_POLARITY; + +always @(posedge pos_clk) begin + if (EN == EN_POLARITY) begin + if (pos_srst) + Q <= SRST_VALUE; + else + Q <= D; + end +end + +endmodule + +// -------------------------------------------------------- + module \$dlatch (EN, D, Q); parameter WIDTH = 0; @@ -1866,6 +2008,28 @@ end endmodule // -------------------------------------------------------- + +module \$adlatch (EN, ARST, D, Q); + +parameter WIDTH = 0; +parameter EN_POLARITY = 1'b1; +parameter ARST_POLARITY = 1'b1; +parameter ARST_VALUE = 0; + +input EN, ARST; +input [WIDTH-1:0] D; +output reg [WIDTH-1:0] Q; + +always @* begin + if (ARST == ARST_POLARITY) + Q = ARST_VALUE; + else if (EN == EN_POLARITY) + Q = D; +end + +endmodule + +// -------------------------------------------------------- `ifndef SIMLIB_NOSR module \$dlatchsr (EN, SET, CLR, D, Q); diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index d6dffdd7f..89d6e530e 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -29,7 +29,7 @@ struct SynthPass : public ScriptPass { SynthPass() : ScriptPass("synth", "generic synthesis script") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -91,7 +91,7 @@ struct SynthPass : public ScriptPass bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap; int lut; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_module.clear(); fsm_opts.clear(); @@ -108,7 +108,7 @@ struct SynthPass : public ScriptPass abc = "abc"; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -195,7 +195,7 @@ struct SynthPass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("begin")) { @@ -220,6 +220,9 @@ struct SynthPass : public ScriptPass run("opt_expr"); run("opt_clean"); run("check"); + run("opt -nodffe -nosdff"); + if (!nofsm) + run("fsm" + fsm_opts, " (unless -nofsm)"); run("opt"); run("wreduce"); run("peepopt"); @@ -233,9 +236,6 @@ struct SynthPass : public ScriptPass if (!noshare) run("share", " (unless -noshare)"); run("opt"); - if (!nofsm) - run("fsm" + fsm_opts, " (unless -nofsm)"); - run("opt -fast"); run("memory -nomap" + memory_opts); run("opt_clean"); } diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index eafe8d4da..2ab28e6e6 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -64,7 +64,7 @@ module _90_simplemap_various; endmodule (* techmap_simplemap *) -(* techmap_celltype = "$sr $ff $dff $dffe $adff $dffsr $dlatch" *) +(* techmap_celltype = "$sr $ff $dff $dffe $adff $adffe $sdff $sdffe $sdffce $dffsr $dffsre $dlatch $adlatch $dlatchsr" *) module _90_simplemap_registers; endmodule @@ -141,78 +141,48 @@ module _90_shift_shiftx (A, B, Y); parameter [B_WIDTH-1:0] _TECHMAP_CONSTVAL_B_ = 0; localparam extbit = _TECHMAP_CELLTYPE_ == "$shift" ? 1'b0 : 1'bx; + wire a_padding = _TECHMAP_CELLTYPE_ == "$shiftx" ? extbit : (A_SIGNED ? A[A_WIDTH-1] : 1'b0); - generate -`ifndef NO_LSB_FIRST_SHIFT_SHIFTX - // If $shift/$shiftx only shifts in units of Y_WIDTH - // (a common pattern created by pmux2shiftx) - // which is checked by ensuring that all that - // the appropriate LSBs of B are constant zero, - // then we can decompose LSB first instead of - // MSB first - localparam CLOG2_Y_WIDTH = $clog2(Y_WIDTH); - if (B_WIDTH > CLOG2_Y_WIDTH+1 && - _TECHMAP_CONSTMSK_B_[CLOG2_Y_WIDTH-1:0] == {CLOG2_Y_WIDTH{1'b1}} && - _TECHMAP_CONSTVAL_B_[CLOG2_Y_WIDTH-1:0] == {CLOG2_Y_WIDTH{1'b0}}) begin - // Halve the size of $shift/$shiftx by $mux-ing A according to - // the LSB of B, after discarding the zeroed bits - localparam Y_WIDTH2 = 2**CLOG2_Y_WIDTH; - localparam entries = (A_WIDTH+Y_WIDTH-1)/Y_WIDTH2; - localparam len = Y_WIDTH2 * ((entries+1)/2); - wire [len-1:0] AA; - wire [(A_WIDTH+Y_WIDTH2+Y_WIDTH-1)-1:0] Apad = {{(Y_WIDTH2+Y_WIDTH-1){extbit}}, A}; - genvar i; - for (i = 0; i < A_WIDTH; i=i+Y_WIDTH2*2) - assign AA[i/2 +: Y_WIDTH2] = B[CLOG2_Y_WIDTH] ? Apad[i+Y_WIDTH2 +: Y_WIDTH2] : Apad[i +: Y_WIDTH2]; - wire [B_WIDTH-2:0] BB = {B[B_WIDTH-1:CLOG2_Y_WIDTH+1], {CLOG2_Y_WIDTH{1'b0}}}; - if (_TECHMAP_CELLTYPE_ == "$shift") - $shift #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(len), .B_WIDTH(B_WIDTH-1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(AA), .B(BB), .Y(Y)); - else - $shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(len), .B_WIDTH(B_WIDTH-1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(AA), .B(BB), .Y(Y)); - end - else -`endif - begin - localparam BB_WIDTH = `MIN($clog2(`MAX(A_WIDTH, Y_WIDTH)) + (B_SIGNED ? 2 : 1), B_WIDTH); - localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH) + (B_SIGNED ? 2**(BB_WIDTH-1) : 0); + localparam BB_WIDTH = `MIN($clog2(`MAX(A_WIDTH, Y_WIDTH)) + (B_SIGNED ? 2 : 1), B_WIDTH); + localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH) + (B_SIGNED ? 2**(BB_WIDTH-1) : 0); - wire [1023:0] _TECHMAP_DO_00_ = "proc;;"; - wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_expr -mux_undef -mux_bool -fine;;;"; + wire [1023:0] _TECHMAP_DO_00_ = "proc;;"; + wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_expr -mux_undef -mux_bool -fine;;;"; - integer i; - (* force_downto *) - reg [WIDTH-1:0] buffer; - reg overflow; + integer i; + (* force_downto *) + reg [WIDTH-1:0] buffer; + reg overflow; - always @* begin - overflow = 0; + always @* begin + overflow = 0; + buffer = {WIDTH{extbit}}; + buffer[Y_WIDTH-1:0] = {Y_WIDTH{a_padding}}; + buffer[A_WIDTH-1:0] = A; + + if (B_WIDTH > BB_WIDTH) begin + if (B_SIGNED) begin + for (i = BB_WIDTH; i < B_WIDTH; i = i+1) + if (B[i] != B[BB_WIDTH-1]) + overflow = 1; + end else + overflow = |B[B_WIDTH-1:BB_WIDTH]; + if (overflow) buffer = {WIDTH{extbit}}; - buffer[`MAX(A_WIDTH, Y_WIDTH)-1:0] = A; - - if (B_WIDTH > BB_WIDTH) begin - if (B_SIGNED) begin - for (i = BB_WIDTH; i < B_WIDTH; i = i+1) - if (B[i] != B[BB_WIDTH-1]) - overflow = 1; - end else - overflow = |B[B_WIDTH-1:BB_WIDTH]; - if (overflow) - buffer = {WIDTH{extbit}}; - end - - for (i = BB_WIDTH-1; i >= 0; i = i-1) - if (B[i]) begin - if (B_SIGNED && i == BB_WIDTH-1) - buffer = {buffer, {2**i{extbit}}}; - else if (2**i < WIDTH) - buffer = {{2**i{extbit}}, buffer[WIDTH-1 : 2**i]}; - else - buffer = {WIDTH{extbit}}; - end - end - assign Y = buffer; end - endgenerate + + if (B_SIGNED && B[BB_WIDTH-1]) + buffer = {buffer, {2**(BB_WIDTH-1){extbit}}}; + + for (i = 0; i < (B_SIGNED ? BB_WIDTH-1 : BB_WIDTH); i = i+1) + if (B[i]) begin + if (2**i < WIDTH) + buffer = {{2**i{extbit}}, buffer[WIDTH-1 : 2**i]}; + else + buffer = {WIDTH{extbit}}; + end + end + assign Y = buffer; endmodule diff --git a/techlibs/coolrunner2/coolrunner2_fixup.cc b/techlibs/coolrunner2/coolrunner2_fixup.cc index 8bbff9ba5..50710e2bd 100644 --- a/techlibs/coolrunner2/coolrunner2_fixup.cc +++ b/techlibs/coolrunner2/coolrunner2_fixup.cc @@ -112,7 +112,7 @@ RTLIL::Wire *makeptermbuffer(RTLIL::Module *module, SigBit inwire) struct Coolrunner2FixupPass : public Pass { Coolrunner2FixupPass() : Pass("coolrunner2_fixup", "insert necessary buffer cells for CoolRunner-II architecture") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" coolrunner2_fixup [options] [selection]\n"); @@ -120,7 +120,7 @@ struct Coolrunner2FixupPass : public Pass { log("Insert necessary buffer cells for CoolRunner-II architecture.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing COOLRUNNER2_FIXUP pass (insert necessary buffer cells for CoolRunner-II architecture).\n"); extra_args(args, 1, design); diff --git a/techlibs/coolrunner2/coolrunner2_sop.cc b/techlibs/coolrunner2/coolrunner2_sop.cc index 045c73978..17e0d8432 100644 --- a/techlibs/coolrunner2/coolrunner2_sop.cc +++ b/techlibs/coolrunner2/coolrunner2_sop.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct Coolrunner2SopPass : public Pass { Coolrunner2SopPass() : Pass("coolrunner2_sop", "break $sop cells into ANDTERM/ORTERM cells") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" coolrunner2_sop [options] [selection]\n"); @@ -33,7 +33,7 @@ struct Coolrunner2SopPass : public Pass { log("Break $sop cells into ANDTERM/ORTERM cells.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing COOLRUNNER2_SOP pass (break $sop cells into ANDTERM/ORTERM cells).\n"); extra_args(args, 1, design); diff --git a/techlibs/coolrunner2/synth_coolrunner2.cc b/techlibs/coolrunner2/synth_coolrunner2.cc index d5eeaf547..47102fbb1 100644 --- a/techlibs/coolrunner2/synth_coolrunner2.cc +++ b/techlibs/coolrunner2/synth_coolrunner2.cc @@ -29,7 +29,7 @@ struct SynthCoolrunner2Pass : public ScriptPass { SynthCoolrunner2Pass() : ScriptPass("synth_coolrunner2", "synthesis for Xilinx Coolrunner-II CPLDs") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -66,7 +66,7 @@ struct SynthCoolrunner2Pass : public ScriptPass string top_opt, json_file; bool flatten, retime; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; json_file = ""; @@ -74,7 +74,7 @@ struct SynthCoolrunner2Pass : public ScriptPass retime = false; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -121,7 +121,7 @@ struct SynthCoolrunner2Pass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("begin")) { diff --git a/techlibs/easic/synth_easic.cc b/techlibs/easic/synth_easic.cc index b4a3a1ac9..897bc1c40 100644 --- a/techlibs/easic/synth_easic.cc +++ b/techlibs/easic/synth_easic.cc @@ -29,7 +29,7 @@ struct SynthEasicPass : public ScriptPass { SynthEasicPass() : ScriptPass("synth_easic", "synthesis for eASIC platform") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -67,7 +67,7 @@ struct SynthEasicPass : public ScriptPass string top_opt, vlog_file, etools_path; bool flatten, retime; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; vlog_file = ""; @@ -76,7 +76,7 @@ struct SynthEasicPass : public ScriptPass retime = false; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -127,7 +127,7 @@ struct SynthEasicPass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { string phys_clk_lib = stringf("%s/data_ruby28/design_libs/logical/timing/gp/n3x_phys_clk_0v893ff125c.lib", etools_path.c_str()); string logic_lut_lib = stringf("%s/data_ruby28/design_libs/logical/timing/gp/n3x_logic_lut_0v893ff125c.lib", etools_path.c_str()); diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc index 9d564c78c..4c1bc23b5 100644 --- a/techlibs/ecp5/Makefile.inc +++ b/techlibs/ecp5/Makefile.inc @@ -1,6 +1,5 @@ -OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o \ - techlibs/ecp5/ecp5_gsr.o +OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_gsr.o GENFILES += techlibs/ecp5/bram_init_1_2_4.vh GENFILES += techlibs/ecp5/bram_init_9_18_36.vh diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v index e19ac9ab9..dc83d96dc 100644 --- a/techlibs/ecp5/cells_map.v +++ b/techlibs/ecp5/cells_map.v @@ -1,64 +1,99 @@ -module \$_DFF_N_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule -module \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule - -module \$_DFFE_NN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule -module \$_DFFE_PN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule - -module \$_DFFE_NP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule -module \$_DFFE_PP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule - -module \$_DFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$_DFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$_DFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule - -module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule - -module \$__DFFS_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule - -module \$__DFFS_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule - -module \$__DFFE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule - -module \$__DFFE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule - -module \$__DFFSE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule - -module \$__DFFSE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$_DFF_N_ (input D, C, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFF_P_ (input D, C, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_NN_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_PN_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_NP_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_PP_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_DFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_DFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule `ifdef ASYNC_PRLD module \$_DLATCH_N_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(!E), .DI(1'b0), .M(D), .Q(Q)); endmodule module \$_DLATCH_P_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(E), .DI(1'b0), .M(D), .Q(Q)); endmodule -module \$_DFFSR_NNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule -module \$_DFFSR_NNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule -module \$_DFFSR_NPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule module \$_DFFSR_NPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule -module \$_DFFSR_PNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule -module \$_DFFSR_PNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule -module \$_DFFSR_PPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule module \$_DFFSR_PPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule `endif diff --git a/techlibs/ecp5/ecp5_ffinit.cc b/techlibs/ecp5/ecp5_ffinit.cc deleted file mode 100644 index ba72bd0c6..000000000 --- a/techlibs/ecp5/ecp5_ffinit.cc +++ /dev/null @@ -1,197 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * Copyright (C) 2018-19 David Shah <david@symbioticeda.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 Ecp5FfinitPass : public Pass { - Ecp5FfinitPass() : Pass("ecp5_ffinit", "ECP5: handle FF init values") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" ecp5_ffinit [options] [selection]\n"); - log("\n"); - log("Remove init values for FF output signals when equal to reset value.\n"); - log("If reset is not used, set the reset value to the init value, otherwise\n"); - log("unmap out the reset (if not an async reset).\n"); - } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing ECP5_FFINIT pass (implement FF init values).\n"); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - // if (args[argidx] == "-singleton") { - // singleton_mode = true; - // continue; - // } - break; - } - extra_args(args, argidx, design); - - for (auto module : design->selected_modules()) - { - log("Handling FF init values in %s.\n", log_id(module)); - - SigMap sigmap(module); - pool<Wire*> init_wires; - dict<SigBit, State> initbits; - dict<SigBit, SigBit> initbit_to_wire; - pool<SigBit> handled_initbits; - - for (auto wire : module->selected_wires()) - { - if (wire->attributes.count(ID::init) == 0) - continue; - - SigSpec wirebits = sigmap(wire); - Const initval = wire->attributes.at(ID::init); - init_wires.insert(wire); - - for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) - { - SigBit bit = wirebits[i]; - State val = initval[i]; - - if (val != State::S0 && val != State::S1) - continue; - - if (initbits.count(bit)) { - if (initbits.at(bit) != val) { - log_warning("Conflicting init values for signal %s (%s = %s, %s = %s).\n", - log_signal(bit), log_signal(SigBit(wire, i)), log_signal(val), - log_signal(initbit_to_wire[bit]), log_signal(initbits.at(bit))); - initbits.at(bit) = State::Sx; - } - continue; - } - - initbits[bit] = val; - initbit_to_wire[bit] = SigBit(wire, i); - } - } - for (auto cell : module->selected_cells()) - { - if (cell->type != ID(TRELLIS_FF)) - continue; - SigSpec sig_d = cell->getPort(ID(DI)); - SigSpec sig_q = cell->getPort(ID::Q); - SigSpec sig_lsr = cell->getPort(ID(LSR)); - - if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1) - continue; - - SigBit bit_d = sigmap(sig_d[0]); - SigBit bit_q = sigmap(sig_q[0]); - - std::string regset = cell->getParam(ID(REGSET)).decode_string(); - State resetState; - if (regset == "SET") - resetState = State::S1; - else if (regset == "RESET") - resetState = State::S0; - else - log_error("FF cell %s has illegal REGSET value %s.\n", - log_id(cell), regset.c_str()); - - if (!initbits.count(bit_q)) - continue; - - State val = initbits.at(bit_q); - - if (val == State::Sx) - continue; - - log("FF init value for cell %s (%s): %s = %c\n", log_id(cell), log_id(cell->type), - log_signal(bit_q), val != State::S0 ? '1' : '0'); - // Initval is the same as the reset state. Matches hardware, nowt more to do - if (val == resetState) { - handled_initbits.insert(bit_q); - continue; - } - - if (GetSize(sig_lsr) >= 1 && sig_lsr[0] != State::S0) { - std::string srmode = cell->getParam(ID(SRMODE)).decode_string(); - if (srmode == "ASYNC") { - log("Async reset value %c for FF cell %s inconsistent with init value %c.\n", - resetState != State::S0 ? '1' : '0', log_id(cell), val != State::S0 ? '1' : '0'); - } else { - SigBit bit_lsr = sigmap(sig_lsr[0]); - Wire *new_bit_d = module->addWire(NEW_ID); - if (resetState == State::S0) { - module->addAndnotGate(NEW_ID, bit_d, bit_lsr, new_bit_d); - } else { - module->addOrGate(NEW_ID, bit_d, bit_lsr, new_bit_d); - } - - cell->setPort(ID(DI), new_bit_d); - cell->setPort(ID(LSR), State::S0); - - if(cell->hasPort(ID(CE))) { - std::string cemux = cell->getParam(ID(CEMUX)).decode_string(); - SigSpec sig_ce = cell->getPort(ID(CE)); - if (GetSize(sig_ce) >= 1) { - SigBit bit_ce = sigmap(sig_ce[0]); - Wire *new_bit_ce = module->addWire(NEW_ID); - if (cemux == "INV") - module->addAndnotGate(NEW_ID, bit_ce, bit_lsr, new_bit_ce); - else - module->addOrGate(NEW_ID, bit_ce, bit_lsr, new_bit_ce); - cell->setPort(ID(CE), new_bit_ce); - } - } - cell->setParam(ID(REGSET), val != State::S0 ? Const("SET") : Const("RESET")); - handled_initbits.insert(bit_q); - } - } else { - cell->setParam(ID(REGSET), val != State::S0 ? Const("SET") : Const("RESET")); - handled_initbits.insert(bit_q); - } - } - - for (auto wire : init_wires) - { - if (wire->attributes.count(ID::init) == 0) - continue; - - SigSpec wirebits = sigmap(wire); - Const &initval = wire->attributes.at(ID::init); - bool remove_attribute = true; - - for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) { - if (handled_initbits.count(wirebits[i])) - initval[i] = State::Sx; - else if (initval[i] != State::Sx) - remove_attribute = false; - } - - if (remove_attribute) - wire->attributes.erase(ID::init); - } - } - } -} Ecp5FfinitPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/ecp5/ecp5_gsr.cc b/techlibs/ecp5/ecp5_gsr.cc index 3d3f8e1c1..18d99cfb2 100644 --- a/techlibs/ecp5/ecp5_gsr.cc +++ b/techlibs/ecp5/ecp5_gsr.cc @@ -26,7 +26,7 @@ PRIVATE_NAMESPACE_BEGIN struct Ecp5GsrPass : public Pass { Ecp5GsrPass() : Pass("ecp5_gsr", "ECP5: handle GSR") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -40,7 +40,7 @@ struct Ecp5GsrPass : public Pass { log("is not set, otherwise it will be resolved to \"DISABLED\".\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing ECP5_GSR pass (implement FF init values).\n"); diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index aceb36abc..3cee9722e 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -30,12 +30,12 @@ struct SynthEcp5Pass : public ScriptPass { SynthEcp5Pass() : ScriptPass("synth_ecp5", "synthesis for ECP5 FPGAs") { } - void on_register() YS_OVERRIDE + void on_register() override { RTLIL::constpad["synth_ecp5.abc9.W"] = "300"; } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -112,7 +112,7 @@ struct SynthEcp5Pass : public ScriptPass string top_opt, blif_file, edif_file, json_file; bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, nodsp, vpr; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; blif_file = ""; @@ -133,7 +133,7 @@ struct SynthEcp5Pass : public ScriptPass nodsp = false; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -239,7 +239,7 @@ struct SynthEcp5Pass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("begin")) { @@ -257,6 +257,8 @@ struct SynthEcp5Pass : public ScriptPass run("opt_expr"); run("opt_clean"); run("check"); + run("opt -nodffe -nosdff"); + run("fsm"); run("opt"); run("wreduce"); run("peepopt"); @@ -271,8 +273,6 @@ struct SynthEcp5Pass : public ScriptPass } run("alumacc"); run("opt"); - run("fsm"); - run("opt -fast"); run("memory -nomap"); run("opt_clean"); } @@ -311,16 +311,25 @@ struct SynthEcp5Pass : public ScriptPass if (check_label("map_ffs")) { - run("dff2dffs"); run("opt_clean"); - if (!nodffe) - run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); + std::string dfflegalize_args = " -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r"; + if (help_mode) { + dfflegalize_args += " [-cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r]"; + } else if (!nodffe) { + dfflegalize_args += " -cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r"; + } + dfflegalize_args += " -cell $_DLATCH_?_ x"; + if (help_mode) { + dfflegalize_args += " [-cell $_DFFSR_?PP_ x]"; + } else if (asyncprld) { + dfflegalize_args += " -cell $_DFFSR_?PP_ x"; + } + run("dfflegalize" + dfflegalize_args, "($_DFFSR_*_ only if -asyncprld, $_*DFFE_* only if not -nodffe)"); if ((abc9 && dff) || help_mode) - run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$__DFFS*", "(only if -abc9 and -dff"); + run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "(only if -abc9 and -dff"); run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : ""))); run("opt_expr -undriven -mux_undef"); run("simplemap"); - run("ecp5_ffinit"); run("ecp5_gsr"); run("attrmvcp -copy -attr syn_useioff"); run("opt_clean"); diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index 69665982c..2a3a953e3 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -1,10 +1,10 @@ OBJS += techlibs/efinix/synth_efinix.o -OBJS += techlibs/efinix/efinix_gbuf.o OBJS += techlibs/efinix/efinix_fixcarry.o $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/brams_map.v)) +$(eval $(call add_share_file,share/efinix,techlibs/efinix/gbuf_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/brams.txt)) diff --git a/techlibs/efinix/cells_map.v b/techlibs/efinix/cells_map.v index 1090f8b27..6f6271da2 100644 --- a/techlibs/efinix/cells_map.v +++ b/techlibs/efinix/cells_map.v @@ -1,21 +1,59 @@ -module \$_DFF_N_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule -module \$_DFF_P_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule +(* techmap_celltype = "$_DFFE_[PN][PN][01][PN]_" *) +module \$_DFFE_xxxx_ (input D, C, R, E, output Q); -module \$_DFFE_NN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule -module \$_DFFE_NP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule + parameter _TECHMAP_CELLTYPE_ = ""; -module \$_DFFE_PN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule -module \$_DFFE_PP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule + EFX_FF #( + .CLK_POLARITY(_TECHMAP_CELLTYPE_[39:32] == "P"), + .CE_POLARITY(_TECHMAP_CELLTYPE_[15:8] == "P"), + .SR_POLARITY(_TECHMAP_CELLTYPE_[31:24] == "P"), + .D_POLARITY(1'b1), + .SR_SYNC(1'b0), + .SR_VALUE(_TECHMAP_CELLTYPE_[23:16] == "1"), + .SR_SYNC_PRIORITY(1'b1) + ) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(R), .Q(Q)); -module \$_DFF_NN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_PN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_PN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -module \$_DFF_NP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +endmodule + +(* techmap_celltype = "$_SDFFE_[PN][PN][01][PN]_" *) +module \$_SDFFE_xxxx_ (input D, C, R, E, output Q); + + parameter _TECHMAP_CELLTYPE_ = ""; + + EFX_FF #( + .CLK_POLARITY(_TECHMAP_CELLTYPE_[39:32] == "P"), + .CE_POLARITY(_TECHMAP_CELLTYPE_[15:8] == "P"), + .SR_POLARITY(_TECHMAP_CELLTYPE_[31:24] == "P"), + .D_POLARITY(1'b1), + .SR_SYNC(1'b1), + .SR_VALUE(_TECHMAP_CELLTYPE_[23:16] == "1"), + .SR_SYNC_PRIORITY(1'b1) + ) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(R), .Q(Q)); + + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + +endmodule + +(* techmap_celltype = "$_SDFFCE_[PN][PN][01][PN]_" *) +module \$_SDFFCE_xxxx_ (input D, C, R, E, output Q); + + parameter _TECHMAP_CELLTYPE_ = ""; + + EFX_FF #( + .CLK_POLARITY(_TECHMAP_CELLTYPE_[39:32] == "P"), + .CE_POLARITY(_TECHMAP_CELLTYPE_[15:8] == "P"), + .SR_POLARITY(_TECHMAP_CELLTYPE_[31:24] == "P"), + .D_POLARITY(1'b1), + .SR_SYNC(1'b1), + .SR_VALUE(_TECHMAP_CELLTYPE_[23:16] == "1"), + .SR_SYNC_PRIORITY(1'b0) + ) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(R), .Q(Q)); + + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + +endmodule module \$_DLATCH_N_ (E, D, Q); wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; diff --git a/techlibs/efinix/cells_sim.v b/techlibs/efinix/cells_sim.v index a74d1c571..22c7bc776 100644 --- a/techlibs/efinix/cells_sim.v +++ b/techlibs/efinix/cells_sim.v @@ -36,6 +36,7 @@ module EFX_FF( output reg Q, input D, input CE, + (* clkbuf_sink *) input CLK, input SR ); @@ -100,6 +101,7 @@ endmodule module EFX_GBUFCE( input CE, input I, + (* clkbuf_driver *) output O ); parameter CE_POLARITY = 1'b1; @@ -115,11 +117,13 @@ module EFX_RAM_5K( input [WRITE_WIDTH-1:0] WDATA, input [WRITE_ADDR_WIDTH-1:0] WADDR, input WE, + (* clkbuf_sink *) input WCLK, input WCLKE, output [READ_WIDTH-1:0] RDATA, input [READ_ADDR_WIDTH-1:0] RADDR, input RE, + (* clkbuf_sink *) input RCLK ); parameter READ_WIDTH = 20; @@ -172,4 +176,4 @@ module EFX_RAM_5K( (WRITE_WIDTH == 10) ? 9 : // 512x10 (WRITE_WIDTH == 5) ? 10 : -1; // 1024x5 -endmodule
\ No newline at end of file +endmodule diff --git a/techlibs/efinix/efinix_fixcarry.cc b/techlibs/efinix/efinix_fixcarry.cc index 1a1733a17..486b8e89c 100644 --- a/techlibs/efinix/efinix_fixcarry.cc +++ b/techlibs/efinix/efinix_fixcarry.cc @@ -90,7 +90,7 @@ static void fix_carry_chain(Module *module) struct EfinixCarryFixPass : public Pass { EfinixCarryFixPass() : Pass("efinix_fixcarry", "Efinix: fix carry chain") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -99,7 +99,7 @@ struct EfinixCarryFixPass : public Pass { log("Add Efinix adders to fix carry chain if needed.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing EFINIX_FIXCARRY pass (fix invalid carry chain).\n"); diff --git a/techlibs/efinix/efinix_gbuf.cc b/techlibs/efinix/efinix_gbuf.cc deleted file mode 100644 index 55dfb3c79..000000000 --- a/techlibs/efinix/efinix_gbuf.cc +++ /dev/null @@ -1,119 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2019 Miodrag Milanovic <miodrag@symbioticeda.com> - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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 - -static void handle_gbufs(Module *module) -{ - SigMap sigmap(module); - - pool<SigBit> clk_bits; - dict<SigBit, SigBit> rewrite_bits; - vector<pair<Cell*, SigBit>> pad_bits; - - for (auto cell : module->cells()) - { - if (cell->type == ID(EFX_FF)) { - for (auto bit : sigmap(cell->getPort(ID::CLK))) - clk_bits.insert(bit); - } - if (cell->type == ID(EFX_RAM_5K)) { - for (auto bit : sigmap(cell->getPort(ID(RCLK)))) - clk_bits.insert(bit); - for (auto bit : sigmap(cell->getPort(ID(WCLK)))) - clk_bits.insert(bit); - } - } - - for (auto wire : vector<Wire*>(module->wires())) - { - if (!wire->port_input) - continue; - - for (int index = 0; index < GetSize(wire); index++) - { - SigBit bit(wire, index); - SigBit canonical_bit = sigmap(bit); - - if (!clk_bits.count(canonical_bit)) - continue; - - Cell *c = module->addCell(NEW_ID, ID(EFX_GBUFCE)); - SigBit new_bit = module->addWire(NEW_ID); - c->setParam(ID(CE_POLARITY), State::S1); - c->setPort(ID::O, new_bit); - c->setPort(ID(CE), State::S1); - pad_bits.push_back(make_pair(c, bit)); - rewrite_bits[canonical_bit] = new_bit; - - log("Added %s cell %s for port bit %s.\n", log_id(c->type), log_id(c), log_signal(bit)); - } - } - - auto rewrite_function = [&](SigSpec &s) { - for (auto &bit : s) { - SigBit canonical_bit = sigmap(bit); - if (rewrite_bits.count(canonical_bit)) - bit = rewrite_bits.at(canonical_bit); - } - }; - - module->rewrite_sigspecs(rewrite_function); - - for (auto &it : pad_bits) - it.first->setPort(ID::I, it.second); -} - -struct EfinixGbufPass : public Pass { - EfinixGbufPass() : Pass("efinix_gbuf", "Efinix: insert global clock buffers") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" efinix_gbuf [options] [selection]\n"); - log("\n"); - log("Add Efinix global clock buffers to top module as needed.\n"); - log("\n"); - } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing efinix_gbuf pass (insert global clock buffers).\n"); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - break; - } - extra_args(args, argidx, design); - - Module *module = design->top_module(); - - if (module == nullptr) - log_cmd_error("No top module found.\n"); - - handle_gbufs(module); - } -} EfinixGbufPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/efinix/gbuf_map.v b/techlibs/efinix/gbuf_map.v new file mode 100644 index 000000000..43e0c9ac3 --- /dev/null +++ b/techlibs/efinix/gbuf_map.v @@ -0,0 +1,3 @@ +module \$__EFX_GBUF (input I, output O); + EFX_GBUFCE #(.CE_POLARITY(1'b1)) _TECHMAP_REPLACE_ (.I(I), .O(O), .CE(1'b1)); +endmodule diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index f9a7ef865..001b05945 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -30,7 +30,7 @@ struct SynthEfinixPass : public ScriptPass { SynthEfinixPass() : ScriptPass("synth_efinix", "synthesis for Efinix FPGAs") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -72,7 +72,7 @@ struct SynthEfinixPass : public ScriptPass string top_opt, edif_file, json_file; bool flatten, retime, nobram; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; edif_file = ""; @@ -82,7 +82,7 @@ struct SynthEfinixPass : public ScriptPass nobram = false; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -137,7 +137,7 @@ struct SynthEfinixPass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("begin")) { @@ -182,8 +182,8 @@ struct SynthEfinixPass : public ScriptPass if (check_label("map_ffs")) { + run("dfflegalize -cell $_DFFE_????_ 0 -cell $_SDFFE_????_ 0 -cell $_SDFFCE_????_ 0 -cell $_DLATCH_?_ x"); run("techmap -D NO_LUT -map +/efinix/cells_map.v"); - run("dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit"); run("opt_expr -mux_undef"); run("simplemap"); } @@ -202,7 +202,8 @@ struct SynthEfinixPass : public ScriptPass if (check_label("map_gbuf")) { - run("efinix_gbuf"); + run("clkbufmap -buf $__EFX_GBUF O:I"); + run("techmap -map +/efinix/gbuf_map.v"); run("efinix_fixcarry"); run("clean"); } diff --git a/techlibs/gowin/Makefile.inc b/techlibs/gowin/Makefile.inc index 0756e3bcf..e6a6be970 100644 --- a/techlibs/gowin/Makefile.inc +++ b/techlibs/gowin/Makefile.inc @@ -1,6 +1,5 @@ OBJS += techlibs/gowin/synth_gowin.o -OBJS += techlibs/gowin/determine_init.o GENFILES += techlibs/gowin/bram_init_16.vh diff --git a/techlibs/gowin/cells_map.v b/techlibs/gowin/cells_map.v index b44350616..851ef20b2 100644 --- a/techlibs/gowin/cells_map.v +++ b/techlibs/gowin/cells_map.v @@ -3,228 +3,123 @@ //value regardless. The parameter is ignored. // DFFN D Flip-Flop with Negative-Edge Clock -module \$_DFF_N_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, output Q); - generate - if (_TECHMAP_WIREINIT_Q_ === 1'b1) - DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(1'b0)); - else - DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); - endgenerate +module \$_DFF_N_ (input D, C, output Q); + DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFF D Flip-Flop -module \$_DFF_P_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, output Q); - generate - if (_TECHMAP_WIREINIT_Q_ === 1'b1) - DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(1'b0)); - else - DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); - endgenerate +module \$_DFF_P_ (input D, C, output Q); + DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFE D Flip-Flop with Clock Enable -module \$_DFFE_PP_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); - generate - if (_TECHMAP_WIREINIT_Q_ === 1'b1) - DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E), .SET(1'b0)); - else - DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -module \$_DFFE_PN_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); - generate - if (_TECHMAP_WIREINIT_Q_ === 1'b1) - DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E), .SET(1'b0)); - else - DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); - endgenerate +module \$_DFFE_PP_ (input D, C, E, output Q); + DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFNE D Flip-Flop with Negative-Edge Clock and Clock Enable -module \$_DFFE_NP_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); - generate - if (_TECHMAP_WIREINIT_Q_ === 1'b1) - DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E), .SET(1'b0)); - else - DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -module \$_DFFE_NN_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, E, output Q); - generate - if (_TECHMAP_WIREINIT_Q_ === 1'b1) - DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E), .SET(1'b0)); - else - DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); - endgenerate +module \$_DFFE_NP_ (input D, C, E, output Q); + DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFR D Flip-Flop with Synchronous Reset -module \$__DFFS_PN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); - DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; -endmodule - -module \$__DFFS_PP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); +module \$_SDFF_PP0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFNR D Flip-Flop with Negative-Edge Clock and Synchronous Reset -module \$__DFFS_NN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); - DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; -endmodule -module \$__DFFS_NP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); +module \$_SDFF_NP0_ (input D, C, R, output Q); DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFRE D Flip-Flop with Clock Enable and Synchronous Reset -module \$__DFFSE_PN0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); - DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; -endmodule -module \$__DFFSE_PP0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); +module \$_SDFFE_PP0P_ (input D, C, R, E, output Q); DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFNRE D Flip-Flop with Negative-Edge Clock,Clock Enable, and Synchronous Reset -module \$__DFFSE_NN0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); - DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; -endmodule -module \$__DFFSE_NP0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); +module \$_SDFFE_NP0P_ (input D, C, R, E, output Q); DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFS D Flip-Flop with Synchronous Set -module \$__DFFS_PN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); - DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; -endmodule -module \$__DFFS_PP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); +module \$_SDFF_PP1_ (input D, C, R, output Q); DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFNS D Flip-Flop with Negative-Edge Clock and Synchronous Set -module \$__DFFS_NN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); - DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; -endmodule -module \$__DFFS_NP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); +module \$_SDFF_NP1_ (input D, C, R, output Q); DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFSE D Flip-Flop with Clock Enable and Synchronous Set -module \$__DFFSE_PN1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); - DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; -endmodule -module \$__DFFSE_PP1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); +module \$_SDFFE_PP1P_ (input D, C, R, E, output Q); DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFNSE D Flip-Flop with Negative-Edge Clock,Clock Enable,and Synchronous Set -module \$__DFFSE_NN1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); - DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; -endmodule -module \$__DFFSE_NP1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); +module \$_SDFFE_NP1P_ (input D, C, R, E, output Q); DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFP D Flip-Flop with Asynchronous Preset -module \$_DFF_PP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); +module \$_DFF_PP1_ (input D, C, R, output Q); DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; -endmodule -module \$_DFF_PN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); - DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFNP D Flip-Flop with Negative-Edge Clock and Asynchronous Preset -module \$_DFF_NP1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); +module \$_DFF_NP1_ (input D, C, R, output Q); DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; -endmodule -module \$_DFF_NN1_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); - DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFC D Flip-Flop with Asynchronous Clear -module \$_DFF_PP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); +module \$_DFF_PP0_ (input D, C, R, output Q); DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; -endmodule -module \$_DFF_PN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); - DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFNC D Flip-Flop with Negative-Edge Clock and Asynchronous Clear -module \$_DFF_NP0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); +module \$_DFF_NP0_ (input D, C, R, output Q); DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; -endmodule -module \$_DFF_NN0_ #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, output Q); - DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFPE D Flip-Flop with Clock Enable and Asynchronous Preset -module \$__DFFE_PP1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); +module \$_DFFE_PP1P_ (input D, C, R, E, output Q); DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; -endmodule -module \$__DFFE_PN1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); - DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFNPE D Flip-Flop with Negative-Edge Clock,Clock Enable, and Asynchronous Preset -module \$__DFFE_NP1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); +module \$_DFFE_NP1P_ (input D, C, R, E, output Q); DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; -endmodule -module \$__DFFE_NN1 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); - DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b0; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFCE D Flip-Flop with Clock Enable and Asynchronous Clear -module \$__DFFE_PP0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); +module \$_DFFE_PP0P_ (input D, C, R, E, output Q); DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; -endmodule -module \$__DFFE_PN0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); - DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule // DFFNCE D Flip-Flop with Negative-Edge Clock,Clock Enable and Asynchronous Clear -module \$__DFFE_NP0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); +module \$_DFFE_NP0P_ (input D, C, R, E, output Q); DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; -endmodule -module \$__DFFE_NN0 #(parameter _TECHMAP_WIREINIT_Q_ = 1'bx) (input D, C, R, E, output Q); - DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); - wire _TECHMAP_REMOVEINIT_Q_ = _TECHMAP_WIREINIT_Q_ !== 1'b1; + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index a67855dab..509bf3ef2 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -1,33 +1,112 @@ +(* abc9_lut=1 *) module LUT1(output F, input I0); parameter [1:0] INIT = 0; + specify + (I0 => F) = (555, 902); + endspecify assign F = I0 ? INIT[1] : INIT[0]; endmodule +(* abc9_lut=1 *) module LUT2(output F, input I0, I1); parameter [3:0] INIT = 0; + specify + (I0 => F) = (867, 1184); + (I1 => F) = (555, 902); + endspecify wire [ 1: 0] s1 = I1 ? INIT[ 3: 2] : INIT[ 1: 0]; assign F = I0 ? s1[1] : s1[0]; endmodule +(* abc9_lut=1 *) module LUT3(output F, input I0, I1, I2); parameter [7:0] INIT = 0; + specify + (I0 => F) = (1054, 1486); + (I1 => F) = (867, 1184); + (I2 => F) = (555, 902); + endspecify wire [ 3: 0] s2 = I2 ? INIT[ 7: 4] : INIT[ 3: 0]; wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0]; assign F = I0 ? s1[1] : s1[0]; endmodule +(* abc9_lut=1 *) module LUT4(output F, input I0, I1, I2, I3); parameter [15:0] INIT = 0; + specify + (I0 => F) = (1054, 1486); + (I1 => F) = (1053, 1583); + (I2 => F) = (867, 1184); + (I3 => F) = (555, 902); + endspecify wire [ 7: 0] s3 = I3 ? INIT[15: 8] : INIT[ 7: 0]; wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0]; wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0]; assign F = I0 ? s1[1] : s1[0]; endmodule +(* abc9_lut=2 *) +module __APICULA_LUT5(output F, input I0, I1, I2, I3, M0); + specify + (I0 => F) = (1187, 1638); + (I1 => F) = (1184, 1638); + (I2 => F) = (995, 1371); + (I3 => F) = (808, 1116); + (M0 => F) = (486, 680); + endspecify +endmodule + +(* abc9_lut=4 *) +module __APICULA_LUT6(output F, input I0, I1, I2, I3, M0, M1); + specify + (I0 => F) = (1187 + 136, 1638 + 255); + (I1 => F) = (1184 + 136, 1638 + 255); + (I2 => F) = (995 + 136, 1371 + 255); + (I3 => F) = (808 + 136, 1116 + 255); + (M0 => F) = (486 + 136, 680 + 255); + (M1 => F) = (478, 723); + endspecify +endmodule + +(* abc9_lut=8 *) +module __APICULA_LUT7(output F, input I0, I1, I2, I3, M0, M1, M2); + specify + (I0 => F) = (1187 + 136 + 136, 1638 + 255 + 255); + (I1 => F) = (1184 + 136 + 136, 1638 + 255 + 255); + (I2 => F) = (995 + 136 + 136, 1371 + 255 + 255); + (I3 => F) = (808 + 136 + 136, 1116 + 255 + 255); + (M0 => F) = (486 + 136 + 136, 680 + 255 + 255); + (M1 => F) = (478 + 136, 723 + 255); + (M2 => F) = (478, 723); + endspecify +endmodule + +(* abc9_lut=16 *) +module __APICULA_LUT8(output F, input I0, I1, I2, I3, M0, M1, M2, M3); + specify + (I0 => F) = (1187 + 136 + 136 + 136, 1638 + 255 + 255 + 255); + (I1 => F) = (1184 + 136 + 136 + 136, 1638 + 255 + 255 + 255); + (I2 => F) = (995 + 136 + 136 + 136, 1371 + 255 + 255 + 255); + (I3 => F) = (808 + 136 + 136 + 136, 1116 + 255 + 255 + 255); + (M0 => F) = (486 + 136 + 136 + 136, 680 + 255 + 255 + 255); + (M1 => F) = (478 + 136 + 136, 723 + 255 + 255); + (M2 => F) = (478 + 136, 723 + 255); + (M3 => F) = (478, 723); + endspecify + endmodule + module MUX2 (O, I0, I1, S0); input I0,I1; input S0; output O; + + specify + (I0 => O) = (141, 160); + (I1 => O) = (141, 160); + (S0 => O) = (486, 680); + endspecify + assign O = S0 ? I1 : I0; endmodule @@ -35,6 +114,13 @@ module MUX2_LUT5 (O, I0, I1, S0); input I0,I1; input S0; output O; + + specify + (I0 => O) = (141, 160); + (I1 => O) = (141, 160); + (S0 => O) = (486, 680); + endspecify + MUX2 mux2_lut5 (O, I0, I1, S0); endmodule @@ -42,6 +128,13 @@ module MUX2_LUT6 (O, I0, I1, S0); input I0,I1; input S0; output O; + + specify + (I0 => O) = (136, 255); + (I1 => O) = (136, 255); + (S0 => O) = (478, 723); + endspecify + MUX2 mux2_lut6 (O, I0, I1, S0); endmodule @@ -49,6 +142,13 @@ module MUX2_LUT7 (O, I0, I1, S0); input I0,I1; input S0; output O; + + specify + (I0 => O) = (136, 255); + (I1 => O) = (136, 255); + (S0 => O) = (478, 723); + endspecify + MUX2 mux2_lut7 (O, I0, I1, S0); endmodule @@ -56,29 +156,58 @@ module MUX2_LUT8 (O, I0, I1, S0); input I0,I1; input S0; output O; + + specify + (I0 => O) = (136, 255); + (I1 => O) = (136, 255); + (S0 => O) = (478, 723); + endspecify + MUX2 mux2_lut8 (O, I0, I1, S0); endmodule +(* abc9_flop, lib_whitebox *) module DFF (output reg Q, input CLK, D); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + (posedge CLK => (Q : D)) = (480, 660); + $setup(D, posedge CLK, 576); + endspecify + always @(posedge CLK) Q <= D; endmodule +(* abc9_flop, lib_whitebox *) module DFFE (output reg Q, input D, CLK, CE); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + if (CE) (posedge CLK => (Q : D)) = (480, 660); + $setup(D, posedge CLK &&& CE, 576); + $setup(CE, posedge CLK, 63); + endspecify + always @(posedge CLK) begin if (CE) Q <= D; end endmodule // DFFE (positive clock edge; clock enable) - +(* abc9_box, lib_whitebox *) module DFFS (output reg Q, input D, CLK, SET); - parameter [0:0] INIT = 1'b0; + parameter [0:0] INIT = 1'b1; initial Q = INIT; + + specify + (posedge CLK => (Q : D)) = (480, 660); + $setup(D, posedge CLK, 576); + $setup(SET, posedge CLK, 63); + endspecify + always @(posedge CLK) begin if (SET) Q <= 1'b1; @@ -87,10 +216,18 @@ module DFFS (output reg Q, input D, CLK, SET); end endmodule // DFFS (positive clock edge; synchronous set) - +(* abc9_box, lib_whitebox *) module DFFSE (output reg Q, input D, CLK, CE, SET); - parameter [0:0] INIT = 1'b0; + parameter [0:0] INIT = 1'b1; initial Q = INIT; + + specify + if (CE) (posedge CLK => (Q : D)) = (480, 660); + $setup(D, posedge CLK &&& CE, 576); + $setup(CE, posedge CLK, 63); + $setup(SET, posedge CLK, 63); + endspecify + always @(posedge CLK) begin if (SET) Q <= 1'b1; @@ -99,10 +236,17 @@ module DFFSE (output reg Q, input D, CLK, CE, SET); end endmodule // DFFSE (positive clock edge; synchronous set takes precedence over clock enable) - +(* abc9_flop, lib_whitebox *) module DFFR (output reg Q, input D, CLK, RESET); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + (posedge CLK => (Q : D)) = (480, 660); + $setup(D, posedge CLK, 576); + $setup(RESET, posedge CLK, 63); + endspecify + always @(posedge CLK) begin if (RESET) Q <= 1'b0; @@ -111,10 +255,18 @@ module DFFR (output reg Q, input D, CLK, RESET); end endmodule // DFFR (positive clock edge; synchronous reset) - +(* abc9_flop, lib_whitebox *) module DFFRE (output reg Q, input D, CLK, CE, RESET); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + if (CE) (posedge CLK => (Q : D)) = (480, 660); + $setup(D, posedge CLK &&& CE, 576); + $setup(CE, posedge CLK, 63); + $setup(RESET, posedge CLK, 63); + endspecify + always @(posedge CLK) begin if (RESET) Q <= 1'b0; @@ -123,10 +275,17 @@ module DFFRE (output reg Q, input D, CLK, CE, RESET); end endmodule // DFFRE (positive clock edge; synchronous reset takes precedence over clock enable) - +(* abc9_box, lib_whitebox *) module DFFP (output reg Q, input D, CLK, PRESET); - parameter [0:0] INIT = 1'b0; + parameter [0:0] INIT = 1'b1; initial Q = INIT; + + specify + (posedge CLK => (Q : D)) = (480, 660); + (posedge PRESET => (Q : 1'b1)) = (1800, 2679); + $setup(D, posedge CLK, 576); + endspecify + always @(posedge CLK or posedge PRESET) begin if(PRESET) Q <= 1'b1; @@ -135,10 +294,18 @@ module DFFP (output reg Q, input D, CLK, PRESET); end endmodule // DFFP (positive clock edge; asynchronous preset) - +(* abc9_box, lib_whitebox *) module DFFPE (output reg Q, input D, CLK, CE, PRESET); - parameter [0:0] INIT = 1'b0; + parameter [0:0] INIT = 1'b1; initial Q = INIT; + + specify + if (CE) (posedge CLK => (Q : D)) = (480, 660); + (posedge PRESET => (Q : 1'b1)) = (1800, 2679); + $setup(D, posedge CLK &&& CE, 576); + $setup(CE, posedge CLK, 63); + endspecify + always @(posedge CLK or posedge PRESET) begin if(PRESET) Q <= 1'b1; @@ -147,10 +314,17 @@ module DFFPE (output reg Q, input D, CLK, CE, PRESET); end endmodule // DFFPE (positive clock edge; asynchronous preset; clock enable) - +(* abc9_box, lib_whitebox *) module DFFC (output reg Q, input D, CLK, CLEAR); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + (posedge CLK => (Q : D)) = (480, 660); + (posedge CLEAR => (Q : 1'b0)) = (1800, 2679); + $setup(D, posedge CLK, 576); + endspecify + always @(posedge CLK or posedge CLEAR) begin if(CLEAR) Q <= 1'b0; @@ -159,10 +333,18 @@ module DFFC (output reg Q, input D, CLK, CLEAR); end endmodule // DFFC (positive clock edge; asynchronous clear) - +(* abc9_box, lib_whitebox *) module DFFCE (output reg Q, input D, CLK, CE, CLEAR); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + if (CE) (posedge CLK => (Q : D)) = (480, 660); + (posedge CLEAR => (Q : 1'b0)) = (1800, 2679); + $setup(D, posedge CLK &&& CE, 576); + $setup(CE, posedge CLK, 63); + endspecify + always @(posedge CLK or posedge CLEAR) begin if(CLEAR) Q <= 1'b0; @@ -171,27 +353,48 @@ module DFFCE (output reg Q, input D, CLK, CE, CLEAR); end endmodule // DFFCE (positive clock edge; asynchronous clear; clock enable) - +(* abc9_flop, lib_whitebox *) module DFFN (output reg Q, input CLK, D); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + (negedge CLK => (Q : D)) = (480, 660); + $setup(D, negedge CLK, 576); + endspecify + always @(negedge CLK) Q <= D; endmodule +(* abc9_flop, lib_whitebox *) module DFFNE (output reg Q, input D, CLK, CE); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + if (CE) (negedge CLK => (Q : D)) = (480, 660); + $setup(D, negedge CLK &&& CE, 576); + $setup(CE, negedge CLK, 63); + endspecify + always @(negedge CLK) begin if (CE) Q <= D; end endmodule // DFFNE (negative clock edge; clock enable) - +(* abc9_box, lib_whitebox *) module DFFNS (output reg Q, input D, CLK, SET); - parameter [0:0] INIT = 1'b0; + parameter [0:0] INIT = 1'b1; initial Q = INIT; + + specify + (negedge CLK => (Q : D)) = (480, 660); + $setup(D, negedge CLK, 576); + $setup(SET, negedge CLK, 63); + endspecify + always @(negedge CLK) begin if (SET) Q <= 1'b1; @@ -200,10 +403,18 @@ module DFFNS (output reg Q, input D, CLK, SET); end endmodule // DFFNS (negative clock edge; synchronous set) - +(* abc9_box, lib_whitebox *) module DFFNSE (output reg Q, input D, CLK, CE, SET); - parameter [0:0] INIT = 1'b0; + parameter [0:0] INIT = 1'b1; initial Q = INIT; + + specify + if (CE) (negedge CLK => (Q : D)) = (480, 660); + $setup(D, negedge CLK &&& CE, 576); + $setup(CE, negedge CLK, 63); + $setup(SET, negedge CLK, 63); + endspecify + always @(negedge CLK) begin if (SET) Q <= 1'b1; @@ -212,10 +423,17 @@ module DFFNSE (output reg Q, input D, CLK, CE, SET); end endmodule // DFFNSE (negative clock edge; synchronous set takes precedence over clock enable) - +(* abc9_flop, lib_whitebox *) module DFFNR (output reg Q, input D, CLK, RESET); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + (negedge CLK => (Q : D)) = (480, 660); + $setup(D, negedge CLK, 576); + $setup(RESET, negedge CLK, 63); + endspecify + always @(negedge CLK) begin if (RESET) Q <= 1'b0; @@ -224,10 +442,18 @@ module DFFNR (output reg Q, input D, CLK, RESET); end endmodule // DFFNR (negative clock edge; synchronous reset) - +(* abc9_flop, lib_whitebox *) module DFFNRE (output reg Q, input D, CLK, CE, RESET); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + if (CE) (negedge CLK => (Q : D)) = (480, 660); + $setup(D, negedge CLK &&& CE, 576); + $setup(CE, negedge CLK, 63); + $setup(RESET, negedge CLK, 63); + endspecify + always @(negedge CLK) begin if (RESET) Q <= 1'b0; @@ -236,10 +462,17 @@ module DFFNRE (output reg Q, input D, CLK, CE, RESET); end endmodule // DFFNRE (negative clock edge; synchronous reset takes precedence over clock enable) - +(* abc9_box, lib_whitebox *) module DFFNP (output reg Q, input D, CLK, PRESET); - parameter [0:0] INIT = 1'b0; + parameter [0:0] INIT = 1'b1; initial Q = INIT; + + specify + (negedge CLK => (Q : D)) = (480, 660); + (posedge PRESET => (Q : 1'b1)) = (1800, 2679); + $setup(D, negedge CLK, 576); + endspecify + always @(negedge CLK or posedge PRESET) begin if(PRESET) Q <= 1'b1; @@ -248,10 +481,18 @@ module DFFNP (output reg Q, input D, CLK, PRESET); end endmodule // DFFNP (negative clock edge; asynchronous preset) - +(* abc9_box, lib_whitebox *) module DFFNPE (output reg Q, input D, CLK, CE, PRESET); - parameter [0:0] INIT = 1'b0; + parameter [0:0] INIT = 1'b1; initial Q = INIT; + + specify + if (CE) (negedge CLK => (Q : D)) = (480, 660); + (posedge PRESET => (Q : 1'b1)) = (1800, 2679); + $setup(D, negedge CLK &&& CE, 576); + $setup(CE, negedge CLK, 63); + endspecify + always @(negedge CLK or posedge PRESET) begin if(PRESET) Q <= 1'b1; @@ -260,10 +501,17 @@ module DFFNPE (output reg Q, input D, CLK, CE, PRESET); end endmodule // DFFNPE (negative clock edge; asynchronous preset; clock enable) - +(* abc9_box, lib_whitebox *) module DFFNC (output reg Q, input D, CLK, CLEAR); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + (negedge CLK => (Q : D)) = (480, 660); + (posedge CLEAR => (Q : 1'b0)) = (1800, 2679); + $setup(D, negedge CLK, 576); + endspecify + always @(negedge CLK or posedge CLEAR) begin if(CLEAR) Q <= 1'b0; @@ -272,10 +520,18 @@ module DFFNC (output reg Q, input D, CLK, CLEAR); end endmodule // DFFNC (negative clock edge; asynchronous clear) - +(* abc9_box, lib_whitebox *) module DFFNCE (output reg Q, input D, CLK, CE, CLEAR); parameter [0:0] INIT = 1'b0; initial Q = INIT; + + specify + if (CE) (negedge CLK => (Q : D)) = (480, 660); + (posedge CLEAR => (Q : 1'b0)) = (1800, 2679); + $setup(D, negedge CLK &&& CE, 576); + $setup(CE, negedge CLK, 63); + endspecify + always @(negedge CLK or posedge CLEAR) begin if(CLEAR) Q <= 1'b0; @@ -294,11 +550,23 @@ module GND(output G); assign G = 0; endmodule +(* abc9_box *) module IBUF(output O, input I); + + specify + (I => O) = 0; + endspecify + assign O = I; endmodule +(* abc9_box *) module OBUF(output O, input I); + + specify + (I => O) = 0; + endspecify + assign O = I; endmodule @@ -320,14 +588,15 @@ module GSR (input GSRI); wire GSRO = GSRI; endmodule +(* abc9_box, lib_whitebox *) module ALU (SUM, COUT, I0, I1, I3, CIN); input I0; input I1; input I3; -input CIN; +(* abc9_carry *) input CIN; output SUM; -output COUT; +(* abc9_carry *) output COUT; localparam ADD = 0; localparam SUB = 1; @@ -344,6 +613,17 @@ parameter ALU_MODE = 0; reg S, C; +specify + (I0 => SUM) = (1043, 1432); + (I1 => SUM) = (775, 1049); + (I3 => SUM) = (751, 1010); + (CIN => SUM) = (694, 811); + (I0 => COUT) = (1010, 1380); + (I1 => COUT) = (1021, 1505); + (I3 => COUT) = (483, 792); + (CIN => COUT) = (49, 82); +endspecify + assign SUM = S ^ CIN; assign COUT = S? CIN : C; @@ -394,7 +674,6 @@ end endmodule - module RAM16S4 (DO, DI, AD, WRE, CLK); parameter WIDTH = 4; parameter INIT_0 = 16'h0000; @@ -408,6 +687,14 @@ module RAM16S4 (DO, DI, AD, WRE, CLK); input CLK; input WRE; + specify + (AD => DO) = (270, 405); + $setup(DI, posedge CLK, 62); + $setup(WRE, posedge CLK, 62); + $setup(AD, posedge CLK, 62); + (posedge CLK => (DO : {WIDTH{1'bx}})) = (474, 565); + endspecify + reg [15:0] mem0, mem1, mem2, mem3; initial begin @@ -516,5 +803,66 @@ input [31:0] DI; input [2:0] BLKSEL; output [31:0] DO; +specify + (posedge CLKB => (DO : DI)) = (419, 493); + $setup(RESETA, posedge CLKA, 62); + $setup(RESETB, posedge CLKB, 62); + $setup(OCE, posedge CLKB, 62); + $setup(CEA, posedge CLKA, 62); + $setup(CEB, posedge CLKB, 62); + $setup(OCE, posedge CLKB, 62); + $setup(WREA, posedge CLKA, 62); + $setup(WREB, posedge CLKB, 62); + $setup(DI, posedge CLKA, 62); + $setup(ADA, posedge CLKA, 62); + $setup(ADB, posedge CLKB, 62); + $setup(BLKSEL, posedge CLKA, 62); +endspecify + endmodule +(* blackbox *) +module rPLL (CLKOUT, CLKOUTP, CLKOUTD, CLKOUTD3, LOCK, CLKIN, CLKFB, FBDSEL, IDSEL, ODSEL, DUTYDA, PSDA, FDLY, RESET, RESET_P); +input CLKIN; +input CLKFB; +input RESET; +input RESET_P; +input [5:0] FBDSEL; +input [5:0] IDSEL; +input [5:0] ODSEL; +input [3:0] PSDA,FDLY; +input [3:0] DUTYDA; + +output CLKOUT; +output LOCK; +output CLKOUTP; +output CLKOUTD; +output CLKOUTD3; + +parameter FCLKIN = "100.0"; // frequency of CLKIN +parameter DYN_IDIV_SEL= "false"; // true:IDSEL, false:IDIV_SEL +parameter IDIV_SEL = 0; // 0:1, 1:2 ... 63:64 +parameter DYN_FBDIV_SEL= "false"; // true:FBDSEL, false:FBDIV_SEL +parameter FBDIV_SEL = 0; // 0:1, 1:2 ... 63:64 +parameter DYN_ODIV_SEL= "false"; // true:ODSEL, false:ODIV_SEL +parameter ODIV_SEL = 8; // 2/4/8/16/32/48/64/80/96/112/128 + +parameter PSDA_SEL= "0000"; +parameter DYN_DA_EN = "false"; // true:PSDA or DUTYDA or FDA, false: DA_SEL +parameter DUTYDA_SEL= "1000"; + +parameter CLKOUT_FT_DIR = 1'b1; // CLKOUT fine tuning direction. 1'b1 only +parameter CLKOUTP_FT_DIR = 1'b1; // 1'b1 only +parameter CLKOUT_DLY_STEP = 0; // 0, 1, 2, 4 +parameter CLKOUTP_DLY_STEP = 0; // 0, 1, 2 + +parameter CLKFB_SEL = "internal"; // "internal", "external" +parameter CLKOUT_BYPASS = "false"; // "true", "false" +parameter CLKOUTP_BYPASS = "false"; // "true", "false" +parameter CLKOUTD_BYPASS = "false"; // "true", "false" +parameter DYN_SDIV_SEL = 2; // 2~128, only even numbers +parameter CLKOUTD_SRC = "CLKOUT"; // CLKOUT, CLKOUTP +parameter CLKOUTD3_SRC = "CLKOUT"; // CLKOUT, CLKOUTP +parameter DEVICE = "GW1N-1"; // "GW1N-1", "GW1N-4", "GW1N-9", "GW1NR-4", "GW1NR-9", "GW1N-4B", "GW1NR-4B", "GW1NS-2", "GW1NS-2C", "GW1NZ-1", "GW1NSR-2", "GW1NSR-2C", "GW1N-1S", "GW1NSE-2C", "GW1NRF-4B", "GW1N-9C", "GW1NR-9C", "GW1N-4C", "GW1NR-4C" + +endmodule diff --git a/techlibs/gowin/determine_init.cc b/techlibs/gowin/determine_init.cc deleted file mode 100644 index 18a64e451..000000000 --- a/techlibs/gowin/determine_init.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io> - * - * 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 DetermineInitPass : public Pass { - DetermineInitPass() : Pass("determine_init", "Determine the init value of cells") { } - void help() YS_OVERRIDE - { - log("\n"); - log(" determine_init [selection]\n"); - log("\n"); - log("Determine the init value of cells that doesn't allow unknown init value.\n"); - log("\n"); - } - - Const determine_init(Const init) - { - for (int i = 0; i < GetSize(init); i++) { - if (init[i] != State::S0 && init[i] != State::S1) - init[i] = State::S0; - } - - return init; - } - - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing DETERMINE_INIT pass (determine init value for cells).\n"); - - extra_args(args, args.size(), design); - - int cnt = 0; - for (auto module : design->selected_modules()) - { - for (auto cell : module->selected_cells()) - { - if (cell->type == ID(RAM16S4)) - { - cell->setParam(ID(INIT_0), determine_init(cell->getParam(ID(INIT_0)))); - cell->setParam(ID(INIT_1), determine_init(cell->getParam(ID(INIT_1)))); - cell->setParam(ID(INIT_2), determine_init(cell->getParam(ID(INIT_2)))); - cell->setParam(ID(INIT_3), determine_init(cell->getParam(ID(INIT_3)))); - cnt++; - } - } - } - log_header(design, "Updated %d cells with determined init value.\n", cnt); - } -} DetermineInitPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index dd965c0b8..4d1e968ae 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -29,7 +29,7 @@ struct SynthGowinPass : public ScriptPass { SynthGowinPass() : ScriptPass("synth_gowin", "synthesis for Gowin FPGAs") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -69,9 +69,9 @@ struct SynthGowinPass : public ScriptPass log("\n"); log(" -noiopads\n"); log(" do not emit IOB at top level ports\n"); - //log("\n"); - //log(" -abc9\n"); - //log(" use new ABC9 flow (EXPERIMENTAL)\n"); + log("\n"); + log(" -abc9\n"); + log(" use new ABC9 flow (EXPERIMENTAL)\n"); log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); @@ -82,7 +82,7 @@ struct SynthGowinPass : public ScriptPass string top_opt, vout_file; bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; vout_file = ""; @@ -96,7 +96,7 @@ struct SynthGowinPass : public ScriptPass noiopads = false; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -144,10 +144,10 @@ struct SynthGowinPass : public ScriptPass nowidelut = true; continue; } - //if (args[argidx] == "-abc9") { - // abc9 = true; - // continue; - //} + if (args[argidx] == "-abc9") { + abc9 = true; + continue; + } if (args[argidx] == "-noiopads") { noiopads = true; continue; @@ -167,11 +167,11 @@ struct SynthGowinPass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("begin")) { - run("read_verilog -lib +/gowin/cells_sim.v"); + run("read_verilog -specify -lib +/gowin/cells_sim.v"); run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str())); } @@ -198,7 +198,7 @@ struct SynthGowinPass : public ScriptPass { run("memory_bram -rules +/gowin/lutrams.txt"); run("techmap -map +/gowin/lutrams_map.v"); - run("determine_init"); + run("setundef -params -zero t:RAM16S4"); } if (check_label("map_ffram")) @@ -219,10 +219,11 @@ struct SynthGowinPass : public ScriptPass if (check_label("map_ffs")) { - run("dff2dffs -match-init"); run("opt_clean"); - if (!nodffe) - run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); + if (nodffe) + run("dfflegalize -cell $_DFF_?_ 0 -cell $_SDFF_?P?_ r -cell $_DFF_?P?_ r"); + else + run("dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_SDFF_?P?_ r -cell $_SDFFE_?P?P_ r -cell $_DFF_?P?_ r -cell $_DFFE_?P?P_ r"); run("techmap -map +/gowin/cells_map.v"); run("opt_expr -mux_undef"); run("simplemap"); @@ -230,13 +231,15 @@ struct SynthGowinPass : public ScriptPass if (check_label("map_luts")) { - /*if (nowidelut && abc9) { - run("abc9 -lut 4"); - } else*/ if (nowidelut && !abc9) { + if (nowidelut && abc9) { + run("read_verilog -icells -lib -specify +/abc9_model.v"); + run("abc9 -maxlut 4 -W 500"); + } else if (nowidelut && !abc9) { run("abc -lut 4"); - } else /*if (!nowidelut && abc9) { - run("abc9 -lut 4:8"); - } else*/ if (!nowidelut && !abc9) { + } else if (!nowidelut && abc9) { + run("read_verilog -icells -lib -specify +/abc9_model.v"); + run("abc9 -maxlut 8 -W 500"); + } else if (!nowidelut && !abc9) { run("abc -lut 4:8"); } run("clean"); @@ -252,6 +255,7 @@ struct SynthGowinPass : public ScriptPass run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O " "-toutpad TBUF OEN:I:O -tinoutpad IOBUF OEN:O:I:IO", "(unless -noiopads)"); run("clean"); + run("autoname"); } if (check_label("check")) diff --git a/techlibs/greenpak4/greenpak4_dffinv.cc b/techlibs/greenpak4/greenpak4_dffinv.cc index 62057318b..b8797bc19 100644 --- a/techlibs/greenpak4/greenpak4_dffinv.cc +++ b/techlibs/greenpak4/greenpak4_dffinv.cc @@ -91,7 +91,7 @@ void invert_gp_dff(Cell *cell, bool invert_input) struct Greenpak4DffInvPass : public Pass { Greenpak4DffInvPass() : Pass("greenpak4_dffinv", "merge greenpak4 inverters and DFF/latches") { } - void help() YS_OVERRIDE + void help() override { log("\n"); log(" greenpak4_dffinv [options] [selection]\n"); @@ -99,7 +99,7 @@ struct Greenpak4DffInvPass : public Pass { log("Merge GP_INV cells with GP_DFF* and GP_DLATCH* cells.\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing GREENPAK4_DFFINV pass (merge input/output inverters into FF/latch cells).\n"); diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc index bfbb56d15..d9af340d9 100644 --- a/techlibs/greenpak4/synth_greenpak4.cc +++ b/techlibs/greenpak4/synth_greenpak4.cc @@ -29,7 +29,7 @@ struct SynthGreenPAK4Pass : public ScriptPass { SynthGreenPAK4Pass() : ScriptPass("synth_greenpak4", "synthesis for GreenPAK4 FPGAs") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -70,7 +70,7 @@ struct SynthGreenPAK4Pass : public ScriptPass string top_opt, part, json_file; bool flatten, retime; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; part = "SLG46621V"; @@ -79,7 +79,7 @@ struct SynthGreenPAK4Pass : public ScriptPass retime = false; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -133,7 +133,7 @@ struct SynthGreenPAK4Pass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("begin")) { @@ -162,7 +162,7 @@ struct SynthGreenPAK4Pass : public ScriptPass run("opt -undriven -fine"); run("techmap -map +/techmap.v -map +/greenpak4/cells_latch.v"); run("dfflibmap -prepare -liberty +/greenpak4/gp_dff.lib"); - run("opt -fast"); + run("opt -fast -noclkinv -noff"); if (retime || help_mode) run("abc -dff -D 1", "(only if -retime)"); } diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc index 1a8caf9a9..8ce3cb024 100644 --- a/techlibs/ice40/Makefile.inc +++ b/techlibs/ice40/Makefile.inc @@ -1,8 +1,6 @@ OBJS += techlibs/ice40/synth_ice40.o OBJS += techlibs/ice40/ice40_braminit.o -OBJS += techlibs/ice40/ice40_ffssr.o -OBJS += techlibs/ice40/ice40_ffinit.o OBJS += techlibs/ice40/ice40_opt.o GENFILES += techlibs/ice40/brams_init1.vh diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index ad572c877..7ee809262 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -2508,7 +2508,7 @@ module SB_SPRAM256KA ( always @(negedge POWEROFF) begin for (i = 0; i <= 16383; i = i+1) - mem[i] = 'bx; + mem[i] = 16'bx; end always @(posedge CLOCK, posedge off) begin @@ -2516,17 +2516,17 @@ module SB_SPRAM256KA ( DATAOUT <= 0; end else if (STANDBY) begin - DATAOUT <= 'bx; + DATAOUT <= 16'bx; end else if (CHIPSELECT) begin if (!WREN) begin DATAOUT <= mem[ADDRESS]; end else begin - if (MASKWREN[0]) mem[ADDRESS][ 3: 0] = DATAIN[ 3: 0]; - if (MASKWREN[1]) mem[ADDRESS][ 7: 4] = DATAIN[ 7: 4]; - if (MASKWREN[2]) mem[ADDRESS][11: 8] = DATAIN[11: 8]; - if (MASKWREN[3]) mem[ADDRESS][15:12] = DATAIN[15:12]; - DATAOUT <= 'bx; + if (MASKWREN[0]) mem[ADDRESS][ 3: 0] <= DATAIN[ 3: 0]; + if (MASKWREN[1]) mem[ADDRESS][ 7: 4] <= DATAIN[ 7: 4]; + if (MASKWREN[2]) mem[ADDRESS][11: 8] <= DATAIN[11: 8]; + if (MASKWREN[3]) mem[ADDRESS][15:12] <= DATAIN[15:12]; + DATAOUT <= 16'bx; end end end diff --git a/techlibs/ice40/ff_map.v b/techlibs/ice40/ff_map.v index e8807e0bd..8174323a2 100644 --- a/techlibs/ice40/ff_map.v +++ b/techlibs/ice40/ff_map.v @@ -1,28 +1,25 @@ -module \$_DFF_N_ (input D, C, output Q); SB_DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C)); endmodule -module \$_DFF_P_ (input D, C, output Q); SB_DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C)); endmodule +module \$_DFF_N_ (input D, C, output Q); SB_DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_DFF_P_ (input D, C, output Q); SB_DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFFE_NN_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule -module \$_DFFE_PN_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule +module \$_DFFE_NP_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_DFFE_PP_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFFE_NP_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule -module \$_DFFE_PP_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule +module \$_DFF_NP0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_DFF_NP1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_DFF_PP0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_NN0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(!R)); endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(!R)); endmodule -module \$_DFF_PN0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(!R)); endmodule -module \$_DFF_PN1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(!R)); endmodule +module \$_DFFE_NP0P_ (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_DFFE_NP1P_ (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_DFFE_PP0P_ (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_DFFE_PP1P_ (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$_DFF_NP0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); endmodule +module \$_SDFF_NP0_ (input D, C, R, output Q); SB_DFFNSR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_SDFF_NP1_ (input D, C, R, output Q); SB_DFFNSS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_SDFF_PP0_ (input D, C, R, output Q); SB_DFFSR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_SDFF_PP1_ (input D, C, R, output Q); SB_DFFSS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule -module \$__DFFE_NN0 (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule -module \$__DFFE_NN1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule -module \$__DFFE_PN0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule -module \$__DFFE_PN1 (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule - -module \$__DFFE_NP0 (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule -module \$__DFFE_NP1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule -module \$__DFFE_PP0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule -module \$__DFFE_PP1 (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule +module \$_SDFFCE_NP0P_ (input D, C, E, R, output Q); SB_DFFNESR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_SDFFCE_NP1P_ (input D, C, E, R, output Q); SB_DFFNESS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_SDFFCE_PP0P_ (input D, C, E, R, output Q); SB_DFFESR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule +module \$_SDFFCE_PP1P_ (input D, C, E, R, output Q); SB_DFFESS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule diff --git a/techlibs/ice40/ice40_braminit.cc b/techlibs/ice40/ice40_braminit.cc index 936c189ea..e5d1f7e24 100644 --- a/techlibs/ice40/ice40_braminit.cc +++ b/techlibs/ice40/ice40_braminit.cc @@ -128,7 +128,7 @@ static void run_ice40_braminit(Module *module) struct Ice40BRAMInitPass : public Pass { Ice40BRAMInitPass() : Pass("ice40_braminit", "iCE40: perform SB_RAM40_4K initialization from file") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -138,7 +138,7 @@ struct Ice40BRAMInitPass : public Pass { log("parameter and converts it into the required INIT_x attributes\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing ICE40_BRAMINIT pass.\n"); diff --git a/techlibs/ice40/ice40_ffinit.cc b/techlibs/ice40/ice40_ffinit.cc deleted file mode 100644 index d7715135e..000000000 --- a/techlibs/ice40/ice40_ffinit.cc +++ /dev/null @@ -1,179 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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 Ice40FfinitPass : public Pass { - Ice40FfinitPass() : Pass("ice40_ffinit", "iCE40: handle FF init values") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" ice40_ffinit [options] [selection]\n"); - log("\n"); - log("Remove zero init values for FF output signals. Add inverters to implement\n"); - log("nonzero init values.\n"); - log("\n"); - } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing ICE40_FFINIT pass (implement FF init values).\n"); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - // if (args[argidx] == "-singleton") { - // singleton_mode = true; - // continue; - // } - break; - } - extra_args(args, argidx, design); - - for (auto module : design->selected_modules()) - { - log("Handling FF init values in %s.\n", log_id(module)); - - SigMap sigmap(module); - pool<Wire*> init_wires; - dict<SigBit, State> initbits; - dict<SigBit, SigBit> initbit_to_wire; - pool<SigBit> handled_initbits; - - for (auto wire : module->selected_wires()) - { - if (wire->attributes.count(ID::init) == 0) - continue; - - SigSpec wirebits = sigmap(wire); - Const initval = wire->attributes.at(ID::init); - init_wires.insert(wire); - - for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) - { - SigBit bit = wirebits[i]; - State val = initval[i]; - - if (val != State::S0 && val != State::S1) - continue; - - if (initbits.count(bit)) { - if (initbits.at(bit) != val) { - log_warning("Conflicting init values for signal %s (%s = %s, %s = %s).\n", - log_signal(bit), log_signal(SigBit(wire, i)), log_signal(val), - log_signal(initbit_to_wire[bit]), log_signal(initbits.at(bit))); - initbits.at(bit) = State::Sx; - } - continue; - } - - initbits[bit] = val; - initbit_to_wire[bit] = SigBit(wire, i); - } - } - - pool<IdString> sb_dff_types = { - ID(SB_DFF), ID(SB_DFFE), ID(SB_DFFSR), ID(SB_DFFR), ID(SB_DFFSS), ID(SB_DFFS), ID(SB_DFFESR), - ID(SB_DFFER), ID(SB_DFFESS), ID(SB_DFFES), ID(SB_DFFN), ID(SB_DFFNE), ID(SB_DFFNSR), ID(SB_DFFNR), - ID(SB_DFFNSS), ID(SB_DFFNS), ID(SB_DFFNESR), ID(SB_DFFNER), ID(SB_DFFNESS), ID(SB_DFFNES) - }; - - for (auto cell : module->selected_cells()) - { - if (!sb_dff_types.count(cell->type)) - continue; - - SigSpec sig_d = cell->getPort(ID::D); - SigSpec sig_q = cell->getPort(ID::Q); - - if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1) - continue; - - SigBit bit_d = sigmap(sig_d[0]); - SigBit bit_q = sigmap(sig_q[0]); - - if (!initbits.count(bit_q)) - continue; - - State val = initbits.at(bit_q); - - if (val == State::Sx) - continue; - - handled_initbits.insert(bit_q); - - log("FF init value for cell %s (%s): %s = %c\n", log_id(cell), log_id(cell->type), - log_signal(bit_q), val != State::S0 ? '1' : '0'); - - if (val == State::S0) - continue; - - string type_str = cell->type.str(); - - if (type_str.back() == 'S') { - type_str.back() = 'R'; - cell->type = type_str; - cell->setPort(ID::R, cell->getPort(ID::S)); - cell->unsetPort(ID::S); - } else - if (type_str.back() == 'R') { - type_str.back() = 'S'; - cell->type = type_str; - cell->setPort(ID::S, cell->getPort(ID::R)); - cell->unsetPort(ID::R); - } - - Wire *new_bit_d = module->addWire(NEW_ID); - Wire *new_bit_q = module->addWire(NEW_ID); - - module->addNotGate(NEW_ID, bit_d, new_bit_d); - module->addNotGate(NEW_ID, new_bit_q, bit_q); - - cell->setPort(ID::D, new_bit_d); - cell->setPort(ID::Q, new_bit_q); - } - - for (auto wire : init_wires) - { - if (wire->attributes.count(ID::init) == 0) - continue; - - SigSpec wirebits = sigmap(wire); - Const &initval = wire->attributes.at(ID::init); - bool remove_attribute = true; - - for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) { - if (handled_initbits.count(wirebits[i])) - initval[i] = State::Sx; - else if (initval[i] != State::Sx) - remove_attribute = false; - } - - if (remove_attribute) - wire->attributes.erase(ID::init); - } - } - } -} Ice40FfinitPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/ice40/ice40_ffssr.cc b/techlibs/ice40/ice40_ffssr.cc deleted file mode 100644 index ffb8c74b1..000000000 --- a/techlibs/ice40/ice40_ffssr.cc +++ /dev/null @@ -1,131 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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 Ice40FfssrPass : public Pass { - Ice40FfssrPass() : Pass("ice40_ffssr", "iCE40: merge synchronous set/reset into FF cells") { } - void help() YS_OVERRIDE - { - log("\n"); - log(" ice40_ffssr [options] [selection]\n"); - log("\n"); - log("Merge synchronous set/reset $_MUX_ cells into iCE40 FFs.\n"); - log("\n"); - } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing ICE40_FFSSR pass (merge synchronous set/reset into FF cells).\n"); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - // if (args[argidx] == "-singleton") { - // singleton_mode = true; - // continue; - // } - break; - } - extra_args(args, argidx, design); - - pool<IdString> sb_dff_types; - sb_dff_types.insert(ID(SB_DFF)); - sb_dff_types.insert(ID(SB_DFFE)); - sb_dff_types.insert(ID(SB_DFFN)); - sb_dff_types.insert(ID(SB_DFFNE)); - - for (auto module : design->selected_modules()) - { - log("Merging set/reset $_MUX_ cells into SB_FFs in %s.\n", log_id(module)); - - SigMap sigmap(module); - dict<SigBit, Cell*> sr_muxes; - vector<Cell*> ff_cells; - - for (auto cell : module->selected_cells()) - { - if (sb_dff_types.count(cell->type)) { - ff_cells.push_back(cell); - continue; - } - - if (cell->type != ID($_MUX_)) - continue; - - SigBit bit_a = sigmap(cell->getPort(ID::A)); - SigBit bit_b = sigmap(cell->getPort(ID::B)); - - if (bit_a.wire == nullptr || bit_b.wire == nullptr) - sr_muxes[sigmap(cell->getPort(ID::Y))] = cell; - } - - for (auto cell : ff_cells) - { - if (cell->get_bool_attribute(ID(dont_touch))) - continue; - - SigSpec sig_d = cell->getPort(ID::D); - - if (GetSize(sig_d) < 1) - continue; - - SigBit bit_d = sigmap(sig_d[0]); - - if (sr_muxes.count(bit_d) == 0) - continue; - - Cell *mux_cell = sr_muxes.at(bit_d); - SigBit bit_a = sigmap(mux_cell->getPort(ID::A)); - SigBit bit_b = sigmap(mux_cell->getPort(ID::B)); - SigBit bit_s = sigmap(mux_cell->getPort(ID::S)); - - log(" Merging %s (A=%s, B=%s, S=%s) into %s (%s).\n", log_id(mux_cell), - log_signal(bit_a), log_signal(bit_b), log_signal(bit_s), log_id(cell), log_id(cell->type)); - - SigBit sr_val, sr_sig; - if (bit_a.wire == nullptr) { - bit_d = bit_b; - sr_val = bit_a; - sr_sig = module->NotGate(NEW_ID, bit_s); - } else { - log_assert(bit_b.wire == nullptr); - bit_d = bit_a; - sr_val = bit_b; - sr_sig = bit_s; - } - - if (sr_val == State::S1) { - cell->type = cell->type.str() + "SS"; - cell->setPort(ID::S, sr_sig); - cell->setPort(ID::D, bit_d); - } else { - cell->type = cell->type.str() + "SR"; - cell->setPort(ID::R, sr_sig); - cell->setPort(ID::D, bit_d); - } - } - } - } -} Ice40FfssrPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index 18c1a58cf..d28607904 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -203,7 +203,7 @@ static void run_ice40_opts(Module *module) struct Ice40OptPass : public Pass { Ice40OptPass() : Pass("ice40_opt", "iCE40: perform simple optimizations") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -215,12 +215,12 @@ struct Ice40OptPass : public Pass { log(" <ice40 specific optimizations>\n"); log(" opt_expr -mux_undef -undriven [-full]\n"); log(" opt_merge\n"); - log(" opt_rmdff\n"); + log(" opt_dff\n"); log(" opt_clean\n"); log(" while <changed design>\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string opt_expr_args = "-mux_undef -undriven"; @@ -247,7 +247,7 @@ struct Ice40OptPass : public Pass { Pass::call(design, "opt_expr " + opt_expr_args); Pass::call(design, "opt_merge"); - Pass::call(design, "opt_rmdff"); + Pass::call(design, "opt_dff"); Pass::call(design, "opt_clean"); if (design->scratchpad_get_bool("opt.did_something") == false) diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 27850b075..b945889fe 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -29,14 +29,14 @@ struct SynthIce40Pass : public ScriptPass { SynthIce40Pass() : ScriptPass("synth_ice40", "synthesis for iCE40 FPGAs") { } - void on_register() YS_OVERRIDE + void on_register() override { RTLIL::constpad["synth_ice40.abc9.hx.W"] = "250"; RTLIL::constpad["synth_ice40.abc9.lp.W"] = "400"; RTLIL::constpad["synth_ice40.abc9.u.W"] = "750"; } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -119,7 +119,7 @@ struct SynthIce40Pass : public ScriptPass bool nocarry, nodffe, nobram, dsp, flatten, retime, noabc, abc2, vpr, abc9, dff, flowmap; int min_ce_use; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; blif_file = ""; @@ -140,7 +140,7 @@ struct SynthIce40Pass : public ScriptPass device_opt = "hx"; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -262,7 +262,7 @@ struct SynthIce40Pass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { std::string define; if (device_opt == "lp") @@ -292,6 +292,8 @@ struct SynthIce40Pass : public ScriptPass run("opt_expr"); run("opt_clean"); run("check"); + run("opt -nodffe -nosdff"); + run("fsm"); run("opt"); run("wreduce"); run("peepopt"); @@ -316,8 +318,6 @@ struct SynthIce40Pass : public ScriptPass } run("alumacc"); run("opt"); - run("fsm"); - run("opt -fast"); run("memory -nomap"); run("opt_clean"); } @@ -354,20 +354,13 @@ struct SynthIce40Pass : public ScriptPass if (check_label("map_ffs")) { - if (!nodffe) - run("dff2dffe -direct-match $_DFF_*"); - if (min_ce_use >= 0) { - run("opt_merge"); - run(stringf("dff2dffe -unmap-mince %d", min_ce_use)); - run("simplemap t:$dff"); - } - if ((abc9 && dff) || help_mode) - run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$__DFFS*", "(only if -abc9 and -dff"); + if (nodffe) + run(stringf("dfflegalize -cell $_DFF_?_ 0 -cell $_DFF_?P?_ 0 -cell $_SDFF_?P?_ 0 -cell $_DLATCH_?_ x")); + else + run(stringf("dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_DFF_?P?_ 0 -cell $_DFFE_?P?P_ 0 -cell $_SDFF_?P?_ 0 -cell $_SDFFCE_?P?P_ 0 -cell $_DLATCH_?_ x -mince %d", min_ce_use)); run("techmap -map +/ice40/ff_map.v"); run("opt_expr -mux_undef"); run("simplemap"); - run("ice40_ffinit"); - run("ice40_ffssr"); run("ice40_opt -full"); } diff --git a/techlibs/intel/Makefile.inc b/techlibs/intel/Makefile.inc index f751e341f..b06cf5b72 100644 --- a/techlibs/intel/Makefile.inc +++ b/techlibs/intel/Makefile.inc @@ -5,9 +5,10 @@ $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/m9k_bb.v)) $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/altpll_bb.v)) $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_m9k.txt)) $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_map_m9k.v)) +$(eval $(call add_share_file,share/intel/common,techlibs/intel/common/ff_map.v)) # Add the cell models and mappings for the VQM backend -families := max10 arria10gx cyclonev cyclone10lp cycloneiv cycloneive +families := max10 cyclone10lp cycloneiv cycloneive $(foreach family,$(families), $(eval $(call add_share_file,share/intel/$(family),techlibs/intel/$(family)/cells_sim.v))) $(foreach family,$(families), $(eval $(call add_share_file,share/intel/$(family),techlibs/intel/$(family)/cells_map.v))) #$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/arith_map.v)) diff --git a/techlibs/intel/arria10gx/cells_arith.v b/techlibs/intel/arria10gx/cells_arith.v deleted file mode 100644 index 6a52a0f95..000000000 --- a/techlibs/intel/arria10gx/cells_arith.v +++ /dev/null @@ -1,71 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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. - * - */ - -// NOTE: This is still WIP. -(* techmap_celltype = "$alu" *) -module _80_altera_a10gx_alu (A, B, CI, BI, X, Y, CO); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - (* force_downto *) - input [A_WIDTH-1:0] A; - (* force_downto *) - input [B_WIDTH-1:0] B; - (* force_downto *) - output [Y_WIDTH-1:0] X, Y; - - input CI, BI; - //output [Y_WIDTH-1:0] CO; - output CO; - - wire _TECHMAP_FAIL_ = Y_WIDTH <= 4; - - (* force_downto *) - wire [Y_WIDTH-1:0] A_buf, B_buf; - \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); - \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - - (* force_downto *) - wire [Y_WIDTH-1:0] AA = A_buf; - (* force_downto *) - wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; - //wire [Y_WIDTH:0] C = {CO, CI}; - wire [Y_WIDTH+1:0] COx; - wire [Y_WIDTH+1:0] C = {COx, CI}; - - /* Start implementation */ - (* keep *) fiftyfivenm_lcell_comb #(.lut_mask(16'b0000_0000_1010_1010), .sum_lutc_input("cin")) carry_start (.cout(COx[0]), .dataa(C[0]), .datab(1'b1), .datac(1'b1), .datad(1'b1)); - - genvar i; - generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice - if(i==Y_WIDTH-1) begin - (* keep *) fiftyfivenm_lcell_comb #(.lut_mask(16'b1111_0000_1110_0000), .sum_lutc_input("cin")) carry_end (.combout(COx[Y_WIDTH]), .dataa(1'b1), .datab(1'b1), .datac(1'b1), .datad(1'b1), .cin(C[Y_WIDTH])); - assign CO = COx[Y_WIDTH]; - end - else - fiftyfivenm_lcell_comb #(.lut_mask(16'b1001_0110_1110_1000), .sum_lutc_input("cin")) arith_cell (.combout(Y[i]), .cout(COx[i+1]), .dataa(AA[i]), .datab(BB[i]), .datac(1'b1), .datad(1'b1), .cin(C[i+1])); - end: slice - endgenerate - /* End implementation */ - assign X = AA ^ BB; - -endmodule diff --git a/techlibs/intel/arria10gx/cells_map.v b/techlibs/intel/arria10gx/cells_map.v deleted file mode 100644 index 83f5881da..000000000 --- a/techlibs/intel/arria10gx/cells_map.v +++ /dev/null @@ -1,54 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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. - * - */ -// Input buffer map -module \$__inpad (input I, output O); - twentynm_io_ibuf _TECHMAP_REPLACE_ (.o(O), .i(I), .ibar(1'b0)); -endmodule - -// Output buffer map -module \$__outpad (input I, output O); - twentynm_io_obuf _TECHMAP_REPLACE_ (.o(O), .i(I), .oe(1'b1)); -endmodule - -// LUT Map -module \$lut (A, Y); - parameter WIDTH = 0; - parameter LUT = 0; - (* force_downto *) - input [WIDTH-1:0] A; - output Y; - generate - if (WIDTH == 1) begin - assign Y = ~A[0]; // Not need to spend 1 logic cell for such an easy function - end else - if (WIDTH == 2) begin - twentynm_lcell_comb #(.lut_mask({16{LUT}}), .shared_arith("off"), .extended_lut("off")) - _TECHMAP_REPLACE_ (.combout(Y), .dataa(A[0]), .datab(A[1]), .datac(1'b1),.datad(1'b1), .datae(1'b1), .dataf(1'b1), .datag(1'b1)); - end /*else - if(WIDTH == 3) begin - fiftyfivenm_lcell_comb #(.lut_mask({2{LUT}}), .sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.combout(Y), .dataa(A[0]), .datab(A[1]), .datac(A[2]),.datad(1'b1)); - end else - if(WIDTH == 4) begin - fiftyfivenm_lcell_comb #(.lut_mask(LUT), .sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.combout(Y), .dataa(A[0]), .datab(A[1]), .datac(A[2]),.datad(A[3])); - end*/ else - wire _TECHMAP_FAIL_ = 1; - endgenerate -endmodule // - - diff --git a/techlibs/intel/arria10gx/cells_sim.v b/techlibs/intel/arria10gx/cells_sim.v deleted file mode 100644 index e892b377e..000000000 --- a/techlibs/intel/arria10gx/cells_sim.v +++ /dev/null @@ -1,59 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -module VCC (output V); - assign V = 1'b1; -endmodule // VCC - -module GND (output G); - assign G = 1'b0; -endmodule // GND - -/* Altera Arria 10 GX devices Input Buffer Primitive */ -module twentynm_io_ibuf (output o, input i, input ibar); - assign ibar = ibar; - assign o = i; -endmodule // twentynm_io_ibuf - -/* Altera Arria 10 GX devices Output Buffer Primitive */ -module twentynm_io_obuf (output o, input i, input oe); - assign o = i; - assign oe = oe; -endmodule // twentynm_io_obuf - -/* Altera Arria 10 GX LUT Primitive */ -module twentynm_lcell_comb (output combout, cout, sumout, - input dataa, datab, datac, datad, - input datae, dataf, datag, cin, - input sharein); - -parameter lut_mask = 64'hFFFFFFFFFFFFFFFF; -parameter dont_touch = "off"; -parameter lpm_type = "twentynm_lcell_comb"; -parameter shared_arith = "off"; -parameter extended_lut = "off"; - -// TODO: This is still WIP -initial begin - $display("Simulation model is still under investigation\n"); -end - -endmodule // twentynm_lcell_comb - - - diff --git a/techlibs/intel/common/ff_map.v b/techlibs/intel/common/ff_map.v new file mode 100644 index 000000000..e3f92adbb --- /dev/null +++ b/techlibs/intel/common/ff_map.v @@ -0,0 +1,11 @@ +// Async Active Low Reset DFF +module \$_DFFE_PN0P_ (input D, C, R, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) begin + dffeas #(.is_wysiwyg("TRUE"), .power_up("high")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(E), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); + end else begin + dffeas #(.is_wysiwyg("TRUE"), .power_up("low")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(E), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); + end + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule diff --git a/techlibs/intel/common/m9k_bb.v b/techlibs/intel/common/m9k_bb.v index b18a752f5..4bb230642 100644 --- a/techlibs/intel/common/m9k_bb.v +++ b/techlibs/intel/common/m9k_bb.v @@ -32,7 +32,7 @@ module altsyncram(data_a, address_a, wren_a, rden_a, q_a, data_b, address_b, wr parameter outdata_reg_a = "UNREGISTERED"; parameter operation_mode = "SINGLE_PORT"; parameter intended_device_family = "MAX 10 FPGA"; - parameter outdata_reg_a = "UNREGISTERED"; + parameter outdata_reg_b = "UNREGISTERED"; parameter lpm_type = "altsyncram"; parameter init_type = "unused"; parameter ram_block_type = "AUTO"; diff --git a/techlibs/intel/cyclone10lp/cells_map.v b/techlibs/intel/cyclone10lp/cells_map.v index 2a80ea678..22907b144 100644 --- a/techlibs/intel/cyclone10lp/cells_map.v +++ b/techlibs/intel/cyclone10lp/cells_map.v @@ -19,41 +19,6 @@ // > c60k28 (Viacheslav, VT) [at] yandex [dot] com // > Intel FPGA technology mapping. User must first simulate the generated \ // > netlist before going to test it on board. -// > Changelog: 1) The missing power_up parameter in the techmap introduces a problem in Quartus mapper. Fixed. - -// Normal mode DFF negedge clk, negedge reset -module \$_DFF_N_ (input D, C, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule -// Normal mode DFF -module \$_DFF_P_ (input D, C, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule - -// Async Active Low Reset DFF -module \$_DFF_PN0_ (input D, C, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up("power_up")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule -// Async Active High Reset DFF -module \$_DFF_PP0_ (input D, C, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - wire R_i = ~ R; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R_i), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule - -module \$__DFFE_PP0 (input D, C, E, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - wire E_i = ~ E; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(E_i), .sload(1'b0)); -endmodule // Input buffer map module \$__inpad (input I, output O); diff --git a/techlibs/intel/cycloneiv/cells_map.v b/techlibs/intel/cycloneiv/cells_map.v index 9d8a5a2b7..41afd94be 100644 --- a/techlibs/intel/cycloneiv/cells_map.v +++ b/techlibs/intel/cycloneiv/cells_map.v @@ -19,41 +19,6 @@ // > c60k28 (Viacheslav, VT) [at] yandex [dot] com // > Intel FPGA technology mapping. User must first simulate the generated \ // > netlist before going to test it on board. -// > Changelog: 1) The missing power_up parameter in the techmap introduces a problem in Quartus mapper. Fixed. - -// Normal mode DFF negedge clk, negedge reset -module \$_DFF_N_ (input D, C, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule -// Normal mode DFF -module \$_DFF_P_ (input D, C, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule - -// Async Active Low Reset DFF -module \$_DFF_PN0_ (input D, C, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up("power_up")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule -// Async Active High Reset DFF -module \$_DFF_PP0_ (input D, C, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - wire R_i = ~ R; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R_i), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule - -module \$__DFFE_PP0 (input D, C, E, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - wire E_i = ~ E; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(E_i), .sload(1'b0)); -endmodule // Input buffer map module \$__inpad (input I, output O); diff --git a/techlibs/intel/cycloneive/cells_map.v b/techlibs/intel/cycloneive/cells_map.v index fead2837b..6d7f36ec5 100644 --- a/techlibs/intel/cycloneive/cells_map.v +++ b/techlibs/intel/cycloneive/cells_map.v @@ -19,41 +19,6 @@ // > c60k28 (Viacheslav, VT) [at] yandex [dot] com // > Intel FPGA technology mapping. User must first simulate the generated \ // > netlist before going to test it on board. -// > Changelog: 1) The missing power_up parameter in the techmap introduces a problem in Quartus mapper. Fixed. - -// Normal mode DFF negedge clk, negedge reset -module \$_DFF_N_ (input D, C, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule -// Normal mode DFF -module \$_DFF_P_ (input D, C, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule - -// Async Active Low Reset DFF -module \$_DFF_PN0_ (input D, C, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up("power_up")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule -// Async Active High Reset DFF -module \$_DFF_PP0_ (input D, C, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - wire R_i = ~ R; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R_i), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule - -module \$__DFFE_PP0 (input D, C, E, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - wire E_i = ~ E; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(E_i), .sload(1'b0)); -endmodule // Input buffer map module \$__inpad (input I, output O); diff --git a/techlibs/intel/cyclonev/cells_arith.v b/techlibs/intel/cyclonev/cells_arith.v deleted file mode 100644 index 6a52a0f95..000000000 --- a/techlibs/intel/cyclonev/cells_arith.v +++ /dev/null @@ -1,71 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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. - * - */ - -// NOTE: This is still WIP. -(* techmap_celltype = "$alu" *) -module _80_altera_a10gx_alu (A, B, CI, BI, X, Y, CO); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - (* force_downto *) - input [A_WIDTH-1:0] A; - (* force_downto *) - input [B_WIDTH-1:0] B; - (* force_downto *) - output [Y_WIDTH-1:0] X, Y; - - input CI, BI; - //output [Y_WIDTH-1:0] CO; - output CO; - - wire _TECHMAP_FAIL_ = Y_WIDTH <= 4; - - (* force_downto *) - wire [Y_WIDTH-1:0] A_buf, B_buf; - \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); - \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - - (* force_downto *) - wire [Y_WIDTH-1:0] AA = A_buf; - (* force_downto *) - wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; - //wire [Y_WIDTH:0] C = {CO, CI}; - wire [Y_WIDTH+1:0] COx; - wire [Y_WIDTH+1:0] C = {COx, CI}; - - /* Start implementation */ - (* keep *) fiftyfivenm_lcell_comb #(.lut_mask(16'b0000_0000_1010_1010), .sum_lutc_input("cin")) carry_start (.cout(COx[0]), .dataa(C[0]), .datab(1'b1), .datac(1'b1), .datad(1'b1)); - - genvar i; - generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice - if(i==Y_WIDTH-1) begin - (* keep *) fiftyfivenm_lcell_comb #(.lut_mask(16'b1111_0000_1110_0000), .sum_lutc_input("cin")) carry_end (.combout(COx[Y_WIDTH]), .dataa(1'b1), .datab(1'b1), .datac(1'b1), .datad(1'b1), .cin(C[Y_WIDTH])); - assign CO = COx[Y_WIDTH]; - end - else - fiftyfivenm_lcell_comb #(.lut_mask(16'b1001_0110_1110_1000), .sum_lutc_input("cin")) arith_cell (.combout(Y[i]), .cout(COx[i+1]), .dataa(AA[i]), .datab(BB[i]), .datac(1'b1), .datad(1'b1), .cin(C[i+1])); - end: slice - endgenerate - /* End implementation */ - assign X = AA ^ BB; - -endmodule diff --git a/techlibs/intel/cyclonev/cells_map.v b/techlibs/intel/cyclonev/cells_map.v deleted file mode 100644 index eb4cd54d1..000000000 --- a/techlibs/intel/cyclonev/cells_map.v +++ /dev/null @@ -1,163 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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. - * - */ -// > c60k28 (Viacheslav, VT) [at] yandex [dot] com -// > Intel FPGA technology mapping. User must first simulate the generated \ -// > netlist before going to test it on board. -// > Changelog: 1) The missing power_up parameter in the techmap introduces a problem in Quartus mapper. Fixed. -// 2) Cyclone V 7-input LUT function was wrong implemented. Removed abc option to map this function \ -// and added the explanation in this file instead. Such function needs to be implemented. - -// Normal mode DFF negedge clk, negedge reset -module \$_DFF_N_ (input D, C, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule -// Normal mode DFF -module \$_DFF_P_ (input D, C, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule - -// Async Active Low Reset DFF -module \$_DFF_PN0_ (input D, C, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up("power_up")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule -// Async Active High Reset DFF -module \$_DFF_PP0_ (input D, C, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - wire R_i = ~ R; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R_i), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule - -module \$__DFFE_PP0 (input D, C, E, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - wire E_i = ~ E; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(E_i), .sload(1'b0)); -endmodule - -// Input buffer map -module \$__inpad (input I, output O); - cyclonev_io_ibuf _TECHMAP_REPLACE_ (.o(O), .i(I), .ibar(1'b0)); -endmodule - -// Output buffer map -module \$__outpad (input I, output O); - cyclonev_io_obuf _TECHMAP_REPLACE_ (.o(O), .i(I), .oe(1'b1)); -endmodule - -// LUT Map -module \$lut (A, Y); - parameter WIDTH = 0; - parameter LUT = 0; - (* force_downto *) - input [WIDTH-1:0] A; - output Y; - wire VCC; - wire GND; - assign {VCC,GND} = {1'b1,1'b0}; - - generate - if (WIDTH == 1) begin - assign Y = ~A[0]; // Not need to spend 1 logic cell for such an easy function - end - else - if (WIDTH == 2) begin - cyclonev_lcell_comb #(.lut_mask({16{LUT}}), .shared_arith("off"), .extended_lut("off")) - _TECHMAP_REPLACE_ - (.combout(Y), - .dataa(A[0]), - .datab(A[1]), - .datac(VCC), - .datad(VCC), - .datae(VCC), - .dataf(VCC), - .datag(VCC)); - end - else - if(WIDTH == 3) begin - cyclonev_lcell_comb #(.lut_mask({8{LUT}}), .shared_arith("off"), .extended_lut("off")) - _TECHMAP_REPLACE_ - (.combout(Y), - .dataa(A[0]), - .datab(A[1]), - .datac(A[2]), - .datad(VCC), - .datae(VCC), - .dataf(VCC), - .datag(VCC)); - end - else - if(WIDTH == 4) begin - cyclonev_lcell_comb #(.lut_mask({4{LUT}}), .shared_arith("off"), .extended_lut("off")) - _TECHMAP_REPLACE_ - (.combout(Y), - .dataa(A[0]), - .datab(A[1]), - .datac(A[2]), - .datad(A[3]), - .datae(VCC), - .dataf(VCC), - .datag(VCC)); - end - else - if(WIDTH == 5) begin - cyclonev_lcell_comb #(.lut_mask({2{LUT}}), .shared_arith("off"), .extended_lut("off")) - _TECHMAP_REPLACE_ - (.combout(Y), - .dataa(A[0]), - .datab(A[1]), - .datac(A[2]), - .datad(A[3]), - .datae(A[4]), - .dataf(VCC), - .datag(VCC)); - end - else - if(WIDTH == 6) begin - cyclonev_lcell_comb #(.lut_mask(LUT), .shared_arith("off"), .extended_lut("off")) - _TECHMAP_REPLACE_ - (.combout(Y), - .dataa(A[0]), - .datab(A[1]), - .datac(A[2]), - .datad(A[3]), - .datae(A[4]), - .dataf(A[5]), - .datag(VCC)); - end - /*else - if(WIDTH == 7) begin - TODO: There's not a just 7-input function on Cyclone V, see the following note: - **Extended LUT Mode** - Use extended LUT mode to implement a specific set of 7-input functions. The set must - be a 2-to-1 multiplexer fed by two arbitrary 5-input functions sharing four inputs. - [source](Device Interfaces and Integration Basics for Cyclone V Devices). - end*/ - else - wire _TECHMAP_FAIL_ = 1; - endgenerate -endmodule // lut - - diff --git a/techlibs/intel/max10/cells_map.v b/techlibs/intel/max10/cells_map.v index 6a4072049..8f198daef 100644 --- a/techlibs/intel/max10/cells_map.v +++ b/techlibs/intel/max10/cells_map.v @@ -19,41 +19,6 @@ // > c60k28 (Viacheslav, VT) [at] yandex [dot] com // > Intel FPGA technology mapping. User must first simulate the generated \ // > netlist before going to test it on board. -// > Changelog: 1) The missing power_up parameter in the techmap introduces a problem in Quartus mapper. Fixed. - -// Normal mode DFF negedge clk, negedge reset -module \$_DFF_N_ (input D, C, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule -// Normal mode DFF -module \$_DFF_P_ (input D, C, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(1'b1), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule - -// Async Active Low Reset DFF -module \$_DFF_PN0_ (input D, C, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up("power_up")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule -// Async Active High Reset DFF -module \$_DFF_PP0_ (input D, C, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - wire R_i = ~ R; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R_i), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(1'b0), .sload(1'b0)); -endmodule - -module \$__DFFE_PP0 (input D, C, E, R, output Q); - parameter WYSIWYG="TRUE"; - parameter power_up=1'bx; - wire E_i = ~ E; - dffeas #(.is_wysiwyg(WYSIWYG), .power_up(power_up)) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .clrn(R), .prn(1'b1), .ena(1'b1), .asdata(1'b0), .aload(1'b0), .sclr(E_i), .sload(1'b0)); -endmodule // Input buffer map module \$__inpad (input I, output O); diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index 8601ebb37..a513528f7 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -28,7 +28,7 @@ PRIVATE_NAMESPACE_BEGIN struct SynthIntelPass : public ScriptPass { SynthIntelPass() : ScriptPass("synth_intel", "synthesis for Intel (Altera) FPGAs.") { experimental(); } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -36,11 +36,11 @@ struct SynthIntelPass : public ScriptPass { log("\n"); log("This command runs synthesis for Intel FPGAs.\n"); log("\n"); - log(" -family <max10 | arria10gx | cyclone10lp | cyclonev | cycloneiv | cycloneive>\n"); + log(" -family <max10 | cyclone10lp | cycloneiv | cycloneive>\n"); log(" generate the synthesis netlist for the specified family.\n"); log(" MAX10 is the default target if no family argument specified.\n"); log(" For Cyclone IV GX devices, use cycloneiv argument; for Cyclone IV E, use cycloneive.\n"); - log(" Cyclone V and Arria 10 GX devices are experimental.\n"); + log(" For Cyclone V and Cyclone 10 GX, use the synth_intel_alm backend instead.\n"); log("\n"); log(" -top <module>\n"); log(" use the specified module as top module (default='top')\n"); @@ -81,7 +81,7 @@ struct SynthIntelPass : public ScriptPass { string top_opt, family_opt, vout_file, blif_file; bool retime, flatten, nobram, iopads; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; family_opt = "max10"; @@ -93,7 +93,7 @@ struct SynthIntelPass : public ScriptPass { iopads = false; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -147,9 +147,11 @@ struct SynthIntelPass : public ScriptPass { if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); + + if (family_opt == "cyclonev") + log_cmd_error("Cyclone V synthesis has been moved to synth_intel_alm.\n"); + if (family_opt != "max10" && - family_opt != "arria10gx" && - family_opt != "cyclonev" && family_opt != "cycloneiv" && family_opt != "cycloneive" && family_opt != "cyclone10lp") @@ -163,7 +165,7 @@ struct SynthIntelPass : public ScriptPass { log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("begin")) { if (check_label("family")) @@ -202,8 +204,6 @@ struct SynthIntelPass : public ScriptPass { run("opt -fast -mux_undef -undriven -fine -full"); run("memory_map"); run("opt -undriven -fine"); - run("dff2dffe -direct-match $_DFF_*"); - run("opt -fine"); run("techmap -map +/techmap.v"); run("opt -full"); run("clean -purge"); @@ -212,11 +212,13 @@ struct SynthIntelPass : public ScriptPass { run("abc -markgroups -dff -D 1", "(only if -retime)"); } + if (check_label("map_ffs")) { + run("dfflegalize -cell $_DFFE_PN0P_ 01"); + run("techmap -map +/intel/common/ff_map.v"); + } + if (check_label("map_luts")) { - if (family_opt == "arria10gx" || family_opt == "cyclonev") - run("abc -luts 2:2,3,6:5" + string(retime ? " -dff" : "")); - else - run("abc -lut 4" + string(retime ? " -dff" : "")); + run("abc -lut 4" + string(retime ? " -dff" : "")); run("clean"); } @@ -224,7 +226,6 @@ struct SynthIntelPass : public ScriptPass { if (iopads || help_mode) run("iopadmap -bits -outpad $__outpad I:O -inpad $__inpad O:I", "(if -iopads)"); run(stringf("techmap -map +/intel/%s/cells_map.v", family_opt.c_str())); - run("dffinit -highlow -ff dffeas q power_up"); run("clean -purge"); } diff --git a/techlibs/intel_alm/Makefile.inc b/techlibs/intel_alm/Makefile.inc index ed6c4510b..da88762c4 100644 --- a/techlibs/intel_alm/Makefile.inc +++ b/techlibs/intel_alm/Makefile.inc @@ -2,17 +2,24 @@ OBJS += techlibs/intel_alm/synth_intel_alm.o # Techmap +$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/abc9_map.v)) +$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/abc9_unmap.v)) +$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/abc9_model.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/alm_map.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/alm_sim.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/arith_alm_map.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dff_map.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dff_sim.v)) +$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dsp_sim.v)) +$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dsp_map.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/mem_sim.v)) +$(eval $(call add_share_file,share/intel_alm/cyclonev,techlibs/intel_alm/cyclonev/cells_sim.v)) + # RAM -bramtypes := m10k m20k -$(foreach bramtype, $(bramtypes), $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_$(bramtype).txt))) -$(foreach bramtype, $(bramtypes), $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_$(bramtype)_map.v))) +$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m10k.txt)) +$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m20k.txt)) +$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m20k_map.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/lutram_mlab.txt)) # Miscellaneous diff --git a/techlibs/intel_alm/common/abc9_map.v b/techlibs/intel_alm/common/abc9_map.v new file mode 100644 index 000000000..9d11bb240 --- /dev/null +++ b/techlibs/intel_alm/common/abc9_map.v @@ -0,0 +1,18 @@ +// This file exists to map purely-synchronous flops to ABC9 flops, while +// mapping flops with asynchronous-clear as boxes, this is because ABC9 +// doesn't support asynchronous-clear flops in sequential synthesis. + +module MISTRAL_FF( + input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA, + output reg Q +); + +parameter _TECHMAP_CONSTMSK_ACLR_ = 1'b0; + +// If the async-clear is constant, we assume it's disabled. +if (_TECHMAP_CONSTMSK_ACLR_ != 1'b0) + $__MISTRAL_FF_SYNCONLY _TECHMAP_REPLACE_ (.DATAIN(DATAIN), .CLK(CLK), .ENA(ENA), .SCLR(SCLR), .SLOAD(SLOAD), .SDATA(SDATA), .Q(Q)); +else + wire _TECHMAP_FAIL_ = 1; + +endmodule diff --git a/techlibs/intel_alm/common/abc9_model.v b/techlibs/intel_alm/common/abc9_model.v new file mode 100644 index 000000000..8f06d3835 --- /dev/null +++ b/techlibs/intel_alm/common/abc9_model.v @@ -0,0 +1,10 @@ +// This is a purely-synchronous flop, that ABC9 can use for sequential synthesis. +(* abc9_flop, lib_whitebox *) +module $__MISTRAL_FF_SYNCONLY ( + input DATAIN, CLK, ENA, SCLR, SLOAD, SDATA, + output reg Q +); + +MISTRAL_FF ff (.DATAIN(DATAIN), .CLK(CLK), .ENA(ENA), .ACLR(1'b1), .SCLR(SCLR), .SLOAD(SLOAD), .SDATA(SDATA), .Q(Q)); + +endmodule diff --git a/techlibs/intel_alm/common/abc9_unmap.v b/techlibs/intel_alm/common/abc9_unmap.v new file mode 100644 index 000000000..4b28866a3 --- /dev/null +++ b/techlibs/intel_alm/common/abc9_unmap.v @@ -0,0 +1,11 @@ +// After performing sequential synthesis, map the synchronous flops back to +// standard MISTRAL_FF flops. + +module $__MISTRAL_FF_SYNCONLY ( + input DATAIN, CLK, ENA, SCLR, SLOAD, SDATA, + output reg Q +); + +MISTRAL_FF _TECHMAP_REPLACE_ (.DATAIN(DATAIN), .CLK(CLK), .ACLR(1'b1), .ENA(ENA), .SCLR(SCLR), .SLOAD(SLOAD), .SDATA(SDATA), .Q(Q)); + +endmodule diff --git a/techlibs/intel_alm/common/alm_sim.v b/techlibs/intel_alm/common/alm_sim.v index 979c51132..906a95b0b 100644 --- a/techlibs/intel_alm/common/alm_sim.v +++ b/techlibs/intel_alm/common/alm_sim.v @@ -69,6 +69,14 @@ `default_nettype none +// Cyclone V LUT output timings (picoseconds): +// +// CARRY A B C D E F G +// COMBOUT - 605 583 510 512 - 97 400 (LUT6) +// COMBOUT - 602 583 457 510 302 93 483 (LUT7) +// SUMOUT 368 1342 1323 887 927 - 785 - +// CARRYOUT 71 1082 1062 866 813 - 1198 - + (* abc9_lut=2, lib_whitebox *) module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q); @@ -76,12 +84,12 @@ parameter [63:0] LUT = 64'h0000_0000_0000_0000; `ifdef cyclonev specify - (A => Q) = 602; - (B => Q) = 584; + (A => Q) = 605; + (B => Q) = 583; (C => Q) = 510; - (D => Q) = 510; - (E => Q) = 339; - (F => Q) = 94; + (D => Q) = 512; + (E => Q) = 400; + (F => Q) = 97; endspecify `endif `ifdef cyclone10gx @@ -107,11 +115,11 @@ parameter [31:0] LUT = 32'h0000_0000; `ifdef cyclonev specify - (A => Q) = 584; + (A => Q) = 583; (B => Q) = 510; - (C => Q) = 510; - (D => Q) = 339; - (E => Q) = 94; + (C => Q) = 512; + (D => Q) = 400; + (E => Q) = 97; endspecify `endif `ifdef cyclone10gx @@ -137,9 +145,9 @@ parameter [15:0] LUT = 16'h0000; `ifdef cyclonev specify (A => Q) = 510; - (B => Q) = 510; - (C => Q) = 339; - (D => Q) = 94; + (B => Q) = 512; + (C => Q) = 400; + (D => Q) = 97; endspecify `endif `ifdef cyclone10gx @@ -164,8 +172,8 @@ parameter [7:0] LUT = 8'h00; `ifdef cyclonev specify (A => Q) = 510; - (B => Q) = 339; - (C => Q) = 94; + (B => Q) = 400; + (C => Q) = 97; endspecify `endif `ifdef cyclone10gx @@ -188,8 +196,8 @@ parameter [3:0] LUT = 4'h0; `ifdef cyclonev specify - (A => Q) = 339; - (B => Q) = 94; + (A => Q) = 400; + (B => Q) = 97; endspecify `endif `ifdef cyclone10gx @@ -209,7 +217,7 @@ module MISTRAL_NOT(input A, output Q); `ifdef cyclonev specify - (A => Q) = 94; + (A => Q) = 97; endspecify `endif `ifdef cyclone10gx @@ -230,31 +238,33 @@ parameter LUT1 = 16'h0000; `ifdef cyclonev specify - (A => SO) = 1283; - (B => SO) = 1167; - (C => SO) = 866; - (D0 => SO) = 756; - (D1 => SO) = 756; - (CI => SO) = 355; - (A => CO) = 950; - (B => CO) = 1039; - (C => CO) = 820; - (D0 => CO) = 1006; - (D1 => CO) = 1006; - (CI => CO) = 23; + (A => SO) = 1342; + (B => SO) = 1323; + (C => SO) = 927; + (D0 => SO) = 887; + (D1 => SO) = 785; + (CI => SO) = 368; + + (A => CO) = 1082; + (B => CO) = 1062; + (C => CO) = 813; + (D0 => CO) = 866; + (D1 => CO) = 1198; + (CI => CO) = 36; // Divided by 2 to account for there being two ALUT_ARITHs in an ALM) endspecify `endif `ifdef cyclone10gx specify - (A => SO) = 644; - (B => SO) = 477; - (C => SO) = 416; + (A => SO) = 644; + (B => SO) = 477; + (C => SO) = 416; (D0 => SO) = 380; (D1 => SO) = 431; (CI => SO) = 276; - (A => CO) = 525; - (B => CO) = 433; - (C => CO) = 712; + + (A => CO) = 525; + (B => CO) = 433; + (C => CO) = 712; (D0 => CO) = 653; (D1 => CO) = 593; (CI => CO) = 16; diff --git a/techlibs/intel_alm/common/bram_m10k.txt b/techlibs/intel_alm/common/bram_m10k.txt index 837e3a330..e9355fe2c 100644 --- a/techlibs/intel_alm/common/bram_m10k.txt +++ b/techlibs/intel_alm/common/bram_m10k.txt @@ -1,4 +1,4 @@ -bram __MISTRAL_M10K_SDP +bram MISTRAL_M10K init 0 # TODO: Re-enable when I figure out how BRAM init works abits 13 @D8192x1 dbits 1 @D8192x1 @@ -27,7 +27,7 @@ bram __MISTRAL_M10K_SDP endbram -match __MISTRAL_M10K_SDP +match MISTRAL_M10K min efficiency 5 make_transp endmatch diff --git a/techlibs/intel_alm/common/bram_m10k_map.v b/techlibs/intel_alm/common/bram_m10k_map.v deleted file mode 100644 index 061463c3e..000000000 --- a/techlibs/intel_alm/common/bram_m10k_map.v +++ /dev/null @@ -1,31 +0,0 @@ -module __MISTRAL_M10K_SDP(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
-
-parameter CFG_ABITS = 10;
-parameter CFG_DBITS = 10;
-parameter CFG_ENABLE_A = 1;
-parameter CFG_ENABLE_B = 1;
-
-input CLK1;
-input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
-input [CFG_DBITS-1:0] A1DATA;
-output [CFG_DBITS-1:0] B1DATA;
-input [CFG_ENABLE_A-1:0] A1EN, B1EN;
-
-altsyncram #(
- .operation_mode("dual_port"),
- .ram_block_type("m10k"),
- .widthad_a(CFG_ABITS),
- .width_a(CFG_DBITS),
- .widthad_b(CFG_ABITS),
- .width_b(CFG_DBITS),
-) _TECHMAP_REPLACE_ (
- .address_a(A1ADDR),
- .data_a(A1DATA),
- .wren_a(A1EN),
- .address_b(B1ADDR),
- .q_b(B1DATA),
- .clock0(CLK1),
- .clock1(CLK1)
-);
-
-endmodule
diff --git a/techlibs/intel_alm/common/dff_map.v b/techlibs/intel_alm/common/dff_map.v index 962be670c..1a4b5d65a 100644 --- a/techlibs/intel_alm/common/dff_map.v +++ b/techlibs/intel_alm/common/dff_map.v @@ -1,124 +1,13 @@ `default_nettype none -// D flip-flops -module \$_DFF_P_ (input D, C, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b0; -if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin +// D flip-flop with async reset and enable +module \$_DFFE_PN0P_ (input D, C, R, E, output Q); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); -end else $error("Cannot implement a flip-flop that initialises to one"); + MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(R), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); endmodule -module \$_DFF_N_ (input D, C, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b0; -if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin +// D flip-flop with sync reset and enable (enable has priority) +module \$_SDFFCE_PP0P_ (input D, C, R, E, output Q); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); -end else $error("Cannot implement a flip-flop that initialises to one"); -endmodule - -// D flip-flops with reset -module \$_DFF_PP0_ (input D, C, R, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b0; -if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); -end else $error("Cannot implement a flip-flop with reset that initialises to one"); -endmodule - -module \$_DFF_PN0_ (input D, C, R, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b0; -if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); -end else $error("Cannot implement a flip-flop with reset that initialises to one"); -endmodule - -module \$_DFF_NP0_ (input D, C, R, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b0; -if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); -end else $error("Cannot implement a flip-flop with reset that initialises to one"); -endmodule - -module \$_DFF_NN0_ (input D, C, R, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b0; -if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); -end else $error("Cannot implement a flip-flop with reset that initialises to one"); -endmodule - -// D flip-flops with set -module \$_DFF_PP1_ (input D, C, R, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b1; -if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - wire Q_tmp; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp)); - assign Q = ~Q_tmp; -end else $error("Cannot implement a flip-flop with set that initialises to zero"); -endmodule - -module \$_DFF_PN1_ (input D, C, R, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b1; -if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - wire Q_tmp; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp)); -end else $error("Cannot implement a flip-flop with set that initialises to zero"); -endmodule - -module \$_DFF_NP1_ (input D, C, R, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b1; -if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - wire Q_tmp; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(~C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp)); - assign Q = ~Q_tmp; -end else $error("Cannot implement a flip-flop with set that initialises to zero"); -endmodule - -module \$_DFF_NN1_ (input D, C, R, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b1; -if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - wire Q_tmp; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(~C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp)); - assign Q = ~Q_tmp; -end else $error("Cannot implement a flip-flop with set that initialises to zero"); -endmodule - -// D flip-flops with clock enable -module \$_DFFE_PP_ (input D, C, E, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b0; -if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); -end else $error("Cannot implement a flip-flop with enable that initialises to one"); -endmodule - -module \$_DFFE_PN_ (input D, C, E, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b0; -if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(~E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); -end else $error("Cannot implement a flip-flop with enable that initialises to one"); -endmodule - -module \$_DFFE_NP_ (input D, C, E, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b0; -if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); -end else $error("Cannot implement a flip-flop with enable that initialises to one"); -endmodule - -module \$_DFFE_NN_ (input D, C, E, output Q); -parameter _TECHMAP_WIREINIT_Q_ = 1'b0; -if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(~E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); -end else $error("Cannot implement a flip-flop with enable that initialises to one"); + MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(E), .SCLR(R), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q)); endmodule diff --git a/techlibs/intel_alm/common/dff_sim.v b/techlibs/intel_alm/common/dff_sim.v index 32444dd46..d2cff0adb 100644 --- a/techlibs/intel_alm/common/dff_sim.v +++ b/techlibs/intel_alm/common/dff_sim.v @@ -53,6 +53,8 @@ // Q: data output // // Note: the DFFEAS primitive is mostly emulated; it does not reflect what the hardware implements. + +(* abc9_box, lib_whitebox *) module MISTRAL_FF( input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA, output reg Q @@ -60,14 +62,34 @@ module MISTRAL_FF( `ifdef cyclonev specify - (posedge CLK => (Q : DATAIN)) = 262; - $setup(DATAIN, posedge CLK, 522); + if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 731; + if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 890; + if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 618; + + $setup(DATAIN, posedge CLK, /* -196 */ 0); + $setup(ENA, posedge CLK, /* -196 */ 0); + $setup(SCLR, posedge CLK, /* -196 */ 0); + $setup(SLOAD, posedge CLK, /* -196 */ 0); + $setup(SDATA, posedge CLK, /* -196 */ 0); + + if (ACLR === 1'b0) (ACLR => Q) = 282; endspecify `endif `ifdef cyclone10gx specify - (posedge CLK => (Q : DATAIN)) = 219; + // TODO (long-term): investigate these numbers. + // It seems relying on the Quartus Timing Analyzer was not the best idea; it's too fiddly. + if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 219; + if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 219; + if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 219; + $setup(DATAIN, posedge CLK, 268); + $setup(ENA, posedge CLK, 268); + $setup(SCLR, posedge CLK, 268); + $setup(SLOAD, posedge CLK, 268); + $setup(SDATA, posedge CLK, 268); + + if (ACLR === 1'b0) (ACLR => Q) = 0; endspecify `endif diff --git a/techlibs/intel_alm/common/dsp_map.v b/techlibs/intel_alm/common/dsp_map.v new file mode 100644 index 000000000..e12e777a4 --- /dev/null +++ b/techlibs/intel_alm/common/dsp_map.v @@ -0,0 +1,51 @@ +`default_nettype none + +module __MUL27X27(A, B, Y); + +parameter A_SIGNED = 1; +parameter B_SIGNED = 1; +parameter A_WIDTH = 27; +parameter B_WIDTH = 27; +parameter Y_WIDTH = 54; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +MISTRAL_MUL27X27 _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y)); + +endmodule + + +module __MUL18X18(A, B, Y); + +parameter A_SIGNED = 1; +parameter B_SIGNED = 1; +parameter A_WIDTH = 18; +parameter B_WIDTH = 18; +parameter Y_WIDTH = 36; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +MISTRAL_MUL18X18 _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y)); + +endmodule + + +module __MUL9X9(A, B, Y); + +parameter A_SIGNED = 1; +parameter B_SIGNED = 1; +parameter A_WIDTH = 9; +parameter B_WIDTH = 9; +parameter Y_WIDTH = 18; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +MISTRAL_MUL9X9 _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y)); + +endmodule diff --git a/techlibs/intel_alm/common/dsp_sim.v b/techlibs/intel_alm/common/dsp_sim.v new file mode 100644 index 000000000..bdb6d18d5 --- /dev/null +++ b/techlibs/intel_alm/common/dsp_sim.v @@ -0,0 +1,83 @@ +(* abc9_box *) +module MISTRAL_MUL27X27(input [26:0] A, input [26:0] B, output [53:0] Y); + +parameter A_SIGNED = 1; +parameter B_SIGNED = 1; + +// TODO: Cyclone 10 GX timings; the below are for Cyclone V +specify + (A *> Y) = 3732; + (B *> Y) = 3928; +endspecify + +wire [53:0] A_, B_; + +if (A_SIGNED) + assign A_ = $signed(A); +else + assign A_ = $unsigned(A); + +if (B_SIGNED) + assign B_ = $signed(B); +else + assign B_ = $unsigned(B); + +assign Y = A_ * B_; + +endmodule + +(* abc9_box *) +module MISTRAL_MUL18X18(input [17:0] A, input [17:0] B, output [35:0] Y); + +parameter A_SIGNED = 1; +parameter B_SIGNED = 1; + +// TODO: Cyclone 10 GX timings; the below are for Cyclone V +specify + (A *> Y) = 3180; + (B *> Y) = 3982; +endspecify + +wire [35:0] A_, B_; + +if (A_SIGNED) + assign A_ = $signed(A); +else + assign A_ = $unsigned(A); + +if (B_SIGNED) + assign B_ = $signed(B); +else + assign B_ = $unsigned(B); + +assign Y = A_ * B_; + +endmodule + +(* abc9_box *) +module MISTRAL_MUL9X9(input [8:0] A, input [8:0] B, output [17:0] Y); + +parameter A_SIGNED = 1; +parameter B_SIGNED = 1; + +// TODO: Cyclone 10 GX timings; the below are for Cyclone V +specify + (A *> Y) = 2818; + (B *> Y) = 3051; +endspecify + +wire [17:0] A_, B_; + +if (A_SIGNED) + assign A_ = $signed(A); +else + assign A_ = $unsigned(A); + +if (B_SIGNED) + assign B_ = $signed(B); +else + assign B_ = $unsigned(B); + +assign Y = A_ * B_; + +endmodule diff --git a/techlibs/intel_alm/common/megafunction_bb.v b/techlibs/intel_alm/common/megafunction_bb.v index c749fa70b..874f293b1 100644 --- a/techlibs/intel_alm/common/megafunction_bb.v +++ b/techlibs/intel_alm/common/megafunction_bb.v @@ -2,6 +2,306 @@ `default_nettype none (* blackbox *) +module altera_pll +#( + parameter reference_clock_frequency = "0 ps", + parameter fractional_vco_multiplier = "false", + parameter pll_type = "General", + parameter pll_subtype = "General", + parameter number_of_clocks = 1, + parameter operation_mode = "internal feedback", + parameter deserialization_factor = 4, + parameter data_rate = 0, + + parameter sim_additional_refclk_cycles_to_lock = 0, + parameter output_clock_frequency0 = "0 ps", + parameter phase_shift0 = "0 ps", + parameter duty_cycle0 = 50, + + parameter output_clock_frequency1 = "0 ps", + parameter phase_shift1 = "0 ps", + parameter duty_cycle1 = 50, + + parameter output_clock_frequency2 = "0 ps", + parameter phase_shift2 = "0 ps", + parameter duty_cycle2 = 50, + + parameter output_clock_frequency3 = "0 ps", + parameter phase_shift3 = "0 ps", + parameter duty_cycle3 = 50, + + parameter output_clock_frequency4 = "0 ps", + parameter phase_shift4 = "0 ps", + parameter duty_cycle4 = 50, + + parameter output_clock_frequency5 = "0 ps", + parameter phase_shift5 = "0 ps", + parameter duty_cycle5 = 50, + + parameter output_clock_frequency6 = "0 ps", + parameter phase_shift6 = "0 ps", + parameter duty_cycle6 = 50, + + parameter output_clock_frequency7 = "0 ps", + parameter phase_shift7 = "0 ps", + parameter duty_cycle7 = 50, + + parameter output_clock_frequency8 = "0 ps", + parameter phase_shift8 = "0 ps", + parameter duty_cycle8 = 50, + + parameter output_clock_frequency9 = "0 ps", + parameter phase_shift9 = "0 ps", + parameter duty_cycle9 = 50, + + + parameter output_clock_frequency10 = "0 ps", + parameter phase_shift10 = "0 ps", + parameter duty_cycle10 = 50, + + parameter output_clock_frequency11 = "0 ps", + parameter phase_shift11 = "0 ps", + parameter duty_cycle11 = 50, + + parameter output_clock_frequency12 = "0 ps", + parameter phase_shift12 = "0 ps", + parameter duty_cycle12 = 50, + + parameter output_clock_frequency13 = "0 ps", + parameter phase_shift13 = "0 ps", + parameter duty_cycle13 = 50, + + parameter output_clock_frequency14 = "0 ps", + parameter phase_shift14 = "0 ps", + parameter duty_cycle14 = 50, + + parameter output_clock_frequency15 = "0 ps", + parameter phase_shift15 = "0 ps", + parameter duty_cycle15 = 50, + + parameter output_clock_frequency16 = "0 ps", + parameter phase_shift16 = "0 ps", + parameter duty_cycle16 = 50, + + parameter output_clock_frequency17 = "0 ps", + parameter phase_shift17 = "0 ps", + parameter duty_cycle17 = 50, + + parameter clock_name_0 = "", + parameter clock_name_1 = "", + parameter clock_name_2 = "", + parameter clock_name_3 = "", + parameter clock_name_4 = "", + parameter clock_name_5 = "", + parameter clock_name_6 = "", + parameter clock_name_7 = "", + parameter clock_name_8 = "", + + parameter clock_name_global_0 = "false", + parameter clock_name_global_1 = "false", + parameter clock_name_global_2 = "false", + parameter clock_name_global_3 = "false", + parameter clock_name_global_4 = "false", + parameter clock_name_global_5 = "false", + parameter clock_name_global_6 = "false", + parameter clock_name_global_7 = "false", + parameter clock_name_global_8 = "false", + + parameter m_cnt_hi_div = 1, + parameter m_cnt_lo_div = 1, + parameter m_cnt_bypass_en = "false", + parameter m_cnt_odd_div_duty_en = "false", + parameter n_cnt_hi_div = 1, + parameter n_cnt_lo_div = 1, + parameter n_cnt_bypass_en = "false", + parameter n_cnt_odd_div_duty_en = "false", + parameter c_cnt_hi_div0 = 1, + parameter c_cnt_lo_div0 = 1, + parameter c_cnt_bypass_en0 = "false", + parameter c_cnt_in_src0 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en0 = "false", + parameter c_cnt_prst0 = 1, + parameter c_cnt_ph_mux_prst0 = 0, + parameter c_cnt_hi_div1 = 1, + parameter c_cnt_lo_div1 = 1, + parameter c_cnt_bypass_en1 = "false", + parameter c_cnt_in_src1 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en1 = "false", + parameter c_cnt_prst1 = 1, + parameter c_cnt_ph_mux_prst1 = 0, + parameter c_cnt_hi_div2 = 1, + parameter c_cnt_lo_div2 = 1, + parameter c_cnt_bypass_en2 = "false", + parameter c_cnt_in_src2 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en2 = "false", + parameter c_cnt_prst2 = 1, + parameter c_cnt_ph_mux_prst2 = 0, + parameter c_cnt_hi_div3 = 1, + parameter c_cnt_lo_div3 = 1, + parameter c_cnt_bypass_en3 = "false", + parameter c_cnt_in_src3 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en3 = "false", + parameter c_cnt_prst3 = 1, + parameter c_cnt_ph_mux_prst3 = 0, + parameter c_cnt_hi_div4 = 1, + parameter c_cnt_lo_div4 = 1, + parameter c_cnt_bypass_en4 = "false", + parameter c_cnt_in_src4 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en4 = "false", + parameter c_cnt_prst4 = 1, + parameter c_cnt_ph_mux_prst4 = 0, + parameter c_cnt_hi_div5 = 1, + parameter c_cnt_lo_div5 = 1, + parameter c_cnt_bypass_en5 = "false", + parameter c_cnt_in_src5 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en5 = "false", + parameter c_cnt_prst5 = 1, + parameter c_cnt_ph_mux_prst5 = 0, + parameter c_cnt_hi_div6 = 1, + parameter c_cnt_lo_div6 = 1, + parameter c_cnt_bypass_en6 = "false", + parameter c_cnt_in_src6 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en6 = "false", + parameter c_cnt_prst6 = 1, + parameter c_cnt_ph_mux_prst6 = 0, + parameter c_cnt_hi_div7 = 1, + parameter c_cnt_lo_div7 = 1, + parameter c_cnt_bypass_en7 = "false", + parameter c_cnt_in_src7 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en7 = "false", + parameter c_cnt_prst7 = 1, + parameter c_cnt_ph_mux_prst7 = 0, + parameter c_cnt_hi_div8 = 1, + parameter c_cnt_lo_div8 = 1, + parameter c_cnt_bypass_en8 = "false", + parameter c_cnt_in_src8 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en8 = "false", + parameter c_cnt_prst8 = 1, + parameter c_cnt_ph_mux_prst8 = 0, + parameter c_cnt_hi_div9 = 1, + parameter c_cnt_lo_div9 = 1, + parameter c_cnt_bypass_en9 = "false", + parameter c_cnt_in_src9 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en9 = "false", + parameter c_cnt_prst9 = 1, + parameter c_cnt_ph_mux_prst9 = 0, + parameter c_cnt_hi_div10 = 1, + parameter c_cnt_lo_div10 = 1, + parameter c_cnt_bypass_en10 = "false", + parameter c_cnt_in_src10 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en10 = "false", + parameter c_cnt_prst10 = 1, + parameter c_cnt_ph_mux_prst10 = 0, + parameter c_cnt_hi_div11 = 1, + parameter c_cnt_lo_div11 = 1, + parameter c_cnt_bypass_en11 = "false", + parameter c_cnt_in_src11 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en11 = "false", + parameter c_cnt_prst11 = 1, + parameter c_cnt_ph_mux_prst11 = 0, + parameter c_cnt_hi_div12 = 1, + parameter c_cnt_lo_div12 = 1, + parameter c_cnt_bypass_en12 = "false", + parameter c_cnt_in_src12 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en12 = "false", + parameter c_cnt_prst12 = 1, + parameter c_cnt_ph_mux_prst12 = 0, + parameter c_cnt_hi_div13 = 1, + parameter c_cnt_lo_div13 = 1, + parameter c_cnt_bypass_en13 = "false", + parameter c_cnt_in_src13 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en13 = "false", + parameter c_cnt_prst13 = 1, + parameter c_cnt_ph_mux_prst13 = 0, + parameter c_cnt_hi_div14 = 1, + parameter c_cnt_lo_div14 = 1, + parameter c_cnt_bypass_en14 = "false", + parameter c_cnt_in_src14 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en14 = "false", + parameter c_cnt_prst14 = 1, + parameter c_cnt_ph_mux_prst14 = 0, + parameter c_cnt_hi_div15 = 1, + parameter c_cnt_lo_div15 = 1, + parameter c_cnt_bypass_en15 = "false", + parameter c_cnt_in_src15 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en15 = "false", + parameter c_cnt_prst15 = 1, + parameter c_cnt_ph_mux_prst15 = 0, + parameter c_cnt_hi_div16 = 1, + parameter c_cnt_lo_div16 = 1, + parameter c_cnt_bypass_en16 = "false", + parameter c_cnt_in_src16 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en16 = "false", + parameter c_cnt_prst16 = 1, + parameter c_cnt_ph_mux_prst16 = 0, + parameter c_cnt_hi_div17 = 1, + parameter c_cnt_lo_div17 = 1, + parameter c_cnt_bypass_en17 = "false", + parameter c_cnt_in_src17 = "ph_mux_clk", + parameter c_cnt_odd_div_duty_en17 = "false", + parameter c_cnt_prst17 = 1, + parameter c_cnt_ph_mux_prst17 = 0, + parameter pll_vco_div = 1, + parameter pll_slf_rst = "false", + parameter pll_bw_sel = "low", + parameter pll_output_clk_frequency = "0 MHz", + parameter pll_cp_current = 0, + parameter pll_bwctrl = 0, + parameter pll_fractional_division = 1, + parameter pll_fractional_cout = 24, + parameter pll_dsm_out_sel = "1st_order", + parameter mimic_fbclk_type = "gclk", + parameter pll_fbclk_mux_1 = "glb", + parameter pll_fbclk_mux_2 = "fb_1", + parameter pll_m_cnt_in_src = "ph_mux_clk", + parameter pll_vcoph_div = 1, + parameter refclk1_frequency = "0 MHz", + parameter pll_clkin_0_src = "clk_0", + parameter pll_clkin_1_src = "clk_0", + parameter pll_clk_loss_sw_en = "false", + parameter pll_auto_clk_sw_en = "false", + parameter pll_manu_clk_sw_en = "false", + parameter pll_clk_sw_dly = 0, + parameter pll_extclk_0_cnt_src = "pll_extclk_cnt_src_vss", + parameter pll_extclk_1_cnt_src = "pll_extclk_cnt_src_vss" +) ( + //input + input refclk, + input refclk1, + input fbclk, + input rst, + input phase_en, + input updn, + input [2:0] num_phase_shifts, + input scanclk, + input [4:0] cntsel, + input [63:0] reconfig_to_pll, + input extswitch, + input adjpllin, + input cclk, + + //output + output [ number_of_clocks -1 : 0] outclk, + output fboutclk, + output locked, + output phase_done, + output [63:0] reconfig_from_pll, + output activeclk, + output [1:0] clkbad, + output [7:0] phout, + output [1:0] lvds_clk, + output [1:0] loaden, + output [1:0] extclk_out, + output [ number_of_clocks -1 : 0] cascade_out, + + //inout + inout zdbfbclk +); + +endmodule + + +(* blackbox *) module altera_std_synchronizer(clk, din, dout, reset_n); parameter depth = 2; @@ -14,6 +314,137 @@ output dout; endmodule (* blackbox *) +module altddio_in ( + datain, // required port, DDR input data + inclock, // required port, input reference clock to sample data by + inclocken, // enable data clock + aset, // asynchronous set + aclr, // asynchronous clear + sset, // synchronous set + sclr, // synchronous clear + dataout_h, // data sampled at the rising edge of inclock + dataout_l // data sampled at the falling edge of inclock +); + +parameter width = 1; +parameter power_up_high = "OFF"; +parameter invert_input_clocks = "OFF"; +parameter intended_device_family = "Stratix"; +parameter lpm_type = "altddio_in"; +parameter lpm_hint = "UNUSED"; + +input [width-1:0] datain; +input inclock; +input inclocken; +input aset; +input aclr; +input sset; +input sclr; + +output [width-1:0] dataout_h; +output [width-1:0] dataout_l; + +endmodule + + +(* blackbox *) +module altddio_out ( + datain_h, + datain_l, + outclock, + outclocken, + aset, + aclr, + sset, + sclr, + oe, + dataout, + oe_out +); + +parameter width = 1; +parameter power_up_high = "OFF"; +parameter oe_reg = "UNUSED"; +parameter extend_oe_disable = "UNUSED"; +parameter intended_device_family = "Stratix"; +parameter invert_output = "OFF"; +parameter lpm_type = "altddio_out"; +parameter lpm_hint = "UNUSED"; + +input [width-1:0] datain_h; +input [width-1:0] datain_l; +input outclock; +input outclocken; +input aset; +input aclr; +input sset; +input sclr; +input oe; + +output [width-1:0] dataout; +output [width-1:0] oe_out; + +endmodule + + +(* blackbox *) +module altddio_bidir ( + datain_h, + datain_l, + inclock, + inclocken, + outclock, + outclocken, + aset, + aclr, + sset, + sclr, + oe, + dataout_h, + dataout_l, + combout, + oe_out, + dqsundelayedout, + padio +); + +// GLOBAL PARAMETER DECLARATION +parameter width = 1; // required parameter +parameter power_up_high = "OFF"; +parameter oe_reg = "UNUSED"; +parameter extend_oe_disable = "UNUSED"; +parameter implement_input_in_lcell = "UNUSED"; +parameter invert_output = "OFF"; +parameter intended_device_family = "Stratix"; +parameter lpm_type = "altddio_bidir"; +parameter lpm_hint = "UNUSED"; + +// INPUT PORT DECLARATION +input [width-1:0] datain_h; +input [width-1:0] datain_l; +input inclock; +input inclocken; +input outclock; +input outclocken; +input aset; +input aclr; +input sset; +input sclr; +input oe; + +// OUTPUT PORT DECLARATION +output [width-1:0] dataout_h; +output [width-1:0] dataout_l; +output [width-1:0] combout; +output [width-1:0] oe_out; +output [width-1:0] dqsundelayedout; +// BIDIRECTIONAL PORT DECLARATION +inout [width-1:0] padio; + +endmodule + + +(* blackbox *) module altiobuf_in(datain, dataout); parameter enable_bus_hold = "FALSE"; @@ -129,3 +560,70 @@ output [data_width-1:0] portbdataout; input ena0, clk0, clk1; endmodule + +(* blackbox *) +module cyclonev_mac(ax, ay, resulta); + +parameter ax_width = 9; +parameter signed_max = "true"; +parameter ay_scan_in_width = 9; +parameter signed_may = "true"; +parameter result_a_width = 18; +parameter operation_mode = "M9x9"; + +input [ax_width-1:0] ax; +input [ay_scan_in_width-1:0] ay; +output [result_a_width-1:0] resulta; + +endmodule + +(* blackbox *) +module cyclone10gx_mac(ax, ay, resulta); + +parameter ax_width = 18; +parameter signed_max = "true"; +parameter ay_scan_in_width = 18; +parameter signed_may = "true"; +parameter result_a_width = 36; +parameter operation_mode = "M18X18_FULL"; + +input [ax_width-1:0] ax; +input [ay_scan_in_width-1:0] ay; +output [result_a_width-1:0] resulta; + +endmodule + +(* blackbox *) +module cyclonev_ram_block(portaaddr, portadatain, portawe, portbaddr, portbdataout, portbre, clk0); + +parameter operation_mode = "dual_port"; +parameter logical_ram_name = ""; +parameter port_a_address_width = 10; +parameter port_a_data_width = 10; +parameter port_a_logical_ram_depth = 1024; +parameter port_a_logical_ram_width = 10; +parameter port_a_first_address = 0; +parameter port_a_last_address = 1023; +parameter port_a_first_bit_number = 0; +parameter port_b_address_width = 10; +parameter port_b_data_width = 10; +parameter port_b_logical_ram_depth = 1024; +parameter port_b_logical_ram_width = 10; +parameter port_b_first_address = 0; +parameter port_b_last_address = 1023; +parameter port_b_first_bit_number = 0; +parameter port_b_address_clock = "clock0"; +parameter port_b_read_enable_clock = "clock0"; +parameter mem_init0 = ""; +parameter mem_init1 = ""; +parameter mem_init2 = ""; +parameter mem_init3 = ""; +parameter mem_init4 = ""; + +input [port_a_address_width-1:0] portaaddr; +input [port_b_address_width-1:0] portbaddr; +input [port_a_data_width-1:0] portadatain; +output [port_b_data_width-1:0] portbdataout; +input clk0, portawe, portbre; + +endmodule diff --git a/techlibs/intel_alm/common/mem_sim.v b/techlibs/intel_alm/common/mem_sim.v index ae79b19a4..e09aafaa2 100644 --- a/techlibs/intel_alm/common/mem_sim.v +++ b/techlibs/intel_alm/common/mem_sim.v @@ -48,13 +48,62 @@ // the following model because it's very difficult to trigger this in practice // as clock cycles will be much longer than any potential blip of 'x, so the // model can be treated as always returning a defined result. + +(* abc9_box, lib_whitebox *) module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, CLK1, input [4:0] B1ADDR, output B1DATA); reg [31:0] mem = 32'b0; +// TODO: Cyclone 10 GX timings; the below timings are for Cyclone V +specify + $setup(A1ADDR, posedge CLK1, 86); + $setup(A1DATA, posedge CLK1, 86); + $setup(A1EN, posedge CLK1, 86); + + (B1ADDR[0] => B1DATA) = 487; + (B1ADDR[1] => B1DATA) = 475; + (B1ADDR[2] => B1DATA) = 382; + (B1ADDR[3] => B1DATA) = 284; + (B1ADDR[4] => B1DATA) = 96; +endspecify + always @(posedge CLK1) if (A1EN) mem[A1ADDR] <= A1DATA; assign B1DATA = mem[B1ADDR]; endmodule + +// The M10K +// -------- +// TODO + +module MISTRAL_M10K(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + +parameter CFG_ABITS = 10; +parameter CFG_DBITS = 10; + +input CLK1; +input [CFG_ABITS-1:0] A1ADDR, B1ADDR; +input [CFG_DBITS-1:0] A1DATA; +input A1EN, B1EN; +output reg [CFG_DBITS-1:0] B1DATA; + +reg [2**CFG_ABITS * CFG_DBITS - 1 : 0] mem = 0; + +specify + $setup(A1ADDR, posedge CLK1, 0); + $setup(A1DATA, posedge CLK1, 0); + + if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 0; +endspecify + +always @(posedge CLK1) begin + if (A1EN) + mem[(A1ADDR + 1) * CFG_DBITS - 1 : A1ADDR * CFG_DBITS] <= A1DATA; + + if (B1EN) + B1DATA <= mem[(B1ADDR + 1) * CFG_DBITS - 1 : B1ADDR * CFG_DBITS]; +end + +endmodule diff --git a/techlibs/intel_alm/common/quartus_rename.v b/techlibs/intel_alm/common/quartus_rename.v index c40a4e02d..3b4628675 100644 --- a/techlibs/intel_alm/common/quartus_rename.v +++ b/techlibs/intel_alm/common/quartus_rename.v @@ -1,9 +1,11 @@ `ifdef cyclonev `define LCELL cyclonev_lcell_comb +`define MAC cyclonev_mac `define MLAB cyclonev_mlab_cell `endif `ifdef cyclone10gx `define LCELL cyclone10gx_lcell_comb +`define MAC cyclone10gx_mac `define MLAB cyclone10gx_mlab_cell `endif @@ -86,6 +88,8 @@ endmodule module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, CLK1, input [4:0] B1ADDR, output B1DATA); +parameter _TECHMAP_CELLNAME_ = ""; + // Here we get to an unfortunate situation. The cell has a mem_init0 parameter, // which takes in a hexadecimal string that could be used to initialise RAM. // In the vendor simulation models, this appears to work fine, but Quartus, @@ -97,7 +101,7 @@ module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, CLK1, input [4:0] B1 // or an undocumented way to get Quartus to initialise from mem_init0 is found. `MLAB #( - .logical_ram_name("MISTRAL_MLAB"), + .logical_ram_name(_TECHMAP_CELLNAME_), .logical_ram_depth(32), .logical_ram_width(1), .mixed_port_feed_through_mode("Dont Care"), @@ -119,3 +123,113 @@ module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, CLK1, input [4:0] B1 ); endmodule + + +module MISTRAL_M10K(A1ADDR, A1DATA, A1EN, CLK1, B1ADDR, B1DATA, B1EN); + +parameter CFG_ABITS = 10; +parameter CFG_DBITS = 10; + +parameter _TECHMAP_CELLNAME_ = ""; + +input [CFG_ABITS-1:0] A1ADDR, B1ADDR; +input [CFG_DBITS-1:0] A1DATA; +input CLK1, A1EN, B1EN; +output [CFG_DBITS-1:0] B1DATA; + +// Much like the MLAB, the M10K has mem_init[01234] parameters which would let +// you initialise the RAM cell via hex literals. If they were implemented. + +cyclonev_ram_block #( + .operation_mode("dual_port"), + .logical_ram_name(_TECHMAP_CELLNAME_), + .port_a_address_width(CFG_ABITS), + .port_a_data_width(CFG_DBITS), + .port_a_logical_ram_depth(2**CFG_ABITS), + .port_a_logical_ram_width(CFG_DBITS), + .port_a_first_address(0), + .port_a_last_address(2**CFG_ABITS - 1), + .port_a_first_bit_number(0), + .port_b_address_width(CFG_ABITS), + .port_b_data_width(CFG_DBITS), + .port_b_logical_ram_depth(2**CFG_ABITS), + .port_b_logical_ram_width(CFG_DBITS), + .port_b_first_address(0), + .port_b_last_address(2**CFG_ABITS - 1), + .port_b_first_bit_number(0), + .port_b_address_clock("clock0"), + .port_b_read_enable_clock("clock0") +) _TECHMAP_REPLACE_ ( + .portaaddr(A1ADDR), + .portadatain(A1DATA), + .portawe(A1EN), + .portbaddr(B1ADDR), + .portbdataout(B1DATA), + .portbre(B1EN), + .clk0(CLK1) +); + +endmodule + + +module MISTRAL_MUL27X27(input [26:0] A, B, output [53:0] Y); + +parameter A_SIGNED = 1; +parameter B_SIGNED = 1; + +`MAC #( + .ax_width(27), + .signed_max(A_SIGNED ? "true" : "false"), + .ay_scan_in_width(27), + .signed_may(B_SIGNED ? "true" : "false"), + .result_a_width(54), + .operation_mode("M27x27") +) _TECHMAP_REPLACE_ ( + .ax(A), + .ay(B), + .resulta(Y) +); + +endmodule + + +module MISTRAL_MUL18X18(input [17:0] A, B, output [35:0] Y); + +parameter A_SIGNED = 1; +parameter B_SIGNED = 1; + +`MAC #( + .ax_width(18), + .signed_max(A_SIGNED ? "true" : "false"), + .ay_scan_in_width(18), + .signed_may(B_SIGNED ? "true" : "false"), + .result_a_width(36), + .operation_mode("M18x18_FULL") +) _TECHMAP_REPLACE_ ( + .ax(A), + .ay(B), + .resulta(Y) +); + +endmodule + + +module MISTRAL_MUL9X9(input [8:0] A, B, output [17:0] Y); + +parameter A_SIGNED = 1; +parameter B_SIGNED = 1; + +`MAC #( + .ax_width(9), + .signed_max(A_SIGNED ? "true" : "false"), + .ay_scan_in_width(9), + .signed_may(B_SIGNED ? "true" : "false"), + .result_a_width(18), + .operation_mode("M9x9") +) _TECHMAP_REPLACE_ ( + .ax(A), + .ay(B), + .resulta(Y) +); + +endmodule diff --git a/techlibs/intel/cyclonev/cells_sim.v b/techlibs/intel_alm/cyclonev/cells_sim.v index 9b2a10e72..9b2a10e72 100644 --- a/techlibs/intel/cyclonev/cells_sim.v +++ b/techlibs/intel_alm/cyclonev/cells_sim.v diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc index 0f844961e..6719eb65c 100644 --- a/techlibs/intel_alm/synth_intel_alm.cc +++ b/techlibs/intel_alm/synth_intel_alm.cc @@ -29,7 +29,7 @@ PRIVATE_NAMESPACE_BEGIN struct SynthIntelALMPass : public ScriptPass { SynthIntelALMPass() : ScriptPass("synth_intel_alm", "synthesis for ALM-based Intel (Altera) FPGAs.") {} - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -38,20 +38,26 @@ struct SynthIntelALMPass : public ScriptPass { log("This command runs synthesis for ALM-based Intel FPGAs.\n"); log("\n"); log(" -top <module>\n"); - log(" use the specified module as top module (default='top')\n"); + log(" use the specified module as top module\n"); log("\n"); log(" -family <family>\n"); log(" target one of:\n"); log(" \"cyclonev\" - Cyclone V (default)\n"); log(" \"cyclone10gx\" - Cyclone 10GX\n"); log("\n"); - log(" -quartus\n"); - log(" output a netlist using Quartus cells instead of MISTRAL_* cells\n"); - log("\n"); log(" -vqm <file>\n"); log(" write the design to the specified Verilog Quartus Mapping File. Writing of an\n"); log(" output file is omitted if this parameter is not specified. Implies -quartus.\n"); log("\n"); + log(" -noflatten\n"); + log(" do not flatten design before synthesis; useful for per-module area statistics\n"); + log("\n"); + log(" -quartus\n"); + log(" output a netlist using Quartus cells instead of MISTRAL_* cells\n"); + log("\n"); + log(" -dff\n"); + log(" pass DFFs to ABC to perform sequential logic optimisations (EXPERIMENTAL)\n"); + log("\n"); log(" -run <from_label>:<to_label>\n"); log(" only run the commands between the labels (see below). an empty\n"); log(" from label is synonymous to 'begin', and empty to label is\n"); @@ -63,8 +69,8 @@ struct SynthIntelALMPass : public ScriptPass { log(" -nobram\n"); log(" do not use block RAM cells in output netlist\n"); log("\n"); - log(" -noflatten\n"); - log(" do not flatten design before synthesis\n"); + log(" -nodsp\n"); + log(" do not map multipliers to MISTRAL_MUL cells\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); @@ -72,9 +78,9 @@ struct SynthIntelALMPass : public ScriptPass { } string top_opt, family_opt, bram_type, vout_file; - bool flatten, quartus, nolutram, nobram; + bool flatten, quartus, nolutram, nobram, dff, nodsp; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; family_opt = "cyclonev"; @@ -84,9 +90,11 @@ struct SynthIntelALMPass : public ScriptPass { quartus = false; nolutram = false; nobram = false; + dff = false; + nodsp = false; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -126,10 +134,18 @@ struct SynthIntelALMPass : public ScriptPass { nobram = true; continue; } + if (args[argidx] == "-nodsp") { + nodsp = true; + continue; + } if (args[argidx] == "-noflatten") { flatten = false; continue; } + if (args[argidx] == "-dff") { + dff = true; + continue; + } break; } extra_args(args, argidx, design); @@ -153,7 +169,7 @@ struct SynthIntelALMPass : public ScriptPass { log_pop(); } - void script() YS_OVERRIDE + void script() override { if (help_mode) { family_opt = "<family>"; @@ -161,10 +177,13 @@ struct SynthIntelALMPass : public ScriptPass { } if (check_label("begin")) { - run(stringf("read_verilog -sv -lib +/intel/%s/cells_sim.v", family_opt.c_str())); + if (family_opt == "cyclonev") + run(stringf("read_verilog -sv -lib +/intel_alm/%s/cells_sim.v", family_opt.c_str())); run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/alm_sim.v", family_opt.c_str())); run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dff_sim.v", family_opt.c_str())); + run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dsp_sim.v", family_opt.c_str())); run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/mem_sim.v", family_opt.c_str())); + run(stringf("read_verilog -specify -lib -D %s -icells +/intel_alm/common/abc9_model.v", family_opt.c_str())); // Misc and common cells run("read_verilog -lib +/intel/common/altpll_bb.v"); @@ -172,21 +191,56 @@ struct SynthIntelALMPass : public ScriptPass { run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str())); } - if (flatten && check_label("flatten", "(unless -noflatten)")) { + if (check_label("coarse")) { run("proc"); - run("flatten"); + if (flatten || help_mode) + run("flatten", "(skip if -noflatten)"); run("tribuf -logic"); run("deminout"); - } - - if (check_label("coarse")) { - run("synth -run coarse -lut 6"); - run("techmap -map +/intel_alm/common/arith_alm_map.v"); + run("opt_expr"); + run("opt_clean"); + run("check"); + run("opt -nodffe -nosdff"); + run("fsm"); + run("opt"); + run("wreduce"); + run("peepopt"); + run("opt_clean"); + run("share"); + run("techmap -map +/cmp2lut.v -D LUT_WIDTH=6"); + run("opt_expr"); + run("opt_clean"); + if (help_mode) { + run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)"); + } else if (!nodsp) { + // Cyclone V supports 9x9 multiplication, Cyclone 10 GX does not. + run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=19 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL27X27"); + run("chtype -set $mul t:$__soft_mul"); + run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=19 -D DSP_NAME=__MUL27X27"); + run("chtype -set $mul t:$__soft_mul"); + if (family_opt == "cyclonev") { + run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL18X18"); + run("chtype -set $mul t:$__soft_mul"); + run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=10 -D DSP_NAME=__MUL18X18"); + run("chtype -set $mul t:$__soft_mul"); + run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=9 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL9X9"); + run("chtype -set $mul t:$__soft_mul"); + } else if (family_opt == "cyclone10gx") { + run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL18X18"); + run("chtype -set $mul t:$__soft_mul"); + } + } + run("alumacc"); + run("techmap -map +/intel_alm/common/arith_alm_map.v -map +/intel_alm/common/dsp_map.v"); + run("opt"); + run("memory -nomap"); + run("opt_clean"); } if (!nobram && check_label("map_bram", "(skip if -nobram)")) { run(stringf("memory_bram -rules +/intel_alm/common/bram_%s.txt", bram_type.c_str())); - run(stringf("techmap -map +/intel_alm/common/bram_%s_map.v", bram_type.c_str())); + if (help_mode || bram_type != "m10k") + run(stringf("techmap -map +/intel_alm/common/bram_%s_map.v", bram_type.c_str())); } if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) { @@ -199,17 +253,17 @@ struct SynthIntelALMPass : public ScriptPass { } if (check_label("map_ffs")) { - run("dff2dffe -direct-match $_DFF_*"); - // As mentioned in common/dff_sim.v, Intel flops power up to zero, - // so use `zinit` to add inverters where needed. - run("zinit"); - run("techmap -map +/techmap.v -map +/intel_alm/common/dff_map.v"); + run("techmap"); + run("dfflegalize -cell $_DFFE_PN0P_ 0 -cell $_SDFFCE_PP0P_ 0"); + run("techmap -map +/intel_alm/common/dff_map.v"); run("opt -full -undriven -mux_undef"); run("clean -purge"); } if (check_label("map_luts")) { - run("abc9 -maxlut 6 -W 200"); + run("techmap -map +/intel_alm/common/abc9_map.v"); + run(stringf("abc9 %s -maxlut 6 -W 600", help_mode ? "[-dff]" : dff ? "-dff" : "")); + run("techmap -map +/intel_alm/common/abc9_unmap.v"); run("techmap -map +/intel_alm/common/alm_map.v"); run("opt -fast"); run("autoname"); diff --git a/techlibs/nexus/Makefile.inc b/techlibs/nexus/Makefile.inc new file mode 100644 index 000000000..c9a9ad4ff --- /dev/null +++ b/techlibs/nexus/Makefile.inc @@ -0,0 +1,15 @@ +OBJS += techlibs/nexus/synth_nexus.o + +$(eval $(call add_share_file,share/nexus,techlibs/nexus/cells_map.v)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/cells_sim.v)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/parse_init.vh)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/cells_xtra.v)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/lutrams_map.v)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/lutrams.txt)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/brams_init.vh)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/brams_map.v)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/brams.txt)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/arith_map.v)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/latches_map.v)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/dsp_map.v)) + diff --git a/techlibs/nexus/arith_map.v b/techlibs/nexus/arith_map.v new file mode 100644 index 000000000..fd9d61be3 --- /dev/null +++ b/techlibs/nexus/arith_map.v @@ -0,0 +1,99 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xen <claire@symbioticeda.com> + * Copyright (C) 2018 David Shah <dave@ds0.me> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +(* techmap_celltype = "$alu" *) +module _80_nexus_alu (A, B, CI, BI, X, Y, CO); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] X, Y; + + input CI, BI; + (* force_downto *) + output [Y_WIDTH-1:0] CO; + + wire _TECHMAP_FAIL_ = Y_WIDTH <= 4; + + (* force_downto *) + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + + function integer round_up2; + input integer N; + begin + round_up2 = ((N + 1) / 2) * 2; + end + endfunction + + localparam Y_WIDTH2 = round_up2(Y_WIDTH); + + (* force_downto *) + wire [Y_WIDTH2-1:0] AA = A_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BX = B_buf; + (* force_downto *) + wire [Y_WIDTH2+1:0] FCO, Y1; + + genvar i; + + // Carry feed-in + CCU2 #( + .INIT0("0xFFFF"), + .INIT1("0x00AA"), + .INJECT("NO") + ) ccu2c_i ( + .A0(1'b1), .B0(1'b1), .C0(1'b1), .D0(1'b1), + .A1(CI), .B1(1'b1), .C1(1'b1), .D1(1'b1), + .COUT(FCO[0]) + ); + + generate for (i = 0; i < Y_WIDTH2; i = i + 2) begin:slice + CCU2 #( + .INIT0("0x96AA"), + .INIT1("0x96AA"), + .INJECT("NO") + ) ccu2c_i ( + .CIN(FCO[i]), + .A0(AA[i]), .B0(BX[i]), .C0(BI), .D0(1'b1), + .A1(AA[i+1]), .B1(BX[i+1]), .C1(BI), .D1(1'b1), + .S0(Y[i]), .S1(Y1[i]), + .COUT(FCO[i+2]) + ); + + assign CO[i] = (AA[i] && BB[i]) || (((i == 0) ? CI : CO[i-1]) && (AA[i] || BB[i])); + if (i+1 < Y_WIDTH) begin + assign CO[i+1] = (AA[i+1] && BB[i+1]) || (CO[i] && (AA[i+1] || BB[i+1])); + assign Y[i+1] = Y1[i]; + end + end endgenerate + + assign X = AA ^ BB; +endmodule diff --git a/techlibs/nexus/brams.txt b/techlibs/nexus/brams.txt new file mode 100644 index 000000000..086afe8bf --- /dev/null +++ b/techlibs/nexus/brams.txt @@ -0,0 +1,63 @@ +bram $__NX_PDP16K + init 1 + + abits 9 @a9d36 + dbits 36 @a9d36 + abits 10 @a10d18 + dbits 18 @a10d18 + abits 11 @a11d9 + dbits 9 @a11d9 + abits 12 @a12d4 + dbits 4 @a12d4 + abits 13 @a13d2 + dbits 2 @a13d2 + abits 14 @a14d1 + dbits 1 @a14d1 + + groups 2 + ports 1 1 + wrmode 1 0 + enable 4 1 @a9d36 + enable 2 1 @a10d18 + enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 + transp 0 0 + clocks 2 3 + clkpol 2 3 +endbram + +match $__NX_PDP16K + # implicitly requested RAM or ROM + attribute !syn_ramstyle syn_ramstyle=auto + attribute !syn_romstyle syn_romstyle=auto + attribute !ram_block + attribute !rom_block + attribute !logic_block + min bits 2048 + min efficiency 5 + shuffle_enable A + make_transp + or_next_if_better +endmatch + +match $__NX_PDP16K + # explicitly requested RAM + attribute syn_ramstyle=block_ram ram_block + attribute !syn_romstyle + attribute !rom_block + attribute !logic_block + min wports 1 + shuffle_enable A + make_transp + or_next_if_better +endmatch + +match $__NX_PDP16K + # explicitly requested ROM + attribute syn_romstyle=ebr rom_block + attribute !syn_ramstyle + attribute !ram_block + attribute !logic_block + max wports 0 + make_transp + shuffle_enable A +endmatch diff --git a/techlibs/nexus/brams_init.vh b/techlibs/nexus/brams_init.vh new file mode 100644 index 000000000..5b1d0188a --- /dev/null +++ b/techlibs/nexus/brams_init.vh @@ -0,0 +1,64 @@ +.INITVAL_00($sformatf("0x%080x", permute_init(INIT[0 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_01($sformatf("0x%080x", permute_init(INIT[1 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_02($sformatf("0x%080x", permute_init(INIT[2 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_03($sformatf("0x%080x", permute_init(INIT[3 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_04($sformatf("0x%080x", permute_init(INIT[4 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_05($sformatf("0x%080x", permute_init(INIT[5 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_06($sformatf("0x%080x", permute_init(INIT[6 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_07($sformatf("0x%080x", permute_init(INIT[7 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_08($sformatf("0x%080x", permute_init(INIT[8 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_09($sformatf("0x%080x", permute_init(INIT[9 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0A($sformatf("0x%080x", permute_init(INIT[10 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0B($sformatf("0x%080x", permute_init(INIT[11 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0C($sformatf("0x%080x", permute_init(INIT[12 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0D($sformatf("0x%080x", permute_init(INIT[13 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0E($sformatf("0x%080x", permute_init(INIT[14 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0F($sformatf("0x%080x", permute_init(INIT[15 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_10($sformatf("0x%080x", permute_init(INIT[16 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_11($sformatf("0x%080x", permute_init(INIT[17 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_12($sformatf("0x%080x", permute_init(INIT[18 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_13($sformatf("0x%080x", permute_init(INIT[19 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_14($sformatf("0x%080x", permute_init(INIT[20 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_15($sformatf("0x%080x", permute_init(INIT[21 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_16($sformatf("0x%080x", permute_init(INIT[22 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_17($sformatf("0x%080x", permute_init(INIT[23 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_18($sformatf("0x%080x", permute_init(INIT[24 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_19($sformatf("0x%080x", permute_init(INIT[25 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1A($sformatf("0x%080x", permute_init(INIT[26 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1B($sformatf("0x%080x", permute_init(INIT[27 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1C($sformatf("0x%080x", permute_init(INIT[28 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1D($sformatf("0x%080x", permute_init(INIT[29 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1E($sformatf("0x%080x", permute_init(INIT[30 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1F($sformatf("0x%080x", permute_init(INIT[31 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_20($sformatf("0x%080x", permute_init(INIT[32 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_21($sformatf("0x%080x", permute_init(INIT[33 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_22($sformatf("0x%080x", permute_init(INIT[34 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_23($sformatf("0x%080x", permute_init(INIT[35 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_24($sformatf("0x%080x", permute_init(INIT[36 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_25($sformatf("0x%080x", permute_init(INIT[37 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_26($sformatf("0x%080x", permute_init(INIT[38 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_27($sformatf("0x%080x", permute_init(INIT[39 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_28($sformatf("0x%080x", permute_init(INIT[40 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_29($sformatf("0x%080x", permute_init(INIT[41 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2A($sformatf("0x%080x", permute_init(INIT[42 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2B($sformatf("0x%080x", permute_init(INIT[43 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2C($sformatf("0x%080x", permute_init(INIT[44 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2D($sformatf("0x%080x", permute_init(INIT[45 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2E($sformatf("0x%080x", permute_init(INIT[46 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2F($sformatf("0x%080x", permute_init(INIT[47 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_30($sformatf("0x%080x", permute_init(INIT[48 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_31($sformatf("0x%080x", permute_init(INIT[49 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_32($sformatf("0x%080x", permute_init(INIT[50 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_33($sformatf("0x%080x", permute_init(INIT[51 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_34($sformatf("0x%080x", permute_init(INIT[52 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_35($sformatf("0x%080x", permute_init(INIT[53 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_36($sformatf("0x%080x", permute_init(INIT[54 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_37($sformatf("0x%080x", permute_init(INIT[55 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_38($sformatf("0x%080x", permute_init(INIT[56 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_39($sformatf("0x%080x", permute_init(INIT[57 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3A($sformatf("0x%080x", permute_init(INIT[58 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3B($sformatf("0x%080x", permute_init(INIT[59 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3C($sformatf("0x%080x", permute_init(INIT[60 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3D($sformatf("0x%080x", permute_init(INIT[61 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3E($sformatf("0x%080x", permute_init(INIT[62 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3F($sformatf("0x%080x", permute_init(INIT[63 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))) diff --git a/techlibs/nexus/brams_map.v b/techlibs/nexus/brams_map.v new file mode 100644 index 000000000..214da4326 --- /dev/null +++ b/techlibs/nexus/brams_map.v @@ -0,0 +1,115 @@ +module \$__NX_PDP16K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 9; + parameter CFG_DBITS = 36; + parameter CFG_ENABLE_A = 4; + + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + parameter [18431:0] INIT = 18432'b0; + + parameter _TECHMAP_BITS_CONNMAP_ = 8; + parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_CLK2_ = 0; + parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_CLK3_ = 0; + + input CLK2; + input CLK3; + + input [CFG_ABITS-1:0] A1ADDR; + input [CFG_DBITS-1:0] A1DATA; + input [CFG_ENABLE_A-1:0] A1EN; + + input [CFG_ABITS-1:0] B1ADDR; + output [CFG_DBITS-1:0] B1DATA; + input B1EN; + + // Address is left justified, in x18 and above lower bits are byte enables + localparam A_SHIFT = + (CFG_DBITS == 36) ? 5 : + (CFG_DBITS == 18) ? 4 : + (CFG_DBITS == 9) ? 3 : + (CFG_DBITS == 4) ? 2 : + (CFG_DBITS == 2) ? 1 : + 0; + + // Different primitives needed for single vs dual clock case + localparam SINGLE_CLOCK = (_TECHMAP_CONNMAP_CLK2_ == _TECHMAP_CONNMAP_CLK3_); + + localparam WIDTH = $sformatf("X%d", CFG_DBITS); + + wire [13:0] ra, wa; + wire [35:0] rd, wd; + + assign ra = {B1ADDR, {A_SHIFT{1'b1}}}; + + generate + if (CFG_ENABLE_A > 1) + assign wa = {A1ADDR, {(A_SHIFT-CFG_ENABLE_A){1'b1}}, A1EN}; + else + assign wa = {A1ADDR, {A_SHIFT{1'b1}}}; + endgenerate + + assign wd = A1DATA; + assign B1DATA = rd[CFG_DBITS-1:0]; + + wire wck, rck; + + generate + if (CLKPOL2) + assign wck = CLK2; + else + INV wck_inv_i (.A(CLK2), .Z(wck)); + if (CLKPOL3) + assign rck = CLK3; + else + INV wck_inv_i (.A(CLK3), .Z(rck)); + endgenerate + + wire we = |A1EN; + + localparam INIT_CHUNK_SIZE = (CFG_DBITS <= 4) ? 256 : 288; + + function [319:0] permute_init; + input [INIT_CHUNK_SIZE-1:0] chunk; + integer i; + begin + if (CFG_DBITS <= 4) begin + for (i = 0; i < 32; i = i + 1'b1) + permute_init[i * 10 +: 10] = {2'b00, chunk[i * 8 +: 8]}; + end else begin + for (i = 0; i < 32; i = i + 1'b1) + permute_init[i * 10 +: 10] = {1'b0, chunk[i * 9 +: 9]}; + end + end + endfunction + + generate + if (SINGLE_CLOCK) begin + PDPSC16K #( + .DATA_WIDTH_W(WIDTH), + .DATA_WIDTH_R(WIDTH), + .OUTREG("BYPASSED"), + .ECC("DISABLED"), + .GSR("DISABLED"), +`include "brams_init.vh" + ) _TECHMAP_REPLACE_ ( + .CLK(wck), .RST(1'b0), + .DI(wd), .ADW(wa), .CEW(we), .CSW(3'b111), + .ADR(ra), .DO(rd), .CER(B1EN), .CSR(3'b111) + ); + end else begin + PDP16K #( + .DATA_WIDTH_W(WIDTH), + .DATA_WIDTH_R(WIDTH), + .OUTREG("BYPASSED"), + .ECC("DISABLED"), + .GSR("DISABLED"), +`include "brams_init.vh" + ) _TECHMAP_REPLACE_ ( + .CLKW(wck), .CLKR(rck), .RST(1'b0), + .DI(wd), .ADW(wa), .CEW(we), .CSW(3'b111), + .ADR(ra), .DO(rd), .CER(B1EN), .CSR(3'b111) + ); + end + endgenerate + +endmodule diff --git a/techlibs/nexus/cells_map.v b/techlibs/nexus/cells_map.v new file mode 100644 index 000000000..86911d7a0 --- /dev/null +++ b/techlibs/nexus/cells_map.v @@ -0,0 +1,106 @@ +// Flipflop intermediate map level +module \$__FF_NOLSR (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + generate + if (_TECHMAP_WIREINIT_Q_ === 1'b1) + FD1P3JX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .PD(1'b0), .Q(Q)); + else + FD1P3IX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .CD(1'b0), .Q(Q)); + endgenerate +endmodule + +module \$__FF_SYNCLSR (input D, C, E, R, output Q); + parameter SR_VAL = 1'b0; + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + wire Ci, Ei, Ri, Rg, Dd; + generate + if (SR_VAL) + FD1P3JX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .PD(R), .Q(Q)); + else + FD1P3IX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .CD(R), .Q(Q)); + endgenerate +endmodule + +module \$__FF_ASYNCLSR (input D, C, E, R, output Q); + parameter SR_VAL = 1'b0; + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + wire _TECHMAP_REMOVEINIT_Q_ = (_TECHMAP_WIREINIT_Q_ === 1'bx || _TECHMAP_WIREINIT_Q_ === SR_VAL); + wire Ci, Ei, Ri, Rg, Dd; + generate + if (SR_VAL) + FD1P3BX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .PD(R), .Q(Q)); + else + FD1P3DX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .CD(R), .Q(Q)); + endgenerate +endmodule + + +module \$_DFF_P_ (input D, C, output Q); \$__FF_NOLSR _TECHMAP_REPLACE_ (.D(D), .C(C), .E(1'b1), .Q(Q)); endmodule + +module \$_DFFE_PP_ (input D, C, E, output Q); \$__FF_NOLSR _TECHMAP_REPLACE_ (.D(D), .C(C), .E(E), .Q(Q)); endmodule + +module \$_DFF_PP0_ (input D, C, R, output Q); \$__FF_ASYNCLSR #(0) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(1'b1), .Q(Q)); endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); \$__FF_ASYNCLSR #(1) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(1'b1), .Q(Q)); endmodule + +module \$_SDFF_PP0_ (input D, C, R, output Q); \$__FF_SYNCLSR #(0) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(1'b1), .Q(Q)); endmodule +module \$_SDFF_PP1_ (input D, C, R, output Q); \$__FF_SYNCLSR #(1) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(1'b1), .Q(Q)); endmodule + +module \$_DFFE_PP0P_ (input D, C, E, R, output Q); \$__FF_ASYNCLSR #(0) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(E), .Q(Q)); endmodule +module \$_DFFE_PP1P_ (input D, C, E, R, output Q); \$__FF_ASYNCLSR #(1) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(E), .Q(Q)); endmodule + +module \$_SDFFE_PP0P_ (input D, C, E, R, output Q); \$__FF_SYNCLSR #(0) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(E), .Q(Q)); endmodule +module \$_SDFFE_PP1P_ (input D, C, E, R, output Q); \$__FF_SYNCLSR #(1) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(E), .Q(Q)); endmodule + +module \$__NX_TINOUTPAD (input I, OE, output O, inout B); + BB _TECHMAP_REPLACE_ (.I(I), .O(O), .T(~OE), .B(B)); +endmodule + +module \$__NX_TOUTPAD (input I, OE, output O); + OBZ _TECHMAP_REPLACE_ (.I(I), .O(), .T(~OE), .O(O)); +endmodule + +`ifndef NO_LUT +module \$lut (A, Y); + parameter WIDTH = 0; + parameter LUT = 0; + + input [WIDTH-1:0] A; + output Y; + + generate + if (WIDTH == 1) begin + if (LUT == 2'b01) + INV _TECHMAP_REPLACE_ (.A(A[0]), .Z(Y)); + else + LUT4 #(.INIT($sformatf("0x%04x", {{8{LUT[1]}}, {8{LUT[0]}}}))) _TECHMAP_REPLACE_ (.Z(Y), + .D(A[0])); + end else + if (WIDTH == 2) begin + localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[2]}}, {4{LUT[1]}}, {4{LUT[0]}}}; + LUT4 #(.INIT($sformatf("0x%04x", INIT))) _TECHMAP_REPLACE_ (.Z(Y), + .C(A[0]), .D(A[1])); + end else + if (WIDTH == 3) begin + localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[6]}}, {2{LUT[5]}}, {2{LUT[4]}}, {2{LUT[3]}}, {2{LUT[2]}}, {2{LUT[1]}}, {2{LUT[0]}}}; + LUT4 #(.INIT($sformatf("0x%04x", INIT))) _TECHMAP_REPLACE_ (.Z(Y), + .B(A[0]), .C(A[1]), .D(A[2])); + end else + if (WIDTH == 4) begin + LUT4 #(.INIT($sformatf("0x%04x", LUT))) _TECHMAP_REPLACE_ (.Z(Y), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + end else + if (WIDTH == 5) begin + WIDEFN9 #( + .INIT0($sformatf("0x%04x", LUT[15:0 ])), + .INIT1($sformatf("0x%04x", LUT[31:16])), + ) _TECHMAP_REPLACE_ ( + .A0(A[0]), .B0(A[1]), .C0(A[2]), .D0(A[3]), + .A1(A[0]), .B1(A[1]), .C1(A[2]), .D1(A[3]), + .SEL(A[4]), .Z(Y) + ); + end + endgenerate +endmodule +`endif diff --git a/techlibs/nexus/cells_sim.v b/techlibs/nexus/cells_sim.v new file mode 100644 index 000000000..b5938e08f --- /dev/null +++ b/techlibs/nexus/cells_sim.v @@ -0,0 +1,943 @@ +(* abc9_lut=1, lib_whitebox *) +module LUT4(input A, B, C, D, output Z); + parameter INIT = "0x0000"; +`include "parse_init.vh" + localparam initp = parse_init(INIT); + wire [7:0] s3 = D ? initp[15:8] : initp[7:0]; + wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0]; + wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0]; + assign Z = A ? s1[1] : s1[0]; + + // Per-input delay differences are considered 'interconnect' + // so not known yet + specify + (A => Z) = 233; + (B => Z) = 233; + (C => Z) = 233; + (D => Z) = 233; + endspecify + +endmodule + +// This is a placeholder for ABC9 to extract the area/delay +// cost of 5-input LUTs and is not intended to be instantiated +(* abc9_lut=2 *) +module \$__ABC9_LUT5 (input SEL, D, C, B, A, output Z); + specify + (SEL => Z) = 171; + (D => Z) = 303; + (C => Z) = 311; + (B => Z) = 309; + (A => Z) = 306; + endspecify +endmodule + +// Two LUT4s and MUX2 +module WIDEFN9(input A0, B0, C0, D0, A1, B1, C1, D1, SEL, output Z); + parameter INIT0 = "0x0000"; + parameter INIT1 = "0x0000"; + wire z0, z1; + LUT4 #(.INIT(INIT0)) lut4_0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(z0)); + LUT4 #(.INIT(INIT1)) lut4_1 (.A(A1), .B(B1), .C(C1), .D(D1), .Z(z1)); + assign Z = SEL ? z1 : z0; +endmodule + +(* abc9_box, lib_whitebox *) +module INV(input A, output Z); + assign Z = !A; + + specify + (A => Z) = 10; + endspecify +endmodule + +// Bidirectional IO buffer +module BB(input T, I, output O, + (* iopad_external_pin *) inout B); + assign B = T ? 1'bz : O; + assign I = B; +endmodule + +// Input buffer +module IB( + (* iopad_external_pin *) input I, + output O); + assign O = I; +endmodule + +// Output buffer +module OB(input I, + (* iopad_external_pin *) output O); + assign O = I; +endmodule + +// Output buffer with tristate +module OBZ(input I, T, + (* iopad_external_pin *) output O); + assign O = T ? 1'bz : I; +endmodule + +// Constants +module VLO(output Z); + assign Z = 1'b0; +endmodule + +module VHI(output Z); + assign Z = 1'b1; +endmodule + +// Vendor flipflops +// (all have active high clock, enable and set/reset - use INV to invert) + +// Async preset +(* abc9_box, lib_whitebox *) +module FD1P3BX(input D, CK, SP, PD, output reg Q); + parameter GSR = "DISABLED"; + initial Q = 1'b1; + always @(posedge CK or posedge PD) + if (PD) + Q <= 1'b1; + else if (SP) + Q <= D; + specify + $setup(D, posedge CK, 0); + $setup(SP, posedge CK, 212); + $setup(PD, posedge CK, 224); +`ifndef YOSYS + if (PD) (posedge CLK => (Q : 1)) = 0; +`else + if (PD) (PD => Q) = 0; // Technically, this should be an edge sensitive path + // but for facilitating a bypass box, let's pretend it's + // a simple path +`endif + if (!PD && SP) (posedge CK => (Q : D)) = 336; + endspecify +endmodule + +// Async clear +(* abc9_box, lib_whitebox *) +module FD1P3DX(input D, CK, SP, CD, output reg Q); + parameter GSR = "DISABLED"; + initial Q = 1'b0; + always @(posedge CK or posedge CD) + if (CD) + Q <= 1'b0; + else if (SP) + Q <= D; + specify + $setup(D, posedge CK, 0); + $setup(SP, posedge CK, 212); + $setup(CD, posedge CK, 224); +`ifndef YOSYS + if (CD) (posedge CLK => (Q : 0)) = 0; +`else + if (CD) (CD => Q) = 0; // Technically, this should be an edge sensitive path + // but for facilitating a bypass box, let's pretend it's + // a simple path +`endif + if (!CD && SP) (posedge CK => (Q : D)) = 336; + endspecify +endmodule + +// Sync clear +(* abc9_flop, lib_whitebox *) +module FD1P3IX(input D, CK, SP, CD, output reg Q); + parameter GSR = "DISABLED"; + initial Q = 1'b0; + always @(posedge CK) + if (CD) + Q <= 1'b0; + else if (SP) + Q <= D; + specify + $setup(D, posedge CK, 0); + $setup(SP, posedge CK, 212); + $setup(CD, posedge CK, 224); + if (!CD && SP) (posedge CK => (Q : D)) = 336; + endspecify +endmodule + +// Sync preset +(* abc9_flop, lib_whitebox *) +module FD1P3JX(input D, CK, SP, PD, output reg Q); + parameter GSR = "DISABLED"; + initial Q = 1'b1; + always @(posedge CK) + if (PD) + Q <= 1'b1; + else if (SP) + Q <= D; + specify + $setup(D, posedge CK, 0); + $setup(SP, posedge CK, 212); + $setup(PD, posedge CK, 224); + if (!PD && SP) (posedge CK => (Q : D)) = 336; + endspecify +endmodule + +// LUT4 with LUT3 tap for CCU2 use only +(* lib_whitebox *) +module LUT4_3(input A, B, C, D, output Z, Z3); + parameter INIT = "0x0000"; +`include "parse_init.vh" + localparam initp = parse_init(INIT); + wire [7:0] s3 = D ? initp[15:8] : initp[7:0]; + wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0]; + wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0]; + assign Z = A ? s1[1] : s1[0]; + + wire [3:0] s2_3 = C ? initp[ 7:4] : initp[3:0]; + wire [1:0] s1_3 = B ? s2_3[ 3:2] : s2_3[1:0]; + assign Z3 = A ? s1_3[1] : s1_3[0]; + +endmodule + +// Carry primitive (incoporating two LUTs) +(* abc9_box, lib_whitebox *) +module CCU2( + (* abc9_carry *) input CIN, + input A1, B1, C1, D1, A0, B0, C0, D0, + output S1, S0, + (* abc9_carry *) output COUT); + parameter INJECT = "YES"; + parameter INIT0 = "0x0000"; + parameter INIT1 = "0x1111"; + + localparam inject_p = (INJECT == "YES") ? 1'b1 : 1'b0; + + wire LUT3_0, LUT4_0, LUT3_1, LUT4_1, carry_0; + LUT4_3 #(.INIT(INIT0)) lut0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0), .Z3(LUT3_0)); + LUT4_3 #(.INIT(INIT1)) lut1 (.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1), .Z3(LUT3_1)); + + assign S0 = LUT4_0 ^ (CIN & ~inject_p); + assign carry_0 = LUT4_0 ? CIN : (LUT3_0 & ~inject_p); + assign S1 = LUT4_1 ^ (carry_0 & ~inject_p); + assign COUT = LUT4_1 ? carry_0 : (LUT3_1 & ~inject_p); + + specify + (A0 => S0) = 233; + (B0 => S0) = 233; + (C0 => S0) = 233; + (D0 => S0) = 233; + (CIN => S0) = 228; + (A0 => S1) = 481; + (B0 => S1) = 481; + (C0 => S1) = 481; + (D0 => S1) = 481; + (A1 => S1) = 233; + (B1 => S1) = 233; + (C1 => S1) = 233; + (D1 => S1) = 233; + (CIN => S1) = 307; + (A0 => COUT) = 347; + (B0 => COUT) = 347; + (C0 => COUT) = 347; + (D0 => COUT) = 347; + (A1 => COUT) = 347; + (B1 => COUT) = 347; + (C1 => COUT) = 347; + (D1 => COUT) = 347; + (CIN => COUT) = 59; + endspecify + +endmodule + +// Packed flipflop +module OXIDE_FF(input CLK, LSR, CE, DI, M, output reg Q); + parameter GSR = "ENABLED"; + parameter [127:0] CEMUX = "1"; + parameter CLKMUX = "CLK"; + parameter LSRMUX = "LSR"; + parameter REGDDR = "DISABLED"; + parameter SRMODE = "LSR_OVER_CE"; + parameter REGSET = "RESET"; + parameter [127:0] LSRMODE = "LSR"; + + wire muxce; + generate + case (CEMUX) + "1": assign muxce = 1'b1; + "0": assign muxce = 1'b0; + "INV": assign muxce = ~CE; + default: assign muxce = CE; + endcase + endgenerate + + wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; + wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; + wire srval; + generate + if (LSRMODE == "PRLD") + assign srval = M; + else + assign srval = (REGSET == "SET") ? 1'b1 : 1'b0; + endgenerate + + initial Q = srval; + + generate + if (REGDDR == "ENABLED") begin + if (SRMODE == "ASYNC") begin + always @(posedge muxclk, negedge muxclk, posedge muxlsr) + if (muxlsr) + Q <= srval; + else if (muxce) + Q <= DI; + end else begin + always @(posedge muxclk, negedge muxclk) + if (muxlsr) + Q <= srval; + else if (muxce) + Q <= DI; + end + end else begin + if (SRMODE == "ASYNC") begin + always @(posedge muxclk, posedge muxlsr) + if (muxlsr) + Q <= srval; + else if (muxce) + Q <= DI; + end else begin + always @(posedge muxclk) + if (muxlsr) + Q <= srval; + else if (muxce) + Q <= DI; + end + end + endgenerate +endmodule + +// Packed combinational logic (for post-pnr sim) +module OXIDE_COMB( + input A, B, C, D, // LUT inputs + input SEL, // mux select input + input F1, // output from LUT 1 for mux + input FCI, // carry input + input WAD0, WAD1, WAD2, WAD3, // LUTRAM write address inputs + input WD, // LUTRAM write data input + input WCK, WRE, // LUTRAM write clock and enable + output F, // LUT/carry output + output OFX // mux output +); + parameter MODE = "LOGIC"; // LOGIC, CCU2, DPRAM + parameter [15:0] INIT = 16'h0000; + parameter INJECT = "YES"; + + localparam inject_p = (INJECT == "YES") ? 1'b1 : 1'b0; + + reg [15:0] lut = INIT; + + wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0]; + wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0]; + wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0]; + wire Z = A ? s1[1] : s1[0]; + + wire [3:0] s2_3 = C ? INIT[ 7:4] : INIT[3:0]; + wire [1:0] s1_3 = B ? s2_3[ 3:2] : s2_3[1:0]; + wire Z3 = A ? s1_3[1] : s1_3[0]; + + generate + if (MODE == "DPRAM") begin + always @(posedge WCK) + if (WRE) + lut[{WAD3, WAD2, WAD1, WAD0}] <= WD; + end + if (MODE == "CCU2") begin + assign F = Z ^ (FCI & ~inject_p); + assign FCO = Z ? FCI : (Z3 & ~inject_p); + end else begin + assign F = Z; + end + endgenerate + + assign OFX = SEL ? F1 : F; + +endmodule + +// LUTRAM +module DPR16X4( + input [3:0] RAD, DI, WAD, + input WRE, WCK, + output [3:0] DO +); + parameter INITVAL = "0x0000000000000000"; +`include "parse_init.vh" + localparam [63:0] parsed_init = parse_init_64(INITVAL); + + reg [3:0] mem[0:15]; + integer i; + initial begin + for (i = 0; i < 15; i++) + mem[i] = parsed_init[i * 4 +: 4]; + end + + always @(posedge WCK) + if (WRE) + mem[WAD] <= DI; + assign DO = mem[RAD]; +endmodule + +// Used for all the DSP models to reduce duplication +module OXIDE_DSP_REG #( + parameter W = 18, + parameter USED = "REGISTER", + parameter RESETMODE = "SYNC" +) ( + input CLK, CE, RST, + input [W-1:0] D, + output reg [W-1:0] Q +); + generate + if (USED == "BYPASS") + always @* Q = D; + else if (USED == "REGISTER") begin + initial Q = 0; + if (RESETMODE == "ASYNC") + always @(posedge CLK, posedge RST) begin + if (RST) + Q <= 0; + else if (CE) + Q <= D; + end + else if (RESETMODE == "SYNC") + always @(posedge CLK) begin + if (RST) + Q <= 0; + else if (CE) + Q <= D; + end + end + endgenerate +endmodule + +module OXIDE_DSP_SIM #( + // User facing parameters + parameter REGINPUTA = "BYPASS", + parameter REGINPUTB = "BYPASS", + parameter REGINPUTC = "BYPASS", + parameter REGADDSUB = "BYPASS", + parameter REGLOADC = "BYPASS", + parameter REGLOADC2 = "BYPASS", + parameter REGCIN = "BYPASS", + parameter REGPIPELINE = "BYPASS", + parameter REGOUTPUT = "BYPASS", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC", + // Internally used parameters + parameter A_WIDTH = 36, + parameter B_WIDTH = 36, + parameter C_WIDTH = 36, + parameter Z_WIDTH = 72, + parameter PREADD_USED = 0, + parameter ADDSUB_USED = 0 +) ( + input [A_WIDTH-1:0] A, + input [B_WIDTH-1:0] B, + input [C_WIDTH-1:0] C, + input SIGNEDA, + input SIGNEDB, + input SIGNEDC, + input CIN, + input LOADC, + input ADDSUB, + input CLK, + input CEA, CEB, CEC, CEPIPE, CECTRL, CECIN, CEOUT, + input RSTA, RSTB, RSTC, RSTPIPE, RSTCTRL, RSTCIN, RSTOUT, + output wire [Z_WIDTH-1:0] Z +); + + localparam M_WIDTH = (A_WIDTH+B_WIDTH); + + /******** REGISTERS ********/ + + wire [M_WIDTH-1:0] pipe_d, pipe_q; + wire [Z_WIDTH-1:0] z_d; + + wire [A_WIDTH-1:0] a_r; + wire [B_WIDTH-1:0] b_r; + wire [C_WIDTH-1:0] c_r, c_r2; + wire asgd_r, bsgd_r, csgd_r, csgd_r2; + + wire addsub_r, addsub_r2, cin_r, cin_r2, sgd_r, sgd_r2; + wire loadc_r, loadc_r2; + + OXIDE_DSP_REG #(A_WIDTH+1, REGINPUTA, RESETMODE) a_reg(CLK, CEA, RSTA, {SIGNEDA, A}, {asgd_r, a_r}); + OXIDE_DSP_REG #(B_WIDTH+1, REGINPUTB, RESETMODE) b_reg(CLK, CEB, RSTB, {SIGNEDB, B}, {bsgd_r, b_r}); + OXIDE_DSP_REG #(C_WIDTH+1, REGINPUTC, RESETMODE) c_reg(CLK, CEC, RSTC, {SIGNEDC, C}, {csgd_r, c_r}); + + OXIDE_DSP_REG #(M_WIDTH, REGPIPELINE, RESETMODE) pipe_reg(CLK, CEPIPE, RSTPIPE, pipe_d, pipe_q); + + OXIDE_DSP_REG #(2, REGADDSUB, RESETMODE) addsub_reg(CLK, CECTRL, RSTCTRL, {SIGNEDA, ADDSUB}, {sgd_r, addsub_r}); + OXIDE_DSP_REG #(1, REGLOADC, RESETMODE) loadc_reg(CLK, CECTRL, RSTCTRL, LOADC, loadc_r); + OXIDE_DSP_REG #(2, REGPIPELINE, RESETMODE) addsub2_reg(CLK, CECTRL, RSTCTRL, {sgd_r, addsub_r}, {sgd_r2, addsub_r2}); + OXIDE_DSP_REG #(1, REGLOADC2, RESETMODE) loadc2_reg(CLK, CECTRL, RSTCTRL, loadc_r, loadc_r2); + + OXIDE_DSP_REG #(1, REGCIN, RESETMODE) cin_reg(CLK, CECIN, RSTCIN, CIN, cin_r); + OXIDE_DSP_REG #(1, REGPIPELINE, RESETMODE) cin2_reg(CLK, CECIN, RSTCIN, cin_r, cin_r2); + + OXIDE_DSP_REG #(C_WIDTH+1, REGPIPELINE, RESETMODE) c2_reg(CLK, CEC, RSTC, {csgd_r, c_r}, {csgd_r2, c_r2}); + + OXIDE_DSP_REG #(Z_WIDTH, REGOUTPUT, RESETMODE) z_reg(CLK, CEOUT, RSTOUT, z_d, Z); + + /******** PREADDER ********/ + + wire [B_WIDTH-1:0] mult_b; + wire mult_b_sgd; + + generate + if (PREADD_USED) begin + assign mult_b = (b_r + c_r); + assign mult_b_sgd = (bsgd_r | csgd_r); + end else begin + assign mult_b = b_r; + assign mult_b_sgd = bsgd_r; + end + endgenerate + + /******** MULTIPLIER ********/ + + // sign extend operands if needed + wire [M_WIDTH-1:0] mult_a_ext = {{(M_WIDTH-A_WIDTH){asgd_r ? a_r[A_WIDTH-1] : 1'b0}}, a_r}; + wire [M_WIDTH-1:0] mult_b_ext = {{(M_WIDTH-B_WIDTH){mult_b_sgd ? mult_b[B_WIDTH-1] : 1'b0}}, mult_b}; + + wire [M_WIDTH-1:0] mult_m = mult_a_ext * mult_b_ext; + + /******** ACCUMULATOR ********/ + + wire [Z_WIDTH-1:0] m_ext; + + generate + if (ADDSUB_USED) begin + assign pipe_d = mult_m; + assign m_ext = {{(Z_WIDTH-M_WIDTH){sgd_r2 ? pipe_q[M_WIDTH-1] : 1'b0}}, pipe_q}; + assign z_d = (loadc_r2 ? c_r2 : Z) + cin_r2 + (addsub_r2 ? -m_ext : m_ext); + end else begin + assign z_d = mult_m; + end + endgenerate + + +endmodule + +module MULT9X9 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [8:0] A, + input [8:0] B, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input SIGNEDA, + input SIGNEDB, + input RSTOUT, + input CEOUT, + output [17:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(9), + .B_WIDTH(9), + .Z_WIDTH(18), + .PREADD_USED(0), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + +module MULT18X18 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [17:0] A, + input [17:0] B, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input SIGNEDA, + input SIGNEDB, + input RSTOUT, + input CEOUT, + output [35:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(18), + .B_WIDTH(18), + .Z_WIDTH(36), + .PREADD_USED(0), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + +module MULT18X36 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [17:0] A, + input [35:0] B, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input SIGNEDA, + input SIGNEDB, + input RSTOUT, + input CEOUT, + output [53:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(18), + .B_WIDTH(36), + .Z_WIDTH(54), + .PREADD_USED(0), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + +module MULT36X36 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [35:0] A, + input [35:0] B, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input SIGNEDA, + input SIGNEDB, + input RSTOUT, + input CEOUT, + output [71:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(36), + .B_WIDTH(36), + .Z_WIDTH(72), + .PREADD_USED(0), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + + +module MULTPREADD9X9 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGINPUTC = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [8:0] A, + input [8:0] B, + input [8:0] C, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input CEC, + input RSTC, + input SIGNEDA, + input SIGNEDB, + input SIGNEDC, + input RSTOUT, + input CEOUT, + output [17:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGINPUTC(REGINPUTC), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(9), + .B_WIDTH(9), + .C_WIDTH(9), + .Z_WIDTH(18), + .PREADD_USED(1), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), .C(C), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .CEC(CEC), .RSTC(RSTC), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), .SIGNEDC(SIGNEDC), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + + +module MULTPREADD18X18 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGINPUTC = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [17:0] A, + input [17:0] B, + input [17:0] C, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input CEC, + input RSTC, + input SIGNEDA, + input SIGNEDB, + input SIGNEDC, + input RSTOUT, + input CEOUT, + output [35:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGINPUTC(REGINPUTC), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(18), + .B_WIDTH(18), + .C_WIDTH(18), + .Z_WIDTH(36), + .PREADD_USED(1), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), .C(C), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .CEC(CEC), .RSTC(RSTC), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), .SIGNEDC(SIGNEDC), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + + +module MULTADDSUB18X18 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGINPUTC = "REGISTER", + parameter REGADDSUB = "REGISTER", + parameter REGLOADC = "REGISTER", + parameter REGLOADC2 = "REGISTER", + parameter REGCIN = "REGISTER", + parameter REGPIPELINE = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [17:0] A, + input [17:0] B, + input [53:0] C, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input CEC, + input RSTC, + input SIGNED, + input RSTPIPE, + input CEPIPE, + input RSTCTRL, + input CECTRL, + input RSTCIN, + input CECIN, + input LOADC, + input ADDSUB, + output [53:0] Z, + input RSTOUT, + input CEOUT, + input CIN +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGINPUTC(REGINPUTC), + .REGADDSUB(REGADDSUB), + .REGLOADC(REGLOADC), + .REGLOADC2(REGLOADC2), + .REGCIN(REGCIN), + .REGPIPELINE(REGPIPELINE), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(18), + .B_WIDTH(18), + .C_WIDTH(54), + .Z_WIDTH(54), + .PREADD_USED(0), + .ADDSUB_USED(1) + ) dsp_i ( + .A(A), .B(B), .C(C), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .CEC(CEC), .RSTC(RSTC), + .CEPIPE(CEPIPE), .RSTPIPE(RSTPIPE), + .CECTRL(CECTRL), .RSTCTRL(RSTCTRL), + .CECIN(CECIN), .RSTCIN(RSTCIN), + .CIN(CIN), .LOADC(LOADC), .ADDSUB(ADDSUB), + .SIGNEDA(SIGNED), .SIGNEDB(SIGNED), .SIGNEDC(SIGNED), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + + +module MULTADDSUB36X36 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGINPUTC = "REGISTER", + parameter REGADDSUB = "REGISTER", + parameter REGLOADC = "REGISTER", + parameter REGLOADC2 = "REGISTER", + parameter REGCIN = "REGISTER", + parameter REGPIPELINE = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [35:0] A, + input [35:0] B, + input [107:0] C, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input CEC, + input RSTC, + input SIGNED, + input RSTPIPE, + input CEPIPE, + input RSTCTRL, + input CECTRL, + input RSTCIN, + input CECIN, + input LOADC, + input ADDSUB, + output [107:0] Z, + input RSTOUT, + input CEOUT, + input CIN +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGINPUTC(REGINPUTC), + .REGADDSUB(REGADDSUB), + .REGLOADC(REGLOADC), + .REGLOADC2(REGLOADC2), + .REGCIN(REGCIN), + .REGPIPELINE(REGPIPELINE), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(36), + .B_WIDTH(36), + .C_WIDTH(108), + .Z_WIDTH(108), + .PREADD_USED(0), + .ADDSUB_USED(1) + ) dsp_i ( + .A(A), .B(B), .C(C), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .CEC(CEC), .RSTC(RSTC), + .CEPIPE(CEPIPE), .RSTPIPE(RSTPIPE), + .CECTRL(CECTRL), .RSTCTRL(RSTCTRL), + .CECIN(CECIN), .RSTCIN(RSTCIN), + .CIN(CIN), .LOADC(LOADC), .ADDSUB(ADDSUB), + .SIGNEDA(SIGNED), .SIGNEDB(SIGNED), .SIGNEDC(SIGNED), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule diff --git a/techlibs/nexus/cells_xtra.py b/techlibs/nexus/cells_xtra.py new file mode 100644 index 000000000..6ced76950 --- /dev/null +++ b/techlibs/nexus/cells_xtra.py @@ -0,0 +1,286 @@ +#!/usr/bin/env python3 + +# Based on Xilinx cells_xtra.py; modified for Radiant's structure + +from argparse import ArgumentParser +from io import StringIO +from enum import Enum, auto +import os.path +import sys +import re + + +class Cell: + def __init__(self, name, keep=False, port_attrs={}): + self.name = name + self.keep = keep + self.port_attrs = port_attrs + self.found = False + +class State(Enum): + OUTSIDE = auto() + IN_MODULE = auto() + IN_OTHER_MODULE = auto() + IN_FUNCTION = auto() + IN_TASK = auto() + +devices = [ + ("lifcl", [ + Cell("ACC54"), + Cell("ADC"), + Cell("ALUREG"), + Cell("BB_ADC", keep=True), + Cell("BB_CDR", keep=True), + Cell("BB_I3C_A", keep=True), + Cell("BFD1P3KX"), + Cell("BFD1P3LX"), + Cell("BNKREF18", keep=True), + Cell("CONFIG_LMMI", keep=True), + Cell("DCC"), + Cell("DCS"), + Cell("DDRDLL"), + Cell("DELAYA"), + Cell("DELAYB"), + Cell("DIFFIO18", keep=True), + Cell("DLLDEL"), + Cell("DP16K_MODE"), + Cell("DP16K"), + Cell("DPHY", keep=True), + Cell("DPSC512K"), + Cell("DQSBUF"), + Cell("EBR_CORE"), + Cell("EBR"), + Cell("ECLKDIV"), + Cell("ECLKSYNC"), + Cell("FBMUX"), + Cell("FIFO16K_MODE"), + Cell("FIFO16K"), + Cell("GSR"), + Cell("HSE"), + Cell("I2CFIFO"), + Cell("IDDR71"), + Cell("IDDRX1"), + Cell("IDDRX2DQ"), + Cell("IDDRX2"), + Cell("IDDRX4DQ"), + Cell("IDDRX4"), + Cell("IDDRX5"), + Cell("IFD1P3BX"), + Cell("IFD1P3DX"), + Cell("IFD1P3IX"), + Cell("IFD1P3JX"), + Cell("JTAG", keep=True), + Cell("LRAM"), + Cell("M18X36"), + Cell("MIPI"), + Cell("MULT18"), +# Cell("MULT18X18"), +# Cell("MULT18X36"), + Cell("MULT36"), +# Cell("MULT36X36"), + Cell("MULT9"), +# Cell("MULT9X9"), +# Cell("MULTADDSUB18X18"), + Cell("MULTADDSUB18X18WIDE"), +# Cell("MULTADDSUB18X36"), +# Cell("MULTADDSUB36X36"), + Cell("MULTADDSUB9X9WIDE"), + Cell("MULTIBOOT", keep=True), +# Cell("MULTPREADD18X18"), +# Cell("MULTPREADD9X9"), + Cell("ODDR71"), + Cell("ODDRX1"), + Cell("ODDRX2DQS"), + Cell("ODDRX2DQ"), + Cell("ODDRX2"), + Cell("ODDRX4DQS"), + Cell("ODDRX4DQ"), + Cell("ODDRX4"), + Cell("ODDRX5"), + Cell("OFD1P3BX"), + Cell("OFD1P3DX"), + Cell("OFD1P3IX"), + Cell("OFD1P3JX"), + Cell("OSC"), + Cell("OSCA"), + Cell("OSHX2"), + Cell("OSHX4"), + Cell("PCIE"), + Cell("PCLKDIV"), + Cell("PCLKDIVSP"), + Cell("PDP16K_MODE"), + Cell("PDP16K"), + Cell("PDPSC16K_MODE"), + Cell("PDPSC16K"), + Cell("PDPSC512K"), + Cell("PLL"), + Cell("PREADD9"), + Cell("PUR", keep=True), + Cell("REFMUX"), + Cell("REG18"), + Cell("SEDC", keep=True), + Cell("SEIO18"), + Cell("SEIO33"), + Cell("SGMIICDR"), + Cell("SP16K_MODE"), + Cell("SP16K"), + Cell("SP512K"), + Cell("TSALLA"), + Cell("TSHX2DQS"), + Cell("TSHX2DQ"), + Cell("TSHX4DQS"), + Cell("TSHX4DQ"), + Cell("WDT", keep=True), + + Cell("ACC54_CORE"), + Cell("ADC_CORE"), + Cell("ALUREG_CORE"), + Cell("BNKREF18_CORE"), + Cell("BNKREF33_CORE"), + Cell("DIFFIO18_CORE"), + Cell("CONFIG_CLKRST_CORE", keep=True), + Cell("CONFIG_HSE_CORE", keep=True), + Cell("CONFIG_IP_CORE", keep=True), + Cell("CONFIG_JTAG_CORE", keep=True), + Cell("CONFIG_LMMI_CORE", keep=True), + Cell("CONFIG_MULTIBOOT_CORE", keep=True), + Cell("CONFIG_SEDC_CORE", keep=True), + Cell("CONFIG_WDT_CORE", keep=True), + Cell("DDRDLL_CORE"), + Cell("DLLDEL_CORE"), + Cell("DPHY_CORE"), + Cell("DQSBUF_CORE"), + Cell("ECLKDIV_CORE"), + Cell("ECLKSYNC_CORE"), + Cell("FBMUX_CORE"), + Cell("GSR_CORE"), + Cell("I2CFIFO_CORE"), + Cell("LRAM_CORE"), + Cell("MULT18_CORE"), + Cell("MULT18X36_CORE"), + Cell("MULT36_CORE"), + Cell("MULT9_CORE"), + Cell("OSC_CORE"), + Cell("PCIE_CORE"), + Cell("PLL_CORE"), + Cell("PREADD9_CORE"), + Cell("REFMUX_CORE"), + Cell("REG18_CORE"), + Cell("SEIO18_CORE"), + Cell("SEIO33_CORE"), + Cell("SGMIICDR_CORE"), + ]) +] + +def xtract_cells_decl(device, cells, dirs, outf): + fname = os.path.join(dir, device + '.v') + with open(fname) as f: + state = State.OUTSIDE + # Probably the most horrible Verilog "parser" ever written. + cell = None + for l in f: + l, _, comment = l.partition('//') + l = l.strip() + if l.startswith("module "): + cell_name = l[7:l.find('(')].strip() + cell = None + module_ports = [] + iopad_pin = set() + if state != State.OUTSIDE: + print('Nested modules in {}.'.format(fname)) + sys.exit(1) + for c in cells: + if c.name != cell_name: + continue + cell = c + state = State.IN_MODULE + if cell.keep: + outf.write('(* keep *)\n') + outf.write('module {} (...);\n'.format(cell.name)) + cell.found = True + + m = re.search(r'synthesis .*black_box_pad_pin="([^"]*)"', comment) + if m: + iopad_pin = set(m.group(1).split(",")) + + if cell is None: + state = State.IN_OTHER_MODULE + elif l.startswith('task '): + if state == State.IN_MODULE: + state = State.IN_TASK + elif l.startswith('function '): + if state == State.IN_MODULE: + state = State.IN_FUNCTION + elif l == 'endtask': + if state == State.IN_TASK: + state = State.IN_MODULE + elif l == 'endfunction': + if state == State.IN_FUNCTION: + state = State.IN_MODULE + elif l == 'endmodule': + if state == State.IN_MODULE: + for kind, rng, port in module_ports: + for attr in cell.port_attrs.get(port, []): + outf.write(' (* {} *)\n'.format(attr)) + if port in iopad_pin: + outf.write(' (* iopad_external_pin *)\n') + if rng is None: + outf.write(' {} {};\n'.format(kind, port)) + else: + outf.write(' {} {} {};\n'.format(kind, rng, port)) + outf.write(l + '\n') + outf.write('\n') + elif state != State.IN_OTHER_MODULE: + print('endmodule in weird place in {}.'.format(cell.name, fname)) + sys.exit(1) + state = State.OUTSIDE + elif l.startswith(('input ', 'output ', 'inout ')) and state == State.IN_MODULE: + if l.endswith((';', ',')): + l = l[:-1] + if ';' in l: + print('Weird port line in {} [{}].'.format(fname, l)) + sys.exit(1) + kind, _, ports = l.partition(' ') + for port in ports.split(','): + port = port.strip() + if port.startswith('['): + rng, port = port.split() + else: + rng = None + module_ports.append((kind, rng, port)) + elif l.startswith('parameter ') and state == State.IN_MODULE: + if l.endswith((';', ',')): + l = l[:-1] + while ' ' in l: + l = l.replace(' ', ' ') + if ';' in l: + print('Weird parameter line in {} [{}].'.format(fname, l)) + sys.exit(1) + outf.write(' {};\n'.format(l)) + + if state != State.OUTSIDE: + print('endmodule not found in {}.'.format(fname)) + sys.exit(1) + for cell in cells: + if not cell.found: + print('cell {} not found in {}.'.format(cell.name, fname)) +if __name__ == '__main__': + parser = ArgumentParser(description='Extract Lattice blackbox cell definitions from Radiant.') + parser.add_argument('radiant_dir', nargs='?', default='/opt/lscc/radiant/2.0/') + args = parser.parse_args() + + dirs = [ + os.path.join(args.radiant_dir, 'cae_library/synthesis/verilog/'), + ] + for dir in dirs: + if not os.path.isdir(dir): + print('{} is not a directory'.format(dir)) + + out = StringIO() + for device, cells in devices: + xtract_cells_decl(device, cells, dirs, out) + + with open('cells_xtra.v', 'w') as f: + f.write('// Created by cells_xtra.py from Lattice models\n') + f.write('\n') + f.write(out.getvalue()) diff --git a/techlibs/nexus/cells_xtra.v b/techlibs/nexus/cells_xtra.v new file mode 100644 index 000000000..6cf3a645d --- /dev/null +++ b/techlibs/nexus/cells_xtra.v @@ -0,0 +1,10389 @@ +// Created by cells_xtra.py from Lattice models + +module ACC54 (...); + parameter SIGN = "DISABLED"; + parameter M9ADDSUB_CTRL = "ADDITION"; + parameter ADDSUB_CTRL = "ADD_ADD_CTRL_54_BIT_ADDER"; + parameter STATICOPCODE_EN = "DISABLED"; + parameter OUTREGBYPS = "REGISTER"; + parameter GSR = "ENABLED"; + parameter PROGCONST = "0b000000000000000000000000000000000000000000000000000000"; + parameter CONSTSEL = "BYPASS"; + parameter DSPCASCADE = "DISABLED"; + parameter ACC108CASCADE = "BYPASSCASCADE"; + parameter ACCUMODE = "MODE0"; + parameter ACCUBYPS = "USED"; + parameter CREGBYPS1 = "REGISTER"; + parameter CREGBYPS2 = "REGISTER"; + parameter CREGBYPS3 = "REGISTER"; + parameter CINREGBYPS1 = "REGISTER"; + parameter CINREGBYPS2 = "REGISTER"; + parameter CINREGBYPS3 = "REGISTER"; + parameter LOADREGBYPS1 = "REGISTER"; + parameter LOADREGBYPS2 = "REGISTER"; + parameter LOADREGBYPS3 = "REGISTER"; + parameter M9ADDSUBREGBYPS1 = "REGISTER"; + parameter M9ADDSUBREGBYPS2 = "REGISTER"; + parameter M9ADDSUBREGBYPS3 = "REGISTER"; + parameter ADDSUBSIGNREGBYPS1 = "REGISTER"; + parameter ADDSUBSIGNREGBYPS2 = "REGISTER"; + parameter ADDSUBSIGNREGBYPS3 = "REGISTER"; + parameter ROUNDHALFUP = "DISABLED"; + parameter ROUNDRTZI = "ROUND_TO_ZERO"; + parameter ROUNDBIT = "ROUND_TO_BIT0"; + parameter CASCOUTREGBYPS = "REGISTER"; + parameter SFTEN = "DISABLED"; + parameter RESET = "SYNC"; + input [3:0] SFTCTRL; + input [53:0] DSPIN; + input [71:0] PP; + input [53:0] CINPUT; + input LOAD; + input [1:0] M9ADDSUB; + input [1:0] ADDSUB; + input CIN; + input [1:0] CASIN; + input CEO; + input RSTO; + input CEC; + input RSTC; + input CLK; + input SIGNEDI; + output [35:0] SUM1; + output [35:0] SUM0; + output [53:0] DSPOUT; + output [1:0] CASCOUT; + input ROUNDEN; + input CECIN; + input CECTRL; + input RSTCIN; + input RSTCTRL; +endmodule + +module ADC (...); + parameter ADC_ENP = "ENABLED"; + parameter CLK_DIV = "2"; + parameter CTLCOMPSW1 = "DISABLED"; + parameter CTLCOMPSW2 = "DISABLED"; + parameter CTLCOMPSW3 = "DISABLED"; + parameter DF = "STRAIGHT_BINARY"; + parameter EN_COMP1 = "ENABLED"; + parameter EN_COMP2 = "ENABLED"; + parameter EN_COMP3 = "ENABLED"; + parameter OMA = "BIPOLAR"; + parameter OMB = "BIPOLAR"; + parameter REFBUFAEN = "ENABLED"; + parameter REFBUFBEN = "ENABLED"; + parameter SLEEP = "DISABLED"; + parameter VREFACFG = "1P0_TO_1P2"; + parameter VREFASEL = "INTERNAL"; + parameter VREFBCFG = "1P0_TO_1P2"; + parameter VREFBSEL = "INTERNAL"; + (* iopad_external_pin *) + input DN0; + (* iopad_external_pin *) + input DN1; + (* iopad_external_pin *) + input DP0; + (* iopad_external_pin *) + input DP1; + input ADCEN; + input CAL; + output CALRDY; + input CHAEN; + input [3:0] CHASEL; + input CHBEN; + input [3:0] CHBSEL; + input CLKDCLK; + input CLKFAB; + output COG; + input COMP1IN; + input COMP1IP; + output COMP1OL; + input COMP2IN; + input COMP2IP; + output COMP2OL; + input COMP3IN; + input COMP3IP; + output COMP3OL; + input CONVSTOP; + output [11:0] DA; + output [11:0] DB; + output EOC; + input [15:0] GPION; + input [15:0] GPIOP; + input RESETN; + input RSTN; + input SOC; + output COMP1O; + output COMP2O; + output COMP3O; +endmodule + +module ALUREG (...); + parameter ALURST_ACTIVELOW = "DISABLE"; + parameter GSR = "ENABLED"; + parameter INREG = "DISABLE"; + parameter MULFXP_ROUND = "ENABLE"; + parameter OUTREG = "DISABLE"; + parameter REGRST_ACTIVELOW = "DISABLE"; + parameter RETAIN = "ENABLE"; + parameter RFASYNC_RD = "SYNC_RD"; + parameter RFR0_RO = "R0READONLY"; + parameter RFUNALIA_WR = "DISABLE"; + parameter RFWCLK_INV = "SIG"; + input ALUCLK; + output ALUFLAGC; + output ALUFLAGV; + output ALUFLAGZ; + input ALUFORWARDA; + input ALUFORWARDB; + input ALUIREGEN; + input ALUOREGEN; + input ALURST; + input [31:0] DATAA; + input [31:0] DATAB; + input [4:0] DATAC; + input [6:0] OPC; + input OPCCUSTOM; + input [4:0] RADDRA; + input [4:0] RADDRB; + output [31:0] RDATAA; + output [31:0] RDATAB; + input REGCLK; + input REGCLKEN; + input REGRST; + output [31:0] RESULT; + input [4:0] WADDR; + input [1:0] WDROTATE; + input WDSIGNEXT; + input [1:0] WDSIZE; + input [31:0] WDATA; + input WREN; +endmodule + +(* keep *) +module BB_ADC (...); + (* iopad_external_pin *) + inout IOPAD; + output INADC; +endmodule + +(* keep *) +module BB_CDR (...); + (* iopad_external_pin *) + inout IOPAD; + output INADC; +endmodule + +(* keep *) +module BB_I3C_A (...); + (* iopad_external_pin *) + inout IOPAD; + output PADDI; + input PADDO; + input PADDT; + input I3CRESEN; + input I3CWKPU; +endmodule + +module BFD1P3KX (...); + parameter GSR = "ENABLED"; + parameter OUTSET = "RESET"; + parameter INSET = "RESET"; + parameter TSSET = "RESET"; + input DOUT; + input DIN; + input DT; + input CEOUT; + input CLKOUT; + input SROUT; + input CEIN; + input CLKIN; + input SRIN; + output QOUT; + output QIN; + output QT; +endmodule + +module BFD1P3LX (...); + parameter GSR = "ENABLED"; + parameter OUTSET = "RESET"; + parameter INSET = "RESET"; + parameter TSSET = "RESET"; + input DOUT; + input DIN; + input DT; + input CEOUT; + input CLKOUT; + input SROUT; + input CEIN; + input CLKIN; + input SRIN; + output QOUT; + output QIN; + output QT; +endmodule + +(* keep *) +module BNKREF18 (...); + parameter BANK = "0b0000"; + parameter STANDBY_DIFFIO = "DISABLED"; + parameter STANDBY_INR = "DISABLED"; + input STDBYINR; + input STDBYDIF; + output [6:0] PVTCODE; +endmodule + +(* keep *) +module CONFIG_LMMI (...); + parameter LMMI_EN = "DIS"; + input LMMICLK; + input LMMIREQUEST; + input LMMIWRRD_N; + input [7:0] LMMIOFFSET; + input [7:0] LMMIWDATA; + output [7:0] LMMIRDATA; + output LMMIREADY; + output LMMIRDATAVALID; + input LMMIRESETN; + input RSTSMCLK; + input SMCLK; +endmodule + +module DDRDLL (...); + parameter GSR = "ENABLED"; + parameter ENA_ROUNDOFF = "ENABLED"; + parameter FORCE_MAX_DELAY = "CODE_OR_LOCK_FROM_DLL_LOOP"; + output [8:0] CODE; + input FREEZE; + output LOCK; + input CLKIN; + input RST; + output [8:0] DCNTL; + input UDDCNTL_N; +endmodule + +module DELAYA (...); + parameter DEL_MODE = "USER_DEFINED"; + parameter DEL_VALUE = "0"; + parameter COARSE_DELAY_MODE = "STATIC"; + parameter COARSE_DELAY = "0NS"; + parameter EDGE_MONITOR = "DISABLED"; + parameter WAIT_FOR_EDGE = "DISABLED"; + input A; + input LOAD_N; + input MOVE; + input DIRECTION; + input COARSE0; + input COARSE1; + input RANKSELECT; + input RANKENABLE; + input RANK0UPDATE; + input RANK1UPDATE; + output Z; + output EDETERR; + output CFLAG; +endmodule + +module DELAYB (...); + parameter DEL_VALUE = "0"; + parameter COARSE_DELAY = "0NS"; + parameter DEL_MODE = "USER_DEFINED"; + input A; + output Z; +endmodule + +(* keep *) +module DIFFIO18 (...); + parameter PULLMODE = "DOWN"; + parameter ENADC_IN = "DISABLED"; + parameter MIPI = "DISABLED"; + input PADDO; + input DOLP; + (* iopad_external_pin *) + inout IOPAD; + output PADDI; + output INLP; + input PADDT; + output INADC; + input HSRXEN; + input HSTXEN; +endmodule + +module DLLDEL (...); + parameter ADJUST = "0"; + parameter DEL_ADJUST = "PLUS"; + parameter ENABLE = "ENABLED"; + input CLKIN; + output CLKOUT; + input [8:0] CODE; + output COUT; + input DIR; + input LOAD_N; + input MOVE; +endmodule + +module DP16K_MODE (...); + parameter DATA_WIDTH_A = "X18"; + parameter DATA_WIDTH_B = "X18"; + parameter OUTREG_A = "BYPASSED"; + parameter OUTREG_B = "BYPASSED"; + parameter GSR = "ENABLED"; + parameter RESETMODE_A = "SYNC"; + parameter RESETMODE_B = "SYNC"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter CSDECODE_A = "000"; + parameter CSDECODE_B = "000"; + parameter ASYNC_RST_RELEASE_A = "SYNC"; + parameter ASYNC_RST_RELEASE_B = "SYNC"; + parameter INIT_DATA = "STATIC"; + input DIA0; + input DIA1; + input DIA2; + input DIA3; + input DIA4; + input DIA5; + input DIA6; + input DIA7; + input DIA8; + input DIA9; + input DIA10; + input DIA11; + input DIA12; + input DIA13; + input DIA14; + input DIA15; + input DIA16; + input DIA17; + input DIB0; + input DIB1; + input DIB2; + input DIB3; + input DIB4; + input DIB5; + input DIB6; + input DIB7; + input DIB8; + input DIB9; + input DIB10; + input DIB11; + input DIB12; + input DIB13; + input DIB14; + input DIB15; + input DIB16; + input DIB17; + input ADA0; + input ADA1; + input ADA2; + input ADA3; + input ADA4; + input ADA5; + input ADA6; + input ADA7; + input ADA8; + input ADA9; + input ADA10; + input ADA11; + input ADA12; + input ADA13; + input ADB0; + input ADB1; + input ADB2; + input ADB3; + input ADB4; + input ADB5; + input ADB6; + input ADB7; + input ADB8; + input ADB9; + input ADB10; + input ADB11; + input ADB12; + input ADB13; + input CLKA; + input CLKB; + input CEA; + input CEB; + input WEA; + input WEB; + input CSA0; + input CSA1; + input CSA2; + input CSB0; + input CSB1; + input CSB2; + input RSTA; + input RSTB; + output DOA0; + output DOA1; + output DOA2; + output DOA3; + output DOA4; + output DOA5; + output DOA6; + output DOA7; + output DOA8; + output DOA9; + output DOA10; + output DOA11; + output DOA12; + output DOA13; + output DOA14; + output DOA15; + output DOA16; + output DOA17; + output DOB0; + output DOB1; + output DOB2; + output DOB3; + output DOB4; + output DOB5; + output DOB6; + output DOB7; + output DOB8; + output DOB9; + output DOB10; + output DOB11; + output DOB12; + output DOB13; + output DOB14; + output DOB15; + output DOB16; + output DOB17; +endmodule + +module DP16K (...); + parameter DATA_WIDTH_A = "X18"; + parameter DATA_WIDTH_B = "X18"; + parameter OUTREG_A = "BYPASSED"; + parameter OUTREG_B = "BYPASSED"; + parameter GSR = "ENABLED"; + parameter RESETMODE_A = "SYNC"; + parameter RESETMODE_B = "SYNC"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter CSDECODE_A = "000"; + parameter CSDECODE_B = "000"; + parameter ASYNC_RST_RELEASE_A = "SYNC"; + parameter ASYNC_RST_RELEASE_B = "SYNC"; + parameter INIT_DATA = "STATIC"; + input [17:0] DIA; + input [17:0] DIB; + input [13:0] ADA; + input [13:0] ADB; + input CLKA; + input CLKB; + input CEA; + input CEB; + input WEA; + input WEB; + input [2:0] CSA; + input [2:0] CSB; + input RSTA; + input RSTB; + output [17:0] DOA; + output [17:0] DOB; +endmodule + +(* keep *) +module DPHY (...); + parameter GSR = "ENABLED"; + parameter AUTO_PD_EN = "POWERED_UP"; + parameter CFG_NUM_LANES = "ONE_LANE"; + parameter CM = "0b00000000"; + parameter CN = "0b00000"; + parameter CO = "0b000"; + parameter CONT_CLK_MODE = "DISABLED"; + parameter DESKEW_EN = "DISABLED"; + parameter DSI_CSI = "CSI2_APP"; + parameter EN_CIL = "CIL_ENABLED"; + parameter HSEL = "DISABLED"; + parameter LANE0_SEL = "LANE_0"; + parameter LOCK_BYP = "GATE_TXBYTECLKHS"; + parameter MASTER_SLAVE = "SLAVE"; + parameter PLLCLKBYPASS = "REGISTERED"; + parameter RSEL = "0b00"; + parameter RXCDRP = "0b00"; + parameter RXDATAWIDTHHS = "0b00"; + parameter RXLPRP = "0b000"; + parameter TEST_ENBL = "0b000000"; + parameter TEST_PATTERN = "0b00000000000000000000000000000000"; + parameter TST = "0b1001"; + parameter TXDATAWIDTHHS = "0b00"; + parameter U_PRG_HS_PREPARE = "0b00"; + parameter U_PRG_HS_TRAIL = "0b000000"; + parameter U_PRG_HS_ZERO = "0b000000"; + parameter U_PRG_RXHS_SETTLE = "0b000000"; + parameter UC_PRG_HS_PREPARE = "1P0_TXCLKESC"; + parameter UC_PRG_HS_TRAIL = "0b00000"; + parameter UC_PRG_HS_ZERO = "0b0000000"; + parameter UC_PRG_RXHS_SETTLE = "0b000000"; + input LMMICLK; + input LMMIRESET_N; + input LMMIREQUEST; + input LMMIWRRD_N; + input [4:0] LMMIOFFSET; + input [3:0] LMMIWDATA; + output [3:0] LMMIRDATA; + output LMMIRDATAVALID; + output LMMIREADY; + input BITCKEXT; + (* iopad_external_pin *) + inout CKN; + (* iopad_external_pin *) + inout CKP; + input CLKREF; + output [1:0] D0ACTIVE; + output [9:0] D0BYTCNT; + output [9:0] D0ERRCNT; + output [1:0] D0PASS; + output [1:0] D0VALID; + output [1:0] D1ACTIVE; + output [9:0] D1BYTCNT; + output [9:0] D1ERRCNT; + output [1:0] D1PASS; + output [1:0] D1VALID; + output [1:0] D2ACTIVE; + output [9:0] D2BYTCNT; + output [9:0] D2ERRCNT; + output [1:0] D2PASS; + output [1:0] D2VALID; + output [1:0] D3ACTIVE; + output [9:0] D3BYTCNT; + output [9:0] D3ERRCNT; + output [1:0] D3PASS; + output [1:0] D3VALID; + output [9:0] DCTSTOUT; + (* iopad_external_pin *) + inout DN0; + (* iopad_external_pin *) + inout DN1; + (* iopad_external_pin *) + inout DN2; + (* iopad_external_pin *) + inout DN3; + (* iopad_external_pin *) + inout DP0; + (* iopad_external_pin *) + inout DP1; + (* iopad_external_pin *) + inout DP2; + (* iopad_external_pin *) + inout DP3; + output LOCK; + input PDDPHY; + input PDPLL; + input SCCLKIN; + output UDIR; + input UED0THEN; + output UERCLP0; + output UERCLP1; + output UERCTRL; + output UERE; + output UERSTHS; + output UERSSHS; + output UERSE; + input UFRXMODE; + input UTXMDTX; + output URXACTHS; + output URXCKE; + input URXCKINE; + output [7:0] URXDE; + output [15:0] URXDHS; + output URXLPDTE; + output URXSKCHS; + output URXDRX; + output [3:0] URXSHS; + output URE0D3DP; + output URE1D3DN; + output URE2CKDP; + output URE3CKDN; + output URXULPSE; + output URXVDE; + output [3:0] URXVDHS; + output USSTT; + input UTDIS; + input UTXCKE; + input UDE0D0TN; + input UDE1D1TN; + input UDE2D2TN; + input UDE3D3TN; + input UDE4CKTN; + input UDE5D0RN; + input UDE6D1RN; + input UDE7D2RN; + input [31:0] UTXDHS; + input UTXENER; + output UTXRRS; + output UTXRYP; + output UTXRYSK; + input UTXRD0EN; + input UTRD0SEN; + input UTXSKD0N; + input UTXTGE0; + input UTXTGE1; + input UTXTGE2; + input UTXTGE3; + input UTXULPSE; + input UTXUPSEX; + input UTXVDE; + input [3:0] UTXWVDHS; + output UUSAN; + output U1DIR; + input U1ENTHEN; + output U1ERCLP0; + output U1ERCLP1; + output U1ERCTRL; + output U1ERE; + output U1ERSTHS; + output U1ERSSHS; + output U1ERSE; + input U1FRXMD; + input U1FTXST; + output U1RXATHS; + output U1RXCKE; + output [7:0] U1RXDE; + output [15:0] U1RXDHS; + output U1RXDTE; + output U1RXSKS; + output U1RXSK; + output [3:0] U1RXSHS; + output U1RE0D; + output U1RE1CN; + output U1RE2D; + output U1RE3N; + output U1RXUPSE; + output U1RXVDE; + output [3:0] U1RXVDHS; + output U1SSTT; + input U1TDIS; + input U1TREQ; + input U1TDE0D3; + input U1TDE1CK; + input U1TDE2D0; + input U1TDE3D1; + input U1TDE4D2; + input U1TDE5D3; + input U1TDE6; + input U1TDE7; + input [31:0] U1TXDHS; + input U1TXLPD; + output U1TXRYE; + output U1TXRY; + output U1TXRYSK; + input U1TXREQ; + input U1TXREQH; + input U1TXSK; + input U1TXTGE0; + input U1TXTGE1; + input U1TXTGE2; + input U1TXTGE3; + input U1TXUPSE; + input U1TXUPSX; + input U1TXVDE; + input [3:0] U1TXWVHS; + output U1USAN; + output U2DIR; + input U2END2; + output U2ERCLP0; + output U2ERCLP1; + output U2ERCTRL; + output U2ERE; + output U2ERSTHS; + output U2ERSSHS; + output U2ERSE; + input U2FRXMD; + input U2FTXST; + output U2RXACHS; + output U2RXCKE; + output [7:0] U2RXDE; + output [15:0] U2RXDHS; + output U2RPDTE; + output U2RXSK; + output U2RXSKC; + output [3:0] U2RXSHS; + output U2RE0D2; + output U2RE1D2; + output U2RE2D3; + output U2RE3D3; + output U2RXUPSE; + output U2RXVDE; + output [3:0] U2RXVDHS; + output U2SSTT; + input U2TDIS; + input U2TREQ; + input U2TDE0D0; + input U2TDE1D1; + input U2TDE2D2; + input U2TDE3D3; + input U2TDE4CK; + input U2TDE5D0; + input U2TDE6D1; + input U2TDE7D2; + input [31:0] U2TXDHS; + input U2TPDTE; + output U2TXRYE; + output U2TXRYH; + output U2TXRYSK; + input U2TXREQ; + input U2TXREQH; + input U2TXSKC; + input U2TXTGE0; + input U2TXTGE1; + input U2TXTGE2; + input U2TXTGE3; + input U2TXUPSE; + input U2TXUPSX; + input U2TXVDE; + input [3:0] U2TXWVHS; + output U2USAN; + output U3DIR; + input U3END3; + output U3ERCLP0; + output U3ERCLP1; + output U3ERCTRL; + output U3ERE; + output U3ERSTHS; + output U3ERSSHS; + output U3ERSE; + input U3FRXMD; + input U3FTXST; + output U3RXATHS; + output U3RXCKE; + output [7:0] U3RXDE; + output [15:0] U3RXDHS; + output U3RPDTE; + output U3RXSK; + output U3RXSKC; + output [3:0] U3RXSHS; + output U3RE0CK; + output U3RE1CK; + output U3RE2; + output U3RE3; + output U3RXUPSE; + output U3RXVDE; + output [3:0] U3RXVDHS; + output U3SSTT; + input U3TDISD2; + input U3TREQD2; + input U3TDE0D3; + input U3TDE1D0; + input U3TDE2D1; + input U3TDE3D2; + input U3TDE4D3; + input U3TDE5CK; + input U3TDE6; + input U3TDE7; + input [31:0] U3TXDHS; + input U3TXLPDT; + output U3TXRY; + output U3TXRYHS; + output U3TXRYSK; + input U3TXREQ; + input U3TXREQH; + input U3TXSKC; + input U3TXTGE0; + input U3TXTGE1; + input U3TXTGE2; + input U3TXTGE3; + input U3TXULPS; + input U3TXUPSX; + input U3TXVD3; + input [3:0] U3TXWVHS; + output U3USAN; + input UCENCK; + output UCRXCKAT; + output UCRXUCKN; + output UCSSTT; + input UCTXREQH; + input UCTXUPSC; + input UCTXUPSX; + output UCUSAN; + input LTSTEN; + input [1:0] LTSTLANE; + output URWDCKHS; + input UTRNREQ; + output UTWDCKHS; + output UCRXWCHS; + output CLKLBACT; +endmodule + +module DPSC512K (...); + parameter OUTREG_A = "NO_REG"; + parameter OUTREG_B = "NO_REG"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_40 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_41 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_42 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_43 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_44 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_45 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_46 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_47 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_48 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_49 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_50 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_51 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_52 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_53 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_54 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_55 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_56 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_57 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_58 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_59 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_60 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_61 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_62 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_63 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_64 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_65 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_66 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_67 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_68 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_69 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_70 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_71 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_72 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_73 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_74 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_75 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_76 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_77 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_78 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_79 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter ECC_BYTE_SEL = "ECC_EN"; + input [31:0] DIA; + input [31:0] DIB; + input [13:0] ADA; + input [13:0] ADB; + input CLK; + input CEA; + input CEB; + input WEA; + input WEB; + input CSA; + input CSB; + input RSTA; + input RSTB; + input [3:0] BENA_N; + input [3:0] BENB_N; + input CEOUTA; + input CEOUTB; + output [31:0] DOA; + output [31:0] DOB; + output [1:0] ERRDECA; + output [1:0] ERRDECB; +endmodule + +module DQSBUF (...); + parameter GSR = "ENABLED"; + parameter ENABLE_FIFO = "DISABLED"; + parameter FORCE_READ = "DISABLED"; + parameter FREE_WHEEL = "DDR"; + parameter MODX = "NOT_USED"; + parameter MT_EN_READ = "DISABLED"; + parameter MT_EN_WRITE = "DISABLED"; + parameter MT_EN_WRITE_LEVELING = "DISABLED"; + parameter RD_PNTR = "0b000"; + parameter READ_ENABLE = "DISABLED"; + parameter RX_CENTERED = "ENABLED"; + parameter S_READ = "0"; + parameter S_WRITE = "0"; + parameter SIGN_READ = "POSITIVE"; + parameter SIGN_WRITE = "POSITIVE"; + parameter UPDATE_QU = "UP1_AND_UP0_SAME"; + parameter WRITE_ENABLE = "DISABLED"; + parameter SEL_READ_BIT_ENABLE_CYCLES = "NORMAL"; + parameter BYPASS_WR_LEVEL_SMTH_LATCH = "SMOOTHING_PATH"; + parameter BYPASS_WR_SMTH_LATCH = "SMOOTHING_PATH"; + parameter BYPASS_READ_SMTH_LATCH = "SMOOTHING_PATH"; + output BTDETECT; + output BURSTDETECT; + output DATAVALID; + input DQSI; + output DQSW; + output DQSWRD; + input PAUSE; + input [3:0] RDCLKSEL; + input RDDIR; + input RDLOADN; + output [2:0] RDPNTR; + input [3:0] READ; + output READCOUT; + input READMOVE; + input RST; + input SCLK; + input SELCLK; + output DQSR90; + output DQSW270; + output WRCOUT; + input WRDIR; + input WRLOAD_N; + output WRLVCOUT; + input WRLVDIR; + input WRLVLOAD_N; + input WRLVMOVE; + input WRMOVE; + output [2:0] WRPNTR; + input ECLKIN; + input RSTSMCNT; + input [8:0] DLLCODE; +endmodule + +module EBR_CORE (...); + parameter INIT_DATA = "STATIC"; + parameter DATA_WIDTH_A = "X36"; + parameter DATA_WIDTH_B = "X36"; + parameter REGMODE_A = "BYPASSED"; + parameter REGMODE_B = "BYPASSED"; + parameter GSR = "ENABLED"; + parameter CSDECODE_A = "000"; + parameter CSDECODE_B = "000"; + parameter WID = "0b00000000000"; + parameter RESETMODE_A = "SYNC"; + parameter ASYNC_RESET_RELEASE_A = "SYNC"; + parameter RESETMODE_B = "SYNC"; + parameter ASYNC_RESET_RELEASE_B = "SYNC"; + parameter ECC = "DISABLED"; + parameter EBR_MODE = "DP"; + parameter FULL = "0b11111111100000"; + parameter ALMOST_FULL = "0b00000000000000"; + parameter EMPTY = "0b11111"; + parameter ALMOST_EMPTY = "0b00000000000000"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + input DIA0; + input DIA1; + input DIA2; + input DIA3; + input DIA4; + input DIA5; + input DIA6; + input DIA7; + input DIA8; + input DIA9; + input DIA10; + input DIA11; + input DIA12; + input DIA13; + input DIA14; + input DIA15; + input DIA16; + input DIA17; + input DIB0; + input DIB1; + input DIB2; + input DIB3; + input DIB4; + input DIB5; + input DIB6; + input DIB7; + input DIB8; + input DIB9; + input DIB10; + input DIB11; + input DIB12; + input DIB13; + input DIB14; + input DIB15; + input DIB16; + input DIB17; + input ADA0; + input ADA1; + input ADA2; + input ADA3; + input ADA4; + input ADA5; + input ADA6; + input ADA7; + input ADA8; + input ADA9; + input ADA10; + input ADA11; + input ADA12; + input ADA13; + input ADB0; + input ADB1; + input ADB2; + input ADB3; + input ADB4; + input ADB5; + input ADB6; + input ADB7; + input ADB8; + input ADB9; + input ADB10; + input ADB11; + input ADB12; + input ADB13; + input CLKA; + input CLKB; + input WEA; + input WEB; + input CEA; + input CEB; + input RSTA; + input RSTB; + input CSA0; + input CSA1; + input CSA2; + input CSB0; + input CSB1; + input CSB2; + output FULLF; + output AFULL; + output EMPTYF; + output AEMPTY; + output DOA0; + output DOA1; + output DOA2; + output DOA3; + output DOA4; + output DOA5; + output DOA6; + output DOA7; + output DOA8; + output DOA9; + output DOA10; + output DOA11; + output DOA12; + output DOA13; + output DOA14; + output DOA15; + output DOA16; + output DOA17; + output DOB0; + output DOB1; + output DOB2; + output DOB3; + output DOB4; + output DOB5; + output DOB6; + output DOB7; + output DOB8; + output DOB9; + output DOB10; + output DOB11; + output DOB12; + output DOB13; + output DOB14; + output DOB15; + output DOB16; + output DOB17; + output ONEERR; + output TWOERR; +endmodule + +module EBR (...); + parameter INIT_DATA = "STATIC"; + parameter DATA_WIDTH_A = "X36"; + parameter DATA_WIDTH_B = "X36"; + parameter REGMODE_A = "BYPASSED"; + parameter REGMODE_B = "BYPASSED"; + parameter GSR = "ENABLED"; + parameter CSDECODE_A = "000"; + parameter CSDECODE_B = "000"; + parameter WID = "0b00000000000"; + parameter RESETMODE_A = "SYNC"; + parameter ASYNC_RESET_RELEASE_A = "SYNC"; + parameter RESETMODE_B = "SYNC"; + parameter ASYNC_RESET_RELEASE_B = "SYNC"; + parameter ECC = "DISABLED"; + parameter EBR_MODE = "DP"; + parameter FULL = "0b11111111100000"; + parameter ALMOST_FULL = "0b00000000000000"; + parameter ALMOST_EMPTY = "0b00000000000000"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + input [17:0] DIA; + input [17:0] DIB; + input [13:0] ADA; + input [13:0] ADB; + input CLKA; + input CLKB; + input WEA; + input WEB; + input CEA; + input CEB; + input RSTA; + input RSTB; + input [2:0] CSA; + input [2:0] CSB; + output FULLF; + output AFULL; + output EMPTYF; + output AEMPTY; + output [17:0] DOA; + output [17:0] DOB; + output ONEERR; + output TWOERR; +endmodule + +module ECLKDIV (...); + parameter ECLK_DIV = "DISABLE"; + parameter GSR = "ENABLED"; + output DIVOUT; + input DIVRST; + input ECLKIN; + input SLIP; +endmodule + +module ECLKSYNC (...); + parameter STOP_EN = "DISABLE"; + input ECLKIN; + output ECLKOUT; + input STOP; +endmodule + +module FBMUX (...); + parameter INTFB = "IGNORED"; + parameter SEL_FBK = "DIVA"; + parameter CLKMUX_FB = "CMUX_CLKOP"; + parameter INTFBKDEL_SEL = "DISABLED"; + output ENEXT; + output FBKCK; + input LGYRDYN; + input INTLOCK; + input WKUPSYNC; + input [15:0] FBKCLK; +endmodule + +module FIFO16K_MODE (...); + parameter DATA_WIDTH_A = "X18"; + parameter DATA_WIDTH_B = "X18"; + parameter OUTREG_A = "BYPASSED"; + parameter OUTREG_B = "BYPASSED"; + parameter GSR = "ENABLED"; + parameter RESETMODE_A = "SYNC"; + parameter RESETMODE_B = "SYNC"; + parameter ASYNC_RST_RELEASE_A = "SYNC"; + parameter ASYNC_RST_RELEASE_B = "SYNC"; + parameter ALMOST_FULL = "0b00000000000000"; + parameter ALMOST_EMPTY = "0b00000000000000"; + parameter ECC = "DISABLED"; + parameter FULLBITS = "0b11111111100000"; + input DIA0; + input DIA1; + input DIA2; + input DIA3; + input DIA4; + input DIA5; + input DIA6; + input DIA7; + input DIA8; + input DIA9; + input DIA10; + input DIA11; + input DIA12; + input DIA13; + input DIA14; + input DIA15; + input DIA16; + input DIA17; + input DIB0; + input DIB1; + input DIB2; + input DIB3; + input DIB4; + input DIB5; + input DIB6; + input DIB7; + input DIB8; + input DIB9; + input DIB10; + input DIB11; + input DIB12; + input DIB13; + input DIB14; + input DIB15; + input DIB16; + input DIB17; + input CKA; + input CKB; + input CEA; + input CEB; + input CSA0; + input CSA1; + input CSA2; + input CSB0; + input CSB1; + input CSB2; + input RSTA; + input RSTB; + output DOA0; + output DOA1; + output DOA2; + output DOA3; + output DOA4; + output DOA5; + output DOA6; + output DOA7; + output DOA8; + output DOA9; + output DOA10; + output DOA11; + output DOA12; + output DOA13; + output DOA14; + output DOA15; + output DOA16; + output DOA17; + output DOB0; + output DOB1; + output DOB2; + output DOB3; + output DOB4; + output DOB5; + output DOB6; + output DOB7; + output DOB8; + output DOB9; + output DOB10; + output DOB11; + output DOB12; + output DOB13; + output DOB14; + output DOB15; + output DOB16; + output DOB17; + output ALMOSTFULL; + output FULL; + output ALMOSTEMPTY; + output EMPTY; + output ONEBITERR; + output TWOBITERR; +endmodule + +module FIFO16K (...); + parameter DATA_WIDTH_A = "X18"; + parameter DATA_WIDTH_B = "X18"; + parameter OUTREG_A = "BYPASSED"; + parameter OUTREG_B = "BYPASSED"; + parameter GSR = "ENABLED"; + parameter RESETMODE_A = "SYNC"; + parameter RESETMODE_B = "SYNC"; + parameter ASYNC_RST_RELEASE_A = "SYNC"; + parameter ASYNC_RST_RELEASE_B = "SYNC"; + parameter ALMOST_FULL = "0b00000000000000"; + parameter ALMOST_EMPTY = "0b00000000000000"; + parameter ECC = "DISABLED"; + parameter FULLBITS = "0b11111111100000"; + input [17:0] DIA; + input [17:0] DIB; + input CKA; + input CKB; + input CEA; + input CEB; + input [2:0] CSA; + input [2:0] CSB; + input RSTA; + input RSTB; + output [17:0] DOA; + output [17:0] DOB; + output ALMOSTFULL; + output FULL; + output ALMOSTEMPTY; + output EMPTY; + output ONEBITERR; + output TWOBITERR; +endmodule + +module HSE (...); + parameter MCGLBGSRNDIS = "EN"; + parameter MCHSEDISABLE = "EN"; + parameter MCHSEOTPEN = "DIS"; + input LMMICLK; + input LMMIRESET_N; + input LMMIREQUEST; + input LMMIWRRD_N; + input [17:0] LMMIOFFSET; + input [31:0] LMMIWDATA; + output [31:0] LMMIRDATA; + output LMMIRDATAVALID; + output LMMIREADY; + input ASFCLKI; + output ASFEMPTYO; + output ASFFULLO; + input ASFRDI; + input ASFRESETI; + input ASFWRI; + input CFG_CLK; + input HSE_CLK; + input HSELRSTN; +endmodule + +module I2CFIFO (...); + parameter BRNBASEDELAY = "0b0000"; + parameter CR1CKDIS = "EN"; + parameter CR1FIFOMODE = "REG"; + parameter CR1GCEN = "DIS"; + parameter CR1I2CEN = "DIS"; + parameter CR1SDADELSEL = "NDLY0"; + parameter CR1SLPCLKEN = "DIS"; + parameter CR2CORERSTN = "DIS"; + parameter CR2HARDTIE = "TIE"; + parameter CR2INTCLREN = "DIS"; + parameter CR2MRDCMPLWKUP = "DIS"; + parameter CR2RXFIFOAFWKUP = "DIS"; + parameter CR2SLVADDRWKUP = "DIS"; + parameter GSR = "ENABLED"; + parameter I2CRXFIFOAFVAL = "0b00000"; + parameter I2CSLVADDRA = "0b0000000000"; + parameter I2CTXFIFOAEVAL = "0b0000"; + parameter INTARBLIE = "DIS"; + parameter INTBUSFREEIE = "DIS"; + parameter INTHGCIE = "DIS"; + parameter INTMRDCMPLIE = "DIS"; + parameter INTRNACKIEORRSVD = "DIS"; + parameter INTRSVDORTROEIE = "DIS"; + parameter INTRSVDORTRRDYIE = "DIS"; + parameter INTRXOVERFIEORRSVD = "DIS"; + parameter INTRXUNDERFIE = "DIS"; + parameter INTTXOVERFIE = "DIS"; + parameter INTTXSERRIEORRSVD = "DIS"; + parameter LMMI_EXTRA_ONE = "DIS"; + parameter LMMI_EXTRA_TWO = "DIS"; + parameter NCRALTIOEN = "FABRIC"; + parameter NCRFILTERDIS = "EN"; + parameter NCRSDAINDLYEN = "DIS"; + parameter NCRSDAOUTDLYEN = "DIS"; + parameter NONUSRTESTSOFTTRIMEN = "DIS"; + parameter NONUSRTSTSOFTTRIMVALUE = "0b000"; + parameter REGI2CBR = "0b0000000000"; + parameter TSPTIMERVALUE = "0b10010010111"; + input LMMICLK; + input LMMIRESET_N; + input LMMIREQUEST; + input LMMIWRRD_N; + input [5:0] LMMIOFFSET; + input [7:0] LMMIWDATA; + output [7:0] LMMIRDATA; + output LMMIRDATAVALID; + output LMMIREADY; + input ALTSCLIN; + output ALTSCLOEN; + output ALTSCLOUT; + input ALTSDAIN; + output ALTSDAOEN; + output ALTSDAOUT; + output BUSBUSY; + input FIFORESET; + input I2CLSRRSTN; + output INSLEEP; + output IRQ; + output MRDCMPL; + output RXFIFOAF; + output RXFIFOE; + output RXFIFOF; + input SCLIN; + output SCLOE; + output SCLOEN; + output SCLOUT; + input SDAIN; + output SDAOE; + output SDAOEN; + output SDAOUT; + output SLVADDRMATCH; + output SLVADDRMATCHSCL; + output SRDWR; + output TXFIFOAE; + output TXFIFOE; + output TXFIFOF; +endmodule + +module IDDR71 (...); + parameter GSR = "ENABLED"; + input D; + input SCLK; + input RST; + input ECLK; + input ALIGNWD; + output Q0; + output Q1; + output Q2; + output Q3; + output Q4; + output Q5; + output Q6; +endmodule + +module IDDRX1 (...); + parameter GSR = "ENABLED"; + input D; + input SCLK; + input RST; + output Q0; + output Q1; +endmodule + +module IDDRX2DQ (...); + parameter GSR = "ENABLED"; + input D; + input DQSR90; + input ECLK; + input SCLK; + input RST; + input RDPNTR0; + input RDPNTR1; + input RDPNTR2; + input WRPNTR0; + input WRPNTR1; + input WRPNTR2; + output Q0; + output Q1; + output Q2; + output Q3; +endmodule + +module IDDRX2 (...); + parameter GSR = "ENABLED"; + input D; + input SCLK; + input RST; + input ECLK; + input ALIGNWD; + output Q0; + output Q1; + output Q2; + output Q3; +endmodule + +module IDDRX4DQ (...); + parameter GSR = "ENABLED"; + input D; + input DQSR90; + input ECLK; + input SCLK; + input RST; + input RDPNTR0; + input RDPNTR1; + input RDPNTR2; + input WRPNTR0; + input WRPNTR1; + input WRPNTR2; + output Q0; + output Q1; + output Q2; + output Q3; + output Q4; + output Q5; + output Q6; + output Q7; +endmodule + +module IDDRX4 (...); + parameter GSR = "ENABLED"; + input D; + input SCLK; + input RST; + input ECLK; + input ALIGNWD; + output Q0; + output Q1; + output Q2; + output Q3; + output Q4; + output Q5; + output Q6; + output Q7; +endmodule + +module IDDRX5 (...); + parameter GSR = "ENABLED"; + input D; + input SCLK; + input RST; + input ECLK; + input ALIGNWD; + output Q0; + output Q1; + output Q2; + output Q3; + output Q4; + output Q5; + output Q6; + output Q7; + output Q8; + output Q9; +endmodule + +module IFD1P3BX (...); + parameter GSR = "ENABLED"; + input D; + input SP; + input CK; + input PD; + output Q; +endmodule + +module IFD1P3DX (...); + parameter GSR = "ENABLED"; + input D; + input SP; + input CK; + input CD; + output Q; +endmodule + +module IFD1P3IX (...); + parameter GSR = "ENABLED"; + input D; + input SP; + input CK; + input CD; + output Q; +endmodule + +module IFD1P3JX (...); + parameter GSR = "ENABLED"; + input D; + input SP; + input CK; + input PD; + output Q; +endmodule + +(* keep *) +module JTAG (...); + parameter MCER1EXIST = "NEXIST"; + parameter MCER2EXIST = "NEXIST"; + output JCE1; + output JCE2; + output JRSTN; + output JRTI1; + output JRTI2; + output JSHIFT; + output JTDI; + output JUPDATE; + input JTDO1; + input JTDO2; + input SMCLK; + input TCK; + output JTCK; + input TDI; + output TDO_OEN; + output TDO; + input TMS; +endmodule + +module LRAM (...); + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_40 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_41 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_42 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_43 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_44 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_45 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_46 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_47 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_48 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_49 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_50 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_51 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_52 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_53 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_54 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_55 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_56 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_57 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_58 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_59 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_60 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_61 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_62 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_63 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_64 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_65 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_66 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_67 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_68 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_69 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_70 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_71 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_72 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_73 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_74 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_75 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_76 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_77 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_78 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_79 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter ASYNC_RST_RELEASE = "SYNC"; + parameter CFG_INIT_ID = "0b00000000000"; + parameter DATA_PRESERVE = "DISABLE"; + parameter EBR_SP_EN = "DISABLE"; + parameter ECC_BYTE_SEL = "ECC_EN"; + parameter GSR = "ENABLED"; + parameter OUT_REGMODE_A = "NO_REG"; + parameter OUT_REGMODE_B = "NO_REG"; + parameter RESETMODE = "SYNC"; + parameter RST_AB_EN = "RESET_AB_DISABLE"; + parameter SP_EN = "DISABLE"; + parameter UNALIGNED_READ = "DISABLE"; + input [13:0] ADA; + input [13:0] ADB; + input [3:0] BENA_N; + input [3:0] BENB_N; + input CEA; + input CEB; + input CLK; + input CSA; + input CSB; + input [31:0] DIA; + input [31:0] DIB; + output [31:0] DOA; + output [31:0] DOB; + input DPS; + output [1:0] ERRDECA; + output [1:0] ERRDECB; + input OCEA; + input OCEB; + output OEA; + output OEB; + input RSTA; + input RSTB; + input WEA; + input WEB; + output ERRDET; + output LRAMREADY; +endmodule + +module M18X36 (...); + parameter SFTEN = "DISABLED"; + parameter MULT18X36 = "ENABLED"; + parameter MULT36 = "DISABLED"; + parameter MULT36X36H = "USED_AS_LOWER_BIT_GENERATION"; + parameter ROUNDHALFUP = "DISABLED"; + parameter ROUNDRTZI = "ROUND_TO_ZERO"; + parameter ROUNDBIT = "ROUND_TO_BIT0"; + input [3:0] SFTCTRL; + input [37:0] PH36; + input [37:0] PL36; + input SGNED18H; + input SGNED18L; + output [72:0] P72; + input ROUNDEN; +endmodule + +module MULT18 (...); + parameter SFTEN = "DISABLED"; + parameter MULT18X18 = "ENABLED"; + parameter ROUNDHALFUP = "DISABLED"; + parameter ROUNDRTZI = "ROUND_TO_ZERO"; + parameter ROUNDBIT = "ROUND_TO_BIT0"; + input [3:0] SFTCTRL; + input ARHSIGN; + input BRHSIGN; + input [8:0] ARH; + input [8:0] BRH; + input [8:0] ARL; + input [8:0] BRL; + input [19:0] PL18; + input [19:0] PH18; + output SIGNED18; + output [37:0] P36; + input ROUNDEN; +endmodule + +module MULT36 (...); + parameter MULT36X36 = "ENABLED"; + input [72:0] PH72; + input [72:0] PL72; + output [71:0] PML72; + output [71:0] PMH72; +endmodule + +module MULT9 (...); + parameter SIGNEDSTATIC_EN = "DISABLED"; + parameter ASIGNED_OPERAND_EN = "DISABLED"; + parameter BYPASS_MULT9 = "USED"; + parameter REGBYPSB = "REGISTER"; + parameter REGBYPSA1 = "REGISTER"; + parameter REGBYPSA2 = "REGISTER"; + parameter SHIFTA = "DISABLED"; + parameter SR_18BITSHIFT_EN = "DISABLED"; + parameter GSR = "ENABLED"; + parameter RESET = "SYNC"; + input [8:0] A; + input ASIGNED; + input [8:0] BR; + input [8:0] AS1; + input [8:0] AS2; + input ASSIGNED1; + input ASSIGNED2; + input BRSIGNED; + input CLK; + input CEA; + input RSTA; + output [8:0] AO; + output [8:0] BO; + output AOSIGNED; + output BOSIGNED; + output [8:0] AR; + output ARSIGNED; + output [19:0] P18; + input CEP; + input RSTP; +endmodule + +module MULTADDSUB18X18WIDE (...); + parameter REGINPUTAB0 = "REGISTER"; + parameter REGINPUTAB1 = "REGISTER"; + parameter REGINPUTC = "REGISTER"; + parameter REGADDSUB = "REGISTER"; + parameter REGLOADC = "REGISTER"; + parameter REGLOADC2 = "REGISTER"; + parameter REGPIPELINE = "REGISTER"; + parameter REGOUTPUT = "REGISTER"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + input [17:0] A0; + input [17:0] B0; + input [17:0] A1; + input [17:0] B1; + input [53:0] C; + input CLK; + input CEA0; + input CEA1; + input RSTA0; + input RSTA1; + input CEB0; + input CEB1; + input RSTB0; + input RSTB1; + input CEC; + input RSTC; + input RSTCTRL; + input CECTRL; + input SIGNED; + input RSTPIPE; + input CEPIPE; + output [53:0] Z; + input RSTOUT; + input CEOUT; + input LOADC; + input [1:0] ADDSUB; +endmodule + +module MULTADDSUB9X9WIDE (...); + parameter REGINPUTAB0 = "REGISTER"; + parameter REGINPUTAB1 = "REGISTER"; + parameter REGINPUTAB2 = "REGISTER"; + parameter REGINPUTAB3 = "REGISTER"; + parameter REGINPUTC = "REGISTER"; + parameter REGADDSUB = "REGISTER"; + parameter REGLOADC = "REGISTER"; + parameter REGLOADC2 = "REGISTER"; + parameter REGPIPELINE = "REGISTER"; + parameter REGOUTPUT = "REGISTER"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + input [8:0] A0; + input [8:0] B0; + input [8:0] A1; + input [8:0] B1; + input [8:0] A2; + input [8:0] B2; + input [8:0] A3; + input [8:0] B3; + input [53:0] C; + input CLK; + input CEA0A1; + input CEA2A3; + input RSTA0A1; + input RSTA2A3; + input CEB0B1; + input CEB2B3; + input RSTB0B1; + input RSTB2B3; + input CEC; + input RSTC; + input RSTCTRL; + input CECTRL; + input SIGNED; + input RSTPIPE; + input CEPIPE; + input RSTOUT; + input CEOUT; + input LOADC; + input [3:0] ADDSUB; + output [53:0] Z; +endmodule + +(* keep *) +module MULTIBOOT (...); + parameter MSPIADDR = "0b00000000000000000000000000000000"; + parameter SOURCESEL = "DIS"; + input AUTOREBOOT; + input [31:0] MSPIMADDR; +endmodule + +module ODDR71 (...); + parameter GSR = "ENABLED"; + input D0; + input D1; + input D2; + input D3; + input D4; + input D5; + input D6; + input SCLK; + input RST; + input ECLK; + output Q; +endmodule + +module ODDRX1 (...); + parameter GSR = "ENABLED"; + input D0; + input D1; + input SCLK; + input RST; + output Q; +endmodule + +module ODDRX2DQS (...); + parameter GSR = "ENABLED"; + input D0; + input D1; + input D2; + input D3; + input DQSW; + input ECLK; + input SCLK; + input RST; + output Q; +endmodule + +module ODDRX2DQ (...); + parameter GSR = "ENABLED"; + input D0; + input D1; + input D2; + input D3; + input DQSW270; + input ECLK; + input SCLK; + input RST; + output Q; +endmodule + +module ODDRX2 (...); + parameter GSR = "ENABLED"; + input D0; + input D1; + input D2; + input D3; + input SCLK; + input RST; + input ECLK; + output Q; +endmodule + +module ODDRX4DQS (...); + parameter GSR = "ENABLED"; + input D0; + input D1; + input D2; + input D3; + input D4; + input D5; + input D6; + input D7; + input DQSW; + input ECLK; + input SCLK; + input RST; + output Q; +endmodule + +module ODDRX4DQ (...); + parameter GSR = "ENABLED"; + input D0; + input D1; + input D2; + input D3; + input D4; + input D5; + input D6; + input D7; + input DQSW270; + input ECLK; + input SCLK; + input RST; + output Q; +endmodule + +module ODDRX4 (...); + parameter GSR = "ENABLED"; + input D0; + input D1; + input D2; + input D3; + input D4; + input D5; + input D6; + input D7; + input SCLK; + input RST; + input ECLK; + output Q; +endmodule + +module ODDRX5 (...); + parameter GSR = "ENABLED"; + input D0; + input D1; + input D2; + input D3; + input D4; + input D5; + input D6; + input D7; + input D8; + input D9; + input SCLK; + input RST; + input ECLK; + output Q; +endmodule + +module OFD1P3BX (...); + parameter GSR = "ENABLED"; + input D; + input SP; + input CK; + input PD; + output Q; +endmodule + +module OFD1P3DX (...); + parameter GSR = "ENABLED"; + input D; + input SP; + input CK; + input CD; + output Q; +endmodule + +module OFD1P3IX (...); + parameter GSR = "ENABLED"; + input D; + input SP; + input CK; + input CD; + output Q; +endmodule + +module OFD1P3JX (...); + parameter GSR = "ENABLED"; + input D; + input SP; + input CK; + input PD; + output Q; +endmodule + +module OSHX2 (...); + parameter GSR = "ENABLED"; + input D0; + input D1; + input ECLK; + input SCLK; + input RST; + output Q; +endmodule + +module OSHX4 (...); + parameter GSR = "ENABLED"; + input D0; + input D1; + input D2; + input D3; + input ECLK; + input SCLK; + input RST; + output Q; +endmodule + +module PCIE (...); + parameter ENABLE_USER_CFG = "DISABLED"; + parameter PWDN_N = "DISABLED"; + parameter GSR = "ENABLED"; + parameter IDDQ_PCS = "DISABLED"; + parameter PHY_MODE = "0b0000"; + parameter ALT_CLK_SEL_VCC = "PAD"; + parameter L0S_ADJ = "0b00000110000000"; + parameter L0S_EXIT_LATENCY = "MORE_4_US"; + parameter L1_EXIT_LATENCY = "MORE_64_US"; + parameter CALIB_3DB = "ENABLED"; + parameter DB_UPSTREAM = "6DB"; + parameter ERR_REC_ENTRY_SEL = "RCVRY_AFTER"; + parameter A_CHNGD_MAX = "0b100"; + parameter A0_FORCE = "DISABLED"; + parameter A0_FREEZE = "DISABLED"; + parameter A0_INIT = "0b000000"; + parameter A0DIR_VAL = "DISABLED"; + parameter A1_FORCE = "DISABLED"; + parameter A1_FREEZE = "DISABLED"; + parameter A1_INIT = "0b000000"; + parameter A1DIR_VAL = "DISABLED"; + parameter A2_FORCE = "DISABLED"; + parameter A2_FREEZE = "DISABLED"; + parameter A2_INIT = "0b000000"; + parameter A2GAIN_CALIB = "0b100110"; + parameter ACJTAG_REG = "0b00"; + parameter ADDR_LIMIT_PRE_MTHD_CTRL = "0b0100"; + parameter ADDR_LIMIT_TABLE_MTHD_CTRL = "0b00101"; + parameter ADIR_OVR = "DISABLED"; + parameter ADV_CH_CD_SEL = "IMPLEMENT_CH"; + parameter ADV_TARGET_LINK_SPEED_USPORT_A = "DISABLED"; + parameter ADV_TARGET_LINK_SPEED_USPORT_B = "DISABLED"; + parameter ADV_TARGET_LINK_SPEED_USPORT_C = "DISABLED"; + parameter ADV_TARGET_LINK_SPEED_USPORT_D = "DISABLED"; + parameter ADVANCE = "DISABLED"; + parameter ALERT_ENABLE = "0b000"; + parameter ALMOST_EMPTY_10B = "0b001110"; + parameter MID_VALUE_10B = "0b011110"; + parameter ALMOST_EMPTY_20B = "0b001111"; + parameter ALMOST_EMPTY_GEN3 = "0b001100"; + parameter ALMOST_FULL_10B = "0b110000"; + parameter ALMOST_FULL_20B = "0b011000"; + parameter ALMOST_FULL_GEN3 = "0b010110"; + parameter ARRAY_DA = "0b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter ARRAY_MT = "0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000011100000000000010000000000000001001000000000000011000000000000001010000000000000100"; + parameter ARXCDRICP_RATE0 = "0b011"; + parameter ARXCDRICP_RATE1 = "0b011"; + parameter ARXCDRICP_RATE2 = "0b011"; + parameter ARXDMPWRDWN = "DISABLED"; + parameter ARXDPPWRDN = "DISABLED"; + parameter ARXEOM_PWRDN = "POWERED_DOWN"; + parameter ARXICP_RATE0 = "0b011"; + parameter ARXICP_RATE1 = "0b011"; + parameter ARXICP_RATE2 = "0b011"; + parameter ARXOVR_OUT = "DISABLED"; + parameter ARXRSACTAT = "0b0001"; + parameter ARXRSAPTAT = "0b1000"; + parameter ARXRSVCTL = "0b00000000"; + parameter ARXSEL_OUT = "DISABLED"; + parameter ASPM_L1_1_SUPPORTED = "SUPPORTED"; + parameter ASPM_L1_2_SUPPORTED = "SUPPORTED"; + parameter ASPM_SUPPORT = "L0S_AND_L1_SUPPORTED"; + parameter ATTENTION_BUTTON_PRESENT = "NOT_SUPPORTED"; + parameter ATTENTION_INDICATOR_PRESENT = "NOT_SUPPORTED"; + parameter ATXICP_RATE0 = "0b101"; + parameter ATXICP_RATE1 = "0b101"; + parameter AUTO_SHIFT = "ENABLED"; + parameter AUX_CURRENT = "SELF_POWERED"; + parameter AUXCLK1US_MAX = "0b00001001"; + parameter AUXIDL_MAX = "0b00000100"; + parameter BAR_INDEX_CFG0_A = "0b000"; + parameter BAR_INDEX_CFG0_B = "0b000"; + parameter BAR_INDEX_CFG0_C = "0b000"; + parameter BAR_INDEX_CFG0_D = "0b000"; + parameter BAR_INDEX_CFG1_A = "0b001"; + parameter BAR_INDEX_CFG1_B = "0b001"; + parameter BAR_INDEX_CFG1_C = "0b001"; + parameter BAR_INDEX_CFG1_D = "0b001"; + parameter BAR_INDEX_CFG2_A = "0b010"; + parameter BAR_INDEX_CFG2_B = "0b010"; + parameter BAR_INDEX_CFG2_C = "0b010"; + parameter BAR_INDEX_CFG2_D = "0b010"; + parameter BAR_INDEX_CFG3_A = "0b011"; + parameter BAR_INDEX_CFG3_B = "0b011"; + parameter BAR_INDEX_CFG3_C = "0b011"; + parameter BAR_INDEX_CFG3_D = "0b011"; + parameter BAR_INDEX_CFG4_A = "0b100"; + parameter BAR_INDEX_CFG4_B = "0b100"; + parameter BAR_INDEX_CFG4_C = "0b100"; + parameter BAR_INDEX_CFG4_D = "0b100"; + parameter BAR_INDEX_CFG5_A = "0b101"; + parameter BAR_INDEX_CFG5_B = "0b101"; + parameter BAR_INDEX_CFG5_C = "0b101"; + parameter BAR_INDEX_CFG5_D = "0b101"; + parameter BIR_MSIX_PBA_A = "BAR0"; + parameter BIR_MSIX_PBA_B = "BAR0"; + parameter BIR_MSIX_PBA_C = "BAR0"; + parameter BIR_MSIX_PBA_D = "BAR0"; + parameter BIR_MSIX_TABLE_A = "BAR0"; + parameter BIR_MSIX_TABLE_B = "BAR0"; + parameter BIR_MSIX_TABLE_C = "BAR0"; + parameter BIR_MSIX_TABLE_D = "BAR0"; + parameter BYP_AVG = "USED"; + parameter BYPASS = "PERFORM_RECEIVER_DETECTION"; + parameter BYPASS_ADDR_DEC = "NORMAL"; + parameter CALIB_SETTLE_MAX = "0b001"; + parameter CALIB_STABLE_MAX = "0b11000"; + parameter CAPABILITY_VERSION = "0b0010"; + parameter CDR_ERR = "DISABLED"; + parameter CDR_P1 = "CDR_PLL_RESET"; + parameter CDR_PLL_DELTA = "0P4_PERCENT"; + parameter CDR_REFERENCE = "0b00"; + parameter CDRPLL_CMP_MAX = "0b00010100"; + parameter CDRPLL_CNT_MAX = "0b00000100"; + parameter CDRPLL_PRE_RXEQ_COARSE_TIMER = "0b01010000"; + parameter CDRPLL_PRE_RXEQ_FINE_TIMER = "0b10110100"; + parameter CDRPLL_PST_RXEQ_COARSE_TIMER = "0b01000000"; + parameter CDRPLL_PST_RXEQ_FINE_TIMER = "0b01000010"; + parameter CFG_A_BAR0 = "0b11111111111111110000000000001100"; + parameter CFG_A_BAR1 = "0b11111111111111111111111111111111"; + parameter CFG_A_BAR2 = "0b11111111111111111110000000001100"; + parameter CFG_A_BAR3 = "0b11111111111111111111111111111111"; + parameter CFG_A_BAR4 = "0b11111111111111111110000000001100"; + parameter CFG_A_BAR5 = "0b11111111111111111111111111111111"; + parameter CFG_B_BAR0 = "0b11111111111111110000000000001100"; + parameter CFG_B_BAR1 = "0b11111111111111111111111111111111"; + parameter CFG_B_BAR2 = "0b11111111111111111110000000001100"; + parameter CFG_B_BAR3 = "0b11111111111111111111111111111111"; + parameter CFG_B_BAR4 = "0b11111111111111111110000000001100"; + parameter CFG_B_BAR5 = "0b11111111111111111111111111111111"; + parameter CFG_C_BAR0 = "0b11111111111111110000000000001100"; + parameter CFG_C_BAR1 = "0b11111111111111111111111111111111"; + parameter CFG_C_BAR2 = "0b11111111111111111110000000001100"; + parameter CFG_C_BAR3 = "0b11111111111111111111111111111111"; + parameter CFG_C_BAR4 = "0b11111111111111111110000000001100"; + parameter CFG_C_BAR5 = "0b11111111111111111111111111111111"; + parameter CFG_D_BAR0 = "0b11111111111111110000000000001100"; + parameter CFG_D_BAR1 = "0b11111111111111111111111111111111"; + parameter CFG_D_BAR2 = "0b11111111111111111110000000001100"; + parameter CFG_D_BAR3 = "0b11111111111111111111111111111111"; + parameter CFG_D_BAR4 = "0b11111111111111111110000000001100"; + parameter CFG_D_BAR5 = "0b11111111111111111111111111111111"; + parameter CFG_EXP_ROM_A = "0b00000000000000000000000000000000"; + parameter CFG_EXP_ROM_B = "0b00000000000000000000000000000000"; + parameter CFG_EXP_ROM_C = "0b00000000000000000000000000000000"; + parameter CFG_EXP_ROM_D = "0b00000000000000000000000000000000"; + parameter CIS_POINTER_CARDBUS_A = "0b00000000000000000000000000000000"; + parameter CIS_POINTER_CARDBUS_B = "0b00000000000000000000000000000000"; + parameter CIS_POINTER_CARDBUS_C = "0b00000000000000000000000000000000"; + parameter CIS_POINTER_CARDBUS_D = "0b00000000000000000000000000000000"; + parameter CLASS_CODE_ID3A = "0b000100011000000000000000"; + parameter CLASS_CODE_ID3B = "0b000100011000000000000000"; + parameter CLASS_CODE_ID3C = "0b000100011000000000000000"; + parameter CLASS_CODE_ID3D = "0b000100011000000000000000"; + parameter CM_RESTORE_TIME = "0b00000000"; + parameter CNT250NS_MAX = "0b001111100"; + parameter COARSE_GAIN = "DISABLED"; + parameter COEF_EN_LPBK_MASTER = "OTHERWISE"; + parameter COEF_EN_LPBK_SLAVE = "OTHERWISE"; + parameter COEF_ENABLE = "DETERMINE_LOCAL_PHY"; + parameter COEF_EQTX_FORCE = "0b000000000000000000"; + parameter COEF_LPBK_MASTER = "0b000000000000000000"; + parameter COEF_LPBK_SLAVE = "0b000000000000000000"; + parameter COEF0_POST = "0b000101"; + parameter COEF0_POST_CURSOR = "0b000000"; + parameter COEF0_PRE = "0b000000"; + parameter COEF0_PRE_CURSOR = "0b000000"; + parameter COEF1_POST = "0b000011"; + parameter COEF1_POST_CURSOR = "0b000000"; + parameter COEF1_PRE = "0b000000"; + parameter COEF1_PRE_CURSOR = "0b000000"; + parameter COEF10_POST = "0b000111"; + parameter COEF10_PRE = "0b000000"; + parameter COEF2_POST = "0b000100"; + parameter COEF2_POST_CURSOR = "0b000000"; + parameter COEF2_PRE = "0b000000"; + parameter COEF2_PRE_CURSOR = "0b000000"; + parameter COEF3_POST = "0b000010"; + parameter COEF3_POST_CURSOR = "0b000000"; + parameter COEF3_PRE = "0b000000"; + parameter COEF3_PRE_CURSOR = "0b000000"; + parameter COEF4_POST = "0b000000"; + parameter COEF4_PRE = "0b000000"; + parameter COEF5_POST = "0b000000"; + parameter COEF5_PRE = "0b000001"; + parameter COEF6_POST = "0b000000"; + parameter COEF6_PRE = "0b000010"; + parameter COEF7_POST = "0b000100"; + parameter COEF7_PRE = "0b000011"; + parameter COEF8_POST = "0b000011"; + parameter COEF8_PRE = "0b000010"; + parameter COEF9_POST = "0b000000"; + parameter COEF9_PRE = "0b000011"; + parameter COMP_128_SUPPORTED = "ENABLED"; + parameter COMP_32_SUPPORTED = "ENABLED"; + parameter COMP_64_SUPPORTED = "ENABLED"; + parameter COMPLETE = "DISABLED"; + parameter CONV_METHOD = "COMPUTE_PCIE_SPEC"; + parameter CORE_BYPASS = "NORMAL"; + parameter CORE_EN = "ENABLED"; + parameter COUNT_ACK_TO_NAK = "0b00000000"; + parameter CPL_TIMEOUT_DISABLE_SUPPORTED = "SUPPORTED"; + parameter CPL_TIMEOUT_RANGES_SUPPORTED = "NOT_SUPPORTED"; + parameter CRS_ENABLE = "DISABLED"; + parameter CSTAT_DATA_SCALE = "UNKNOWN_SCALE"; + parameter CSTAT_DATA_SELECT = "D0_POWER_CONSUMED"; + parameter CTLE_SETTLE = "0b100"; + parameter CTLEBIAS_1 = "0b1000"; + parameter ATXICP_RATE2 = "0b100"; + parameter CTLEBYPASS = "DISABLED"; + parameter CUR_FOM = "NUMBER_OF_CLOCK"; + parameter CUR_FOM_AVG = "0b101"; + parameter CUST_AUTO = "DISABLED"; + parameter CUST_CHK = "SET"; + parameter CUST_SEL = "DISABLED"; + parameter CUST_SKIP = "DISABLED"; + parameter CUST_TYP = "0b000"; + parameter CUSTOM_PATTERN = "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter D1_SUPPORT = "SUPPORTED"; + parameter D2_SUPPORT = "SUPPORTED"; + parameter DATA_INJECT = "0b00000000000000000000000000000000"; + parameter DATA_PM = "0b00000000"; + parameter DEEMPH_5G_3_5DB_6DB_N = "6DB"; + parameter DEEMPH_5G_ENABLE = "DISABLED"; + parameter DEEMPH_LPBK_MASTER = "6P0DB"; + parameter DEEMPH_LPBK_SLAVE = "6P0DB"; + parameter DEVICE_ID_ID1A = "0b1110000000000100"; + parameter DEVICE_ID_ID1B = "0b1110000000000100"; + parameter DEVICE_ID_ID1C = "0b1110000000000100"; + parameter DEVICE_ID_ID1D = "0b1110000000000100"; + parameter DEVICE_PORT_TYPE = "PCIE_ENDPOINT"; + parameter DFE_BIAS = "0b0001"; + parameter DFE_PWDN = "DISABLED"; + parameter DIR_PRE_GAIN = "0b00"; + parameter DIR_PST_GAIN = "0b01"; + parameter DIS_ARI_CAP = "ENABLED"; + parameter DIS_CSR_RST = "DISABLED"; + parameter DIS_INTERRUPT = "ENABLED"; + parameter DIS_INTERRUPT_B = "ENABLED"; + parameter DIS_INTERRUPT_C = "ENABLED"; + parameter DIS_INTERRUPT_D = "ENABLED"; + parameter DIS_MSI_CAP = "ENABLED"; + parameter DIS_MSI_CAP_B = "ENABLED"; + parameter DIS_MSI_CAP_C = "ENABLED"; + parameter DIS_MSI_CAP_D = "ENABLED"; + parameter DIS_MSIX_CAP = "ENABLED"; + parameter DIS_MSIX_CAP_B = "ENABLED"; + parameter DIS_MSIX_CAP_C = "ENABLED"; + parameter DIS_MSIX_CAP_D = "ENABLED"; + parameter DISABLE_FLR_CAPABILITY = "ENABLED"; + parameter DLLP_CRC_ERR_ENABLE = "DISABLED"; + parameter DLLP_CRC_ERR_RATE = "0b000000000000"; + parameter DLLP_INJECT_ENABLE = "DISABLED"; + parameter DOUBLE_TX_DATA_VALID = "ONE_CLK_EVERY_64_CLKS"; + parameter DOWNSTREAM_EQ_SKIP_PHASE_2_3 = "NORMAL_OPERATION"; + parameter DS_DRIVE_CLKREQ = "ENABLED"; + parameter DS_PORT_RX_PRESET_HINT = "0b001"; + parameter DS_PORT_TX_PRESET = "0b0011"; + parameter DS_US_N_PORTTYPE = "UPSTREAM"; + parameter DSI = "NO_DSI_NECESSARY"; + parameter DSP_DIR = "ANALYSIS_OF_DATA_BY_DSP"; + parameter DSPDIR_PRESGN = "0b11110000"; + parameter DSPDIR_PREVAL = "0b00011000"; + parameter DSPDIR_PSTSGN0 = "0b11111111"; + parameter DSPDIR_PSTSGN1 = "0b00000000"; + parameter DSPDIR_PSTVAL0 = "0b00000010"; + parameter DSPDIR_PSTVAL1 = "0b01000000"; + parameter EARLY_RX_EVAL = "RX_SIGNAL_AFTER_TS1"; + parameter ECRC_GEN_CHK_CAPABLE = "SUPPORTED"; + parameter EFF_LPBK = "PASSED"; + parameter EI4 = "EI_IV"; + parameter EM_INTERLOCK_PRESENT = "NOT_SUPPORTED"; + parameter EN = "DISABLED"; + parameter EN_ACK_TO_DIV = "ACK_SPEC"; + parameter EN_ACK_TO_NAK = "DO_NOTHING"; + parameter EN_ACS_VIOLATION = "DISABLED"; + parameter EN_ASPM_L0S = "ENABLED"; + parameter EN_ASPM_L1 = "ENABLED"; + parameter EN_ATOMIC_OP_CAP = "ENABLED"; + parameter EN_ATOMICOP_EGRESS_BLOCKED = "DISABLED"; + parameter EN_ATS_CAP = "ENABLED"; + parameter EN_BDGT_CAP = "DISABLED"; + parameter EN_CAP = "ENABLED"; + parameter EN_CAP_B = "ENABLED"; + parameter EN_CAP_C = "ENABLED"; + parameter EN_CAP_D = "ENABLED"; + parameter EN_COMPLETER_ABORT = "DISABLED"; + parameter EN_COMPLETION_TIMEOUT = "ENABLED"; + parameter EN_CORR_INTERNAL_ERROR = "DISABLED"; + parameter EN_DPA_CAP = "DISABLED"; + parameter EN_DRCT_SCR_OFF = "OTHERWISE"; + parameter EN_DRCT_TO_LPBK = "OTHERWISE"; + parameter EN_EQTX_OVERRIDE = "PIPE_LOCAL_FS_AND_PIPE_LOCAL_LF"; + parameter EN_FORCE_SCR_OFF_FAST = "OTHERWISE"; + parameter EN_L1 = "ENABLED"; + parameter EN_L1PMSS_CAP = "ENABLED"; + parameter EN_L2 = "ENABLED"; + parameter EN_LPBK_ERR_RST = "MASTER_LPBK_INCREMENT"; + parameter EN_LTR_CAP = "ENABLED"; + parameter EN_MC_BLOCKED_TLP = "DISABLED"; + parameter EN_NWL_VSEC_CAP = "ENABLED"; + parameter EN_PORT_DIS = "DISABLED"; + parameter EN_PORT_INTLEG = "ENABLED"; + parameter EN_RBAR_CAP_A = "ENABLED"; + parameter EN_RBAR_CAP_B = "ENABLED"; + parameter EN_RBAR_CAP_C = "ENABLED"; + parameter EN_RBAR_CAP_D = "ENABLED"; + parameter EN_RECEIVER_OVERFLOW = "DISABLED"; + parameter EN_SELF_XLINK = "OTHERWISE"; + parameter EN_SURPRISE_DOWN_ERROR = "DISABLED"; + parameter EN_TLP_PREFIX_BLOCKED = "DISABLED"; + parameter EN_UCORR_INTERNAL_ERROR = "DISABLED"; + parameter EN_USER_WRITE = "READ_WRITE_ACCESS"; + parameter END_END_PREFIXES_SUPPORTED = "NOT_SUPPORTED"; + parameter END_ON_HOLD = "YES_EXIT_ON_HOLD"; + parameter ENDCALIB_MAX = "0b10000100"; + parameter ENDPOINT_L0S_ACCEPTABLE_LATENCY = "MAX_64_NS"; + parameter ENDPOINT_L1_ACCEPTABLE_LATENCY = "MAX_1_US"; + parameter ENTRY_TIME_ASPM_L0S = "0b0000000000000000"; + parameter ENTRY_TIME_ASPM_L1 = "0b0000000000000000"; + parameter EOM_TIME = "0b0000000000000000"; + parameter EOM0DIR = "SELECT_DIR_1"; + parameter EOM1DIR = "SELECT_DIR_0"; + parameter EOMCTRL0_LOW = "DISABLED"; + parameter EOMDIVDIS = "DISABLED"; + parameter EOMMODE = "0b00"; + parameter EOMRDSEL = "DISABLED"; + parameter EOMSTART = "DISABLED"; + parameter EOMX = "0b000000"; + parameter EOMX_UPDATE_CNT_VALUE = "0b0011111"; + parameter EOMY = "0b00000000"; + parameter ERRCNT_DEC = "0b00100000"; + parameter ERRCNT_THR = "0b1000"; + parameter ES_PWDN = "DISABLED"; + parameter EVAL_RST = "DISABLED"; + parameter EXCLUDE_L0 = "INCLUDE"; + parameter EXCLUDE_CFG_COMPLETE = "INCLUDE"; + parameter EXCLUDE_CFG_IDLE = "INCLUDE"; + parameter EXCLUDE_LOOPBACK_MASTER = "INCLUDE"; + parameter EXCLUDE_REC_IDLE = "INCLUDE"; + parameter EXCLUDE_REC_RCVR_CFG = "INCLUDE"; + parameter EXIT_DIRECT_TO_DETECT = "DO_NOT_EXIT_TO_DETECT"; + parameter EXT_CONTROL = "DISABLED"; + parameter EXTENDED_TAG_FIELD_EN_DEFAULT = "EIGHT_BIT"; + parameter EXTENDED_TAG_FIELD_SUPPORTED = "EIGHT_BIT"; + parameter F_ARXCTLEDIR = "IGNORED"; + parameter F_ARXCTLENULL = "0b0000"; + parameter F_ARXDMDIR = "DISABLED"; + parameter F_ARXDMNULL = "0b00000"; + parameter F_ARXEOMDIR = "IGNORED"; + parameter F_ARXEOMNULL = "0b00000"; + parameter F_ARXESDIR = "IGNORED"; + parameter F_ARXESNULL = "0b00000"; + parameter F_ARXTDIR = "IGNORED"; + parameter F_ARXTNULL = "0b00000"; + parameter F_ASCHCAL = "IGNORED"; + parameter F_ASCHDIR = "IGNORED"; + parameter F_ASCHNULL = "0b0000"; + parameter FAIL_LIMIT_ERR = "RXEQ_NOT_FAIL"; + parameter FAST = "L0"; + parameter FC_UPDATE_TIMER_DISABLE = "ENABLED"; + parameter FC_UPDATE_TIMER_DIV = "PCIE_REC_VALUES"; + parameter FILTER = "0b1001"; + parameter FINE_GAIN = "DISABLED"; + parameter FOM_COMPARE = "0b00000000"; + parameter FOM_HIRES = "DISABLED"; + parameter FOM_ITERCNT = "0b101"; + parameter FOM_THR = "0b0100"; + parameter FORCE_ATXDRA = "0b000000000000000000000"; + parameter FORCE_ATXDRP = "0b000000000000000000000"; + parameter FORCE_ATXDRR = "0b000000000000000000000"; + parameter FORCE_ATXDRT = "0b000000000000000000000"; + parameter FORCE_DIR_RSLT = "0b000000"; + parameter FORCE_FOM_RSLT = "0b00000000"; + parameter FORCE_IDLE = "DISABLED"; + parameter FORCE_RX_DETECT = "DISABLED"; + parameter FORCE_SIGNAL = "DISABLED"; + parameter FREQ_LOCK = "DISABLED"; + parameter FS = "0b110000"; + parameter GAIN_TIMER1 = "0b0101"; + parameter GEN12_ENA_POST_A0 = "DISABLED"; + parameter GEN12_ENA_POST_A1A2 = "DISABLED"; + parameter GEN12_ENA_PREA0 = "DISABLED"; + parameter GEN3_ENA_POST_A0 = "ENABLED"; + parameter GEN3_ENA_POST_A1A2 = "ENABLED"; + parameter GEN3_ENA_PREA0 = "ENABLED"; + parameter GLOBAL_INVAL_SUPPORT = "ENABLED"; + parameter HINT = "0b000"; + parameter HINT0_3DB = "ENABLED"; + parameter HINT0_A0GAIN = "0b111"; + parameter HINT0_A2GAIN = "0b111"; + parameter HINT1_3DB = "ENABLED"; + parameter HINT1_A0GAIN = "0b011"; + parameter HINT1_A2GAIN = "0b101"; + parameter HINT2_3DB = "ENABLED"; + parameter HINT2_A0GAIN = "0b011"; + parameter HINT2_A2GAIN = "0b111"; + parameter HINT3_3DB = "ENABLED"; + parameter HINT3_A0GAIN = "0b000"; + parameter HINT3_A2GAIN = "0b111"; + parameter HINT4_3DB = "DISABLED"; + parameter HINT4_A0GAIN = "0b111"; + parameter HINT4_A2GAIN = "0b111"; + parameter HINT5_3DB = "DISABLED"; + parameter HINT5_A0GAIN = "0b011"; + parameter HINT5_A2GAIN = "0b101"; + parameter HINT6_3DB = "DISABLED"; + parameter HINT6_A0GAIN = "0b011"; + parameter HINT6_A2GAIN = "0b111"; + parameter HINT7_3DB = "DISABLED"; + parameter HINT7_A0GAIN = "0b000"; + parameter HINT7_A2GAIN = "0b111"; + parameter HINT7_OVR = "DISABLED"; + parameter HLD_RST = "WRITE_1"; + parameter HOT_PLUG_CAPABLE = "NOT_SUPPORTED"; + parameter HOT_PLUG_SURPRISE = "NOT_POSSIBLE"; + parameter ID_DS_PORT = "0b0000000000000000"; + parameter ID_NWL_VSEC_CAP = "0b0000000000000001"; + parameter IGNORE_ECRC = "DISABLED"; + parameter IGNORE_POISON = "ENABLED"; + parameter INDICATOR = "0b00000000000000000000000000000000"; + parameter INHIBIT = "PERFORM_RECEIVER_DETECTION"; + parameter INJECT_DATA_ERROR_0 = "DISABLED"; + parameter INJECT_DATA_ERROR_1 = "DISABLED"; + parameter INJECT_DATA_ERROR_2 = "DISABLED"; + parameter INJECT_DATA_ERROR_3 = "DISABLED"; + parameter INJECT_DATA_ERROR_EN = "DISABLED"; + parameter INJECT_ERR_LANE_SELECT_0 = "DISABLED"; + parameter INJECT_ERR_LANE_SELECT_1 = "DISABLED"; + parameter INJECT_ERR_LANE_SELECT_2 = "DISABLED"; + parameter INJECT_ERR_LANE_SELECT_3 = "DISABLED"; + parameter INJECT_RX_1BIT_DATA_ERR = "DISABLED"; + parameter INJECT_RX_2BIT_DATA_ERR = "DISABLED"; + parameter INJECT_RX_SKP_ERR = "DISABLED"; + parameter INJECT_RX_VALID_ERR = "DISABLED"; + parameter INT_CLR = "DISABLED"; + parameter INT_EN = "DISABLED"; + parameter INTERRUPT_MESSAGE_NUMBER = "0b00000"; + parameter INVAL_Q_DEPTH = "0b00000"; + parameter ITERATION_MAX = "0b000000"; + parameter L1_ENTER_PLL_RESET_TIME = "0b100"; + parameter L1_EXIT_PLL_LOCK_TIME = "0b01110"; + parameter L1PM_SUPPORTED = "SUPPORTED"; + parameter L2_D3HOT_ENABLE = "DISABLED"; + parameter LANE_SELECT = "0b0000"; + parameter LF = "0b001000"; + parameter LF_PHY = "0b001010"; + parameter LINK_LANE = "ENABLED"; + parameter LPBK_EN = "DISABLED"; + parameter LW_START_UPDN_ACK_EN = "DISABLED"; + parameter LW_START_UPDN_COUNT = "0b000011111010"; + parameter LW_START_UPDN_EIE_EN = "DISABLED"; + parameter LW_START_UPDN_EN_DIR_DS = "DO_NOT_ASSERT"; + parameter LW_START_UPDN_END_DELAY = "0b1001"; + parameter LW_START_UPDN_RATE_EN_16G = "DISABLED"; + parameter LW_START_UPDN_RATE_EN_2P5G = "ENABLED"; + parameter LW_START_UPDN_RATE_EN_5G = "ENABLED"; + parameter LW_START_UPDN_RATE_EN_8G = "ENABLED"; + parameter LW_START_UPDN_START_DELAY = "0b1000"; + parameter LW_START_UPDN_TIMER_EN = "DISABLED"; + parameter MARGIN_ENABLE = "PCIE_SPEC"; + parameter MARGIN_VALUE = "0b000"; + parameter MASK_0 = "SKIP_RCVR_DETECTION"; + parameter MASK_1 = "SKIP_RCVR_DETECTION"; + parameter MASK_2 = "SKIP_RCVR_DETECTION"; + parameter MASK_3 = "SKIP_RCVR_DETECTION"; + parameter MAX_LINK_WIDTH = "1_LANE"; + parameter MAX_SPEED = "8G"; + parameter MAX_VAR = "0b00100"; + parameter MERGE_LMMI_RDATA = "DISABLED"; + parameter METHOD_FMERIT_CTRL = "STEP_PCIE_TX_PRESETS"; + parameter METHOD_TX_CRED_CLEANUP = "HEADER"; + parameter MGMT_INTLEG = "0b0000"; + parameter MGMT_LTSSM_DIS = "DISABLED"; + parameter MID_VALUE_20B = "0b010100"; + parameter MID_VALUE_GEN3 = "0b001110"; + parameter MIN_SPEED = "2P5G"; + parameter MIN_TIME = "0_MS"; + parameter MIN_TIME_CFG = "4US"; + parameter MIX_DIR = "DISABLED"; + parameter MODE_BFF = "RESTART"; + parameter MRL_SENSOR_PRESENT = "NOT_SUPPORTED"; + parameter MULT_ENABLE = "RECOMMENDED_VALUES"; + parameter MULT_MESSAGE_CAPABLE_MSICAP_A = "EIGHT"; + parameter MULT_MESSAGE_CAPABLE_MSICAP_B = "EIGHT"; + parameter MULT_MESSAGE_CAPABLE_MSICAP_C = "EIGHT"; + parameter MULT_MESSAGE_CAPABLE_MSICAP_D = "EIGHT"; + parameter NFTS = "0b11111111"; + parameter NO_COMMAND_COMPLETED_SUPPORT = "SW_NOTIF_PROVIDED"; + parameter NO_FCMP = "DISABLED"; + parameter NO_REMOTE_CHANGE = "DISABLED"; + parameter NO_TX_IDLE_DELAY = "DATA_VALID_GAP"; + parameter NUM_LANES = "1_LANE"; + parameter NUMBER_DSLINK = "0b00000"; + parameter NUMHI_A = "0b00000000000000000000000000000000"; + parameter NUMHI_B = "0b00000000000000000000000000000000"; + parameter NUMHI_C = "0b00000000000000000000000000000000"; + parameter NUMHI_D = "0b00000000000000000000000000000000"; + parameter NUMHOLD = "SINGLE_HOLD_RESPONSE"; + parameter NUMLO_A = "0b00000000000000000000000000000000"; + parameter NUMLO_B = "0b00000000000000000000000000000000"; + parameter NUMLO_C = "0b00000000000000000000000000000000"; + parameter NUMLO_D = "0b00000000000000000000000000000000"; + parameter OBFF_SUPPORTED = "NOT_SUPPORTED"; + parameter OFFSET_MSIX_PBA_A = "0b00000000000000000111000000000"; + parameter OFFSET_MSIX_PBA_B = "0b00000000000000000111000000000"; + parameter OFFSET_MSIX_PBA_C = "0b00000000000000000111000000000"; + parameter OFFSET_MSIX_PBA_D = "0b00000000000000000111000000000"; + parameter OFFSET_MSIX_TABLE_A = "0b00000000000000000110000000000"; + parameter OFFSET_MSIX_TABLE_B = "0b00000000000000000110000000000"; + parameter OFFSET_MSIX_TABLE_C = "0b00000000000000000110000000000"; + parameter OFFSET_MSIX_TABLE_D = "0b00000000000000000110000000000"; + parameter OVER_CTLE = "DISABLED"; + parameter OVER_RX = "DISABLED"; + parameter OVER_RXDM = "DISABLED"; + parameter OVER_RXDP = "DISABLED"; + parameter OVER_RXES = "DISABLED"; + parameter OVER_RXT = "DISABLED"; + parameter OVER_SCH = "DISABLED"; + parameter OVER_TX = "DISABLED"; + parameter OVERRIDE = "DISABLED"; + parameter OVR_CDR = "DISABLED"; + parameter OVR_DIR = "DISABLED"; + parameter OVR_FOM = "DISABLED"; + parameter OVR_GAIN3DB = "ENABLED"; + parameter OVR_HINT3DB = "ENABLED"; + parameter P_CLK_PERIOD = "0b0000111110100000"; + parameter PAR_LPBK = "DISABLED"; + parameter PAS = "10X"; + parameter PATTERN_0 = "UNSCRAMBLED"; + parameter PATTERN_1 = "UNSCRAMBLED"; + parameter PATTERN_2 = "UNSCRAMBLED"; + parameter PCIPM_L1_1_SUPPORTED = "SUPPORTED"; + parameter PCIPM_L1_2_SUPPORTED = "SUPPORTED"; + parameter PERIOD_SRIS_128B130B = "0b000000"; + parameter PERIOD_SRIS_8B10B = "0b00000000"; + parameter PERIOD_SRNS_128B130B = "0b00000000"; + parameter PERIOD_SRNS_8B10B = "0b00000000"; + parameter PHANTOM_FUNCTIONS_SUPPORTED = "NO_FUNCTION_BITS"; + parameter PHYSICAL_SLOT_NUMBER = "0b0000000000001"; + parameter PIN_INTERRUPT_A = "INTA"; + parameter PIN_INTERRUPT_B = "INTA"; + parameter PIN_INTERRUPT_C = "INTA"; + parameter PIN_INTERRUPT_D = "INTA"; + parameter PIPE_TX_SWING = "FULL_SWING"; + parameter PLESIO_LPBK = "DISABLED"; + parameter PM_REDUCE_TIMEOUTS = "DISABLED"; + parameter PMA_DRIVEN_MODE = "PCS_DRIVEN"; + parameter PMCSR_B2_B3_SUPPORT = "DISABLED"; + parameter PMCSR_BUS_P_C_EN = "DISABLED"; + parameter PME_CLOCK = "DISABLED"; + parameter PME_SUPPORT = "0b11111"; + parameter PMFF_ALL = "DISABLED"; + parameter PORT_CM_RESTORE_TIME = "0b00000000"; + parameter PORT_NUMBER = "0b00000000"; + parameter PORT_TPOWER_ON_SCALE = "2_US"; + parameter PORT_TPOWER_ON_VALUE = "0b00000"; + parameter POST = "0b000000"; + parameter POST_A0COEF = "0b001"; + parameter POST_A1COEF = "0b001"; + parameter POST_A2COEF = "0b001"; + parameter POST_CURSOR_LIMIT = "0b100000"; + parameter POST_CURSOR_STEP_SIZE = "0b001000"; + parameter POST_ITERCNT = "0b100"; + parameter POST_STEP = "STEP_SIZE_4"; + parameter POWER_CONTROLLER_PRESENT = "NOT_SUPPORTED"; + parameter POWER_INDICATOR_PRESENT = "NOT_SUPPORTED"; + parameter POWER_REQUIRED = "AUX_POWER_NOT_REQUIRED"; + parameter PRBS_CHK = "DISABLED"; + parameter PRBS_GEN = "DISABLED"; + parameter PRBS_TYP = "PRBS7"; + parameter PRE = "0b000000"; + parameter PRE_A0COEF = "0b101"; + parameter PRE_A1COEF = "0b101"; + parameter PRE_A2COEF = "0b101"; + parameter PRE_CURSOR_LIMIT = "0b010000"; + parameter PRE_CURSOR_STEP_SIZE = "0b000100"; + parameter PRE_FOM = "ENABLED"; + parameter PRE_FOM_AVG = "0b100"; + parameter PRE_ITERCNT = "0b100"; + parameter PRE_RXEQ_TIMER = "0b00010100"; + parameter PRE_STEP = "STEP_SIZE_2"; + parameter PRESET_COUNT_INI = "0b0000"; + parameter PRESET_EN_LPBK_MASTER = "OTHERWISE"; + parameter PRESET_EN_LPBK_SLAVE = "OTHERWISE"; + parameter PRESET_ENABLE = "NORMAL_OP"; + parameter PRESET_EQTX_FORCE = "0b0000"; + parameter PRESET_LPBK_MASTER = "0b0000"; + parameter PRESET_LPBK_SLAVE_0 = "OTHERWISE"; + parameter PRESET_LPBK_SLAVE_1 = "OTHERWISE"; + parameter PRESET_LPBK_SLAVE_2 = "OTHERWISE"; + parameter PRESET_LPBK_SLAVE_3 = "OTHERWISE"; + parameter PRESET_REJECT = "0b00000000000"; + parameter PRESET0_POSTCURSOR = "0b1000"; + parameter PRESET0_PRECURSOR = "0b0000"; + parameter PRESET1_POSTCURSOR = "0b0101"; + parameter PRESET1_PRECURSOR = "0b0000"; + parameter PRESET10_POSTCURSOR = "0b1010"; + parameter PRESET10_PRECURSOR = "0b0000"; + parameter PRESET2_POSTCURSOR = "0b0110"; + parameter PRESET2_PRECURSOR = "0b0000"; + parameter PRESET3_POSTCURSOR = "0b0100"; + parameter PRESET3_PRECURSOR = "0b0000"; + parameter PRESET4_POSTCURSOR = "0b0000"; + parameter PRESET4_PRECURSOR = "0b0000"; + parameter PRESET5_POSTCURSOR = "0b0000"; + parameter PRESET5_PRECURSOR = "0b0011"; + parameter PRESET6_POSTCURSOR = "0b0000"; + parameter PRESET6_PRECURSOR = "0b0100"; + parameter PRESET7_POSTCURSOR = "0b0110"; + parameter PRESET7_PRECURSOR = "0b0011"; + parameter PRESET8_POSTCURSOR = "0b0100"; + parameter PRESET8_PRECURSOR = "0b0100"; + parameter PRESET9_POSTCURSOR = "0b0000"; + parameter PRESET9_PRECURSOR = "0b0101"; + parameter PS_REENTRY_TIME = "0b00000000"; + parameter RATE = "2P5G"; + parameter RATE_ENABLE = "INITIAL_SPEED_CHANGES"; + parameter RCB = "DISABLED"; + parameter REC_SPD_INFER_EQ_PH0123 = "EXCLUDE_TIME_SPENT"; + parameter REC_SPD_INFER_RCVR_CFG = "EXCLUDE_TIME_SPENT"; + parameter REC_SPD_INFER_RCVR_LOCK = "EXCLUDE_TIME_SPENT"; + parameter DIS_FUNC_B = "ENABLED"; + parameter DIS_FUNC_C = "ENABLED"; + parameter DIS_FUNC_D = "ENABLED"; + parameter REDUCE_TIMEOUTS_LTSSMSIM = "DISABLED"; + parameter REDUCE_TIMEOUTS_SIM = "DISABLED"; + parameter REDUCE_TS1 = "DISABLED"; + parameter REENTRY_DISABLE = "ENABLED"; + parameter REENTRY_TIME = "0b00000000000000"; + parameter REQ_FEEDBACK = "0b00000000"; + parameter RESET_EIEOS_INTERVAL_COUNT = "DISABLED"; + parameter REVISION_ID_ID3A = "0b00000100"; + parameter REVISION_ID_ID3B = "0b00000100"; + parameter REVISION_ID_ID3C = "0b00000100"; + parameter REVISION_ID_ID3D = "0b00000100"; + parameter RL1 = "0b0011"; + parameter RL2 = "0b0101"; + parameter RL3 = "0b0011"; + parameter ROUTING_SUPPORTED = "DISABLED"; + parameter RP_COMPLETER_EN = "DISABLED"; + parameter RSTCDR_ERR = "ENABLED"; + parameter RSTCDR_FRQ = "ENABLED"; + parameter RSTCDR_IDL = "DISABLED"; + parameter RX_BYPASS_DECODE_EN = "ENABLED"; + parameter RX_BYPASS_MSG_DEC = "NORMAL_OPERATION"; + parameter RX_CONVERT_UR_TO_CA = "NORMAL_OPERATION"; + parameter RX_D_ALLOC_C = "0b0000000001100000"; + parameter RX_D_ALLOC_N = "0b0000000000000110"; + parameter RX_D_ALLOC_P = "0b0000000001101100"; + parameter RX_DIV_MODE1 = "0b10"; + parameter RX_DIV_MODE0 = "DIV_2"; + parameter RX_DIV_MODE2 = "0b00"; + parameter RX_DL_ACTIVE_DISABLE = "BLOCK_RECEPTION_TLP"; + parameter RX_EARLY_FORWARD_DISABLE = "FWD_RX_DATA_LL"; + parameter RX_ERR_COR = "DISABLED"; + parameter RX_ERR_UCOR = "DISABLED"; + parameter RX_FORCE_RO = "DISABLED"; + parameter RX_H_ALLOC_C = "0b000000100000"; + parameter RX_H_ALLOC_N = "0b000000001000"; + parameter RX_H_ALLOC_P = "0b000000010000"; + parameter RX_HIZ = "IGNORED"; + parameter RX_IMPED_RATIO = "0b10000000"; + parameter RX_INHIBIT_ACK_NAK = "PROCESS_RCVD_ACK"; + parameter RX_INHIBIT_TLP = "PROCESS_RCVD_TLP"; + parameter RX_LCRC_INJECT_EN = "DO_NOT_INJECT_ERROR"; + parameter RX_MALF_INJECT_EN = "DO_NOT_INJECT_ERROR"; + parameter RX_POLINV = "NORMAL"; + parameter RX_PRIORITY = "DISABLED"; + parameter RX_PRIORITY_N_STARVE_THRESH = "0b00010000"; + parameter RX_PRIORITY_P_STARVE_THRESH = "0b00010000"; + parameter RX_PWRDN = "IGNORED"; + parameter RX_TLP_VALID = "DISABLED"; + parameter RXEQ_ALGO = "0b111"; + parameter RXEQ_ENABLE = "0b100"; + parameter RXEQ_EVAL_MAX = "0b11111111"; + parameter RXEQ_MANUAL = "DISABLED"; + parameter RXEQ_STATE = "0b0000"; + parameter RXF_A = "0b0100"; + parameter RXF_B = "0b0100"; + parameter RXF_C = "0b0100"; + parameter RXHF_CLKDN = "ENABLED"; + parameter RXIDLE_MAX = "0b1111"; + parameter RXIDLE_MAX2 = "0b0000010000000000"; + parameter RXIDLE_MSB = "0b11"; + parameter RXM_A = "0b10"; + parameter RXM_B = "0b01"; + parameter RXM_C = "0b00"; + parameter RXN_A = "0b00100"; + parameter RXN_B = "0b01001"; + parameter RXN_C = "0b01111"; + parameter RXOFF_SETTLE_MAX = "0b011"; + parameter RXOFF_STABLE_MAX = "0b10000"; + parameter RXPLLINIT = "DISABLED"; + parameter RXPLLRST = "SET"; + parameter SELECT_DIR_FOM_N = "FME_METHOD"; + parameter SELECTABLE_DEEMPHASIS = "6P0DB"; + parameter SEQ_NUM = "0b000000000000"; + parameter SIGNAL_DETECT_THRESHOLD = "125_MV"; + parameter SIZE_CFG0_A = "0b00000"; + parameter SIZE_CFG0_B = "0b00000"; + parameter SIZE_CFG0_C = "0b00000"; + parameter SIZE_CFG0_D = "0b00000"; + parameter SIZE_CFG1_A = "0b00000"; + parameter SIZE_CFG1_B = "0b00000"; + parameter SIZE_CFG1_C = "0b00000"; + parameter SIZE_CFG1_D = "0b00000"; + parameter SIZE_CFG2_A = "0b00000"; + parameter SIZE_CFG2_B = "0b00000"; + parameter SIZE_CFG2_C = "0b00000"; + parameter SIZE_CFG2_D = "0b00000"; + parameter SIZE_CFG3_A = "0b00000"; + parameter SIZE_CFG3_B = "0b00000"; + parameter SIZE_CFG3_C = "0b00000"; + parameter SIZE_CFG3_D = "0b00000"; + parameter SIZE_CFG4_A = "0b00000"; + parameter SIZE_CFG4_B = "0b00000"; + parameter SIZE_CFG4_C = "0b00000"; + parameter SIZE_CFG4_D = "0b00000"; + parameter SIZE_CFG5_A = "0b00000"; + parameter SIZE_CFG5_B = "0b00000"; + parameter SIZE_CFG5_C = "0b00000"; + parameter SIZE_CFG5_D = "0b00000"; + parameter SKIP_FINAL_COEF_CHECK = "DISABLED"; + parameter SLOT_CLOCK_CONFIGURATION = "REFCLK_BY_SLOT"; + parameter SLOT_IMPLEMENTED = "UNCONNECTED"; + parameter SLOT_POWER_LIMIT_SCALE = "0b00"; + parameter SLOT_POWER_LIMIT_VALUE = "0b00001010"; + parameter SPEED_LPBK_CTRL = "2P5G"; + parameter START_PRESET = "PRESET_VALUE"; + parameter START_REMOTE_ADV = "OTHERWISE"; + parameter STATE_DATA_N = "USE_RX_DATA_OBSERVATION"; + parameter STEP_SELECT = "0b00000"; + parameter STP_OVERRIDE_EN = "DISABLED"; + parameter STP_OVERRIDE_LEN = "0b00000000000"; + parameter STP_OVERRIDE_NEW_LEN = "0b00000000000"; + parameter SUBSTATE_MAX = "0b00000"; + parameter SUBSYSTEM_ID_ID2A = "0b1110000000000100"; + parameter SUBSYSTEM_ID_ID2B = "0b1110000000000100"; + parameter SUBSYSTEM_ID_ID2C = "0b1110000000000100"; + parameter SUBSYSTEM_ID_ID2D = "0b1110000000000100"; + parameter SUBSYSTEM_VENDOR_ID_ID2A = "0b0001100110101010"; + parameter SUBSYSTEM_VENDOR_ID_ID2B = "0b0001100110101010"; + parameter SUBSYSTEM_VENDOR_ID_ID2C = "0b0001100110101010"; + parameter SUBSYSTEM_VENDOR_ID_ID2D = "0b0001100110101010"; + parameter SUPP_SIZE_CFG0_A = "0b00000000000000001111"; + parameter SUPP_SIZE_CFG0_B = "0b00000000000000001111"; + parameter SUPP_SIZE_CFG0_C = "0b00000000000000001111"; + parameter SUPP_SIZE_CFG0_D = "0b00000000000000001111"; + parameter SUPP_SIZE_CFG1_A = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG1_B = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG1_C = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG1_D = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG2_A = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG2_B = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG2_C = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG2_D = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG3_A = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG3_B = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG3_C = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG3_D = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG4_A = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG4_B = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG4_C = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG4_D = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG5_A = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG5_B = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG5_C = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG5_D = "0b00000000000000000000"; + parameter SYS_ALLOC = "PWR_BUDGET_CAP_VALUES"; + parameter T0_RX_BYPASS_MSG_DEC = "NORMAL_OPERATION"; + parameter TABLE_SIZE_MSIXCAP_A = "0b00000000111"; + parameter TABLE_SIZE_MSIXCAP_B = "0b00000000111"; + parameter TABLE_SIZE_MSIXCAP_C = "0b00000000111"; + parameter TABLE_SIZE_MSIXCAP_D = "0b00000000111"; + parameter TARGET_LINK_SPEED = "8G"; + parameter TARGET_ONLY = "DISABLED"; + parameter TD1_MEANS_ADD_HAS_N = "ECRC_CONTAINED"; + parameter TIMEOUT_THRESHOLD_PME = "0b000000000000"; + parameter TIMEOUT_THRESHOLD_PME_TO_ACK_DS = "0b00000000"; + parameter TIMER = "0b00000000"; + parameter TLP_LCRC_ERR_ENABLE = "DISABLED"; + parameter TLP_LCRC_ERR_RATE = "0b000"; + parameter TLP_SEQ_ERR_ENABLE = "DISABLED"; + parameter TLUNIT = "1_MS"; + parameter TO_EXTEND = "0b01111111"; + parameter TRNG_A0COEF = "0b101"; + parameter TRNG_A1COEF = "0b101"; + parameter TRNG_A2COEF = "0b101"; + parameter TRNG_FAST = "DISABLED"; + parameter TRNG_ITERCNT = "0b100"; + parameter TRNG_RXEQ_TIMER = "0b00100000"; + parameter TS1_ACK_BLOCK_USE_PRESET = "FORCED_TO_ZERO"; + parameter TS1_ACK_DELAY = "0b00011111"; + parameter TS1_ACK_MASK_USE_PRESET = "IGNORES_USE_PRESET"; + parameter TX_AMP_RATIO_MARGIN0_FULL = "0b10000000"; + parameter TX_AMP_RATIO_MARGIN0_HALF = "0b01010000"; + parameter TX_AMP_RATIO_MARGIN1_FULL = "0b01111000"; + parameter TX_AMP_RATIO_MARGIN1_HALF = "0b01011000"; + parameter TX_AMP_RATIO_MARGIN2_FULL = "0b01101000"; + parameter TX_AMP_RATIO_MARGIN2_HALF = "0b01001000"; + parameter TX_AMP_RATIO_MARGIN3_FULL = "0b01100000"; + parameter TX_AMP_RATIO_MARGIN3_HALF = "0b01000000"; + parameter TX_AMP_RATIO_MARGIN4_FULL = "0b01011000"; + parameter TX_AMP_RATIO_MARGIN4_HALF = "0b00111000"; + parameter TX_AMP_RATIO_MARGIN5_FULL = "0b01010000"; + parameter TX_AMP_RATIO_MARGIN5_HALF = "0b00110000"; + parameter TX_AMP_RATIO_MARGIN6_FULL = "0b01001000"; + parameter TX_AMP_RATIO_MARGIN6_HALF = "0b00101000"; + parameter TX_AMP_RATIO_MARGIN7_FULL = "0b01000000"; + parameter TX_AMP_RATIO_MARGIN7_HALF = "0b00100000"; + parameter TX_BYPASS_DECODE_EN = "ENABLED"; + parameter TX_BYPASS_MSG_DEC = "NORMAL_OPERATION"; + parameter TX_COMP_RECEIVE = "DOES_NOT_ASSERT"; + parameter TX_CONVERT_UR_TO_CA = "NORMAL_OPERATION"; + parameter TX_D_ALLOC_C = "0b0000000001100000"; + parameter TX_D_ALLOC_N = "0b0000000000000110"; + parameter TX_D_ALLOC_P = "0b0000000001101100"; + parameter TX_DIV_MODE0 = "0b10"; + parameter TX_DIV_MODE1 = "0b10"; + parameter TX_DIV_MODE2 = "0b10"; + parameter TX_EQ_EVAL_CNT_SEL = "WAIT_8_CLKS"; + parameter TX_ERR_COR = "DISABLED"; + parameter TX_ERR_UCOR = "DISABLED"; + parameter TX_FORCE_RO = "DISABLED"; + parameter TX_GAP_INJECT_EN = "DO_NOT_INJECT_GAP"; + parameter TX_H_ALLOC_C = "0b000000100000"; + parameter TX_H_ALLOC_N = "0b000000001000"; + parameter TX_H_ALLOC_P = "0b000000010000"; + parameter TX_HIZ = "IGNORED"; + parameter TX_IMPED_RATIO = "0b10000000"; + parameter TX_PAR1_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_PAR2_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter TX_PAR2_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_PAR2_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_POLINV = "NORMAL"; + parameter TX_PRE_RATIO = "0b00000000"; + parameter TX_PRE_RATIO_DEEMP0_FULL = "0b00000000"; + parameter TX_PRE_RATIO_DEEMP0_HALF = "0b00000000"; + parameter TX_PRE_RATIO_DEEMP1_FULL = "0b00000000"; + parameter TX_PRE_RATIO_DEEMP1_HALF = "0b00000000"; + parameter TX_PRIORITY = "DISABLED"; + parameter TX_PRIORITY_N_STARVE_THRESH = "0b00010000"; + parameter TX_PRIORITY_P_STARVE_THRESH = "0b00010000"; + parameter TX_PST_RATIO = "0b00010101"; + parameter TX_PST_RATIO_DEEMP0_FULL = "0b00100000"; + parameter TX_PST_RATIO_DEEMP0_HALF = "0b00100000"; + parameter TX_PST_RATIO_DEEMP1_FULL = "0b00010101"; + parameter TX_PST_RATIO_DEEMP1_HALF = "0b00010101"; + parameter TX_QUIESCE = "DISABLED"; + parameter TX_REPLAY_ECC1_HANDLE_DISABLE = "ENABLE_CORRECTION"; + parameter TX_REPLAY_ECC1_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_REPLAY_ECC1_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_REPLAY_ECC2_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter TX_REPLAY_ECC2_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_REPLAY_ECC2_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_REQ_EQ = "DISABLED"; + parameter TX_SELECT_RX_FEEDBACK = "REFCLK"; + parameter TX_TLP_VALID = "DISABLED"; + parameter TXF_A = "0b0100"; + parameter TXF_B = "0b0100"; + parameter TXF_C = "0b0100"; + parameter TXHF_CLKDN = "ENABLED"; + parameter TXM_A = "0b10"; + parameter TXM_B = "0b01"; + parameter TXM_C = "0b00"; + parameter TXN_A = "0b00100"; + parameter TXN_B = "0b01001"; + parameter TXN_C = "0b01111"; + parameter TXPLL_INIT = "DISABLED"; + parameter TXPLLRST = "DISABLED"; + parameter TYPE1_TYPE0_N = "ENDPOINT"; + parameter U_CLK_PERIOD = "0b0001111101000000"; + parameter US_PORT_PS_ENTRY_TIME = "0b0000000000000000"; + parameter US_PORT_RX_PRESET_HINT = "0b010"; + parameter US_PORT_TX_PRESET = "0b0100"; + parameter USE_COEF_PRE_MTHD_CTRL = "PRESET_VALUE"; + parameter USE_COEF_UPDN_CTRL = "PRESET_VALUE"; + parameter USER_AUTO_N = "AUTOMATIC_ON_RECEPTION"; + parameter VEC_MASK_CAPABLE_MSICAP_A = "ENABLED"; + parameter VEC_MASK_CAPABLE_MSICAP_B = "ENABLED"; + parameter VEC_MASK_CAPABLE_MSICAP_C = "ENABLED"; + parameter VEC_MASK_CAPABLE_MSICAP_D = "ENABLED"; + parameter VENDOR_ID_ID1A = "0b0001100110101010"; + parameter VENDOR_ID_ID1B = "0b0001100110101010"; + parameter VENDOR_ID_ID1C = "0b0001100110101010"; + parameter VENDOR_ID_ID1D = "0b0001100110101010"; + parameter VENDOR0_UR = "REPORT"; + parameter VERSION_AER_CAP = "VER_0X2"; + parameter VERSION_PM_CAP = "0b011"; + parameter XLCY0 = "0b00000000"; + parameter XLCY1 = "0b00000000"; + parameter RX_ESP_RESP_WAIT = "0b01000000"; + parameter SEL_PCLK_DIV2 = "PCLK_DIV2"; + parameter COMPLIANCE = "ENABLED"; + parameter LOOPBACK = "ENABLED"; + parameter HOT_RESET = "ENABLED"; + parameter DIS_PREVENT = "ENABLED"; + parameter MPS_VIOLATION_RX = "DISABLED"; + parameter MPS_VIOLATION_TX = "DISABLED"; + parameter EN_RX_ALLOC_SEL = "HW"; + parameter EN_TX_ALLOC_SEL = "HW"; + parameter AUX_CLK_PERIOD = "0b1111010000100100"; + parameter EN_PIPE_IF_CTRL = "DISABLED"; + parameter PIPE_PWRDN = "P1"; + parameter TX_CM_DIS = "DEASSERTED"; + parameter RX_EI_DIS = "DEASSERTED"; + parameter PCLKREQ_N = "DEASSERTED"; + parameter STS_PHY_STATUS = "DEASSERTED"; + parameter STS_PIPE_RSTN = "DEASSERTED"; + parameter LEGACY_MODE = "MATCH_TS"; + parameter OVERFLOW = "DISABLED"; + parameter DIR = "RECEIVE"; + parameter SPEED = "8G"; + parameter LANE = "0"; + parameter COEF_ENABLE_8G = "DISABLED"; + parameter PRESET_ENABLE_8G = "DISABLED"; + parameter VALUE_8G_PRE = "0b000000"; + parameter VALUE_8G_POST = "0b000000"; + parameter REQ_EQ_MAX_COUNT = "0b10"; + parameter MESO_LPBK = "DISABLED"; + parameter TX_REPLAY_ECC2_INJECT_M_1_N = "INJECT_1_ERR"; + parameter TX_REPLAY_ECC1_INJECT_M_1_N = "INJECT_1_ERR"; + parameter REDO = "DISABLED"; + parameter RX_PAR_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter RX_PAR_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter RX_ECC2_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter RX_ECC2_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter RX_ECC2_INJECT_M_1_N = "INJECT_1_ERR"; + parameter RX_ECC2_INJECT_TYPE = "POSTED_DATA_RAM"; + parameter RX_ECC2_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter RX_ECC1_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter RX_ECC1_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter RX_ECC1_INJECT_M_1_N = "INJECT_1_ERR"; + parameter RX_ECC1_INJECT_TYPE = "POSTED_DATA_RAM"; + parameter RX_ECC1_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter RX_ERR_PAR = "OTHERWISE"; + parameter RX_ERR_ECC2 = "OTHERWISE"; + parameter RX_ERR_ECC1 = "OTHERWISE"; + parameter TX_PAR_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_PAR_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_ECC2_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_ECC2_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter TX_ECC2_INJECT_M_1_N = "INJECT_1_ERR"; + parameter TX_ECC2_INJECT_TYPE = "POSTED_DATA_RAM"; + parameter TX_ECC2_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_ECC1_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_ECC1_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter TX_ECC1_INJECT_M_1_N = "INJECT_1_ERR"; + parameter TX_ECC1_INJECT_TYPE = "POSTED_DATA_RAM"; + parameter TX_ECC1_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_ERR_PAR = "OTHERWISE"; + parameter TX_ERR_ECC2 = "OTHERWISE"; + parameter TX_ERR_ECC1 = "OTHERWISE"; + parameter MAX_PAYLOAD_SIZE_SUPPORTED = "256_BYTES"; + parameter ARXCAL_OUT = "DISABLED"; + parameter F_ARXDPDIR = "IGNORED"; + parameter IDLE_INFER_REC_RCVR_CFG = "OTHERWISE"; + parameter IDLE_INFER_LPBK_SLAVE = "OTHERWISE"; + parameter IDLE_INFER_REC_SPEED2_SUCCESS = "OTHERWISE"; + parameter IDLE_INFER_REC_SPEED2_UNSUCCESS = "OTHERWISE"; + parameter IDLE_INFER_L0_TO_REC_RCVR_LOCK = "OTHERWISE"; + parameter SPEED_CHANGE_FAIL = "OTHERWISE"; + parameter DIRECT_TO_DETECT_FAST = "OTHERWISE"; + parameter DIRECT_TO_RCVRY_CH_BOND = "OTHERWISE"; + parameter DIRECT_TO_LPBK_ENTRY = "OTHERWISE"; + parameter DIRECT_SPEED_CHANGE = "OTHERWISE"; + parameter L0_TO_REC_RCVR_LOCK_RX_TS12 = "OTHERWISE"; + parameter L0_TO_REC_RCVR_LOCK_RX_8G_EIE = "OTHERWISE"; + parameter L0_TO_REC_RCVR_LOCK_RX_INFER = "OTHERWISE"; + parameter DIRECT_TO_RCVRY_PHY = "OTHERWISE"; + parameter DIRECT_TO_RCVRY_FRAME = "OTHERWISE"; + parameter DIRECT_TO_RCVRY_REPLAY = "OTHERWISE"; + parameter DIRECT_TO_HOT_RESET = "OTHERWISE"; + parameter DIRECT_TO_DISABLE = "OTHERWISE"; + parameter RX_L0S_DIRECT_TO_RCVRY = "OTHERWISE"; + parameter AUTONOMOUS_WIDTH_CHANGE = "OTHERWISE"; + parameter DIRECTED_RETRAIN_LINK = "OTHERWISE"; + parameter ERR_TX_PIPE_UNDERFLOW = "OTHERWISE"; + parameter TS2_DETECT3 = "OTHERWISE"; + parameter TS2_DETECT2 = "OTHERWISE"; + parameter TS2_DETECT1 = "OTHERWISE"; + parameter TS2_DETECT0 = "OTHERWISE"; + parameter TS1_DETECT3 = "OTHERWISE"; + parameter TS1_DETECT2 = "OTHERWISE"; + parameter TS1_DETECT1 = "OTHERWISE"; + parameter TS1_DETECT0 = "OTHERWISE"; + parameter TS2I_DETECT3 = "OTHERWISE"; + parameter TS2I_DETECT2 = "OTHERWISE"; + parameter TS2I_DETECT1 = "OTHERWISE"; + parameter TS2I_DETECT0 = "OTHERWISE"; + parameter TS1I_DETECT3 = "OTHERWISE"; + parameter TS1I_DETECT2 = "OTHERWISE"; + parameter TS1I_DETECT1 = "OTHERWISE"; + parameter TS1I_DETECT0 = "OTHERWISE"; + parameter FTS_DETECT3 = "OTHERWISE"; + parameter FTS_DETECT2 = "OTHERWISE"; + parameter FTS_DETECT1 = "OTHERWISE"; + parameter FTS_DETECT0 = "OTHERWISE"; + parameter SKP_DETECT3 = "OTHERWISE"; + parameter SKP_DETECT2 = "OTHERWISE"; + parameter SKP_DETECT1 = "OTHERWISE"; + parameter SKP_DETECT0 = "OTHERWISE"; + parameter EIE_DETECT3 = "OTHERWISE"; + parameter EIE_DETECT2 = "OTHERWISE"; + parameter EIE_DETECT1 = "OTHERWISE"; + parameter EIE_DETECT0 = "OTHERWISE"; + parameter EIOS_DETECT3 = "OTHERWISE"; + parameter EIOS_DETECT2 = "OTHERWISE"; + parameter EIOS_DETECT1 = "OTHERWISE"; + parameter EIOS_DETECT0 = "OTHERWISE"; + parameter DATA_DETECT3 = "OTHERWISE"; + parameter DATA_DETECT2 = "OTHERWISE"; + parameter DATA_DETECT1 = "OTHERWISE"; + parameter DATA_DETECT0 = "OTHERWISE"; + parameter SDS_DETECT3 = "OTHERWISE"; + parameter SDS_DETECT2 = "OTHERWISE"; + parameter SDS_DETECT1 = "OTHERWISE"; + parameter SDS_DETECT0 = "OTHERWISE"; + parameter INFO_BAD_TLP_NULL_ERR = "OTHERWISE"; + parameter INFO_BAD_TLP_PHY_ERR = "OTHERWISE"; + parameter INFO_BAD_TLP_MALF_ERR = "OTHERWISE"; + parameter INFO_BAD_TLP_ECRC_ERR = "OTHERWISE"; + parameter INFO_SCHEDULE_DUPL_ACK = "OTHERWISE"; + parameter INFO_BAD_TLP_SEQ_ERR = "OTHERWISE"; + parameter INFO_BAD_TLP_CRC_ERR = "OTHERWISE"; + parameter INFO_NAK_RECEIVED = "OTHERWISE"; + parameter INFO_DESKEW_OVERFLOW_ERROR = "OTHERWISE"; + parameter INFO_TX_DATA_UNDERFLOW = "OTHERWISE"; + parameter INFO_REPLAY_STARTED = "OTHERWISE"; + parameter ERR_AER_TX_PAR2 = "OTHERWISE"; + parameter ERR_AER_TX_REPLAY_ECC2 = "OTHERWISE"; + parameter ERR_AER_TX_REPLAY_ECC1 = "OTHERWISE"; + parameter ERR_AER_SURPRISE_DOWN = "OTHERWISE"; + parameter ERR_AER_DL_PROTOCOL_ERROR = "OTHERWISE"; + parameter ERR_AER_REPLAY_TIMER_TIMEOUT = "OTHERWISE"; + parameter ERR_AER_REPLAY_NUM_ROLLOVER = "OTHERWISE"; + parameter ERR_AER_BAD_DLLP = "OTHERWISE"; + parameter ERR_AER_BAD_TLP = "OTHERWISE"; + parameter ERR_AER_RECEIVER_ERROR = "OTHERWISE"; + parameter P_RX_LIM_H = "DISABLED"; + parameter P_RX_LIM_D = "DISABLED"; + parameter N_RX_LIM_H = "DISABLED"; + parameter N_RX_LIM_D = "DISABLED"; + parameter C_RX_LIM_H = "DISABLED"; + parameter C_RX_LIM_D = "DISABLED"; + parameter P_TX_LIM_H = "DISABLED"; + parameter P_TX_LIM_D = "DISABLED"; + parameter N_TX_LIM_H = "DISABLED"; + parameter N_TX_LIM_D = "DISABLED"; + parameter C_TX_LIM_H = "DISABLED"; + parameter C_TX_LIM_D = "DISABLED"; + parameter MAX_RSA_WAIT = "0b00101000"; + parameter F_ARXDPNULL = "0b00000"; + input LMMICLK; + input LMMIRESET_N; + input LMMIREQUEST; + input LMMIWRRD_N; + input [14:0] LMMIOFFSET; + input [31:0] LMMIWDATA; + output [31:0] LMMIRDATA; + output LMMIRDATAVALID; + output LMMIREADY; + output ACJNOUT; + output ACJPOUT; + input AUXCK; + input CKUSRI; + output CKUSRO; + input ECKIN; + input ECKIND2; + output ECKINDO; + input ERSTN; + input ERSTND2; + input ERXCKD2; + output ERXCKDO; + input ERXRSND2; + input ETXCKD2; + output ETXCKDO; + input ETXRSND2; + output [3:0] FLR; + input [3:0] FLRACK; + input [3:0] MINTLEG; + output MINTO; + input PERSTN; + output [4:0] PMCTRL; + output PMCTRLEN; + input [4:0] PMDPAST; + input PRMSGSD; + input [12:0] PRNOSNP; + input PRNSNPRE; + input [12:0] PRSNOOP; + input PRSNPRE; + input [31:0] PPBDREG; + output [7:0] PPBDSEL; + input REXTCK; + input REXTRST; + input RSTUSRN; + output UDLLKUP; + input ULTSDIS; + output UPLLKUP; + output UTLLKUP; + input [9:0] UCFGADDR; + input [2:0] UCFGF; + output [31:0] UCFGRDD; + output UCFGRDE; + output UCFGRDY; + input UCFGSERD; + input UCFGVD; + input [3:0] UCFGWRBE; + input [31:0] UCFGWRD; + input UCFGWRDN; + input USERAUPD; + input [3:0] USERTRS; + output [12:0] VRXCMDD; + input VRXCINIT; + input [11:0] VRXCNH; + input VRXCNINF; + input VRXCRRE; + output [31:0] VRXD; + output [3:0] VRXDP; + output VRXEOP; + output VRXERR; + output [1:0] VRXF; + input VRXRDY; + output [1:0] VRXSEL; + output VRXSOP; + output VRXVD; + output VXCDINIT; + output [11:0] VXCDNH; + output VTXCRRE; + input [31:0] VXD; + input [3:0] VXDP; + input VXEOP; + input VXEOPN; + output VXRDY; + input VXSOP; + input VXVD; + output [7:0] TESTOUT; + (* iopad_external_pin *) + input S0REFCKN; + (* iopad_external_pin *) + input S0REFCKP; + (* iopad_external_pin *) + input S0REFRET; + (* iopad_external_pin *) + input S0REXT; + (* iopad_external_pin *) + input S0RXN; + (* iopad_external_pin *) + input S0RXP; + (* iopad_external_pin *) + output S0TXN; + (* iopad_external_pin *) + output S0TXP; + input CLKREQI; + output CLKREQO; + output CLKREQOE; +endmodule + +module PDP16K_MODE (...); + parameter DATA_WIDTH_W = "X36"; + parameter DATA_WIDTH_R = "X36"; + parameter OUTREG = "BYPASSED"; + parameter RESETMODE = "SYNC"; + parameter GSR = "ENABLED"; + parameter ECC = "DISABLED"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter CSDECODE_W = "000"; + parameter CSDECODE_R = "000"; + parameter ASYNC_RST_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + input DI0; + input DI1; + input DI2; + input DI3; + input DI4; + input DI5; + input DI6; + input DI7; + input DI8; + input DI9; + input DI10; + input DI11; + input DI12; + input DI13; + input DI14; + input DI15; + input DI16; + input DI17; + input DI18; + input DI19; + input DI20; + input DI21; + input DI22; + input DI23; + input DI24; + input DI25; + input DI26; + input DI27; + input DI28; + input DI29; + input DI30; + input DI31; + input DI32; + input DI33; + input DI34; + input DI35; + input ADW0; + input ADW1; + input ADW2; + input ADW3; + input ADW4; + input ADW5; + input ADW6; + input ADW7; + input ADW8; + input ADW9; + input ADW10; + input ADW11; + input ADW12; + input ADW13; + input ADR0; + input ADR1; + input ADR2; + input ADR3; + input ADR4; + input ADR5; + input ADR6; + input ADR7; + input ADR8; + input ADR9; + input ADR10; + input ADR11; + input ADR12; + input ADR13; + input CLKW; + input CLKR; + input CEW; + input CER; + input CSW0; + input CSW1; + input CSW2; + input CSR0; + input CSR1; + input CSR2; + input RST; + output DO0; + output DO1; + output DO2; + output DO3; + output DO4; + output DO5; + output DO6; + output DO7; + output DO8; + output DO9; + output DO10; + output DO11; + output DO12; + output DO13; + output DO14; + output DO15; + output DO16; + output DO17; + output DO18; + output DO19; + output DO20; + output DO21; + output DO22; + output DO23; + output DO24; + output DO25; + output DO26; + output DO27; + output DO28; + output DO29; + output DO30; + output DO31; + output DO32; + output DO33; + output DO34; + output DO35; + output ONEBITERR; + output TWOBITERR; +endmodule + +module PDP16K (...); + parameter DATA_WIDTH_W = "X36"; + parameter DATA_WIDTH_R = "X36"; + parameter OUTREG = "BYPASSED"; + parameter RESETMODE = "SYNC"; + parameter GSR = "ENABLED"; + parameter ECC = "DISABLED"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter CSDECODE_W = "000"; + parameter CSDECODE_R = "000"; + parameter ASYNC_RST_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + input [35:0] DI; + input [13:0] ADW; + input [13:0] ADR; + input CLKW; + input CLKR; + input CEW; + input CER; + input [2:0] CSW; + input [2:0] CSR; + input RST; + output [35:0] DO; + output ONEBITERR; + output TWOBITERR; +endmodule + +module PDPSC16K_MODE (...); + parameter DATA_WIDTH_W = "X36"; + parameter DATA_WIDTH_R = "X36"; + parameter OUTREG = "BYPASSED"; + parameter RESETMODE = "SYNC"; + parameter GSR = "ENABLED"; + parameter ECC = "DISABLED"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter CSDECODE_W = "000"; + parameter CSDECODE_R = "000"; + parameter ASYNC_RST_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + input DI0; + input DI1; + input DI2; + input DI3; + input DI4; + input DI5; + input DI6; + input DI7; + input DI8; + input DI9; + input DI10; + input DI11; + input DI12; + input DI13; + input DI14; + input DI15; + input DI16; + input DI17; + input DI18; + input DI19; + input DI20; + input DI21; + input DI22; + input DI23; + input DI24; + input DI25; + input DI26; + input DI27; + input DI28; + input DI29; + input DI30; + input DI31; + input DI32; + input DI33; + input DI34; + input DI35; + input ADW0; + input ADW1; + input ADW2; + input ADW3; + input ADW4; + input ADW5; + input ADW6; + input ADW7; + input ADW8; + input ADW9; + input ADW10; + input ADW11; + input ADW12; + input ADW13; + input ADR0; + input ADR1; + input ADR2; + input ADR3; + input ADR4; + input ADR5; + input ADR6; + input ADR7; + input ADR8; + input ADR9; + input ADR10; + input ADR11; + input ADR12; + input ADR13; + input CLK; + input CER; + input CEW; + input CSW0; + input CSW1; + input CSW2; + input CSR0; + input CSR1; + input CSR2; + input RST; + output DO0; + output DO1; + output DO2; + output DO3; + output DO4; + output DO5; + output DO6; + output DO7; + output DO8; + output DO9; + output DO10; + output DO11; + output DO12; + output DO13; + output DO14; + output DO15; + output DO16; + output DO17; + output DO18; + output DO19; + output DO20; + output DO21; + output DO22; + output DO23; + output DO24; + output DO25; + output DO26; + output DO27; + output DO28; + output DO29; + output DO30; + output DO31; + output DO32; + output DO33; + output DO34; + output DO35; + output ONEBITERR; + output TWOBITERR; +endmodule + +module PDPSC16K (...); + parameter DATA_WIDTH_W = "X36"; + parameter DATA_WIDTH_R = "X36"; + parameter OUTREG = "BYPASSED"; + parameter RESETMODE = "SYNC"; + parameter GSR = "ENABLED"; + parameter ECC = "DISABLED"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter CSDECODE_W = "000"; + parameter CSDECODE_R = "000"; + parameter ASYNC_RST_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + input [35:0] DI; + input [13:0] ADW; + input [13:0] ADR; + input CLK; + input CER; + input CEW; + input [2:0] CSW; + input [2:0] CSR; + input RST; + output [35:0] DO; + output ONEBITERR; + output TWOBITERR; +endmodule + +module PDPSC512K (...); + parameter OUTREG = "NO_REG"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_40 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_41 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_42 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_43 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_44 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_45 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_46 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_47 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_48 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_49 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_50 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_51 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_52 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_53 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_54 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_55 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_56 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_57 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_58 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_59 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_60 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_61 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_62 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_63 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_64 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_65 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_66 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_67 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_68 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_69 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_70 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_71 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_72 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_73 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_74 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_75 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_76 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_77 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_78 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_79 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter ECC_BYTE_SEL = "ECC_EN"; + input [31:0] DI; + input [13:0] ADW; + input [13:0] ADR; + input CLK; + input CEW; + input CER; + input WE; + input CSW; + input CSR; + input RSTR; + input [3:0] BYTEEN_N; + output [31:0] DO; + output [1:0] ERRDECA; + output [1:0] ERRDECB; +endmodule + +module PLL (...); + parameter BW_CTL_BIAS = "0b0101"; + parameter CLKOP_TRIM = "0b0000"; + parameter CLKOS_TRIM = "0b0000"; + parameter CLKOS2_TRIM = "0b0000"; + parameter CLKOS3_TRIM = "0b0000"; + parameter CLKOS4_TRIM = "0b0000"; + parameter CLKOS5_TRIM = "0b0000"; + parameter CRIPPLE = "5P"; + parameter CSET = "40P"; + parameter DELAY_CTRL = "200PS"; + parameter DELA = "0"; + parameter DELB = "0"; + parameter DELC = "0"; + parameter DELD = "0"; + parameter DELE = "0"; + parameter DELF = "0"; + parameter DIRECTION = "DISABLED"; + parameter DIVA = "0"; + parameter DIVB = "0"; + parameter DIVC = "0"; + parameter DIVD = "0"; + parameter DIVE = "0"; + parameter DIVF = "0"; + parameter DYN_SEL = "0b000"; + parameter DYN_SOURCE = "STATIC"; + parameter ENCLK_CLKOP = "DISABLED"; + parameter ENCLK_CLKOS = "DISABLED"; + parameter ENCLK_CLKOS2 = "DISABLED"; + parameter ENCLK_CLKOS3 = "DISABLED"; + parameter ENCLK_CLKOS4 = "DISABLED"; + parameter ENCLK_CLKOS5 = "DISABLED"; + parameter ENABLE_SYNC = "DISABLED"; + parameter FAST_LOCK_EN = "ENABLED"; + parameter V2I_1V_EN = "DISABLED"; + parameter FBK_CUR_BLE = "0b00000000"; + parameter FBK_EDGE_SEL = "POSITIVE"; + parameter FBK_IF_TIMING_CTL = "0b00"; + parameter FBK_INTEGER_MODE = "DISABLED"; + parameter FBK_MASK = "0b00001000"; + parameter FBK_MMD_DIG = "8"; + parameter FBK_MMD_PULS_CTL = "0b0000"; + parameter FBK_MODE = "0b00"; + parameter FBK_PI_BYPASS = "NOT_BYPASSED"; + parameter FBK_PI_RC = "0b1100"; + parameter FBK_PR_CC = "0b0000"; + parameter FBK_PR_IC = "0b1000"; + parameter FLOAT_CP = "DISABLED"; + parameter FLOCK_CTRL = "2X"; + parameter FLOCK_EN = "ENABLED"; + parameter FLOCK_SRC_SEL = "REFCLK"; + parameter FORCE_FILTER = "DISABLED"; + parameter I_CTRL = "10UA"; + parameter IPI_CMP = "0b1000"; + parameter IPI_CMPN = "0b0011"; + parameter IPI_COMP_EN = "DISABLED"; + parameter IPP_CTRL = "0b1000"; + parameter IPP_SEL = "0b1111"; + parameter KP_VCO = "0b11001"; + parameter LDT_INT_LOCK_STICKY = "DISABLED"; + parameter LDT_LOCK = "1536CYC"; + parameter LDT_LOCK_SEL = "U_FREQ"; + parameter LEGACY_ATT = "DISABLED"; + parameter LOAD_REG = "DISABLED"; + parameter OPENLOOP_EN = "DISABLED"; + parameter PHIA = "0"; + parameter PHIB = "0"; + parameter PHIC = "0"; + parameter PHID = "0"; + parameter PHIE = "0"; + parameter PHIF = "0"; + parameter PLLPDN_EN = "DISABLED"; + parameter PLLPD_N = "UNUSED"; + parameter PLLRESET_ENA = "DISABLED"; + parameter REF_INTEGER_MODE = "DISABLED"; + parameter REF_MASK = "0b00000000"; + parameter REF_MMD_DIG = "8"; + parameter REF_MMD_IN = "0b00001000"; + parameter REF_MMD_PULS_CTL = "0b0000"; + parameter REF_TIMING_CTL = "0b00"; + parameter REFIN_RESET = "SET"; + parameter RESET_LF = "DISABLED"; + parameter ROTATE = "DISABLED"; + parameter SEL_OUTA = "DISABLED"; + parameter SEL_OUTB = "DISABLED"; + parameter SEL_OUTC = "DISABLED"; + parameter SEL_OUTD = "DISABLED"; + parameter SEL_OUTE = "DISABLED"; + parameter SEL_OUTF = "DISABLED"; + parameter SLEEP = "DISABLED"; + parameter SSC_DITHER = "DISABLED"; + parameter SSC_EN_CENTER_IN = "DOWN_TRIANGLE"; + parameter SSC_EN_SDM = "DISABLED"; + parameter SSC_EN_SSC = "DISABLED"; + parameter SSC_F_CODE = "0b000000000000000"; + parameter SSC_N_CODE = "0b000010100"; + parameter SSC_ORDER = "SDM_ORDER2"; + parameter SSC_PI_BYPASS = "NOT_BYPASSED"; + parameter SSC_REG_WEIGHTING_SEL = "0b000"; + parameter SSC_SQUARE_MODE = "DISABLED"; + parameter SSC_STEP_IN = "0b0000000"; + parameter SSC_TBASE = "0b000000000000"; + parameter STDBY_ATT = "DISABLED"; + parameter TRIMOP_BYPASS_N = "BYPASSED"; + parameter TRIMOS_BYPASS_N = "BYPASSED"; + parameter TRIMOS2_BYPASS_N = "BYPASSED"; + parameter TRIMOS3_BYPASS_N = "BYPASSED"; + parameter TRIMOS4_BYPASS_N = "BYPASSED"; + parameter TRIMOS5_BYPASS_N = "BYPASSED"; + parameter V2I_KVCO_SEL = "85"; + parameter V2I_PP_ICTRL = "0b00110"; + parameter V2I_PP_RES = "10K"; + parameter CLKMUX_FB = "CMUX_CLKOP"; + parameter SEL_FBK = "DIVA"; + parameter DIV_DEL = "0b0000001"; + parameter PHASE_SEL_DEL = "0b000"; + parameter PHASE_SEL_DEL_P1 = "0b000"; + parameter EXTERNAL_DIVIDE_FACTOR = "0"; + output INTFBKOP; + output INTFBKOS; + output INTFBKOS2; + output INTFBKOS3; + output INTFBKOS4; + output INTFBKOS5; + input DIR; + input [2:0] DIRSEL; + input LOADREG; + input DYNROTATE; + input LMMICLK; + input LMMIRESET_N; + input LMMIREQUEST; + input LMMIWRRD_N; + input [6:0] LMMIOFFSET; + input [7:0] LMMIWDATA; + output [7:0] LMMIRDATA; + output LMMIRDATAVALID; + output LMMIREADY; + input PLLPOWERDOWN_N; + input REFCK; + output CLKOP; + output CLKOS; + output CLKOS2; + output CLKOS3; + output CLKOS4; + output CLKOS5; + input ENCLKOP; + input ENCLKOS; + input ENCLKOS2; + input ENCLKOS3; + input ENCLKOS4; + input ENCLKOS5; + input FBKCK; + output INTLOCK; + input LEGACY; + output LEGRDYN; + output LOCK; + output PFDDN; + output PFDUP; + input PLLRESET; + input STDBY; + output REFMUXCK; + output REGQA; + output REGQB; + output REGQB1; + output CLKOUTDL; + input ROTDEL; + input DIRDEL; + input ROTDELP1; + input [4:0] GRAYTEST; + input [1:0] BINTEST; + input DIRDELP1; + input [4:0] GRAYACT; + input [1:0] BINACT; +endmodule + +module PREADD9 (...); + parameter SIGNEDSTATIC_EN = "DISABLED"; + parameter SUBSTRACT_EN = "SUBTRACTION"; + parameter CSIGNED = "DISABLED"; + parameter BSIGNED_OPERAND_EN = "DISABLED"; + parameter BYPASS_PREADD9 = "USED"; + parameter REGBYPSBR0 = "REGISTER"; + parameter REGBYPSBR1 = "BYPASS"; + parameter REGBYPSBL = "REGISTER"; + parameter SHIFTBR = "REGISTER"; + parameter SHIFTBL = "REGISTER"; + parameter GSR = "ENABLED"; + parameter PREADDCAS_EN = "DISABLED"; + parameter SR_18BITSHIFT_EN = "DISABLED"; + parameter OPC = "INPUT_B_AS_PREADDER_OPERAND"; + parameter RESET = "SYNC"; + input [8:0] B; + input BSIGNED; + input [9:0] C; + input [8:0] BRS1; + input [8:0] BRS2; + input [8:0] BLS1; + input [8:0] BLS2; + input BRSS1; + input BRSS2; + input BLSS1; + input BLSS2; + input PRCASIN; + input CLK; + input RSTB; + input CEB; + input RSTCL; + input CECL; + output [8:0] BRSO; + output [8:0] BLSO; + output BRSOSGND; + output BLSOSGND; + output PRCASOUT; + output [8:0] BR; + output BRSIGNED; +endmodule + +module REFMUX (...); + parameter REFSEL_ATT = "MC1"; + parameter SEL1 = "SELECT_REFCLK1"; + parameter SEL_REF2 = "REFCLK2_0"; + parameter SEL_REF1 = "REFCLK1_0"; + output REFCK; + output ZRSEL3; + input REFSEL; + input [7:0] REFCLK1; + input [7:0] REFCLK2; +endmodule + +module REG18 (...); + parameter REGBYPS = "REGISTER"; + parameter GSR = "ENABLED"; + parameter RESET = "SYNC"; + input [17:0] PM; + output [17:0] PP; + input CEP; + input RSTP; + input CLK; +endmodule + +(* keep *) +module SEDC (...); + parameter SEDCEN = "DIS"; + input SEDENABLE; + input SEDCCOF; + input SEDCENABLE; + input SEDCMODE; + input SEDCSTART; + output SEDCBUSY; + output SEDCERR; + output SEDCERRC; + output SEDCERRCRC; + output SEDCERRM; + output [15:0] SEDCFRMERRLOC; + input OSCCLKSEDC; + input RSTSEDC; + output [12:0] SEDCDSRERRLOCCIB; +endmodule + +module SEIO18 (...); + parameter PULLMODE = "DOWN"; + parameter MIPI = "DISABLED"; + parameter ENADC_IN = "DISABLED"; + input PADDO; + input DOLP; + (* iopad_external_pin *) + inout IOPAD; + output PADDI; + output INLP; + input PADDT; + output INADC; +endmodule + +module SEIO33 (...); + parameter PULLMODE = "DOWN"; + (* iopad_external_pin *) + inout IOPAD; + output PADDI; + input PADDO; + input PADDT; + input I3CRESEN; + input I3CWKPU; +endmodule + +module SGMIICDR (...); + parameter GSR = "ENABLED"; + parameter DCOITUNE4LSB = "0_PERCENT"; + parameter DCOCTLGI = "0_PERCENT"; + parameter DCOSTEP = "100_PERCENT"; + parameter DCOCALDIV = "100_PERCENT"; + parameter DCOIOSTUNE = "0_PERCENT"; + parameter DCOFLTDAC = "80MHZ"; + parameter DCOSTARTVAL = "NOMINAL"; + parameter DCONUOFLSB = "NEG_60_PERCENT"; + parameter RPWDNB = "POWER_UP"; + parameter CDR_CNT4SEL = "BYPASSED"; + parameter DCOITUNE = "100_PERCENT"; + parameter BAND_THRESHOLD = "0b000000"; + parameter AUTO_FACQ_EN = "ENABLED"; + parameter AUTO_CALIB_EN = "ENABLED"; + parameter CDR_LOL_SET = "1000_PPM"; + parameter FC2DCO_FLOOP = "DISABLED"; + parameter FC2DCO_DLOOP = "DISABLED"; + parameter CALIB_TIME_SEL = "24_CYC"; + parameter CALIB_CK_MODE = "BY_2"; + parameter BAND_CALIB_MODE = "256_FDBK_CLK_CYC"; + parameter REG_BAND_SEL = "0b00000"; + parameter REG_BAND_OFFSET = "0b0000"; + parameter REG_IDAC_SEL = "0b00000000"; + parameter LB_CTL = "DISABLED"; + parameter REG_IDAC_EN = "DISABLED"; + parameter ATDCFG = "0_PS"; + parameter ATDDLY = "0_PS"; + parameter BDAVOID_ENB = "ENABLED"; + parameter BYPASSATD = "NOT_BYPASS"; + parameter DCOIUPDNX2 = "1X"; + parameter IDAC_EN = "DISABLED"; + parameter FB_CLK_DIV = "0b010"; + parameter EN_RECALIB = "ENABLED"; + input LMMICLK; + input LMMIRESET_N; + input LMMIREQUEST; + input LMMIWRRD_N; + input [3:0] LMMIOFFSET; + input [7:0] LMMIWDATA; + output [7:0] LMMIRDATA; + output LMMIRDATAVALID; + output LMMIREADY; + input DCALIRST; + input DFACQRST; + input RRST; + input SPCLK; + output SRCLK; + output [9:0] SRXD; + input RSTBFBW; + input RSTBRXF; + input SGMIIIN; + input SREFCLK; + output CDRLOL; +endmodule + +module SP16K_MODE (...); + parameter DATA_WIDTH = "X18"; + parameter OUTREG = "BYPASSED"; + parameter RESETMODE = "SYNC"; + parameter GSR = "ENABLED"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter CSDECODE = "000"; + parameter ASYNC_RST_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + input DI0; + input DI1; + input DI2; + input DI3; + input DI4; + input DI5; + input DI6; + input DI7; + input DI8; + input DI9; + input DI10; + input DI11; + input DI12; + input DI13; + input DI14; + input DI15; + input DI16; + input DI17; + input AD0; + input AD1; + input AD2; + input AD3; + input AD4; + input AD5; + input AD6; + input AD7; + input AD8; + input AD9; + input AD10; + input AD11; + input AD12; + input AD13; + input CLK; + input CE; + input WE; + input CS0; + input CS1; + input CS2; + input RST; + output DO0; + output DO1; + output DO2; + output DO3; + output DO4; + output DO5; + output DO6; + output DO7; + output DO8; + output DO9; + output DO10; + output DO11; + output DO12; + output DO13; + output DO14; + output DO15; + output DO16; + output DO17; +endmodule + +module SP16K (...); + parameter DATA_WIDTH = "X18"; + parameter OUTREG = "BYPASSED"; + parameter RESETMODE = "SYNC"; + parameter GSR = "ENABLED"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter CSDECODE = "000"; + parameter ASYNC_RST_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + input [17:0] DI; + input [13:0] AD; + input CLK; + input CE; + input WE; + input [2:0] CS; + input RST; + output [17:0] DO; +endmodule + +module SP512K (...); + parameter OUTREG = "NO_REG"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_40 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_41 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_42 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_43 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_44 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_45 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_46 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_47 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_48 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_49 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_50 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_51 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_52 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_53 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_54 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_55 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_56 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_57 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_58 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_59 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_60 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_61 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_62 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_63 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_64 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_65 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_66 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_67 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_68 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_69 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_70 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_71 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_72 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_73 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_74 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_75 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_76 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_77 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_78 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_79 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter ECC_BYTE_SEL = "ECC_EN"; + input [31:0] DI; + input [13:0] AD; + input CLK; + input CE; + input WE; + input CS; + input RSTOUT; + input CEOUT; + input [3:0] BYTEEN_N; + output [31:0] DO; + output [1:0] ERRDECA; + output [1:0] ERRDECB; +endmodule + +module TSHX2DQS (...); + parameter GSR = "ENABLED"; + input T0; + input T1; + input DQSW; + input ECLK; + input SCLK; + input RST; + output Q; +endmodule + +module TSHX2DQ (...); + parameter GSR = "ENABLED"; + input T0; + input T1; + input DQSW270; + input ECLK; + input SCLK; + input RST; + output Q; +endmodule + +module TSHX4DQS (...); + parameter GSR = "ENABLED"; + input T0; + input T1; + input T2; + input T3; + input DQSW; + input ECLK; + input SCLK; + input RST; + output Q; +endmodule + +module TSHX4DQ (...); + parameter GSR = "ENABLED"; + input T0; + input T1; + input T2; + input T3; + input DQSW270; + input ECLK; + input SCLK; + input RST; + output Q; +endmodule + +(* keep *) +module WDT (...); + parameter WDTEN = "DIS"; + parameter WDTMODE = "SINGLE"; + parameter WDTVALUE = "0b000000000000000000"; + input WDTRELOAD; + input WDT_CLK; + input WDT_RST; +endmodule + +module MIPI (...); + parameter MIPI_ID = "0"; + (* iopad_external_pin *) + inout BP; + (* iopad_external_pin *) + inout BN; + input AP; + input AN; + input TP; + input TN; + input IHS; + input HSRXEN; + input HSTXEN; + output OHS; + output OLSP; + output OLSN; +endmodule + +(* keep *) +module CONFIG_IP_CORE (...); + parameter DONEPHASE = "DIS"; + parameter DSRFCTRL = "0b00"; + parameter ENTSALL = "DIS"; + parameter MCCFGUSEREN = "DIS"; + parameter MCCIBINT = "DIS"; + parameter MCHSEUSEREN = "DIS"; + parameter MCJTAGDISABLE = "EN"; + parameter MCPERSISTUI2C = "DIS"; + parameter MCSPARE = "0b00000"; + parameter MCUCLKSEL = "DIS"; + parameter MCUI2CAFWKUP = "DIS"; + parameter PERSISTI2C = "DIS"; + parameter PERSISTI3C = "DIS"; + parameter PERSISTMQUAD = "DIS"; + parameter PERSISTMSPI = "DIS"; + parameter PERSISTSHEXA = "DIS"; + parameter PERSISTSOCTA = "DIS"; + parameter PERSISTSQUAD = "DIS"; + parameter PERSISTSSPI = "DIS"; + parameter PERSISTWKUP = "DIS"; + parameter PPTQOUT = "0b0000"; + parameter SCANEN = "DIS"; + parameter SYNCEXTDONE = "DIS"; + parameter TRANECI = "DIS"; + parameter TRANHSE = "DIS"; + parameter TRANSBI = "DIS"; + parameter TSALLINV = "NINV"; + parameter WLSLEW = "DIS"; + output CFGDONECIB; + input CIBTSALL; + output FREEZEIOCIB; + output LASTADDRCIB15; + output LASTADDRCIB14; + output LASTADDRCIB13; + output LASTADDRCIB12; + output LASTADDRCIB11; + output LASTADDRCIB10; + output LASTADDRCIB9; + output LASTADDRCIB8; + output LASTADDRCIB7; + output LASTADDRCIB6; + output LASTADDRCIB5; + output LASTADDRCIB4; + output LASTADDRCIB3; + output LASTADDRCIB2; + output LASTADDRCIB1; + output LASTADDRCIB0; + input MBISTENABLEN; + output MBISTRRMATCH; + input MBISTTRRAEN; +endmodule + +module TSALLA (...); + input TSALL; +endmodule + +module OSCA (...); + parameter HF_CLK_DIV = "1"; + parameter HF_SED_SEC_DIV = "1"; + parameter HF_OSC_EN = "ENABLED"; + parameter LF_OUTPUT_EN = "DISABLED"; + input HFOUTEN; + input HFSDSCEN; + output HFCLKOUT; + output LFCLKOUT; + output HFCLKCFG; + output HFSDCOUT; +endmodule + +module OSC (...); + parameter DTR_EN = "ENABLED"; + parameter HF_CLK_DIV = "1"; + parameter HF_SED_SEC_DIV = "1"; + parameter HF_FABRIC_EN = "DISABLED"; + parameter HF_OSC_EN = "ENABLED"; + parameter HFDIV_FABRIC_EN = "ENABLED"; + parameter LF_FABRIC_EN = "DISABLED"; + parameter LF_OUTPUT_EN = "DISABLED"; + parameter DEBUG_N = "DISABLED"; + parameter MCJTAGGSRNDIS = "EN"; + parameter MCLMMIGSRNDIS = "EN"; + parameter MCSEDCGSRNDIS = "EN"; + parameter MCWDTGSRNDIS = "EN"; + parameter SMCLK_DIV = "3"; + output HFCLKOUT; + input HFSDSCEN; + output LFCLKOUT; + output HFSDCOUT; + output HSE_CLK; + input JTAG_LRST_N; + input LMMI_CLK; + output LMMI_CLK_O; + input LMMI_LRST_N; + output LMMI_RST; + input SEDC_CLK; + input SEDC_LRST_N; + output SEDC_RST; + output CFG_CLK; + output SMCLK_RST; + output WDT_CLK; + input WDT_LRST_N; + output WDT_RST; +endmodule + +module ACC54_CORE (...); + parameter SIGN = "DISABLED"; + parameter M9ADDSUB_CTRL = "ADDITION"; + parameter ADDSUB_CTRL = "ADD_ADD_CTRL_54_BIT_ADDER"; + parameter STATICOPCODE_EN = "DISABLED"; + parameter OUTREGBYPS = "REGISTER"; + parameter GSR = "ENABLED"; + parameter PROGCONST = "0b000000000000000000000000000000000000000000000000000000"; + parameter CONSTSEL = "BYPASS"; + parameter DSPCASCADE = "DISABLED"; + parameter ACC108CASCADE = "BYPASSCASCADE"; + parameter ACCUMODE = "MODE0"; + parameter ACCUBYPS = "USED"; + parameter CREGBYPS1 = "REGISTER"; + parameter CREGBYPS2 = "REGISTER"; + parameter CREGBYPS3 = "REGISTER"; + parameter CINREGBYPS1 = "REGISTER"; + parameter CINREGBYPS2 = "REGISTER"; + parameter CINREGBYPS3 = "REGISTER"; + parameter LOADREGBYPS1 = "REGISTER"; + parameter LOADREGBYPS2 = "REGISTER"; + parameter LOADREGBYPS3 = "REGISTER"; + parameter M9ADDSUBREGBYPS1 = "REGISTER"; + parameter M9ADDSUBREGBYPS2 = "REGISTER"; + parameter M9ADDSUBREGBYPS3 = "REGISTER"; + parameter ADDSUBSIGNREGBYPS1 = "REGISTER"; + parameter ADDSUBSIGNREGBYPS2 = "REGISTER"; + parameter ADDSUBSIGNREGBYPS3 = "REGISTER"; + parameter ROUNDHALFUP = "DISABLED"; + parameter ROUNDRTZI = "ROUND_TO_ZERO"; + parameter ROUNDBIT = "ROUND_TO_BIT0"; + parameter CASCOUTREGBYPS = "REGISTER"; + parameter SFTEN = "DISABLED"; + parameter RESET = "SYNC"; + input SFTCTRL3; + input SFTCTRL2; + input SFTCTRL1; + input SFTCTRL0; + input DSPIN53; + input DSPIN52; + input DSPIN51; + input DSPIN50; + input DSPIN49; + input DSPIN48; + input DSPIN47; + input DSPIN46; + input DSPIN45; + input DSPIN44; + input DSPIN43; + input DSPIN42; + input DSPIN41; + input DSPIN40; + input DSPIN39; + input DSPIN38; + input DSPIN37; + input DSPIN36; + input DSPIN35; + input DSPIN34; + input DSPIN33; + input DSPIN32; + input DSPIN31; + input DSPIN30; + input DSPIN29; + input DSPIN28; + input DSPIN27; + input DSPIN26; + input DSPIN25; + input DSPIN24; + input DSPIN23; + input DSPIN22; + input DSPIN21; + input DSPIN20; + input DSPIN19; + input DSPIN18; + input DSPIN17; + input DSPIN16; + input DSPIN15; + input DSPIN14; + input DSPIN13; + input DSPIN12; + input DSPIN11; + input DSPIN10; + input DSPIN9; + input DSPIN8; + input DSPIN7; + input DSPIN6; + input DSPIN5; + input DSPIN4; + input DSPIN3; + input DSPIN2; + input DSPIN1; + input DSPIN0; + input PP71; + input PP70; + input PP69; + input PP68; + input PP67; + input PP66; + input PP65; + input PP64; + input PP63; + input PP62; + input PP61; + input PP60; + input PP59; + input PP58; + input PP57; + input PP56; + input PP55; + input PP54; + input PP53; + input PP52; + input PP51; + input PP50; + input PP49; + input PP48; + input PP47; + input PP46; + input PP45; + input PP44; + input PP43; + input PP42; + input PP41; + input PP40; + input PP39; + input PP38; + input PP37; + input PP36; + input PP35; + input PP34; + input PP33; + input PP32; + input PP31; + input PP30; + input PP29; + input PP28; + input PP27; + input PP26; + input PP25; + input PP24; + input PP23; + input PP22; + input PP21; + input PP20; + input PP19; + input PP18; + input PP17; + input PP16; + input PP15; + input PP14; + input PP13; + input PP12; + input PP11; + input PP10; + input PP9; + input PP8; + input PP7; + input PP6; + input PP5; + input PP4; + input PP3; + input PP2; + input PP1; + input PP0; + input CINPUT53; + input CINPUT52; + input CINPUT51; + input CINPUT50; + input CINPUT49; + input CINPUT48; + input CINPUT47; + input CINPUT46; + input CINPUT45; + input CINPUT44; + input CINPUT43; + input CINPUT42; + input CINPUT41; + input CINPUT40; + input CINPUT39; + input CINPUT38; + input CINPUT37; + input CINPUT36; + input CINPUT35; + input CINPUT34; + input CINPUT33; + input CINPUT32; + input CINPUT31; + input CINPUT30; + input CINPUT29; + input CINPUT28; + input CINPUT27; + input CINPUT26; + input CINPUT25; + input CINPUT24; + input CINPUT23; + input CINPUT22; + input CINPUT21; + input CINPUT20; + input CINPUT19; + input CINPUT18; + input CINPUT17; + input CINPUT16; + input CINPUT15; + input CINPUT14; + input CINPUT13; + input CINPUT12; + input CINPUT11; + input CINPUT10; + input CINPUT9; + input CINPUT8; + input CINPUT7; + input CINPUT6; + input CINPUT5; + input CINPUT4; + input CINPUT3; + input CINPUT2; + input CINPUT1; + input CINPUT0; + input LOAD; + input M9ADDSUB1; + input M9ADDSUB0; + input ADDSUB1; + input ADDSUB0; + input CIN; + input CASIN1; + input CASIN0; + input CEO; + input RSTO; + input CEC; + input RSTC; + input CLK; + input SIGNEDI; + output SUM135; + output SUM134; + output SUM133; + output SUM132; + output SUM131; + output SUM130; + output SUM129; + output SUM128; + output SUM127; + output SUM126; + output SUM125; + output SUM124; + output SUM123; + output SUM122; + output SUM121; + output SUM120; + output SUM119; + output SUM118; + output SUM117; + output SUM116; + output SUM115; + output SUM114; + output SUM113; + output SUM112; + output SUM111; + output SUM110; + output SUM19; + output SUM18; + output SUM17; + output SUM16; + output SUM15; + output SUM14; + output SUM13; + output SUM12; + output SUM11; + output SUM10; + output SUM035; + output SUM034; + output SUM033; + output SUM032; + output SUM031; + output SUM030; + output SUM029; + output SUM028; + output SUM027; + output SUM026; + output SUM025; + output SUM024; + output SUM023; + output SUM022; + output SUM021; + output SUM020; + output SUM019; + output SUM018; + output SUM017; + output SUM016; + output SUM015; + output SUM014; + output SUM013; + output SUM012; + output SUM011; + output SUM010; + output SUM09; + output SUM08; + output SUM07; + output SUM06; + output SUM05; + output SUM04; + output SUM03; + output SUM02; + output SUM01; + output SUM00; + output DSPOUT53; + output DSPOUT52; + output DSPOUT51; + output DSPOUT50; + output DSPOUT49; + output DSPOUT48; + output DSPOUT47; + output DSPOUT46; + output DSPOUT45; + output DSPOUT44; + output DSPOUT43; + output DSPOUT42; + output DSPOUT41; + output DSPOUT40; + output DSPOUT39; + output DSPOUT38; + output DSPOUT37; + output DSPOUT36; + output DSPOUT35; + output DSPOUT34; + output DSPOUT33; + output DSPOUT32; + output DSPOUT31; + output DSPOUT30; + output DSPOUT29; + output DSPOUT28; + output DSPOUT27; + output DSPOUT26; + output DSPOUT25; + output DSPOUT24; + output DSPOUT23; + output DSPOUT22; + output DSPOUT21; + output DSPOUT20; + output DSPOUT19; + output DSPOUT18; + output DSPOUT17; + output DSPOUT16; + output DSPOUT15; + output DSPOUT14; + output DSPOUT13; + output DSPOUT12; + output DSPOUT11; + output DSPOUT10; + output DSPOUT9; + output DSPOUT8; + output DSPOUT7; + output DSPOUT6; + output DSPOUT5; + output DSPOUT4; + output DSPOUT3; + output DSPOUT2; + output DSPOUT1; + output DSPOUT0; + output CASCOUT1; + output CASCOUT0; + input ROUNDEN; + input CECIN; + input CECTRL; + input RSTCIN; + input RSTCTRL; +endmodule + +module ADC_CORE (...); + parameter ADC_ENP = "ENABLED"; + parameter CLK_DIV = "2"; + parameter CTLCOMPSW1 = "DISABLED"; + parameter CTLCOMPSW2 = "DISABLED"; + parameter CTLCOMPSW3 = "DISABLED"; + parameter DF = "STRAIGHT_BINARY"; + parameter EN_COMP1 = "ENABLED"; + parameter EN_COMP2 = "ENABLED"; + parameter EN_COMP3 = "ENABLED"; + parameter OMA = "BIPOLAR"; + parameter OMB = "BIPOLAR"; + parameter REFBUFAEN = "ENABLED"; + parameter REFBUFBEN = "ENABLED"; + parameter SLEEP = "DISABLED"; + parameter VREFACFG = "1P0_TO_1P2"; + parameter VREFASEL = "INTERNAL"; + parameter VREFBCFG = "1P0_TO_1P2"; + parameter VREFBSEL = "INTERNAL"; + input ADCEN; + input CAL; + output CALRDY; + input CHAEN; + input CHASEL3; + input CHASEL2; + input CHASEL1; + input CHASEL0; + input CHBEN; + input CHBSEL3; + input CHBSEL2; + input CHBSEL1; + input CHBSEL0; + input CLKDCLK; + input CLKFAB; + output COG; + input COMP1IN; + input COMP1IP; + output COMP1OL; + input COMP2IN; + input COMP2IP; + output COMP2OL; + input COMP3IN; + input COMP3IP; + output COMP3OL; + input CONVSTOP; + output DA11; + output DA10; + output DA9; + output DA8; + output DA7; + output DA6; + output DA5; + output DA4; + output DA3; + output DA2; + output DA1; + output DA0; + output DB11; + output DB10; + output DB9; + output DB8; + output DB7; + output DB6; + output DB5; + output DB4; + output DB3; + output DB2; + output DB1; + output DB0; + (* iopad_external_pin *) + input DN1; + (* iopad_external_pin *) + input DN0; + (* iopad_external_pin *) + input DP1; + (* iopad_external_pin *) + input DP0; + output EOC; + input GPION15; + input GPION14; + input GPION13; + input GPION12; + input GPION11; + input GPION10; + input GPION9; + input GPION8; + input GPION7; + input GPION6; + input GPION5; + input GPION4; + input GPION3; + input GPION2; + input GPION1; + input GPION0; + input GPIOP15; + input GPIOP14; + input GPIOP13; + input GPIOP12; + input GPIOP11; + input GPIOP10; + input GPIOP9; + input GPIOP8; + input GPIOP7; + input GPIOP6; + input GPIOP5; + input GPIOP4; + input GPIOP3; + input GPIOP2; + input GPIOP1; + input GPIOP0; + input RESETN; + input RSTN; + input RSVDH; + input RSVDL; + input SOC; + output COMP1O; + output COMP2O; + output COMP3O; +endmodule + +module ALUREG_CORE (...); + parameter ALURST_ACTIVELOW = "DISABLE"; + parameter GSR = "ENABLED"; + parameter INREG = "DISABLE"; + parameter MULFXP_ROUND = "ENABLE"; + parameter OUTREG = "DISABLE"; + parameter REGRST_ACTIVELOW = "DISABLE"; + parameter RETAIN = "ENABLE"; + parameter RFASYNC_RD = "SYNC_RD"; + parameter RFR0_RO = "R0READONLY"; + parameter RFUNALIA_WR = "DISABLE"; + parameter RFWCLK_INV = "SIG"; + input OPCGLOADCLK; + input ALUCLK; + output ALUFLAGC; + output ALUFLAGV; + output ALUFLAGZ; + input ALUFORWARDA; + input ALUFORWARDB; + input ALUIREGEN; + input ALUOREGEN; + input ALURST; + input DATAA31; + input DATAA30; + input DATAA29; + input DATAA28; + input DATAA27; + input DATAA26; + input DATAA25; + input DATAA24; + input DATAA23; + input DATAA22; + input DATAA21; + input DATAA20; + input DATAA19; + input DATAA18; + input DATAA17; + input DATAA16; + input DATAA15; + input DATAA14; + input DATAA13; + input DATAA12; + input DATAA11; + input DATAA10; + input DATAA9; + input DATAA8; + input DATAA7; + input DATAA6; + input DATAA5; + input DATAA4; + input DATAA3; + input DATAA2; + input DATAA1; + input DATAA0; + input DATAB31; + input DATAB30; + input DATAB29; + input DATAB28; + input DATAB27; + input DATAB26; + input DATAB25; + input DATAB24; + input DATAB23; + input DATAB22; + input DATAB21; + input DATAB20; + input DATAB19; + input DATAB18; + input DATAB17; + input DATAB16; + input DATAB15; + input DATAB14; + input DATAB13; + input DATAB12; + input DATAB11; + input DATAB10; + input DATAB9; + input DATAB8; + input DATAB7; + input DATAB6; + input DATAB5; + input DATAB4; + input DATAB3; + input DATAB2; + input DATAB1; + input DATAB0; + input DATAC4; + input DATAC3; + input DATAC2; + input DATAC1; + input DATAC0; + input OPC6; + input OPC5; + input OPC4; + input OPC3; + input OPC2; + input OPC1; + input OPC0; + input OPCCUSTOM; + input RADDRA4; + input RADDRA3; + input RADDRA2; + input RADDRA1; + input RADDRA0; + input RADDRB4; + input RADDRB3; + input RADDRB2; + input RADDRB1; + input RADDRB0; + output RDATAA31; + output RDATAA30; + output RDATAA29; + output RDATAA28; + output RDATAA27; + output RDATAA26; + output RDATAA25; + output RDATAA24; + output RDATAA23; + output RDATAA22; + output RDATAA21; + output RDATAA20; + output RDATAA19; + output RDATAA18; + output RDATAA17; + output RDATAA16; + output RDATAA15; + output RDATAA14; + output RDATAA13; + output RDATAA12; + output RDATAA11; + output RDATAA10; + output RDATAA9; + output RDATAA8; + output RDATAA7; + output RDATAA6; + output RDATAA5; + output RDATAA4; + output RDATAA3; + output RDATAA2; + output RDATAA1; + output RDATAA0; + output RDATAB31; + output RDATAB30; + output RDATAB29; + output RDATAB28; + output RDATAB27; + output RDATAB26; + output RDATAB25; + output RDATAB24; + output RDATAB23; + output RDATAB22; + output RDATAB21; + output RDATAB20; + output RDATAB19; + output RDATAB18; + output RDATAB17; + output RDATAB16; + output RDATAB15; + output RDATAB14; + output RDATAB13; + output RDATAB12; + output RDATAB11; + output RDATAB10; + output RDATAB9; + output RDATAB8; + output RDATAB7; + output RDATAB6; + output RDATAB5; + output RDATAB4; + output RDATAB3; + output RDATAB2; + output RDATAB1; + output RDATAB0; + input REGCLK; + input REGCLKEN; + input REGRST; + output RESULT31; + output RESULT30; + output RESULT29; + output RESULT28; + output RESULT27; + output RESULT26; + output RESULT25; + output RESULT24; + output RESULT23; + output RESULT22; + output RESULT21; + output RESULT20; + output RESULT19; + output RESULT18; + output RESULT17; + output RESULT16; + output RESULT15; + output RESULT14; + output RESULT13; + output RESULT12; + output RESULT11; + output RESULT10; + output RESULT9; + output RESULT8; + output RESULT7; + output RESULT6; + output RESULT5; + output RESULT4; + output RESULT3; + output RESULT2; + output RESULT1; + output RESULT0; + input SCANCLK; + input SCANRST; + input WADDR4; + input WADDR3; + input WADDR2; + input WADDR1; + input WADDR0; + input WDROTATE1; + input WDROTATE0; + input WDSIGNEXT; + input WDSIZE1; + input WDSIZE0; + input WDATA31; + input WDATA30; + input WDATA29; + input WDATA28; + input WDATA27; + input WDATA26; + input WDATA25; + input WDATA24; + input WDATA23; + input WDATA22; + input WDATA21; + input WDATA20; + input WDATA19; + input WDATA18; + input WDATA17; + input WDATA16; + input WDATA15; + input WDATA14; + input WDATA13; + input WDATA12; + input WDATA11; + input WDATA10; + input WDATA9; + input WDATA8; + input WDATA7; + input WDATA6; + input WDATA5; + input WDATA4; + input WDATA3; + input WDATA2; + input WDATA1; + input WDATA0; + input WREN; +endmodule + +module BNKREF18_CORE (...); + parameter BANK = "0b0000"; + parameter STANDBY_DIFFIO = "DISABLED"; + parameter STANDBY_INR = "DISABLED"; + input STDBYINR; + input STDBYDIF; + input PVTSNKI6; + input PVTSNKI5; + input PVTSNKI4; + input PVTSNKI3; + input PVTSNKI2; + input PVTSNKI1; + input PVTSNKI0; + input PVTSRCI6; + input PVTSRCI5; + input PVTSRCI4; + input PVTSRCI3; + input PVTSRCI2; + input PVTSRCI1; + input PVTSRCI0; + output PVTCODE6; + output PVTCODE5; + output PVTCODE4; + output PVTCODE3; + output PVTCODE2; + output PVTCODE1; + output PVTCODE0; + input PVTSEL; +endmodule + +module BNKREF33_CORE (...); + parameter BANK = "0b0000"; + input PVTSEL; + input PVTSNKI6; + input PVTSNKI5; + input PVTSNKI4; + input PVTSNKI3; + input PVTSNKI2; + input PVTSNKI1; + input PVTSNKI0; + input PVTSRCI6; + input PVTSRCI5; + input PVTSRCI4; + input PVTSRCI3; + input PVTSRCI2; + input PVTSRCI1; + input PVTSRCI0; + output PVTCODE6; + output PVTCODE5; + output PVTCODE4; + output PVTCODE3; + output PVTCODE2; + output PVTCODE1; + output PVTCODE0; +endmodule + +module DIFFIO18_CORE (...); + parameter MIPI_ID = "0"; + parameter PULLMODE = "DOWN"; + parameter ENADC_IN = "DISABLED"; + parameter MIPI = "DISABLED"; + input I; + input DOLP; + (* iopad_external_pin *) + inout B; + output O; + output INLP; + input T; + output INADC; + input HSRXEN; + input HSTXEN; +endmodule + +(* keep *) +module CONFIG_CLKRST_CORE (...); + parameter MCJTAGGSRNDIS = "EN"; + parameter MCLMMIGSRNDIS = "EN"; + parameter MCSEDCGSRNDIS = "EN"; + parameter MCWDTGSRNDIS = "EN"; + parameter SMCLK_DIV = "3"; + output HSE_CLK; + input JTAG_LRST_N; + input LMMI_CLK; + output LMMI_CLK_O; + input LMMI_LRST_N; + output LMMI_RST; + input OSCCLK; + input SEDC_CLK; + input SEDC_LRST_N; + output SEDC_RST; + output CFG_CLK; + output SMCLK_RST; + output WDT_CLK; + input WDT_LRST_N; + output WDT_RST; +endmodule + +(* keep *) +module CONFIG_HSE_CORE (...); + parameter MCGLBGSRNDIS = "EN"; + parameter MCHSEDISABLE = "EN"; + parameter MCHSEOTPEN = "DIS"; + input ASFCLKI; + output ASFEMPTYO; + output ASFFULLO; + input ASFRDI; + input ASFRESETI; + input ASFWRI; + input CFG_CLK; + input HSE_CLK; + input HSELRSTN; + input LMMICLK; + input LMMIOFFSET17; + input LMMIOFFSET16; + input LMMIOFFSET15; + input LMMIOFFSET14; + input LMMIOFFSET13; + input LMMIOFFSET12; + input LMMIOFFSET11; + input LMMIOFFSET10; + input LMMIOFFSET9; + input LMMIOFFSET8; + input LMMIOFFSET7; + input LMMIOFFSET6; + input LMMIOFFSET5; + input LMMIOFFSET4; + input LMMIOFFSET3; + input LMMIOFFSET2; + input LMMIOFFSET1; + input LMMIOFFSET0; + output LMMIRDATA31; + output LMMIRDATA30; + output LMMIRDATA29; + output LMMIRDATA28; + output LMMIRDATA27; + output LMMIRDATA26; + output LMMIRDATA25; + output LMMIRDATA24; + output LMMIRDATA23; + output LMMIRDATA22; + output LMMIRDATA21; + output LMMIRDATA20; + output LMMIRDATA19; + output LMMIRDATA18; + output LMMIRDATA17; + output LMMIRDATA16; + output LMMIRDATA15; + output LMMIRDATA14; + output LMMIRDATA13; + output LMMIRDATA12; + output LMMIRDATA11; + output LMMIRDATA10; + output LMMIRDATA9; + output LMMIRDATA8; + output LMMIRDATA7; + output LMMIRDATA6; + output LMMIRDATA5; + output LMMIRDATA4; + output LMMIRDATA3; + output LMMIRDATA2; + output LMMIRDATA1; + output LMMIRDATA0; + output LMMIRDATAVALID; + output LMMIREADY; + input LMMIREQUEST; + input LMMIRESETN; + input LMMIWDATA31; + input LMMIWDATA30; + input LMMIWDATA29; + input LMMIWDATA28; + input LMMIWDATA27; + input LMMIWDATA26; + input LMMIWDATA25; + input LMMIWDATA24; + input LMMIWDATA23; + input LMMIWDATA22; + input LMMIWDATA21; + input LMMIWDATA20; + input LMMIWDATA19; + input LMMIWDATA18; + input LMMIWDATA17; + input LMMIWDATA16; + input LMMIWDATA15; + input LMMIWDATA14; + input LMMIWDATA13; + input LMMIWDATA12; + input LMMIWDATA11; + input LMMIWDATA10; + input LMMIWDATA9; + input LMMIWDATA8; + input LMMIWDATA7; + input LMMIWDATA6; + input LMMIWDATA5; + input LMMIWDATA4; + input LMMIWDATA3; + input LMMIWDATA2; + input LMMIWDATA1; + input LMMIWDATA0; + input LMMIWRRDN; + input OTM; +endmodule + +(* keep *) +module CONFIG_JTAG_CORE (...); + parameter MCER1EXIST = "NEXIST"; + parameter MCER2EXIST = "NEXIST"; + output JCE1; + output JCE2; + output JRSTN; + output JRTI1; + output JRTI2; + output JSHIFT; + output JTDI; + output JUPDATE; + input JTDO1; + input JTDO2; + input SMCLK; + input TCK; + output JTCK; + input TDI; + output TDO_OEN; + output TDO; + input TMS; +endmodule + +(* keep *) +module CONFIG_LMMI_CORE (...); + parameter LMMI_EN = "DIS"; + input LMMIOFFSET7; + input LMMIOFFSET6; + input LMMIOFFSET5; + input LMMIOFFSET4; + input LMMIOFFSET3; + input LMMIOFFSET2; + input LMMIOFFSET1; + input LMMIOFFSET0; + input LMMICLK; + output LMMIRDATA7; + output LMMIRDATA6; + output LMMIRDATA5; + output LMMIRDATA4; + output LMMIRDATA3; + output LMMIRDATA2; + output LMMIRDATA1; + output LMMIRDATA0; + output LMMIRDATAVALID; + output LMMIREADY; + input LMMIRESETN; + input LMMIREQUEST; + input LMMIWDATA7; + input LMMIWDATA6; + input LMMIWDATA5; + input LMMIWDATA4; + input LMMIWDATA3; + input LMMIWDATA2; + input LMMIWDATA1; + input LMMIWDATA0; + input LMMIWRRDN; + input RSTSMCLK; + input SMCLK; +endmodule + +(* keep *) +module CONFIG_MULTIBOOT_CORE (...); + parameter MSPIADDR = "0b00000000000000000000000000000000"; + parameter SOURCESEL = "DIS"; + input CIBAUTOREBOOT; + input CIBMSPIMADDR31; + input CIBMSPIMADDR30; + input CIBMSPIMADDR29; + input CIBMSPIMADDR28; + input CIBMSPIMADDR27; + input CIBMSPIMADDR26; + input CIBMSPIMADDR25; + input CIBMSPIMADDR24; + input CIBMSPIMADDR23; + input CIBMSPIMADDR22; + input CIBMSPIMADDR21; + input CIBMSPIMADDR20; + input CIBMSPIMADDR19; + input CIBMSPIMADDR18; + input CIBMSPIMADDR17; + input CIBMSPIMADDR16; + input CIBMSPIMADDR15; + input CIBMSPIMADDR14; + input CIBMSPIMADDR13; + input CIBMSPIMADDR12; + input CIBMSPIMADDR11; + input CIBMSPIMADDR10; + input CIBMSPIMADDR9; + input CIBMSPIMADDR8; + input CIBMSPIMADDR7; + input CIBMSPIMADDR6; + input CIBMSPIMADDR5; + input CIBMSPIMADDR4; + input CIBMSPIMADDR3; + input CIBMSPIMADDR2; + input CIBMSPIMADDR1; + input CIBMSPIMADDR0; +endmodule + +(* keep *) +module CONFIG_SEDC_CORE (...); + parameter SEDCEN = "DIS"; + input CIBSED1ENABLE; + input CIBSEDCCOF; + input CIBSEDCENABLE; + input CIBSEDCMODE; + input CIBSEDCSTART; + input OSCCLKSEDC; + input RSTSEDC; + output SEDCBUSYCIB; + output SEDCDSRERRLOCCIB12; + output SEDCDSRERRLOCCIB11; + output SEDCDSRERRLOCCIB10; + output SEDCDSRERRLOCCIB9; + output SEDCDSRERRLOCCIB8; + output SEDCDSRERRLOCCIB7; + output SEDCDSRERRLOCCIB6; + output SEDCDSRERRLOCCIB5; + output SEDCDSRERRLOCCIB4; + output SEDCDSRERRLOCCIB3; + output SEDCDSRERRLOCCIB2; + output SEDCDSRERRLOCCIB1; + output SEDCDSRERRLOCCIB0; + output SEDCERR1CIB; + output SEDCERRCCIB; + output SEDCERRCRCCIB; + output SEDCERRMCIB; + output SEDCFRMERRLOCCIB15; + output SEDCFRMERRLOCCIB14; + output SEDCFRMERRLOCCIB13; + output SEDCFRMERRLOCCIB12; + output SEDCFRMERRLOCCIB11; + output SEDCFRMERRLOCCIB10; + output SEDCFRMERRLOCCIB9; + output SEDCFRMERRLOCCIB8; + output SEDCFRMERRLOCCIB7; + output SEDCFRMERRLOCCIB6; + output SEDCFRMERRLOCCIB5; + output SEDCFRMERRLOCCIB4; + output SEDCFRMERRLOCCIB3; + output SEDCFRMERRLOCCIB2; + output SEDCFRMERRLOCCIB1; + output SEDCFRMERRLOCCIB0; +endmodule + +(* keep *) +module CONFIG_WDT_CORE (...); + parameter WDTEN = "DIS"; + parameter WDTMODE = "SINGLE"; + parameter WDTVALUE = "0b000000000000000000"; + input CIBWDTRELOAD; + input WDT_CLK; + input WDT_RST; +endmodule + +module DDRDLL_CORE (...); + parameter GSR = "ENABLED"; + parameter ENA_ROUNDOFF = "ENABLED"; + parameter FORCE_MAX_DELAY = "CODE_OR_LOCK_FROM_DLL_LOOP"; + output CODE8; + output CODE7; + output CODE6; + output CODE5; + output CODE4; + output CODE3; + output CODE2; + output CODE1; + output CODE0; + input FREEZE; + output LOCK; + input CLKIN; + input RST; + output DCNTL8; + output DCNTL7; + output DCNTL6; + output DCNTL5; + output DCNTL4; + output DCNTL3; + output DCNTL2; + output DCNTL1; + output DCNTL0; + input UDDCNTL_N; +endmodule + +module DLLDEL_CORE (...); + parameter ADJUST = "0"; + parameter DEL_ADJUST = "PLUS"; + parameter ENABLE = "DISABLED"; + input CLKIN; + output CLKOUT; + input CODE8; + input CODE7; + input CODE6; + input CODE5; + input CODE4; + input CODE3; + input CODE2; + input CODE1; + input CODE0; + output COUT; + input DIR; + input LOAD_N; + input MOVE; +endmodule + +module DPHY_CORE (...); + parameter GSR = "ENABLED"; + parameter AUTO_PD_EN = "POWERED_UP"; + parameter CFG_NUM_LANES = "ONE_LANE"; + parameter CM = "0b00000000"; + parameter CN = "0b00000"; + parameter CO = "0b000"; + parameter CONT_CLK_MODE = "DISABLED"; + parameter DESKEW_EN = "DISABLED"; + parameter DSI_CSI = "CSI2_APP"; + parameter EN_CIL = "CIL_ENABLED"; + parameter HSEL = "DISABLED"; + parameter LANE0_SEL = "LANE_0"; + parameter LOCK_BYP = "GATE_TXBYTECLKHS"; + parameter MASTER_SLAVE = "SLAVE"; + parameter PLLCLKBYPASS = "REGISTERED"; + parameter RSEL = "0b00"; + parameter RXCDRP = "0b00"; + parameter RXDATAWIDTHHS = "0b00"; + parameter RXLPRP = "0b000"; + parameter TEST_ENBL = "0b000000"; + parameter TEST_PATTERN = "0b00000000000000000000000000000000"; + parameter TST = "0b1001"; + parameter TXDATAWIDTHHS = "0b00"; + parameter U_PRG_HS_PREPARE = "0b00"; + parameter U_PRG_HS_TRAIL = "0b000000"; + parameter U_PRG_HS_ZERO = "0b000000"; + parameter U_PRG_RXHS_SETTLE = "0b000000"; + parameter UC_PRG_HS_PREPARE = "1P0_TXCLKESC"; + parameter UC_PRG_HS_TRAIL = "0b00000"; + parameter UC_PRG_HS_ZERO = "0b0000000"; + parameter UC_PRG_RXHS_SETTLE = "0b000000"; + input BITCKEXT; + (* iopad_external_pin *) + inout CKN; + (* iopad_external_pin *) + inout CKP; + input CLKREF; + output D0ACTIVE1; + output D0ACTIVE0; + output D0BYTCNT9; + output D0BYTCNT8; + output D0BYTCNT7; + output D0BYTCNT6; + output D0BYTCNT5; + output D0BYTCNT4; + output D0BYTCNT3; + output D0BYTCNT2; + output D0BYTCNT1; + output D0BYTCNT0; + output D0ERRCNT9; + output D0ERRCNT8; + output D0ERRCNT7; + output D0ERRCNT6; + output D0ERRCNT5; + output D0ERRCNT4; + output D0ERRCNT3; + output D0ERRCNT2; + output D0ERRCNT1; + output D0ERRCNT0; + output D0PASS1; + output D0PASS0; + output D0VALID1; + output D0VALID0; + output D1ACTIVE1; + output D1ACTIVE0; + output D1BYTCNT9; + output D1BYTCNT8; + output D1BYTCNT7; + output D1BYTCNT6; + output D1BYTCNT5; + output D1BYTCNT4; + output D1BYTCNT3; + output D1BYTCNT2; + output D1BYTCNT1; + output D1BYTCNT0; + output D1ERRCNT9; + output D1ERRCNT8; + output D1ERRCNT7; + output D1ERRCNT6; + output D1ERRCNT5; + output D1ERRCNT4; + output D1ERRCNT3; + output D1ERRCNT2; + output D1ERRCNT1; + output D1ERRCNT0; + output D1PASS1; + output D1PASS0; + output D1VALID1; + output D1VALID0; + output D2ACTIVE1; + output D2ACTIVE0; + output D2BYTCNT9; + output D2BYTCNT8; + output D2BYTCNT7; + output D2BYTCNT6; + output D2BYTCNT5; + output D2BYTCNT4; + output D2BYTCNT3; + output D2BYTCNT2; + output D2BYTCNT1; + output D2BYTCNT0; + output D2ERRCNT9; + output D2ERRCNT8; + output D2ERRCNT7; + output D2ERRCNT6; + output D2ERRCNT5; + output D2ERRCNT4; + output D2ERRCNT3; + output D2ERRCNT2; + output D2ERRCNT1; + output D2ERRCNT0; + output D2PASS1; + output D2PASS0; + output D2VALID1; + output D2VALID0; + output D3ACTIVE1; + output D3ACTIVE0; + output D3BYTCNT9; + output D3BYTCNT8; + output D3BYTCNT7; + output D3BYTCNT6; + output D3BYTCNT5; + output D3BYTCNT4; + output D3BYTCNT3; + output D3BYTCNT2; + output D3BYTCNT1; + output D3BYTCNT0; + output D3ERRCNT9; + output D3ERRCNT8; + output D3ERRCNT7; + output D3ERRCNT6; + output D3ERRCNT5; + output D3ERRCNT4; + output D3ERRCNT3; + output D3ERRCNT2; + output D3ERRCNT1; + output D3ERRCNT0; + output D3PASS1; + output D3PASS0; + output D3VALID1; + output D3VALID0; + output DCTSTOUT9; + output DCTSTOUT8; + output DCTSTOUT7; + output DCTSTOUT6; + output DCTSTOUT5; + output DCTSTOUT4; + output DCTSTOUT3; + output DCTSTOUT2; + output DCTSTOUT1; + output DCTSTOUT0; + (* iopad_external_pin *) + inout DN0; + (* iopad_external_pin *) + inout DN1; + (* iopad_external_pin *) + inout DN2; + (* iopad_external_pin *) + inout DN3; + (* iopad_external_pin *) + inout DP0; + (* iopad_external_pin *) + inout DP1; + (* iopad_external_pin *) + inout DP2; + (* iopad_external_pin *) + inout DP3; + output LOCK; + input PDDPHY; + input PDPLL; + input SCCLKIN; + input SCRSTNIN; + output UDIR; + input UED0THEN; + output UERCLP0; + output UERCLP1; + output UERCTRL; + output UERE; + output UERSTHS; + output UERSSHS; + output UERSE; + input UFRXMODE; + input UTXMDTX; + output URXACTHS; + output URXCKE; + input URXCKINE; + output URXDE7; + output URXDE6; + output URXDE5; + output URXDE4; + output URXDE3; + output URXDE2; + output URXDE1; + output URXDE0; + output URXDHS15; + output URXDHS14; + output URXDHS13; + output URXDHS12; + output URXDHS11; + output URXDHS10; + output URXDHS9; + output URXDHS8; + output URXDHS7; + output URXDHS6; + output URXDHS5; + output URXDHS4; + output URXDHS3; + output URXDHS2; + output URXDHS1; + output URXDHS0; + output URXLPDTE; + output URXSKCHS; + output URXDRX; + output URXSHS3; + output URXSHS2; + output URXSHS1; + output URXSHS0; + output URE0D3DP; + output URE1D3DN; + output URE2CKDP; + output URE3CKDN; + output URXULPSE; + output URXVDE; + output URXVDHS3; + output URXVDHS2; + output URXVDHS1; + output URXVDHS0; + output USSTT; + input UTDIS; + input UTXCKE; + input UDE0D0TN; + input UDE1D1TN; + input UDE2D2TN; + input UDE3D3TN; + input UDE4CKTN; + input UDE5D0RN; + input UDE6D1RN; + input UDE7D2RN; + input UTXDHS31; + input UTXDHS30; + input UTXDHS29; + input UTXDHS28; + input UTXDHS27; + input UTXDHS26; + input UTXDHS25; + input UTXDHS24; + input UTXDHS23; + input UTXDHS22; + input UTXDHS21; + input UTXDHS20; + input UTXDHS19; + input UTXDHS18; + input UTXDHS17; + input UTXDHS16; + input UTXDHS15; + input UTXDHS14; + input UTXDHS13; + input UTXDHS12; + input UTXDHS11; + input UTXDHS10; + input UTXDHS9; + input UTXDHS8; + input UTXDHS7; + input UTXDHS6; + input UTXDHS5; + input UTXDHS4; + input UTXDHS3; + input UTXDHS2; + input UTXDHS1; + input UTXDHS0; + input UTXENER; + output UTXRRS; + output UTXRYP; + output UTXRYSK; + input UTXRD0EN; + input UTRD0SEN; + input UTXSKD0N; + input UTXTGE0; + input UTXTGE1; + input UTXTGE2; + input UTXTGE3; + input UTXULPSE; + input UTXUPSEX; + input UTXVDE; + input UTXWVDHS3; + input UTXWVDHS2; + input UTXWVDHS1; + input UTXWVDHS0; + output UUSAN; + output U1DIR; + input U1ENTHEN; + output U1ERCLP0; + output U1ERCLP1; + output U1ERCTRL; + output U1ERE; + output U1ERSTHS; + output U1ERSSHS; + output U1ERSE; + input U1FRXMD; + input U1FTXST; + output U1RXATHS; + output U1RXCKE; + output U1RXDE7; + output U1RXDE6; + output U1RXDE5; + output U1RXDE4; + output U1RXDE3; + output U1RXDE2; + output U1RXDE1; + output U1RXDE0; + output U1RXDHS15; + output U1RXDHS14; + output U1RXDHS13; + output U1RXDHS12; + output U1RXDHS11; + output U1RXDHS10; + output U1RXDHS9; + output U1RXDHS8; + output U1RXDHS7; + output U1RXDHS6; + output U1RXDHS5; + output U1RXDHS4; + output U1RXDHS3; + output U1RXDHS2; + output U1RXDHS1; + output U1RXDHS0; + output U1RXDTE; + output U1RXSKS; + output U1RXSK; + output U1RXSHS3; + output U1RXSHS2; + output U1RXSHS1; + output U1RXSHS0; + output U1RE0D; + output U1RE1CN; + output U1RE2D; + output U1RE3N; + output U1RXUPSE; + output U1RXVDE; + output U1RXVDHS3; + output U1RXVDHS2; + output U1RXVDHS1; + output U1RXVDHS0; + output U1SSTT; + input U1TDIS; + input U1TREQ; + input U1TDE0D3; + input U1TDE1CK; + input U1TDE2D0; + input U1TDE3D1; + input U1TDE4D2; + input U1TDE5D3; + input U1TDE6; + input U1TDE7; + input U1TXDHS31; + input U1TXDHS30; + input U1TXDHS29; + input U1TXDHS28; + input U1TXDHS27; + input U1TXDHS26; + input U1TXDHS25; + input U1TXDHS24; + input U1TXDHS23; + input U1TXDHS22; + input U1TXDHS21; + input U1TXDHS20; + input U1TXDHS19; + input U1TXDHS18; + input U1TXDHS17; + input U1TXDHS16; + input U1TXDHS15; + input U1TXDHS14; + input U1TXDHS13; + input U1TXDHS12; + input U1TXDHS11; + input U1TXDHS10; + input U1TXDHS9; + input U1TXDHS8; + input U1TXDHS7; + input U1TXDHS6; + input U1TXDHS5; + input U1TXDHS4; + input U1TXDHS3; + input U1TXDHS2; + input U1TXDHS1; + input U1TXDHS0; + input U1TXLPD; + output U1TXRYE; + output U1TXRY; + output U1TXRYSK; + input U1TXREQ; + input U1TXREQH; + input U1TXSK; + input U1TXTGE0; + input U1TXTGE1; + input U1TXTGE2; + input U1TXTGE3; + input U1TXUPSE; + input U1TXUPSX; + input U1TXVDE; + input U1TXWVHS3; + input U1TXWVHS2; + input U1TXWVHS1; + input U1TXWVHS0; + output U1USAN; + output U2DIR; + input U2END2; + output U2ERCLP0; + output U2ERCLP1; + output U2ERCTRL; + output U2ERE; + output U2ERSTHS; + output U2ERSSHS; + output U2ERSE; + input U2FRXMD; + input U2FTXST; + output U2RXACHS; + output U2RXCKE; + output U2RXDE7; + output U2RXDE6; + output U2RXDE5; + output U2RXDE4; + output U2RXDE3; + output U2RXDE2; + output U2RXDE1; + output U2RXDE0; + output U2RXDHS15; + output U2RXDHS14; + output U2RXDHS13; + output U2RXDHS12; + output U2RXDHS11; + output U2RXDHS10; + output U2RXDHS9; + output U2RXDHS8; + output U2RXDHS7; + output U2RXDHS6; + output U2RXDHS5; + output U2RXDHS4; + output U2RXDHS3; + output U2RXDHS2; + output U2RXDHS1; + output U2RXDHS0; + output U2RPDTE; + output U2RXSK; + output U2RXSKC; + output U2RXSHS3; + output U2RXSHS2; + output U2RXSHS1; + output U2RXSHS0; + output U2RE0D2; + output U2RE1D2; + output U2RE2D3; + output U2RE3D3; + output U2RXUPSE; + output U2RXVDE; + output U2RXVDHS3; + output U2RXVDHS2; + output U2RXVDHS1; + output U2RXVDHS0; + output U2SSTT; + input U2TDIS; + input U2TREQ; + input U2TDE0D0; + input U2TDE1D1; + input U2TDE2D2; + input U2TDE3D3; + input U2TDE4CK; + input U2TDE5D0; + input U2TDE6D1; + input U2TDE7D2; + input U2TXDHS31; + input U2TXDHS30; + input U2TXDHS29; + input U2TXDHS28; + input U2TXDHS27; + input U2TXDHS26; + input U2TXDHS25; + input U2TXDHS24; + input U2TXDHS23; + input U2TXDHS22; + input U2TXDHS21; + input U2TXDHS20; + input U2TXDHS19; + input U2TXDHS18; + input U2TXDHS17; + input U2TXDHS16; + input U2TXDHS15; + input U2TXDHS14; + input U2TXDHS13; + input U2TXDHS12; + input U2TXDHS11; + input U2TXDHS10; + input U2TXDHS9; + input U2TXDHS8; + input U2TXDHS7; + input U2TXDHS6; + input U2TXDHS5; + input U2TXDHS4; + input U2TXDHS3; + input U2TXDHS2; + input U2TXDHS1; + input U2TXDHS0; + input U2TPDTE; + output U2TXRYE; + output U2TXRYH; + output U2TXRYSK; + input U2TXREQ; + input U2TXREQH; + input U2TXSKC; + input U2TXTGE0; + input U2TXTGE1; + input U2TXTGE2; + input U2TXTGE3; + input U2TXUPSE; + input U2TXUPSX; + input U2TXVDE; + input U2TXWVHS3; + input U2TXWVHS2; + input U2TXWVHS1; + input U2TXWVHS0; + output U2USAN; + output U3DIR; + input U3END3; + output U3ERCLP0; + output U3ERCLP1; + output U3ERCTRL; + output U3ERE; + output U3ERSTHS; + output U3ERSSHS; + output U3ERSE; + input U3FRXMD; + input U3FTXST; + output U3RXATHS; + output U3RXCKE; + output U3RXDE7; + output U3RXDE6; + output U3RXDE5; + output U3RXDE4; + output U3RXDE3; + output U3RXDE2; + output U3RXDE1; + output U3RXDE0; + output U3RXDHS15; + output U3RXDHS14; + output U3RXDHS13; + output U3RXDHS12; + output U3RXDHS11; + output U3RXDHS10; + output U3RXDHS9; + output U3RXDHS8; + output U3RXDHS7; + output U3RXDHS6; + output U3RXDHS5; + output U3RXDHS4; + output U3RXDHS3; + output U3RXDHS2; + output U3RXDHS1; + output U3RXDHS0; + output U3RPDTE; + output U3RXSK; + output U3RXSKC; + output U3RXSHS3; + output U3RXSHS2; + output U3RXSHS1; + output U3RXSHS0; + output U3RE0CK; + output U3RE1CK; + output U3RE2; + output U3RE3; + output U3RXUPSE; + output U3RXVDE; + output U3RXVDHS3; + output U3RXVDHS2; + output U3RXVDHS1; + output U3RXVDHS0; + output U3SSTT; + input U3TDISD2; + input U3TREQD2; + input U3TDE0D3; + input U3TDE1D0; + input U3TDE2D1; + input U3TDE3D2; + input U3TDE4D3; + input U3TDE5CK; + input U3TDE6; + input U3TDE7; + input U3TXDHS31; + input U3TXDHS30; + input U3TXDHS29; + input U3TXDHS28; + input U3TXDHS27; + input U3TXDHS26; + input U3TXDHS25; + input U3TXDHS24; + input U3TXDHS23; + input U3TXDHS22; + input U3TXDHS21; + input U3TXDHS20; + input U3TXDHS19; + input U3TXDHS18; + input U3TXDHS17; + input U3TXDHS16; + input U3TXDHS15; + input U3TXDHS14; + input U3TXDHS13; + input U3TXDHS12; + input U3TXDHS11; + input U3TXDHS10; + input U3TXDHS9; + input U3TXDHS8; + input U3TXDHS7; + input U3TXDHS6; + input U3TXDHS5; + input U3TXDHS4; + input U3TXDHS3; + input U3TXDHS2; + input U3TXDHS1; + input U3TXDHS0; + input U3TXLPDT; + output U3TXRY; + output U3TXRYHS; + output U3TXRYSK; + input U3TXREQ; + input U3TXREQH; + input U3TXSKC; + input U3TXTGE0; + input U3TXTGE1; + input U3TXTGE2; + input U3TXTGE3; + input U3TXULPS; + input U3TXUPSX; + input U3TXVD3; + input U3TXWVHS3; + input U3TXWVHS2; + input U3TXWVHS1; + input U3TXWVHS0; + output U3USAN; + input UCENCK; + output UCRXCKAT; + output UCRXUCKN; + output UCSSTT; + input UCTXREQH; + input UCTXUPSC; + input UCTXUPSX; + output UCUSAN; + input SCANCLK; + input SCANRST; + input LMMICLK; + input LMMIOFFSET4; + input LMMIOFFSET3; + input LMMIOFFSET2; + input LMMIOFFSET1; + input LMMIOFFSET0; + output LMMIRDATA3; + output LMMIRDATA2; + output LMMIRDATA1; + output LMMIRDATA0; + output LMMIRDATAVALID; + output LMMIREADY; + input LMMIREQUEST; + input LMMIRESETN; + input LMMIWDATA3; + input LMMIWDATA2; + input LMMIWDATA1; + input LMMIWDATA0; + input LMMIWRRDN; + input LTSTEN; + input LTSTLANE1; + input LTSTLANE0; + output URWDCKHS; + input UTRNREQ; + output UTWDCKHS; + output UCRXWCHS; + input OPCGLDCK; + output CLKLBACT; +endmodule + +module DQSBUF_CORE (...); + parameter GSR = "ENABLED"; + parameter ENABLE_FIFO = "DISABLED"; + parameter FORCE_READ = "DISABLED"; + parameter FREE_WHEEL = "DDR"; + parameter MODX = "NOT_USED"; + parameter MT_EN_READ = "DISABLED"; + parameter MT_EN_WRITE = "DISABLED"; + parameter MT_EN_WRITE_LEVELING = "DISABLED"; + parameter RD_PNTR = "0b000"; + parameter READ_ENABLE = "DISABLED"; + parameter RX_CENTERED = "ENABLED"; + parameter S_READ = "0"; + parameter S_WRITE = "0"; + parameter SIGN_READ = "POSITIVE"; + parameter SIGN_WRITE = "POSITIVE"; + parameter UPDATE_QU = "UP1_AND_UP0_SAME"; + parameter WRITE_ENABLE = "DISABLED"; + parameter SEL_READ_BIT_ENABLE_CYCLES = "NORMAL"; + parameter BYPASS_WR_LEVEL_SMTH_LATCH = "SMOOTHING_PATH"; + parameter BYPASS_WR_SMTH_LATCH = "SMOOTHING_PATH"; + parameter BYPASS_READ_SMTH_LATCH = "SMOOTHING_PATH"; + output BTDETECT; + output BURSTDETECT; + output DATAVALID; + input DQSI; + output DQSW; + output DQSWRD; + input PAUSE; + input RDCLKSEL3; + input RDCLKSEL2; + input RDCLKSEL1; + input RDCLKSEL0; + input RDDIR; + input RDLOADN; + output RDPNTR2; + output RDPNTR1; + output RDPNTR0; + input READ3; + input READ2; + input READ1; + input READ0; + output READCOUT; + input READMOVE; + input RST; + input SCLK; + input SELCLK; + output DQSR90; + output DQSW270; + output WRCOUT; + input WRDIR; + input WRLOAD_N; + output WRLVCOUT; + input WRLVDIR; + input WRLVLOAD_N; + input WRLVMOVE; + input WRMOVE; + output WRPNTR2; + output WRPNTR1; + output WRPNTR0; + input ECLKIN; + input RSTSMCNT; + input DLLCODE8; + input DLLCODE7; + input DLLCODE6; + input DLLCODE5; + input DLLCODE4; + input DLLCODE3; + input DLLCODE2; + input DLLCODE1; + input DLLCODE0; +endmodule + +module ECLKDIV_CORE (...); + parameter ECLK_DIV = "DISABLE"; + parameter GSR = "ENABLED"; + output DIVOUT; + input DIVRST; + input ECLKIN; + input SLIP; + input TESTINP3; + input TESTINP2; + input TESTINP1; + input TESTINP0; +endmodule + +module ECLKSYNC_CORE (...); + parameter STOP_EN = "DISABLE"; + input ECLKIN; + output ECLKOUT; + input STOP; +endmodule + +module FBMUX_CORE (...); + parameter INTFB = "IGNORED"; + parameter SEL_FBK = "DIVA"; + parameter CLKMUX_FB = "CMUX_CLKOP"; + parameter INTFBKDEL_SEL = "DISABLED"; + output ENEXT; + output FBKCK; + input LGYRDYN; + input INTLOCK; + input WKUPSYNC; + input FBKCLK15; + input FBKCLK14; + input FBKCLK13; + input FBKCLK12; + input FBKCLK11; + input FBKCLK10; + input FBKCLK9; + input FBKCLK8; + input FBKCLK7; + input FBKCLK6; + input FBKCLK5; + input FBKCLK4; + input FBKCLK3; + input FBKCLK2; + input FBKCLK1; + input FBKCLK0; +endmodule + +module I2CFIFO_CORE (...); + parameter BRNBASEDELAY = "0b0000"; + parameter CR1CKDIS = "EN"; + parameter CR1FIFOMODE = "REG"; + parameter CR1GCEN = "DIS"; + parameter CR1I2CEN = "DIS"; + parameter CR1SDADELSEL = "NDLY0"; + parameter CR1SLPCLKEN = "DIS"; + parameter CR2CORERSTN = "DIS"; + parameter CR2HARDTIE = "TIE"; + parameter CR2INTCLREN = "DIS"; + parameter CR2MRDCMPLWKUP = "DIS"; + parameter CR2RXFIFOAFWKUP = "DIS"; + parameter CR2SLVADDRWKUP = "DIS"; + parameter GSR = "ENABLED"; + parameter I2CRXFIFOAFVAL = "0b00000"; + parameter I2CSLVADDRA = "0b0000000000"; + parameter I2CTXFIFOAEVAL = "0b0000"; + parameter INTARBLIE = "DIS"; + parameter INTBUSFREEIE = "DIS"; + parameter INTHGCIE = "DIS"; + parameter INTMRDCMPLIE = "DIS"; + parameter INTRNACKIEORRSVD = "DIS"; + parameter INTRSVDORTROEIE = "DIS"; + parameter INTRSVDORTRRDYIE = "DIS"; + parameter INTRXOVERFIEORRSVD = "DIS"; + parameter INTRXUNDERFIE = "DIS"; + parameter INTTXOVERFIE = "DIS"; + parameter INTTXSERRIEORRSVD = "DIS"; + parameter LMMI_EXTRA_ONE = "DIS"; + parameter LMMI_EXTRA_TWO = "DIS"; + parameter NCRALTIOEN = "FABRIC"; + parameter NCRFILTERDIS = "EN"; + parameter NCRSDAINDLYEN = "DIS"; + parameter NCRSDAOUTDLYEN = "DIS"; + parameter NONUSRTESTSOFTTRIMEN = "DIS"; + parameter NONUSRTSTSOFTTRIMVALUE = "0b000"; + parameter REGI2CBR = "0b0000000000"; + parameter TSPTIMERVALUE = "0b10010010111"; + input ALTSCLIN; + output ALTSCLOEN; + output ALTSCLOUT; + input ALTSDAIN; + output ALTSDAOEN; + output ALTSDAOUT; + output BUSBUSY; + input FIFORESET; + input I2CLSRRSTN; + output INSLEEP; + output IRQ; + input LMMICLK; + input LMMIOFFSET5; + input LMMIOFFSET4; + input LMMIOFFSET3; + input LMMIOFFSET2; + input LMMIOFFSET1; + input LMMIOFFSET0; + output LMMIRDATA7; + output LMMIRDATA6; + output LMMIRDATA5; + output LMMIRDATA4; + output LMMIRDATA3; + output LMMIRDATA2; + output LMMIRDATA1; + output LMMIRDATA0; + output LMMIRDATAVALID; + output LMMIREADY; + input LMMIREQUEST; + input LMMIRESETN; + input LMMIWDATA7; + input LMMIWDATA6; + input LMMIWDATA5; + input LMMIWDATA4; + input LMMIWDATA3; + input LMMIWDATA2; + input LMMIWDATA1; + input LMMIWDATA0; + input LMMIWRRDN; + output MRDCMPL; + input OPCGLOADCLK; + output RXFIFOAF; + output RXFIFOE; + output RXFIFOF; + input SCANCLK; + input SCANRST; + input SCLIN; + output SCLOE; + output SCLOEN; + output SCLOUT; + input SDAIN; + output SDAOE; + output SDAOEN; + output SDAOUT; + input SLEEPCLKSELN; + output SLVADDRMATCH; + output SLVADDRMATCHSCL; + output SRDWR; + output TXFIFOAE; + output TXFIFOE; + output TXFIFOF; +endmodule + +module LRAM_CORE (...); + parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_20 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_21 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_22 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_23 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_24 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_25 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_26 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_27 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_28 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_29 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_2F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_30 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_31 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_32 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_33 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_34 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_35 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_36 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_37 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_38 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_39 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_3F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_40 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_41 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_42 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_43 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_44 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_45 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_46 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_47 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_48 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_49 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_4F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_50 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_51 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_52 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_53 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_54 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_55 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_56 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_57 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_58 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_59 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_5F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_60 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_61 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_62 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_63 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_64 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_65 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_66 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_67 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_68 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_69 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_6F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_70 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_71 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_72 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_73 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_74 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_75 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_76 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_77 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_78 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_79 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_7F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter ASYNC_RST_RELEASE = "SYNC"; + parameter CFG_INIT_ID = "0b00000000000"; + parameter DATA_PRESERVE = "DISABLE"; + parameter EBR_SP_EN = "DISABLE"; + parameter ECC_BYTE_SEL = "ECC_EN"; + parameter GSR = "ENABLED"; + parameter OUT_REGMODE_A = "NO_REG"; + parameter OUT_REGMODE_B = "NO_REG"; + parameter RESETMODE = "SYNC"; + parameter RST_AB_EN = "RESET_AB_DISABLE"; + parameter SP_EN = "DISABLE"; + parameter UNALIGNED_READ = "DISABLE"; + input ADA13; + input ADA12; + input ADA11; + input ADA10; + input ADA9; + input ADA8; + input ADA7; + input ADA6; + input ADA5; + input ADA4; + input ADA3; + input ADA2; + input ADA1; + input ADA0; + input ADB13; + input ADB12; + input ADB11; + input ADB10; + input ADB9; + input ADB8; + input ADB7; + input ADB6; + input ADB5; + input ADB4; + input ADB3; + input ADB2; + input ADB1; + input ADB0; + input BENA_N3; + input BENA_N2; + input BENA_N1; + input BENA_N0; + input BENB_N3; + input BENB_N2; + input BENB_N1; + input BENB_N0; + input CEA; + input CEB; + input CLK; + input CSA; + input CSB; + input DIA31; + input DIA30; + input DIA29; + input DIA28; + input DIA27; + input DIA26; + input DIA25; + input DIA24; + input DIA23; + input DIA22; + input DIA21; + input DIA20; + input DIA19; + input DIA18; + input DIA17; + input DIA16; + input DIA15; + input DIA14; + input DIA13; + input DIA12; + input DIA11; + input DIA10; + input DIA9; + input DIA8; + input DIA7; + input DIA6; + input DIA5; + input DIA4; + input DIA3; + input DIA2; + input DIA1; + input DIA0; + input DIB31; + input DIB30; + input DIB29; + input DIB28; + input DIB27; + input DIB26; + input DIB25; + input DIB24; + input DIB23; + input DIB22; + input DIB21; + input DIB20; + input DIB19; + input DIB18; + input DIB17; + input DIB16; + input DIB15; + input DIB14; + input DIB13; + input DIB12; + input DIB11; + input DIB10; + input DIB9; + input DIB8; + input DIB7; + input DIB6; + input DIB5; + input DIB4; + input DIB3; + input DIB2; + input DIB1; + input DIB0; + output DOA31; + output DOA30; + output DOA29; + output DOA28; + output DOA27; + output DOA26; + output DOA25; + output DOA24; + output DOA23; + output DOA22; + output DOA21; + output DOA20; + output DOA19; + output DOA18; + output DOA17; + output DOA16; + output DOA15; + output DOA14; + output DOA13; + output DOA12; + output DOA11; + output DOA10; + output DOA9; + output DOA8; + output DOA7; + output DOA6; + output DOA5; + output DOA4; + output DOA3; + output DOA2; + output DOA1; + output DOA0; + output DOB31; + output DOB30; + output DOB29; + output DOB28; + output DOB27; + output DOB26; + output DOB25; + output DOB24; + output DOB23; + output DOB22; + output DOB21; + output DOB20; + output DOB19; + output DOB18; + output DOB17; + output DOB16; + output DOB15; + output DOB14; + output DOB13; + output DOB12; + output DOB11; + output DOB10; + output DOB9; + output DOB8; + output DOB7; + output DOB6; + output DOB5; + output DOB4; + output DOB3; + output DOB2; + output DOB1; + output DOB0; + input DPS; + output ERRDECA1; + output ERRDECA0; + output ERRDECB1; + output ERRDECB0; + input IGN; + input INITN; + input OCEA; + input OCEB; + output OEA; + output OEB; + input RSTA; + input RSTB; + input STDBYN; + input TBISTN; + input WEA; + input WEB; + output ERRDET; + output LRAMREADY; + input OPCGLOADCLK; + input SCANCLK; + input SCANRST; +endmodule + +module MULT18_CORE (...); + parameter SFTEN = "DISABLED"; + parameter MULT18X18 = "ENABLED"; + parameter ROUNDHALFUP = "DISABLED"; + parameter ROUNDRTZI = "ROUND_TO_ZERO"; + parameter ROUNDBIT = "ROUND_TO_BIT0"; + input SFTCTRL3; + input SFTCTRL2; + input SFTCTRL1; + input SFTCTRL0; + input ARHSIGN; + input BRHSIGN; + input ARH8; + input ARH7; + input ARH6; + input ARH5; + input ARH4; + input ARH3; + input ARH2; + input ARH1; + input ARH0; + input BRH8; + input BRH7; + input BRH6; + input BRH5; + input BRH4; + input BRH3; + input BRH2; + input BRH1; + input BRH0; + input ARL8; + input ARL7; + input ARL6; + input ARL5; + input ARL4; + input ARL3; + input ARL2; + input ARL1; + input ARL0; + input BRL8; + input BRL7; + input BRL6; + input BRL5; + input BRL4; + input BRL3; + input BRL2; + input BRL1; + input BRL0; + input PL1819; + input PL1818; + input PL1817; + input PL1816; + input PL1815; + input PL1814; + input PL1813; + input PL1812; + input PL1811; + input PL1810; + input PL189; + input PL188; + input PL187; + input PL186; + input PL185; + input PL184; + input PL183; + input PL182; + input PL181; + input PL180; + input PH1819; + input PH1818; + input PH1817; + input PH1816; + input PH1815; + input PH1814; + input PH1813; + input PH1812; + input PH1811; + input PH1810; + input PH189; + input PH188; + input PH187; + input PH186; + input PH185; + input PH184; + input PH183; + input PH182; + input PH181; + input PH180; + output SIGNED18; + output P3637; + output P3636; + output P3635; + output P3634; + output P3633; + output P3632; + output P3631; + output P3630; + output P3629; + output P3628; + output P3627; + output P3626; + output P3625; + output P3624; + output P3623; + output P3622; + output P3621; + output P3620; + output P3619; + output P3618; + output P3617; + output P3616; + output P3615; + output P3614; + output P3613; + output P3612; + output P3611; + output P3610; + output P369; + output P368; + output P367; + output P366; + output P365; + output P364; + output P363; + output P362; + output P361; + output P360; + input ROUNDEN; +endmodule + +module MULT18X36_CORE (...); + parameter SFTEN = "DISABLED"; + parameter MULT18X36 = "ENABLED"; + parameter MULT36 = "DISABLED"; + parameter MULT36X36H = "USED_AS_LOWER_BIT_GENERATION"; + parameter ROUNDHALFUP = "DISABLED"; + parameter ROUNDRTZI = "ROUND_TO_ZERO"; + parameter ROUNDBIT = "ROUND_TO_BIT0"; + input SFTCTRL3; + input SFTCTRL2; + input SFTCTRL1; + input SFTCTRL0; + input PH3637; + input PH3636; + input PH3635; + input PH3634; + input PH3633; + input PH3632; + input PH3631; + input PH3630; + input PH3629; + input PH3628; + input PH3627; + input PH3626; + input PH3625; + input PH3624; + input PH3623; + input PH3622; + input PH3621; + input PH3620; + input PH3619; + input PH3618; + input PH3617; + input PH3616; + input PH3615; + input PH3614; + input PH3613; + input PH3612; + input PH3611; + input PH3610; + input PH369; + input PH368; + input PH367; + input PH366; + input PH365; + input PH364; + input PH363; + input PH362; + input PH361; + input PH360; + input PL3637; + input PL3636; + input PL3635; + input PL3634; + input PL3633; + input PL3632; + input PL3631; + input PL3630; + input PL3629; + input PL3628; + input PL3627; + input PL3626; + input PL3625; + input PL3624; + input PL3623; + input PL3622; + input PL3621; + input PL3620; + input PL3619; + input PL3618; + input PL3617; + input PL3616; + input PL3615; + input PL3614; + input PL3613; + input PL3612; + input PL3611; + input PL3610; + input PL369; + input PL368; + input PL367; + input PL366; + input PL365; + input PL364; + input PL363; + input PL362; + input PL361; + input PL360; + input SGNED18H; + input SGNED18L; + output P7272; + output P7271; + output P7270; + output P7269; + output P7268; + output P7267; + output P7266; + output P7265; + output P7264; + output P7263; + output P7262; + output P7261; + output P7260; + output P7259; + output P7258; + output P7257; + output P7256; + output P7255; + output P7254; + output P7253; + output P7252; + output P7251; + output P7250; + output P7249; + output P7248; + output P7247; + output P7246; + output P7245; + output P7244; + output P7243; + output P7242; + output P7241; + output P7240; + output P7239; + output P7238; + output P7237; + output P7236; + output P7235; + output P7234; + output P7233; + output P7232; + output P7231; + output P7230; + output P7229; + output P7228; + output P7227; + output P7226; + output P7225; + output P7224; + output P7223; + output P7222; + output P7221; + output P7220; + output P7219; + output P7218; + output P7217; + output P7216; + output P7215; + output P7214; + output P7213; + output P7212; + output P7211; + output P7210; + output P729; + output P728; + output P727; + output P726; + output P725; + output P724; + output P723; + output P722; + output P721; + output P720; + input ROUNDEN; +endmodule + +module MULT36_CORE (...); + parameter MULT36X36 = "ENABLED"; + input PH7272; + input PH7271; + input PH7270; + input PH7269; + input PH7268; + input PH7267; + input PH7266; + input PH7265; + input PH7264; + input PH7263; + input PH7262; + input PH7261; + input PH7260; + input PH7259; + input PH7258; + input PH7257; + input PH7256; + input PH7255; + input PH7254; + input PH7253; + input PH7252; + input PH7251; + input PH7250; + input PH7249; + input PH7248; + input PH7247; + input PH7246; + input PH7245; + input PH7244; + input PH7243; + input PH7242; + input PH7241; + input PH7240; + input PH7239; + input PH7238; + input PH7237; + input PH7236; + input PH7235; + input PH7234; + input PH7233; + input PH7232; + input PH7231; + input PH7230; + input PH7229; + input PH7228; + input PH7227; + input PH7226; + input PH7225; + input PH7224; + input PH7223; + input PH7222; + input PH7221; + input PH7220; + input PH7219; + input PH7218; + input PH7217; + input PH7216; + input PH7215; + input PH7214; + input PH7213; + input PH7212; + input PH7211; + input PH7210; + input PH729; + input PH728; + input PH727; + input PH726; + input PH725; + input PH724; + input PH723; + input PH722; + input PH721; + input PH720; + input PL7272; + input PL7271; + input PL7270; + input PL7269; + input PL7268; + input PL7267; + input PL7266; + input PL7265; + input PL7264; + input PL7263; + input PL7262; + input PL7261; + input PL7260; + input PL7259; + input PL7258; + input PL7257; + input PL7256; + input PL7255; + input PL7254; + input PL7253; + input PL7252; + input PL7251; + input PL7250; + input PL7249; + input PL7248; + input PL7247; + input PL7246; + input PL7245; + input PL7244; + input PL7243; + input PL7242; + input PL7241; + input PL7240; + input PL7239; + input PL7238; + input PL7237; + input PL7236; + input PL7235; + input PL7234; + input PL7233; + input PL7232; + input PL7231; + input PL7230; + input PL7229; + input PL7228; + input PL7227; + input PL7226; + input PL7225; + input PL7224; + input PL7223; + input PL7222; + input PL7221; + input PL7220; + input PL7219; + input PL7218; + input PL7217; + input PL7216; + input PL7215; + input PL7214; + input PL7213; + input PL7212; + input PL7211; + input PL7210; + input PL729; + input PL728; + input PL727; + input PL726; + input PL725; + input PL724; + input PL723; + input PL722; + input PL721; + input PL720; + output PML7271; + output PML7270; + output PML7269; + output PML7268; + output PML7267; + output PML7266; + output PML7265; + output PML7264; + output PML7263; + output PML7262; + output PML7261; + output PML7260; + output PML7259; + output PML7258; + output PML7257; + output PML7256; + output PML7255; + output PML7254; + output PML7253; + output PML7252; + output PML7251; + output PML7250; + output PML7249; + output PML7248; + output PML7247; + output PML7246; + output PML7245; + output PML7244; + output PML7243; + output PML7242; + output PML7241; + output PML7240; + output PML7239; + output PML7238; + output PML7237; + output PML7236; + output PML7235; + output PML7234; + output PML7233; + output PML7232; + output PML7231; + output PML7230; + output PML7229; + output PML7228; + output PML7227; + output PML7226; + output PML7225; + output PML7224; + output PML7223; + output PML7222; + output PML7221; + output PML7220; + output PML7219; + output PML7218; + output PML7217; + output PML7216; + output PML7215; + output PML7214; + output PML7213; + output PML7212; + output PML7211; + output PML7210; + output PML729; + output PML728; + output PML727; + output PML726; + output PML725; + output PML724; + output PML723; + output PML722; + output PML721; + output PML720; + output PMH7271; + output PMH7270; + output PMH7269; + output PMH7268; + output PMH7267; + output PMH7266; + output PMH7265; + output PMH7264; + output PMH7263; + output PMH7262; + output PMH7261; + output PMH7260; + output PMH7259; + output PMH7258; + output PMH7257; + output PMH7256; + output PMH7255; + output PMH7254; + output PMH7253; + output PMH7252; + output PMH7251; + output PMH7250; + output PMH7249; + output PMH7248; + output PMH7247; + output PMH7246; + output PMH7245; + output PMH7244; + output PMH7243; + output PMH7242; + output PMH7241; + output PMH7240; + output PMH7239; + output PMH7238; + output PMH7237; + output PMH7236; + output PMH7235; + output PMH7234; + output PMH7233; + output PMH7232; + output PMH7231; + output PMH7230; + output PMH7229; + output PMH7228; + output PMH7227; + output PMH7226; + output PMH7225; + output PMH7224; + output PMH7223; + output PMH7222; + output PMH7221; + output PMH7220; + output PMH7219; + output PMH7218; + output PMH7217; + output PMH7216; + output PMH7215; + output PMH7214; + output PMH7213; + output PMH7212; + output PMH7211; + output PMH7210; + output PMH729; + output PMH728; + output PMH727; + output PMH726; + output PMH725; + output PMH724; + output PMH723; + output PMH722; + output PMH721; + output PMH720; +endmodule + +module MULT9_CORE (...); + parameter SIGNEDSTATIC_EN = "DISABLED"; + parameter ASIGNED_OPERAND_EN = "DISABLED"; + parameter BYPASS_MULT9 = "USED"; + parameter REGBYPSB = "REGISTER"; + parameter REGBYPSA1 = "REGISTER"; + parameter REGBYPSA2 = "REGISTER"; + parameter SHIFTA = "DISABLED"; + parameter SR_18BITSHIFT_EN = "DISABLED"; + parameter GSR = "ENABLED"; + parameter RESET = "SYNC"; + input A8; + input A7; + input A6; + input A5; + input A4; + input A3; + input A2; + input A1; + input A0; + input ASIGNED; + input BR8; + input BR7; + input BR6; + input BR5; + input BR4; + input BR3; + input BR2; + input BR1; + input BR0; + input AS18; + input AS17; + input AS16; + input AS15; + input AS14; + input AS13; + input AS12; + input AS11; + input AS10; + input AS28; + input AS27; + input AS26; + input AS25; + input AS24; + input AS23; + input AS22; + input AS21; + input AS20; + input ASSIGNED1; + input ASSIGNED2; + input BRSIGNED; + input CLK; + input CEA; + input RSTA; + output AO8; + output AO7; + output AO6; + output AO5; + output AO4; + output AO3; + output AO2; + output AO1; + output AO0; + output BO8; + output BO7; + output BO6; + output BO5; + output BO4; + output BO3; + output BO2; + output BO1; + output BO0; + output AOSIGNED; + output BOSIGNED; + output AR8; + output AR7; + output AR6; + output AR5; + output AR4; + output AR3; + output AR2; + output AR1; + output AR0; + output ARSIGNED; + output P1819; + output P1818; + output P1817; + output P1816; + output P1815; + output P1814; + output P1813; + output P1812; + output P1811; + output P1810; + output P189; + output P188; + output P187; + output P186; + output P185; + output P184; + output P183; + output P182; + output P181; + output P180; + input CEP; + input RSTP; +endmodule + +module OSC_CORE (...); + parameter DTR_EN = "ENABLED"; + parameter HF_CLK_DIV = "1"; + parameter HF_SED_SEC_DIV = "1"; + parameter HF_FABRIC_EN = "DISABLED"; + parameter HF_OSC_EN = "ENABLED"; + parameter HFDIV_FABRIC_EN = "ENABLED"; + parameter LF_FABRIC_EN = "DISABLED"; + parameter LF_OUTPUT_EN = "DISABLED"; + parameter DEBUG_N = "DISABLED"; + output HFCLKOUT; + input HFOUTEN; + input HFSDSCEN; + input HFTRMFAB8; + input HFTRMFAB7; + input HFTRMFAB6; + input HFTRMFAB5; + input HFTRMFAB4; + input HFTRMFAB3; + input HFTRMFAB2; + input HFTRMFAB1; + input HFTRMFAB0; + output LFCLKOUT; + input LFTRMFAB8; + input LFTRMFAB7; + input LFTRMFAB6; + input LFTRMFAB5; + input LFTRMFAB4; + input LFTRMFAB3; + input LFTRMFAB2; + input LFTRMFAB1; + input LFTRMFAB0; + output HFCLKCFG; + output HFSDCOUT; +endmodule + +module PCIE_CORE (...); + parameter ENABLE_USER_CFG = "DISABLED"; + parameter PWDN_N = "DISABLED"; + parameter GSR = "ENABLED"; + parameter IDDQ_PCS = "DISABLED"; + parameter PHY_MODE = "0b0000"; + parameter ALT_CLK_SEL_VCC = "PAD"; + parameter L0S_ADJ = "0b00000110000000"; + parameter L0S_EXIT_LATENCY = "MORE_4_US"; + parameter L1_EXIT_LATENCY = "MORE_64_US"; + parameter CALIB_3DB = "ENABLED"; + parameter DB_UPSTREAM = "6DB"; + parameter ERR_REC_ENTRY_SEL = "RCVRY_AFTER"; + parameter A_CHNGD_MAX = "0b100"; + parameter A0_FORCE = "DISABLED"; + parameter A0_FREEZE = "DISABLED"; + parameter A0_INIT = "0b000000"; + parameter A0DIR_VAL = "DISABLED"; + parameter A1_FORCE = "DISABLED"; + parameter A1_FREEZE = "DISABLED"; + parameter A1_INIT = "0b000000"; + parameter A1DIR_VAL = "DISABLED"; + parameter A2_FORCE = "DISABLED"; + parameter A2_FREEZE = "DISABLED"; + parameter A2_INIT = "0b000000"; + parameter A2GAIN_CALIB = "0b100110"; + parameter ACJTAG_REG = "0b00"; + parameter ADDR_LIMIT_PRE_MTHD_CTRL = "0b0100"; + parameter ADDR_LIMIT_TABLE_MTHD_CTRL = "0b00101"; + parameter ADIR_OVR = "DISABLED"; + parameter ADV_CH_CD_SEL = "IMPLEMENT_CH"; + parameter ADV_TARGET_LINK_SPEED_USPORT_A = "DISABLED"; + parameter ADV_TARGET_LINK_SPEED_USPORT_B = "DISABLED"; + parameter ADV_TARGET_LINK_SPEED_USPORT_C = "DISABLED"; + parameter ADV_TARGET_LINK_SPEED_USPORT_D = "DISABLED"; + parameter ADVANCE = "DISABLED"; + parameter ALERT_ENABLE = "0b000"; + parameter ALMOST_EMPTY_10B = "0b001110"; + parameter MID_VALUE_10B = "0b011110"; + parameter ALMOST_EMPTY_20B = "0b001111"; + parameter ALMOST_EMPTY_GEN3 = "0b001100"; + parameter ALMOST_FULL_10B = "0b110000"; + parameter ALMOST_FULL_20B = "0b011000"; + parameter ALMOST_FULL_GEN3 = "0b010110"; + parameter ARRAY_DA = "0b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter ARRAY_MT = "0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000011100000000000010000000000000001001000000000000011000000000000001010000000000000100"; + parameter ARXCDRICP_RATE0 = "0b011"; + parameter ARXCDRICP_RATE1 = "0b011"; + parameter ARXCDRICP_RATE2 = "0b011"; + parameter ARXDMPWRDWN = "DISABLED"; + parameter ARXDPPWRDN = "DISABLED"; + parameter ARXEOM_PWRDN = "POWERED_DOWN"; + parameter ARXICP_RATE0 = "0b011"; + parameter ARXICP_RATE1 = "0b011"; + parameter ARXICP_RATE2 = "0b011"; + parameter ARXOVR_OUT = "DISABLED"; + parameter ARXRSACTAT = "0b0001"; + parameter ARXRSAPTAT = "0b1000"; + parameter ARXRSVCTL = "0b00000000"; + parameter ARXSEL_OUT = "DISABLED"; + parameter ASPM_L1_1_SUPPORTED = "SUPPORTED"; + parameter ASPM_L1_2_SUPPORTED = "SUPPORTED"; + parameter ASPM_SUPPORT = "L0S_AND_L1_SUPPORTED"; + parameter ATTENTION_BUTTON_PRESENT = "NOT_SUPPORTED"; + parameter ATTENTION_INDICATOR_PRESENT = "NOT_SUPPORTED"; + parameter ATXICP_RATE0 = "0b101"; + parameter ATXICP_RATE1 = "0b101"; + parameter AUTO_SHIFT = "ENABLED"; + parameter AUX_CURRENT = "SELF_POWERED"; + parameter AUXCLK1US_MAX = "0b00001001"; + parameter AUXIDL_MAX = "0b00000100"; + parameter BAR_INDEX_CFG0_A = "0b000"; + parameter BAR_INDEX_CFG0_B = "0b000"; + parameter BAR_INDEX_CFG0_C = "0b000"; + parameter BAR_INDEX_CFG0_D = "0b000"; + parameter BAR_INDEX_CFG1_A = "0b001"; + parameter BAR_INDEX_CFG1_B = "0b001"; + parameter BAR_INDEX_CFG1_C = "0b001"; + parameter BAR_INDEX_CFG1_D = "0b001"; + parameter BAR_INDEX_CFG2_A = "0b010"; + parameter BAR_INDEX_CFG2_B = "0b010"; + parameter BAR_INDEX_CFG2_C = "0b010"; + parameter BAR_INDEX_CFG2_D = "0b010"; + parameter BAR_INDEX_CFG3_A = "0b011"; + parameter BAR_INDEX_CFG3_B = "0b011"; + parameter BAR_INDEX_CFG3_C = "0b011"; + parameter BAR_INDEX_CFG3_D = "0b011"; + parameter BAR_INDEX_CFG4_A = "0b100"; + parameter BAR_INDEX_CFG4_B = "0b100"; + parameter BAR_INDEX_CFG4_C = "0b100"; + parameter BAR_INDEX_CFG4_D = "0b100"; + parameter BAR_INDEX_CFG5_A = "0b101"; + parameter BAR_INDEX_CFG5_B = "0b101"; + parameter BAR_INDEX_CFG5_C = "0b101"; + parameter BAR_INDEX_CFG5_D = "0b101"; + parameter BIR_MSIX_PBA_A = "BAR0"; + parameter BIR_MSIX_PBA_B = "BAR0"; + parameter BIR_MSIX_PBA_C = "BAR0"; + parameter BIR_MSIX_PBA_D = "BAR0"; + parameter BIR_MSIX_TABLE_A = "BAR0"; + parameter BIR_MSIX_TABLE_B = "BAR0"; + parameter BIR_MSIX_TABLE_C = "BAR0"; + parameter BIR_MSIX_TABLE_D = "BAR0"; + parameter BYP_AVG = "USED"; + parameter BYPASS = "PERFORM_RECEIVER_DETECTION"; + parameter BYPASS_ADDR_DEC = "NORMAL"; + parameter CALIB_SETTLE_MAX = "0b001"; + parameter CALIB_STABLE_MAX = "0b11000"; + parameter CAPABILITY_VERSION = "0b0010"; + parameter CDR_ERR = "DISABLED"; + parameter CDR_P1 = "CDR_PLL_RESET"; + parameter CDR_PLL_DELTA = "0P4_PERCENT"; + parameter CDR_REFERENCE = "0b00"; + parameter CDRPLL_CMP_MAX = "0b00010100"; + parameter CDRPLL_CNT_MAX = "0b00000100"; + parameter CDRPLL_PRE_RXEQ_COARSE_TIMER = "0b01010000"; + parameter CDRPLL_PRE_RXEQ_FINE_TIMER = "0b10110100"; + parameter CDRPLL_PST_RXEQ_COARSE_TIMER = "0b01000000"; + parameter CDRPLL_PST_RXEQ_FINE_TIMER = "0b01000010"; + parameter CFG_A_BAR0 = "0b11111111111111110000000000001100"; + parameter CFG_A_BAR1 = "0b11111111111111111111111111111111"; + parameter CFG_A_BAR2 = "0b11111111111111111110000000001100"; + parameter CFG_A_BAR3 = "0b11111111111111111111111111111111"; + parameter CFG_A_BAR4 = "0b11111111111111111110000000001100"; + parameter CFG_A_BAR5 = "0b11111111111111111111111111111111"; + parameter CFG_B_BAR0 = "0b11111111111111110000000000001100"; + parameter CFG_B_BAR1 = "0b11111111111111111111111111111111"; + parameter CFG_B_BAR2 = "0b11111111111111111110000000001100"; + parameter CFG_B_BAR3 = "0b11111111111111111111111111111111"; + parameter CFG_B_BAR4 = "0b11111111111111111110000000001100"; + parameter CFG_B_BAR5 = "0b11111111111111111111111111111111"; + parameter CFG_C_BAR0 = "0b11111111111111110000000000001100"; + parameter CFG_C_BAR1 = "0b11111111111111111111111111111111"; + parameter CFG_C_BAR2 = "0b11111111111111111110000000001100"; + parameter CFG_C_BAR3 = "0b11111111111111111111111111111111"; + parameter CFG_C_BAR4 = "0b11111111111111111110000000001100"; + parameter CFG_C_BAR5 = "0b11111111111111111111111111111111"; + parameter CFG_D_BAR0 = "0b11111111111111110000000000001100"; + parameter CFG_D_BAR1 = "0b11111111111111111111111111111111"; + parameter CFG_D_BAR2 = "0b11111111111111111110000000001100"; + parameter CFG_D_BAR3 = "0b11111111111111111111111111111111"; + parameter CFG_D_BAR4 = "0b11111111111111111110000000001100"; + parameter CFG_D_BAR5 = "0b11111111111111111111111111111111"; + parameter CFG_EXP_ROM_A = "0b00000000000000000000000000000000"; + parameter CFG_EXP_ROM_B = "0b00000000000000000000000000000000"; + parameter CFG_EXP_ROM_C = "0b00000000000000000000000000000000"; + parameter CFG_EXP_ROM_D = "0b00000000000000000000000000000000"; + parameter CIS_POINTER_CARDBUS_A = "0b00000000000000000000000000000000"; + parameter CIS_POINTER_CARDBUS_B = "0b00000000000000000000000000000000"; + parameter CIS_POINTER_CARDBUS_C = "0b00000000000000000000000000000000"; + parameter CIS_POINTER_CARDBUS_D = "0b00000000000000000000000000000000"; + parameter CLASS_CODE_ID3A = "0b000100011000000000000000"; + parameter CLASS_CODE_ID3B = "0b000100011000000000000000"; + parameter CLASS_CODE_ID3C = "0b000100011000000000000000"; + parameter CLASS_CODE_ID3D = "0b000100011000000000000000"; + parameter CM_RESTORE_TIME = "0b00000000"; + parameter CNT250NS_MAX = "0b001111100"; + parameter COARSE_GAIN = "DISABLED"; + parameter COEF_EN_LPBK_MASTER = "OTHERWISE"; + parameter COEF_EN_LPBK_SLAVE = "OTHERWISE"; + parameter COEF_ENABLE = "DETERMINE_LOCAL_PHY"; + parameter COEF_EQTX_FORCE = "0b000000000000000000"; + parameter COEF_LPBK_MASTER = "0b000000000000000000"; + parameter COEF_LPBK_SLAVE = "0b000000000000000000"; + parameter COEF0_POST = "0b000101"; + parameter COEF0_POST_CURSOR = "0b000000"; + parameter COEF0_PRE = "0b000000"; + parameter COEF0_PRE_CURSOR = "0b000000"; + parameter COEF1_POST = "0b000011"; + parameter COEF1_POST_CURSOR = "0b000000"; + parameter COEF1_PRE = "0b000000"; + parameter COEF1_PRE_CURSOR = "0b000000"; + parameter COEF10_POST = "0b000111"; + parameter COEF10_PRE = "0b000000"; + parameter COEF2_POST = "0b000100"; + parameter COEF2_POST_CURSOR = "0b000000"; + parameter COEF2_PRE = "0b000000"; + parameter COEF2_PRE_CURSOR = "0b000000"; + parameter COEF3_POST = "0b000010"; + parameter COEF3_POST_CURSOR = "0b000000"; + parameter COEF3_PRE = "0b000000"; + parameter COEF3_PRE_CURSOR = "0b000000"; + parameter COEF4_POST = "0b000000"; + parameter COEF4_PRE = "0b000000"; + parameter COEF5_POST = "0b000000"; + parameter COEF5_PRE = "0b000001"; + parameter COEF6_POST = "0b000000"; + parameter COEF6_PRE = "0b000010"; + parameter COEF7_POST = "0b000100"; + parameter COEF7_PRE = "0b000011"; + parameter COEF8_POST = "0b000011"; + parameter COEF8_PRE = "0b000010"; + parameter COEF9_POST = "0b000000"; + parameter COEF9_PRE = "0b000011"; + parameter COMP_128_SUPPORTED = "ENABLED"; + parameter COMP_32_SUPPORTED = "ENABLED"; + parameter COMP_64_SUPPORTED = "ENABLED"; + parameter COMPLETE = "DISABLED"; + parameter CONV_METHOD = "COMPUTE_PCIE_SPEC"; + parameter CORE_BYPASS = "NORMAL"; + parameter CORE_EN = "ENABLED"; + parameter COUNT_ACK_TO_NAK = "0b00000000"; + parameter CPL_TIMEOUT_DISABLE_SUPPORTED = "SUPPORTED"; + parameter CPL_TIMEOUT_RANGES_SUPPORTED = "NOT_SUPPORTED"; + parameter CRS_ENABLE = "DISABLED"; + parameter CSTAT_DATA_SCALE = "UNKNOWN_SCALE"; + parameter CSTAT_DATA_SELECT = "D0_POWER_CONSUMED"; + parameter CTLE_SETTLE = "0b100"; + parameter CTLEBIAS_1 = "0b1000"; + parameter ATXICP_RATE2 = "0b100"; + parameter CTLEBYPASS = "DISABLED"; + parameter CUR_FOM = "NUMBER_OF_CLOCK"; + parameter CUR_FOM_AVG = "0b101"; + parameter CUST_AUTO = "DISABLED"; + parameter CUST_CHK = "SET"; + parameter CUST_SEL = "DISABLED"; + parameter CUST_SKIP = "DISABLED"; + parameter CUST_TYP = "0b000"; + parameter CUSTOM_PATTERN = "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter D1_SUPPORT = "SUPPORTED"; + parameter D2_SUPPORT = "SUPPORTED"; + parameter DATA_INJECT = "0b00000000000000000000000000000000"; + parameter DATA_PM = "0b00000000"; + parameter DEEMPH_5G_3_5DB_6DB_N = "6DB"; + parameter DEEMPH_5G_ENABLE = "DISABLED"; + parameter DEEMPH_LPBK_MASTER = "6P0DB"; + parameter DEEMPH_LPBK_SLAVE = "6P0DB"; + parameter DEVICE_ID_ID1A = "0b1110000000000100"; + parameter DEVICE_ID_ID1B = "0b1110000000000100"; + parameter DEVICE_ID_ID1C = "0b1110000000000100"; + parameter DEVICE_ID_ID1D = "0b1110000000000100"; + parameter DEVICE_PORT_TYPE = "PCIE_ENDPOINT"; + parameter DFE_BIAS = "0b0001"; + parameter DFE_PWDN = "DISABLED"; + parameter DIR_PRE_GAIN = "0b00"; + parameter DIR_PST_GAIN = "0b01"; + parameter DIS_ARI_CAP = "ENABLED"; + parameter DIS_CSR_RST = "DISABLED"; + parameter DIS_INTERRUPT = "ENABLED"; + parameter DIS_INTERRUPT_B = "ENABLED"; + parameter DIS_INTERRUPT_C = "ENABLED"; + parameter DIS_INTERRUPT_D = "ENABLED"; + parameter DIS_MSI_CAP = "ENABLED"; + parameter DIS_MSI_CAP_B = "ENABLED"; + parameter DIS_MSI_CAP_C = "ENABLED"; + parameter DIS_MSI_CAP_D = "ENABLED"; + parameter DIS_MSIX_CAP = "ENABLED"; + parameter DIS_MSIX_CAP_B = "ENABLED"; + parameter DIS_MSIX_CAP_C = "ENABLED"; + parameter DIS_MSIX_CAP_D = "ENABLED"; + parameter DISABLE_FLR_CAPABILITY = "ENABLED"; + parameter DLLP_CRC_ERR_ENABLE = "DISABLED"; + parameter DLLP_CRC_ERR_RATE = "0b000000000000"; + parameter DLLP_INJECT_ENABLE = "DISABLED"; + parameter DOUBLE_TX_DATA_VALID = "ONE_CLK_EVERY_64_CLKS"; + parameter DOWNSTREAM_EQ_SKIP_PHASE_2_3 = "NORMAL_OPERATION"; + parameter DS_DRIVE_CLKREQ = "ENABLED"; + parameter DS_PORT_RX_PRESET_HINT = "0b001"; + parameter DS_PORT_TX_PRESET = "0b0011"; + parameter DS_US_N_PORTTYPE = "UPSTREAM"; + parameter DSI = "NO_DSI_NECESSARY"; + parameter DSP_DIR = "ANALYSIS_OF_DATA_BY_DSP"; + parameter DSPDIR_PRESGN = "0b11110000"; + parameter DSPDIR_PREVAL = "0b00011000"; + parameter DSPDIR_PSTSGN0 = "0b11111111"; + parameter DSPDIR_PSTSGN1 = "0b00000000"; + parameter DSPDIR_PSTVAL0 = "0b00000010"; + parameter DSPDIR_PSTVAL1 = "0b01000000"; + parameter EARLY_RX_EVAL = "RX_SIGNAL_AFTER_TS1"; + parameter ECRC_GEN_CHK_CAPABLE = "SUPPORTED"; + parameter EFF_LPBK = "PASSED"; + parameter EI4 = "EI_IV"; + parameter EM_INTERLOCK_PRESENT = "NOT_SUPPORTED"; + parameter EN = "DISABLED"; + parameter EN_ACK_TO_DIV = "ACK_SPEC"; + parameter EN_ACK_TO_NAK = "DO_NOTHING"; + parameter EN_ACS_VIOLATION = "DISABLED"; + parameter EN_ASPM_L0S = "ENABLED"; + parameter EN_ASPM_L1 = "ENABLED"; + parameter EN_ATOMIC_OP_CAP = "ENABLED"; + parameter EN_ATOMICOP_EGRESS_BLOCKED = "DISABLED"; + parameter EN_ATS_CAP = "ENABLED"; + parameter EN_BDGT_CAP = "DISABLED"; + parameter EN_CAP = "ENABLED"; + parameter EN_CAP_B = "ENABLED"; + parameter EN_CAP_C = "ENABLED"; + parameter EN_CAP_D = "ENABLED"; + parameter EN_COMPLETER_ABORT = "DISABLED"; + parameter EN_COMPLETION_TIMEOUT = "ENABLED"; + parameter EN_CORR_INTERNAL_ERROR = "DISABLED"; + parameter EN_DPA_CAP = "DISABLED"; + parameter EN_DRCT_SCR_OFF = "OTHERWISE"; + parameter EN_DRCT_TO_LPBK = "OTHERWISE"; + parameter EN_EQTX_OVERRIDE = "PIPE_LOCAL_FS_AND_PIPE_LOCAL_LF"; + parameter EN_FORCE_SCR_OFF_FAST = "OTHERWISE"; + parameter EN_L1 = "ENABLED"; + parameter EN_L1PMSS_CAP = "ENABLED"; + parameter EN_L2 = "ENABLED"; + parameter EN_LPBK_ERR_RST = "MASTER_LPBK_INCREMENT"; + parameter EN_LTR_CAP = "ENABLED"; + parameter EN_MC_BLOCKED_TLP = "DISABLED"; + parameter EN_NWL_VSEC_CAP = "ENABLED"; + parameter EN_PORT_DIS = "DISABLED"; + parameter EN_PORT_INTLEG = "ENABLED"; + parameter EN_RBAR_CAP_A = "ENABLED"; + parameter EN_RBAR_CAP_B = "ENABLED"; + parameter EN_RBAR_CAP_C = "ENABLED"; + parameter EN_RBAR_CAP_D = "ENABLED"; + parameter EN_RECEIVER_OVERFLOW = "DISABLED"; + parameter EN_SELF_XLINK = "OTHERWISE"; + parameter EN_SURPRISE_DOWN_ERROR = "DISABLED"; + parameter EN_TLP_PREFIX_BLOCKED = "DISABLED"; + parameter EN_UCORR_INTERNAL_ERROR = "DISABLED"; + parameter EN_USER_WRITE = "READ_WRITE_ACCESS"; + parameter END_END_PREFIXES_SUPPORTED = "NOT_SUPPORTED"; + parameter END_ON_HOLD = "YES_EXIT_ON_HOLD"; + parameter ENDCALIB_MAX = "0b10000100"; + parameter ENDPOINT_L0S_ACCEPTABLE_LATENCY = "MAX_64_NS"; + parameter ENDPOINT_L1_ACCEPTABLE_LATENCY = "MAX_1_US"; + parameter ENTRY_TIME_ASPM_L0S = "0b0000000000000000"; + parameter ENTRY_TIME_ASPM_L1 = "0b0000000000000000"; + parameter EOM_TIME = "0b0000000000000000"; + parameter EOM0DIR = "SELECT_DIR_1"; + parameter EOM1DIR = "SELECT_DIR_0"; + parameter EOMCTRL0_LOW = "DISABLED"; + parameter EOMDIVDIS = "DISABLED"; + parameter EOMMODE = "0b00"; + parameter EOMRDSEL = "DISABLED"; + parameter EOMSTART = "DISABLED"; + parameter EOMX = "0b000000"; + parameter EOMX_UPDATE_CNT_VALUE = "0b0011111"; + parameter EOMY = "0b00000000"; + parameter ERRCNT_DEC = "0b00100000"; + parameter ERRCNT_THR = "0b1000"; + parameter ES_PWDN = "DISABLED"; + parameter EVAL_RST = "DISABLED"; + parameter EXCLUDE_L0 = "INCLUDE"; + parameter EXCLUDE_CFG_COMPLETE = "INCLUDE"; + parameter EXCLUDE_CFG_IDLE = "INCLUDE"; + parameter EXCLUDE_LOOPBACK_MASTER = "INCLUDE"; + parameter EXCLUDE_REC_IDLE = "INCLUDE"; + parameter EXCLUDE_REC_RCVR_CFG = "INCLUDE"; + parameter EXIT_DIRECT_TO_DETECT = "DO_NOT_EXIT_TO_DETECT"; + parameter EXT_CONTROL = "DISABLED"; + parameter EXTENDED_TAG_FIELD_EN_DEFAULT = "EIGHT_BIT"; + parameter EXTENDED_TAG_FIELD_SUPPORTED = "EIGHT_BIT"; + parameter F_ARXCTLEDIR = "IGNORED"; + parameter F_ARXCTLENULL = "0b0000"; + parameter F_ARXDMDIR = "DISABLED"; + parameter F_ARXDMNULL = "0b00000"; + parameter F_ARXEOMDIR = "IGNORED"; + parameter F_ARXEOMNULL = "0b00000"; + parameter F_ARXESDIR = "IGNORED"; + parameter F_ARXESNULL = "0b00000"; + parameter F_ARXTDIR = "IGNORED"; + parameter F_ARXTNULL = "0b00000"; + parameter F_ASCHCAL = "IGNORED"; + parameter F_ASCHDIR = "IGNORED"; + parameter F_ASCHNULL = "0b0000"; + parameter FAIL_LIMIT_ERR = "RXEQ_NOT_FAIL"; + parameter FAST = "L0"; + parameter FC_UPDATE_TIMER_DISABLE = "ENABLED"; + parameter FC_UPDATE_TIMER_DIV = "PCIE_REC_VALUES"; + parameter FILTER = "0b1001"; + parameter FINE_GAIN = "DISABLED"; + parameter FOM_COMPARE = "0b00000000"; + parameter FOM_HIRES = "DISABLED"; + parameter FOM_ITERCNT = "0b101"; + parameter FOM_THR = "0b0100"; + parameter FORCE_ATXDRA = "0b000000000000000000000"; + parameter FORCE_ATXDRP = "0b000000000000000000000"; + parameter FORCE_ATXDRR = "0b000000000000000000000"; + parameter FORCE_ATXDRT = "0b000000000000000000000"; + parameter FORCE_DIR_RSLT = "0b000000"; + parameter FORCE_FOM_RSLT = "0b00000000"; + parameter FORCE_IDLE = "DISABLED"; + parameter FORCE_RX_DETECT = "DISABLED"; + parameter FORCE_SIGNAL = "DISABLED"; + parameter FREQ_LOCK = "DISABLED"; + parameter FS = "0b110000"; + parameter GAIN_TIMER1 = "0b0101"; + parameter GEN12_ENA_POST_A0 = "DISABLED"; + parameter GEN12_ENA_POST_A1A2 = "DISABLED"; + parameter GEN12_ENA_PREA0 = "DISABLED"; + parameter GEN3_ENA_POST_A0 = "ENABLED"; + parameter GEN3_ENA_POST_A1A2 = "ENABLED"; + parameter GEN3_ENA_PREA0 = "ENABLED"; + parameter GLOBAL_INVAL_SUPPORT = "ENABLED"; + parameter HINT = "0b000"; + parameter HINT0_3DB = "ENABLED"; + parameter HINT0_A0GAIN = "0b111"; + parameter HINT0_A2GAIN = "0b111"; + parameter HINT1_3DB = "ENABLED"; + parameter HINT1_A0GAIN = "0b011"; + parameter HINT1_A2GAIN = "0b101"; + parameter HINT2_3DB = "ENABLED"; + parameter HINT2_A0GAIN = "0b011"; + parameter HINT2_A2GAIN = "0b111"; + parameter HINT3_3DB = "ENABLED"; + parameter HINT3_A0GAIN = "0b000"; + parameter HINT3_A2GAIN = "0b111"; + parameter HINT4_3DB = "DISABLED"; + parameter HINT4_A0GAIN = "0b111"; + parameter HINT4_A2GAIN = "0b111"; + parameter HINT5_3DB = "DISABLED"; + parameter HINT5_A0GAIN = "0b011"; + parameter HINT5_A2GAIN = "0b101"; + parameter HINT6_3DB = "DISABLED"; + parameter HINT6_A0GAIN = "0b011"; + parameter HINT6_A2GAIN = "0b111"; + parameter HINT7_3DB = "DISABLED"; + parameter HINT7_A0GAIN = "0b000"; + parameter HINT7_A2GAIN = "0b111"; + parameter HINT7_OVR = "DISABLED"; + parameter HLD_RST = "WRITE_1"; + parameter HOT_PLUG_CAPABLE = "NOT_SUPPORTED"; + parameter HOT_PLUG_SURPRISE = "NOT_POSSIBLE"; + parameter ID_DS_PORT = "0b0000000000000000"; + parameter ID_NWL_VSEC_CAP = "0b0000000000000001"; + parameter IGNORE_ECRC = "DISABLED"; + parameter IGNORE_POISON = "ENABLED"; + parameter INDICATOR = "0b00000000000000000000000000000000"; + parameter INHIBIT = "PERFORM_RECEIVER_DETECTION"; + parameter INJECT_DATA_ERROR_0 = "DISABLED"; + parameter INJECT_DATA_ERROR_1 = "DISABLED"; + parameter INJECT_DATA_ERROR_2 = "DISABLED"; + parameter INJECT_DATA_ERROR_3 = "DISABLED"; + parameter INJECT_DATA_ERROR_EN = "DISABLED"; + parameter INJECT_ERR_LANE_SELECT_0 = "DISABLED"; + parameter INJECT_ERR_LANE_SELECT_1 = "DISABLED"; + parameter INJECT_ERR_LANE_SELECT_2 = "DISABLED"; + parameter INJECT_ERR_LANE_SELECT_3 = "DISABLED"; + parameter INJECT_RX_1BIT_DATA_ERR = "DISABLED"; + parameter INJECT_RX_2BIT_DATA_ERR = "DISABLED"; + parameter INJECT_RX_SKP_ERR = "DISABLED"; + parameter INJECT_RX_VALID_ERR = "DISABLED"; + parameter INT_CLR = "DISABLED"; + parameter INT_EN = "DISABLED"; + parameter INTERRUPT_MESSAGE_NUMBER = "0b00000"; + parameter INVAL_Q_DEPTH = "0b00000"; + parameter ITERATION_MAX = "0b000000"; + parameter L1_ENTER_PLL_RESET_TIME = "0b100"; + parameter L1_EXIT_PLL_LOCK_TIME = "0b01110"; + parameter L1PM_SUPPORTED = "SUPPORTED"; + parameter L2_D3HOT_ENABLE = "DISABLED"; + parameter LANE_SELECT = "0b0000"; + parameter LF = "0b001000"; + parameter LF_PHY = "0b001010"; + parameter LINK_LANE = "ENABLED"; + parameter LPBK_EN = "DISABLED"; + parameter LW_START_UPDN_ACK_EN = "DISABLED"; + parameter LW_START_UPDN_COUNT = "0b000011111010"; + parameter LW_START_UPDN_EIE_EN = "DISABLED"; + parameter LW_START_UPDN_EN_DIR_DS = "DO_NOT_ASSERT"; + parameter LW_START_UPDN_END_DELAY = "0b1001"; + parameter LW_START_UPDN_RATE_EN_16G = "DISABLED"; + parameter LW_START_UPDN_RATE_EN_2P5G = "ENABLED"; + parameter LW_START_UPDN_RATE_EN_5G = "ENABLED"; + parameter LW_START_UPDN_RATE_EN_8G = "ENABLED"; + parameter LW_START_UPDN_START_DELAY = "0b1000"; + parameter LW_START_UPDN_TIMER_EN = "DISABLED"; + parameter MARGIN_ENABLE = "PCIE_SPEC"; + parameter MARGIN_VALUE = "0b000"; + parameter MASK_0 = "SKIP_RCVR_DETECTION"; + parameter MASK_1 = "SKIP_RCVR_DETECTION"; + parameter MASK_2 = "SKIP_RCVR_DETECTION"; + parameter MASK_3 = "SKIP_RCVR_DETECTION"; + parameter MAX_LINK_WIDTH = "1_LANE"; + parameter MAX_SPEED = "8G"; + parameter MAX_VAR = "0b00100"; + parameter MERGE_LMMI_RDATA = "DISABLED"; + parameter METHOD_FMERIT_CTRL = "STEP_PCIE_TX_PRESETS"; + parameter METHOD_TX_CRED_CLEANUP = "HEADER"; + parameter MGMT_INTLEG = "0b0000"; + parameter MGMT_LTSSM_DIS = "DISABLED"; + parameter MID_VALUE_20B = "0b010100"; + parameter MID_VALUE_GEN3 = "0b001110"; + parameter MIN_SPEED = "2P5G"; + parameter MIN_TIME = "0_MS"; + parameter MIN_TIME_CFG = "4US"; + parameter MIX_DIR = "DISABLED"; + parameter MODE_BFF = "RESTART"; + parameter MRL_SENSOR_PRESENT = "NOT_SUPPORTED"; + parameter MULT_ENABLE = "RECOMMENDED_VALUES"; + parameter MULT_MESSAGE_CAPABLE_MSICAP_A = "EIGHT"; + parameter MULT_MESSAGE_CAPABLE_MSICAP_B = "EIGHT"; + parameter MULT_MESSAGE_CAPABLE_MSICAP_C = "EIGHT"; + parameter MULT_MESSAGE_CAPABLE_MSICAP_D = "EIGHT"; + parameter NFTS = "0b11111111"; + parameter NO_COMMAND_COMPLETED_SUPPORT = "SW_NOTIF_PROVIDED"; + parameter NO_FCMP = "DISABLED"; + parameter NO_REMOTE_CHANGE = "DISABLED"; + parameter NO_TX_IDLE_DELAY = "DATA_VALID_GAP"; + parameter NUM_LANES = "1_LANE"; + parameter NUMBER_DSLINK = "0b00000"; + parameter NUMHI_A = "0b00000000000000000000000000000000"; + parameter NUMHI_B = "0b00000000000000000000000000000000"; + parameter NUMHI_C = "0b00000000000000000000000000000000"; + parameter NUMHI_D = "0b00000000000000000000000000000000"; + parameter NUMHOLD = "SINGLE_HOLD_RESPONSE"; + parameter NUMLO_A = "0b00000000000000000000000000000000"; + parameter NUMLO_B = "0b00000000000000000000000000000000"; + parameter NUMLO_C = "0b00000000000000000000000000000000"; + parameter NUMLO_D = "0b00000000000000000000000000000000"; + parameter OBFF_SUPPORTED = "NOT_SUPPORTED"; + parameter OFFSET_MSIX_PBA_A = "0b00000000000000000111000000000"; + parameter OFFSET_MSIX_PBA_B = "0b00000000000000000111000000000"; + parameter OFFSET_MSIX_PBA_C = "0b00000000000000000111000000000"; + parameter OFFSET_MSIX_PBA_D = "0b00000000000000000111000000000"; + parameter OFFSET_MSIX_TABLE_A = "0b00000000000000000110000000000"; + parameter OFFSET_MSIX_TABLE_B = "0b00000000000000000110000000000"; + parameter OFFSET_MSIX_TABLE_C = "0b00000000000000000110000000000"; + parameter OFFSET_MSIX_TABLE_D = "0b00000000000000000110000000000"; + parameter OVER_CTLE = "DISABLED"; + parameter OVER_RX = "DISABLED"; + parameter OVER_RXDM = "DISABLED"; + parameter OVER_RXDP = "DISABLED"; + parameter OVER_RXES = "DISABLED"; + parameter OVER_RXT = "DISABLED"; + parameter OVER_SCH = "DISABLED"; + parameter OVER_TX = "DISABLED"; + parameter OVERRIDE = "DISABLED"; + parameter OVR_CDR = "DISABLED"; + parameter OVR_DIR = "DISABLED"; + parameter OVR_FOM = "DISABLED"; + parameter OVR_GAIN3DB = "ENABLED"; + parameter OVR_HINT3DB = "ENABLED"; + parameter P_CLK_PERIOD = "0b0000111110100000"; + parameter PAR_LPBK = "DISABLED"; + parameter PAS = "10X"; + parameter PATTERN_0 = "UNSCRAMBLED"; + parameter PATTERN_1 = "UNSCRAMBLED"; + parameter PATTERN_2 = "UNSCRAMBLED"; + parameter PCIPM_L1_1_SUPPORTED = "SUPPORTED"; + parameter PCIPM_L1_2_SUPPORTED = "SUPPORTED"; + parameter PERIOD_SRIS_128B130B = "0b000000"; + parameter PERIOD_SRIS_8B10B = "0b00000000"; + parameter PERIOD_SRNS_128B130B = "0b00000000"; + parameter PERIOD_SRNS_8B10B = "0b00000000"; + parameter PHANTOM_FUNCTIONS_SUPPORTED = "NO_FUNCTION_BITS"; + parameter PHYSICAL_SLOT_NUMBER = "0b0000000000001"; + parameter PIN_INTERRUPT_A = "INTA"; + parameter PIN_INTERRUPT_B = "INTA"; + parameter PIN_INTERRUPT_C = "INTA"; + parameter PIN_INTERRUPT_D = "INTA"; + parameter PIPE_TX_SWING = "FULL_SWING"; + parameter PLESIO_LPBK = "DISABLED"; + parameter PM_REDUCE_TIMEOUTS = "DISABLED"; + parameter PMA_DRIVEN_MODE = "PCS_DRIVEN"; + parameter PMCSR_B2_B3_SUPPORT = "DISABLED"; + parameter PMCSR_BUS_P_C_EN = "DISABLED"; + parameter PME_CLOCK = "DISABLED"; + parameter PME_SUPPORT = "0b11111"; + parameter PMFF_ALL = "DISABLED"; + parameter PORT_CM_RESTORE_TIME = "0b00000000"; + parameter PORT_NUMBER = "0b00000000"; + parameter PORT_TPOWER_ON_SCALE = "2_US"; + parameter PORT_TPOWER_ON_VALUE = "0b00000"; + parameter POST = "0b000000"; + parameter POST_A0COEF = "0b001"; + parameter POST_A1COEF = "0b001"; + parameter POST_A2COEF = "0b001"; + parameter POST_CURSOR_LIMIT = "0b100000"; + parameter POST_CURSOR_STEP_SIZE = "0b001000"; + parameter POST_ITERCNT = "0b100"; + parameter POST_STEP = "STEP_SIZE_4"; + parameter POWER_CONTROLLER_PRESENT = "NOT_SUPPORTED"; + parameter POWER_INDICATOR_PRESENT = "NOT_SUPPORTED"; + parameter POWER_REQUIRED = "AUX_POWER_NOT_REQUIRED"; + parameter PRBS_CHK = "DISABLED"; + parameter PRBS_GEN = "DISABLED"; + parameter PRBS_TYP = "PRBS7"; + parameter PRE = "0b000000"; + parameter PRE_A0COEF = "0b101"; + parameter PRE_A1COEF = "0b101"; + parameter PRE_A2COEF = "0b101"; + parameter PRE_CURSOR_LIMIT = "0b010000"; + parameter PRE_CURSOR_STEP_SIZE = "0b000100"; + parameter PRE_FOM = "ENABLED"; + parameter PRE_FOM_AVG = "0b100"; + parameter PRE_ITERCNT = "0b100"; + parameter PRE_RXEQ_TIMER = "0b00010100"; + parameter PRE_STEP = "STEP_SIZE_2"; + parameter PRESET_COUNT_INI = "0b0000"; + parameter PRESET_EN_LPBK_MASTER = "OTHERWISE"; + parameter PRESET_EN_LPBK_SLAVE = "OTHERWISE"; + parameter PRESET_ENABLE = "NORMAL_OP"; + parameter PRESET_EQTX_FORCE = "0b0000"; + parameter PRESET_LPBK_MASTER = "0b0000"; + parameter PRESET_LPBK_SLAVE_0 = "OTHERWISE"; + parameter PRESET_LPBK_SLAVE_1 = "OTHERWISE"; + parameter PRESET_LPBK_SLAVE_2 = "OTHERWISE"; + parameter PRESET_LPBK_SLAVE_3 = "OTHERWISE"; + parameter PRESET_REJECT = "0b00000000000"; + parameter PRESET0_POSTCURSOR = "0b1000"; + parameter PRESET0_PRECURSOR = "0b0000"; + parameter PRESET1_POSTCURSOR = "0b0101"; + parameter PRESET1_PRECURSOR = "0b0000"; + parameter PRESET10_POSTCURSOR = "0b1010"; + parameter PRESET10_PRECURSOR = "0b0000"; + parameter PRESET2_POSTCURSOR = "0b0110"; + parameter PRESET2_PRECURSOR = "0b0000"; + parameter PRESET3_POSTCURSOR = "0b0100"; + parameter PRESET3_PRECURSOR = "0b0000"; + parameter PRESET4_POSTCURSOR = "0b0000"; + parameter PRESET4_PRECURSOR = "0b0000"; + parameter PRESET5_POSTCURSOR = "0b0000"; + parameter PRESET5_PRECURSOR = "0b0011"; + parameter PRESET6_POSTCURSOR = "0b0000"; + parameter PRESET6_PRECURSOR = "0b0100"; + parameter PRESET7_POSTCURSOR = "0b0110"; + parameter PRESET7_PRECURSOR = "0b0011"; + parameter PRESET8_POSTCURSOR = "0b0100"; + parameter PRESET8_PRECURSOR = "0b0100"; + parameter PRESET9_POSTCURSOR = "0b0000"; + parameter PRESET9_PRECURSOR = "0b0101"; + parameter PS_REENTRY_TIME = "0b00000000"; + parameter RATE = "2P5G"; + parameter RATE_ENABLE = "INITIAL_SPEED_CHANGES"; + parameter RCB = "DISABLED"; + parameter REC_SPD_INFER_EQ_PH0123 = "EXCLUDE_TIME_SPENT"; + parameter REC_SPD_INFER_RCVR_CFG = "EXCLUDE_TIME_SPENT"; + parameter REC_SPD_INFER_RCVR_LOCK = "EXCLUDE_TIME_SPENT"; + parameter DIS_FUNC_B = "ENABLED"; + parameter DIS_FUNC_C = "ENABLED"; + parameter DIS_FUNC_D = "ENABLED"; + parameter REDUCE_TIMEOUTS_LTSSMSIM = "DISABLED"; + parameter REDUCE_TIMEOUTS_SIM = "DISABLED"; + parameter REDUCE_TS1 = "DISABLED"; + parameter REENTRY_DISABLE = "ENABLED"; + parameter REENTRY_TIME = "0b00000000000000"; + parameter REQ_FEEDBACK = "0b00000000"; + parameter RESET_EIEOS_INTERVAL_COUNT = "DISABLED"; + parameter REVISION_ID_ID3A = "0b00000100"; + parameter REVISION_ID_ID3B = "0b00000100"; + parameter REVISION_ID_ID3C = "0b00000100"; + parameter REVISION_ID_ID3D = "0b00000100"; + parameter RL1 = "0b0011"; + parameter RL2 = "0b0101"; + parameter RL3 = "0b0011"; + parameter ROUTING_SUPPORTED = "DISABLED"; + parameter RP_COMPLETER_EN = "DISABLED"; + parameter RSTCDR_ERR = "ENABLED"; + parameter RSTCDR_FRQ = "ENABLED"; + parameter RSTCDR_IDL = "DISABLED"; + parameter RX_BYPASS_DECODE_EN = "ENABLED"; + parameter RX_BYPASS_MSG_DEC = "NORMAL_OPERATION"; + parameter RX_CONVERT_UR_TO_CA = "NORMAL_OPERATION"; + parameter RX_D_ALLOC_C = "0b0000000001100000"; + parameter RX_D_ALLOC_N = "0b0000000000000110"; + parameter RX_D_ALLOC_P = "0b0000000001101100"; + parameter RX_DIV_MODE1 = "0b10"; + parameter RX_DIV_MODE0 = "DIV_2"; + parameter RX_DIV_MODE2 = "0b00"; + parameter RX_DL_ACTIVE_DISABLE = "BLOCK_RECEPTION_TLP"; + parameter RX_EARLY_FORWARD_DISABLE = "FWD_RX_DATA_LL"; + parameter RX_ERR_COR = "DISABLED"; + parameter RX_ERR_UCOR = "DISABLED"; + parameter RX_FORCE_RO = "DISABLED"; + parameter RX_H_ALLOC_C = "0b000000100000"; + parameter RX_H_ALLOC_N = "0b000000001000"; + parameter RX_H_ALLOC_P = "0b000000010000"; + parameter RX_HIZ = "IGNORED"; + parameter RX_IMPED_RATIO = "0b10000000"; + parameter RX_INHIBIT_ACK_NAK = "PROCESS_RCVD_ACK"; + parameter RX_INHIBIT_TLP = "PROCESS_RCVD_TLP"; + parameter RX_LCRC_INJECT_EN = "DO_NOT_INJECT_ERROR"; + parameter RX_MALF_INJECT_EN = "DO_NOT_INJECT_ERROR"; + parameter RX_POLINV = "NORMAL"; + parameter RX_PRIORITY = "DISABLED"; + parameter RX_PRIORITY_N_STARVE_THRESH = "0b00010000"; + parameter RX_PRIORITY_P_STARVE_THRESH = "0b00010000"; + parameter RX_PWRDN = "IGNORED"; + parameter RX_TLP_VALID = "DISABLED"; + parameter RXEQ_ALGO = "0b111"; + parameter RXEQ_ENABLE = "0b100"; + parameter RXEQ_EVAL_MAX = "0b11111111"; + parameter RXEQ_MANUAL = "DISABLED"; + parameter RXEQ_STATE = "0b0000"; + parameter RXF_A = "0b0100"; + parameter RXF_B = "0b0100"; + parameter RXF_C = "0b0100"; + parameter RXHF_CLKDN = "ENABLED"; + parameter RXIDLE_MAX = "0b1111"; + parameter RXIDLE_MAX2 = "0b0000010000000000"; + parameter RXIDLE_MSB = "0b11"; + parameter RXM_A = "0b10"; + parameter RXM_B = "0b01"; + parameter RXM_C = "0b00"; + parameter RXN_A = "0b00100"; + parameter RXN_B = "0b01001"; + parameter RXN_C = "0b01111"; + parameter RXOFF_SETTLE_MAX = "0b011"; + parameter RXOFF_STABLE_MAX = "0b10000"; + parameter RXPLLINIT = "DISABLED"; + parameter RXPLLRST = "SET"; + parameter SELECT_DIR_FOM_N = "FME_METHOD"; + parameter SELECTABLE_DEEMPHASIS = "6P0DB"; + parameter SEQ_NUM = "0b000000000000"; + parameter SIGNAL_DETECT_THRESHOLD = "125_MV"; + parameter SIZE_CFG0_A = "0b00000"; + parameter SIZE_CFG0_B = "0b00000"; + parameter SIZE_CFG0_C = "0b00000"; + parameter SIZE_CFG0_D = "0b00000"; + parameter SIZE_CFG1_A = "0b00000"; + parameter SIZE_CFG1_B = "0b00000"; + parameter SIZE_CFG1_C = "0b00000"; + parameter SIZE_CFG1_D = "0b00000"; + parameter SIZE_CFG2_A = "0b00000"; + parameter SIZE_CFG2_B = "0b00000"; + parameter SIZE_CFG2_C = "0b00000"; + parameter SIZE_CFG2_D = "0b00000"; + parameter SIZE_CFG3_A = "0b00000"; + parameter SIZE_CFG3_B = "0b00000"; + parameter SIZE_CFG3_C = "0b00000"; + parameter SIZE_CFG3_D = "0b00000"; + parameter SIZE_CFG4_A = "0b00000"; + parameter SIZE_CFG4_B = "0b00000"; + parameter SIZE_CFG4_C = "0b00000"; + parameter SIZE_CFG4_D = "0b00000"; + parameter SIZE_CFG5_A = "0b00000"; + parameter SIZE_CFG5_B = "0b00000"; + parameter SIZE_CFG5_C = "0b00000"; + parameter SIZE_CFG5_D = "0b00000"; + parameter SKIP_FINAL_COEF_CHECK = "DISABLED"; + parameter SLOT_CLOCK_CONFIGURATION = "REFCLK_BY_SLOT"; + parameter SLOT_IMPLEMENTED = "UNCONNECTED"; + parameter SLOT_POWER_LIMIT_SCALE = "0b00"; + parameter SLOT_POWER_LIMIT_VALUE = "0b00001010"; + parameter SPEED_LPBK_CTRL = "2P5G"; + parameter START_PRESET = "PRESET_VALUE"; + parameter START_REMOTE_ADV = "OTHERWISE"; + parameter STATE_DATA_N = "USE_RX_DATA_OBSERVATION"; + parameter STEP_SELECT = "0b00000"; + parameter STP_OVERRIDE_EN = "DISABLED"; + parameter STP_OVERRIDE_LEN = "0b00000000000"; + parameter STP_OVERRIDE_NEW_LEN = "0b00000000000"; + parameter SUBSTATE_MAX = "0b00000"; + parameter SUBSYSTEM_ID_ID2A = "0b1110000000000100"; + parameter SUBSYSTEM_ID_ID2B = "0b1110000000000100"; + parameter SUBSYSTEM_ID_ID2C = "0b1110000000000100"; + parameter SUBSYSTEM_ID_ID2D = "0b1110000000000100"; + parameter SUBSYSTEM_VENDOR_ID_ID2A = "0b0001100110101010"; + parameter SUBSYSTEM_VENDOR_ID_ID2B = "0b0001100110101010"; + parameter SUBSYSTEM_VENDOR_ID_ID2C = "0b0001100110101010"; + parameter SUBSYSTEM_VENDOR_ID_ID2D = "0b0001100110101010"; + parameter SUPP_SIZE_CFG0_A = "0b00000000000000001111"; + parameter SUPP_SIZE_CFG0_B = "0b00000000000000001111"; + parameter SUPP_SIZE_CFG0_C = "0b00000000000000001111"; + parameter SUPP_SIZE_CFG0_D = "0b00000000000000001111"; + parameter SUPP_SIZE_CFG1_A = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG1_B = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG1_C = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG1_D = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG2_A = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG2_B = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG2_C = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG2_D = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG3_A = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG3_B = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG3_C = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG3_D = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG4_A = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG4_B = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG4_C = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG4_D = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG5_A = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG5_B = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG5_C = "0b00000000000000000000"; + parameter SUPP_SIZE_CFG5_D = "0b00000000000000000000"; + parameter SYS_ALLOC = "PWR_BUDGET_CAP_VALUES"; + parameter T0_RX_BYPASS_MSG_DEC = "NORMAL_OPERATION"; + parameter TABLE_SIZE_MSIXCAP_A = "0b00000000111"; + parameter TABLE_SIZE_MSIXCAP_B = "0b00000000111"; + parameter TABLE_SIZE_MSIXCAP_C = "0b00000000111"; + parameter TABLE_SIZE_MSIXCAP_D = "0b00000000111"; + parameter TARGET_LINK_SPEED = "8G"; + parameter TARGET_ONLY = "DISABLED"; + parameter TD1_MEANS_ADD_HAS_N = "ECRC_CONTAINED"; + parameter TIMEOUT_THRESHOLD_PME = "0b000000000000"; + parameter TIMEOUT_THRESHOLD_PME_TO_ACK_DS = "0b00000000"; + parameter TIMER = "0b00000000"; + parameter TLP_LCRC_ERR_ENABLE = "DISABLED"; + parameter TLP_LCRC_ERR_RATE = "0b000"; + parameter TLP_SEQ_ERR_ENABLE = "DISABLED"; + parameter TLUNIT = "1_MS"; + parameter TO_EXTEND = "0b01111111"; + parameter TRNG_A0COEF = "0b101"; + parameter TRNG_A1COEF = "0b101"; + parameter TRNG_A2COEF = "0b101"; + parameter TRNG_FAST = "DISABLED"; + parameter TRNG_ITERCNT = "0b100"; + parameter TRNG_RXEQ_TIMER = "0b00100000"; + parameter TS1_ACK_BLOCK_USE_PRESET = "FORCED_TO_ZERO"; + parameter TS1_ACK_DELAY = "0b00011111"; + parameter TS1_ACK_MASK_USE_PRESET = "IGNORES_USE_PRESET"; + parameter TX_AMP_RATIO_MARGIN0_FULL = "0b10000000"; + parameter TX_AMP_RATIO_MARGIN0_HALF = "0b01010000"; + parameter TX_AMP_RATIO_MARGIN1_FULL = "0b01111000"; + parameter TX_AMP_RATIO_MARGIN1_HALF = "0b01011000"; + parameter TX_AMP_RATIO_MARGIN2_FULL = "0b01101000"; + parameter TX_AMP_RATIO_MARGIN2_HALF = "0b01001000"; + parameter TX_AMP_RATIO_MARGIN3_FULL = "0b01100000"; + parameter TX_AMP_RATIO_MARGIN3_HALF = "0b01000000"; + parameter TX_AMP_RATIO_MARGIN4_FULL = "0b01011000"; + parameter TX_AMP_RATIO_MARGIN4_HALF = "0b00111000"; + parameter TX_AMP_RATIO_MARGIN5_FULL = "0b01010000"; + parameter TX_AMP_RATIO_MARGIN5_HALF = "0b00110000"; + parameter TX_AMP_RATIO_MARGIN6_FULL = "0b01001000"; + parameter TX_AMP_RATIO_MARGIN6_HALF = "0b00101000"; + parameter TX_AMP_RATIO_MARGIN7_FULL = "0b01000000"; + parameter TX_AMP_RATIO_MARGIN7_HALF = "0b00100000"; + parameter TX_BYPASS_DECODE_EN = "ENABLED"; + parameter TX_BYPASS_MSG_DEC = "NORMAL_OPERATION"; + parameter TX_COMP_RECEIVE = "DOES_NOT_ASSERT"; + parameter TX_CONVERT_UR_TO_CA = "NORMAL_OPERATION"; + parameter TX_D_ALLOC_C = "0b0000000001100000"; + parameter TX_D_ALLOC_N = "0b0000000000000110"; + parameter TX_D_ALLOC_P = "0b0000000001101100"; + parameter TX_DIV_MODE0 = "0b10"; + parameter TX_DIV_MODE1 = "0b10"; + parameter TX_DIV_MODE2 = "0b10"; + parameter TX_EQ_EVAL_CNT_SEL = "WAIT_8_CLKS"; + parameter TX_ERR_COR = "DISABLED"; + parameter TX_ERR_UCOR = "DISABLED"; + parameter TX_FORCE_RO = "DISABLED"; + parameter TX_GAP_INJECT_EN = "DO_NOT_INJECT_GAP"; + parameter TX_H_ALLOC_C = "0b000000100000"; + parameter TX_H_ALLOC_N = "0b000000001000"; + parameter TX_H_ALLOC_P = "0b000000010000"; + parameter TX_HIZ = "IGNORED"; + parameter TX_IMPED_RATIO = "0b10000000"; + parameter TX_PAR1_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_PAR2_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter TX_PAR2_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_PAR2_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_POLINV = "NORMAL"; + parameter TX_PRE_RATIO = "0b00000000"; + parameter TX_PRE_RATIO_DEEMP0_FULL = "0b00000000"; + parameter TX_PRE_RATIO_DEEMP0_HALF = "0b00000000"; + parameter TX_PRE_RATIO_DEEMP1_FULL = "0b00000000"; + parameter TX_PRE_RATIO_DEEMP1_HALF = "0b00000000"; + parameter TX_PRIORITY = "DISABLED"; + parameter TX_PRIORITY_N_STARVE_THRESH = "0b00010000"; + parameter TX_PRIORITY_P_STARVE_THRESH = "0b00010000"; + parameter TX_PST_RATIO = "0b00010101"; + parameter TX_PST_RATIO_DEEMP0_FULL = "0b00100000"; + parameter TX_PST_RATIO_DEEMP0_HALF = "0b00100000"; + parameter TX_PST_RATIO_DEEMP1_FULL = "0b00010101"; + parameter TX_PST_RATIO_DEEMP1_HALF = "0b00010101"; + parameter TX_QUIESCE = "DISABLED"; + parameter TX_REPLAY_ECC1_HANDLE_DISABLE = "ENABLE_CORRECTION"; + parameter TX_REPLAY_ECC1_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_REPLAY_ECC1_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_REPLAY_ECC2_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter TX_REPLAY_ECC2_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_REPLAY_ECC2_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_REQ_EQ = "DISABLED"; + parameter TX_SELECT_RX_FEEDBACK = "REFCLK"; + parameter TX_TLP_VALID = "DISABLED"; + parameter TXF_A = "0b0100"; + parameter TXF_B = "0b0100"; + parameter TXF_C = "0b0100"; + parameter TXHF_CLKDN = "ENABLED"; + parameter TXM_A = "0b10"; + parameter TXM_B = "0b01"; + parameter TXM_C = "0b00"; + parameter TXN_A = "0b00100"; + parameter TXN_B = "0b01001"; + parameter TXN_C = "0b01111"; + parameter TXPLL_INIT = "DISABLED"; + parameter TXPLLRST = "DISABLED"; + parameter TYPE1_TYPE0_N = "ENDPOINT"; + parameter U_CLK_PERIOD = "0b0001111101000000"; + parameter US_PORT_PS_ENTRY_TIME = "0b0000000000000000"; + parameter US_PORT_RX_PRESET_HINT = "0b010"; + parameter US_PORT_TX_PRESET = "0b0100"; + parameter USE_COEF_PRE_MTHD_CTRL = "PRESET_VALUE"; + parameter USE_COEF_UPDN_CTRL = "PRESET_VALUE"; + parameter USER_AUTO_N = "AUTOMATIC_ON_RECEPTION"; + parameter VEC_MASK_CAPABLE_MSICAP_A = "ENABLED"; + parameter VEC_MASK_CAPABLE_MSICAP_B = "ENABLED"; + parameter VEC_MASK_CAPABLE_MSICAP_C = "ENABLED"; + parameter VEC_MASK_CAPABLE_MSICAP_D = "ENABLED"; + parameter VENDOR_ID_ID1A = "0b0001100110101010"; + parameter VENDOR_ID_ID1B = "0b0001100110101010"; + parameter VENDOR_ID_ID1C = "0b0001100110101010"; + parameter VENDOR_ID_ID1D = "0b0001100110101010"; + parameter VENDOR0_UR = "REPORT"; + parameter VERSION_AER_CAP = "VER_0X2"; + parameter VERSION_PM_CAP = "0b011"; + parameter XLCY0 = "0b00000000"; + parameter XLCY1 = "0b00000000"; + parameter RX_ESP_RESP_WAIT = "0b01000000"; + parameter SEL_PCLK_DIV2 = "PCLK_DIV2"; + parameter COMPLIANCE = "ENABLED"; + parameter LOOPBACK = "ENABLED"; + parameter HOT_RESET = "ENABLED"; + parameter DIS_PREVENT = "ENABLED"; + parameter MPS_VIOLATION_RX = "DISABLED"; + parameter MPS_VIOLATION_TX = "DISABLED"; + parameter EN_RX_ALLOC_SEL = "HW"; + parameter EN_TX_ALLOC_SEL = "HW"; + parameter AUX_CLK_PERIOD = "0b1111010000100100"; + parameter EN_PIPE_IF_CTRL = "DISABLED"; + parameter PIPE_PWRDN = "P1"; + parameter TX_CM_DIS = "DEASSERTED"; + parameter RX_EI_DIS = "DEASSERTED"; + parameter PCLKREQ_N = "DEASSERTED"; + parameter STS_PHY_STATUS = "DEASSERTED"; + parameter STS_PIPE_RSTN = "DEASSERTED"; + parameter LEGACY_MODE = "MATCH_TS"; + parameter OVERFLOW = "DISABLED"; + parameter DIR = "RECEIVE"; + parameter SPEED = "8G"; + parameter LANE = "0"; + parameter COEF_ENABLE_8G = "DISABLED"; + parameter PRESET_ENABLE_8G = "DISABLED"; + parameter VALUE_8G_PRE = "0b000000"; + parameter VALUE_8G_POST = "0b000000"; + parameter REQ_EQ_MAX_COUNT = "0b10"; + parameter MESO_LPBK = "DISABLED"; + parameter TX_REPLAY_ECC2_INJECT_M_1_N = "INJECT_1_ERR"; + parameter TX_REPLAY_ECC1_INJECT_M_1_N = "INJECT_1_ERR"; + parameter REDO = "DISABLED"; + parameter RX_PAR_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter RX_PAR_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter RX_ECC2_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter RX_ECC2_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter RX_ECC2_INJECT_M_1_N = "INJECT_1_ERR"; + parameter RX_ECC2_INJECT_TYPE = "POSTED_DATA_RAM"; + parameter RX_ECC2_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter RX_ECC1_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter RX_ECC1_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter RX_ECC1_INJECT_M_1_N = "INJECT_1_ERR"; + parameter RX_ECC1_INJECT_TYPE = "POSTED_DATA_RAM"; + parameter RX_ECC1_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter RX_ERR_PAR = "OTHERWISE"; + parameter RX_ERR_ECC2 = "OTHERWISE"; + parameter RX_ERR_ECC1 = "OTHERWISE"; + parameter TX_PAR_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_PAR_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_ECC2_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_ECC2_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter TX_ECC2_INJECT_M_1_N = "INJECT_1_ERR"; + parameter TX_ECC2_INJECT_TYPE = "POSTED_DATA_RAM"; + parameter TX_ECC2_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_ECC1_REPORT_DISABLE = "ENABLE_REPORTING"; + parameter TX_ECC1_HANDLE_DISABLE = "ENABLE_HANDLING"; + parameter TX_ECC1_INJECT_M_1_N = "INJECT_1_ERR"; + parameter TX_ECC1_INJECT_TYPE = "POSTED_DATA_RAM"; + parameter TX_ECC1_INJECT_EN = "DO_NOT_INJECT_ERR"; + parameter TX_ERR_PAR = "OTHERWISE"; + parameter TX_ERR_ECC2 = "OTHERWISE"; + parameter TX_ERR_ECC1 = "OTHERWISE"; + parameter MAX_PAYLOAD_SIZE_SUPPORTED = "256_BYTES"; + parameter ARXCAL_OUT = "DISABLED"; + parameter F_ARXDPDIR = "IGNORED"; + parameter IDLE_INFER_REC_RCVR_CFG = "OTHERWISE"; + parameter IDLE_INFER_LPBK_SLAVE = "OTHERWISE"; + parameter IDLE_INFER_REC_SPEED2_SUCCESS = "OTHERWISE"; + parameter IDLE_INFER_REC_SPEED2_UNSUCCESS = "OTHERWISE"; + parameter IDLE_INFER_L0_TO_REC_RCVR_LOCK = "OTHERWISE"; + parameter SPEED_CHANGE_FAIL = "OTHERWISE"; + parameter DIRECT_TO_DETECT_FAST = "OTHERWISE"; + parameter DIRECT_TO_RCVRY_CH_BOND = "OTHERWISE"; + parameter DIRECT_TO_LPBK_ENTRY = "OTHERWISE"; + parameter DIRECT_SPEED_CHANGE = "OTHERWISE"; + parameter L0_TO_REC_RCVR_LOCK_RX_TS12 = "OTHERWISE"; + parameter L0_TO_REC_RCVR_LOCK_RX_8G_EIE = "OTHERWISE"; + parameter L0_TO_REC_RCVR_LOCK_RX_INFER = "OTHERWISE"; + parameter DIRECT_TO_RCVRY_PHY = "OTHERWISE"; + parameter DIRECT_TO_RCVRY_FRAME = "OTHERWISE"; + parameter DIRECT_TO_RCVRY_REPLAY = "OTHERWISE"; + parameter DIRECT_TO_HOT_RESET = "OTHERWISE"; + parameter DIRECT_TO_DISABLE = "OTHERWISE"; + parameter RX_L0S_DIRECT_TO_RCVRY = "OTHERWISE"; + parameter AUTONOMOUS_WIDTH_CHANGE = "OTHERWISE"; + parameter DIRECTED_RETRAIN_LINK = "OTHERWISE"; + parameter ERR_TX_PIPE_UNDERFLOW = "OTHERWISE"; + parameter TS2_DETECT3 = "OTHERWISE"; + parameter TS2_DETECT2 = "OTHERWISE"; + parameter TS2_DETECT1 = "OTHERWISE"; + parameter TS2_DETECT0 = "OTHERWISE"; + parameter TS1_DETECT3 = "OTHERWISE"; + parameter TS1_DETECT2 = "OTHERWISE"; + parameter TS1_DETECT1 = "OTHERWISE"; + parameter TS1_DETECT0 = "OTHERWISE"; + parameter TS2I_DETECT3 = "OTHERWISE"; + parameter TS2I_DETECT2 = "OTHERWISE"; + parameter TS2I_DETECT1 = "OTHERWISE"; + parameter TS2I_DETECT0 = "OTHERWISE"; + parameter TS1I_DETECT3 = "OTHERWISE"; + parameter TS1I_DETECT2 = "OTHERWISE"; + parameter TS1I_DETECT1 = "OTHERWISE"; + parameter TS1I_DETECT0 = "OTHERWISE"; + parameter FTS_DETECT3 = "OTHERWISE"; + parameter FTS_DETECT2 = "OTHERWISE"; + parameter FTS_DETECT1 = "OTHERWISE"; + parameter FTS_DETECT0 = "OTHERWISE"; + parameter SKP_DETECT3 = "OTHERWISE"; + parameter SKP_DETECT2 = "OTHERWISE"; + parameter SKP_DETECT1 = "OTHERWISE"; + parameter SKP_DETECT0 = "OTHERWISE"; + parameter EIE_DETECT3 = "OTHERWISE"; + parameter EIE_DETECT2 = "OTHERWISE"; + parameter EIE_DETECT1 = "OTHERWISE"; + parameter EIE_DETECT0 = "OTHERWISE"; + parameter EIOS_DETECT3 = "OTHERWISE"; + parameter EIOS_DETECT2 = "OTHERWISE"; + parameter EIOS_DETECT1 = "OTHERWISE"; + parameter EIOS_DETECT0 = "OTHERWISE"; + parameter DATA_DETECT3 = "OTHERWISE"; + parameter DATA_DETECT2 = "OTHERWISE"; + parameter DATA_DETECT1 = "OTHERWISE"; + parameter DATA_DETECT0 = "OTHERWISE"; + parameter SDS_DETECT3 = "OTHERWISE"; + parameter SDS_DETECT2 = "OTHERWISE"; + parameter SDS_DETECT1 = "OTHERWISE"; + parameter SDS_DETECT0 = "OTHERWISE"; + parameter INFO_BAD_TLP_NULL_ERR = "OTHERWISE"; + parameter INFO_BAD_TLP_PHY_ERR = "OTHERWISE"; + parameter INFO_BAD_TLP_MALF_ERR = "OTHERWISE"; + parameter INFO_BAD_TLP_ECRC_ERR = "OTHERWISE"; + parameter INFO_SCHEDULE_DUPL_ACK = "OTHERWISE"; + parameter INFO_BAD_TLP_SEQ_ERR = "OTHERWISE"; + parameter INFO_BAD_TLP_CRC_ERR = "OTHERWISE"; + parameter INFO_NAK_RECEIVED = "OTHERWISE"; + parameter INFO_DESKEW_OVERFLOW_ERROR = "OTHERWISE"; + parameter INFO_TX_DATA_UNDERFLOW = "OTHERWISE"; + parameter INFO_REPLAY_STARTED = "OTHERWISE"; + parameter ERR_AER_TX_PAR2 = "OTHERWISE"; + parameter ERR_AER_TX_REPLAY_ECC2 = "OTHERWISE"; + parameter ERR_AER_TX_REPLAY_ECC1 = "OTHERWISE"; + parameter ERR_AER_SURPRISE_DOWN = "OTHERWISE"; + parameter ERR_AER_DL_PROTOCOL_ERROR = "OTHERWISE"; + parameter ERR_AER_REPLAY_TIMER_TIMEOUT = "OTHERWISE"; + parameter ERR_AER_REPLAY_NUM_ROLLOVER = "OTHERWISE"; + parameter ERR_AER_BAD_DLLP = "OTHERWISE"; + parameter ERR_AER_BAD_TLP = "OTHERWISE"; + parameter ERR_AER_RECEIVER_ERROR = "OTHERWISE"; + parameter P_RX_LIM_H = "DISABLED"; + parameter P_RX_LIM_D = "DISABLED"; + parameter N_RX_LIM_H = "DISABLED"; + parameter N_RX_LIM_D = "DISABLED"; + parameter C_RX_LIM_H = "DISABLED"; + parameter C_RX_LIM_D = "DISABLED"; + parameter P_TX_LIM_H = "DISABLED"; + parameter P_TX_LIM_D = "DISABLED"; + parameter N_TX_LIM_H = "DISABLED"; + parameter N_TX_LIM_D = "DISABLED"; + parameter C_TX_LIM_H = "DISABLED"; + parameter C_TX_LIM_D = "DISABLED"; + parameter MAX_RSA_WAIT = "0b00101000"; + parameter F_ARXDPNULL = "0b00000"; + input ACTACMD; + input ACTDR11; + input ACTEN; + input ACTHIGHZ; + input ACTMD; + output ACJNOUT; + output ACJPOUT; + input AUXCK; + input CKUSRI; + output CKUSRO; + input ECKIN; + input ECKIND2; + output ECKINDO; + input ERSTN; + input ERSTND2; + input ERXCKD2; + output ERXCKDO; + input ERXRSND2; + input ETXCKD2; + output ETXCKDO; + input ETXRSND2; + output FLR3; + output FLR2; + output FLR1; + output FLR0; + input FLRACK3; + input FLRACK2; + input FLRACK1; + input FLRACK0; + input MINTLEG3; + input MINTLEG2; + input MINTLEG1; + input MINTLEG0; + output MINTO; + input PERSTN; + output PMCTRL4; + output PMCTRL3; + output PMCTRL2; + output PMCTRL1; + output PMCTRL0; + output PMCTRLEN; + input PMDPAST4; + input PMDPAST3; + input PMDPAST2; + input PMDPAST1; + input PMDPAST0; + input PRMSGSD; + input PRNOSNP12; + input PRNOSNP11; + input PRNOSNP10; + input PRNOSNP9; + input PRNOSNP8; + input PRNOSNP7; + input PRNOSNP6; + input PRNOSNP5; + input PRNOSNP4; + input PRNOSNP3; + input PRNOSNP2; + input PRNOSNP1; + input PRNOSNP0; + input PRNSNPRE; + input PRSNOOP12; + input PRSNOOP11; + input PRSNOOP10; + input PRSNOOP9; + input PRSNOOP8; + input PRSNOOP7; + input PRSNOOP6; + input PRSNOOP5; + input PRSNOOP4; + input PRSNOOP3; + input PRSNOOP2; + input PRSNOOP1; + input PRSNOOP0; + input PRSNPRE; + input PPBDREG31; + input PPBDREG30; + input PPBDREG29; + input PPBDREG28; + input PPBDREG27; + input PPBDREG26; + input PPBDREG25; + input PPBDREG24; + input PPBDREG23; + input PPBDREG22; + input PPBDREG21; + input PPBDREG20; + input PPBDREG19; + input PPBDREG18; + input PPBDREG17; + input PPBDREG16; + input PPBDREG15; + input PPBDREG14; + input PPBDREG13; + input PPBDREG12; + input PPBDREG11; + input PPBDREG10; + input PPBDREG9; + input PPBDREG8; + input PPBDREG7; + input PPBDREG6; + input PPBDREG5; + input PPBDREG4; + input PPBDREG3; + input PPBDREG2; + input PPBDREG1; + input PPBDREG0; + output PPBDSEL7; + output PPBDSEL6; + output PPBDSEL5; + output PPBDSEL4; + output PPBDSEL3; + output PPBDSEL2; + output PPBDSEL1; + output PPBDSEL0; + input REXTCK; + input REXTRST; + input RSTUSRN; + output UDLLKUP; + input ULTSDIS; + output UPLLKUP; + output UTLLKUP; + input UCFGADDR11; + input UCFGADDR10; + input UCFGADDR9; + input UCFGADDR8; + input UCFGADDR7; + input UCFGADDR6; + input UCFGADDR5; + input UCFGADDR4; + input UCFGADDR3; + input UCFGADDR2; + input UCFGF2; + input UCFGF1; + input UCFGF0; + output UCFGRDD31; + output UCFGRDD30; + output UCFGRDD29; + output UCFGRDD28; + output UCFGRDD27; + output UCFGRDD26; + output UCFGRDD25; + output UCFGRDD24; + output UCFGRDD23; + output UCFGRDD22; + output UCFGRDD21; + output UCFGRDD20; + output UCFGRDD19; + output UCFGRDD18; + output UCFGRDD17; + output UCFGRDD16; + output UCFGRDD15; + output UCFGRDD14; + output UCFGRDD13; + output UCFGRDD12; + output UCFGRDD11; + output UCFGRDD10; + output UCFGRDD9; + output UCFGRDD8; + output UCFGRDD7; + output UCFGRDD6; + output UCFGRDD5; + output UCFGRDD4; + output UCFGRDD3; + output UCFGRDD2; + output UCFGRDD1; + output UCFGRDD0; + output UCFGRDE; + output UCFGRDY; + input UCFGSERD; + input UCFGVD; + input UCFGWRBE3; + input UCFGWRBE2; + input UCFGWRBE1; + input UCFGWRBE0; + input UCFGWRD31; + input UCFGWRD30; + input UCFGWRD29; + input UCFGWRD28; + input UCFGWRD27; + input UCFGWRD26; + input UCFGWRD25; + input UCFGWRD24; + input UCFGWRD23; + input UCFGWRD22; + input UCFGWRD21; + input UCFGWRD20; + input UCFGWRD19; + input UCFGWRD18; + input UCFGWRD17; + input UCFGWRD16; + input UCFGWRD15; + input UCFGWRD14; + input UCFGWRD13; + input UCFGWRD12; + input UCFGWRD11; + input UCFGWRD10; + input UCFGWRD9; + input UCFGWRD8; + input UCFGWRD7; + input UCFGWRD6; + input UCFGWRD5; + input UCFGWRD4; + input UCFGWRD3; + input UCFGWRD2; + input UCFGWRD1; + input UCFGWRD0; + input UCFGWRDN; + input USERAUPD; + input USERTRS3; + input USERTRS2; + input USERTRS1; + input USERTRS0; + input LMMICLK; + input LMMIOFFSET16; + input LMMIOFFSET15; + input LMMIOFFSET14; + input LMMIOFFSET13; + input LMMIOFFSET12; + input LMMIOFFSET11; + input LMMIOFFSET10; + input LMMIOFFSET9; + input LMMIOFFSET8; + input LMMIOFFSET7; + input LMMIOFFSET6; + input LMMIOFFSET5; + input LMMIOFFSET4; + input LMMIOFFSET3; + input LMMIOFFSET2; + output LMMIRDATA31; + output LMMIRDATA30; + output LMMIRDATA29; + output LMMIRDATA28; + output LMMIRDATA27; + output LMMIRDATA26; + output LMMIRDATA25; + output LMMIRDATA24; + output LMMIRDATA23; + output LMMIRDATA22; + output LMMIRDATA21; + output LMMIRDATA20; + output LMMIRDATA19; + output LMMIRDATA18; + output LMMIRDATA17; + output LMMIRDATA16; + output LMMIRDATA15; + output LMMIRDATA14; + output LMMIRDATA13; + output LMMIRDATA12; + output LMMIRDATA11; + output LMMIRDATA10; + output LMMIRDATA9; + output LMMIRDATA8; + output LMMIRDATA7; + output LMMIRDATA6; + output LMMIRDATA5; + output LMMIRDATA4; + output LMMIRDATA3; + output LMMIRDATA2; + output LMMIRDATA1; + output LMMIRDATA0; + output LMMIRDATAVALID; + output LMMIREADY; + input LMMIREQUEST; + input LMMIRESETN; + input LMMIWDATA31; + input LMMIWDATA30; + input LMMIWDATA29; + input LMMIWDATA28; + input LMMIWDATA27; + input LMMIWDATA26; + input LMMIWDATA25; + input LMMIWDATA24; + input LMMIWDATA23; + input LMMIWDATA22; + input LMMIWDATA21; + input LMMIWDATA20; + input LMMIWDATA19; + input LMMIWDATA18; + input LMMIWDATA17; + input LMMIWDATA16; + input LMMIWDATA15; + input LMMIWDATA14; + input LMMIWDATA13; + input LMMIWDATA12; + input LMMIWDATA11; + input LMMIWDATA10; + input LMMIWDATA9; + input LMMIWDATA8; + input LMMIWDATA7; + input LMMIWDATA6; + input LMMIWDATA5; + input LMMIWDATA4; + input LMMIWDATA3; + input LMMIWDATA2; + input LMMIWDATA1; + input LMMIWDATA0; + input LMMIWRRDN; + output VRXCMDD12; + output VRXCMDD11; + output VRXCMDD10; + output VRXCMDD9; + output VRXCMDD8; + output VRXCMDD7; + output VRXCMDD6; + output VRXCMDD5; + output VRXCMDD4; + output VRXCMDD3; + output VRXCMDD2; + output VRXCMDD1; + output VRXCMDD0; + input VRXCINIT; + input VRXCNH11; + input VRXCNH10; + input VRXCNH9; + input VRXCNH8; + input VRXCNH7; + input VRXCNH6; + input VRXCNH5; + input VRXCNH4; + input VRXCNH3; + input VRXCNH2; + input VRXCNH1; + input VRXCNH0; + input VRXCNINF; + input VRXCRRE; + output VRXD31; + output VRXD30; + output VRXD29; + output VRXD28; + output VRXD27; + output VRXD26; + output VRXD25; + output VRXD24; + output VRXD23; + output VRXD22; + output VRXD21; + output VRXD20; + output VRXD19; + output VRXD18; + output VRXD17; + output VRXD16; + output VRXD15; + output VRXD14; + output VRXD13; + output VRXD12; + output VRXD11; + output VRXD10; + output VRXD9; + output VRXD8; + output VRXD7; + output VRXD6; + output VRXD5; + output VRXD4; + output VRXD3; + output VRXD2; + output VRXD1; + output VRXD0; + output VRXDP3; + output VRXDP2; + output VRXDP1; + output VRXDP0; + output VRXEOP; + output VRXERR; + output VRXF1; + output VRXF0; + input VRXRDY; + output VRXSEL1; + output VRXSEL0; + output VRXSOP; + output VRXVD; + output VXCDINIT; + output VXCDNH11; + output VXCDNH10; + output VXCDNH9; + output VXCDNH8; + output VXCDNH7; + output VXCDNH6; + output VXCDNH5; + output VXCDNH4; + output VXCDNH3; + output VXCDNH2; + output VXCDNH1; + output VXCDNH0; + output VTXCRRE; + input VXD31; + input VXD30; + input VXD29; + input VXD28; + input VXD27; + input VXD26; + input VXD25; + input VXD24; + input VXD23; + input VXD22; + input VXD21; + input VXD20; + input VXD19; + input VXD18; + input VXD17; + input VXD16; + input VXD15; + input VXD14; + input VXD13; + input VXD12; + input VXD11; + input VXD10; + input VXD9; + input VXD8; + input VXD7; + input VXD6; + input VXD5; + input VXD4; + input VXD3; + input VXD2; + input VXD1; + input VXD0; + input VXDP3; + input VXDP2; + input VXDP1; + input VXDP0; + input VXEOP; + input VXEOPN; + output VXRDY; + input VXSOP; + input VXVD; + output TESTOUT7; + output TESTOUT6; + output TESTOUT5; + output TESTOUT4; + output TESTOUT3; + output TESTOUT2; + output TESTOUT1; + output TESTOUT0; + input REFCLKNA; + (* iopad_external_pin *) + input S0REFCKN; + (* iopad_external_pin *) + input S0REFCKP; + (* iopad_external_pin *) + input S0REFRET; + (* iopad_external_pin *) + input S0REXT; + (* iopad_external_pin *) + input S0RXN; + (* iopad_external_pin *) + input S0RXP; + (* iopad_external_pin *) + output S0TXN; + (* iopad_external_pin *) + output S0TXP; + input CLKREQI; + output CLKREQO; + output CLKREQOE; + input SCANCLK; + input SCANRST; + input OPCGLDCK; + input ALTCLKIN; +endmodule + +module PLL_CORE (...); + parameter BW_CTL_BIAS = "0b0101"; + parameter CLKOP_TRIM = "0b0000"; + parameter CLKOS_TRIM = "0b0000"; + parameter CLKOS2_TRIM = "0b0000"; + parameter CLKOS3_TRIM = "0b0000"; + parameter CLKOS4_TRIM = "0b0000"; + parameter CLKOS5_TRIM = "0b0000"; + parameter CRIPPLE = "5P"; + parameter CSET = "40P"; + parameter DELAY_CTRL = "200PS"; + parameter DELA = "0"; + parameter DELB = "0"; + parameter DELC = "0"; + parameter DELD = "0"; + parameter DELE = "0"; + parameter DELF = "0"; + parameter DIRECTION = "DISABLED"; + parameter DIVA = "0"; + parameter DIVB = "0"; + parameter DIVC = "0"; + parameter DIVD = "0"; + parameter DIVE = "0"; + parameter DIVF = "0"; + parameter DYN_SEL = "0b000"; + parameter DYN_SOURCE = "STATIC"; + parameter ENCLK_CLKOP = "DISABLED"; + parameter ENCLK_CLKOS = "DISABLED"; + parameter ENCLK_CLKOS2 = "DISABLED"; + parameter ENCLK_CLKOS3 = "DISABLED"; + parameter ENCLK_CLKOS4 = "DISABLED"; + parameter ENCLK_CLKOS5 = "DISABLED"; + parameter ENABLE_SYNC = "DISABLED"; + parameter FAST_LOCK_EN = "ENABLED"; + parameter V2I_1V_EN = "DISABLED"; + parameter FBK_CUR_BLE = "0b00000000"; + parameter FBK_EDGE_SEL = "POSITIVE"; + parameter FBK_IF_TIMING_CTL = "0b00"; + parameter FBK_INTEGER_MODE = "DISABLED"; + parameter FBK_MASK = "0b00001000"; + parameter FBK_MMD_DIG = "8"; + parameter FBK_MMD_PULS_CTL = "0b0000"; + parameter FBK_MODE = "0b00"; + parameter FBK_PI_BYPASS = "NOT_BYPASSED"; + parameter FBK_PI_RC = "0b1100"; + parameter FBK_PR_CC = "0b0000"; + parameter FBK_PR_IC = "0b1000"; + parameter FLOAT_CP = "DISABLED"; + parameter FLOCK_CTRL = "2X"; + parameter FLOCK_EN = "ENABLED"; + parameter FLOCK_SRC_SEL = "REFCLK"; + parameter FORCE_FILTER = "DISABLED"; + parameter I_CTRL = "10UA"; + parameter IPI_CMP = "0b1000"; + parameter IPI_CMPN = "0b0011"; + parameter IPI_COMP_EN = "DISABLED"; + parameter IPP_CTRL = "0b1000"; + parameter IPP_SEL = "0b1111"; + parameter KP_VCO = "0b11001"; + parameter LDT_INT_LOCK_STICKY = "DISABLED"; + parameter LDT_LOCK = "1536CYC"; + parameter LDT_LOCK_SEL = "U_FREQ"; + parameter LEGACY_ATT = "DISABLED"; + parameter LOAD_REG = "DISABLED"; + parameter OPENLOOP_EN = "DISABLED"; + parameter PHIA = "0"; + parameter PHIB = "0"; + parameter PHIC = "0"; + parameter PHID = "0"; + parameter PHIE = "0"; + parameter PHIF = "0"; + parameter PLLPDN_EN = "DISABLED"; + parameter PLLPD_N = "UNUSED"; + parameter PLLRESET_ENA = "DISABLED"; + parameter REF_INTEGER_MODE = "DISABLED"; + parameter REF_MASK = "0b00000000"; + parameter REF_MMD_DIG = "8"; + parameter REF_MMD_IN = "0b00001000"; + parameter REF_MMD_PULS_CTL = "0b0000"; + parameter REF_TIMING_CTL = "0b00"; + parameter REFIN_RESET = "SET"; + parameter RESET_LF = "DISABLED"; + parameter ROTATE = "DISABLED"; + parameter SEL_OUTA = "DISABLED"; + parameter SEL_OUTB = "DISABLED"; + parameter SEL_OUTC = "DISABLED"; + parameter SEL_OUTD = "DISABLED"; + parameter SEL_OUTE = "DISABLED"; + parameter SEL_OUTF = "DISABLED"; + parameter SLEEP = "DISABLED"; + parameter SSC_DITHER = "DISABLED"; + parameter SSC_EN_CENTER_IN = "DOWN_TRIANGLE"; + parameter SSC_EN_SDM = "DISABLED"; + parameter SSC_EN_SSC = "DISABLED"; + parameter SSC_F_CODE = "0b000000000000000"; + parameter SSC_N_CODE = "0b000010100"; + parameter SSC_ORDER = "SDM_ORDER2"; + parameter SSC_PI_BYPASS = "NOT_BYPASSED"; + parameter SSC_REG_WEIGHTING_SEL = "0b000"; + parameter SSC_SQUARE_MODE = "DISABLED"; + parameter SSC_STEP_IN = "0b0000000"; + parameter SSC_TBASE = "0b000000000000"; + parameter STDBY_ATT = "DISABLED"; + parameter TRIMOP_BYPASS_N = "BYPASSED"; + parameter TRIMOS_BYPASS_N = "BYPASSED"; + parameter TRIMOS2_BYPASS_N = "BYPASSED"; + parameter TRIMOS3_BYPASS_N = "BYPASSED"; + parameter TRIMOS4_BYPASS_N = "BYPASSED"; + parameter TRIMOS5_BYPASS_N = "BYPASSED"; + parameter V2I_KVCO_SEL = "85"; + parameter V2I_PP_ICTRL = "0b00110"; + parameter V2I_PP_RES = "10K"; + parameter CLKMUX_FB = "CMUX_CLKOP"; + parameter SEL_FBK = "DIVA"; + parameter DIV_DEL = "0b0000001"; + parameter PHASE_SEL_DEL = "0b000"; + parameter PHASE_SEL_DEL_P1 = "0b000"; + parameter EXTERNAL_DIVIDE_FACTOR = "0"; + input CIBDIR; + input CIBDSEL2; + input CIBDSEL1; + input CIBDSEL0; + input CIBLDREG; + input CIBROT; + output CLKOP; + output CLKOS; + output CLKOS2; + output CLKOS3; + output CLKOS4; + output CLKOS5; + input ENEXT; + input ENCLKOP; + input ENCLKOS; + input ENCLKOS2; + input ENCLKOS3; + input ENCLKOS4; + input ENCLKOS5; + input FBKCK; + output INTFBK5; + output INTFBK4; + output INTFBK3; + output INTFBK2; + output INTFBK1; + output INTFBK0; + output INTLOCK; + input LEGACY; + output LEGRDYN; + input LMMICLK; + input LMMIOFFSET6; + input LMMIOFFSET5; + input LMMIOFFSET4; + input LMMIOFFSET3; + input LMMIOFFSET2; + input LMMIOFFSET1; + input LMMIOFFSET0; + output LMMIRDATA7; + output LMMIRDATA6; + output LMMIRDATA5; + output LMMIRDATA4; + output LMMIRDATA3; + output LMMIRDATA2; + output LMMIRDATA1; + output LMMIRDATA0; + output LMMIRDATAVALID; + output LMMIREADY; + input LMMIREQUEST; + input LMMIRESETN; + input LMMIWDATA7; + input LMMIWDATA6; + input LMMIWDATA5; + input LMMIWDATA4; + input LMMIWDATA3; + input LMMIWDATA2; + input LMMIWDATA1; + input LMMIWDATA0; + input LMMIWRRDN; + output LOCK; + output PFDDN; + output PFDUP; + input PLLRESET; + input REFCK; + input STDBY; + input ZRSEL3; + output REFMUXCK; + input PLLPDN; + output REGQA; + output REGQB; + output REGQB1; + output CLKOUTDL; + input ROTDEL; + input DIRDEL; + input ROTDELP1; + input GRAYTEST4; + input GRAYTEST3; + input GRAYTEST2; + input GRAYTEST1; + input GRAYTEST0; + input BINTEST1; + input BINTEST0; + input DIRDELP1; + input GRAYACT4; + input GRAYACT3; + input GRAYACT2; + input GRAYACT1; + input GRAYACT0; + input BINACT1; + input BINACT0; + input OPCGLDCK; + input SCANRST; + input SCANCLK; +endmodule + +module PREADD9_CORE (...); + parameter SIGNEDSTATIC_EN = "DISABLED"; + parameter SUBSTRACT_EN = "SUBTRACTION"; + parameter CSIGNED = "DISABLED"; + parameter BSIGNED_OPERAND_EN = "DISABLED"; + parameter BYPASS_PREADD9 = "USED"; + parameter REGBYPSBR0 = "REGISTER"; + parameter REGBYPSBR1 = "BYPASS"; + parameter REGBYPSBL = "REGISTER"; + parameter SHIFTBR = "REGISTER"; + parameter SHIFTBL = "REGISTER"; + parameter GSR = "ENABLED"; + parameter PREADDCAS_EN = "DISABLED"; + parameter SR_18BITSHIFT_EN = "DISABLED"; + parameter OPC = "INPUT_B_AS_PREADDER_OPERAND"; + parameter RESET = "SYNC"; + input B8; + input B7; + input B6; + input B5; + input B4; + input B3; + input B2; + input B1; + input B0; + input BSIGNED; + input C9; + input C8; + input C7; + input C6; + input C5; + input C4; + input C3; + input C2; + input C1; + input C0; + input BRS18; + input BRS17; + input BRS16; + input BRS15; + input BRS14; + input BRS13; + input BRS12; + input BRS11; + input BRS10; + input BRS28; + input BRS27; + input BRS26; + input BRS25; + input BRS24; + input BRS23; + input BRS22; + input BRS21; + input BRS20; + input BLS18; + input BLS17; + input BLS16; + input BLS15; + input BLS14; + input BLS13; + input BLS12; + input BLS11; + input BLS10; + input BLS28; + input BLS27; + input BLS26; + input BLS25; + input BLS24; + input BLS23; + input BLS22; + input BLS21; + input BLS20; + input BRSS1; + input BRSS2; + input BLSS1; + input BLSS2; + input PRCASIN; + input CLK; + input RSTB; + input CEB; + input RSTCL; + input CECL; + output BRSO8; + output BRSO7; + output BRSO6; + output BRSO5; + output BRSO4; + output BRSO3; + output BRSO2; + output BRSO1; + output BRSO0; + output BLSO8; + output BLSO7; + output BLSO6; + output BLSO5; + output BLSO4; + output BLSO3; + output BLSO2; + output BLSO1; + output BLSO0; + output BRSOSGND; + output BLSOSGND; + output PRCASOUT; + output BR8; + output BR7; + output BR6; + output BR5; + output BR4; + output BR3; + output BR2; + output BR1; + output BR0; + output BRSIGNED; +endmodule + +module REFMUX_CORE (...); + parameter REFSEL_ATT = "MC1"; + parameter SEL1 = "SELECT_REFCLK1"; + parameter SEL_REF2 = "REFCLK2_0"; + parameter SEL_REF1 = "REFCLK1_0"; + output REFCK; + output ZRSEL3; + input REFSEL; + input REFCLK17; + input REFCLK16; + input REFCLK15; + input REFCLK14; + input REFCLK13; + input REFCLK12; + input REFCLK11; + input REFCLK10; + input REFCLK27; + input REFCLK26; + input REFCLK25; + input REFCLK24; + input REFCLK23; + input REFCLK22; + input REFCLK21; + input REFCLK20; +endmodule + +module REG18_CORE (...); + parameter REGBYPS = "REGISTER"; + parameter GSR = "ENABLED"; + parameter RESET = "SYNC"; + input PM17; + input PM16; + input PM15; + input PM14; + input PM13; + input PM12; + input PM11; + input PM10; + input PM9; + input PM8; + input PM7; + input PM6; + input PM5; + input PM4; + input PM3; + input PM2; + input PM1; + input PM0; + output PP17; + output PP16; + output PP15; + output PP14; + output PP13; + output PP12; + output PP11; + output PP10; + output PP9; + output PP8; + output PP7; + output PP6; + output PP5; + output PP4; + output PP3; + output PP2; + output PP1; + output PP0; + input CEP; + input RSTP; + input CLK; +endmodule + +module SEIO18_CORE (...); + parameter MIPI_ID = "0"; + parameter PULLMODE = "DOWN"; + parameter MIPI = "DISABLED"; + parameter ENADC_IN = "DISABLED"; + input I; + input DOLP; + (* iopad_external_pin *) + inout B; + output O; + output INLP; + input T; + output INADC; +endmodule + +module SEIO33_CORE (...); + parameter PULLMODE = "DOWN"; + (* iopad_external_pin *) + inout B; + output O; + input I; + input T; + input I3CRESEN; + input I3CWKPU; +endmodule + +module SGMIICDR_CORE (...); + parameter GSR = "ENABLED"; + parameter DCOITUNE4LSB = "0_PERCENT"; + parameter DCOCTLGI = "0_PERCENT"; + parameter DCOSTEP = "100_PERCENT"; + parameter DCOCALDIV = "100_PERCENT"; + parameter DCOIOSTUNE = "0_PERCENT"; + parameter DCOFLTDAC = "80MHZ"; + parameter DCOSTARTVAL = "NOMINAL"; + parameter DCONUOFLSB = "NEG_60_PERCENT"; + parameter RPWDNB = "POWER_UP"; + parameter CDR_CNT4SEL = "BYPASSED"; + parameter DCOITUNE = "100_PERCENT"; + parameter BAND_THRESHOLD = "0b000000"; + parameter AUTO_FACQ_EN = "ENABLED"; + parameter AUTO_CALIB_EN = "ENABLED"; + parameter CDR_LOL_SET = "1000_PPM"; + parameter FC2DCO_FLOOP = "DISABLED"; + parameter FC2DCO_DLOOP = "DISABLED"; + parameter CALIB_TIME_SEL = "24_CYC"; + parameter CALIB_CK_MODE = "BY_2"; + parameter BAND_CALIB_MODE = "256_FDBK_CLK_CYC"; + parameter REG_BAND_SEL = "0b00000"; + parameter REG_BAND_OFFSET = "0b0000"; + parameter REG_IDAC_SEL = "0b00000000"; + parameter LB_CTL = "DISABLED"; + parameter REG_IDAC_EN = "DISABLED"; + parameter ATDCFG = "0_PS"; + parameter ATDDLY = "0_PS"; + parameter BDAVOID_ENB = "ENABLED"; + parameter BYPASSATD = "NOT_BYPASS"; + parameter DCOIUPDNX2 = "1X"; + parameter IDAC_EN = "DISABLED"; + parameter FB_CLK_DIV = "0b010"; + parameter EN_RECALIB = "ENABLED"; + input DCALIRST; + input DFACQRST; + input RRST; + input SPCLK; + output SRCLK; + output SRXD9; + output SRXD8; + output SRXD7; + output SRXD6; + output SRXD5; + output SRXD4; + output SRXD3; + output SRXD2; + output SRXD1; + output SRXD0; + input LMMICLK; + input LMMIREQUEST; + input LMMIWRRDN; + input LMMIOFFSET3; + input LMMIOFFSET2; + input LMMIOFFSET1; + input LMMIOFFSET0; + input LMMIWDATA7; + input LMMIWDATA6; + input LMMIWDATA5; + input LMMIWDATA4; + input LMMIWDATA3; + input LMMIWDATA2; + input LMMIWDATA1; + input LMMIWDATA0; + output LMMIRDATA7; + output LMMIRDATA6; + output LMMIRDATA5; + output LMMIRDATA4; + output LMMIRDATA3; + output LMMIRDATA2; + output LMMIRDATA1; + output LMMIRDATA0; + output LMMIRDATAVALID; + output LMMIREADY; + input LMMIRESETN; + input RSTBFBW; + input RSTBRXF; + input SGMIIIN; + input SREFCLK; + output CDRLOL; + input OPCGLOADCLK; + input SCANCLK; + input SCANRST; +endmodule + +module GSR (...); + parameter SYNCMODE = "ASYNC"; + input GSR_N; + input CLK; +endmodule + +module DCC (...); + parameter DCCEN = "0"; + input CE; + input CLKI; + output CLKO; +endmodule + +module DCS (...); + parameter DCSMODE = "GND"; + input CLK0; + input CLK1; + output DCSOUT; + input SEL; + input SELFORCE; +endmodule + +module GSR_CORE (...); + parameter GSR = "ENABLED"; + parameter GSR_SYNC = "ASYNC"; + output GSROUT; + input CLK; + input GSR_N; +endmodule + +module PCLKDIV (...); + parameter DIV_PCLKDIV = "X1"; + parameter GSR = "ENABLED"; + parameter TESTEN_PCLKDIV = "0"; + parameter TESTMODE_PCLKDIV = "0"; + input CLKIN; + output CLKOUT; + input LSRPDIV; + input PCLKDIVTESTINP2; + input PCLKDIVTESTINP1; + input PCLKDIVTESTINP0; +endmodule + +(* keep *) +module PUR (...); + parameter RST_PULSE = "1"; + input PUR; +endmodule + +module PCLKDIVSP (...); + parameter DIV_PCLKDIV = "X1"; + parameter GSR = "ENABLED"; + input CLKIN; + output CLKOUT; + input LSRPDIV; +endmodule + diff --git a/techlibs/nexus/dsp_map.v b/techlibs/nexus/dsp_map.v new file mode 100644 index 000000000..b12528309 --- /dev/null +++ b/techlibs/nexus/dsp_map.v @@ -0,0 +1,79 @@ +module \$__NX_MUL36X36 (input [35:0] A, input [35:0] B, output [71:0] Y); + + parameter A_WIDTH = 36; + parameter B_WIDTH = 36; + parameter Y_WIDTH = 72; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT36X36 #( + .REGINPUTA("BYPASS"), + .REGINPUTB("BYPASS"), + .REGOUTPUT("BYPASS") + ) _TECHMAP_REPLACE_ ( + .A(A), .B(B), + .SIGNEDA(A_SIGNED ? 1'b1 : 1'b0), + .SIGNEDB(B_SIGNED ? 1'b1 : 1'b0), + .Z(Y) + ); +endmodule + +module \$__NX_MUL36X18 (input [35:0] A, input [17:0] B, output [53:0] Y); + + parameter A_WIDTH = 36; + parameter B_WIDTH = 18; + parameter Y_WIDTH = 54; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT18X36 #( + .REGINPUTA("BYPASS"), + .REGINPUTB("BYPASS"), + .REGOUTPUT("BYPASS") + ) _TECHMAP_REPLACE_ ( + .A(B), .B(A), + .SIGNEDA(B_SIGNED ? 1'b1 : 1'b0), + .SIGNEDB(A_SIGNED ? 1'b1 : 1'b0), + .Z(Y) + ); +endmodule + +module \$__NX_MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y); + + parameter A_WIDTH = 18; + parameter B_WIDTH = 18; + parameter Y_WIDTH = 36; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT18X18 #( + .REGINPUTA("BYPASS"), + .REGINPUTB("BYPASS"), + .REGOUTPUT("BYPASS") + ) _TECHMAP_REPLACE_ ( + .A(A), .B(B), + .SIGNEDA(A_SIGNED ? 1'b1 : 1'b0), + .SIGNEDB(B_SIGNED ? 1'b1 : 1'b0), + .Z(Y) + ); +endmodule + +module \$__NX_MUL9X9 (input [8:0] A, input [8:0] B, output [17:0] Y); + + parameter A_WIDTH = 9; + parameter B_WIDTH = 9; + parameter Y_WIDTH = 18; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT9X9 #( + .REGINPUTA("BYPASS"), + .REGINPUTB("BYPASS"), + .REGOUTPUT("BYPASS") + ) _TECHMAP_REPLACE_ ( + .A(A), .B(B), + .SIGNEDA(A_SIGNED ? 1'b1 : 1'b0), + .SIGNEDB(B_SIGNED ? 1'b1 : 1'b0), + .Z(Y) + ); +endmodule diff --git a/techlibs/nexus/latches_map.v b/techlibs/nexus/latches_map.v new file mode 100644 index 000000000..c28f88cf7 --- /dev/null +++ b/techlibs/nexus/latches_map.v @@ -0,0 +1,11 @@ +module \$_DLATCH_N_ (E, D, Q); + wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; + input E, D; + output Q = !E ? D : Q; +endmodule + +module \$_DLATCH_P_ (E, D, Q); + wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; + input E, D; + output Q = E ? D : Q; +endmodule diff --git a/techlibs/nexus/lutrams.txt b/techlibs/nexus/lutrams.txt new file mode 100644 index 000000000..2568b9998 --- /dev/null +++ b/techlibs/nexus/lutrams.txt @@ -0,0 +1,26 @@ +bram $__NEXUS_DPR16X4 + init 1 + abits 4 + dbits 4 + groups 2 + ports 1 1 + wrmode 0 1 + enable 0 1 + transp 0 0 + clocks 0 1 + clkpol 0 2 +endbram + +# The syn_* attributes are described in: +# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx +attr_icase 1 + +match $__NEXUS_DPR16X4 + attribute !syn_ramstyle syn_ramstyle=auto syn_ramstyle=distributed + attribute !syn_romstyle syn_romstyle=auto + attribute !ram_block + attribute !rom_block + attribute !logic_block + make_outreg + min wports 1 +endmatch diff --git a/techlibs/nexus/lutrams_map.v b/techlibs/nexus/lutrams_map.v new file mode 100644 index 000000000..0910664ce --- /dev/null +++ b/techlibs/nexus/lutrams_map.v @@ -0,0 +1,34 @@ +module \$__NEXUS_DPR16X4 (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); + parameter [63:0] INIT = 64'b0; + parameter CLKPOL2 = 1; + input CLK1; + + input [3:0] A1ADDR; + output [3:0] A1DATA; + + input [3:0] B1ADDR; + input [3:0] B1DATA; + input B1EN; + + + wire wck; + + generate + if (CLKPOL2) + assign wck = CLK1; + else + INV wck_inv_i (.A(CLK1), .Z(wck)); + endgenerate + + DPR16X4 #( + .INITVAL($sformatf("0x%08x", INIT)) + ) _TECHMAP_REPLACE_ ( + .RAD(A1ADDR), + .DO(A1DATA), + + .WAD(B1ADDR), + .DI(B1DATA), + .WCK(CLK1), + .WRE(B1EN) + ); +endmodule diff --git a/techlibs/nexus/parse_init.vh b/techlibs/nexus/parse_init.vh new file mode 100644 index 000000000..0f9ab7897 --- /dev/null +++ b/techlibs/nexus/parse_init.vh @@ -0,0 +1,33 @@ +function [15:0] parse_init; + input [((2+(16/4))*8)-1:0] init; + reg [7:0] c; + integer i; + begin + for (i = 0; i < (16/4); i = i + 1) begin + c = init[(i * 8) +: 8]; + if (c >= "0" && c <= "9") + parse_init[(i * 4) +: 4] = (c - "0"); + else if (c >= "A" && c <= "F") + parse_init[(i * 4) +: 4] = (c - "A") + 10; + else if (c >= "a" && c <= "f") + parse_init[(i * 4) +: 4] = (c - "a") + 10; + end + end +endfunction + +function [63:0] parse_init_64; + input [((2+(64/4))*8)-1:0] init; + reg [7:0] c; + integer i; + begin + for (i = 0; i < (64/4); i = i + 1) begin + c = init[(i * 8) +: 8]; + if (c >= "0" && c <= "9") + parse_init_64[(i * 4) +: 4] = (c - "0"); + else if (c >= "A" && c <= "F") + parse_init_64[(i * 4) +: 4] = (c - "A") + 10; + else if (c >= "a" && c <= "f") + parse_init_64[(i * 4) +: 4] = (c - "a") + 10; + end + end +endfunction diff --git a/techlibs/nexus/synth_nexus.cc b/techlibs/nexus/synth_nexus.cc new file mode 100644 index 000000000..9eabbace7 --- /dev/null +++ b/techlibs/nexus/synth_nexus.cc @@ -0,0 +1,408 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 David Shah <dave@ds0.me> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct SynthNexusPass : public ScriptPass +{ + SynthNexusPass() : ScriptPass("synth_nexus", "synthesis for Lattice Nexus FPGAs") { } + + void on_register() override + { + RTLIL::constpad["synth_nexus.abc9.W"] = "300"; + } + + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synth_nexus [options]\n"); + log("\n"); + log("This command runs synthesis for Lattice Nexus FPGAs.\n"); + log("\n"); + log(" -top <module>\n"); + log(" use the specified module as top module\n"); + log("\n"); + log(" -family <device>\n"); + log(" run synthesis for the specified Nexus device\n"); + log(" supported values: lifcl, lfd2nx\n"); + log("\n"); + log(" -json <file>\n"); + log(" write the design to the specified JSON file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -vm <file>\n"); + log(" write the design to the specified structural Verilog file. writing of\n"); + log(" an output file is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -run <from_label>:<to_label>\n"); + log(" only run the commands between the labels (see below). an empty\n"); + log(" from label is synonymous to 'begin', and empty to label is\n"); + log(" synonymous to the end of the command list.\n"); + log("\n"); + log(" -noflatten\n"); + log(" do not flatten design before synthesis\n"); + log("\n"); + log(" -dff\n"); + log(" run 'abc'/'abc9' with -dff option\n"); + log("\n"); + log(" -retime\n"); + log(" run 'abc' with '-dff -D 1' options\n"); + log("\n"); + log(" -noccu2\n"); + log(" do not use CCU2 cells in output netlist\n"); + log("\n"); + log(" -nodffe\n"); + log(" do not use flipflops with CE in output netlist\n"); + log("\n"); + log(" -nobram\n"); + log(" do not use block RAM cells in output netlist\n"); + log("\n"); + log(" -nolutram\n"); + log(" do not use LUT RAM cells in output netlist\n"); + log("\n"); + log(" -nowidelut\n"); + log(" do not use PFU muxes to implement LUTs larger than LUT4s\n"); + log("\n"); + log(" -noiopad\n"); + log(" do not insert IO buffers\n"); + log("\n"); + log(" -nodsp\n"); + log(" do not infer DSP multipliers\n"); + log("\n"); + log(" -abc9\n"); + log(" use new ABC9 flow (EXPERIMENTAL)\n"); + log("\n"); + log("The following commands are executed by this synthesis command:\n"); + help_script(); + log("\n"); + } + + string top_opt, json_file, vm_file, family; + bool noccu2, nodffe, nobram, nolutram, nowidelut, noiopad, nodsp, flatten, dff, retime, abc9; + + void clear_flags() override + { + top_opt = "-auto-top"; + family = "lifcl"; + json_file = ""; + vm_file = ""; + noccu2 = false; + nodffe = false; + nobram = false; + nolutram = false; + nowidelut = false; + noiopad = false; + nodsp = false; + flatten = true; + dff = false; + retime = false; + } + + void execute(std::vector<std::string> args, RTLIL::Design *design) override + { + string run_from, run_to; + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_opt = "-top " + args[++argidx]; + continue; + } + if (args[argidx] == "-json" && argidx+1 < args.size()) { + json_file = args[++argidx]; + continue; + } + if (args[argidx] == "-vm" && argidx+1 < args.size()) { + vm_file = args[++argidx]; + continue; + } + if (args[argidx] == "-run" && argidx+1 < args.size()) { + size_t pos = args[argidx+1].find(':'); + if (pos == std::string::npos) + break; + run_from = args[++argidx].substr(0, pos); + run_to = args[argidx].substr(pos+1); + continue; + } + if ((args[argidx] == "-family") && argidx+1 < args.size()) { + family = args[++argidx]; + continue; + } + if (args[argidx] == "-flatten") { + flatten = true; + continue; + } + if (args[argidx] == "-noflatten") { + flatten = false; + continue; + } + if (args[argidx] == "-dff") { + dff = true; + continue; + } + if (args[argidx] == "-nodsp") { + nodsp = true; + continue; + } + if (args[argidx] == "-retime") { + retime = true; + continue; + } + if (args[argidx] == "-noccu2") { + noccu2 = true; + continue; + } + if (args[argidx] == "-nodffe") { + nodffe = true; + continue; + } + if (args[argidx] == "-nobram") { + nobram = true; + continue; + } + if (args[argidx] == "-nolutram") { + nolutram = true; + continue; + } + if (args[argidx] == "-nowidelut") { + nowidelut = true; + continue; + } + if (args[argidx] == "-noiopad") { + noiopad = true; + continue; + } + if (args[argidx] == "-abc9") { + abc9 = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (!design->full_selection()) + log_cmd_error("This command only operates on fully selected designs!\n"); + + if (abc9 && retime) + log_cmd_error("-retime option not currently compatible with -abc9!\n"); + + log_header(design, "Executing SYNTH_NEXUS pass.\n"); + log_push(); + + run_script(design, run_from, run_to); + + log_pop(); + } + + struct DSPRule { + int a_maxwidth; + int b_maxwidth; + int a_minwidth; + int b_minwidth; + std::string prim; + }; + + const std::vector<DSPRule> dsp_rules = { + {36, 36, 22, 22, "$__NX_MUL36X36"}, + {36, 18, 22, 10, "$__NX_MUL36X18"}, + {18, 18, 10, 4, "$__NX_MUL18X18"}, + {18, 18, 4, 10, "$__NX_MUL18X18"}, + { 9, 9, 4, 4, "$__NX_MUL9X9"}, + }; + + void script() override + { + + if (family != "lifcl" && family != "lfd2nx") + log_cmd_error("Invalid Nexus -family setting: '%s'.\n", family.c_str()); + + if (check_label("begin")) + { + run("read_verilog -lib -specify +/nexus/cells_sim.v +/nexus/cells_xtra.v"); + run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str())); + } + + if (check_label("coarse")) + { + run("proc"); + if (flatten || help_mode) + run("flatten"); + run("tribuf -logic"); + run("deminout"); + run("opt_expr"); + run("opt_clean"); + run("check"); + run("opt -nodffe -nosdff"); + run("fsm"); + run("opt"); + run("wreduce"); + run("peepopt"); + run("opt_clean"); + run("share"); + run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4"); + run("opt_expr"); + run("opt_clean"); + + if (help_mode) { + run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)"); + run("techmap -map +/nexus/dsp_map.v", "(unless -nodsp)"); + } else if (!nodsp) { + for (const auto &rule : dsp_rules) { + run(stringf("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=%d -D DSP_B_MAXWIDTH=%d -D DSP_A_MINWIDTH=%d -D DSP_B_MINWIDTH=%d -D DSP_NAME=%s", + rule.a_maxwidth, rule.b_maxwidth, rule.a_minwidth, rule.b_minwidth, rule.prim.c_str())); + run("chtype -set $mul t:$__soft_mul"); + } + run("techmap -map +/nexus/dsp_map.v"); + } + + run("alumacc"); + run("opt"); + run("memory -nomap"); + run("opt_clean"); + } + + if (!nobram && check_label("map_bram", "(skip if -nobram)")) + { + run("memory_bram -rules +/nexus/brams.txt"); + run("setundef -zero -params t:$__NX_PDP16K"); + run("techmap -map +/nexus/brams_map.v"); + } + + if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) + { + run("memory_bram -rules +/nexus/lutrams.txt"); + run("setundef -zero -params t:$__NEXUS_DPR16X4"); + run("techmap -map +/nexus/lutrams_map.v"); + } + + if (check_label("map_ffram")) + { + run("opt -fast -mux_undef -undriven -fine"); + run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block " + "-attr syn_ramstyle=auto -attr syn_ramstyle=registers " + "-attr syn_romstyle=auto -attr syn_romstyle=logic"); + run("opt -undriven -fine"); + } + + if (check_label("map_gates")) + { + if (noccu2) + run("techmap"); + else + run("techmap -map +/techmap.v -map +/nexus/arith_map.v"); + if (help_mode || !noiopad) + run("iopadmap -bits -outpad OB I:O -inpad IB O:I -toutpad $__NX_TOUTPAD OE:I:O -tinoutpad $__NX_TINOUTPAD OE:O:I:B A:top", "(skip if '-noiopad')"); + run("opt -fast"); + if (retime || help_mode) + run("abc -dff -D 1", "(only if -retime)"); + } + + if (check_label("map_ffs")) + { + run("opt_clean"); + std::string dfflegalize_args = " -cell $_DFF_P_ 01 -cell $_DFF_PP?_ r -cell $_SDFF_PP?_ r -cell $_DLATCH_?_ x"; + if (help_mode) { + dfflegalize_args += " [-cell $_DFFE_PP_ 01 -cell $_DFFE_PP?P_ r -cell $_SDFFE_PP?P_ r]"; + } else if (!nodffe) { + dfflegalize_args += " -cell $_DFFE_PP_ 01 -cell $_DFFE_PP?P_ r -cell $_SDFFE_PP?P_ r"; + } + run("dfflegalize" + dfflegalize_args, "($_*DFFE_* only if not -nodffe)"); + if ((abc9 && dff) || help_mode) + run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "(only if -abc9 and -dff"); + run("techmap -D NO_LUT -map +/nexus/cells_map.v"); + run("opt_expr -undriven -mux_undef"); + run("simplemap"); + run("attrmvcp -copy -attr syn_useioff"); + run("opt_clean"); + } + + if (check_label("map_luts")) + { + run("techmap -map +/nexus/latches_map.v"); + + if (abc9) { + std::string abc9_opts; + if (nowidelut) + abc9_opts += " -maxlut 4"; + std::string k = "synth_nexus.abc9.W"; + if (active_design && active_design->scratchpad.count(k)) + abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str()); + else + abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str()); + if (nowidelut) + abc9_opts += " -maxlut 4"; + if (dff) + abc9_opts += " -dff"; + run("abc9" + abc9_opts); + } else { + std::string abc_args = " -dress"; + if (nowidelut) + abc_args += " -lut 4"; + else + abc_args += " -lut 4:5"; + if (dff) + abc_args += " -dff"; + run("abc" + abc_args); + } + run("clean"); + } + + if (check_label("map_cells")) + { + run("techmap -map +/nexus/cells_map.v"); + + // This is needed for Radiant, but perhaps not optimal for nextpnr... + run("setundef -zero"); + + run("hilomap -singleton -hicell VHI Z -locell VLO Z"); + run("clean"); + } + + if (check_label("check")) + { + run("autoname"); + run("hierarchy -check"); + run("stat"); + run("check -noinit"); + } + + if (check_label("json")) + { + if (!json_file.empty() || help_mode) + run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str())); + } + + if (check_label("vm")) + { + if (!vm_file.empty() || help_mode) + run(stringf("write_verilog %s", help_mode ? "<file-name>" : vm_file.c_str())); + } + } +} SynthNexusPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/sf2/Makefile.inc b/techlibs/sf2/Makefile.inc index cc3054ace..cade49f37 100644 --- a/techlibs/sf2/Makefile.inc +++ b/techlibs/sf2/Makefile.inc @@ -1,6 +1,5 @@ OBJS += techlibs/sf2/synth_sf2.o -OBJS += techlibs/sf2/sf2_iobs.o $(eval $(call add_share_file,share/sf2,techlibs/sf2/arith_map.v)) $(eval $(call add_share_file,share/sf2,techlibs/sf2/cells_map.v)) diff --git a/techlibs/sf2/cells_map.v b/techlibs/sf2/cells_map.v index 9fddc0f41..88782995e 100644 --- a/techlibs/sf2/cells_map.v +++ b/techlibs/sf2/cells_map.v @@ -1,59 +1,27 @@ -module \$_DFF_N_ (input D, C, output Q); - SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(1'b1), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +module \$_DFFE_PN0P_ (input D, C, R, E, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(E), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); endmodule -module \$_DFF_P_ (input D, C, output Q); - SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(1'b1), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +module \$_DFFE_PN1P_ (input D, C, R, E, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(E), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); endmodule -module \$_DFF_NN0_ (input D, C, R, output Q); - SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +module \$_SDFFCE_PN0P_ (input D, C, R, E, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(E), .ALn(1'b1), .ADn(1'b0), .SLn(R), .SD(1'b0), .LAT(1'b0), .Q(Q)); endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); - SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +module \$_SDFFCE_PN1P_ (input D, C, R, E, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(E), .ALn(1'b1), .ADn(1'b0), .SLn(R), .SD(1'b1), .LAT(1'b0), .Q(Q)); endmodule -module \$_DFF_NP0_ (input D, C, R, output Q); - SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(!R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +module \$_DLATCH_PN0_ (input D, R, E, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(E), .EN(1'b1), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b1), .Q(Q)); endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); - SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(!R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +module \$_DLATCH_PN1_ (input D, R, E, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(E), .EN(1'b1), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b1), .Q(Q)); endmodule -module \$_DFF_PN0_ (input D, C, R, output Q); - SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); -endmodule - -module \$_DFF_PN1_ (input D, C, R, output Q); - SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); -endmodule - -module \$_DFF_PP0_ (input D, C, R, output Q); - SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(!R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); -endmodule - -module \$_DFF_PP1_ (input D, C, R, output Q); - SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(!R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); -endmodule - -// module \$_DFFE_NN_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule -// module \$_DFFE_PN_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule -// -// module \$_DFFE_NP_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule -// module \$_DFFE_PP_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule -// -// module \$__DFFE_NN0 (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule -// module \$__DFFE_NN1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule -// module \$__DFFE_PN0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule -// module \$__DFFE_PN1 (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule -// -// module \$__DFFE_NP0 (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule -// module \$__DFFE_NP1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule -// module \$__DFFE_PP0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule -// module \$__DFFE_PP1 (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule - `ifndef NO_LUT module \$lut (A, Y); parameter WIDTH = 0; diff --git a/techlibs/sf2/cells_sim.v b/techlibs/sf2/cells_sim.v index c62748b11..eff57a655 100644 --- a/techlibs/sf2/cells_sim.v +++ b/techlibs/sf2/cells_sim.v @@ -1,7 +1,6 @@ // https://coredocs.s3.amazonaws.com/Libero/12_0_0/Tool/sf2_mlg.pdf module ADD2 ( - input A, B, output Y ); @@ -76,6 +75,7 @@ endmodule module CLKINT ( input A, + (* clkbuf_driver *) output Y ); assign Y = A; @@ -83,6 +83,7 @@ endmodule module CLKINT_PRESERVE ( input A, + (* clkbuf_driver *) output Y ); assign Y = A; @@ -90,6 +91,7 @@ endmodule module GCLKINT ( input A, EN, + (* clkbuf_driver *) output Y ); assign Y = A & EN; @@ -97,6 +99,7 @@ endmodule module RCLKINT ( input A, + (* clkbuf_driver *) output Y ); assign Y = A; @@ -104,6 +107,7 @@ endmodule module RGCLKINT ( input A, EN, + (* clkbuf_driver *) output Y ); assign Y = A & EN; @@ -113,6 +117,7 @@ module SLE ( output Q, input ADn, input ALn, + (* clkbuf_sink *) input CLK, input D, input LAT, @@ -155,9 +160,41 @@ endmodule // module SYSRESET // module SYSCTRL_RESET_STATUS // module LIVE_PROBE_FB -// module GCLKBUF -// module GCLKBUF_DIFF -// module GCLKBIBUF + +(* blackbox *) +module GCLKBUF ( + (* iopad_external_pin *) + input PAD, + input EN, + (* clkbuf_driver *) + output Y +); +endmodule + +(* blackbox *) +module GCLKBUF_DIFF ( + (* iopad_external_pin *) + input PADP, + (* iopad_external_pin *) + input PADN, + input EN, + (* clkbuf_driver *) + output Y +); +endmodule + +(* blackbox *) +module GCLKBIBUF ( + input D, + input E, + input EN, + (* iopad_external_pin *) + inout PAD, + (* clkbuf_driver *) + output Y +); +endmodule + // module DFN1 // module DFN1C0 // module DFN1E1 @@ -288,38 +325,118 @@ module XOR8 ( endmodule // module UJTAG -// module BIBUF -// module BIBUF_DIFF -// module CLKBIBUF + +module BIBUF ( + input D, + input E, + (* iopad_external_pin *) + inout PAD, + output Y +); + assign PAD = E ? D : 1'bz; + assign Y = PAD; +endmodule + +(* blackbox *) +module BIBUF_DIFF ( + input D, + input E, + (* iopad_external_pin *) + inout PADP, + (* iopad_external_pin *) + inout PADN, + output Y +); +endmodule + +module CLKBIBUF ( + input D, + input E, + (* iopad_external_pin *) + inout PAD, + (* clkbuf_driver *) + output Y +); + assign PAD = E ? D : 1'bz; + assign Y = PAD; +endmodule module CLKBUF ( + (* iopad_external_pin *) input PAD, + (* clkbuf_driver *) output Y ); assign Y = PAD; endmodule -// module CLKBUF_DIFF +(* blackbox *) +module CLKBUF_DIFF ( + (* iopad_external_pin *) + input PADP, + (* iopad_external_pin *) + input PADN, + (* clkbuf_driver *) + output Y +); +endmodule module INBUF ( + (* iopad_external_pin *) input PAD, output Y ); assign Y = PAD; endmodule -// module INBUF_DIFF +(* blackbox *) +module INBUF_DIFF ( + (* iopad_external_pin *) + input PADP, + (* iopad_external_pin *) + input PADN, + output Y +); +endmodule module OUTBUF ( input D, + (* iopad_external_pin *) output PAD ); assign PAD = D; endmodule -// module OUTBUF_DIFF -// module TRIBUFF -// module TRIBUFF_DIFF +(* blackbox *) +module OUTBUF_DIFF ( + input D, + (* iopad_external_pin *) + output PADP, + (* iopad_external_pin *) + output PADN +); +endmodule + +module TRIBUFF ( + input D, + input E, + (* iopad_external_pin *) + output PAD +); + assign PAD = E ? D : 1'bz; +endmodule + +(* blackbox *) +module TRIBUFF_DIFF ( + input D, + input E, + (* iopad_external_pin *) + output PADP, + (* iopad_external_pin *) + output PADN +); +endmodule + // module DDR_IN // module DDR_OUT // module RAM1K18 diff --git a/techlibs/sf2/sf2_iobs.cc b/techlibs/sf2/sf2_iobs.cc deleted file mode 100644 index 619888d38..000000000 --- a/techlibs/sf2/sf2_iobs.cc +++ /dev/null @@ -1,197 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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 - -static void handle_iobufs(Module *module, bool clkbuf_mode) -{ - SigMap sigmap(module); - - pool<SigBit> clk_bits; - pool<SigBit> handled_io_bits; - dict<SigBit, SigBit> rewrite_bits; - vector<pair<Cell*, SigBit>> pad_bits; - - for (auto cell : module->cells()) - { - if (clkbuf_mode && cell->type == ID(SLE)) { - for (auto bit : sigmap(cell->getPort(ID::CLK))) - clk_bits.insert(bit); - } - if (cell->type.in(ID(INBUF), ID(OUTBUF), ID(TRIBUFF), ID(BIBUF), ID(CLKBUF), ID(CLKBIBUF), - ID(INBUF_DIFF), ID(OUTBUF_DIFF), ID(BIBUFF_DIFF), ID(TRIBUFF_DIFF), ID(CLKBUF_DIFF), - ID(GCLKBUF), ID(GCLKBUF_DIFF), ID(GCLKBIBUF))) { - for (auto bit : sigmap(cell->getPort(ID(PAD)))) - handled_io_bits.insert(bit); - } - } - - for (auto wire : vector<Wire*>(module->wires())) - { - if (!wire->port_input && !wire->port_output) - continue; - - for (int index = 0; index < GetSize(wire); index++) - { - SigBit bit(wire, index); - SigBit canonical_bit = sigmap(bit); - - if (handled_io_bits.count(canonical_bit)) - continue; - - if (wire->port_input && wire->port_output) - log_error("Failed to add buffer for inout port bit %s.\n", log_signal(bit)); - - IdString buf_type, buf_port; - - if (wire->port_output) { - buf_type = ID(OUTBUF); - buf_port = ID::D; - } else if (clkbuf_mode && clk_bits.count(canonical_bit)) { - buf_type = ID(CLKBUF); - buf_port = ID::Y; - } else { - buf_type = ID(INBUF); - buf_port = ID::Y; - } - - Cell *c = module->addCell(NEW_ID, buf_type); - SigBit new_bit = module->addWire(NEW_ID); - c->setPort(buf_port, new_bit); - pad_bits.push_back(make_pair(c, bit)); - rewrite_bits[canonical_bit] = new_bit; - - log("Added %s cell %s for port bit %s.\n", log_id(c->type), log_id(c), log_signal(bit)); - } - } - - auto rewrite_function = [&](SigSpec &s) { - for (auto &bit : s) { - SigBit canonical_bit = sigmap(bit); - if (rewrite_bits.count(canonical_bit)) - bit = rewrite_bits.at(canonical_bit); - } - }; - - module->rewrite_sigspecs(rewrite_function); - - for (auto &it : pad_bits) - it.first->setPort(ID(PAD), it.second); -} - -static void handle_clkint(Module *module) -{ - SigMap sigmap(module); - - pool<SigBit> clk_bits; - vector<SigBit> handled_clk_bits; - - for (auto cell : module->cells()) - { - if (cell->type == ID(SLE)) { - for (auto bit : sigmap(cell->getPort(ID::CLK))) - clk_bits.insert(bit); - } - if (cell->type.in(ID(CLKBUF), ID(CLKBIBUF), ID(CLKBUF_DIFF), ID(GCLKBUF), ID(GCLKBUF_DIFF), ID(GCLKBIBUF), - ID(CLKINT), ID(CLKINT_PRESERVE), ID(GCLKINT), ID(RCLKINT), ID(RGCLKINT))) { - for (auto bit : sigmap(cell->getPort(ID::Y))) - handled_clk_bits.push_back(bit); - } - } - - for (auto bit : handled_clk_bits) - clk_bits.erase(bit); - - for (auto cell : vector<Cell*>(module->cells())) - for (auto &conn : cell->connections()) - { - if (!cell->output(conn.first)) - continue; - - SigSpec sig = conn.second; - bool did_something = false; - - for (auto &bit : sig) { - SigBit canonical_bit = sigmap(bit); - if (clk_bits.count(canonical_bit)) { - Cell *c = module->addCell(NEW_ID, ID(CLKINT)); - SigBit new_bit = module->addWire(NEW_ID); - c->setPort(ID::A, new_bit); - c->setPort(ID::Y, bit); - log("Added %s cell %s for clock signal %s.\n", log_id(c->type), log_id(c), log_signal(bit)); - clk_bits.erase(canonical_bit); - did_something = true; - bit = new_bit; - } - } - - if (did_something) - cell->setPort(conn.first, sig); - } - - for (auto bit : clk_bits) - log_error("Failed to insert CLKINT for clock signal %s.\n", log_signal(bit)); -} - -struct Sf2IobsPass : public Pass { - Sf2IobsPass() : Pass("sf2_iobs", "SF2: insert IO buffers") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" sf2_iobs [options] [selection]\n"); - log("\n"); - log("Add SF2 I/O buffers and global buffers to top module as needed.\n"); - log("\n"); - log(" -clkbuf\n"); - log(" Insert PAD->global_net clock buffers\n"); - log("\n"); - } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE - { - bool clkbuf_mode = false; - - log_header(design, "Executing sf2_iobs pass (insert IO buffers).\n"); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - if (args[argidx] == "-clkbuf") { - clkbuf_mode = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - Module *module = design->top_module(); - - if (module == nullptr) - log_cmd_error("No top module found.\n"); - - handle_iobufs(module, clkbuf_mode); - handle_clkint(module); - } -} Sf2IobsPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc index 34a7e68be..a0061ebd0 100644 --- a/techlibs/sf2/synth_sf2.cc +++ b/techlibs/sf2/synth_sf2.cc @@ -29,7 +29,7 @@ struct SynthSf2Pass : public ScriptPass { SynthSf2Pass() : ScriptPass("synth_sf2", "synthesis for SmartFusion2 and IGLOO2 FPGAs") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -78,7 +78,7 @@ struct SynthSf2Pass : public ScriptPass string top_opt, edif_file, vlog_file, json_file; bool flatten, retime, iobs, clkbuf; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; edif_file = ""; @@ -90,7 +90,7 @@ struct SynthSf2Pass : public ScriptPass clkbuf = false; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); @@ -153,7 +153,7 @@ struct SynthSf2Pass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { if (check_label("begin")) { @@ -187,6 +187,7 @@ struct SynthSf2Pass : public ScriptPass if (check_label("map_ffs")) { + run("dfflegalize -cell $_DFFE_PN?P_ x -cell $_SDFFCE_PN?P_ x -cell $_DLATCH_PN?_ x"); run("techmap -D NO_LUT -map +/sf2/cells_map.v"); run("opt_expr -mux_undef"); run("simplemap"); @@ -209,10 +210,16 @@ struct SynthSf2Pass : public ScriptPass if (check_label("map_iobs")) { - if (help_mode) - run("sf2_iobs [-clkbuf]", "(unless -noiobs)"); - else if (iobs) - run(clkbuf ? "sf2_iobs -clkbuf" : "sf2_iobs"); + if (help_mode || iobs) { + if (help_mode) { + run("clkbufmap -buf CLKINT Y:A [-inpad CLKBUF Y:PAD]", "(unless -noiobs, -inpad only passed if -clkbuf)"); + } else if (clkbuf) { + run("clkbufmap -buf CLKINT Y:A -inpad CLKBUF Y:PAD"); + } else { + run("clkbufmap -buf CLKINT Y:A"); + } + run("iopadmap -bits -inpad INBUF Y:PAD -outpad OUTBUF D:PAD -toutpad TRIBUFF E:D:PAD -tinoutpad BIBUF E:Y:D:PAD", "(unless -noiobs"); + } run("clean"); } diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index d4d863831..ba87278de 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -42,8 +42,7 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut4_lutrams.txt)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut6_lutrams.txt)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_ff_map.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_ff_map.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/mux_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3s_mult_map.v)) diff --git a/techlibs/xilinx/arith_map.v b/techlibs/xilinx/arith_map.v index 2fc216908..eb8a04bde 100644 --- a/techlibs/xilinx/arith_map.v +++ b/techlibs/xilinx/arith_map.v @@ -35,13 +35,7 @@ module _80_xilinx_lcu (P, G, CI, CO); genvar i; -`ifdef _EXPLICIT_CARRY - localparam EXPLICIT_CARRY = 1'b1; -`else - localparam EXPLICIT_CARRY = 1'b0; -`endif - -generate if (EXPLICIT_CARRY || `LUT_SIZE == 4) begin +generate if (`LUT_SIZE == 4) begin (* force_downto *) wire [WIDTH-1:0] C = {CO, CI}; @@ -135,12 +129,6 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO); genvar i; -`ifdef _EXPLICIT_CARRY - localparam EXPLICIT_CARRY = 1'b1; -`else - localparam EXPLICIT_CARRY = 1'b0; -`endif - generate if (`LUT_SIZE == 4) begin (* force_downto *) @@ -163,106 +151,6 @@ generate if (`LUT_SIZE == 4) begin ); end endgenerate -end else if (EXPLICIT_CARRY) begin - - (* force_downto *) - wire [Y_WIDTH-1:0] S = AA ^ BB; - - wire CINIT; - // Carry chain. - // - // VPR requires that the carry chain never hit the fabric. The CO input - // to this techmap is the carry outputs for synthesis, e.g. might hit the - // fabric. - // - // So we maintain two wire sets, CO_CHAIN is the carry that is for VPR, - // e.g. off fabric dedicated chain. CO is the carry outputs that are - // available to the fabric. - (* force_downto *) - wire [Y_WIDTH-1:0] CO_CHAIN; - (* force_downto *) - wire [Y_WIDTH-1:0] C = {CO_CHAIN, CINIT}; - - // If carry chain is being initialized to a constant, techmap the constant - // source. Otherwise techmap the fabric source. - generate for (i = 0; i < 1; i = i + 1) begin:slice - CARRY0 #(.CYINIT_FABRIC(1)) carry( - .CI_INIT(CI), - .DI(AA[0]), - .S(S[0]), - .CO_CHAIN(CO_CHAIN[0]), - .CO_FABRIC(CO[0]), - .O(Y[0]) - ); - end endgenerate - - generate for (i = 1; i < Y_WIDTH-1; i = i + 1) begin:slice - if(i % 4 == 0) begin - CARRY0 carry ( - .CI(C[i]), - .DI(AA[i]), - .S(S[i]), - .CO_CHAIN(CO_CHAIN[i]), - .CO_FABRIC(CO[i]), - .O(Y[i]) - ); - end - else - begin - CARRY carry ( - .CI(C[i]), - .DI(AA[i]), - .S(S[i]), - .CO_CHAIN(CO_CHAIN[i]), - .CO_FABRIC(CO[i]), - .O(Y[i]) - ); - end - end endgenerate - - generate for (i = Y_WIDTH-1; i < Y_WIDTH; i = i + 1) begin:slice - if(i % 4 == 0) begin - CARRY0 top_of_carry ( - .CI(C[i]), - .DI(AA[i]), - .S(S[i]), - .CO_CHAIN(CO_CHAIN[i]), - .O(Y[i]) - ); - end - else - begin - CARRY top_of_carry ( - .CI(C[i]), - .DI(AA[i]), - .S(S[i]), - .CO_CHAIN(CO_CHAIN[i]), - .O(Y[i]) - ); - end - // Turns out CO_FABRIC and O both use [ABCD]MUX, so provide - // a non-congested path to output the top of the carry chain. - // Registering the output of the CARRY block would solve this, but not - // all designs do that. - if((i+1) % 4 == 0) begin - CARRY0 carry_output ( - .CI(CO_CHAIN[i]), - .DI(0), - .S(0), - .O(CO[i]) - ); - end - else - begin - CARRY carry_output ( - .CI(CO_CHAIN[i]), - .DI(0), - .S(0), - .O(CO[i]) - ); - end - end endgenerate - end else begin localparam CARRY4_COUNT = (Y_WIDTH + 3) / 4; diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 801949d22..ec4635ac6 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -18,43 +18,6 @@ * */ -// Convert negative-polarity reset to positive-polarity -(* techmap_celltype = "$_DFF_NN0_" *) -module _90_dff_nn0_to_np0 (input D, C, R, output Q); \$_DFF_NP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule -(* techmap_celltype = "$_DFF_PN0_" *) -module _90_dff_pn0_to_pp0 (input D, C, R, output Q); \$_DFF_PP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule -(* techmap_celltype = "$_DFF_NN1_" *) -module _90_dff_nn1_to_np1 (input D, C, R, output Q); \$_DFF_NP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule -(* techmap_celltype = "$_DFF_PN1_" *) -module _90_dff_pn1_to_pp1 (input D, C, R, output Q); \$_DFF_PP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule - -(* techmap_celltype = "$__DFFE_NN0" *) -module _90_dffe_nn0_to_np0 (input D, C, R, E, output Q); \$__DFFE_NP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule -(* techmap_celltype = "$__DFFE_PN0" *) -module _90_dffe_pn0_to_pp0 (input D, C, R, E, output Q); \$__DFFE_PP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule -(* techmap_celltype = "$__DFFE_NN1" *) -module _90_dffe_nn1_to_np1 (input D, C, R, E, output Q); \$__DFFE_NP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule -(* techmap_celltype = "$__DFFE_PN1" *) -module _90_dffe_pn1_to_pp1 (input D, C, R, E, output Q); \$__DFFE_PP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule - -(* techmap_celltype = "$__DFFS_NN0_" *) -module _90_dffs_nn0_to_np0 (input D, C, R, output Q); \$__DFFS_NP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule -(* techmap_celltype = "$__DFFS_PN0_" *) -module _90_dffs_pn0_to_pp0 (input D, C, R, output Q); \$__DFFS_PP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule -(* techmap_celltype = "$__DFFS_NN1_" *) -module _90_dffs_nn1_to_np1 (input D, C, R, output Q); \$__DFFS_NP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule -(* techmap_celltype = "$__DFFS_PN1_" *) -module _90_dffs_pn1_to_pp1 (input D, C, R, output Q); \$__DFFS_PP1_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule - -(* techmap_celltype = "$__DFFSE_NN0" *) -module _90_dffse_nn0_to_np0 (input D, C, R, E, output Q); \$__DFFSE_NP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule -(* techmap_celltype = "$__DFFSE_PN0" *) -module _90_dffse_pn0_to_pp0 (input D, C, R, E, output Q); \$__DFFSE_PP0 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule -(* techmap_celltype = "$__DFFSE_NN1" *) -module _90_dffse_nn1_to_np1 (input D, C, R, E, output Q); \$__DFFSE_NP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule -(* techmap_celltype = "$__DFFSE_PN1" *) -module _90_dffse_pn1_to_pp1 (input D, C, R, E, output Q); \$__DFFSE_PP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R), .E(E)); endmodule - module \$__SHREG_ (input C, input D, input E, output Q); parameter DEPTH = 0; parameter [DEPTH-1:0] INIT = 0; diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index f5850d8a2..4162160bb 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -455,29 +455,6 @@ module CARRY8( assign CO[7] = S[7] ? CO[6] : DI[7]; endmodule -`ifdef _EXPLICIT_CARRY - -module CARRY0(output CO_CHAIN, CO_FABRIC, O, input CI, CI_INIT, DI, S); - parameter CYINIT_FABRIC = 0; - wire CI_COMBINE; - if(CYINIT_FABRIC) begin - assign CI_COMBINE = CI_INIT; - end else begin - assign CI_COMBINE = CI; - end - assign CO_CHAIN = S ? CI_COMBINE : DI; - assign CO_FABRIC = S ? CI_COMBINE : DI; - assign O = S ^ CI_COMBINE; -endmodule - -module CARRY(output CO_CHAIN, CO_FABRIC, O, input CI, DI, S); - assign CO_CHAIN = S ? CI : DI; - assign CO_FABRIC = S ? CI : DI; - assign O = S ^ CI; -endmodule - -`endif - module ORCY (output O, input CI, I); assign O = CI | I; endmodule @@ -2358,6 +2335,8 @@ parameter integer PREG = 1; // The multiplier. wire signed [35:0] P_MULT; +wire signed [17:0] A_MULT; +wire signed [17:0] B_MULT; assign P_MULT = A_MULT * B_MULT; // The cascade output. @@ -2396,8 +2375,6 @@ always @(posedge CLK) begin end // The register enables. -wire signed [17:0] A_MULT; -wire signed [17:0] B_MULT; assign A_MULT = (AREG == 1) ? A_REG : A; assign B_MULT = (BREG == 1) ? B_REG : B_MUX; assign P = (PREG == 1) ? P_REG : P_MULT; @@ -3037,8 +3014,12 @@ endmodule // Virtex 6, Series 7. `ifdef YOSYS -(* abc9_box=!(PREG || AREG || ADREG || BREG || CREG || DREG || MREG), - lib_whitebox=!(PREG || AREG || ADREG || BREG || CREG || DREG || MREG) *) +(* abc9_box=!(PREG || AREG || ADREG || BREG || CREG || DREG || MREG) +`ifdef ALLOW_WHITEBOX_DSP48E1 + // Do not make DSP48E1 a whitebox for ABC9 even if fully combinatorial, since it is a big complex block + , lib_whitebox=!(PREG || AREG || ADREG || BREG || CREG || DREG || MREG || INMODEREG || OPMODEREG || ALUMODEREG || CARRYINREG || CARRYINSELREG) +`endif +*) `endif module DSP48E1 ( output [29:0] ACOUT, @@ -3526,11 +3507,15 @@ module DSP48E1 ( if (OPMODEr[3:2] != 2'b01) $fatal(1, "OPMODEr[3:2] must be 2'b01 when OPMODEr[1:0] is 2'b01"); `endif end - 2'b10: begin X = P; + 2'b10: + if (PREG == 1) + X = P; + else begin + X = 48'bx; `ifndef YOSYS - if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[1:0] is 2'b10"); + $fatal(1, "PREG must be 1 when OPMODEr[1:0] is 2'b10"); `endif - end + end 2'b11: X = $signed({Ar2, Br2}); default: X = 48'bx; endcase @@ -3552,20 +3537,36 @@ module DSP48E1 ( case (OPMODEr[6:4]) 3'b000: Z = 48'b0; 3'b001: Z = PCIN; - 3'b010: begin Z = P; + 3'b010: + if (PREG == 1) + Z = P; + else begin + Z = 48'bx; `ifndef YOSYS - if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] i0s 3'b010"); + $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b010"); `endif - end + end 3'b011: Z = Cr; - 3'b100: begin Z = P; + 3'b100: + if (PREG == 1 && OPMODEr[3:0] === 4'b1000) + Z = P; + else begin + Z = 48'bx; `ifndef YOSYS - if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b100"); - if (OPMODEr[3:0] != 4'b1000) $fatal(1, "OPMODEr[3:0] must be 4'b1000 when OPMODEr[6:4] i0s 3'b100"); + if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b100"); + if (OPMODEr[3:0] != 4'b1000) $fatal(1, "OPMODEr[3:0] must be 4'b1000 when OPMODEr[6:4] i0s 3'b100"); `endif - end + end 3'b101: Z = $signed(PCIN[47:17]); - 3'b110: Z = $signed(P[47:17]); + 3'b110: + if (PREG == 1) + Z = $signed(P[47:17]); + else begin + Z = 48'bx; +`ifndef YOSYS + $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b110"); +`endif + end default: Z = 48'bx; endcase end @@ -3591,10 +3592,34 @@ module DSP48E1 ( 3'b001: cin_muxed = ~PCIN[47]; 3'b010: cin_muxed = CARRYCASCIN; 3'b011: cin_muxed = PCIN[47]; - 3'b100: cin_muxed = CARRYCASCOUT; - 3'b101: cin_muxed = ~P[47]; + 3'b100: + if (PREG == 1) + cin_muxed = CARRYCASCOUT; + else begin + cin_muxed = 1'bx; +`ifndef YOSYS + $fatal(1, "PREG must be 1 when CARRYINSEL is 3'b100"); +`endif + end + 3'b101: + if (PREG == 1) + cin_muxed = ~P[47]; + else begin + cin_muxed = 1'bx; +`ifndef YOSYS + $fatal(1, "PREG must be 1 when CARRYINSEL is 3'b101"); +`endif + end 3'b110: cin_muxed = A24_xnor_B17; - 3'b111: cin_muxed = P[47]; + 3'b111: + if (PREG == 1) + cin_muxed = P[47]; + else begin + cin_muxed = 1'bx; +`ifndef YOSYS + $fatal(1, "PREG must be 1 when CARRYINSEL is 3'b111"); +`endif + end default: cin_muxed = 1'bx; endcase end @@ -4186,4 +4211,3 @@ module RAMB36E1 ( if (|DOB_REG) (posedge CLKBWRCLK => (DOPBDOP : 4'bx)) = 882; endspecify endmodule - diff --git a/techlibs/xilinx/ff_map.v b/techlibs/xilinx/ff_map.v new file mode 100644 index 000000000..45d202294 --- /dev/null +++ b/techlibs/xilinx/ff_map.v @@ -0,0 +1,120 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> + * + * 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. + * + */ + +`ifndef _NO_FFS + +// Async reset, enable. + +module \$_DFFE_NP0P_ (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_DFFE_PP0P_ (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +module \$_DFFE_NP1P_ (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_DFFE_PP1P_ (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// Async set and reset, enable. + +module \$_DFFSRE_NPPP_ (input D, C, E, S, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDCPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R), .PRE(S)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_DFFSRE_PPPP_ (input D, C, E, S, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDCPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R), .PRE(S)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// Sync reset, enable. + +module \$_SDFFE_NP0P_ (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_SDFFE_PP0P_ (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +module \$_SDFFE_NP1P_ (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_SDFFE_PP1P_ (input D, C, E, R, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// Latches with reset. + +module \$_DLATCH_NP0_ (input E, R, D, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + LDCE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_DLATCH_PP0_ (input E, R, D, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + LDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_DLATCH_NP1_ (input E, R, D, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + LDPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_DLATCH_PP1_ (input E, R, D, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + LDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(R)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +// Latches with set and reset. + +module \$_DLATCH_NPP_ (input E, S, R, D, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + LDCPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(R), .PRE(S)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule +module \$_DLATCH_PPP_ (input E, S, R, D, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + LDCPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(R), .PRE(S)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule + +`endif + diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index d0de73f83..0adec57a2 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -30,13 +30,13 @@ struct SynthXilinxPass : public ScriptPass { SynthXilinxPass() : ScriptPass("synth_xilinx", "synthesis for Xilinx FPGAs") { } - void on_register() YS_OVERRIDE + void on_register() override { RTLIL::constpad["synth_xilinx.abc9.xc7.W"] = "300"; // Number with which ABC will map a 6-input gate // to one LUT6 (instead of a LUT5 + LUT2) } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -77,10 +77,6 @@ struct SynthXilinxPass : public ScriptPass log(" write the design to the specified BLIF file. writing of an output file\n"); log(" is omitted if this parameter is not specified.\n"); log("\n"); - log(" -vpr\n"); - log(" generate an output netlist (and BLIF file) suitable for VPR\n"); - log(" (this feature is experimental and incomplete)\n"); - log("\n"); log(" -ise\n"); log(" generate an output netlist suitable for ISE\n"); log("\n"); @@ -142,14 +138,14 @@ struct SynthXilinxPass : public ScriptPass } std::string top_opt, edif_file, blif_file, family; - bool flatten, retime, vpr, ise, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, uram; + bool flatten, retime, ise, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, uram; bool abc9, dff; bool flatten_before_abc; int widemux; int lut_size; int widelut_size; - void clear_flags() YS_OVERRIDE + void clear_flags() override { top_opt = "-auto-top"; edif_file.clear(); @@ -157,7 +153,6 @@ struct SynthXilinxPass : public ScriptPass family = "xc7"; flatten = false; retime = false; - vpr = false; ise = false; noiopad = false; noclkbuf = false; @@ -176,7 +171,7 @@ struct SynthXilinxPass : public ScriptPass lut_size = 6; } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { std::string run_from, run_to; clear_flags(); @@ -229,10 +224,6 @@ struct SynthXilinxPass : public ScriptPass nowidelut = true; continue; } - if (args[argidx] == "-vpr") { - vpr = true; - continue; - } if (args[argidx] == "-ise") { ise = true; continue; @@ -337,23 +328,14 @@ struct SynthXilinxPass : public ScriptPass log_pop(); } - void script() YS_OVERRIDE + void script() override { std::string lut_size_s = std::to_string(lut_size); if (help_mode) lut_size_s = "[46]"; - std::string ff_map_file; - if (help_mode) - ff_map_file = "+/xilinx/{family}_ff_map.v"; - else if (family == "xc6s") - ff_map_file = "+/xilinx/xc6s_ff_map.v"; - else - ff_map_file = "+/xilinx/xc7_ff_map.v"; if (check_label("begin")) { std::string read_args; - if (vpr) - read_args += " -D_EXPLICIT_CARRY"; read_args += " -lib -specify +/xilinx/cells_sim.v"; run("read_verilog" + read_args); @@ -375,6 +357,8 @@ struct SynthXilinxPass : public ScriptPass run("opt_expr"); run("opt_clean"); run("check"); + run("opt -nodffe -nosdff"); + run("fsm"); run("opt"); if (help_mode) run("wreduce [-keepdc]", "(option for '-widemux')"); @@ -462,8 +446,6 @@ struct SynthXilinxPass : public ScriptPass run("alumacc"); run("share"); run("opt"); - run("fsm"); - run("opt -fast"); run("memory -nomap"); run("opt_clean"); } @@ -522,28 +504,21 @@ struct SynthXilinxPass : public ScriptPass } if (check_label("map_ffram")) { - // Required for dff2dffs to work. - run("simplemap t:$dff t:$adff t:$mux"); - // Needs to be done before opt -mux_bool happens. - if (help_mode) - run("dff2dffs [-match-init]", "(-match-init for xc6s only)"); - else if (family == "xc6s") - run("dff2dffs -match-init"); - else - run("dff2dffs"); - if (widemux > 0) + if (widemux > 0) { run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover // performs less efficiently - else + } else { run("opt -fast -full"); + } run("memory_map"); } if (check_label("fine")) { - run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); - if (help_mode) - run("muxcover <internal options> ('-widemux' only)"); - else if (widemux > 0) { + if (help_mode) { + run("simplemap t:$mux", "('-widemux' only)"); + run("muxcover <internal options>", "('-widemux' only)"); + } else if (widemux > 0) { + run("simplemap t:$mux"); constexpr int cost_mux2 = 100; std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2); switch (widemux) { @@ -577,8 +552,6 @@ struct SynthXilinxPass : public ScriptPass techmap_args += stringf(" -D MIN_MUX_INPUTS=%d -map +/xilinx/mux_map.v", widemux); if (!nocarry) { techmap_args += " -map +/xilinx/arith_map.v"; - if (vpr) - techmap_args += " -D _EXPLICIT_CARRY"; } run("techmap " + techmap_args); run("opt -fast"); @@ -595,16 +568,22 @@ struct SynthXilinxPass : public ScriptPass run("clean"); } - if (check_label("map_ffs", "('-abc9' only)")) { + if (check_label("map_ffs")) { + if (family == "xc6s") + run("dfflegalize -cell $_DFFE_?P?P_ r -cell $_SDFFE_?P?P_ r -cell $_DLATCH_?P?_ r", "(for xc6s)"); + else if (family == "xc6v" || family == "xc7" || family == "xcu" || family == "xcup") + run("dfflegalize -cell $_DFFE_?P?P_ 01 -cell $_SDFFE_?P?P_ 01 -cell $_DLATCH_?P?_ 01", "(for xc6v, xc7, xcu, xcup)"); + else + run("dfflegalize -cell $_DFFE_?P?P_ 01 -cell $_DFFSRE_?PPP_ 01 -cell $_SDFFE_?P?P_ 01 -cell $_DLATCH_?P?_ 01 -cell $_DLATCHSR_?PP_ 01", "(for xc5v and older)"); if (abc9 || help_mode) { if (dff || help_mode) - run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$__DFFS*", "('-dff' only)"); - run("techmap -map " + ff_map_file); + run("zinit -all w:* t:$_SDFFE_*", "('-dff' only)"); + run("techmap -map +/xilinx/ff_map.v", "('-abc9' only)"); } } if (check_label("map_luts")) { - run("opt_expr -mux_undef"); + run("opt_expr -mux_undef -noclkinv"); if (flatten_before_abc) run("flatten"); if (help_mode) @@ -653,13 +632,13 @@ struct SynthXilinxPass : public ScriptPass } run("clean"); + if (help_mode || !abc9) + run("techmap -map +/xilinx/ff_map.v", "(only if not '-abc9')"); // This shregmap call infers fixed length shift registers after abc // has performed any necessary retiming if (!nosrl || help_mode) run("xilinx_srl -fixed -minlen 3", "(skip if '-nosrl')"); std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/cells_map.v"; - if (help_mode || !abc9) - techmap_args += stringf(" -map %s", ff_map_file.c_str()); techmap_args += " -D LUT_WIDTH=" + lut_size_s; run("techmap " + techmap_args); if (help_mode) diff --git a/techlibs/xilinx/xc6s_ff_map.v b/techlibs/xilinx/xc6s_ff_map.v deleted file mode 100644 index c40f446e0..000000000 --- a/techlibs/xilinx/xc6s_ff_map.v +++ /dev/null @@ -1,256 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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. - * - */ - -// ============================================================================ -// FF mapping for Spartan 6. The primitives used are the same as Series 7, -// but with one major difference: the initial value is implied by the -// primitive type used (FFs with reset pin must have INIT set to 0 or x, FFs -// with set pin must have INIT set to 1 or x). For Yosys primitives without -// set/reset, this means we have to pick the primitive type based on the INIT -// value. - -`ifndef _NO_FFS - -// No reset. - -module \$_DFF_N_ (input D, C, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S(1'b0)); - else - FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$_DFF_P_ (input D, C, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S(1'b0)); - else - FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// No reset, enable. - -module \$_DFFE_NP_ (input D, C, E, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(1'b0)); - else - FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$_DFFE_PP_ (input D, C, E, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(1'b0)); - else - FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Async reset. - -module \$_DFF_NP0_ (input D, C, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1"); - else - FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1"); - else - FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -module \$_DFF_NP1_ (input D, C, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0"); - else - FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0"); - else - FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Async reset, enable. - -module \$__DFFE_NP0 (input D, C, E, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1"); - else - FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFE_PP0 (input D, C, E, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - $error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1"); - else - FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -module \$__DFFE_NP1 (input D, C, E, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0"); - else - FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFE_PP1 (input D, C, E, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0"); - else - FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Sync reset. - -module \$__DFFS_NP0_ (input D, C, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - $error("Spartan 6 doesn't support FFs with reset initialized to 1"); - else - FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFS_PP0_ (input D, C, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - $error("Spartan 6 doesn't support FFs with reset initialized to 1"); - else - FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -module \$__DFFS_NP1_ (input D, C, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("Spartan 6 doesn't support FFs with set initialized to 0"); - else - FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFS_PP1_ (input D, C, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("Spartan 6 doesn't support FFs with set initialized to 0"); - else - FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Sync reset, enable. - -module \$__DFFSE_NP0 (input D, C, E, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - $error("Spartan 6 doesn't support FFs with reset initialized to 1"); - else - FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFSE_PP0 (input D, C, E, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - $error("Spartan 6 doesn't support FFs with reset initialized to 1"); - else - FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -module \$__DFFSE_NP1 (input D, C, E, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("Spartan 6 doesn't support FFs with set initialized to 0"); - else - FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFSE_PP1 (input D, C, E, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("Spartan 6 doesn't support FFs with set initialized to 0"); - else - FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Latches (no reset). - -module \$_DLATCH_N_ (input E, D, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - LDPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(1'b0)); - else - LDCE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$_DLATCH_P_ (input E, D, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - LDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(1'b0)); - else - LDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Latches with reset (TODO). - -`endif - diff --git a/techlibs/xilinx/xc7_dsp_map.v b/techlibs/xilinx/xc7_dsp_map.v index a4256eb92..58df977ec 100644 --- a/techlibs/xilinx/xc7_dsp_map.v +++ b/techlibs/xilinx/xc7_dsp_map.v @@ -33,6 +33,7 @@ module \$__MUL25X18 (input [24:0] A, input [17:0] B, output [42:0] Y); .B(B), .C(48'b0), .D(25'b0), + .CARRYIN(1'b0), .P(P_48), .INMODE(5'b00000), diff --git a/techlibs/xilinx/xc7_ff_map.v b/techlibs/xilinx/xc7_ff_map.v deleted file mode 100644 index 2bd874457..000000000 --- a/techlibs/xilinx/xc7_ff_map.v +++ /dev/null @@ -1,178 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * - * 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. - * - */ - -// ============================================================================ -// FF mapping for Virtex 6, Series 7 and Ultrascale. These families support -// the following features: -// -// - a CLB flip-flop can be used as a latch or as a flip-flop -// - a CLB flip-flop has the following pins: -// -// - data input -// - clock (or gate for latches) (with optional inversion) -// - clock enable (or gate enable, which is just ANDed with gate — unused by -// synthesis) -// - either a set or a reset input, which (for FFs) can be either -// synchronous or asynchronous (with optional inversion) -// - data output -// -// - a flip-flop also has an initial value, which is set at device -// initialization (or whenever GSR is asserted) - -`ifndef _NO_FFS - -// No reset. - -module \$_DFF_N_ (input D, C, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$_DFF_P_ (input D, C, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// No reset, enable. - -module \$_DFFE_NP_ (input D, C, E, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$_DFFE_PP_ (input D, C, E, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Async reset. - -module \$_DFF_NP0_ (input D, C, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -module \$_DFF_NP1_ (input D, C, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Async reset, enable. - -module \$__DFFE_NP0 (input D, C, E, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFE_PP0 (input D, C, E, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -module \$__DFFE_NP1 (input D, C, E, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFE_PP1 (input D, C, E, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Sync reset. - -module \$__DFFS_NP0_ (input D, C, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFS_PP0_ (input D, C, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -module \$__DFFS_NP1_ (input D, C, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFS_PP1_ (input D, C, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Sync reset, enable. - -module \$__DFFSE_NP0 (input D, C, E, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFSE_PP0 (input D, C, E, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -module \$__DFFSE_NP1 (input D, C, E, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$__DFFSE_PP1 (input D, C, E, R, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S( R)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Latches (no reset). - -module \$_DLATCH_N_ (input E, D, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - LDCE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule -module \$_DLATCH_P_ (input E, D, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - LDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(1'b0)); - wire _TECHMAP_REMOVEINIT_Q_ = 1; -endmodule - -// Latches with reset (TODO). - -`endif - diff --git a/techlibs/xilinx/xilinx_dffopt.cc b/techlibs/xilinx/xilinx_dffopt.cc index c9d63c9f7..365f505fb 100644 --- a/techlibs/xilinx/xilinx_dffopt.cc +++ b/techlibs/xilinx/xilinx_dffopt.cc @@ -99,7 +99,7 @@ bool merge_lut(LutData &result, const LutData &data, const LutData select, bool struct XilinxDffOptPass : public Pass { XilinxDffOptPass() : Pass("xilinx_dffopt", "Xilinx: optimize FF control signal usage") { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -113,7 +113,7 @@ struct XilinxDffOptPass : public Pass { log(" Assume a LUT4-based device (instead of a LUT6-based device).\n"); log("\n"); } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { log_header(design, "Executing XILINX_DFFOPT pass (optimize FF control signal usage).\n"); diff --git a/tests/aiger/.gitignore b/tests/aiger/.gitignore index b76bdb653..54b4a279b 100644 --- a/tests/aiger/.gitignore +++ b/tests/aiger/.gitignore @@ -1,3 +1,3 @@ /*_ref.v -/*.aag.log -/*.aig.log +/*.log +/neg.out/ diff --git a/tests/aiger/run-test.sh b/tests/aiger/run-test.sh index de7bc68cf..bcf2b964a 100755 --- a/tests/aiger/run-test.sh +++ b/tests/aiger/run-test.sh @@ -55,5 +55,5 @@ done for y in *.ys; do echo "Running $y." - ../../yosys $y -ql ${y%.*}.log + ../../yosys -ql ${y%.*}.log $y done diff --git a/tests/arch/anlogic/dffs.ys b/tests/arch/anlogic/dffs.ys index d3281ab89..deb90e051 100644 --- a/tests/arch/anlogic/dffs.ys +++ b/tests/arch/anlogic/dffs.ys @@ -15,6 +15,5 @@ proc equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffe # Constrain all select calls below inside the top module -select -assert-count 1 t:AL_MAP_LUT3 select -assert-count 1 t:AL_MAP_SEQ -select -assert-none t:AL_MAP_LUT3 t:AL_MAP_SEQ %% t:* %D +select -assert-none t:AL_MAP_SEQ %% t:* %D diff --git a/tests/arch/anlogic/latches.ys b/tests/arch/anlogic/latches.ys index 8d66f77b3..34a3b14d0 100644 --- a/tests/arch/anlogic/latches.ys +++ b/tests/arch/anlogic/latches.ys @@ -3,31 +3,33 @@ design -save read hierarchy -top latchp proc -# Can't run any sort of equivalence check because latches are blown to LUTs -synth_anlogic +equiv_opt -assert -multiclock -map +/anlogic/cells_sim.v synth_anlogic +design -load postopt cd latchp # Constrain all select calls below inside the top module -select -assert-count 1 t:AL_MAP_LUT3 -select -assert-none t:AL_MAP_LUT3 %% t:* %D +select -assert-count 1 t:AL_MAP_SEQ +select -assert-count 1 t:AL_MAP_LUT1 +select -assert-none t:AL_MAP_SEQ t:AL_MAP_LUT1 %% t:* %D design -load read hierarchy -top latchn proc -# Can't run any sort of equivalence check because latches are blown to LUTs -synth_anlogic +equiv_opt -assert -multiclock -map +/anlogic/cells_sim.v synth_anlogic +design -load postopt cd latchn # Constrain all select calls below inside the top module -select -assert-count 1 t:AL_MAP_LUT3 -select -assert-none t:AL_MAP_LUT3 %% t:* %D +select -assert-count 1 t:AL_MAP_SEQ +select -assert-none t:AL_MAP_SEQ %% t:* %D design -load read hierarchy -top latchsr proc -# Can't run any sort of equivalence check because latches are blown to LUTs -synth_anlogic +equiv_opt -assert -multiclock -map +/anlogic/cells_sim.v synth_anlogic +design -load postopt cd latchsr # Constrain all select calls below inside the top module -select -assert-count 1 t:AL_MAP_LUT5 -select -assert-none t:AL_MAP_LUT5 %% t:* %D +select -assert-count 1 t:AL_MAP_SEQ +select -assert-count 2 t:AL_MAP_LUT3 +select -assert-none t:AL_MAP_SEQ t:AL_MAP_LUT3 %% t:* %D diff --git a/tests/arch/anlogic/run-test.sh b/tests/arch/anlogic/run-test.sh index bf19b887d..4be4b70ae 100755 --- a/tests/arch/anlogic/run-test.sh +++ b/tests/arch/anlogic/run-test.sh @@ -1,20 +1,4 @@ #!/usr/bin/env bash -set -e -{ -echo "all::" -for x in *.ys; do - echo "all:: run-$x" - echo "run-$x:" - echo " @echo 'Running $x..'" - echo " @../../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x" -done -for s in *.sh; do - if [ "$s" != "run-test.sh" ]; then - echo "all:: run-$s" - echo "run-$s:" - echo " @echo 'Running $s..'" - echo " @bash $s" - fi -done -} > run-test.mk -exec ${MAKE:-make} -f run-test.mk +set -eu +source ../../gen-tests-makefile.sh +run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/common/mul.v b/tests/arch/common/mul.v index 437a91cfc..baed64fcd 100644 --- a/tests/arch/common/mul.v +++ b/tests/arch/common/mul.v @@ -1,9 +1,10 @@ module top +#(parameter X_WIDTH=6, Y_WIDTH=6, A_WIDTH=12) ( - input [5:0] x, - input [5:0] y, + input [X_WIDTH-1:0] x, + input [Y_WIDTH-1:0] y, - output [11:0] A, + output [A_WIDTH-1:0] A, ); assign A = x * y; endmodule diff --git a/tests/arch/ecp5/bug2409.ys b/tests/arch/ecp5/bug2409.ys new file mode 100644 index 000000000..5ba9cec17 --- /dev/null +++ b/tests/arch/ecp5/bug2409.ys @@ -0,0 +1,24 @@ +read_verilog <<EOT +module t (...); + +input CLK; +input [10:0] A; +input WE; +input C; +input [7:0] DI; +output reg [7:0] DO; + +reg [7:0] mem[2047:0]; + +always @(posedge CLK) begin + if (C) + if (WE) + mem[A] <= DI; + DO <= mem[A]; +end + +endmodule +EOT + +synth_ecp5 +select -assert-count 1 t:DP16KD diff --git a/tests/arch/ecp5/fsm.ys b/tests/arch/ecp5/fsm.ys index ba91e5fc0..a77986bbc 100644 --- a/tests/arch/ecp5/fsm.ys +++ b/tests/arch/ecp5/fsm.ys @@ -10,8 +10,8 @@ sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd fsm # Constrain all select calls below inside the top module -select -assert-count 1 t:L6MUX21 -select -assert-count 15 t:LUT4 -select -assert-count 6 t:PFUMX +select -assert-max 1 t:L6MUX21 +select -assert-max 16 t:LUT4 +select -assert-max 7 t:PFUMX select -assert-count 6 t:TRELLIS_FF select -assert-none t:L6MUX21 t:LUT4 t:PFUMX t:TRELLIS_FF %% t:* %D diff --git a/tests/arch/ecp5/run-test.sh b/tests/arch/ecp5/run-test.sh index bf19b887d..4be4b70ae 100755 --- a/tests/arch/ecp5/run-test.sh +++ b/tests/arch/ecp5/run-test.sh @@ -1,20 +1,4 @@ #!/usr/bin/env bash -set -e -{ -echo "all::" -for x in *.ys; do - echo "all:: run-$x" - echo "run-$x:" - echo " @echo 'Running $x..'" - echo " @../../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x" -done -for s in *.sh; do - if [ "$s" != "run-test.sh" ]; then - echo "all:: run-$s" - echo "run-$s:" - echo " @echo 'Running $s..'" - echo " @bash $s" - fi -done -} > run-test.mk -exec ${MAKE:-make} -f run-test.mk +set -eu +source ../../gen-tests-makefile.sh +run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/efinix/adffs.ys b/tests/arch/efinix/adffs.ys index 49dc7f256..86d446439 100644 --- a/tests/arch/efinix/adffs.ys +++ b/tests/arch/efinix/adffs.ys @@ -32,9 +32,8 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd dffs # Constrain all select calls below inside the top module select -assert-count 1 t:EFX_FF select -assert-count 1 t:EFX_GBUFCE -select -assert-count 1 t:EFX_LUT4 -select -assert-none t:EFX_FF t:EFX_GBUFCE t:EFX_LUT4 %% t:* %D +select -assert-none t:EFX_FF t:EFX_GBUFCE %% t:* %D design -load read @@ -45,6 +44,5 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd ndffnr # Constrain all select calls below inside the top module select -assert-count 1 t:EFX_FF select -assert-count 1 t:EFX_GBUFCE -select -assert-count 1 t:EFX_LUT4 -select -assert-none t:EFX_FF t:EFX_GBUFCE t:EFX_LUT4 %% t:* %D +select -assert-none t:EFX_FF t:EFX_GBUFCE %% t:* %D diff --git a/tests/arch/efinix/dffs.ys b/tests/arch/efinix/dffs.ys index af787ab67..f9111873c 100644 --- a/tests/arch/efinix/dffs.ys +++ b/tests/arch/efinix/dffs.ys @@ -19,6 +19,5 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd dffe # Constrain all select calls below inside the top module select -assert-count 1 t:EFX_FF select -assert-count 1 t:EFX_GBUFCE -select -assert-count 1 t:EFX_LUT4 -select -assert-none t:EFX_FF t:EFX_GBUFCE t:EFX_LUT4 %% t:* %D +select -assert-none t:EFX_FF t:EFX_GBUFCE %% t:* %D diff --git a/tests/arch/efinix/run-test.sh b/tests/arch/efinix/run-test.sh index bf19b887d..4be4b70ae 100755 --- a/tests/arch/efinix/run-test.sh +++ b/tests/arch/efinix/run-test.sh @@ -1,20 +1,4 @@ #!/usr/bin/env bash -set -e -{ -echo "all::" -for x in *.ys; do - echo "all:: run-$x" - echo "run-$x:" - echo " @echo 'Running $x..'" - echo " @../../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x" -done -for s in *.sh; do - if [ "$s" != "run-test.sh" ]; then - echo "all:: run-$s" - echo "run-$s:" - echo " @echo 'Running $s..'" - echo " @bash $s" - fi -done -} > run-test.mk -exec ${MAKE:-make} -f run-test.mk +set -eu +source ../../gen-tests-makefile.sh +run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/gowin/init-error.ys b/tests/arch/gowin/init-error.ys new file mode 100644 index 000000000..de3813d6f --- /dev/null +++ b/tests/arch/gowin/init-error.ys @@ -0,0 +1,5 @@ +read_verilog init.v +chparam -set INIT 0 myDFF*P* +hierarchy -top myDFFP +logger -expect error "unsupported initial value and async reset value combination" 1 +synth_gowin diff --git a/tests/arch/gowin/init.ys b/tests/arch/gowin/init.ys index ddc0e4757..fba7c2fa5 100644 --- a/tests/arch/gowin/init.ys +++ b/tests/arch/gowin/init.ys @@ -30,45 +30,40 @@ select -assert-count 1 t:DFFRE select -assert-count 1 t:DFFS select -assert-count 1 t:DFFSE -delete design -load read # these should synth to a flop with reset chparam -set INIT 1 myDFF myDFFN myDFFE myDFFNE -# async should give a warning +# async would give an error # sync should synth to a mux -chparam -set INIT 0 myDFF*S* myDFF*P* -chparam -set INIT 1 myDFF*R* myDFF*C* +chparam -set INIT 0 myDFF*S* +chparam -set INIT 1 myDFF*R* proc flatten synth_gowin -run coarse: # check the flops mapped as expected -select -assert-count 1 t:DFF +select -assert-count 2 t:DFF select -assert-count 1 t:DFFC select -assert-count 1 t:DFFCE -select -assert-count 1 t:DFFE -select -assert-count 1 t:DFFN +select -assert-count 0 t:DFFE +select -assert-count 2 t:DFFN select -assert-count 1 t:DFFNC select -assert-count 1 t:DFFNCE -select -assert-count 1 t:DFFNE +select -assert-count 0 t:DFFNE select -assert-count 1 t:DFFNP select -assert-count 1 t:DFFNPE select -assert-count 0 t:DFFNR select -assert-count 0 t:DFFNRE -select -assert-count 2 t:DFFNS -select -assert-count 2 t:DFFNSE +select -assert-count 3 t:DFFNS +select -assert-count 1 t:DFFNSE select -assert-count 1 t:DFFP select -assert-count 1 t:DFFPE select -assert-count 0 t:DFFR select -assert-count 0 t:DFFRE -select -assert-count 2 t:DFFS -select -assert-count 2 t:DFFSE -select -assert-count 12 t:LUT2 - -# check the expected leftover init values -# this would happen if your reset value is not the initial value -# which would be weird -select -assert-count 8 a:init +select -assert-count 3 t:DFFS +select -assert-count 1 t:DFFSE +select -assert-count 4 t:LUT2 +select -assert-count 4 t:LUT4 diff --git a/tests/arch/gowin/run-test.sh b/tests/arch/gowin/run-test.sh index bf19b887d..4be4b70ae 100755 --- a/tests/arch/gowin/run-test.sh +++ b/tests/arch/gowin/run-test.sh @@ -1,20 +1,4 @@ #!/usr/bin/env bash -set -e -{ -echo "all::" -for x in *.ys; do - echo "all:: run-$x" - echo "run-$x:" - echo " @echo 'Running $x..'" - echo " @../../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x" -done -for s in *.sh; do - if [ "$s" != "run-test.sh" ]; then - echo "all:: run-$s" - echo "run-$s:" - echo " @echo 'Running $s..'" - echo " @bash $s" - fi -done -} > run-test.mk -exec ${MAKE:-make} -f run-test.mk +set -eu +source ../../gen-tests-makefile.sh +run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/ice40/fsm.ys b/tests/arch/ice40/fsm.ys index 223ba070e..e3b746202 100644 --- a/tests/arch/ice40/fsm.ys +++ b/tests/arch/ice40/fsm.ys @@ -12,5 +12,5 @@ cd fsm # Constrain all select calls below inside the top module select -assert-count 4 t:SB_DFF select -assert-count 2 t:SB_DFFESR -select -assert-count 15 t:SB_LUT4 +select -assert-max 15 t:SB_LUT4 select -assert-none t:SB_DFFESR t:SB_DFF t:SB_LUT4 %% t:* %D diff --git a/tests/arch/ice40/run-test.sh b/tests/arch/ice40/run-test.sh index bf19b887d..4be4b70ae 100755 --- a/tests/arch/ice40/run-test.sh +++ b/tests/arch/ice40/run-test.sh @@ -1,20 +1,4 @@ #!/usr/bin/env bash -set -e -{ -echo "all::" -for x in *.ys; do - echo "all:: run-$x" - echo "run-$x:" - echo " @echo 'Running $x..'" - echo " @../../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x" -done -for s in *.sh; do - if [ "$s" != "run-test.sh" ]; then - echo "all:: run-$s" - echo "run-$s:" - echo " @echo 'Running $s..'" - echo " @bash $s" - fi -done -} > run-test.mk -exec ${MAKE:-make} -f run-test.mk +set -eu +source ../../gen-tests-makefile.sh +run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/intel_alm/add_sub.ys b/tests/arch/intel_alm/add_sub.ys index 4cb2c2e0d..0f552a27c 100644 --- a/tests/arch/intel_alm/add_sub.ys +++ b/tests/arch/intel_alm/add_sub.ys @@ -6,3 +6,13 @@ cd top # Constrain all select calls below inside the top module stat select -assert-count 8 t:MISTRAL_ALUT_ARITH select -assert-none t:MISTRAL_ALUT_ARITH %% t:* %D + +design -reset +read_verilog ../common/add_sub.v +hierarchy -top top +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +stat +select -assert-count 8 t:MISTRAL_ALUT_ARITH +select -assert-none t:MISTRAL_ALUT_ARITH %% t:* %D diff --git a/tests/arch/intel_alm/adffs.ys b/tests/arch/intel_alm/adffs.ys index 5d8d3a220..4565dcc64 100644 --- a/tests/arch/intel_alm/adffs.ys +++ b/tests/arch/intel_alm/adffs.ys @@ -13,6 +13,18 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D design -load read +hierarchy -top adff +proc +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd adff # Constrain all select calls below inside the top module +select -assert-count 1 t:MISTRAL_FF +select -assert-count 1 t:MISTRAL_NOT + +select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D + + +design -load read hierarchy -top adffn proc equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check @@ -24,6 +36,17 @@ select -assert-none t:MISTRAL_FF %% t:* %D design -load read +hierarchy -top adffn +proc +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd adffn # Constrain all select calls below inside the top module +select -assert-count 1 t:MISTRAL_FF + +select -assert-none t:MISTRAL_FF %% t:* %D + + +design -load read hierarchy -top dffs proc equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check @@ -36,13 +59,36 @@ select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D design -load read +hierarchy -top dffs +proc +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dffs # Constrain all select calls below inside the top module +select -assert-count 1 t:MISTRAL_FF +select -assert-count 1 t:MISTRAL_ALUT2 + +select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D + + +design -load read hierarchy -top ndffnr proc equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd ndffnr # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF -select -assert-count 1 t:MISTRAL_NOT -select -assert-count 1 t:MISTRAL_ALUT2 +select -assert-count 2 t:MISTRAL_NOT -select -assert-none t:MISTRAL_FF t:MISTRAL_NOT t:MISTRAL_ALUT2 %% t:* %D +select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D + + +design -load read +hierarchy -top ndffnr +proc +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd ndffnr # Constrain all select calls below inside the top module +select -assert-count 1 t:MISTRAL_FF +select -assert-count 2 t:MISTRAL_NOT + +select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D diff --git a/tests/arch/intel_alm/blockram.ys b/tests/arch/intel_alm/blockram.ys new file mode 100644 index 000000000..610ae1ffd --- /dev/null +++ b/tests/arch/intel_alm/blockram.ys @@ -0,0 +1,6 @@ +read_verilog ../common/blockram.v +chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 10 sync_ram_sdp +synth_intel_alm -family cyclonev +cd sync_ram_sdp +select -assert-count 1 t:MISTRAL_M10K +select -assert-none t:MISTRAL_M10K %% t:* %D diff --git a/tests/arch/intel_alm/counter.ys b/tests/arch/intel_alm/counter.ys index 945c318d8..50103fefc 100644 --- a/tests/arch/intel_alm/counter.ys +++ b/tests/arch/intel_alm/counter.ys @@ -9,5 +9,19 @@ cd top # Constrain all select calls below inside the top module select -assert-count 2 t:MISTRAL_NOT select -assert-count 8 t:MISTRAL_ALUT_ARITH select -assert-count 8 t:MISTRAL_FF +select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D + + +design -reset +read_verilog ../common/counter.v +hierarchy -top top +proc +flatten +equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 2 t:MISTRAL_NOT +select -assert-count 8 t:MISTRAL_ALUT_ARITH +select -assert-count 8 t:MISTRAL_FF select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D diff --git a/tests/arch/intel_alm/dffs.ys b/tests/arch/intel_alm/dffs.ys index cf29ad8e0..9ae6c637a 100644 --- a/tests/arch/intel_alm/dffs.ys +++ b/tests/arch/intel_alm/dffs.ys @@ -11,12 +11,33 @@ select -assert-count 1 t:MISTRAL_FF select -assert-none t:MISTRAL_FF %% t:* %D design -load read +hierarchy -top dff +proc +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dff # Constrain all select calls below inside the top module +select -assert-count 1 t:MISTRAL_FF + +select -assert-none t:MISTRAL_FF %% t:* %D + + +design -load read hierarchy -top dffe proc equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffe # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_FF -select -assert-count 1 t:MISTRAL_ALUT3 -select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT3 %% t:* %D +select -assert-none t:MISTRAL_FF %% t:* %D + + +design -load read +hierarchy -top dffe +proc +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dffe # Constrain all select calls below inside the top module +select -assert-count 1 t:MISTRAL_FF + +select -assert-none t:MISTRAL_FF %% t:* %D diff --git a/tests/arch/intel_alm/fsm.ys b/tests/arch/intel_alm/fsm.ys index 8bb0ebab2..e54b5c21e 100644 --- a/tests/arch/intel_alm/fsm.ys +++ b/tests/arch/intel_alm/fsm.ys @@ -12,7 +12,33 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd fsm # Constrain all select calls below inside the top module select -assert-count 6 t:MISTRAL_FF +select -assert-max 1 t:MISTRAL_NOT select -assert-max 2 t:MISTRAL_ALUT2 # Clang returns 2, GCC returns 1 -select -assert-count 5 t:MISTRAL_ALUT5 -select -assert-count 1 t:MISTRAL_ALUT6 -select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D +select -assert-max 1 t:MISTRAL_ALUT3 +select -assert-max 2 t:MISTRAL_ALUT4 # Clang returns 0, GCC returns 1 +select -assert-max 6 t:MISTRAL_ALUT5 # Clang returns 5, GCC returns 4 +select -assert-max 2 t:MISTRAL_ALUT6 # Clang returns 1, GCC returns 2 +select -assert-none t:MISTRAL_FF t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_ALUT4 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D + +design -reset +read_verilog ../common/fsm.v +hierarchy -top fsm +proc +flatten + +equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx +async2sync +miter -equiv -make_assert -flatten gold gate miter +sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter + +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd fsm # Constrain all select calls below inside the top module + +select -assert-count 6 t:MISTRAL_FF +select -assert-max 1 t:MISTRAL_NOT +select -assert-max 2 t:MISTRAL_ALUT2 # Clang returns 2, GCC returns 1 +select -assert-max 2 t:MISTRAL_ALUT3 # Clang returns 2, GCC returns 1 +select -assert-max 2 t:MISTRAL_ALUT4 # Clang returns 0, GCC returns 1 +select -assert-max 6 t:MISTRAL_ALUT5 # Clang returns 5, GCC returns 4 +select -assert-max 2 t:MISTRAL_ALUT6 # Clang returns 1, GCC returns 2 +select -assert-none t:MISTRAL_FF t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_ALUT4 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D diff --git a/tests/arch/intel_alm/logic.ys b/tests/arch/intel_alm/logic.ys index fad45db74..e8b26a524 100644 --- a/tests/arch/intel_alm/logic.ys +++ b/tests/arch/intel_alm/logic.ys @@ -9,3 +9,17 @@ select -assert-count 1 t:MISTRAL_NOT select -assert-count 6 t:MISTRAL_ALUT2 select -assert-count 2 t:MISTRAL_ALUT4 select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT4 %% t:* %D + + +design -reset +read_verilog ../common/logic.v +hierarchy -top top +proc +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 1 t:MISTRAL_NOT +select -assert-count 6 t:MISTRAL_ALUT2 +select -assert-count 2 t:MISTRAL_ALUT4 +select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT4 %% t:* %D
\ No newline at end of file diff --git a/tests/arch/intel_alm/lutram.ys b/tests/arch/intel_alm/lutram.ys index 6f997b67b..66f8a1536 100644 --- a/tests/arch/intel_alm/lutram.ys +++ b/tests/arch/intel_alm/lutram.ys @@ -7,7 +7,7 @@ memory opt -full miter -equiv -flatten -make_assert -make_outputs gold gate miter -sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter +sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter design -load postopt cd lutram_1w1r @@ -18,3 +18,24 @@ select -assert-count 8 t:MISTRAL_ALUT3 select -assert-count 17 t:MISTRAL_FF select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_FF t:MISTRAL_MLAB %% t:* %D + +design -reset +read_verilog ../common/lutram.v +hierarchy -top lutram_1w1r +proc +memory -nomap +equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v -map +/intel_alm/common/mem_sim.v synth_intel_alm -family cyclonev -nobram +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +select -assert-count 16 t:MISTRAL_MLAB +select -assert-count 1 t:MISTRAL_NOT +select -assert-count 2 t:MISTRAL_ALUT2 +select -assert-count 8 t:MISTRAL_ALUT3 +select -assert-count 17 t:MISTRAL_FF +select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_FF t:MISTRAL_MLAB %% t:* %D diff --git a/tests/arch/intel_alm/mul.ys b/tests/arch/intel_alm/mul.ys new file mode 100644 index 000000000..49934740f --- /dev/null +++ b/tests/arch/intel_alm/mul.ys @@ -0,0 +1,60 @@ +read_verilog ../common/mul.v +chparam -set X_WIDTH 8 -set Y_WIDTH 8 -set A_WIDTH 16 +hierarchy -top top +proc +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 1 t:MISTRAL_MUL9X9 +select -assert-none t:MISTRAL_MUL9X9 %% t:* %D + +# Cyclone 10 GX does not have 9x9 multipliers. + +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 17 -set Y_WIDTH 17 -set A_WIDTH 34 +hierarchy -top top +proc +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 1 t:MISTRAL_MUL18X18 +select -assert-none t:MISTRAL_MUL18X18 %% t:* %D + +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 17 -set Y_WIDTH 17 -set A_WIDTH 34 +hierarchy -top top +proc +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 1 t:MISTRAL_MUL18X18 +select -assert-none t:MISTRAL_MUL18X18 %% t:* %D + +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 26 -set Y_WIDTH 26 -set A_WIDTH 52 +hierarchy -top top +proc +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclonev # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 1 t:MISTRAL_MUL27X27 +select -assert-none t:MISTRAL_MUL27X27 %% t:* %D + +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 26 -set Y_WIDTH 26 -set A_WIDTH 52 +hierarchy -top top +proc +equiv_opt -assert -map +/intel_alm/common/dsp_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module + +select -assert-count 1 t:MISTRAL_MUL27X27 +select -assert-none t:MISTRAL_MUL27X27 %% t:* %D diff --git a/tests/arch/intel_alm/mux.ys b/tests/arch/intel_alm/mux.ys index 308e45268..ac3b9b08f 100644 --- a/tests/arch/intel_alm/mux.ys +++ b/tests/arch/intel_alm/mux.ys @@ -1,15 +1,26 @@ read_verilog ../common/mux.v design -save read + hierarchy -top mux2 proc equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux2 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 +select -assert-none t:MISTRAL_ALUT3 %% t:* %D + +design -load read +hierarchy -top mux2 +proc +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux2 # Constrain all select calls below inside the top module +select -assert-count 1 t:MISTRAL_ALUT3 select -assert-none t:MISTRAL_ALUT3 %% t:* %D + design -load read hierarchy -top mux4 proc @@ -17,9 +28,19 @@ equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cycl design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux4 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT6 +select -assert-none t:MISTRAL_ALUT6 %% t:* %D + +design -load read +hierarchy -top mux4 +proc +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux4 # Constrain all select calls below inside the top module +select -assert-count 1 t:MISTRAL_ALUT6 select -assert-none t:MISTRAL_ALUT6 %% t:* %D + design -load read hierarchy -top mux8 proc @@ -27,10 +48,20 @@ equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cycl design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 -select -assert-count 1 t:MISTRAL_ALUT5 select -assert-count 2 t:MISTRAL_ALUT6 +select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT6 %% t:* %D + + +design -load read +hierarchy -top mux8 +proc +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux8 # Constrain all select calls below inside the top module +select -assert-count 1 t:MISTRAL_ALUT3 +select -assert-count 2 t:MISTRAL_ALUT6 +select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT6 %% t:* %D -select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D design -load read hierarchy -top mux16 @@ -39,6 +70,18 @@ equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cycl design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module select -assert-count 1 t:MISTRAL_ALUT3 +select -assert-max 2 t:MISTRAL_ALUT5 +select -assert-max 5 t:MISTRAL_ALUT6 +select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D + + +design -load read +hierarchy -top mux16 +proc +equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux16 # Constrain all select calls below inside the top module +select -assert-count 1 t:MISTRAL_ALUT3 select -assert-count 2 t:MISTRAL_ALUT5 select -assert-count 4 t:MISTRAL_ALUT6 diff --git a/tests/arch/intel_alm/quartus_ice.ys b/tests/arch/intel_alm/quartus_ice.ys index 4b9b54d10..a88226e13 100644 --- a/tests/arch/intel_alm/quartus_ice.ys +++ b/tests/arch/intel_alm/quartus_ice.ys @@ -10,3 +10,17 @@ EOT synth_intel_alm -family cyclonev -quartus select -assert-none w:*[* w:*]* + +design -reset +read_verilog <<EOT +// Verilog has syntax for raw identifiers, where you start it with \ and end it with a space. +// This test crashes Quartus due to it parsing \a[10] as a wire slice and not a raw identifier. +module top(); + (* keep *) wire [31:0] \a[10] ; + (* keep *) wire b; + assign b = \a[10] [31]; +endmodule +EOT + +synth_intel_alm -family cyclone10gx -quartus +select -assert-none w:*[* w:*]* diff --git a/tests/arch/intel_alm/run-test.sh b/tests/arch/intel_alm/run-test.sh index bf19b887d..4be4b70ae 100755 --- a/tests/arch/intel_alm/run-test.sh +++ b/tests/arch/intel_alm/run-test.sh @@ -1,20 +1,4 @@ #!/usr/bin/env bash -set -e -{ -echo "all::" -for x in *.ys; do - echo "all:: run-$x" - echo "run-$x:" - echo " @echo 'Running $x..'" - echo " @../../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x" -done -for s in *.sh; do - if [ "$s" != "run-test.sh" ]; then - echo "all:: run-$s" - echo "run-$s:" - echo " @echo 'Running $s..'" - echo " @bash $s" - fi -done -} > run-test.mk -exec ${MAKE:-make} -f run-test.mk +set -eu +source ../../gen-tests-makefile.sh +run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/intel_alm/shifter.ys b/tests/arch/intel_alm/shifter.ys index 014dbd1a8..e307b5486 100644 --- a/tests/arch/intel_alm/shifter.ys +++ b/tests/arch/intel_alm/shifter.ys @@ -6,5 +6,16 @@ equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 8 t:MISTRAL_FF +select -assert-none t:MISTRAL_FF %% t:* %D + +design -reset +read_verilog ../common/shifter.v +hierarchy -top top +proc +flatten +equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 8 t:MISTRAL_FF select -assert-none t:MISTRAL_FF %% t:* %D diff --git a/tests/arch/intel_alm/tribuf.ys b/tests/arch/intel_alm/tribuf.ys index 71b05a747..7f3b38493 100644 --- a/tests/arch/intel_alm/tribuf.ys +++ b/tests/arch/intel_alm/tribuf.ys @@ -9,5 +9,19 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd tristate # Constrain all select calls below inside the top module #Internal cell type used. Need support it. select -assert-count 1 t:$_TBUF_ +select -assert-none t:$_TBUF_ %% t:* %D + +design -reset +read_verilog ../common/tribuf.v +hierarchy -top tristate +proc +tribuf +flatten +synth +equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclone10gx # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd tristate # Constrain all select calls below inside the top module +#Internal cell type used. Need support it. +select -assert-count 1 t:$_TBUF_ select -assert-none t:$_TBUF_ %% t:* %D diff --git a/tests/arch/nexus/.gitignore b/tests/arch/nexus/.gitignore new file mode 100644 index 000000000..ba42e1ee6 --- /dev/null +++ b/tests/arch/nexus/.gitignore @@ -0,0 +1,2 @@ +/*.log +/run-test.mk diff --git a/tests/arch/nexus/add_sub.ys b/tests/arch/nexus/add_sub.ys new file mode 100644 index 000000000..4317bab81 --- /dev/null +++ b/tests/arch/nexus/add_sub.ys @@ -0,0 +1,21 @@ +read_verilog ../common/add_sub.v +hierarchy -top top +proc +design -save orig + +equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +stat +select -assert-count 10 t:LUT4 +select -assert-none t:IB t:OB t:VLO t:LUT4 %% t:* %D + +design -load orig + +equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus -abc9 # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +stat +select -assert-count 6 t:LUT4 +select -assert-count 4 t:WIDEFN9 +select -assert-none t:IB t:OB t:VLO t:LUT4 t:WIDEFN9 %% t:* %D diff --git a/tests/arch/nexus/adffs.ys b/tests/arch/nexus/adffs.ys new file mode 100644 index 000000000..f8796425c --- /dev/null +++ b/tests/arch/nexus/adffs.ys @@ -0,0 +1,44 @@ +read_verilog ../common/adffs.v +design -save read + +hierarchy -top adff +proc +equiv_opt -async2sync -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd adff # Constrain all select calls below inside the top module +stat +select -assert-count 1 t:FD1P3DX +select -assert-none t:FD1P3DX t:IB t:OB t:VLO t:VHI %% t:* %D + +design -load read +hierarchy -top adffn +proc +equiv_opt -async2sync -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd adffn # Constrain all select calls below inside the top module +stat +select -assert-count 1 t:FD1P3DX +select -assert-count 1 t:INV +select -assert-none t:FD1P3DX t:INV t:LUT4 t:IB t:OB t:VLO t:VHI %% t:* %D + +design -load read +hierarchy -top dffs +proc +equiv_opt -async2sync -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dffs # Constrain all select calls below inside the top module +stat +select -assert-count 1 t:FD1P3IX +select -assert-count 1 t:LUT4 +select -assert-none t:FD1P3IX t:LUT4 t:IB t:OB t:VLO t:VHI %% t:* %D + +design -load read +hierarchy -top ndffnr +proc +equiv_opt -async2sync -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd ndffnr # Constrain all select calls below inside the top module +stat +select -assert-count 1 t:FD1P3IX +select -assert-count 2 t:INV +select -assert-none t:FD1P3IX t:INV t:LUT4 t:IB t:OB t:VLO t:VHI %% t:* %D diff --git a/tests/arch/nexus/blockram.ys b/tests/arch/nexus/blockram.ys new file mode 100644 index 000000000..9540136d5 --- /dev/null +++ b/tests/arch/nexus/blockram.ys @@ -0,0 +1,18 @@ +read_verilog ../common/blockram.v +design -save read + +# Check that we use the right dual and single clock variants + +chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 18 sync_ram_sdp +synth_nexus -top sync_ram_sdp +cd sync_ram_sdp +select -assert-count 1 t:PDPSC16K +select -assert-none t:PDPSC16K t:INV t:IB t:OB t:VLO t:VHI %% t:* %D + +design -reset +read_verilog blockram_dc.v +chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 18 sync_ram_sdp_dc +synth_nexus -top sync_ram_sdp_dc +cd sync_ram_sdp_dc +select -assert-count 1 t:PDP16K +select -assert-none t:PDP16K t:INV t:IB t:OB t:VLO t:VHI %% t:* %D diff --git a/tests/arch/nexus/blockram_dc.v b/tests/arch/nexus/blockram_dc.v new file mode 100644 index 000000000..4f5d4f5a6 --- /dev/null +++ b/tests/arch/nexus/blockram_dc.v @@ -0,0 +1,25 @@ + +`default_nettype none +module sync_ram_sdp_dc #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) + (input wire clkw, clkr, write_enable, + input wire [DATA_WIDTH-1:0] data_in, + input wire [ADDRESS_WIDTH-1:0] address_in_r, address_in_w, + output wire [DATA_WIDTH-1:0] data_out); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] data_out_r; + reg [WORD:0] memory [0:DEPTH]; + + always @(posedge clkw) begin + if (write_enable) + memory[address_in_w] <= data_in; + end + always @(posedge clkr) begin + data_out_r <= memory[address_in_r]; + end + + assign data_out = data_out_r; + +endmodule // sync_ram_sdp_dc diff --git a/tests/arch/nexus/counter.ys b/tests/arch/nexus/counter.ys new file mode 100644 index 000000000..44421e377 --- /dev/null +++ b/tests/arch/nexus/counter.ys @@ -0,0 +1,11 @@ +read_verilog ../common/counter.v +hierarchy -top top +proc +flatten +equiv_opt -assert -multiclock -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +stat +select -assert-count 5 t:CCU2 +select -assert-count 8 t:FD1P3DX +select -assert-none t:CCU2 t:FD1P3DX t:IB t:OB t:VLO t:VHI %% t:* %D diff --git a/tests/arch/nexus/dffs.ys b/tests/arch/nexus/dffs.ys new file mode 100644 index 000000000..9ebf68bf4 --- /dev/null +++ b/tests/arch/nexus/dffs.ys @@ -0,0 +1,19 @@ +read_verilog ../common/dffs.v +design -save read + +hierarchy -top dff +proc +equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dff # Constrain all select calls below inside the top module +select -assert-count 1 t:FD1P3IX +select -assert-none t:FD1P3IX t:IB t:OB t:VHI t:VLO %% t:* %D + +design -load read +hierarchy -top dffe +proc +equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dffe # Constrain all select calls below inside the top module +select -assert-count 1 t:FD1P3IX +select -assert-none t:FD1P3IX t:IB t:OB t:VHI t:VLO %% t:* %D diff --git a/tests/arch/nexus/fsm.ys b/tests/arch/nexus/fsm.ys new file mode 100644 index 000000000..24ad8fe5b --- /dev/null +++ b/tests/arch/nexus/fsm.ys @@ -0,0 +1,19 @@ +read_verilog ../common/fsm.v +hierarchy -top fsm +proc +flatten + +equiv_opt -run :prove -map +/nexus/cells_sim.v synth_nexus +miter -equiv -make_assert -flatten gold gate miter +sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter + +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd fsm # Constrain all select calls below inside the top module + +stat + +select -assert-max 1 t:INV +select -assert-max 2 t:LUT4 +select -assert-max 6 t:WIDEFN9 +select -assert-count 6 t:FD1P3IX +select -assert-none t:LUT4 t:FD1P3IX t:WIDEFN9 t:INV t:IB t:OB t:VLO t:VHI %% t:* %D diff --git a/tests/arch/nexus/logic.ys b/tests/arch/nexus/logic.ys new file mode 100644 index 000000000..cff61b509 --- /dev/null +++ b/tests/arch/nexus/logic.ys @@ -0,0 +1,8 @@ +read_verilog ../common/logic.v +hierarchy -top top +proc +equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 8 t:LUT4 +select -assert-none t:LUT4 t:INV t:IB t:OB t:VLO t:VHI %% t:* %D diff --git a/tests/arch/nexus/lutram.ys b/tests/arch/nexus/lutram.ys new file mode 100644 index 000000000..cd645f717 --- /dev/null +++ b/tests/arch/nexus/lutram.ys @@ -0,0 +1,19 @@ +read_verilog ../common/lutram.v +hierarchy -top lutram_1w1r +proc +memory -nomap +equiv_opt -run :prove -map +/nexus/cells_sim.v synth_nexus +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +stat +select -assert-count 8 t:WIDEFN9 +select -assert-count 16 t:LUT4 +select -assert-count 8 t:DPR16X4 +select -assert-count 36 t:FD1P3IX +select -assert-none t:DPR16X4 t:FD1P3IX t:WIDEFN9 t:LUT4 t:INV t:IB t:OB t:VLO t:VHI %% t:* %D diff --git a/tests/arch/nexus/mul.ys b/tests/arch/nexus/mul.ys new file mode 100644 index 000000000..65a2fd8c3 --- /dev/null +++ b/tests/arch/nexus/mul.ys @@ -0,0 +1,50 @@ +read_verilog ../common/mul.v +chparam -set X_WIDTH 8 -set Y_WIDTH 8 -set A_WIDTH 16 +hierarchy -top top +proc + +design -save read + +equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:MULT9X9 + +select -assert-none t:IB t:OB t:VLO t:VHI t:MULT9X9 %% t:* %D + + +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 16 -set Y_WIDTH 16 -set A_WIDTH 32 +hierarchy -top top +proc +# equivalence checking is too slow here +synth_nexus +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:MULT18X18 +select -assert-none t:IB t:OB t:VLO t:VHI t:MULT18X18 %% t:* %D + + +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 32 -set Y_WIDTH 16 -set A_WIDTH 48 +hierarchy -top top +proc +# equivalence checking is too slow here +synth_nexus +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:MULT18X36 +select -assert-none t:IB t:OB t:VLO t:VHI t:MULT18X36 %% t:* %D + + +design -reset +read_verilog ../common/mul.v +chparam -set X_WIDTH 32 -set Y_WIDTH 32 -set A_WIDTH 64 +hierarchy -top top +proc +# equivalence checking is too slow here +synth_nexus +cd top # Constrain all select calls below inside the top module +select -assert-count 1 t:MULT36X36 + +select -assert-none t:IB t:OB t:VLO t:VHI t:MULT36X36 %% t:* %D diff --git a/tests/arch/nexus/mux.ys b/tests/arch/nexus/mux.ys new file mode 100644 index 000000000..0e12d674a --- /dev/null +++ b/tests/arch/nexus/mux.ys @@ -0,0 +1,43 @@ +read_verilog ../common/mux.v +design -save read + +hierarchy -top mux2 +proc +equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux2 # Constrain all select calls below inside the top module +select -assert-count 1 t:LUT4 +select -assert-none t:IB t:OB t:VLO t:VHI t:LUT4 t:WIDEFN9 %% t:* %D + +design -load read +hierarchy -top mux4 +proc +equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux4 # Constrain all select calls below inside the top module +select -assert-count 1 t:WIDEFN9 + +select -assert-none t:IB t:OB t:VLO t:VHI t:LUT4 t:WIDEFN9 %% t:* %D + +design -load read +hierarchy -top mux8 +proc +equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux8 # Constrain all select calls below inside the top module +select -assert-count 4 t:LUT4 +select -assert-count 1 t:WIDEFN9 + +select -assert-none t:IB t:OB t:VLO t:VHI t:LUT4 t:WIDEFN9 %% t:* %D + +design -load read +hierarchy -top mux16 +proc +equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd mux16 # Constrain all select calls below inside the top module +select -assert-min 11 t:LUT4 +select -assert-max 12 t:LUT4 +select -assert-count 1 t:WIDEFN9 + +select -assert-none t:IB t:OB t:VLO t:VHI t:LUT4 t:WIDEFN9 %% t:* %D diff --git a/tests/arch/nexus/run-test.sh b/tests/arch/nexus/run-test.sh new file mode 100644 index 000000000..4be4b70ae --- /dev/null +++ b/tests/arch/nexus/run-test.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -eu +source ../../gen-tests-makefile.sh +run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/arch/nexus/shifter.ys b/tests/arch/nexus/shifter.ys new file mode 100644 index 000000000..a8e34b0f9 --- /dev/null +++ b/tests/arch/nexus/shifter.ys @@ -0,0 +1,9 @@ +read_verilog ../common/shifter.v +hierarchy -top top +proc +flatten +equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 8 t:FD1P3IX +select -assert-none t:FD1P3IX t:WIDEFN9 t:INV t:IB t:OB t:VLO t:VHI %% t:* %D diff --git a/tests/arch/nexus/tribuf.ys b/tests/arch/nexus/tribuf.ys new file mode 100644 index 000000000..70fb7cb5f --- /dev/null +++ b/tests/arch/nexus/tribuf.ys @@ -0,0 +1,12 @@ +read_verilog ../common/tribuf.v +hierarchy -top tristate +proc +tribuf +flatten +synth +equiv_opt -assert -map +/nexus/cells_sim.v -map +/simcells.v synth_nexus # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd tristate # Constrain all select calls below inside the top module +select -assert-count 1 t:OBZ +select -assert-count 1 t:INV +select -assert-none t:OBZ t:INV t:IB t:OB t:VLO t:VHI %% t:* %D diff --git a/tests/arch/xilinx/attributes_test.ys b/tests/arch/xilinx/attributes_test.ys index 7bdd94a63..58552d8fb 100644 --- a/tests/arch/xilinx/attributes_test.ys +++ b/tests/arch/xilinx/attributes_test.ys @@ -16,8 +16,7 @@ select -assert-count 8 t:RAM32X1D # Set ram_style distributed to blockram memory; will be implemented as distributed design -reset read_verilog ../common/memory_attributes/attributes_test.v -prep -setattr -mod -set ram_style "distributed" block_ram +setattr -set ram_style "distributed" block_ram/m:* synth_xilinx -top block_ram -noiopad cd block_ram # Constrain all select calls below inside the top module select -assert-count 32 t:RAM128X1D @@ -25,8 +24,7 @@ select -assert-count 32 t:RAM128X1D # Set synthesis, logic_block to blockram memory; will be implemented as distributed design -reset read_verilog ../common/memory_attributes/attributes_test.v -prep -setattr -mod -set logic_block 1 block_ram +setattr -set logic_block 1 block_ram/m:* synth_xilinx -top block_ram -noiopad cd block_ram # Constrain all select calls below inside the top module select -assert-count 0 t:RAMB18E1 diff --git a/tests/arch/xilinx/dsp_abc9.ys b/tests/arch/xilinx/dsp_abc9.ys new file mode 100644 index 000000000..909e54149 --- /dev/null +++ b/tests/arch/xilinx/dsp_abc9.ys @@ -0,0 +1,37 @@ +read_verilog <<EOT +module top(input [24:0] A, input [17:0] B, output [47:0] P); +DSP48E1 #(.PREG(0)) dsp(.A(A), .B(B), .P(P)); +endmodule +EOT +techmap -autoproc -wb -map +/xilinx/cells_sim.v +opt +scc -expect 0 + + +design -reset +read_verilog <<EOT +module top(input signed [24:0] A, input signed [17:0] B, output [47:0] P); +assign P = A * B; +endmodule +EOT +synth_xilinx -abc9 +techmap -autoproc -wb -map +/xilinx/cells_sim.v +opt -full -fine +select -assert-count 1 t:$mul +select -assert-count 0 t:* t:$mul %D + + +design -reset +read_verilog -icells -formal <<EOT +module top(output [42:0] P); +\$__MUL25X18 mul (.A(42), .B(42), .Y(P)); +assert property (P == 42*42); +endmodule +EOT +techmap -map +/xilinx/xc7_dsp_map.v +verilog_defaults -add -D ALLOW_WHITEBOX_DSP48E1 +synth_xilinx -abc9 +techmap -autoproc -wb -map +/xilinx/cells_sim.v +opt -full -fine +select -assert-count 0 t:* t:$assert %d +sat -verify -prove-asserts diff --git a/tests/arch/xilinx/fsm.ys b/tests/arch/xilinx/fsm.ys index fec4c6082..ace646af4 100644 --- a/tests/arch/xilinx/fsm.ys +++ b/tests/arch/xilinx/fsm.ys @@ -13,12 +13,11 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd fsm # Constrain all select calls below inside the top module stat select -assert-count 1 t:BUFG -select -assert-count 4 t:FDRE -select -assert-count 1 t:FDSE -select -assert-count 1 t:LUT2 -select -assert-count 3 t:LUT5 +select -assert-count 6 t:FDRE +select -assert-count 1 t:LUT4 +select -assert-count 4 t:LUT5 select -assert-count 1 t:LUT6 -select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT5 t:LUT6 %% t:* %D +select -assert-none t:BUFG t:FDRE t:LUT4 t:LUT5 t:LUT6 %% t:* %D design -load orig @@ -32,7 +31,6 @@ stat select -assert-count 1 t:BUFG select -assert-count 6 t:FDRE select -assert-count 1 t:LUT1 -select -assert-count 3 t:LUT3 -select -assert-count 6 t:LUT4 -select -assert-count 6 t:MUXF5 -select -assert-none t:BUFG t:FDRE t:LUT1 t:LUT3 t:LUT4 t:MUXF5 %% t:* %D +select -assert-count 8 t:LUT4 +select -assert-count 5 t:MUXF5 +select -assert-none t:BUFG t:FDRE t:LUT1 t:LUT4 t:MUXF5 %% t:* %D diff --git a/tests/arch/xilinx/latches.ys b/tests/arch/xilinx/latches.ys index e226c2ec8..ee87fee21 100644 --- a/tests/arch/xilinx/latches.ys +++ b/tests/arch/xilinx/latches.ys @@ -18,9 +18,8 @@ equiv_opt -async2sync -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd latchn # Constrain all select calls below inside the top module select -assert-count 1 t:LDCE -select -assert-count 1 t:INV -select -assert-none t:LDCE t:INV %% t:* %D +select -assert-none t:LDCE %% t:* %D design -load read diff --git a/tests/arch/xilinx/nosrl.ys b/tests/arch/xilinx/nosrl.ys new file mode 100644 index 000000000..31bd5d377 --- /dev/null +++ b/tests/arch/xilinx/nosrl.ys @@ -0,0 +1,41 @@ +read_verilog <<EOT + +module xilinx_srl_static_test(input i, clk, output [1:0] q); +reg head = 1'b0; +reg [3:0] shift1 = 4'b0000; +reg [3:0] shift2 = 4'b0000; + +always @(posedge clk) begin + head <= i; + shift1 <= {shift1[2:0], head}; + shift2 <= {shift2[2:0], head}; +end + +assign q = {shift2[3], shift1[3]}; +endmodule + +EOT + +design -save read + +hierarchy -top xilinx_srl_static_test +proc +#equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check +equiv_opt -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd xilinx_srl_static_test # Constrain all select calls below inside the top module +stat +select -assert-count 1 t:BUFG +select -assert-count 1 t:SRL16E +select -assert-none t:BUFG t:SRL16E %% t:* %D + +design -load read +hierarchy -top xilinx_srl_static_test +proc +equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -nosrl -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd xilinx_srl_static_test # Constrain all select calls below inside the top module +stat +select -assert-count 1 t:BUFG +select -assert-count 5 t:FDRE +select -assert-none t:BUFG t:FDRE %% t:* %D diff --git a/tests/arch/xilinx/pmgen_xilinx_srl.ys b/tests/arch/xilinx/pmgen_xilinx_srl.ys index e76fb20ab..9a5e70ea9 100644 --- a/tests/arch/xilinx/pmgen_xilinx_srl.ys +++ b/tests/arch/xilinx/pmgen_xilinx_srl.ys @@ -35,7 +35,6 @@ design -stash gate design -copy-from gold -as gold pmtest_xilinx_srl_pm_fixed design -copy-from gate -as gate pmtest_xilinx_srl_pm_fixed -dff2dffe -unmap # sat does not support flops-with-enable yet miter -equiv -flatten -make_assert gold gate miter sat -set-init-zero -seq 5 -verify -prove-asserts miter @@ -52,6 +51,5 @@ design -stash gate design -copy-from gold -as gold pmtest_xilinx_srl_pm_variable design -copy-from gate -as gate pmtest_xilinx_srl_pm_variable -dff2dffe -unmap # sat does not support flops-with-enable yet miter -equiv -flatten -make_assert gold gate miter sat -set-init-zero -seq 5 -verify -prove-asserts miter diff --git a/tests/arch/xilinx/run-test.sh b/tests/arch/xilinx/run-test.sh index bf19b887d..4be4b70ae 100755 --- a/tests/arch/xilinx/run-test.sh +++ b/tests/arch/xilinx/run-test.sh @@ -1,20 +1,4 @@ #!/usr/bin/env bash -set -e -{ -echo "all::" -for x in *.ys; do - echo "all:: run-$x" - echo "run-$x:" - echo " @echo 'Running $x..'" - echo " @../../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x" -done -for s in *.sh; do - if [ "$s" != "run-test.sh" ]; then - echo "all:: run-$s" - echo "run-$s:" - echo " @echo 'Running $s..'" - echo " @bash $s" - fi -done -} > run-test.mk -exec ${MAKE:-make} -f run-test.mk +set -eu +source ../../gen-tests-makefile.sh +run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'" diff --git a/tests/gen-tests-makefile.sh b/tests/gen-tests-makefile.sh new file mode 100755 index 000000000..ab8fb7013 --- /dev/null +++ b/tests/gen-tests-makefile.sh @@ -0,0 +1,94 @@ +set -eu + +YOSYS_BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"/../ >/dev/null 2>&1 && pwd)" + +# $ generate_target target_name test_command +generate_target() { + target_name=$1 + test_command=$2 + echo "all: $target_name" + echo ".PHONY: $target_name" + echo "$target_name:" + printf "\t@%s\n" "$test_command" + printf "\t@echo 'Passed %s'\n" "$target_name" +} + +# $ generate_ys_test ys_file [yosys_args] +generate_ys_test() { + ys_file=$1 + yosys_args=${2:-} + generate_target "$ys_file" "$YOSYS_BASEDIR/yosys -ql ${ys_file%.*}.log $yosys_args $ys_file" +} + +# $ generate_bash_test bash_file +generate_bash_test() { + bash_file=$1 + generate_target "$bash_file" "bash -v $bash_file >${bash_file%.*}.log 2>&1" +} + +# $ generate_tests [-y|--yosys-scripts] [-s|--prove-sv] [-b|--bash] [-a|--yosys-args yosys_args] +generate_tests() { + do_ys=false + do_sv=false + do_sh=false + yosys_args="" + + while [[ $# -gt 0 ]]; do + arg="$1" + case "$arg" in + -y|--yosys-scripts) + do_ys=true + shift + ;; + -s|--prove-sv) + do_sv=true + shift + ;; + -b|--bash) + do_sh=true + shift + ;; + -a|--yosys-args) + yosys_args+="$2" + shift + shift + ;; + *) + echo >&2 "Unknown argument: $1" + exit 1 + esac + done + + if [[ ! ( $do_ys = true || $do_sv = true || $do_sh = true ) ]]; then + echo >&2 "Error: No file types selected" + exit 1 + fi + + echo ".PHONY: all" + echo "all:" + + if [[ $do_ys = true ]]; then + for x in *.ys; do + generate_ys_test "$x" "$yosys_args" + done + fi; + if [[ $do_sv = true ]]; then + for x in *.sv; do + if [ ! -f "${x%.sv}.ys" ]; then + generate_ys_test "$x" "-p \"prep -top top; sat -verify -prove-asserts\" $yosys_args" + fi; + done + fi; + if [[ $do_sh == true ]]; then + for s in *.sh; do + if [ "$s" != "run-test.sh" ]; then + generate_bash_test "$s" + fi + done + fi +} + +run_tests() { + generate_tests "$@" > run-test.mk + exec ${MAKE:-make} -f run-test.mk +} diff --git a/tests/liberty/run-test.sh b/tests/liberty/run-test.sh index 7e2ed2370..61f19b09b 100755 --- a/tests/liberty/run-test.sh +++ b/tests/liberty/run-test.sh @@ -5,6 +5,6 @@ for x in *.lib; do echo "Running $x.." echo "read_verilog small.v" > test.ys echo "synth -top small" >> test.ys - echo "dfflibmap -liberty ${x}" >> test.ys + echo "dfflibmap -info -liberty ${x}" >> test.ys ../../yosys -ql ${x%.lib}.log -s test.ys done diff --git a/tests/memories/run-test.sh b/tests/memories/run-test.sh index 8d1a8b413..376f5bf79 100755 --- a/tests/memories/run-test.sh +++ b/tests/memories/run-test.sh @@ -9,12 +9,12 @@ while getopts "A:S:" opt do case "$opt" in A) abcopt="-A $OPTARG" ;; - S) seed="-S $OPTARG" ;; + S) seed="$OPTARG" ;; esac done shift "$((OPTIND-1))" -bash ../tools/autotest.sh $abcopt $seed -G *.v +${MAKE:-make} -f ../tools/autotest.mk SEED="$seed" EXTRA_FLAGS="$abcopt" *.v for f in `egrep -l 'expect-(wr-ports|rd-ports|rd-clk)' *.v`; do echo -n "Testing expectations for $f .." diff --git a/tests/opt/.gitignore b/tests/opt/.gitignore index 397b4a762..8355de9dc 100644 --- a/tests/opt/.gitignore +++ b/tests/opt/.gitignore @@ -1 +1,2 @@ *.log +run-test.mk diff --git a/tests/opt/bug2221.ys b/tests/opt/bug2221.ys new file mode 100644 index 000000000..8ac380243 --- /dev/null +++ b/tests/opt/bug2221.ys @@ -0,0 +1,16 @@ +read_verilog <<EOT +module test ( + input [1:0] a, + input [1:0] b, + output [5:0] y +); + +wire [5:0] aa = {a, 4'h0}; +wire [5:0] bb = {b, 4'h0}; + +assign y = aa * bb; + +endmodule +EOT + +equiv_opt -assert opt_expr diff --git a/tests/opt/bug2311.ys b/tests/opt/bug2311.ys new file mode 100644 index 000000000..455147cd3 --- /dev/null +++ b/tests/opt/bug2311.ys @@ -0,0 +1,14 @@ +read_verilog -icells << EOT + +module top(...); + +input A; +output Y; + +$_XNOR_ x (.A(A), .B(A), .Y(Y)); + +endmodule + +EOT + +equiv_opt -assert opt_expr diff --git a/tests/opt/bug2318.ys b/tests/opt/bug2318.ys new file mode 100644 index 000000000..9de6f88ec --- /dev/null +++ b/tests/opt/bug2318.ys @@ -0,0 +1,12 @@ +read_verilog <<EOT +module t(input [3:0] A, input [3:0] B, output signed [3:0] Y); + +wire [7:0] P = A * B; +wire signed [7:0] SP = P; +wire signed [3:0] SB = B; +assign Y = SP / SB; + +endmodule +EOT + +equiv_opt -assert peepopt diff --git a/tests/opt/opt_clean_mem.ys b/tests/opt/opt_clean_mem.ys new file mode 100644 index 000000000..b35b15871 --- /dev/null +++ b/tests/opt/opt_clean_mem.ys @@ -0,0 +1,49 @@ +read_verilog <<EOT +module top(...); + +input [7:0] wa; +input [7:0] ra1; +input [7:0] ra2; +input [7:0] wd; +input clk; +wire [7:0] rd1; +wire [7:0] rd2; + +reg [7:0] mem[0:7]; + +always @(posedge clk) + mem[wa] <= wd; +assign rd1 = mem[ra1]; +assign rd2 = mem[ra2]; + +initial mem[8'h12] = 8'h34; + +endmodule +EOT + +proc +memory_dff + +select -assert-count 2 t:$memrd +select -assert-count 1 t:$memwr +select -assert-count 1 t:$meminit +design -save orig + +opt_clean +select -assert-none t:$memrd +select -assert-none t:$memwr +select -assert-none t:$meminit + +design -load orig +expose top/rd1 +opt_clean +select -assert-count 1 t:$memrd +select -assert-count 1 t:$memwr +select -assert-count 1 t:$meminit + +design -load orig +expose top/rd1 top/rd2 +opt_clean +select -assert-count 2 t:$memrd +select -assert-count 1 t:$memwr +select -assert-count 1 t:$meminit diff --git a/tests/opt/opt_dff_arst.ys b/tests/opt/opt_dff_arst.ys new file mode 100644 index 000000000..2aa3b7a26 --- /dev/null +++ b/tests/opt/opt_dff_arst.ys @@ -0,0 +1,101 @@ +### Always-active ARST removal. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [1:0] D; +output [11:0] Q; +input ARST; +input EN; + +$adff #(.CLK_POLARITY(1'b1), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff0 (.CLK(CLK), .ARST(1'b1), .D(D), .Q(Q[1:0])); +$adffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .ARST_POLARITY(1'b0), .ARST_VALUE(2'h2), .WIDTH(2)) ff1 (.CLK(CLK), .ARST(1'b0), .EN(EN), .D(D), .Q(Q[3:2])); +$adlatch #(.EN_POLARITY(1'b1), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff2 (.EN(EN), .ARST(1'b1), .D(D), .Q(Q[5:4])); +$adff #(.CLK_POLARITY(1'b1), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff3 (.CLK(CLK), .ARST(1'bx), .D(D), .Q(Q[7:6])); +$adffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .ARST_POLARITY(1'b0), .ARST_VALUE(2'h2), .WIDTH(2)) ff4 (.CLK(CLK), .ARST(1'bx), .EN(EN), .D(D), .Q(Q[9:8])); +$adlatch #(.EN_POLARITY(1'b1), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff5 (.EN(EN), .ARST(1'bx), .D(D), .Q(Q[11:10])); + + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-none t:* + +design -load orig + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 1 t:$adff +select -assert-count 1 t:$adffe +select -assert-count 1 t:$adlatch + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-none t:* + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 2 t:$_DFF_???_ +select -assert-count 2 t:$_DFFE_????_ +select -assert-count 2 t:$_DLATCH_???_ + +design -reset + + +### Never-active ARST removal. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [1:0] D; +output [5:0] Q; +input ARST; +input EN; + +$adff #(.CLK_POLARITY(1'b1), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff0 (.CLK(CLK), .ARST(1'b0), .D(D), .Q(Q[1:0])); +$adffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .ARST_POLARITY(1'b0), .ARST_VALUE(2'h2), .WIDTH(2)) ff1 (.CLK(CLK), .ARST(1'b1), .EN(EN), .D(D), .Q(Q[3:2])); +$adlatch #(.EN_POLARITY(1'b1), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff2 (.EN(EN), .ARST(1'b0), .D(D), .Q(Q[5:4])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-none t:$adff +select -assert-none t:$adffe +select -assert-none t:$adlatch +select -assert-count 1 t:$dff +select -assert-count 1 t:$dffe +select -assert-count 1 t:$dlatch + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-none t:$_DFF_???_ +select -assert-none t:$_DFFE_????_ +select -assert-none t:$_DLATCH_???_ +select -assert-count 2 t:$_DFF_P_ +select -assert-count 2 t:$_DFFE_PP_ +select -assert-count 2 t:$_DLATCH_P_ + +design -reset diff --git a/tests/opt/opt_dff_clk.ys b/tests/opt/opt_dff_clk.ys new file mode 100644 index 000000000..f3aefa406 --- /dev/null +++ b/tests/opt/opt_dff_clk.ys @@ -0,0 +1,45 @@ +### Never-toggling CLK removal. + +read_verilog -icells <<EOT + +module top(...); + +input EN; +input [1:0] D; +(* init = 18'h15555 *) +output [17:0] Q; +input SRST; +input ARST; +input [1:0] CLR; +input [1:0] SET; + +$dff #(.CLK_POLARITY(1'b1), .WIDTH(2)) ff0 (.CLK(1'b0), .D(D), .Q(Q[1:0])); +$dffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(2)) ff1 (.CLK(1'b1), .EN(EN), .D(D), .Q(Q[3:2])); +$adff #(.CLK_POLARITY(1'b1), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff2 (.CLK(1'bx), .ARST(ARST), .D(D), .Q(Q[5:4])); +$adffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff3 (.CLK(1'b0), .EN(EN), .ARST(ARST), .D(D), .Q(Q[7:6])); +$sdff #(.CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff4 (.CLK(1'b1), .SRST(SRST), .D(D), .Q(Q[9:8])); +$sdffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff5 (.CLK(1'bx), .EN(EN), .SRST(SRST), .D(D), .Q(Q[11:10])); +$sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff6 (.CLK(1'bx), .EN(EN), .SRST(SRST), .D(D), .Q(Q[13:12])); +$dffsr #(.CLK_POLARITY(1'b1), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff7 (.CLK(1'b1), .SET(SET), .CLR(CLR), .D(D), .Q(Q[15:14])); +$dffsre #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff8 (.CLK(1'bx), .EN(EN), .SET(SET), .CLR(CLR), .D(D), .Q(Q[17:16])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 2 t:$dlatch +select -assert-count 2 t:$sr +select -assert-none t:$dlatch t:$sr %% %n t:* %i + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 4 t:$_DLATCH_?_ +select -assert-count 4 t:$_SR_??_ +select -assert-none t:$_DLATCH_?_ t:$_SR_??_ %% %n t:* %i diff --git a/tests/opt/opt_dff_const.ys b/tests/opt/opt_dff_const.ys new file mode 100644 index 000000000..6a7dec7fa --- /dev/null +++ b/tests/opt/opt_dff_const.ys @@ -0,0 +1,49 @@ +### Replace FFs with a const. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input EN; +(* init=84'haaaaaaaaaaaaaaaaaaaaa *) +output [83:0] Q; +input SRST; +input ARST; +input [3:0] CLR; +input [3:0] SET; + +$dff #(.CLK_POLARITY(1'b1), .WIDTH(4)) ff0 (.CLK(CLK), .D(4'hc), .Q(Q[3:0])); +$dffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(4)) ff1 (.CLK(CLK), .EN(EN), .D(4'hc), .Q(Q[7:4])); +$adff #(.CLK_POLARITY(1'b1), .ARST_POLARITY(1'b1), .ARST_VALUE(8'hf0), .WIDTH(8)) ff2 (.CLK(CLK), .ARST(ARST), .D(8'hcc), .Q(Q[15:8])); +$adffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(8'hf0), .WIDTH(8)) ff3 (.CLK(CLK), .EN(EN), .ARST(ARST), .D(8'hcc), .Q(Q[23:16])); +$sdff #(.CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(8'hf0), .WIDTH(8)) ff4 (.CLK(CLK), .SRST(SRST), .D(8'hcc), .Q(Q[31:24])); +$sdffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(8'hf0), .WIDTH(8)) ff5 (.CLK(CLK), .EN(EN), .SRST(SRST), .D(8'hcc), .Q(Q[39:32])); +$sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(8'hf0), .WIDTH(8)) ff6 (.CLK(CLK), .EN(EN), .SRST(SRST), .D(8'hcc), .Q(Q[47:40])); +$dffsr #(.CLK_POLARITY(1'b1), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(8)) ff7 (.CLK(CLK), .SET({SET, 4'hf}), .CLR({4'h0, CLR}), .D(8'hcc), .Q(Q[55:48])); +$dffsre #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .CLR_POLARITY(1'b0), .SET_POLARITY(1'b1), .WIDTH(8)) ff8 (.CLK(CLK), .EN(EN), .SET({SET, 4'h0}), .CLR({4'hf, CLR}), .D(8'hcc), .Q(Q[63:56])); + +$dlatch #(.EN_POLARITY(1'b1), .WIDTH(4)) ff9 (.EN(EN), .D(4'hc), .Q(Q[67:64])); +$adlatch #(.EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(8'hf0), .WIDTH(8)) ff10 (.EN(EN), .ARST(ARST), .D(8'hcc), .Q(Q[75:68])); +$dlatchsr #(.EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b1), .WIDTH(8)) ff11 (.EN(EN), .SET({SET, 4'h0}), .CLR({4'h0, CLR}), .D(8'hcc), .Q(Q[83:76])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-count 1 t:$dff r:WIDTH=2 %i +select -assert-count 1 t:$dffe r:WIDTH=2 %i +select -assert-count 1 t:$adff r:WIDTH=6 %i +select -assert-count 1 t:$adffe r:WIDTH=6 %i +select -assert-count 1 t:$sdff r:WIDTH=6 %i +select -assert-count 1 t:$sdffe r:WIDTH=6 %i +select -assert-count 1 t:$sdffce r:WIDTH=6 %i +select -assert-count 1 t:$dffsr r:WIDTH=6 %i +select -assert-count 1 t:$dffsre r:WIDTH=6 %i +select -assert-count 1 t:$dlatch r:WIDTH=2 %i +select -assert-count 1 t:$adlatch r:WIDTH=6 %i +select -assert-count 1 t:$dlatchsr r:WIDTH=6 %i diff --git a/tests/opt/opt_dff_dffmux.ys b/tests/opt/opt_dff_dffmux.ys new file mode 100644 index 000000000..43190cc31 --- /dev/null +++ b/tests/opt/opt_dff_dffmux.ys @@ -0,0 +1,129 @@ +design -reset +read_verilog <<EOT +module opt_dffmuxext_unsigned(input clk, ce, input [1:0] i, output reg [3:0] o); + always @(posedge clk) if (ce) o <= i; +endmodule +EOT + +proc +equiv_opt -assert opt +design -load postopt +select -assert-count 1 t:$dffe r:WIDTH=2 %i +select -assert-count 0 t:$dffe %% t:* %D + +#################### + +design -reset +read_verilog <<EOT +module opt_dffmuxext_signed(input clk, ce, input signed [1:0] i, output reg signed [3:0] o); + always @(posedge clk) if (ce) o <= i; +endmodule +EOT + +proc +equiv_opt -assert opt +design -load postopt +wreduce +select -assert-count 1 t:$dffe r:WIDTH=2 %i +select -assert-count 0 t:$dffe %% t:* %D + +################### + +design -reset +read_verilog <<EOT +module opt_dffmuxext_const(input clk, ce, input [1:0] i, output reg [5:0] o); + always @(posedge clk) if (ce) o <= {1'b0, i[1], 2'b1x, i[0], 1'bz}; +endmodule +EOT + +proc +equiv_opt -assert opt +design -load postopt +select -assert-count 1 t:$dffe r:WIDTH=2 %i +select -assert-count 0 t:$dffe %% t:* %D + +################### + +design -reset +read_verilog <<EOT +module opt_dffmuxext_const_init(input clk, ce, input [1:0] i, (* init=6'b0x00x1 *) output reg [5:0] o); + always @(posedge clk) if (ce) o <= {1'b0, i[1], 2'b1x, i[0], 1'bz}; +endmodule +EOT + +proc +equiv_opt -assert opt +design -load postopt +select -assert-count 1 t:$dffe r:WIDTH=4 %i +select -assert-count 0 t:$dffe %% t:* %D + +#################### + +design -reset +read_verilog <<EOT +module opt_dffmuxext_unsigned_rst(input clk, ce, rst, input [1:0] i, output reg [3:0] o); + always @(posedge clk) if (rst) o <= 0; else if (ce) o <= i; +endmodule +EOT + +proc +equiv_opt -assert opt +design -load postopt +wreduce +select -assert-count 1 t:$sdffe r:WIDTH=2 %i +select -assert-count 0 t:$sdffe %% t:* %D + +#################### + +design -reset +read_verilog <<EOT +module opt_dffmuxext_signed_rst(input clk, ce, rstn, input signed [1:0] i, output reg signed [3:0] o); + always @(posedge clk) begin + if (ce) o <= i; + if (!rstn) o <= 4'b1111; + end +endmodule +EOT + +proc +equiv_opt -assert opt +design -load postopt +wreduce +select -assert-count 1 t:$sdffe r:WIDTH=2 %i +select -assert-count 0 t:$sdffe %% t:* %D + +#################### + +design -reset +read_verilog <<EOT +module opt_dffmuxext_signed_rst_init(input clk, ce, rstn, input signed [1:0] i, output reg signed [3:0] o); + initial o <= 4'b0010; + always @(posedge clk) begin + if (ce) o <= i; + if (!rstn) o <= 4'b1111; + end +endmodule +EOT + +proc +# NB: equiv_opt uses equiv_induct which covers +# only the induction half of temporal induction +# --- missing the base-case half +# This makes it akin to `sat -tempinduct-inductonly` +# instead of `sat -tempinduct-baseonly` or +# `sat -tempinduct` which is necessary for this +# testcase +#equiv_opt -assert opt + +design -save gold +opt +wreduce +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -tempinduct -verify -prove-asserts -show-ports miter + +design -load gate +select -assert-count 1 t:$sdffe r:WIDTH=3 %i +select -assert-count 0 t:$sdffe %% t:* %D diff --git a/tests/opt/opt_dff_en.ys b/tests/opt/opt_dff_en.ys new file mode 100644 index 000000000..06ee6c63d --- /dev/null +++ b/tests/opt/opt_dff_en.ys @@ -0,0 +1,157 @@ +### Always-active EN removal. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [1:0] D; +output [15:0] Q; +input SRST; +input ARST; +input [1:0] CLR; +input [1:0] SET; + +$dffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(2)) ff0 (.CLK(CLK), .EN(1'b1), .D(D), .Q(Q[1:0])); +$adffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff1 (.CLK(CLK), .EN(1'b0), .ARST(ARST), .D(D), .Q(Q[3:2])); +$sdffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff2 (.CLK(CLK), .EN(1'b1), .SRST(SRST), .D(D), .Q(Q[5:4])); +$sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff3 (.CLK(CLK), .EN(1'b1), .SRST(SRST), .D(D), .Q(Q[7:6])); +$dffsre #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff4 (.CLK(CLK), .EN(1'b0), .SET(SET), .CLR(CLR), .D(D), .Q(Q[9:8])); + +$dlatch #(.EN_POLARITY(1'b1), .WIDTH(2)) ff5 (.EN(1'b1), .D(D), .Q(Q[11:10])); +$adlatch #(.EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff6 (.EN(1'b0), .ARST(ARST), .D(D), .Q(Q[13:12])); +$dlatchsr #(.EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff7 (.EN(1'b0), .SET(SET), .CLR(CLR), .D(D), .Q(Q[15:14])); + +endmodule + +EOT + +design -save orig + +# Equivalence check will fail for unmapped adlatch and dlatchsr due to negative hold hack. +delete top/ff6 top/ff7 +equiv_opt -undef -assert -multiclock opt_dff + +design -load orig +delete top/ff6 top/ff7 +simplemap +equiv_opt -undef -assert -multiclock opt_dff + +design -load orig +opt_dff +select -assert-count 0 t:$dffe +select -assert-count 0 t:$adffe +select -assert-count 0 t:$sdffe +select -assert-count 0 t:$sdffce +select -assert-count 0 t:$dffsre +select -assert-count 0 t:$dlatch +select -assert-count 0 t:$adlatch +select -assert-count 0 t:$dlatchsr +select -assert-count 1 t:$dff +select -assert-count 2 t:$sdff +select -assert-count 1 t:$adff +select -assert-count 1 t:$dffsr + +design -load orig +simplemap +opt_dff +select -assert-count 0 t:$_DFFE_* +select -assert-count 0 t:$_SDFFE_* +select -assert-count 0 t:$_SDFFCE_* +select -assert-count 0 t:$_DFFSRE_* +select -assert-count 0 t:$_DLATCH* +select -assert-count 2 t:$_DFF_P_ +select -assert-count 4 t:$_SDFF_PP?_ +select -assert-count 2 t:$_DFF_PP?_ +select -assert-count 2 t:$_DFFSR_PNP_ + +design -reset + + + +### Never-active EN removal. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [1:0] D; +(* init = 32'h55555555 *) +output [31:0] Q; +input SRST; +input ARST; +input [1:0] CLR; +input [1:0] SET; + +$dffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(2)) ff0 (.CLK(CLK), .EN(1'b0), .D(D), .Q(Q[1:0])); +$adffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff1 (.CLK(CLK), .EN(1'b1), .ARST(ARST), .D(D), .Q(Q[3:2])); +$sdffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff2 (.CLK(CLK), .EN(1'b0), .SRST(SRST), .D(D), .Q(Q[5:4])); +$sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff3 (.CLK(CLK), .EN(1'b0), .SRST(SRST), .D(D), .Q(Q[7:6])); +$dffsre #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff4 (.CLK(CLK), .EN(1'b1), .SET(SET), .CLR(CLR), .D(D), .Q(Q[9:8])); + +$dlatch #(.EN_POLARITY(1'b1), .WIDTH(2)) ff5 (.EN(1'b0), .D(D), .Q(Q[11:10])); +$adlatch #(.EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff6 (.EN(1'b1), .ARST(ARST), .D(D), .Q(Q[13:12])); +$dlatchsr #(.EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff7 (.EN(1'b1), .SET(SET), .CLR(CLR), .D(D), .Q(Q[15:14])); + +$dffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(2)) ff8 (.CLK(CLK), .EN(1'bx), .D(D), .Q(Q[17:16])); +$adffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff9 (.CLK(CLK), .EN(1'bx), .ARST(ARST), .D(D), .Q(Q[19:18])); +$sdffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff10 (.CLK(CLK), .EN(1'bx), .SRST(SRST), .D(D), .Q(Q[21:20])); +$sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff11 (.CLK(CLK), .EN(1'bx), .SRST(SRST), .D(D), .Q(Q[23:22])); +$dffsre #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff12 (.CLK(CLK), .EN(1'bx), .SET(SET), .CLR(CLR), .D(D), .Q(Q[25:24])); + +$dlatch #(.EN_POLARITY(1'b1), .WIDTH(2)) ff13 (.EN(1'bx), .D(D), .Q(Q[27:26])); +$adlatch #(.EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff14 (.EN(1'bx), .ARST(ARST), .D(D), .Q(Q[29:28])); +$dlatchsr #(.EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff15 (.EN(1'bx), .SET(SET), .CLR(CLR), .D(D), .Q(Q[31:30])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-count 2 t:$dffe +select -assert-count 4 t:$dlatch +select -assert-count 4 t:$sr +select -assert-none t:$dffe t:$dlatch t:$sr %% %n t:* %i + +design -load orig + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 2 t:$dffe +select -assert-count 1 t:$adffe +select -assert-count 1 t:$sdffe +select -assert-count 1 t:$sdffce +select -assert-count 1 t:$dffsre +select -assert-count 3 t:$dlatch +select -assert-count 1 t:$adlatch +select -assert-count 1 t:$dlatchsr +select -assert-count 2 t:$sr + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-count 4 t:$_DFFE_??_ +select -assert-count 8 t:$_DLATCH_?_ +select -assert-count 8 t:$_SR_??_ +select -assert-none t:$_DFFE_??_ t:$_DLATCH_?_ t:$_SR_??_ %% %n t:* %i + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 4 t:$_DFFE_??_ +select -assert-count 2 t:$_DFFE_????_ +select -assert-count 2 t:$_SDFFE_????_ +select -assert-count 2 t:$_SDFFCE_????_ +select -assert-count 2 t:$_DFFSRE_????_ +select -assert-count 6 t:$_DLATCH_?_ +select -assert-count 2 t:$_DLATCH_???_ +select -assert-count 2 t:$_DLATCHSR_???_ +select -assert-count 4 t:$_SR_??_ diff --git a/tests/opt/opt_dff_mux.ys b/tests/opt/opt_dff_mux.ys new file mode 100644 index 000000000..ed01bed59 --- /dev/null +++ b/tests/opt/opt_dff_mux.ys @@ -0,0 +1,86 @@ +### CE and SRST matching. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input NE, NS; +input EN; +output [23:0] Q; +input [23:0] D; +input SRST; +input ARST; +input [1:0] CLR; +input [1:0] SET; + +$dff #(.CLK_POLARITY(1'b1), .WIDTH(2)) ff0 (.CLK(CLK), .D(NS ? 2'h2 : NE ? D[1:0] : Q[1:0]), .Q(Q[1:0])); +$dffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(2)) ff1 (.CLK(CLK), .EN(EN), .D(NS ? 2'h2 : NE ? D[3:2] : Q[3:2]), .Q(Q[3:2])); +$adff #(.CLK_POLARITY(1'b1), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff2 (.CLK(CLK), .ARST(ARST), .D(NS ? 2'h2 : NE ? D[5:4] : Q[5:4]), .Q(Q[5:4])); +$adffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff3 (.CLK(CLK), .EN(EN), .ARST(ARST), .D(NS ? 2'h2 : NE ? D[7:6] : Q[7:6]), .Q(Q[7:6])); +$sdff #(.CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff4 (.CLK(CLK), .SRST(SRST), .D(NS ? 2'h2 : NE ? D[9:8] : Q[9:8]), .Q(Q[9:8])); +$sdffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff5 (.CLK(CLK), .EN(EN), .SRST(SRST), .D(NS ? 2'h2 : NE ? D[11:10] : Q[11:10]), .Q(Q[11:10])); +$sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff6 (.CLK(CLK), .EN(EN), .SRST(SRST), .D(NS ? 2'h2 : NE ? D[13:12] : Q[13:12]), .Q(Q[13:12])); +$dffsr #(.CLK_POLARITY(1'b1), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff7 (.CLK(CLK), .SET(SET), .CLR(CLR), .D(NS ? 2'h2 : NE ? D[15:14] : Q[15:14]), .Q(Q[15:14])); +$dffsre #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff8 (.CLK(CLK), .EN(EN), .SET(SET), .CLR(CLR), .D(NS ? 2'h2 : NE ? D[17:16] : Q[17:16]), .Q(Q[17:16])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +clean +select -assert-count 0 t:$dff +select -assert-count 0 t:$dffe +select -assert-count 0 t:$adff +select -assert-count 2 t:$adffe +select -assert-count 0 t:$dffsr +select -assert-count 2 t:$dffsre +select -assert-count 0 t:$sdff +select -assert-count 3 t:$sdffe +select -assert-count 2 t:$sdffce + +design -load orig + +equiv_opt -undef -assert -multiclock opt_dff -nodffe -nosdff +design -load postopt +clean +select -assert-count 1 t:$dff +select -assert-count 1 t:$dffe +select -assert-count 1 t:$adff +select -assert-count 1 t:$adffe +select -assert-count 1 t:$dffsr +select -assert-count 1 t:$dffsre +select -assert-count 1 t:$sdff +select -assert-count 1 t:$sdffe +select -assert-count 1 t:$sdffce +equiv_opt -undef -assert -multiclock opt_dff -nodffe +design -load postopt +clean +select -assert-count 0 t:$dff +select -assert-count 0 t:$dffe +select -assert-count 1 t:$adff +select -assert-count 1 t:$adffe +select -assert-count 1 t:$dffsr +select -assert-count 1 t:$dffsre +select -assert-count 2 t:$sdff +select -assert-count 1 t:$sdffe +select -assert-count 2 t:$sdffce + +design -load orig + +equiv_opt -undef -assert -multiclock opt_dff -nosdff +design -load postopt +clean +select -assert-count 0 t:$dff +select -assert-count 2 t:$dffe +select -assert-count 0 t:$adff +select -assert-count 2 t:$adffe +select -assert-count 0 t:$dffsr +select -assert-count 2 t:$dffsre +select -assert-count 0 t:$sdff +select -assert-count 2 t:$sdffe +select -assert-count 1 t:$sdffce diff --git a/tests/opt/opt_dff_qd.ys b/tests/opt/opt_dff_qd.ys new file mode 100644 index 000000000..afc96c42f --- /dev/null +++ b/tests/opt/opt_dff_qd.ys @@ -0,0 +1,56 @@ +### Q = D case. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input EN; +(* init = 24'h555555 *) +output [23:0] Q; +input SRST; +input ARST; +input [1:0] CLR; +input [1:0] SET; + +$dff #(.CLK_POLARITY(1'b1), .WIDTH(2)) ff0 (.CLK(CLK), .D(Q[1:0]), .Q(Q[1:0])); +$dffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(2)) ff1 (.CLK(CLK), .EN(EN), .D(Q[3:2]), .Q(Q[3:2])); +$adff #(.CLK_POLARITY(1'b1), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff2 (.CLK(CLK), .ARST(ARST), .D(Q[5:4]), .Q(Q[5:4])); +$adffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff3 (.CLK(CLK), .EN(EN), .ARST(ARST), .D(Q[7:6]), .Q(Q[7:6])); +$sdff #(.CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff4 (.CLK(CLK), .SRST(SRST), .D(Q[9:8]), .Q(Q[9:8])); +$sdffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff5 (.CLK(CLK), .EN(EN), .SRST(SRST), .D(Q[11:10]), .Q(Q[11:10])); +$sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff6 (.CLK(CLK), .EN(EN), .SRST(SRST), .D(Q[13:12]), .Q(Q[13:12])); +$dffsr #(.CLK_POLARITY(1'b1), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff7 (.CLK(CLK), .SET(SET), .CLR(CLR), .D(Q[15:14]), .Q(Q[15:14])); +$dffsre #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff8 (.CLK(CLK), .EN(EN), .SET(SET), .CLR(CLR), .D(Q[17:16]), .Q(Q[17:16])); + +$dlatch #(.EN_POLARITY(1'b1), .WIDTH(2)) ff9 (.EN(EN), .D(Q[19:18]), .Q(Q[19:18])); +$adlatch #(.EN_POLARITY(1'b0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2), .WIDTH(2)) ff10 (.EN(EN), .ARST(ARST), .D(Q[21:20]), .Q(Q[21:20])); +$dlatchsr #(.EN_POLARITY(1'b0), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0), .WIDTH(2)) ff11 (.EN(EN), .SET(SET), .CLR(CLR), .D(Q[23:22]), .Q(Q[23:22])); + +endmodule + +EOT + +design -save orig + +# Equivalence check will fail for unmapped adlatch and dlatchsr due to negative hold hack. +delete top/ff10 top/ff11 +equiv_opt -undef -assert -multiclock opt_dff -keepdc + +design -load orig +opt_dff -keepdc +select -assert-count 1 t:$and +select -assert-count 3 t:$dffe +select -assert-count 3 t:$dlatch +select -assert-count 3 t:$sr +select -assert-none t:$and t:$dffe t:$dlatch t:$sr %% %n t:* %i + +design -load orig +simplemap +opt_dff -keepdc +select -assert-count 2 t:$_AND_ +select -assert-count 6 t:$_DFFE_??_ +select -assert-count 6 t:$_DLATCH_?_ +select -assert-count 6 t:$_SR_??_ +select -assert-none t:$_AND_ t:$_DFFE_??_ t:$_DLATCH_?_ t:$_SR_??_ %% %n t:* %i + diff --git a/tests/opt/opt_dff_sr.ys b/tests/opt/opt_dff_sr.ys new file mode 100644 index 000000000..daedb115c --- /dev/null +++ b/tests/opt/opt_dff_sr.ys @@ -0,0 +1,304 @@ +### Always-active SET/CLR removal. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [5:0] D; +output [23:0] Q; +input CLR; +input SET; +input EN; + +$dffsr #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b1), .CLR_POLARITY(1'b1), .WIDTH(6)) ff0 (.CLK(CLK), .CLR({CLR, CLR, CLR, 1'b1, 1'b0, 1'bx}), .SET({1'b1, 1'b0, 1'bx, SET, SET, SET}), .D(D), .Q(Q[5:0])); +$dffsre #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b0), .CLR_POLARITY(1'b0), .EN_POLARITY(1'b1), .WIDTH(6)) ff1 (.CLK(CLK), .EN(EN), .CLR({CLR, CLR, CLR, 1'b1, 1'b0, 1'bx}), .SET({1'b1, 1'b0, 1'bx, SET, SET, SET}), .D(D), .Q(Q[11:6])); +$dlatchsr #(.SET_POLARITY(1'b0), .CLR_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(6)) ff2 (.EN(EN), .CLR({CLR, CLR, CLR, 1'b1, 1'b0, 1'bx}), .SET({1'b1, 1'b0, 1'bx, SET, SET, SET}), .D(D), .Q(Q[17:12])); +$sr #(.SET_POLARITY(1'b1), .CLR_POLARITY(1'b0), .WIDTH(6)) ff3 (.CLR({CLR, CLR, CLR, 1'b1, 1'b0, 1'bx}), .SET({1'b1, 1'b0, 1'bx, SET, SET, SET}), .Q(Q[23:18])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-count 1 t:$dffsr +select -assert-count 1 t:$dffsr r:WIDTH=2 %i +select -assert-count 1 t:$dffsre +select -assert-count 1 t:$dffsre r:WIDTH=2 %i +select -assert-count 1 t:$dlatchsr +select -assert-count 1 t:$dlatchsr r:WIDTH=2 %i +select -assert-none t:$sr + +design -load orig + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 1 t:$dffsr +select -assert-count 1 t:$dffsr r:WIDTH=4 %i +select -assert-count 1 t:$dffsre +select -assert-count 1 t:$dffsre r:WIDTH=4 %i +select -assert-count 1 t:$dlatchsr +select -assert-count 1 t:$dlatchsr r:WIDTH=4 %i +select -assert-count 1 t:$sr +select -assert-count 1 t:$sr r:WIDTH=4 %i + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-count 1 t:$_DFF_PP0_ +select -assert-count 1 t:$_DFF_PP1_ +select -assert-count 1 t:$_DFFE_PN0P_ +select -assert-count 1 t:$_DFFE_PN1P_ +select -assert-count 1 t:$_DLATCH_PP0_ +select -assert-count 1 t:$_DLATCH_PN1_ +select -assert-none t:$_DFF_PP0_ t:$_DFF_PP1_ t:$_DFFE_PN0P_ t:$_DFFE_PN1P_ t:$_DLATCH_PP0_ t:$_DLATCH_PN1_ t:$_NOT_ %% %n t:* %i + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 1 t:$_DFF_PP0_ +select -assert-count 1 t:$_DFF_PP1_ +select -assert-count 2 t:$_DFFSR_PPP_ +select -assert-count 1 t:$_DFFE_PN0P_ +select -assert-count 1 t:$_DFFE_PN1P_ +select -assert-count 2 t:$_DFFSRE_PNNP_ +select -assert-count 1 t:$_DLATCH_PP0_ +select -assert-count 1 t:$_DLATCH_PN1_ +select -assert-count 2 t:$_DLATCHSR_PNP_ +select -assert-count 1 t:$_DLATCH_P_ +select -assert-count 1 t:$_DLATCH_N_ +select -assert-count 2 t:$_SR_PN_ +select -assert-none t:$_DFF_PP0_ t:$_DFF_PP1_ t:$_DFFSR_PPP_ t:$_DFFE_PN0P_ t:$_DFFE_PN1P_ t:$_DFFSRE_PNNP_ t:$_DLATCH_PP0_ t:$_DLATCH_PN1_ t:$_DLATCHSR_PNP_ t:$_NOT_ t:$_DLATCH_N_ t:$_DLATCH_P_ t:$_SR_PN_ %% %n t:* %i + +design -reset + + + +### Never-active CLR removal. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [5:0] D; +output [23:0] Q; +input CLR; +input SET; +input EN; + +$dffsr #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b1), .CLR_POLARITY(1'b1), .WIDTH(6)) ff0 (.CLK(CLK), .CLR(6'h00), .SET({6{SET}}), .D(D), .Q(Q[5:0])); +$dffsre #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b0), .CLR_POLARITY(1'b0), .EN_POLARITY(1'b1), .WIDTH(6)) ff1 (.CLK(CLK), .EN(EN), .D(D), .CLR(6'h3f), .SET({6{SET}}), .Q(Q[11:6])); +$dlatchsr #(.SET_POLARITY(1'b0), .CLR_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(6)) ff2 (.EN(EN), .D(D), .CLR(6'h00), .SET({6{SET}}), .Q(Q[17:12])); +$sr #(.SET_POLARITY(1'b1), .CLR_POLARITY(1'b0), .WIDTH(6)) ff3 (.CLR(6'h3f), .SET({6{SET}}), .Q(Q[23:18])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 0 t:$dffsr +select -assert-count 0 t:$dffsre +select -assert-count 0 t:$dlatchsr +select -assert-count 0 t:$sr +select -assert-count 1 t:$adff +select -assert-count 1 t:$adffe +select -assert-count 1 t:$adlatch +select -assert-count 1 t:$dlatch + +design -reset + + + +### Never-active CLR removal (not applicable). + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [5:0] D; +output [23:0] Q; +input CLR; +input SET; +input ALT; +input EN; + +$dffsr #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b1), .CLR_POLARITY(1'b1), .WIDTH(6)) ff0 (.CLK(CLK), .CLR(6'h00), .SET({{5{SET}}, ALT}), .D(D), .Q(Q[5:0])); +$dffsre #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b0), .CLR_POLARITY(1'b0), .EN_POLARITY(1'b1), .WIDTH(6)) ff1 (.CLK(CLK), .EN(EN), .D(D), .CLR(6'h3f), .SET({{5{SET}}, ALT}), .Q(Q[11:6])); +$dlatchsr #(.SET_POLARITY(1'b0), .CLR_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(6)) ff2 (.EN(EN), .D(D), .CLR(6'h00), .SET({{5{SET}}, ALT}), .Q(Q[17:12])); +$sr #(.SET_POLARITY(1'b1), .CLR_POLARITY(1'b0), .WIDTH(6)) ff3 (.CLR(6'h3f), .SET({{5{SET}}, ALT}), .Q(Q[23:18])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 1 t:$dffsr +select -assert-count 1 t:$dffsre +select -assert-count 1 t:$dlatchsr +select -assert-count 1 t:$sr +select -assert-count 0 t:$adff +select -assert-count 0 t:$adffe +select -assert-count 0 t:$adlatch +select -assert-count 0 t:$dlatch + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 0 t:$_DFFSR_* +select -assert-count 0 t:$_DFFSRE_* +select -assert-count 0 t:$_DLATCHSR_* +select -assert-count 0 t:$_SR_* +select -assert-count 6 t:$_DFF_PP1_ +select -assert-count 6 t:$_DFFE_PN1P_ +select -assert-count 6 t:$_DLATCH_PN1_ +select -assert-count 6 t:$_DLATCH_P_ + +design -reset + + + +### Never-active SET removal. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [5:0] D; +output [23:0] Q; +input CLR; +input SET; +input EN; + +$dffsr #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b1), .CLR_POLARITY(1'b1), .WIDTH(6)) ff0 (.CLK(CLK), .CLR({6{CLR}}), .SET(6'h00), .D(D), .Q(Q[5:0])); +$dffsre #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b0), .CLR_POLARITY(1'b0), .EN_POLARITY(1'b1), .WIDTH(6)) ff1 (.CLK(CLK), .EN(EN), .D(D), .CLR({6{CLR}}), .SET(6'h3f), .Q(Q[11:6])); +$dlatchsr #(.SET_POLARITY(1'b0), .CLR_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(6)) ff2 (.EN(EN), .D(D), .CLR({6{CLR}}), .SET(6'h3f), .Q(Q[17:12])); +$sr #(.SET_POLARITY(1'b1), .CLR_POLARITY(1'b0), .WIDTH(6)) ff3 (.CLR({6{CLR}}), .SET(6'h00), .Q(Q[23:18])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 0 t:$dffsr +select -assert-count 0 t:$dffsre +select -assert-count 0 t:$dlatchsr +select -assert-count 0 t:$sr +select -assert-count 1 t:$adff +select -assert-count 1 t:$adffe +select -assert-count 1 t:$adlatch +select -assert-count 1 t:$dlatch + +design -reset + + + +### Never-active CLR removal (not applicable). + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [5:0] D; +output [23:0] Q; +input CLR; +input SET; +input ALT; +input EN; + +$dffsr #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b1), .CLR_POLARITY(1'b1), .WIDTH(6)) ff0 (.CLK(CLK), .CLR({{5{CLR}}, ALT}), .SET(6'h00), .D(D), .Q(Q[5:0])); +$dffsre #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b0), .CLR_POLARITY(1'b0), .EN_POLARITY(1'b1), .WIDTH(6)) ff1 (.CLK(CLK), .EN(EN), .D(D), .CLR({{5{CLR}}, ALT}), .SET(6'h3f), .Q(Q[11:6])); +$dlatchsr #(.SET_POLARITY(1'b0), .CLR_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(6)) ff2 (.EN(EN), .D(D), .CLR({{5{CLR}}, ALT}), .SET(6'h3f), .Q(Q[17:12])); +$sr #(.SET_POLARITY(1'b1), .CLR_POLARITY(1'b0), .WIDTH(6)) ff3 (.CLR({{5{CLR}}, ALT}), .SET(6'h00), .Q(Q[23:18])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 1 t:$dffsr +select -assert-count 1 t:$dffsre +select -assert-count 1 t:$dlatchsr +select -assert-count 1 t:$sr +select -assert-count 0 t:$adff +select -assert-count 0 t:$adffe +select -assert-count 0 t:$adlatch +select -assert-count 0 t:$dlatch + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 0 t:$_DFFSR_* +select -assert-count 0 t:$_DFFSRE_* +select -assert-count 0 t:$_DLATCHSR_* +select -assert-count 0 t:$_SR_* +select -assert-count 6 t:$_DFF_PP0_ +select -assert-count 6 t:$_DFFE_PN0P_ +select -assert-count 6 t:$_DLATCH_PP0_ +select -assert-count 6 t:$_DLATCH_N_ + +design -reset + + + +### SET/CLR merge into ARST. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [5:0] D; +output [23:0] Q; +input ARST; +input EN; + +$dffsr #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b1), .CLR_POLARITY(1'b1), .WIDTH(6)) ff0 (.CLK(CLK), .CLR({ARST, 5'h00}), .SET({1'b0, {5{ARST}}}), .D(D), .Q(Q[5:0])); +$dffsre #(.CLK_POLARITY(1'b1), .SET_POLARITY(1'b0), .CLR_POLARITY(1'b0), .EN_POLARITY(1'b1), .WIDTH(6)) ff1 (.CLK(CLK), .EN(EN), .D(D), .CLR({ARST, 5'h1f}), .SET({1'b1, {5{ARST}}}), .Q(Q[11:6])); +$dlatchsr #(.SET_POLARITY(1'b0), .CLR_POLARITY(1'b1), .EN_POLARITY(1'b1), .WIDTH(6)) ff2 (.EN(EN), .D(D), .CLR({ARST, 5'h00}), .SET({1'b1, {5{ARST}}}), .Q(Q[17:12])); +$sr #(.SET_POLARITY(1'b1), .CLR_POLARITY(1'b0), .WIDTH(6)) ff3 (.CLR({ARST, 5'h1f}), .SET({1'b0, {5{ARST}}}), .Q(Q[23:18])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 0 t:$dffsr +select -assert-count 0 t:$dffsre +select -assert-count 1 t:$dlatchsr +select -assert-count 1 t:$sr +select -assert-count 1 t:$adff +select -assert-count 1 t:$adff r:ARST_VALUE=6'h1f %i +select -assert-count 1 t:$adffe +select -assert-count 1 t:$adffe r:ARST_VALUE=6'h1f %i +select -assert-count 0 t:$adlatch +select -assert-count 0 t:$dlatch diff --git a/tests/opt/opt_dff_srst.ys b/tests/opt/opt_dff_srst.ys new file mode 100644 index 000000000..4a77de0b8 --- /dev/null +++ b/tests/opt/opt_dff_srst.ys @@ -0,0 +1,113 @@ +### Always-active SRST removal. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [1:0] D; +(* init=12'h555 *) +output [11:0] Q; +input SRST; +input EN; + +$sdff #(.CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff0 (.CLK(CLK), .SRST(1'b1), .D(D), .Q(Q[1:0])); +$sdffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b0), .SRST_VALUE(2'h2), .WIDTH(2)) ff1 (.CLK(CLK), .SRST(1'b0), .EN(EN), .D(D), .Q(Q[3:2])); +$sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b0), .SRST_VALUE(2'h2), .WIDTH(2)) ff2 (.CLK(CLK), .SRST(1'b0), .EN(EN), .D(D), .Q(Q[5:4])); +$sdff #(.CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff3 (.CLK(CLK), .SRST(1'bx), .D(D), .Q(Q[7:6])); +$sdffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b0), .SRST_VALUE(2'h2), .WIDTH(2)) ff4 (.CLK(CLK), .SRST(1'bx), .EN(EN), .D(D), .Q(Q[9:8])); +$sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b0), .SRST_VALUE(2'h2), .WIDTH(2)) ff5 (.CLK(CLK), .SRST(1'bx), .EN(EN), .D(D), .Q(Q[11:10])); + + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-count 0 t:$sdff +select -assert-count 0 t:$sdffe +select -assert-count 0 t:$sdffce +select -assert-count 4 t:$dff +select -assert-count 2 t:$dffe + +design -load orig + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 1 t:$sdff +select -assert-count 1 t:$sdffe +select -assert-count 1 t:$sdffce +select -assert-count 2 t:$dff +select -assert-count 1 t:$dffe + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-none t:$_SDFF_???_ +select -assert-none t:$_SDFFE_????_ +select -assert-none t:$_SDFFCE_????_ +select -assert-count 8 t:$_DFF_?_ +select -assert-count 4 t:$_DFFE_??_ + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff -keepdc +design -load postopt +select -assert-count 2 t:$_SDFF_???_ +select -assert-count 2 t:$_SDFFE_????_ +select -assert-count 2 t:$_SDFFCE_????_ +select -assert-count 4 t:$_DFF_?_ +select -assert-count 2 t:$_DFFE_??_ + +design -reset + + +### Never-active SRST removal. + +read_verilog -icells <<EOT + +module top(...); + +input CLK; +input [1:0] D; +output [5:0] Q; +input SRST; +input EN; + +$sdff #(.CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2), .WIDTH(2)) ff0 (.CLK(CLK), .SRST(1'b0), .D(D), .Q(Q[1:0])); +$sdffe #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b0), .SRST_VALUE(2'h2), .WIDTH(2)) ff1 (.CLK(CLK), .SRST(1'b1), .EN(EN), .D(D), .Q(Q[3:2])); +$sdffce #(.CLK_POLARITY(1'b1), .EN_POLARITY(1'b1), .SRST_POLARITY(1'b0), .SRST_VALUE(2'h2), .WIDTH(2)) ff2 (.CLK(CLK), .SRST(1'b1), .EN(EN), .D(D), .Q(Q[5:4])); + +endmodule + +EOT + +design -save orig + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-none t:$sdff +select -assert-none t:$sdffe +select -assert-none t:$sdffce +select -assert-count 1 t:$dff +select -assert-count 2 t:$dffe + +design -load orig +simplemap + +equiv_opt -undef -assert -multiclock opt_dff +design -load postopt +select -assert-none t:$_SDFF_???_ +select -assert-none t:$_SDFFE_????_ +select -assert-none t:$_SDFFCE_????_ +select -assert-count 2 t:$_DFF_P_ +select -assert-count 4 t:$_DFFE_PP_ + +design -reset + diff --git a/tests/opt/opt_expr_combined_assign.ys b/tests/opt/opt_expr_combined_assign.ys new file mode 100644 index 000000000..b18923c7b --- /dev/null +++ b/tests/opt/opt_expr_combined_assign.ys @@ -0,0 +1,83 @@ +read_verilog -sv <<EOT +module opt_expr_or_test(input [3:0] i, input [7:0] j, output [8:0] o); +wire[8:0] a = 8'b0; +initial begin + a |= i; + a |= j; +end + assign o = a; +endmodule +EOT +proc +equiv_opt -assert opt_expr -fine +design -load postopt + +select -assert-count 1 t:$or r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=4 %i %i %i + +design -reset +read_verilog -sv <<EOT +module opt_expr_add_test(input [3:0] i, input [7:0] j, output [8:0] o); +wire[8:0] a = 8'b0; +initial begin + a += i; + a += j; +end + assign o = a; +endmodule +EOT +proc +equiv_opt -assert opt_expr -fine +design -load postopt + +select -assert-count 1 t:$add r:A_WIDTH=9 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i + +design -reset +read_verilog -sv <<EOT +module opt_expr_xor_test(input [3:0] i, input [7:0] j, output [8:0] o); +wire[8:0] a = 8'b0; +initial begin + a ^= i; + a ^= j; +end + assign o = a; +endmodule +EOT +proc +equiv_opt -assert opt_expr -fine +design -load postopt + +select -assert-count 1 t:$xor r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=4 %i %i %i + +design -reset +read_verilog -sv <<EOT +module opt_expr_sub_test(input [3:0] i, input [7:0] j, output [8:0] o); +wire[8:0] a = 8'b0; +initial begin + a -= i; + a -= j; +end + assign o = a; +endmodule +EOT +proc +equiv_opt -assert opt_expr -fine +design -load postopt + +select -assert-count 1 t:$sub r:A_WIDTH=9 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i + +design -reset +read_verilog -sv <<EOT +module opt_expr_and_test(input [3:0] i, input [7:0] j, output [8:0] o); +wire[8:0] a = 8'b11111111; +initial begin + a &= i; + a &= j; +end + assign o = a; +endmodule +EOT +proc +equiv_opt -assert opt_expr -fine +design -load postopt + +select -assert-count 1 t:$and r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=4 %i %i %i diff --git a/tests/opt/opt_rmdff.v b/tests/opt/opt_rmdff.v index b1c06703c..536bf1d4e 100644 --- a/tests/opt/opt_rmdff.v +++ b/tests/opt/opt_rmdff.v @@ -1,50 +1,50 @@ module opt_rmdff_test (input C, input D, input E, output [29:0] Q); \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove0 (.CLK(C), .D(D), .EN(1'b0), .Q(Q[0])); // EN is never active -(* init = "1'b1" *) wire Q1; assign Q[1] = Q1; +(* init = 1'b1 *) wire Q1; assign Q[1] = Q1; \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove1 (.CLK(C), .D(D), .EN(1'b0), .Q(Q1)); // EN is never active \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove2 (.CLK(C), .D(D), .EN(1'bx), .Q(Q[2])); // EN is don't care \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep3 (.CLK(C), .D(D), .EN(1'b1), .Q(Q[3])); // EN is always active -(* init = "1'b0" *) wire Q4; assign Q[4] = Q4; +(* init = 1'b0 *) wire Q4; assign Q[4] = Q4; \$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(1)) keep4 (.CLK(C), .D(D), .EN(1'b1), .Q(Q4)); // EN is always active \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove5 (.CLK(C), .D(D), .EN(1'b1), .Q(Q[5])); // EN is never active \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove6 (.CLK(C), .D(D), .EN(1'bx), .Q(Q[6])); // EN is don't care -(* init = "1'b0" *) wire Q7; assign Q[7] = Q7; +(* init = 1'b0 *) wire Q7; assign Q[7] = Q7; \$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(0)) keep7 (.CLK(C), .D(D), .EN(E), .Q(Q7)); // EN is non constant \$_DFFE_PP_ remove8 (.C(C), .D(D), .E(1'b0), .Q(Q[8])); // EN is never active -(* init = "1'b1" *) wire Q9; assign Q[9] = Q9; +(* init = 1'b1 *) wire Q9; assign Q[9] = Q9; \$_DFFE_PP_ remove9 (.C(C), .D(D), .E(1'b0), .Q(Q9)); // EN is never active \$_DFFE_PP_ remove10 (.C(C), .D(D), .E(1'bx), .Q(Q[10])); // EN is don't care \$_DFFE_PP_ keep11 (.C(C), .D(D), .E(1'b1), .Q(Q[11])); // EN is always active -(* init = "1'b0" *) wire Q12; assign Q[12] = Q12; +(* init = 1'b0 *) wire Q12; assign Q[12] = Q12; \$_DFFE_PP_ keep12 (.C(C), .D(D), .E(1'b1), .Q(Q12)); // EN is always active \$_DFFE_NN_ remove13 (.C(C), .D(D), .E(1'b1), .Q(Q[13])); // EN is never active -(* init = "1'b1" *) wire Q14; assign Q[14] = Q14; +(* init = 1'b1 *) wire Q14; assign Q[14] = Q14; \$_DFFE_NN_ remove14 (.C(C), .D(D), .E(1'b1), .Q(Q14)); // EN is never active \$_DFFE_NN_ remove15 (.C(C), .D(D), .E(1'bx), .Q(Q[15])); // EN is don't care \$_DFFE_NN_ keep16 (.C(C), .D(D), .E(1'b0), .Q(Q[16])); // EN is always active -(* init = "1'b0" *) wire Q17; assign Q[17] = Q17; +(* init = 1'b0 *) wire Q17; assign Q[17] = Q17; \$_DFFE_NN_ keep17 (.C(C), .D(D), .E(1'b0), .Q(Q17)); // EN is always active \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove18 (.CLK(1'b0), .D(D), .EN(E), .Q(Q[18])); // CLK is constant -(* init = "1'b1" *) wire Q19; assign Q[19] = Q19; +(* init = 1'b1 *) wire Q19; assign Q[19] = Q19; \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove19 (.CLK(1'b1), .D(D), .EN(E), .Q(Q19)); // CLK is constant \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove20 (.CLK(C), .D(1'bx), .EN(E), .Q(Q[20])); // D is undriven, Q has no initial value -(* init = "1'b0" *) wire Q21; assign Q[21] = Q21; +(* init = 1'b0 *) wire Q21; assign Q[21] = Q21; \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep21 (.CLK(C), .D(1'bx), .EN(E), .Q(Q21)); // D is undriven, Q has initial value //\$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(1)) remove22 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q[22])); // D is constant, no initial Q value, EN is always active // // (TODO, Q starts with 1'bx and becomes 1'b0) -(* init = "1'b0" *) wire Q23; assign Q[23] = Q23; +(* init = 1'b0 *) wire Q23; assign Q[23] = Q23; \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) noenable23 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q23)); // D is constant, initial Q value same as D, EN is always active -(* init = "1'b1" *) wire Q24; assign Q[24] = Q24; +(* init = 1'b1 *) wire Q24; assign Q[24] = Q24; \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) keep24 (.CLK(C), .D(1'b0), .EN(1'b0), .Q(Q24)); // D is constant, initial Q value NOT same as D, EN is always active -(* init = "1'b1" *) wire Q25; assign Q[25] = Q25; +(* init = 1'b1 *) wire Q25; assign Q[25] = Q25; \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove25 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q25)); // D is constant, EN is never active \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove26 (.CLK(C), .D(Q[26]), .EN(1'b1), .Q(Q[26])); // D is Q, EN is always active \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove27 (.CLK(C), .D(Q[27]), .EN(1'b1), .Q(Q[27])); // D is Q, EN is never active, but no initial value \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove28 (.CLK(C), .D(Q[28]), .EN(E), .Q(Q[28])); // EN is nonconst, but no initial value -(* init = "1'b1" *) wire Q29; assign Q[29] = Q29; +(* init = 1'b1 *) wire Q29; assign Q[29] = Q29; \$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep29 (.CLK(C), .D(Q[29]), .EN(1'b1), .Q(Q29)); // EN is always active, but with initial value endmodule diff --git a/tests/opt/opt_rmdff.ys b/tests/opt/opt_rmdff.ys index 83a162f44..998414597 100644 --- a/tests/opt/opt_rmdff.ys +++ b/tests/opt/opt_rmdff.ys @@ -1,9 +1,10 @@ read_verilog -icells opt_rmdff.v prep design -stash gold + read_verilog -icells opt_rmdff.v proc -opt_rmdff +opt_dff select -assert-count 0 c:remove* select -assert-min 7 c:keep* @@ -14,13 +15,18 @@ design -stash gate design -import gold -as gold design -import gate -as gate -equiv_make gold gate equiv -hierarchy -top equiv -equiv_simple -undef -equiv_status -assert +cd gold +# fix up the "EN is don't care" cases, so that the gold output can't +# become defined by using the properties of an undefined enable. (Both +# remove6 and remove15 have active-low enables.) +connect -port remove6 EN 1'b1 +connect -port remove15 E 1'b1 +cd .. + +clk2fflogic +opt_clean + +miter -equiv -ignore_gold_x -make_assert -make_outputs -make_outcmp -flatten gold gate miter +hierarchy -top miter -#design -load gold -#stat -# -#design -load gate -#stat +sat -verify -prove-asserts -enable_undef -set-init-undef -seq 10 -show-public miter diff --git a/tests/opt/opt_rmdff_sat.ys b/tests/opt/opt_rmdff_sat.ys index 1c3dd9c05..231c43ecb 100644 --- a/tests/opt/opt_rmdff_sat.ys +++ b/tests/opt/opt_rmdff_sat.ys @@ -1,5 +1,5 @@ read_verilog opt_rmdff_sat.v prep -flatten -opt_rmdff -sat -synth +opt_dff -sat -nosdff +simplemap select -assert-count 5 t:$_DFF_P_ diff --git a/tests/opt/opt_share_bug2334.ys b/tests/opt/opt_share_bug2334.ys new file mode 100644 index 000000000..004d98349 --- /dev/null +++ b/tests/opt/opt_share_bug2334.ys @@ -0,0 +1,13 @@ +read_verilog <<EOT + +module t(input [3:0] A, input [3:0] B, input [3:0] C, input S, output [3:0] Y); + +wire [3:0] t = A + C; + +assign Y = S ? A + B : {4{t[0]}}; + +endmodule + +EOT + +equiv_opt -assert opt_share diff --git a/tests/opt/opt_share_bug2335.ys b/tests/opt/opt_share_bug2335.ys new file mode 100644 index 000000000..0846a9ec3 --- /dev/null +++ b/tests/opt/opt_share_bug2335.ys @@ -0,0 +1,27 @@ +read_verilog <<EOT + +module top(...); + +input [3:0] A, B, C; +input S; +input [1:0] T; +output [3:0] X; +output reg [3:0] Y; + +wire [3:0] D = A + B; + +assign X = S ? D : A + C; +always @* begin + case(T) + 2'b01: Y <= A; + 2'b10: Y <= B; + default: Y <= D; + endcase +end + +endmodule + +EOT + +proc +equiv_opt -assert opt_share diff --git a/tests/opt/opt_share_bug2336.ys b/tests/opt/opt_share_bug2336.ys new file mode 100644 index 000000000..cd472ef46 --- /dev/null +++ b/tests/opt/opt_share_bug2336.ys @@ -0,0 +1,14 @@ +read_verilog <<EOT + +module top(input [3:0] A, B, C, input S, output [2:0] O); + +wire [3:0] tb = A + B; +wire [3:0] tc = A + C; + +assign O = S ? tb[3:1] : tc[3:1]; + +endmodule + +EOT + +equiv_opt -assert opt_share diff --git a/tests/opt/run-test.sh b/tests/opt/run-test.sh index 44ce7e674..2007cd6e4 100755 --- a/tests/opt/run-test.sh +++ b/tests/opt/run-test.sh @@ -1,6 +1,4 @@ #!/bin/bash -set -e -for x in *.ys; do - echo "Running $x.." - ../../yosys -ql ${x%.ys}.log $x -done +set -eu +source ../gen-tests-makefile.sh +run_tests --yosys-scripts diff --git a/tests/opt_share/run-test.sh b/tests/opt_share/run-test.sh index e01552646..e0008a259 100755 --- a/tests/opt_share/run-test.sh +++ b/tests/opt_share/run-test.sh @@ -22,12 +22,23 @@ mkdir -p temp echo "generating tests.." python3 generate.py -c $count $seed +{ + echo ".PHONY: all" + echo "all:" + + for i in $( ls temp/*.ys | sed 's,[^0-9],,g; s,^0*\(.\),\1,g;' ); do + idx=$( printf "%05d" $i ) + echo ".PHONY: test-$idx" + echo "all: test-$idx" + echo "test-$idx:" + printf "\t@%s\n" \ + "echo -n [$i]" \ + "../../yosys -ql temp/uut_${idx}.log temp/uut_${idx}.ys" + done +} > temp/makefile + echo "running tests.." -for i in $( ls temp/*.ys | sed 's,[^0-9],,g; s,^0*\(.\),\1,g;' ); do - echo -n "[$i]" - idx=$( printf "%05d" $i ) - ../../yosys -ql temp/uut_${idx}.log temp/uut_${idx}.ys -done +${MAKE:-make} -f temp/makefile echo failed_share=$( echo $( gawk '/^#job#/ { j=$2; db[j]=0; } /^Removing [246] cells/ { delete db[j]; } END { for (j in db) print(j); }' temp/all_share_log.txt ) ) diff --git a/tests/sat/.gitignore b/tests/sat/.gitignore index 397b4a762..8355de9dc 100644 --- a/tests/sat/.gitignore +++ b/tests/sat/.gitignore @@ -1 +1,2 @@ *.log +run-test.mk diff --git a/tests/sat/dff.ys b/tests/sat/dff.ys new file mode 100644 index 000000000..ba3625871 --- /dev/null +++ b/tests/sat/dff.ys @@ -0,0 +1,21 @@ +# Ensure all sync-only DFFs have usable SAT models. + +read_verilog -icells <<EOT + +module top(...); + +input C, D, R, E; +output [4:0] Q; + +\$dff #(.WIDTH(1), .CLK_POLARITY(1'b1)) ff0 (.CLK(C), .D(D), .Q(Q[0])); +\$dffe #(.WIDTH(1), .CLK_POLARITY(1'b1), .EN_POLARITY(1'b1)) ff1 (.CLK(C), .D(D), .EN(E), .Q(Q[1])); +\$sdff #(.WIDTH(1), .CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(1'b0)) ff2 (.CLK(C), .D(D), .SRST(R), .Q(Q[2])); +\$sdffe #(.WIDTH(1), .CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(1'b0), .EN_POLARITY(1'b1)) ff3 (.CLK(C), .D(D), .EN(E), .SRST(R), .Q(Q[3])); +\$sdffce #(.WIDTH(1), .CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(1'b0), .EN_POLARITY(1'b1)) ff4 (.CLK(C), .D(D), .EN(E), .SRST(R), .Q(Q[4])); + +endmodule + +EOT + +# This ensures that 1) coarse cells have SAT models, 2) fine cells have SAT models, 3) they're equivalent +equiv_opt -assert simplemap diff --git a/tests/sat/run-test.sh b/tests/sat/run-test.sh index 67e1beb23..74589dfeb 100755 --- a/tests/sat/run-test.sh +++ b/tests/sat/run-test.sh @@ -1,6 +1,4 @@ -#!/bin/bash -set -e -for x in *.ys; do - echo "Running $x.." - ../../yosys -ql ${x%.ys}.log $x -done +#!/usr/bin/env bash +set -eu +source ../gen-tests-makefile.sh +run_tests --yosys-scripts diff --git a/tests/sat/sizebits.sv b/tests/sat/sizebits.sv index d7ce2326e..87fa08f89 100644 --- a/tests/sat/sizebits.sv +++ b/tests/sat/sizebits.sv @@ -1,5 +1,6 @@ module functions01; +wire t; wire [5:2]x; wire [3:0]y[2:7]; wire [3:0]z[7:2][2:9]; @@ -9,24 +10,84 @@ wire [3:0]z[7:2][2:9]; //wire [$size(y)-1:0]y_size; //wire [$size(z)-1:0]z_size; +assert property ($size(t) == 1); assert property ($size(x) == 4); assert property ($size({3{x}}) == 3*4); assert property ($size(y) == 6); assert property ($size(y, 1) == 6); assert property ($size(y, (1+1)) == 4); +// This is unsupported at the moment +//assert property ($size(y[2], 1) == 4); +//assert property ($size(y[2][1], 1) == 1); assert property ($size(z) == 6); assert property ($size(z, 1) == 6); assert property ($size(z, 2) == 8); assert property ($size(z, 3) == 4); +// This is unsupported at the moment +assert property ($size(z[3], 1) == 8); +assert property ($size(z[3][3], 1) == 4); +//assert property ($size(z[3][3][3], 1) == 1); // This should trigger an error if enabled (it does). //assert property ($size(z, 4) == 4); //wire [$bits(x)-1:0]x_bits; //wire [$bits({x, x})-1:0]xx_bits; +assert property ($bits(t) == 1); assert property ($bits(x) == 4); assert property ($bits(y) == 4*6); assert property ($bits(z) == 4*6*8); +assert property ($high(x) == 5); +assert property ($high(y) == 7); +assert property ($high(y, 1) == 7); +assert property ($high(y, (1+1)) == 3); + +assert property ($high(z) == 7); +assert property ($high(z, 1) == 7); +assert property ($high(z, 2) == 9); +assert property ($high(z, 3) == 3); +assert property ($high(z[3]) == 9); +assert property ($high(z[3][3]) == 3); +assert property ($high(z[3], 2) == 3); + +assert property ($low(x) == 2); +assert property ($low(y) == 2); +assert property ($low(y, 1) == 2); +assert property ($low(y, (1+1)) == 0); + +assert property ($low(z) == 2); +assert property ($low(z, 1) == 2); +assert property ($low(z, 2) == 2); +assert property ($low(z, 3) == 0); +assert property ($low(z[3]) == 2); +assert property ($low(z[3][3]) == 0); +assert property ($low(z[3], 2) == 0); + +assert property ($left(x) == 5); +assert property ($left(y) == 2); +assert property ($left(y, 1) == 2); +assert property ($left(y, (1+1)) == 3); + +assert property ($left(z) == 7); +assert property ($left(z, 1) == 7); +assert property ($left(z, 2) == 2); +assert property ($left(z, 3) == 3); +assert property ($left(z[3]) == 2); +assert property ($left(z[3][3]) == 3); +assert property ($left(z[3], 2) == 3); + +assert property ($right(x) == 2); +assert property ($right(y) == 7); +assert property ($right(y, 1) == 7); +assert property ($right(y, (1+1)) == 0); + +assert property ($right(z) == 2); +assert property ($right(z, 1) == 2); +assert property ($right(z, 2) == 9); +assert property ($right(z, 3) == 0); +assert property ($right(z[3]) == 9); +assert property ($right(z[3][3]) == 0); +assert property ($right(z[3], 2) == 0); endmodule diff --git a/tests/simple/const_branch_finish.v b/tests/simple/const_branch_finish.v new file mode 100644 index 000000000..8166688e6 --- /dev/null +++ b/tests/simple/const_branch_finish.v @@ -0,0 +1,39 @@ +`define CONSTANT_CHECK \ + if (WIDTH === 'bx) begin \ + $display("FAIL"); \ + $finish; \ + end + +module top; + parameter WIDTH = 32; + integer j; + initial begin + `CONSTANT_CHECK + if (WIDTH == 32) begin : procedural_conditional_block + `CONSTANT_CHECK + end + case (WIDTH) + 32: `CONSTANT_CHECK + default: ; + endcase + for (j = 0; j < 2; j = j + 1) begin : procedural_loop_block + `CONSTANT_CHECK + end + end + generate + begin : unconditional_block + initial `CONSTANT_CHECK + end + if (WIDTH == 32) begin : conditional_block + initial `CONSTANT_CHECK + end + case (WIDTH) + 32: initial `CONSTANT_CHECK + default: ; + endcase + genvar i; + for (i = 0; i < 2; i = i + 1) begin : loop_block + initial `CONSTANT_CHECK + end + endgenerate +endmodule diff --git a/tests/simple/generate.v b/tests/simple/generate.v index 0e353ad9b..12327b36e 100644 --- a/tests/simple/generate.v +++ b/tests/simple/generate.v @@ -159,3 +159,104 @@ generate end endgenerate endmodule + +// ------------------------------------------ + +module gen_test7; + reg [2:0] out1; + reg [2:0] out2; + wire [2:0] out3; + generate + begin : cond + reg [2:0] sub_out1; + reg [2:0] sub_out2; + wire [2:0] sub_out3; + initial begin : init + reg signed [31:0] x; + x = 2 ** 2; + out1 = x; + sub_out1 = x; + end + always @* begin : proc + reg signed [31:0] x; + x = 2 ** 1; + out2 = x; + sub_out2 = x; + end + genvar x; + for (x = 0; x < 3; x = x + 1) begin + assign out3[x] = 1; + assign sub_out3[x] = 1; + end + end + endgenerate + +// `define VERIFY +`ifdef VERIFY + assert property (out1 == 4); + assert property (out2 == 2); + assert property (out3 == 7); + assert property (cond.sub_out1 == 4); + assert property (cond.sub_out2 == 2); + assert property (cond.sub_out3 == 7); +`endif +endmodule + +// ------------------------------------------ + +module gen_test8; + +// `define VERIFY +`ifdef VERIFY + `define ASSERT(expr) assert property (expr); +`else + `define ASSERT(expr) +`endif + + wire [1:0] x = 2'b11; + generate + begin : A + wire [1:0] x; + begin : B + wire [1:0] x = 2'b00; + `ASSERT(x == 0) + `ASSERT(A.x == 2) + `ASSERT(A.C.x == 1) + `ASSERT(A.B.x == 0) + `ASSERT(gen_test8.x == 3) + `ASSERT(gen_test8.A.x == 2) + `ASSERT(gen_test8.A.C.x == 1) + `ASSERT(gen_test8.A.B.x == 0) + end + begin : C + wire [1:0] x = 2'b01; + `ASSERT(x == 1) + `ASSERT(A.x == 2) + `ASSERT(A.C.x == 1) + `ASSERT(A.B.x == 0) + `ASSERT(gen_test8.x == 3) + `ASSERT(gen_test8.A.x == 2) + `ASSERT(gen_test8.A.C.x == 1) + `ASSERT(gen_test8.A.B.x == 0) + end + assign x = B.x ^ 2'b11 ^ C.x; + `ASSERT(x == 2) + `ASSERT(A.x == 2) + `ASSERT(A.C.x == 1) + `ASSERT(A.B.x == 0) + `ASSERT(gen_test8.x == 3) + `ASSERT(gen_test8.A.x == 2) + `ASSERT(gen_test8.A.C.x == 1) + `ASSERT(gen_test8.A.B.x == 0) + end + endgenerate + + `ASSERT(x == 3) + `ASSERT(A.x == 2) + `ASSERT(A.C.x == 1) + `ASSERT(A.B.x == 0) + `ASSERT(gen_test8.x == 3) + `ASSERT(gen_test8.A.x == 2) + `ASSERT(gen_test8.A.C.x == 1) + `ASSERT(gen_test8.A.B.x == 0) +endmodule diff --git a/tests/simple/run-test.sh b/tests/simple/run-test.sh index f20fd0d30..47bcfd6da 100755 --- a/tests/simple/run-test.sh +++ b/tests/simple/run-test.sh @@ -17,5 +17,4 @@ if ! command -v iverilog > /dev/null ; then exit 1 fi -shopt -s nullglob exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.{sv,v} diff --git a/tests/simple/string_format.v b/tests/simple/string_format.v new file mode 100644 index 000000000..ce45ca1e9 --- /dev/null +++ b/tests/simple/string_format.v @@ -0,0 +1,7 @@ +module top; + parameter STR = "something interesting"; + initial begin + $display("A: %s", STR); + $display("B: %0s", STR); + end +endmodule diff --git a/tests/svtypes/multirange_array.sv b/tests/svtypes/multirange_array.sv new file mode 100644 index 000000000..be0d3dfc2 --- /dev/null +++ b/tests/svtypes/multirange_array.sv @@ -0,0 +1,16 @@ +// test for multirange arrays + +`define STRINGIFY(x) `"x`" +`define STATIC_ASSERT(x) if(!(x)) $error({"assert failed: ", `STRINGIFY(x)}) + +module top; + + logic a [3]; + logic b [3][5]; + logic c [3][5][7]; + + `STATIC_ASSERT($bits(a) == 3); + `STATIC_ASSERT($bits(b) == 15); + `STATIC_ASSERT($bits(c) == 105); + +endmodule diff --git a/tests/svtypes/multirange_subarray_access.ys b/tests/svtypes/multirange_subarray_access.ys new file mode 100644 index 000000000..de57d1423 --- /dev/null +++ b/tests/svtypes/multirange_subarray_access.ys @@ -0,0 +1,12 @@ +logger -expect error "Insufficient number of array indices for a." 1 +read_verilog -sv <<EOT +module foo; +logic a [6:0][4:0][1:0]; +logic b [1:0]; + +assign a[0][0][0] = 1'b0; +assign a[0][0][1] = 1'b1; +assign b = a[0][0]; + +endmodule +EOT diff --git a/tests/svtypes/run-test.sh b/tests/svtypes/run-test.sh index 09a30eed1..91ceae227 100755 --- a/tests/svtypes/run-test.sh +++ b/tests/svtypes/run-test.sh @@ -1,20 +1,4 @@ #!/usr/bin/env bash -set -e -{ -echo "all::" -for x in *.ys; do - echo "all:: run-$x" - echo "run-$x:" - echo " @echo 'Running $x..'" - echo " @../../yosys -ql ${x%.ys}.log $x" -done -for x in *.sv; do - if [ ! -f "${x%.sv}.ys" ]; then - echo "all:: check-$x" - echo "check-$x:" - echo " @echo 'Checking $x..'" - echo " @../../yosys -ql ${x%.sv}.log -p \"prep -top top; sat -verify -prove-asserts\" $x" - fi -done -} > run-test.mk -exec ${MAKE:-make} -f run-test.mk +set -eu +source ../gen-tests-makefile.sh +run_tests --yosys-scripts --prove-sv diff --git a/tests/svtypes/static_cast_negative.ys b/tests/svtypes/static_cast_negative.ys new file mode 100644 index 000000000..4f9e8cf6e --- /dev/null +++ b/tests/svtypes/static_cast_negative.ys @@ -0,0 +1,4 @@ +logger -expect error "Static cast with zero or negative size" 1 +read_verilog -sv <<EOT +module top; wire [7:0] a = (-1)'(a); endmodule +EOT diff --git a/tests/svtypes/static_cast_nonconst.ys b/tests/svtypes/static_cast_nonconst.ys new file mode 100644 index 000000000..72d8f9910 --- /dev/null +++ b/tests/svtypes/static_cast_nonconst.ys @@ -0,0 +1,4 @@ +logger -expect error "Static cast with non constant expression" 1 +read_verilog -sv <<EOT +module top; wire [7:0] a, b = (a)'(0); endmodule +EOT diff --git a/tests/svtypes/static_cast_simple.sv b/tests/svtypes/static_cast_simple.sv new file mode 100644 index 000000000..2e4ad7d2b --- /dev/null +++ b/tests/svtypes/static_cast_simple.sv @@ -0,0 +1,64 @@ +module top; + wire [7:0] a, b, c, d; + assign a = 8'd16; + assign b = 8'd16; + assign c = (a * b) >> 8; + assign d = (16'(a) * b) >> 8; + + parameter P = 16; + + wire signed [7:0] s0, s1, s2; + wire [7:0] u0, u1, u2, u3, u4, u5, u6; + assign s0 = -8'd1; + assign s1 = 4'(s0); + assign s2 = 4'(unsigned'(s0)); + assign u0 = -8'd1; + assign u1 = 4'(u0); + assign u2 = 4'(signed'(u0)); + assign u3 = 8'(4'(s0)); + assign u4 = 8'(4'(u0)); + assign u5 = 8'(4'(signed'(-8'd1))); + assign u6 = 8'(4'(unsigned'(-8'd1))); + + wire [8:0] n0, n1, n2, n3, n4, n5, n6, n7, n8, n9; + assign n0 = s1; + assign n1 = s2; + assign n2 = 9'(s1); + assign n3 = 9'(s2); + assign n4 = 9'(unsigned'(s1)); + assign n5 = 9'(unsigned'(s2)); + assign n6 = 9'(u0); + assign n7 = 9'(u1); + assign n8 = 9'(signed'(u0)); + assign n9 = 9'(signed'(u1)); + + always_comb begin + assert(c == 8'b0000_0000); + assert(d == 8'b0000_0001); + + assert((P + 1)'(a) == 17'b0_0000_0000_0001_0000); + assert((P + 1)'(d - 2) == 17'b1_1111_1111_1111_1111); + + assert(s0 == 8'b1111_1111); + assert(s1 == 8'b1111_1111); + assert(s2 == 8'b0000_1111); + assert(u0 == 8'b1111_1111); + assert(u1 == 8'b0000_1111); + assert(u2 == 8'b1111_1111); + assert(u3 == 8'b1111_1111); + assert(u4 == 8'b0000_1111); + assert(u5 == 8'b1111_1111); + assert(u6 == 8'b0000_1111); + + assert(n0 == 9'b1_1111_1111); + assert(n1 == 9'b0_0000_1111); + assert(n2 == 9'b1_1111_1111); + assert(n3 == 9'b0_0000_1111); + assert(n4 == 9'b0_1111_1111); + assert(n5 == 9'b0_0000_1111); + assert(n6 == 9'b0_1111_1111); + assert(n7 == 9'b0_0000_1111); + assert(n8 == 9'b1_1111_1111); + assert(n9 == 9'b0_0000_1111); + end +endmodule diff --git a/tests/svtypes/static_cast_verilog.ys b/tests/svtypes/static_cast_verilog.ys new file mode 100644 index 000000000..fa3680b68 --- /dev/null +++ b/tests/svtypes/static_cast_verilog.ys @@ -0,0 +1,4 @@ +logger -expect error "Static cast is only supported in SystemVerilog mode" 1 +read_verilog <<EOT +module top; wire [7:0] a = 1'(a); endmodule +EOT diff --git a/tests/svtypes/static_cast_zero.ys b/tests/svtypes/static_cast_zero.ys new file mode 100644 index 000000000..d8335ca1b --- /dev/null +++ b/tests/svtypes/static_cast_zero.ys @@ -0,0 +1,4 @@ +logger -expect error "Static cast with zero or negative size" 1 +read_verilog -sv <<EOT +module top; wire [7:0] a = 0'(a); endmodule +EOT diff --git a/tests/svtypes/struct_array.sv b/tests/svtypes/struct_array.sv index 022ad56c6..873f7befd 100644 --- a/tests/svtypes/struct_array.sv +++ b/tests/svtypes/struct_array.sv @@ -1,7 +1,7 @@ // test for array indexing in structures module top; - + struct packed { bit [5:0] [7:0] a; // 6 element packed array of bytes bit [15:0] b; // filler for non-zero offset @@ -19,4 +19,24 @@ module top; always_comb assert(s==64'h4200_0012_3400_FFFC); + struct packed { + bit [7:0] [7:0] a; // 8 element packed array of bytes + bit [15:0] b; // filler for non-zero offset + } s2; + + initial begin + s2 = '0; + + s2.a[2:1] = 16'h1234; + s2.a[5] = 8'h42; + + s2.a[7] = '1; + s2.a[7][1:0] = '0; + + s2.b = '1; + s2.b[1:0] = '0; + end + + always_comb assert(s2==80'hFC00_4200_0012_3400_FFFC); + endmodule diff --git a/tests/techmap/bug2183.ys b/tests/techmap/bug2183.ys new file mode 100644 index 000000000..8dd09458e --- /dev/null +++ b/tests/techmap/bug2183.ys @@ -0,0 +1,11 @@ +read_verilog <<EOT +module foo(inout a, b); + assign a = b; +endmodule +module bar(output c); + foo f(c, 1'b0); +endmodule +EOT + +hierarchy -auto-top +flatten diff --git a/tests/techmap/bug2321.ys b/tests/techmap/bug2321.ys new file mode 100644 index 000000000..637528b21 --- /dev/null +++ b/tests/techmap/bug2321.ys @@ -0,0 +1,15 @@ +read_verilog <<EOT +module m (input i, output o); +wire [1023:0] _TECHMAP_DO_00_ = "CONSTMAP; "; +endmodule +EOT + +design -stash map + +read_verilog <<EOT +module top(output o); +m m (.o(o), .i(o)); +endmodule +EOT + +techmap -map %map diff --git a/tests/techmap/bug2332.ys b/tests/techmap/bug2332.ys new file mode 100644 index 000000000..ed6b35eb2 --- /dev/null +++ b/tests/techmap/bug2332.ys @@ -0,0 +1,11 @@ +read_verilog <<EOT +module top(input [31:0] a, input signed [2:0] x, output [2:0] o); + +wire [5:0] t = x * 3; +assign o = a >> t; + +endmodule +EOT + +wreduce +equiv_opt -assert peepopt diff --git a/tests/techmap/cellname.ys b/tests/techmap/cellname.ys new file mode 100644 index 000000000..2edd6a9fd --- /dev/null +++ b/tests/techmap/cellname.ys @@ -0,0 +1,41 @@ +read_verilog << EOT + +module sub (input i, output o); +parameter _TECHMAP_CELLNAME_ = ""; +namedsub #(.name(_TECHMAP_CELLNAME_)) _TECHMAP_REPLACE_ (i, o); +endmodule + +EOT + +design -stash map + +read_verilog << EOT + +(* blackbox *) +module sub (input i, output o); +endmodule + +(* blackbox *) +module namedsub (input i, output o); +parameter name = ""; +endmodule + +module top(input [3:0] i, output [3:0] o); + +sub s1 (i[0], o[0]); +sub subsubsub (i[1], o[1]); +sub s2 (i[2], o[2]); +sub xxx (i[3], o[3]); + +endmodule + +EOT + +techmap -map %map + +select -assert-count 4 t:namedsub +select -assert-count 0 t:sub +select -assert-count 1 t:namedsub r:name=s1 %i +select -assert-count 1 t:namedsub r:name=subsubsub %i +select -assert-count 1 t:namedsub r:name=s2 %i +select -assert-count 1 t:namedsub r:name=xxx %i diff --git a/tests/techmap/clkbufmap.ys b/tests/techmap/clkbufmap.ys index b81a35e74..abe830109 100644 --- a/tests/techmap/clkbufmap.ys +++ b/tests/techmap/clkbufmap.ys @@ -1,5 +1,7 @@ read_verilog <<EOT module clkbuf (input i, (* clkbuf_driver *) output o); endmodule +module inbuf (input i, output o); endmodule +module clkinbuf (input i, (* clkbuf_driver *) output o); endmodule module dff ((* clkbuf_sink *) input clk, input d, output q); endmodule module dffe ((* clkbuf_sink *) input c, input d, e, output q); endmodule module latch (input e, d, output q); endmodule @@ -105,3 +107,80 @@ select -assert-count 0 w:clk1 %a %co t:clkbuf %i select -assert-count 0 w:clk2 %a %co t:clkbuf %i select -assert-count 0 top/t:clkbuf select -assert-count 2 sub/t:clkbuf + +# ---------------------- + +design -load ref +clkbufmap -buf clkbuf o:i -inpad inbuf o:i +select -assert-count 3 top/t:clkbuf +select -assert-count 3 sub/t:clkbuf +select -assert-count 2 top/t:inbuf +select -assert-count 0 sub/t:inbuf +select -set clk1 w:clk1 %a %co t:inbuf %i +select -assert-count 1 @clk1 +select -assert-count 1 @clk1 %x:+[o] %co t:clkbuf %i +select -set clk1b @clk1 %x:+[o] %co t:clkbuf %i +select -assert-count 1 @clk1b %x:+[o] %co c:s* %i +select -assert-count 1 @clk1b %x:+[o] %co c:s0 %i +select -set clk2 w:clk2 %a %co t:inbuf %i +select -assert-count 1 @clk2 +select -assert-count 1 @clk2 %x:+[o] %co t:clkbuf %i +select -set clk2b @clk2 %x:+[o] %co t:clkbuf %i +select -assert-count 1 @clk2b %x:+[o] %co c:s* %i +select -assert-count 1 @clk2b %x:+[o] %co c:s1 %i +select -set clk5 w:clk5 %a %ci t:clkbuf %i +select -assert-count 1 @clk5 +select -assert-count 1 @clk5 %x:+[o] %co c:s5 %i +select -assert-count 1 @clk5 %x:+[i] %ci c:s3 %i +select -set sclk4 w:sclk4 %a %ci t:clkbuf %i +select -assert-count 1 @sclk4 +select -assert-count 1 @sclk4 %x:+[o] %co c:s11 %i +select -assert-count 1 @sclk4 %x:+[i] %ci c:s7 %i +select -set sclk8 w:sclk8 %a %ci t:clkbuf %i +select -assert-count 1 @sclk8 +select -assert-count 1 @sclk8 %x:+[o] %co c:s13 %i +select -assert-count 1 @sclk8 %x:+[i] %ci c:s12 %i + +# ---------------------- + +design -load ref +clkbufmap -inpad inbuf o:i +select -assert-count 2 top/t:inbuf +select -assert-count 0 sub/t:inbuf +select -set clk1 w:clk1 %a %co t:inbuf %i +select -assert-count 1 @clk1 +select -assert-count 1 @clk1 %x:+[o] %co c:s* %i +select -assert-count 1 @clk1 %x:+[o] %co c:s0 %i +select -set clk2 w:clk2 %a %co t:inbuf %i +select -assert-count 1 @clk2 +select -assert-count 1 @clk2 %x:+[o] %co c:s* %i +select -assert-count 1 @clk2 %x:+[o] %co c:s1 %i + +# ---------------------- + +design -load ref +clkbufmap -buf clkbuf o:i -inpad clkinbuf o:i +select -assert-count 1 top/t:clkbuf +select -assert-count 3 sub/t:clkbuf +select -assert-count 2 top/t:clkinbuf +select -assert-count 0 sub/t:clkinbuf +select -set clk1 w:clk1 %a %co t:clkinbuf %i +select -assert-count 1 @clk1 +select -assert-count 1 @clk1 %x:+[o] %co c:s* %i +select -assert-count 1 @clk1 %x:+[o] %co c:s0 %i +select -set clk2 w:clk2 %a %co t:clkinbuf %i +select -assert-count 1 @clk2 +select -assert-count 1 @clk2 %x:+[o] %co c:s* %i +select -assert-count 1 @clk2 %x:+[o] %co c:s1 %i +select -set clk5 w:clk5 %a %ci t:clkbuf %i +select -assert-count 1 @clk5 +select -assert-count 1 @clk5 %x:+[o] %co c:s5 %i +select -assert-count 1 @clk5 %x:+[i] %ci c:s3 %i +select -set sclk4 w:sclk4 %a %ci t:clkbuf %i +select -assert-count 1 @sclk4 +select -assert-count 1 @sclk4 %x:+[o] %co c:s11 %i +select -assert-count 1 @sclk4 %x:+[i] %ci c:s7 %i +select -set sclk8 w:sclk8 %a %ci t:clkbuf %i +select -assert-count 1 @sclk8 +select -assert-count 1 @sclk8 %x:+[o] %co c:s13 %i +select -assert-count 1 @sclk8 %x:+[i] %ci c:s12 %i diff --git a/tests/techmap/dff2dffs.ys b/tests/techmap/dff2dffs.ys deleted file mode 100644 index 13f1a3cf3..000000000 --- a/tests/techmap/dff2dffs.ys +++ /dev/null @@ -1,50 +0,0 @@ -read_verilog << EOT -module top(...); -input clk; -input d; -input sr; -output reg q0, q1, q2, q3, q4, q5; - -initial q0 = 1'b0; -initial q1 = 1'b0; -initial q2 = 1'b1; -initial q3 = 1'b1; -initial q4 = 1'bx; -initial q5 = 1'bx; - -always @(posedge clk) begin - q0 <= sr ? 1'b0 : d; - q1 <= sr ? 1'b1 : d; - q2 <= sr ? 1'b0 : d; - q3 <= sr ? 1'b1 : d; - q4 <= sr ? 1'b0 : d; - q5 <= sr ? 1'b1 : d; -end - -endmodule -EOT - -proc -simplemap -design -save ref - -dff2dffs -clean - -select -assert-count 1 w:q0 %x t:$__DFFS_PP0_ %i -select -assert-count 1 w:q1 %x t:$__DFFS_PP1_ %i -select -assert-count 1 w:q2 %x t:$__DFFS_PP0_ %i -select -assert-count 1 w:q3 %x t:$__DFFS_PP1_ %i -select -assert-count 1 w:q4 %x t:$__DFFS_PP0_ %i -select -assert-count 1 w:q5 %x t:$__DFFS_PP1_ %i - -design -load ref -dff2dffs -match-init -clean - -select -assert-count 1 w:q0 %x t:$__DFFS_PP0_ %i -select -assert-count 0 w:q1 %x t:$__DFFS_PP1_ %i -select -assert-count 0 w:q2 %x t:$__DFFS_PP0_ %i -select -assert-count 1 w:q3 %x t:$__DFFS_PP1_ %i -select -assert-count 1 w:q4 %x t:$__DFFS_PP0_ %i -select -assert-count 1 w:q5 %x t:$__DFFS_PP1_ %i diff --git a/tests/techmap/dfflegalize_adff.ys b/tests/techmap/dfflegalize_adff.ys new file mode 100644 index 000000000..135ae0ab7 --- /dev/null +++ b/tests/techmap/dfflegalize_adff.ys @@ -0,0 +1,103 @@ +read_verilog -icells <<EOT + +module adff0(input C, R, D, output [2:0] Q); +$_DFF_PP0_ ff0 (.C(C), .R(R), .D(D), .Q(Q[0])); +$_DFF_PN0_ ff1 (.C(C), .R(R), .D(D), .Q(Q[1])); +$_DFF_NP0_ ff2 (.C(C), .R(R), .D(D), .Q(Q[2])); +endmodule + +module adff1(input C, R, D, output [2:0] Q); +$_DFF_PP1_ ff0 (.C(C), .R(R), .D(D), .Q(Q[0])); +$_DFF_PN1_ ff1 (.C(C), .R(R), .D(D), .Q(Q[1])); +$_DFF_NP1_ ff2 (.C(C), .R(R), .D(D), .Q(Q[2])); +endmodule + +module adffe0(input C, E, R, D, output [3:0] Q); +$_DFFE_PP0P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_DFFE_PP0N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_DFFE_PN0P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_DFFE_NP0P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module adffe1(input C, E, R, D, output [3:0] Q); +$_DFFE_PP1P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_DFFE_PP1N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_DFFE_PN1P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_DFFE_NP1P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module top(input C, E, R, D, output [13:0] Q); +adff0 adff0_(.C(C), .R(R), .D(D), .Q(Q[2:0])); +adff1 adff1_(.C(C), .R(R), .D(D), .Q(Q[5:3])); +adffe0 adffe0_(.C(C), .R(R), .E(E), .D(D), .Q(Q[9:6])); +adffe1 adffe1_(.C(C), .R(R), .E(E), .D(D), .Q(Q[13:10])); +endmodule + +EOT + +design -save orig +flatten +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ x + + +# Convert everything to ADFFs. + +design -load orig +dfflegalize -cell $_DFF_PP0_ x + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 8 adff1/t:$_NOT_ +select -assert-count 2 adffe0/t:$_NOT_ +select -assert-count 10 adffe1/t:$_NOT_ +select -assert-count 0 adff0/t:$_MUX_ +select -assert-count 0 adff1/t:$_MUX_ +select -assert-count 4 adffe0/t:$_MUX_ +select -assert-count 4 adffe1/t:$_MUX_ +select -assert-count 14 t:$_DFF_PP0_ +select -assert-none t:$_DFF_PP0_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to ADFFEs. + +design -load orig +dfflegalize -cell $_DFFE_PP0P_ x + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 8 adff1/t:$_NOT_ +select -assert-count 3 adffe0/t:$_NOT_ +select -assert-count 11 adffe1/t:$_NOT_ +select -assert-count 14 t:$_DFFE_PP0P_ +select -assert-none t:$_DFFE_PP0P_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFSRs. + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ x + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 2 adff1/t:$_NOT_ +select -assert-count 2 adffe0/t:$_NOT_ +select -assert-count 2 adffe1/t:$_NOT_ +select -assert-count 0 adff0/t:$_MUX_ +select -assert-count 0 adff1/t:$_MUX_ +select -assert-count 4 adffe0/t:$_MUX_ +select -assert-count 4 adffe1/t:$_MUX_ +select -assert-count 14 t:$_DFFSR_PPP_ +select -assert-none t:$_DFFSR_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFSREs. + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ x + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 2 adff1/t:$_NOT_ +select -assert-count 3 adffe0/t:$_NOT_ +select -assert-count 3 adffe1/t:$_NOT_ +select -assert-count 14 t:$_DFFSRE_PPPP_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ top/* %% %n t:* %i diff --git a/tests/techmap/dfflegalize_adff_init.ys b/tests/techmap/dfflegalize_adff_init.ys new file mode 100644 index 000000000..7764e15a5 --- /dev/null +++ b/tests/techmap/dfflegalize_adff_init.ys @@ -0,0 +1,279 @@ +read_verilog -icells <<EOT + +module adff0(input C, R, D, (* init = 3'b000 *) output [2:0] Q); +$_DFF_PP0_ ff0 (.C(C), .R(R), .D(D), .Q(Q[0])); +$_DFF_PN0_ ff1 (.C(C), .R(R), .D(D), .Q(Q[1])); +$_DFF_NP0_ ff2 (.C(C), .R(R), .D(D), .Q(Q[2])); +endmodule + +module adff1(input C, R, D, (* init = 3'b000 *) output [2:0] Q); +$_DFF_PP1_ ff0 (.C(C), .R(R), .D(D), .Q(Q[0])); +$_DFF_PN1_ ff1 (.C(C), .R(R), .D(D), .Q(Q[1])); +$_DFF_NP1_ ff2 (.C(C), .R(R), .D(D), .Q(Q[2])); +endmodule + +module adffe0(input C, E, R, D, (* init = 4'b0000 *) output [3:0] Q); +$_DFFE_PP0P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_DFFE_PP0N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_DFFE_PN0P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_DFFE_NP0P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module adffe1(input C, E, R, D, (* init = 4'b0000 *) output [3:0] Q); +$_DFFE_PP1P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_DFFE_PP1N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_DFFE_PN1P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_DFFE_NP1P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module top(input C, E, R, D, output [13:0] Q); +adff0 adff0_(.C(C), .R(R), .D(D), .Q(Q[2:0])); +adff1 adff1_(.C(C), .R(R), .D(D), .Q(Q[5:3])); +adffe0 adffe0_(.C(C), .R(R), .E(E), .D(D), .Q(Q[9:6])); +adffe1 adffe1_(.C(C), .R(R), .E(E), .D(D), .Q(Q[13:10])); +endmodule + +EOT + +design -save orig +flatten +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ 0 -cell $_DLATCH_P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ 1 -cell $_DLATCH_P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP1_ 0 -cell $_DLATCH_P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP1_ 1 -cell $_DLATCH_P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ 0 -cell $_DLATCH_P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ 1 -cell $_DLATCH_P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP1P_ 0 -cell $_DLATCH_P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP1P_ 1 -cell $_DLATCH_P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 1 + + +# Convert everything to ADFFs. + +design -load orig +dfflegalize -cell $_DFF_PP0_ 0 -cell $_DLATCH_P_ 0 + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 10 adff1/t:$_NOT_ +select -assert-count 2 adffe0/t:$_NOT_ +select -assert-count 12 adffe1/t:$_NOT_ +select -assert-count 0 adff0/t:$_MUX_ +select -assert-count 3 adff1/t:$_MUX_ +select -assert-count 4 adffe0/t:$_MUX_ +select -assert-count 8 adffe1/t:$_MUX_ +select -assert-count 3 adff0/t:$_DFF_PP0_ +select -assert-count 6 adff1/t:$_DFF_PP0_ +select -assert-count 4 adffe0/t:$_DFF_PP0_ +select -assert-count 8 adffe1/t:$_DFF_PP0_ +select -assert-count 0 adff0/t:$_DLATCH_P_ +select -assert-count 3 adff1/t:$_DLATCH_P_ +select -assert-count 0 adffe0/t:$_DLATCH_P_ +select -assert-count 4 adffe1/t:$_DLATCH_P_ +select -assert-none t:$_DFF_PP0_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFF_PP0_ 1 -cell $_DLATCH_P_ 0 + +select -assert-count 10 adff0/t:$_NOT_ +select -assert-count 8 adff1/t:$_NOT_ +select -assert-count 12 adffe0/t:$_NOT_ +select -assert-count 10 adffe1/t:$_NOT_ +select -assert-count 3 adff0/t:$_MUX_ +select -assert-count 0 adff1/t:$_MUX_ +select -assert-count 8 adffe0/t:$_MUX_ +select -assert-count 4 adffe1/t:$_MUX_ +select -assert-count 6 adff0/t:$_DFF_PP0_ +select -assert-count 3 adff1/t:$_DFF_PP0_ +select -assert-count 8 adffe0/t:$_DFF_PP0_ +select -assert-count 4 adffe1/t:$_DFF_PP0_ +select -assert-count 3 adff0/t:$_DLATCH_P_ +select -assert-count 0 adff1/t:$_DLATCH_P_ +select -assert-count 4 adffe0/t:$_DLATCH_P_ +select -assert-count 0 adffe1/t:$_DLATCH_P_ +select -assert-none t:$_DFF_PP0_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFF_PP1_ 0 -cell $_DLATCH_P_ 0 + +select -assert-count 10 adff0/t:$_NOT_ +select -assert-count 2 adff1/t:$_NOT_ +select -assert-count 12 adffe0/t:$_NOT_ +select -assert-count 2 adffe1/t:$_NOT_ +select -assert-count 3 adff0/t:$_MUX_ +select -assert-count 0 adff1/t:$_MUX_ +select -assert-count 8 adffe0/t:$_MUX_ +select -assert-count 4 adffe1/t:$_MUX_ +select -assert-count 6 adff0/t:$_DFF_PP1_ +select -assert-count 3 adff1/t:$_DFF_PP1_ +select -assert-count 8 adffe0/t:$_DFF_PP1_ +select -assert-count 4 adffe1/t:$_DFF_PP1_ +select -assert-count 3 adff0/t:$_DLATCH_P_ +select -assert-count 0 adff1/t:$_DLATCH_P_ +select -assert-count 4 adffe0/t:$_DLATCH_P_ +select -assert-count 0 adffe1/t:$_DLATCH_P_ +select -assert-none t:$_DFF_PP1_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFF_PP1_ 1 -cell $_DLATCH_P_ 0 + +select -assert-count 8 adff0/t:$_NOT_ +select -assert-count 10 adff1/t:$_NOT_ +select -assert-count 10 adffe0/t:$_NOT_ +select -assert-count 12 adffe1/t:$_NOT_ +select -assert-count 0 adff0/t:$_MUX_ +select -assert-count 3 adff1/t:$_MUX_ +select -assert-count 4 adffe0/t:$_MUX_ +select -assert-count 8 adffe1/t:$_MUX_ +select -assert-count 3 adff0/t:$_DFF_PP1_ +select -assert-count 6 adff1/t:$_DFF_PP1_ +select -assert-count 4 adffe0/t:$_DFF_PP1_ +select -assert-count 8 adffe1/t:$_DFF_PP1_ +select -assert-count 0 adff0/t:$_DLATCH_P_ +select -assert-count 3 adff1/t:$_DLATCH_P_ +select -assert-count 0 adffe0/t:$_DLATCH_P_ +select -assert-count 4 adffe1/t:$_DLATCH_P_ +select -assert-none t:$_DFF_PP1_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to ADFFEs. + +design -load orig +dfflegalize -cell $_DFFE_PP0P_ 0 -cell $_DLATCH_P_ 1 + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 16 adff1/t:$_NOT_ +select -assert-count 3 adffe0/t:$_NOT_ +select -assert-count 22 adffe1/t:$_NOT_ +select -assert-count 0 adff0/t:$_MUX_ +select -assert-count 3 adff1/t:$_MUX_ +select -assert-count 0 adffe0/t:$_MUX_ +select -assert-count 4 adffe1/t:$_MUX_ +select -assert-count 3 adff0/t:$_DFFE_PP0P_ +select -assert-count 6 adff1/t:$_DFFE_PP0P_ +select -assert-count 4 adffe0/t:$_DFFE_PP0P_ +select -assert-count 8 adffe1/t:$_DFFE_PP0P_ +select -assert-count 0 adff0/t:$_DLATCH_P_ +select -assert-count 3 adff1/t:$_DLATCH_P_ +select -assert-count 0 adffe0/t:$_DLATCH_P_ +select -assert-count 4 adffe1/t:$_DLATCH_P_ +select -assert-none t:$_DFFE_PP0P_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFE_PP0P_ 1 -cell $_DLATCH_P_ 1 + +select -assert-count 16 adff0/t:$_NOT_ +select -assert-count 8 adff1/t:$_NOT_ +select -assert-count 22 adffe0/t:$_NOT_ +select -assert-count 11 adffe1/t:$_NOT_ +select -assert-count 3 adff0/t:$_MUX_ +select -assert-count 0 adff1/t:$_MUX_ +select -assert-count 4 adffe0/t:$_MUX_ +select -assert-count 0 adffe1/t:$_MUX_ +select -assert-count 6 adff0/t:$_DFFE_PP0P_ +select -assert-count 3 adff1/t:$_DFFE_PP0P_ +select -assert-count 8 adffe0/t:$_DFFE_PP0P_ +select -assert-count 4 adffe1/t:$_DFFE_PP0P_ +select -assert-count 3 adff0/t:$_DLATCH_P_ +select -assert-count 0 adff1/t:$_DLATCH_P_ +select -assert-count 4 adffe0/t:$_DLATCH_P_ +select -assert-count 0 adffe1/t:$_DLATCH_P_ +select -assert-none t:$_DFFE_PP0P_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFE_PP1P_ 0 -cell $_DLATCH_P_ 1 + +select -assert-count 16 adff0/t:$_NOT_ +select -assert-count 2 adff1/t:$_NOT_ +select -assert-count 22 adffe0/t:$_NOT_ +select -assert-count 3 adffe1/t:$_NOT_ +select -assert-count 3 adff0/t:$_MUX_ +select -assert-count 0 adff1/t:$_MUX_ +select -assert-count 4 adffe0/t:$_MUX_ +select -assert-count 0 adffe1/t:$_MUX_ +select -assert-count 6 adff0/t:$_DFFE_PP1P_ +select -assert-count 3 adff1/t:$_DFFE_PP1P_ +select -assert-count 8 adffe0/t:$_DFFE_PP1P_ +select -assert-count 4 adffe1/t:$_DFFE_PP1P_ +select -assert-count 3 adff0/t:$_DLATCH_P_ +select -assert-count 0 adff1/t:$_DLATCH_P_ +select -assert-count 4 adffe0/t:$_DLATCH_P_ +select -assert-count 0 adffe1/t:$_DLATCH_P_ +select -assert-none t:$_DFFE_PP1P_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFE_PP1P_ 1 -cell $_DLATCH_P_ 1 + +select -assert-count 8 adff0/t:$_NOT_ +select -assert-count 16 adff1/t:$_NOT_ +select -assert-count 11 adffe0/t:$_NOT_ +select -assert-count 22 adffe1/t:$_NOT_ +select -assert-count 0 adff0/t:$_MUX_ +select -assert-count 3 adff1/t:$_MUX_ +select -assert-count 0 adffe0/t:$_MUX_ +select -assert-count 4 adffe1/t:$_MUX_ +select -assert-count 3 adff0/t:$_DFFE_PP1P_ +select -assert-count 6 adff1/t:$_DFFE_PP1P_ +select -assert-count 4 adffe0/t:$_DFFE_PP1P_ +select -assert-count 8 adffe1/t:$_DFFE_PP1P_ +select -assert-count 0 adff0/t:$_DLATCH_P_ +select -assert-count 3 adff1/t:$_DLATCH_P_ +select -assert-count 0 adffe0/t:$_DLATCH_P_ +select -assert-count 4 adffe1/t:$_DLATCH_P_ +select -assert-none t:$_DFFE_PP1P_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFSRs. + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ 0 + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 2 adff1/t:$_NOT_ +select -assert-count 2 adffe0/t:$_NOT_ +select -assert-count 2 adffe1/t:$_NOT_ +select -assert-count 0 adff0/t:$_MUX_ +select -assert-count 0 adff1/t:$_MUX_ +select -assert-count 4 adffe0/t:$_MUX_ +select -assert-count 4 adffe1/t:$_MUX_ +select -assert-count 14 t:$_DFFSR_PPP_ +select -assert-none t:$_DFFSR_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ 1 + +select -assert-count 8 adff0/t:$_NOT_ +select -assert-count 8 adff1/t:$_NOT_ +select -assert-count 10 adffe0/t:$_NOT_ +select -assert-count 10 adffe1/t:$_NOT_ +select -assert-count 0 adff0/t:$_MUX_ +select -assert-count 0 adff1/t:$_MUX_ +select -assert-count 4 adffe0/t:$_MUX_ +select -assert-count 4 adffe1/t:$_MUX_ +select -assert-count 14 t:$_DFFSR_PPP_ +select -assert-none t:$_DFFSR_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFSREs. + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ 0 + +select -assert-count 2 adff0/t:$_NOT_ +select -assert-count 2 adff1/t:$_NOT_ +select -assert-count 3 adffe0/t:$_NOT_ +select -assert-count 3 adffe1/t:$_NOT_ +select -assert-count 14 t:$_DFFSRE_PPPP_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ 1 + +select -assert-count 8 adff0/t:$_NOT_ +select -assert-count 8 adff1/t:$_NOT_ +select -assert-count 11 adffe0/t:$_NOT_ +select -assert-count 11 adffe1/t:$_NOT_ +select -assert-count 14 t:$_DFFSRE_PPPP_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ top/* %% %n t:* %i diff --git a/tests/techmap/dfflegalize_adlatch.ys b/tests/techmap/dfflegalize_adlatch.ys new file mode 100644 index 000000000..b242cc809 --- /dev/null +++ b/tests/techmap/dfflegalize_adlatch.ys @@ -0,0 +1,51 @@ +read_verilog -icells <<EOT + +module adlatch0(input E, R, D, output [2:0] Q); +$_DLATCH_PP0_ ff0 (.E(E), .R(R), .D(D), .Q(Q[0])); +$_DLATCH_PN0_ ff1 (.E(E), .R(R), .D(D), .Q(Q[1])); +$_DLATCH_NP0_ ff2 (.E(E), .R(R), .D(D), .Q(Q[2])); +endmodule + +module adlatch1(input E, R, D, output [2:0] Q); +$_DLATCH_PP1_ ff0 (.E(E), .R(R), .D(D), .Q(Q[0])); +$_DLATCH_PN1_ ff1 (.E(E), .R(R), .D(D), .Q(Q[1])); +$_DLATCH_NP1_ ff2 (.E(E), .R(R), .D(D), .Q(Q[2])); +endmodule + +module top(input C, E, R, D, output [13:0] Q); +adlatch0 adlatch0_(.E(E), .R(R), .D(D), .Q(Q[2:0])); +adlatch1 adlatch1_(.E(E), .R(R), .D(D), .Q(Q[5:3])); +endmodule + +EOT + +design -save orig +flatten +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ x + + +# Convert everything to ADLATCHs. + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ x + +select -assert-count 2 adlatch0/t:$_NOT_ +select -assert-count 8 adlatch1/t:$_NOT_ +select -assert-count 0 adlatch0/t:$_MUX_ +select -assert-count 0 adlatch1/t:$_MUX_ +select -assert-count 6 t:$_DLATCH_PP0_ +select -assert-none t:$_DLATCH_PP0_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DLATCHSRs. + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ x + +select -assert-count 2 adlatch0/t:$_NOT_ +select -assert-count 2 adlatch1/t:$_NOT_ +select -assert-count 0 adlatch0/t:$_MUX_ +select -assert-count 0 adlatch1/t:$_MUX_ +select -assert-count 6 t:$_DLATCHSR_PPP_ +select -assert-none t:$_DLATCHSR_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i diff --git a/tests/techmap/dfflegalize_adlatch_init.ys b/tests/techmap/dfflegalize_adlatch_init.ys new file mode 100644 index 000000000..7b22ea0c0 --- /dev/null +++ b/tests/techmap/dfflegalize_adlatch_init.ys @@ -0,0 +1,99 @@ +read_verilog -icells <<EOT + +module adlatch0(input E, R, D, (* init = 3'b000 *) output [2:0] Q); +$_DLATCH_PP0_ ff0 (.E(E), .R(R), .D(D), .Q(Q[0])); +$_DLATCH_PN0_ ff1 (.E(E), .R(R), .D(D), .Q(Q[1])); +$_DLATCH_NP0_ ff2 (.E(E), .R(R), .D(D), .Q(Q[2])); +endmodule + +module adlatch1(input E, R, D, (* init = 3'b000 *) output [2:0] Q); +$_DLATCH_PP1_ ff0 (.E(E), .R(R), .D(D), .Q(Q[0])); +$_DLATCH_PN1_ ff1 (.E(E), .R(R), .D(D), .Q(Q[1])); +$_DLATCH_NP1_ ff2 (.E(E), .R(R), .D(D), .Q(Q[2])); +endmodule + +module top(input C, E, R, D, output [13:0] Q); +adlatch0 adlatch0_(.E(E), .R(R), .D(D), .Q(Q[2:0])); +adlatch1 adlatch1_(.E(E), .R(R), .D(D), .Q(Q[5:3])); +endmodule + +EOT + +design -save orig +flatten +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP1_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP1_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ 1 + + +# Convert everything to ADLATCHs. + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ 0 + +select -assert-count 2 adlatch0/t:$_NOT_ +select -assert-count 10 adlatch1/t:$_NOT_ +select -assert-count 0 adlatch0/t:$_MUX_ +select -assert-count 3 adlatch1/t:$_MUX_ +select -assert-count 3 adlatch0/t:$_DLATCH_PP0_ +select -assert-count 9 adlatch1/t:$_DLATCH_PP0_ +select -assert-none t:$_DLATCH_PP0_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ 1 + +select -assert-count 16 adlatch0/t:$_NOT_ +select -assert-count 8 adlatch1/t:$_NOT_ +select -assert-count 3 adlatch0/t:$_MUX_ +select -assert-count 0 adlatch1/t:$_MUX_ +select -assert-count 9 adlatch0/t:$_DLATCH_PP0_ +select -assert-count 3 adlatch1/t:$_DLATCH_PP0_ +select -assert-none t:$_DLATCH_PP0_ t:$_DLATCH_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP1_ 0 + +select -assert-count 10 adlatch0/t:$_NOT_ +select -assert-count 2 adlatch1/t:$_NOT_ +select -assert-count 3 adlatch0/t:$_MUX_ +select -assert-count 0 adlatch1/t:$_MUX_ +select -assert-count 9 adlatch0/t:$_DLATCH_PP1_ +select -assert-count 3 adlatch1/t:$_DLATCH_PP1_ +select -assert-none t:$_DLATCH_PP1_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP1_ 1 + +select -assert-count 8 adlatch0/t:$_NOT_ +select -assert-count 16 adlatch1/t:$_NOT_ +select -assert-count 0 adlatch0/t:$_MUX_ +select -assert-count 3 adlatch1/t:$_MUX_ +select -assert-count 3 adlatch0/t:$_DLATCH_PP1_ +select -assert-count 9 adlatch1/t:$_DLATCH_PP1_ +select -assert-none t:$_DLATCH_PP1_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DLATCHSRs. + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ 0 + +select -assert-count 2 adlatch0/t:$_NOT_ +select -assert-count 2 adlatch1/t:$_NOT_ +select -assert-count 0 adlatch0/t:$_MUX_ +select -assert-count 0 adlatch1/t:$_MUX_ +select -assert-count 6 t:$_DLATCHSR_PPP_ +select -assert-none t:$_DLATCHSR_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ 1 + +select -assert-count 8 adlatch0/t:$_NOT_ +select -assert-count 8 adlatch1/t:$_NOT_ +select -assert-count 0 adlatch0/t:$_MUX_ +select -assert-count 0 adlatch1/t:$_MUX_ +select -assert-count 6 t:$_DLATCHSR_PPP_ +select -assert-none t:$_DLATCHSR_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i diff --git a/tests/techmap/dfflegalize_dff.ys b/tests/techmap/dfflegalize_dff.ys new file mode 100644 index 000000000..63ab47865 --- /dev/null +++ b/tests/techmap/dfflegalize_dff.ys @@ -0,0 +1,306 @@ +read_verilog -icells <<EOT + +module dff(input C, D, output [1:0] Q); +$_DFF_P_ ff0 (.C(C), .D(D), .Q(Q[0])); +$_DFF_N_ ff1 (.C(C), .D(D), .Q(Q[1])); +endmodule + +module dffe(input C, E, D, output [2:0] Q); +$_DFFE_PP_ ff0 (.C(C), .E(E), .D(D), .Q(Q[0])); +$_DFFE_PN_ ff1 (.C(C), .E(E), .D(D), .Q(Q[1])); +$_DFFE_NP_ ff2 (.C(C), .E(E), .D(D), .Q(Q[2])); +endmodule + +module sdff0(input C, R, D, output [2:0] Q); +$_SDFF_PP0_ ff0 (.C(C), .R(R), .D(D), .Q(Q[0])); +$_SDFF_PN0_ ff1 (.C(C), .R(R), .D(D), .Q(Q[1])); +$_SDFF_NP0_ ff2 (.C(C), .R(R), .D(D), .Q(Q[2])); +endmodule + +module sdff1(input C, R, D, output [2:0] Q); +$_SDFF_PP1_ ff0 (.C(C), .R(R), .D(D), .Q(Q[0])); +$_SDFF_PN1_ ff1 (.C(C), .R(R), .D(D), .Q(Q[1])); +$_SDFF_NP1_ ff2 (.C(C), .R(R), .D(D), .Q(Q[2])); +endmodule + +module sdffe0(input C, E, R, D, output [3:0] Q); +$_SDFFE_PP0P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_SDFFE_PP0N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_SDFFE_PN0P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_SDFFE_NP0P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module sdffe1(input C, E, R, D, output [3:0] Q); +$_SDFFE_PP1P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_SDFFE_PP1N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_SDFFE_PN1P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_SDFFE_NP1P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module sdffce0(input C, E, R, D, output [3:0] Q); +$_SDFFCE_PP0P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_SDFFCE_PP0N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_SDFFCE_PN0P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_SDFFCE_NP0P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module sdffce1(input C, E, R, D, output [3:0] Q); +$_SDFFCE_PP1P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_SDFFCE_PP1N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_SDFFCE_PN1P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_SDFFCE_NP1P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module top(input C, E, R, D, output [26:0] Q); +dff dff_(.C(C), .D(D), .Q(Q[1:0])); +dffe dffe_(.C(C), .E(E), .D(D), .Q(Q[4:2])); +sdff0 sdff0_(.C(C), .R(R), .D(D), .Q(Q[7:5])); +sdff1 sdff1_(.C(C), .R(R), .D(D), .Q(Q[10:8])); +sdffe0 sdffe0_(.C(C), .R(R), .E(E), .D(D), .Q(Q[14:11])); +sdffe1 sdffe1_(.C(C), .R(R), .E(E), .D(D), .Q(Q[18:15])); +sdffce0 sdffce0_(.C(C), .R(R), .E(E), .D(D), .Q(Q[22:19])); +sdffce1 sdffce1_(.C(C), .R(R), .E(E), .D(D), .Q(Q[26:23])); +endmodule + +EOT + +design -save orig +flatten +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_P_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_SDFF_PP0_ x +equiv_opt -assert -multiclock dfflegalize -cell $_SDFFE_PP0P_ x +equiv_opt -assert -multiclock dfflegalize -cell $_SDFFCE_PP0P_ x + +# Convert everything to DFFs. + +design -load orig +dfflegalize -cell $_DFF_P_ x + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFF_P_ +select -assert-none t:$_DFF_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFEs. + +design -load orig +dfflegalize -cell $_DFFE_PP_ x + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFE_PP_ +select -assert-none t:$_DFFE_PP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to ADFFs. + +design -load orig +dfflegalize -cell $_DFF_PP0_ x + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFF_PP0_ +select -assert-none t:$_DFF_PP0_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to ADFFEs. + +design -load orig +dfflegalize -cell $_DFFE_PP0P_ x + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFE_PP0P_ +select -assert-none t:$_DFFE_PP0P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFSRs. + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ x + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFSR_PPP_ +select -assert-none t:$_DFFSR_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFSREs. + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ x + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFSRE_PPPP_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to SDFFs. + +design -load orig +dfflegalize -cell $_SDFF_PP0_ x + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 2 sdff0/t:$_NOT_ +select -assert-count 8 sdff1/t:$_NOT_ +select -assert-count 2 sdffe0/t:$_NOT_ +select -assert-count 10 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 10 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 0 sdff0/t:$_MUX_ +select -assert-count 0 sdff1/t:$_MUX_ +select -assert-count 4 sdffe0/t:$_MUX_ +select -assert-count 4 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce0/* sdffce1/* %u %n %i +select -assert-count 2 sdffce0/t:$_AND_ +select -assert-count 2 sdffce1/t:$_AND_ +select -assert-count 1 sdffce0/t:$_ORNOT_ +select -assert-count 1 sdffce1/t:$_ORNOT_ +select -assert-count 1 sdffce0/t:$_ANDNOT_ +select -assert-count 1 sdffce1/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFF_PP0_ +select -assert-none t:$_SDFF_PP0_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + + +# Convert everything to SDFFEs. + +design -load orig +dfflegalize -cell $_SDFFE_PP0P_ x + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 2 sdff0/t:$_NOT_ +select -assert-count 8 sdff1/t:$_NOT_ +select -assert-count 3 sdffe0/t:$_NOT_ +select -assert-count 11 sdffe1/t:$_NOT_ +select -assert-count 3 sdffce0/t:$_NOT_ +select -assert-count 11 sdffce1/t:$_NOT_ +select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce0/* sdffce1/* %u %n %i +select -assert-count 2 sdffce0/t:$_AND_ +select -assert-count 2 sdffce1/t:$_AND_ +select -assert-count 1 sdffce0/t:$_ORNOT_ +select -assert-count 1 sdffce1/t:$_ORNOT_ +select -assert-count 1 sdffce0/t:$_ANDNOT_ +select -assert-count 1 sdffce1/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFFE_PP0P_ +select -assert-none t:$_SDFFE_PP0P_ t:$_NOT_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + + +# Convert everything to SDFFCEs. + +design -load orig +dfflegalize -cell $_SDFFCE_PP0P_ x + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 2 sdff0/t:$_NOT_ +select -assert-count 8 sdff1/t:$_NOT_ +select -assert-count 3 sdffe0/t:$_NOT_ +select -assert-count 11 sdffe1/t:$_NOT_ +select -assert-count 3 sdffce0/t:$_NOT_ +select -assert-count 11 sdffce1/t:$_NOT_ +select -assert-count 0 t:$_OR_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffe0/* sdffe1/* %u %n %i +select -assert-count 2 sdffe0/t:$_OR_ +select -assert-count 2 sdffe1/t:$_OR_ +select -assert-count 1 sdffe0/t:$_ORNOT_ +select -assert-count 1 sdffe1/t:$_ORNOT_ +select -assert-count 1 sdffe0/t:$_ANDNOT_ +select -assert-count 1 sdffe1/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFFCE_PP0P_ +select -assert-none t:$_SDFFCE_PP0P_ t:$_NOT_ t:$_OR_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i diff --git a/tests/techmap/dfflegalize_dff_init.ys b/tests/techmap/dfflegalize_dff_init.ys new file mode 100644 index 000000000..741ac39d0 --- /dev/null +++ b/tests/techmap/dfflegalize_dff_init.ys @@ -0,0 +1,786 @@ +read_verilog -icells <<EOT + +module dff(input C, D, (* init = 2'b00 *) output [1:0] Q); +$_DFF_P_ ff0 (.C(C), .D(D), .Q(Q[0])); +$_DFF_N_ ff1 (.C(C), .D(D), .Q(Q[1])); +endmodule + +module dffe(input C, E, D, (* init = 3'b000 *) output [2:0] Q); +$_DFFE_PP_ ff0 (.C(C), .E(E), .D(D), .Q(Q[0])); +$_DFFE_PN_ ff1 (.C(C), .E(E), .D(D), .Q(Q[1])); +$_DFFE_NP_ ff2 (.C(C), .E(E), .D(D), .Q(Q[2])); +endmodule + +module sdff0(input C, R, D, (* init = 3'b000 *) output [2:0] Q); +$_SDFF_PP0_ ff0 (.C(C), .R(R), .D(D), .Q(Q[0])); +$_SDFF_PN0_ ff1 (.C(C), .R(R), .D(D), .Q(Q[1])); +$_SDFF_NP0_ ff2 (.C(C), .R(R), .D(D), .Q(Q[2])); +endmodule + +module sdff1(input C, R, D, (* init = 3'b000 *) output [2:0] Q); +$_SDFF_PP1_ ff0 (.C(C), .R(R), .D(D), .Q(Q[0])); +$_SDFF_PN1_ ff1 (.C(C), .R(R), .D(D), .Q(Q[1])); +$_SDFF_NP1_ ff2 (.C(C), .R(R), .D(D), .Q(Q[2])); +endmodule + +module sdffe0(input C, E, R, D, (* init = 4'b0000 *) output [3:0] Q); +$_SDFFE_PP0P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_SDFFE_PP0N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_SDFFE_PN0P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_SDFFE_NP0P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module sdffe1(input C, E, R, D, (* init = 4'b0000 *) output [3:0] Q); +$_SDFFE_PP1P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_SDFFE_PP1N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_SDFFE_PN1P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_SDFFE_NP1P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module sdffce0(input C, E, R, D, (* init = 4'b0000 *) output [3:0] Q); +$_SDFFCE_PP0P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_SDFFCE_PP0N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_SDFFCE_PN0P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_SDFFCE_NP0P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module sdffce1(input C, E, R, D, (* init = 4'b0000 *) output [3:0] Q); +$_SDFFCE_PP1P_ ff0 (.C(C), .R(R), .E(E), .D(D), .Q(Q[0])); +$_SDFFCE_PP1N_ ff1 (.C(C), .R(R), .E(E), .D(D), .Q(Q[1])); +$_SDFFCE_PN1P_ ff2 (.C(C), .R(R), .E(E), .D(D), .Q(Q[2])); +$_SDFFCE_NP1P_ ff3 (.C(C), .R(R), .E(E), .D(D), .Q(Q[3])); +endmodule + +module top(input C, E, R, D, output [26:0] Q); +dff dff_(.C(C), .D(D), .Q(Q[1:0])); +dffe dffe_(.C(C), .E(E), .D(D), .Q(Q[4:2])); +sdff0 sdff0_(.C(C), .R(R), .D(D), .Q(Q[7:5])); +sdff1 sdff1_(.C(C), .R(R), .D(D), .Q(Q[10:8])); +sdffe0 sdffe0_(.C(C), .R(R), .E(E), .D(D), .Q(Q[14:11])); +sdffe1 sdffe1_(.C(C), .R(R), .E(E), .D(D), .Q(Q[18:15])); +sdffce0 sdffce0_(.C(C), .R(R), .E(E), .D(D), .Q(Q[22:19])); +sdffce1 sdffce1_(.C(C), .R(R), .E(E), .D(D), .Q(Q[26:23])); +endmodule + +EOT + +design -save orig +flatten +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP1_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP1_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP1P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP1P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFF_PP0_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFF_PP0_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFF_PP1_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFF_PP1_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFFE_PP0P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFFE_PP0P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFFE_PP1P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFFE_PP1P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFFCE_PP0P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFFCE_PP0P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFFCE_PP1P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_SDFFCE_PP1P_ 1 + +# Convert everything to DFFs. + +design -load orig +dfflegalize -cell $_DFF_P_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFF_P_ +select -assert-none t:$_DFF_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFF_P_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 7 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 9 sdffce0/t:$_NOT_ +select -assert-count 9 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFF_P_ +select -assert-none t:$_DFF_P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFEs. + +design -load orig +dfflegalize -cell $_DFFE_PP_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFE_PP_ +select -assert-none t:$_DFFE_PP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFE_PP_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 8 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 10 sdffce0/t:$_NOT_ +select -assert-count 10 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFE_PP_ +select -assert-none t:$_DFFE_PP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to ADFFs. + +design -load orig +dfflegalize -cell $_DFF_PP0_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFF_PP0_ +select -assert-none t:$_DFF_PP0_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFF_PP0_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 7 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 9 sdffce0/t:$_NOT_ +select -assert-count 9 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFF_PP0_ +select -assert-none t:$_DFF_PP0_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFF_PP1_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFF_PP1_ +select -assert-none t:$_DFF_PP1_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFF_PP1_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 7 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 9 sdffce0/t:$_NOT_ +select -assert-count 9 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFF_PP1_ +select -assert-none t:$_DFF_PP1_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to ADFFEs. + +design -load orig +dfflegalize -cell $_DFFE_PP0P_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFE_PP0P_ +select -assert-none t:$_DFFE_PP0P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFE_PP0P_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 8 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 10 sdffce0/t:$_NOT_ +select -assert-count 10 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFE_PP0P_ +select -assert-none t:$_DFFE_PP0P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFE_PP1P_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFE_PP1P_ +select -assert-none t:$_DFFE_PP1P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFE_PP1P_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 8 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 10 sdffce0/t:$_NOT_ +select -assert-count 10 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFE_PP1P_ +select -assert-none t:$_DFFE_PP1P_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFSRs. + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFSR_PPP_ +select -assert-none t:$_DFFSR_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 7 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 9 sdffce0/t:$_NOT_ +select -assert-count 9 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFSR_PPP_ +select -assert-none t:$_DFFSR_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFSREs. + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFSRE_PPPP_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 8 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 10 sdffce0/t:$_NOT_ +select -assert-count 10 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 27 t:$_DFFSRE_PPPP_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to SDFFs. + +design -load orig +dfflegalize -cell $_SDFF_PP0_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 2 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 2 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 1 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 0 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 4 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce0/* %n %i +select -assert-count 2 sdffce0/t:$_AND_ +select -assert-count 1 sdffce0/t:$_ORNOT_ +select -assert-count 1 sdffce0/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFF_PP0_ +select -assert-none t:$_SDFF_PP0_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_SDFF_PP0_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 7 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 8 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 10 sdffe1/t:$_NOT_ +select -assert-count 9 sdffce0/t:$_NOT_ +select -assert-count 10 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 0 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 4 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce1/* %n %i +select -assert-count 2 sdffce1/t:$_AND_ +select -assert-count 1 sdffce1/t:$_ORNOT_ +select -assert-count 1 sdffce1/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFF_PP0_ +select -assert-none t:$_SDFF_PP0_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_SDFF_PP1_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 1 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 2 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 2 sdffe1/t:$_NOT_ +select -assert-count 1 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 0 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 4 sdffe1/t:$_MUX_ +select -assert-count 8 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce1/* %n %i +select -assert-count 2 sdffce1/t:$_AND_ +select -assert-count 1 sdffce1/t:$_ORNOT_ +select -assert-count 1 sdffce1/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFF_PP1_ +select -assert-none t:$_SDFF_PP1_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_SDFF_PP1_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 7 dffe/t:$_NOT_ +select -assert-count 8 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 10 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 10 sdffce0/t:$_NOT_ +select -assert-count 9 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 3 dffe/t:$_MUX_ +select -assert-count 0 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 4 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 8 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce0/* %n %i +select -assert-count 2 sdffce0/t:$_AND_ +select -assert-count 1 sdffce0/t:$_ORNOT_ +select -assert-count 1 sdffce0/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFF_PP1_ +select -assert-none t:$_SDFF_PP1_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + + +# Convert everything to SDFFEs. + +design -load orig +dfflegalize -cell $_SDFFE_PP0P_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 2 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 3 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 3 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 0 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 0 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 0 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce0/* %n %i +select -assert-count 2 sdffce0/t:$_AND_ +select -assert-count 1 sdffce0/t:$_ORNOT_ +select -assert-count 1 sdffce0/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFFE_PP0P_ +select -assert-none t:$_SDFFE_PP0P_ t:$_NOT_ t:$_MUX_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_SDFFE_PP0P_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 8 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 8 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 11 sdffe1/t:$_NOT_ +select -assert-count 10 sdffce0/t:$_NOT_ +select -assert-count 11 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 0 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 0 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 0 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce1/* %n %i +select -assert-count 2 sdffce1/t:$_AND_ +select -assert-count 1 sdffce1/t:$_ORNOT_ +select -assert-count 1 sdffce1/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFFE_PP0P_ +select -assert-none t:$_SDFFE_PP0P_ t:$_NOT_ t:$_MUX_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_SDFFE_PP1P_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 2 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 3 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 3 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 0 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 0 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 0 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce1/* %n %i +select -assert-count 2 sdffce1/t:$_AND_ +select -assert-count 1 sdffce1/t:$_ORNOT_ +select -assert-count 1 sdffce1/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFFE_PP1P_ +select -assert-none t:$_SDFFE_PP1P_ t:$_NOT_ t:$_MUX_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_SDFFE_PP1P_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 8 dffe/t:$_NOT_ +select -assert-count 8 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 11 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 11 sdffce0/t:$_NOT_ +select -assert-count 10 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 0 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 0 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 0 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffce0/* %n %i +select -assert-count 2 sdffce0/t:$_AND_ +select -assert-count 1 sdffce0/t:$_ORNOT_ +select -assert-count 1 sdffce0/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFFE_PP1P_ +select -assert-none t:$_SDFFE_PP1P_ t:$_NOT_ t:$_MUX_ t:$_AND_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + + +# Convert everything to SDFFCEs. + +design -load orig +dfflegalize -cell $_SDFFCE_PP0P_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 2 sdff0/t:$_NOT_ +select -assert-count 1 sdff1/t:$_NOT_ +select -assert-count 3 sdffe0/t:$_NOT_ +select -assert-count 1 sdffe1/t:$_NOT_ +select -assert-count 3 sdffce0/t:$_NOT_ +select -assert-count 2 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 0 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 0 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 0 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_OR_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffe0/* %n %i +select -assert-count 2 sdffe0/t:$_OR_ +select -assert-count 1 sdffe0/t:$_ORNOT_ +select -assert-count 1 sdffe0/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFFCE_PP0P_ +select -assert-none t:$_SDFFCE_PP0P_ t:$_NOT_ t:$_MUX_ t:$_OR_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_SDFFCE_PP0P_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 8 dffe/t:$_NOT_ +select -assert-count 7 sdff0/t:$_NOT_ +select -assert-count 8 sdff1/t:$_NOT_ +select -assert-count 9 sdffe0/t:$_NOT_ +select -assert-count 11 sdffe1/t:$_NOT_ +select -assert-count 10 sdffce0/t:$_NOT_ +select -assert-count 11 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 0 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 0 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 0 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_OR_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffe1/* %n %i +select -assert-count 2 sdffe1/t:$_OR_ +select -assert-count 1 sdffe1/t:$_ORNOT_ +select -assert-count 1 sdffe1/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFFCE_PP0P_ +select -assert-none t:$_SDFFCE_PP0P_ t:$_NOT_ t:$_MUX_ t:$_OR_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_SDFFCE_PP1P_ 0 + +select -assert-count 1 dff/t:$_NOT_ +select -assert-count 2 dffe/t:$_NOT_ +select -assert-count 1 sdff0/t:$_NOT_ +select -assert-count 2 sdff1/t:$_NOT_ +select -assert-count 1 sdffe0/t:$_NOT_ +select -assert-count 3 sdffe1/t:$_NOT_ +select -assert-count 2 sdffce0/t:$_NOT_ +select -assert-count 3 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 3 sdff0/t:$_MUX_ +select -assert-count 0 sdff1/t:$_MUX_ +select -assert-count 8 sdffe0/t:$_MUX_ +select -assert-count 0 sdffe1/t:$_MUX_ +select -assert-count 4 sdffce0/t:$_MUX_ +select -assert-count 0 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_OR_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffe1/* %n %i +select -assert-count 2 sdffe1/t:$_OR_ +select -assert-count 1 sdffe1/t:$_ORNOT_ +select -assert-count 1 sdffe1/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFFCE_PP1P_ +select -assert-none t:$_SDFFCE_PP1P_ t:$_NOT_ t:$_MUX_ t:$_OR_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_SDFFCE_PP1P_ 1 + +select -assert-count 5 dff/t:$_NOT_ +select -assert-count 8 dffe/t:$_NOT_ +select -assert-count 8 sdff0/t:$_NOT_ +select -assert-count 7 sdff1/t:$_NOT_ +select -assert-count 11 sdffe0/t:$_NOT_ +select -assert-count 9 sdffe1/t:$_NOT_ +select -assert-count 11 sdffce0/t:$_NOT_ +select -assert-count 10 sdffce1/t:$_NOT_ +select -assert-count 0 dff/t:$_MUX_ +select -assert-count 0 dffe/t:$_MUX_ +select -assert-count 0 sdff0/t:$_MUX_ +select -assert-count 3 sdff1/t:$_MUX_ +select -assert-count 0 sdffe0/t:$_MUX_ +select -assert-count 8 sdffe1/t:$_MUX_ +select -assert-count 0 sdffce0/t:$_MUX_ +select -assert-count 4 sdffce1/t:$_MUX_ +select -assert-count 0 t:$_OR_ t:$_ORNOT_ t:$_ANDNOT_ %% sdffe0/* %n %i +select -assert-count 2 sdffe0/t:$_OR_ +select -assert-count 1 sdffe0/t:$_ORNOT_ +select -assert-count 1 sdffe0/t:$_ANDNOT_ +select -assert-count 27 t:$_SDFFCE_PP1P_ +select -assert-none t:$_SDFFCE_PP1P_ t:$_NOT_ t:$_MUX_ t:$_OR_ t:$_ORNOT_ t:$_ANDNOT_ top/* %% %n t:* %i diff --git a/tests/techmap/dfflegalize_dffsr.ys b/tests/techmap/dfflegalize_dffsr.ys new file mode 100644 index 000000000..49a7237a2 --- /dev/null +++ b/tests/techmap/dfflegalize_dffsr.ys @@ -0,0 +1,88 @@ +read_verilog -icells <<EOT + +module dffsr(input C, R, S, D, output [3:0] Q); +$_DFFSR_PPP_ ff0 (.C(C), .R(R), .S(S), .D(D), .Q(Q[0])); +$_DFFSR_PPN_ ff1 (.C(C), .R(R), .S(S), .D(D), .Q(Q[1])); +$_DFFSR_PNP_ ff2 (.C(C), .R(R), .S(S), .D(D), .Q(Q[2])); +$_DFFSR_NPP_ ff3 (.C(C), .R(R), .S(S), .D(D), .Q(Q[3])); +endmodule + +module dffsre(input C, R, S, E, D, output [4:0] Q); +$_DFFSRE_PPPP_ ff0 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[0])); +$_DFFSRE_PPPN_ ff1 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[1])); +$_DFFSRE_PPNP_ ff2 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[2])); +$_DFFSRE_PNPP_ ff3 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[3])); +$_DFFSRE_NPPP_ ff4 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[4])); +endmodule + +module top(input C, E, R, S, D, output [8:0] Q); +dffsr dffsr_(.C(C), .R(R), .S(S), .D(D), .Q(Q[3:0])); +dffsre dffsre_(.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[8:4])); +endmodule + +EOT + +design -save orig +flatten +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ x -cell $_SR_PP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ x -cell $_SR_PP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ x + + +# Convert everything to ADFFs. + +design -load orig +dfflegalize -cell $_DFF_PP0_ x -cell $_SR_PP_ x + +select -assert-count 14 dffsr/t:$_NOT_ +select -assert-count 16 dffsre/t:$_NOT_ +select -assert-count 4 dffsr/t:$_MUX_ +select -assert-count 10 dffsre/t:$_MUX_ +select -assert-count 8 dffsr/t:$_DFF_PP0_ +select -assert-count 10 dffsre/t:$_DFF_PP0_ +select -assert-count 4 dffsr/t:$_SR_PP_ +select -assert-count 5 dffsre/t:$_SR_PP_ +select -assert-none t:$_DFF_PP0_ t:$_SR_PP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to ADFFEs. + +design -load orig +dfflegalize -cell $_DFFE_PP0P_ x -cell $_SR_PP_ x + +select -assert-count 14 dffsr/t:$_NOT_ +select -assert-count 18 dffsre/t:$_NOT_ +select -assert-count 4 dffsr/t:$_MUX_ +select -assert-count 5 dffsre/t:$_MUX_ +select -assert-count 8 dffsr/t:$_DFFE_PP0P_ +select -assert-count 10 dffsre/t:$_DFFE_PP0P_ +select -assert-count 4 dffsr/t:$_SR_PP_ +select -assert-count 5 dffsre/t:$_SR_PP_ +select -assert-none t:$_DFFE_PP0P_ t:$_SR_PP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFSRs. + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ x + +select -assert-count 3 dffsr/t:$_NOT_ +select -assert-count 3 dffsre/t:$_NOT_ +select -assert-count 0 dffsr/t:$_MUX_ +select -assert-count 5 dffsre/t:$_MUX_ +select -assert-count 4 dffsr/t:$_DFFSR_PPP_ +select -assert-count 5 dffsre/t:$_DFFSR_PPP_ +select -assert-none t:$_DFFSR_PPP_ t:$_MUX_ t:$_NOT_ top/* %% %n t:* %i + + +# Convert everything to DFFSREs. + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ x + +select -assert-count 3 dffsr/t:$_NOT_ +select -assert-count 4 dffsre/t:$_NOT_ +select -assert-count 4 dffsr/t:$_DFFSRE_PPPP_ +select -assert-count 5 dffsre/t:$_DFFSRE_PPPP_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ top/* %% %n t:* %i diff --git a/tests/techmap/dfflegalize_dffsr_init.ys b/tests/techmap/dfflegalize_dffsr_init.ys new file mode 100644 index 000000000..ce5a32f76 --- /dev/null +++ b/tests/techmap/dfflegalize_dffsr_init.ys @@ -0,0 +1,379 @@ +read_verilog -icells <<EOT + +module dffsr0(input C, R, S, D, (* init = 4'h0 *) output [3:0] Q); +$_DFFSR_PPP_ ff0 (.C(C), .R(R), .S(S), .D(D), .Q(Q[0])); +$_DFFSR_PPN_ ff1 (.C(C), .R(R), .S(S), .D(D), .Q(Q[1])); +$_DFFSR_PNP_ ff2 (.C(C), .R(R), .S(S), .D(D), .Q(Q[2])); +$_DFFSR_NPP_ ff3 (.C(C), .R(R), .S(S), .D(D), .Q(Q[3])); +endmodule + +module dffsr1(input C, R, S, D, (* init = 4'hf *) output [3:0] Q); +$_DFFSR_PPP_ ff0 (.C(C), .R(R), .S(S), .D(D), .Q(Q[0])); +$_DFFSR_PPN_ ff1 (.C(C), .R(R), .S(S), .D(D), .Q(Q[1])); +$_DFFSR_PNP_ ff2 (.C(C), .R(R), .S(S), .D(D), .Q(Q[2])); +$_DFFSR_NPP_ ff3 (.C(C), .R(R), .S(S), .D(D), .Q(Q[3])); +endmodule + +module dffsre0(input C, R, S, E, D, (* init = 5'h0 *) output [4:0] Q); +$_DFFSRE_PPPP_ ff0 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[0])); +$_DFFSRE_PPPN_ ff1 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[1])); +$_DFFSRE_PPNP_ ff2 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[2])); +$_DFFSRE_PNPP_ ff3 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[3])); +$_DFFSRE_NPPP_ ff4 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[4])); +endmodule + +module dffsre1(input C, R, S, E, D, (* init = 5'h1f *) output [4:0] Q); +$_DFFSRE_PPPP_ ff0 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[0])); +$_DFFSRE_PPPN_ ff1 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[1])); +$_DFFSRE_PPNP_ ff2 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[2])); +$_DFFSRE_PNPP_ ff3 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[3])); +$_DFFSRE_NPPP_ ff4 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[4])); +endmodule + +module top(input C, E, R, S, D, output [17:0] Q); +dffsr0 dffsr0_(.C(C), .R(R), .S(S), .D(D), .Q(Q[3:0])); +dffsr1 dffsr1_(.C(C), .R(R), .S(S), .D(D), .Q(Q[7:4])); +dffsre0 dffsre0_(.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[12:8])); +dffsre1 dffsre1_(.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[17:13])); +endmodule + +EOT + +design -save orig +flatten +#equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ 0 -cell $_SR_PP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ 1 -cell $_SR_PP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP1_ 0 -cell $_SR_PP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP1_ 1 -cell $_SR_PP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ 0 -cell $_SR_PP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP0P_ 1 -cell $_SR_PP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP1P_ 0 -cell $_SR_PP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP1P_ 1 -cell $_SR_PP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 1 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 1 + + +# Convert everything to ADFFs. + +design -load orig +dfflegalize -cell $_DFF_PP0_ 0 -cell $_SR_PP_ 0 + +select -assert-count 14 dffsr0/t:$_NOT_ +select -assert-count 18 dffsr1/t:$_NOT_ +select -assert-count 16 dffsre0/t:$_NOT_ +select -assert-count 21 dffsre1/t:$_NOT_ +select -assert-count 4 dffsr0/t:$_MUX_ +select -assert-count 4 dffsr1/t:$_MUX_ +select -assert-count 10 dffsre0/t:$_MUX_ +select -assert-count 10 dffsre1/t:$_MUX_ +select -assert-count 8 dffsr0/t:$_DFF_PP0_ +select -assert-count 8 dffsr1/t:$_DFF_PP0_ +select -assert-count 10 dffsre0/t:$_DFF_PP0_ +select -assert-count 10 dffsre1/t:$_DFF_PP0_ +select -assert-count 4 dffsr0/t:$_SR_PP_ +select -assert-count 4 dffsr1/t:$_SR_PP_ +select -assert-count 5 dffsre0/t:$_SR_PP_ +select -assert-count 5 dffsre1/t:$_SR_PP_ +select -assert-count 1 dffsr1/t:$_AND_ +select -assert-count 2 dffsr1/t:$_ANDNOT_ +select -assert-count 1 dffsr1/t:$_OR_ +select -assert-count 1 dffsre1/t:$_AND_ +select -assert-count 3 dffsre1/t:$_ANDNOT_ +select -assert-count 1 dffsre1/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr1/* dffsre1/* %u %n %i +select -assert-none t:$_DFF_PP0_ t:$_SR_PP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFF_PP0_ 1 -cell $_SR_PP_ 0 + +select -assert-count 18 dffsr0/t:$_NOT_ +select -assert-count 14 dffsr1/t:$_NOT_ +select -assert-count 21 dffsre0/t:$_NOT_ +select -assert-count 16 dffsre1/t:$_NOT_ +select -assert-count 4 dffsr0/t:$_MUX_ +select -assert-count 4 dffsr1/t:$_MUX_ +select -assert-count 10 dffsre0/t:$_MUX_ +select -assert-count 10 dffsre1/t:$_MUX_ +select -assert-count 8 dffsr0/t:$_DFF_PP0_ +select -assert-count 8 dffsr1/t:$_DFF_PP0_ +select -assert-count 10 dffsre0/t:$_DFF_PP0_ +select -assert-count 10 dffsre1/t:$_DFF_PP0_ +select -assert-count 4 dffsr0/t:$_SR_PP_ +select -assert-count 4 dffsr1/t:$_SR_PP_ +select -assert-count 5 dffsre0/t:$_SR_PP_ +select -assert-count 5 dffsre1/t:$_SR_PP_ +select -assert-count 1 dffsr0/t:$_AND_ +select -assert-count 2 dffsr0/t:$_ANDNOT_ +select -assert-count 1 dffsr0/t:$_OR_ +select -assert-count 1 dffsre0/t:$_AND_ +select -assert-count 3 dffsre0/t:$_ANDNOT_ +select -assert-count 1 dffsre0/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr0/* dffsre0/* %u %n %i +select -assert-none t:$_DFF_PP0_ t:$_SR_PP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFF_PP1_ 0 -cell $_SR_PP_ 0 + +select -assert-count 18 dffsr0/t:$_NOT_ +select -assert-count 14 dffsr1/t:$_NOT_ +select -assert-count 21 dffsre0/t:$_NOT_ +select -assert-count 16 dffsre1/t:$_NOT_ +select -assert-count 4 dffsr0/t:$_MUX_ +select -assert-count 4 dffsr1/t:$_MUX_ +select -assert-count 10 dffsre0/t:$_MUX_ +select -assert-count 10 dffsre1/t:$_MUX_ +select -assert-count 8 dffsr0/t:$_DFF_PP1_ +select -assert-count 8 dffsr1/t:$_DFF_PP1_ +select -assert-count 10 dffsre0/t:$_DFF_PP1_ +select -assert-count 10 dffsre1/t:$_DFF_PP1_ +select -assert-count 4 dffsr0/t:$_SR_PP_ +select -assert-count 4 dffsr1/t:$_SR_PP_ +select -assert-count 5 dffsre0/t:$_SR_PP_ +select -assert-count 5 dffsre1/t:$_SR_PP_ +select -assert-count 1 dffsr0/t:$_AND_ +select -assert-count 2 dffsr0/t:$_ANDNOT_ +select -assert-count 1 dffsr0/t:$_OR_ +select -assert-count 1 dffsre0/t:$_AND_ +select -assert-count 3 dffsre0/t:$_ANDNOT_ +select -assert-count 1 dffsre0/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr0/* dffsre0/* %u %n %i +select -assert-none t:$_DFF_PP1_ t:$_SR_PP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFF_PP1_ 1 -cell $_SR_PP_ 0 + +select -assert-count 14 dffsr0/t:$_NOT_ +select -assert-count 18 dffsr1/t:$_NOT_ +select -assert-count 16 dffsre0/t:$_NOT_ +select -assert-count 21 dffsre1/t:$_NOT_ +select -assert-count 4 dffsr0/t:$_MUX_ +select -assert-count 4 dffsr1/t:$_MUX_ +select -assert-count 10 dffsre0/t:$_MUX_ +select -assert-count 10 dffsre1/t:$_MUX_ +select -assert-count 8 dffsr0/t:$_DFF_PP1_ +select -assert-count 8 dffsr1/t:$_DFF_PP1_ +select -assert-count 10 dffsre0/t:$_DFF_PP1_ +select -assert-count 10 dffsre1/t:$_DFF_PP1_ +select -assert-count 4 dffsr0/t:$_SR_PP_ +select -assert-count 4 dffsr1/t:$_SR_PP_ +select -assert-count 5 dffsre0/t:$_SR_PP_ +select -assert-count 5 dffsre1/t:$_SR_PP_ +select -assert-count 1 dffsr1/t:$_AND_ +select -assert-count 2 dffsr1/t:$_ANDNOT_ +select -assert-count 1 dffsr1/t:$_OR_ +select -assert-count 1 dffsre1/t:$_AND_ +select -assert-count 3 dffsre1/t:$_ANDNOT_ +select -assert-count 1 dffsre1/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr1/* dffsre1/* %u %n %i +select -assert-none t:$_DFF_PP1_ t:$_SR_PP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + + +# Convert everything to ADFFEs. + +design -load orig +dfflegalize -cell $_DFFE_PP0P_ 0 -cell $_SR_PP_ 1 + +select -assert-count 18 dffsr0/t:$_NOT_ +select -assert-count 14 dffsr1/t:$_NOT_ +select -assert-count 23 dffsre0/t:$_NOT_ +select -assert-count 18 dffsre1/t:$_NOT_ +select -assert-count 4 dffsr0/t:$_MUX_ +select -assert-count 4 dffsr1/t:$_MUX_ +select -assert-count 5 dffsre0/t:$_MUX_ +select -assert-count 5 dffsre1/t:$_MUX_ +select -assert-count 8 dffsr0/t:$_DFFE_PP0P_ +select -assert-count 8 dffsr1/t:$_DFFE_PP0P_ +select -assert-count 10 dffsre0/t:$_DFFE_PP0P_ +select -assert-count 10 dffsre1/t:$_DFFE_PP0P_ +select -assert-count 4 dffsr0/t:$_SR_PP_ +select -assert-count 4 dffsr1/t:$_SR_PP_ +select -assert-count 5 dffsre0/t:$_SR_PP_ +select -assert-count 5 dffsre1/t:$_SR_PP_ +select -assert-count 1 dffsr0/t:$_AND_ +select -assert-count 2 dffsr0/t:$_ANDNOT_ +select -assert-count 1 dffsr0/t:$_OR_ +select -assert-count 1 dffsre0/t:$_AND_ +select -assert-count 3 dffsre0/t:$_ANDNOT_ +select -assert-count 1 dffsre0/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr0/* dffsre0/* %u %n %i +select -assert-none t:$_DFFE_PP0P_ t:$_SR_PP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFE_PP0P_ 1 -cell $_SR_PP_ 1 + +select -assert-count 14 dffsr0/t:$_NOT_ +select -assert-count 18 dffsr1/t:$_NOT_ +select -assert-count 18 dffsre0/t:$_NOT_ +select -assert-count 23 dffsre1/t:$_NOT_ +select -assert-count 4 dffsr0/t:$_MUX_ +select -assert-count 4 dffsr1/t:$_MUX_ +select -assert-count 5 dffsre0/t:$_MUX_ +select -assert-count 5 dffsre1/t:$_MUX_ +select -assert-count 8 dffsr0/t:$_DFFE_PP0P_ +select -assert-count 8 dffsr1/t:$_DFFE_PP0P_ +select -assert-count 10 dffsre0/t:$_DFFE_PP0P_ +select -assert-count 10 dffsre1/t:$_DFFE_PP0P_ +select -assert-count 4 dffsr0/t:$_SR_PP_ +select -assert-count 4 dffsr1/t:$_SR_PP_ +select -assert-count 5 dffsre0/t:$_SR_PP_ +select -assert-count 5 dffsre1/t:$_SR_PP_ +select -assert-count 1 dffsr1/t:$_AND_ +select -assert-count 2 dffsr1/t:$_ANDNOT_ +select -assert-count 1 dffsr1/t:$_OR_ +select -assert-count 1 dffsre1/t:$_AND_ +select -assert-count 3 dffsre1/t:$_ANDNOT_ +select -assert-count 1 dffsre1/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr1/* dffsre1/* %u %n %i +select -assert-none t:$_DFFE_PP0P_ t:$_SR_PP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFE_PP1P_ 0 -cell $_SR_PP_ 1 + +select -assert-count 14 dffsr0/t:$_NOT_ +select -assert-count 18 dffsr1/t:$_NOT_ +select -assert-count 18 dffsre0/t:$_NOT_ +select -assert-count 23 dffsre1/t:$_NOT_ +select -assert-count 4 dffsr0/t:$_MUX_ +select -assert-count 4 dffsr1/t:$_MUX_ +select -assert-count 5 dffsre0/t:$_MUX_ +select -assert-count 5 dffsre1/t:$_MUX_ +select -assert-count 8 dffsr0/t:$_DFFE_PP1P_ +select -assert-count 8 dffsr1/t:$_DFFE_PP1P_ +select -assert-count 10 dffsre0/t:$_DFFE_PP1P_ +select -assert-count 10 dffsre1/t:$_DFFE_PP1P_ +select -assert-count 4 dffsr0/t:$_SR_PP_ +select -assert-count 4 dffsr1/t:$_SR_PP_ +select -assert-count 5 dffsre0/t:$_SR_PP_ +select -assert-count 5 dffsre1/t:$_SR_PP_ +select -assert-count 1 dffsr1/t:$_AND_ +select -assert-count 2 dffsr1/t:$_ANDNOT_ +select -assert-count 1 dffsr1/t:$_OR_ +select -assert-count 1 dffsre1/t:$_AND_ +select -assert-count 3 dffsre1/t:$_ANDNOT_ +select -assert-count 1 dffsre1/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr1/* dffsre1/* %u %n %i +select -assert-none t:$_DFFE_PP1P_ t:$_SR_PP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFE_PP1P_ 1 -cell $_SR_PP_ 1 + +select -assert-count 18 dffsr0/t:$_NOT_ +select -assert-count 14 dffsr1/t:$_NOT_ +select -assert-count 23 dffsre0/t:$_NOT_ +select -assert-count 18 dffsre1/t:$_NOT_ +select -assert-count 4 dffsr0/t:$_MUX_ +select -assert-count 4 dffsr1/t:$_MUX_ +select -assert-count 5 dffsre0/t:$_MUX_ +select -assert-count 5 dffsre1/t:$_MUX_ +select -assert-count 8 dffsr0/t:$_DFFE_PP1P_ +select -assert-count 8 dffsr1/t:$_DFFE_PP1P_ +select -assert-count 10 dffsre0/t:$_DFFE_PP1P_ +select -assert-count 10 dffsre1/t:$_DFFE_PP1P_ +select -assert-count 4 dffsr0/t:$_SR_PP_ +select -assert-count 4 dffsr1/t:$_SR_PP_ +select -assert-count 5 dffsre0/t:$_SR_PP_ +select -assert-count 5 dffsre1/t:$_SR_PP_ +select -assert-count 1 dffsr0/t:$_AND_ +select -assert-count 2 dffsr0/t:$_ANDNOT_ +select -assert-count 1 dffsr0/t:$_OR_ +select -assert-count 1 dffsre0/t:$_AND_ +select -assert-count 3 dffsre0/t:$_ANDNOT_ +select -assert-count 1 dffsre0/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr0/* dffsre0/* %u %n %i +select -assert-none t:$_DFFE_PP1P_ t:$_SR_PP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + + +# Convert everything to DFFSRs. + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ 0 + +select -assert-count 3 dffsr0/t:$_NOT_ +select -assert-count 11 dffsr1/t:$_NOT_ +select -assert-count 3 dffsre0/t:$_NOT_ +select -assert-count 13 dffsre1/t:$_NOT_ +select -assert-count 0 dffsr0/t:$_MUX_ +select -assert-count 0 dffsr1/t:$_MUX_ +select -assert-count 5 dffsre0/t:$_MUX_ +select -assert-count 5 dffsre1/t:$_MUX_ +select -assert-count 4 dffsr0/t:$_DFFSR_PPP_ +select -assert-count 4 dffsr1/t:$_DFFSR_PPP_ +select -assert-count 5 dffsre0/t:$_DFFSR_PPP_ +select -assert-count 5 dffsre1/t:$_DFFSR_PPP_ +select -assert-count 1 dffsr1/t:$_AND_ +select -assert-count 2 dffsr1/t:$_ANDNOT_ +select -assert-count 1 dffsr1/t:$_OR_ +select -assert-count 1 dffsre1/t:$_AND_ +select -assert-count 3 dffsre1/t:$_ANDNOT_ +select -assert-count 1 dffsre1/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr1/* dffsre1/* %u %n %i +select -assert-none t:$_DFFSR_PPP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ 1 + +select -assert-count 11 dffsr0/t:$_NOT_ +select -assert-count 3 dffsr1/t:$_NOT_ +select -assert-count 13 dffsre0/t:$_NOT_ +select -assert-count 3 dffsre1/t:$_NOT_ +select -assert-count 0 dffsr0/t:$_MUX_ +select -assert-count 0 dffsr1j/t:$_MUX_ +select -assert-count 5 dffsre0/t:$_MUX_ +select -assert-count 5 dffsre1/t:$_MUX_ +select -assert-count 4 dffsr0/t:$_DFFSR_PPP_ +select -assert-count 4 dffsr1/t:$_DFFSR_PPP_ +select -assert-count 5 dffsre0/t:$_DFFSR_PPP_ +select -assert-count 5 dffsre1/t:$_DFFSR_PPP_ +select -assert-count 1 dffsr0/t:$_AND_ +select -assert-count 2 dffsr0/t:$_ANDNOT_ +select -assert-count 1 dffsr0/t:$_OR_ +select -assert-count 1 dffsre0/t:$_AND_ +select -assert-count 3 dffsre0/t:$_ANDNOT_ +select -assert-count 1 dffsre0/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr0/* dffsre0/* %u %n %i +select -assert-none t:$_DFFSR_PPP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + + +# Convert everything to DFFSREs. + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ 0 + +select -assert-count 3 dffsr0/t:$_NOT_ +select -assert-count 11 dffsr1/t:$_NOT_ +select -assert-count 4 dffsre0/t:$_NOT_ +select -assert-count 14 dffsre1/t:$_NOT_ +select -assert-count 4 dffsr0/t:$_DFFSRE_PPPP_ +select -assert-count 4 dffsr1/t:$_DFFSRE_PPPP_ +select -assert-count 5 dffsre0/t:$_DFFSRE_PPPP_ +select -assert-count 5 dffsre1/t:$_DFFSRE_PPPP_ +select -assert-count 1 dffsr1/t:$_AND_ +select -assert-count 2 dffsr1/t:$_ANDNOT_ +select -assert-count 1 dffsr1/t:$_OR_ +select -assert-count 1 dffsre1/t:$_AND_ +select -assert-count 3 dffsre1/t:$_ANDNOT_ +select -assert-count 1 dffsre1/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr1/* dffsre1/* %u %n %i +select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ 1 + +select -assert-count 11 dffsr0/t:$_NOT_ +select -assert-count 3 dffsr1/t:$_NOT_ +select -assert-count 14 dffsre0/t:$_NOT_ +select -assert-count 4 dffsre1/t:$_NOT_ +select -assert-count 4 dffsr0/t:$_DFFSRE_PPPP_ +select -assert-count 4 dffsr1/t:$_DFFSRE_PPPP_ +select -assert-count 5 dffsre0/t:$_DFFSRE_PPPP_ +select -assert-count 5 dffsre1/t:$_DFFSRE_PPPP_ +select -assert-count 1 dffsr0/t:$_AND_ +select -assert-count 2 dffsr0/t:$_ANDNOT_ +select -assert-count 1 dffsr0/t:$_OR_ +select -assert-count 1 dffsre0/t:$_AND_ +select -assert-count 3 dffsre0/t:$_ANDNOT_ +select -assert-count 1 dffsre0/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dffsr0/* dffsre0/* %u %n %i +select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i diff --git a/tests/techmap/dfflegalize_dlatch.ys b/tests/techmap/dfflegalize_dlatch.ys new file mode 100644 index 000000000..b68ea741e --- /dev/null +++ b/tests/techmap/dfflegalize_dlatch.ys @@ -0,0 +1,42 @@ +read_verilog -icells <<EOT + +module dlatch(input E, D, output [1:0] Q); +$_DLATCH_P_ ff0 (.E(E), .D(D), .Q(Q[0])); +$_DLATCH_N_ ff1 (.E(E), .D(D), .Q(Q[1])); +endmodule + +EOT + +design -save orig +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_P_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ x + +# Convert everything to DFFs. + +design -load orig +dfflegalize -cell $_DLATCH_P_ x + +select -assert-count 1 t:$_NOT_ +select -assert-count 2 t:$_DLATCH_P_ +select -assert-none t:$_DLATCH_P_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to ADLATCHs. + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ x + +select -assert-count 1 t:$_NOT_ +select -assert-count 2 t:$_DLATCH_PP0_ +select -assert-none t:$_DLATCH_PP0_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to DLATCHSRs. + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ x + +select -assert-count 1 t:$_NOT_ +select -assert-count 2 t:$_DLATCHSR_PPP_ +select -assert-none t:$_DLATCHSR_PPP_ t:$_NOT_ %% %n t:* %i diff --git a/tests/techmap/dfflegalize_dlatch_const.ys b/tests/techmap/dfflegalize_dlatch_const.ys new file mode 100644 index 000000000..f30a534fd --- /dev/null +++ b/tests/techmap/dfflegalize_dlatch_const.ys @@ -0,0 +1,53 @@ +read_verilog -icells <<EOT + +module dlatch(input E, D, (* init = 8'hf0 *) output [7:0] Q); +$_DLATCH_P_ ff0 (.E(E), .D(1'b0), .Q(Q[0])); +$_DLATCH_N_ ff1 (.E(E), .D(1'b0), .Q(Q[1])); +$_DLATCH_P_ ff2 (.E(E), .D(1'b1), .Q(Q[2])); +$_DLATCH_N_ ff3 (.E(E), .D(1'b1), .Q(Q[3])); +$_DLATCH_P_ ff4 (.E(E), .D(1'b0), .Q(Q[4])); +$_DLATCH_N_ ff5 (.E(E), .D(1'b0), .Q(Q[5])); +$_DLATCH_P_ ff6 (.E(E), .D(1'b1), .Q(Q[6])); +$_DLATCH_N_ ff7 (.E(E), .D(1'b1), .Q(Q[7])); +endmodule + +EOT + +design -save orig +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP0_ 01 +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_PP?_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 1 + +# Convert everything to ADFFs. + +design -load orig +dfflegalize -cell $_DFF_PP0_ 01 + +select -assert-count 12 t:$_NOT_ +select -assert-count 8 t:$_DFF_PP0_ +select -assert-none t:$_DFF_PP0_ t:$_NOT_ %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFF_PP?_ 0 + +select -assert-count 12 t:$_NOT_ +select -assert-count 4 t:$_DFF_PP0_ +select -assert-count 4 t:$_DFF_PP1_ +select -assert-none t:$_DFF_PP0_ t:$_DFF_PP1_ t:$_NOT_ %% %n t:* %i + +# Convert everything to DFFSREs. + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ 0 + +select -assert-count 12 t:$_NOT_ +select -assert-count 8 t:$_DFFSRE_PPPP_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ 1 + +select -assert-count 12 t:$_NOT_ +select -assert-count 8 t:$_DFFSRE_PPPP_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ %% %n t:* %i diff --git a/tests/techmap/dfflegalize_dlatch_init.ys b/tests/techmap/dfflegalize_dlatch_init.ys new file mode 100644 index 000000000..ccc9e41d7 --- /dev/null +++ b/tests/techmap/dfflegalize_dlatch_init.ys @@ -0,0 +1,82 @@ +read_verilog -icells <<EOT + +module dlatch(input E, D, (* init = 2'h0 *) output [1:0] Q); +$_DLATCH_P_ ff0 (.E(E), .D(D), .Q(Q[0])); +$_DLATCH_N_ ff1 (.E(E), .D(D), .Q(Q[1])); +endmodule + +EOT + +design -save orig +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_P_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_P_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP1_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP1_ 1 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ 0 +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ 1 + +# Convert everything to DFFs. + +design -load orig +dfflegalize -cell $_DLATCH_P_ 0 + +select -assert-count 1 t:$_NOT_ +select -assert-count 2 t:$_DLATCH_P_ +select -assert-none t:$_DLATCH_P_ t:$_NOT_ %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_P_ 1 + +select -assert-count 5 t:$_NOT_ +select -assert-count 2 t:$_DLATCH_P_ +select -assert-none t:$_DLATCH_P_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to ADLATCHs. + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ 0 + +select -assert-count 1 t:$_NOT_ +select -assert-count 2 t:$_DLATCH_PP0_ +select -assert-none t:$_DLATCH_PP0_ t:$_NOT_ %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ 1 + +select -assert-count 5 t:$_NOT_ +select -assert-count 2 t:$_DLATCH_PP0_ +select -assert-none t:$_DLATCH_PP0_ t:$_NOT_ %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP1_ 0 + +select -assert-count 1 t:$_NOT_ +select -assert-count 2 t:$_DLATCH_PP1_ +select -assert-none t:$_DLATCH_PP1_ t:$_NOT_ %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP1_ 1 + +select -assert-count 5 t:$_NOT_ +select -assert-count 2 t:$_DLATCH_PP1_ +select -assert-none t:$_DLATCH_PP1_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to DLATCHSRs. + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ 0 + +select -assert-count 1 t:$_NOT_ +select -assert-count 2 t:$_DLATCHSR_PPP_ +select -assert-none t:$_DLATCHSR_PPP_ t:$_NOT_ %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ 1 + +select -assert-count 5 t:$_NOT_ +select -assert-count 2 t:$_DLATCHSR_PPP_ +select -assert-none t:$_DLATCHSR_PPP_ t:$_NOT_ %% %n t:* %i diff --git a/tests/techmap/dfflegalize_dlatchsr.ys b/tests/techmap/dfflegalize_dlatchsr.ys new file mode 100644 index 000000000..53d910723 --- /dev/null +++ b/tests/techmap/dfflegalize_dlatchsr.ys @@ -0,0 +1,37 @@ +read_verilog -icells <<EOT + +module dlatchsr(input E, R, S, D, output [3:0] Q); +$_DLATCHSR_PPP_ ff0 (.E(E), .R(R), .S(S), .D(D), .Q(Q[0])); +$_DLATCHSR_PPN_ ff1 (.E(E), .R(R), .S(S), .D(D), .Q(Q[1])); +$_DLATCHSR_PNP_ ff2 (.E(E), .R(R), .S(S), .D(D), .Q(Q[2])); +$_DLATCHSR_NPP_ ff3 (.E(E), .R(R), .S(S), .D(D), .Q(Q[3])); +endmodule + +EOT + +design -save orig +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ x -cell $_SR_PP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ x + + +# Convert everything to ADLATCHs. + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ x -cell $_SR_PP_ x + +select -assert-count 14 t:$_NOT_ +select -assert-count 4 t:$_MUX_ +select -assert-count 8 t:$_DLATCH_PP0_ +select -assert-count 4 t:$_SR_PP_ +select -assert-none t:$_DLATCH_PP0_ t:$_SR_PP_ t:$_MUX_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to DLATCHSRs. + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ x + +select -assert-count 3 t:$_NOT_ +select -assert-count 0 t:$_MUX_ +select -assert-count 4 t:$_DLATCHSR_PPP_ +select -assert-none t:$_DLATCHSR_PPP_ t:$_MUX_ t:$_NOT_ %% %n t:* %i diff --git a/tests/techmap/dfflegalize_dlatchsr_init.ys b/tests/techmap/dfflegalize_dlatchsr_init.ys new file mode 100644 index 000000000..2d33634d1 --- /dev/null +++ b/tests/techmap/dfflegalize_dlatchsr_init.ys @@ -0,0 +1,127 @@ +read_verilog -icells <<EOT + +module dlatchsr0(input E, R, S, D, (* init = 4'h0 *) output [3:0] Q); +$_DLATCHSR_PPP_ ff0 (.E(E), .R(R), .S(S), .D(D), .Q(Q[0])); +$_DLATCHSR_PPN_ ff1 (.E(E), .R(R), .S(S), .D(D), .Q(Q[1])); +$_DLATCHSR_PNP_ ff2 (.E(E), .R(R), .S(S), .D(D), .Q(Q[2])); +$_DLATCHSR_NPP_ ff3 (.E(E), .R(R), .S(S), .D(D), .Q(Q[3])); +endmodule + +module dlatchsr1(input E, R, S, D, (* init = 4'hf *) output [3:0] Q); +$_DLATCHSR_PPP_ ff0 (.E(E), .R(R), .S(S), .D(D), .Q(Q[0])); +$_DLATCHSR_PPN_ ff1 (.E(E), .R(R), .S(S), .D(D), .Q(Q[1])); +$_DLATCHSR_PNP_ ff2 (.E(E), .R(R), .S(S), .D(D), .Q(Q[2])); +$_DLATCHSR_NPP_ ff3 (.E(E), .R(R), .S(S), .D(D), .Q(Q[3])); +endmodule + +module top(input C, E, R, S, D, output [17:0] Q); +dlatchsr0 dlatchsr0_(.E(E), .R(R), .S(S), .D(D), .Q(Q[3:0])); +dlatchsr1 dlatchsr1_(.E(E), .R(R), .S(S), .D(D), .Q(Q[7:4])); +endmodule + +EOT + +design -save orig +flatten +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ 1 +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP1_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP1_ 1 +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ 1 + + +# Convert everything to ADLATCHs. + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ 0 + +select -assert-count 14 dlatchsr0/t:$_NOT_ +select -assert-count 18 dlatchsr1/t:$_NOT_ +select -assert-count 4 dlatchsr0/t:$_MUX_ +select -assert-count 4 dlatchsr1/t:$_MUX_ +select -assert-count 12 dlatchsr0/t:$_DLATCH_PP0_ +select -assert-count 12 dlatchsr1/t:$_DLATCH_PP0_ +select -assert-count 1 dlatchsr1/t:$_AND_ +select -assert-count 2 dlatchsr1/t:$_ANDNOT_ +select -assert-count 1 dlatchsr1/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dlatchsr1/* %n %i +select -assert-none t:$_DLATCH_PP0_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ 1 + +select -assert-count 14 dlatchsr0/t:$_NOT_ +select -assert-count 18 dlatchsr1/t:$_NOT_ +select -assert-count 4 dlatchsr0/t:$_MUX_ +select -assert-count 4 dlatchsr1/t:$_MUX_ +select -assert-count 12 dlatchsr0/t:$_DLATCH_PP0_ +select -assert-count 12 dlatchsr1/t:$_DLATCH_PP0_ +select -assert-count 1 dlatchsr1/t:$_AND_ +select -assert-count 2 dlatchsr1/t:$_ANDNOT_ +select -assert-count 1 dlatchsr1/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dlatchsr1/* %n %i +select -assert-none t:$_DLATCH_PP0_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP1_ 0 + +select -assert-count 22 dlatchsr0/t:$_NOT_ +select -assert-count 26 dlatchsr1/t:$_NOT_ +select -assert-count 4 dlatchsr0/t:$_MUX_ +select -assert-count 4 dlatchsr1/t:$_MUX_ +select -assert-count 12 dlatchsr0/t:$_DLATCH_PP1_ +select -assert-count 12 dlatchsr1/t:$_DLATCH_PP1_ +select -assert-count 1 dlatchsr1/t:$_AND_ +select -assert-count 2 dlatchsr1/t:$_ANDNOT_ +select -assert-count 1 dlatchsr1/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dlatchsr1/* %n %i +select -assert-none t:$_DLATCH_PP1_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP1_ 1 + +select -assert-count 22 dlatchsr0/t:$_NOT_ +select -assert-count 26 dlatchsr1/t:$_NOT_ +select -assert-count 4 dlatchsr0/t:$_MUX_ +select -assert-count 4 dlatchsr1/t:$_MUX_ +select -assert-count 12 dlatchsr0/t:$_DLATCH_PP1_ +select -assert-count 12 dlatchsr1/t:$_DLATCH_PP1_ +select -assert-count 1 dlatchsr1/t:$_AND_ +select -assert-count 2 dlatchsr1/t:$_ANDNOT_ +select -assert-count 1 dlatchsr1/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dlatchsr1/* %n %i +select -assert-none t:$_DLATCH_PP1_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + + +# Convert everything to DLATCHSRs. + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ 0 + +select -assert-count 3 dlatchsr0/t:$_NOT_ +select -assert-count 11 dlatchsr1/t:$_NOT_ +select -assert-count 0 dlatchsr0/t:$_MUX_ +select -assert-count 0 dlatchsr1/t:$_MUX_ +select -assert-count 4 dlatchsr0/t:$_DLATCHSR_PPP_ +select -assert-count 4 dlatchsr1/t:$_DLATCHSR_PPP_ +select -assert-count 1 dlatchsr1/t:$_AND_ +select -assert-count 2 dlatchsr1/t:$_ANDNOT_ +select -assert-count 1 dlatchsr1/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dlatchsr1/* %n %i +select -assert-none t:$_DLATCHSR_PPP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ 1 + +select -assert-count 11 dlatchsr0/t:$_NOT_ +select -assert-count 3 dlatchsr1/t:$_NOT_ +select -assert-count 0 dlatchsr0/t:$_MUX_ +select -assert-count 0 dlatchsr1j/t:$_MUX_ +select -assert-count 4 dlatchsr0/t:$_DLATCHSR_PPP_ +select -assert-count 4 dlatchsr1/t:$_DLATCHSR_PPP_ +select -assert-count 1 dlatchsr0/t:$_AND_ +select -assert-count 2 dlatchsr0/t:$_ANDNOT_ +select -assert-count 1 dlatchsr0/t:$_OR_ +select -assert-count 0 t:$_AND_ t:$_OR_ t:$_ANDNOT_ %% dlatchsr0/* %n %i +select -assert-none t:$_DLATCHSR_PPP_ t:$_MUX_ t:$_NOT_ t:$_AND_ t:$_ANDNOT_ t:$_OR_ top/* %% %n t:* %i diff --git a/tests/techmap/dfflegalize_inv.ys b/tests/techmap/dfflegalize_inv.ys new file mode 100644 index 000000000..cb42e01a8 --- /dev/null +++ b/tests/techmap/dfflegalize_inv.ys @@ -0,0 +1,178 @@ +# Base test: make sure inverters are applied correctly. + +read_verilog -icells <<EOT + +module top(input C, E, R, S, D, output [64:0] Q); + +$_DFF_P_ ff0 (.C(C), .D(D), .Q(Q[0])); +$_DFF_N_ ff1 (.C(C), .D(D), .Q(Q[1])); + +$_DFFE_PP_ ff2 (.C(C), .E(E), .D(D), .Q(Q[2])); +$_DFFE_PN_ ff3 (.C(C), .E(E), .D(D), .Q(Q[3])); +$_DFFE_NP_ ff4 (.C(C), .E(E), .D(D), .Q(Q[4])); + +$_DFF_PP0_ ff5 (.C(C), .R(R), .D(D), .Q(Q[5])); +$_DFF_PN0_ ff6 (.C(C), .R(R), .D(D), .Q(Q[6])); +$_DFF_NP0_ ff7 (.C(C), .R(R), .D(D), .Q(Q[7])); + +$_DFF_PP1_ ff8 (.C(C), .R(R), .D(D), .Q(Q[8])); +$_DFF_PN1_ ff9 (.C(C), .R(R), .D(D), .Q(Q[9])); +$_DFF_NP1_ ff10 (.C(C), .R(R), .D(D), .Q(Q[10])); + +$_DFFE_PP0P_ ff11 (.C(C), .R(R), .E(E), .D(D), .Q(Q[11])); +$_DFFE_PP0N_ ff12 (.C(C), .R(R), .E(E), .D(D), .Q(Q[12])); +$_DFFE_PN0P_ ff13 (.C(C), .R(R), .E(E), .D(D), .Q(Q[13])); +$_DFFE_NP0P_ ff14 (.C(C), .R(R), .E(E), .D(D), .Q(Q[14])); + +$_DFFE_PP1P_ ff15 (.C(C), .R(R), .E(E), .D(D), .Q(Q[15])); +$_DFFE_PP1N_ ff16 (.C(C), .R(R), .E(E), .D(D), .Q(Q[16])); +$_DFFE_PN1P_ ff17 (.C(C), .R(R), .E(E), .D(D), .Q(Q[17])); +$_DFFE_NP1P_ ff18 (.C(C), .R(R), .E(E), .D(D), .Q(Q[18])); + +$_DFFSR_PPP_ ff19 (.C(C), .R(R), .S(S), .D(D), .Q(Q[19])); +$_DFFSR_PPN_ ff20 (.C(C), .R(R), .S(S), .D(D), .Q(Q[20])); +$_DFFSR_PNP_ ff21 (.C(C), .R(R), .S(S), .D(D), .Q(Q[21])); +$_DFFSR_NPP_ ff22 (.C(C), .R(R), .S(S), .D(D), .Q(Q[22])); + +$_DFFSRE_PPPP_ ff23 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[23])); +$_DFFSRE_PPPN_ ff24 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[24])); +$_DFFSRE_PPNP_ ff25 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[25])); +$_DFFSRE_PNPP_ ff26 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[26])); +$_DFFSRE_NPPP_ ff27 (.C(C), .R(R), .S(S), .E(E), .D(D), .Q(Q[27])); + +$_SDFF_PP0_ ff28 (.C(C), .R(R), .D(D), .Q(Q[28])); +$_SDFF_PN0_ ff29 (.C(C), .R(R), .D(D), .Q(Q[29])); +$_SDFF_NP0_ ff30 (.C(C), .R(R), .D(D), .Q(Q[30])); + +$_SDFF_PP1_ ff31 (.C(C), .R(R), .D(D), .Q(Q[31])); +$_SDFF_PN1_ ff32 (.C(C), .R(R), .D(D), .Q(Q[32])); +$_SDFF_NP1_ ff33 (.C(C), .R(R), .D(D), .Q(Q[33])); + +$_SDFFE_PP0P_ ff34 (.C(C), .R(R), .E(E), .D(D), .Q(Q[34])); +$_SDFFE_PP0N_ ff35 (.C(C), .R(R), .E(E), .D(D), .Q(Q[35])); +$_SDFFE_PN0P_ ff36 (.C(C), .R(R), .E(E), .D(D), .Q(Q[36])); +$_SDFFE_NP0P_ ff37 (.C(C), .R(R), .E(E), .D(D), .Q(Q[37])); + +$_SDFFE_PP1P_ ff38 (.C(C), .R(R), .E(E), .D(D), .Q(Q[38])); +$_SDFFE_PP1N_ ff39 (.C(C), .R(R), .E(E), .D(D), .Q(Q[39])); +$_SDFFE_PN1P_ ff40 (.C(C), .R(R), .E(E), .D(D), .Q(Q[40])); +$_SDFFE_NP1P_ ff41 (.C(C), .R(R), .E(E), .D(D), .Q(Q[41])); + +$_SDFFCE_PP0P_ ff42 (.C(C), .R(R), .E(E), .D(D), .Q(Q[42])); +$_SDFFCE_PP0N_ ff43 (.C(C), .R(R), .E(E), .D(D), .Q(Q[43])); +$_SDFFCE_PN0P_ ff44 (.C(C), .R(R), .E(E), .D(D), .Q(Q[44])); +$_SDFFCE_NP0P_ ff45 (.C(C), .R(R), .E(E), .D(D), .Q(Q[45])); + +$_SDFFCE_PP1P_ ff46 (.C(C), .R(R), .E(E), .D(D), .Q(Q[46])); +$_SDFFCE_PP1N_ ff47 (.C(C), .R(R), .E(E), .D(D), .Q(Q[47])); +$_SDFFCE_PN1P_ ff48 (.C(C), .R(R), .E(E), .D(D), .Q(Q[48])); +$_SDFFCE_NP1P_ ff49 (.C(C), .R(R), .E(E), .D(D), .Q(Q[49])); + +$_DLATCH_P_ ff50 (.E(E), .D(D), .Q(Q[50])); +$_DLATCH_N_ ff51 (.E(E), .D(D), .Q(Q[51])); + +$_DLATCH_PP0_ ff52 (.E(E), .R(R), .D(D), .Q(Q[52])); +$_DLATCH_PN0_ ff53 (.E(E), .R(R), .D(D), .Q(Q[53])); +$_DLATCH_NP0_ ff54 (.E(E), .R(R), .D(D), .Q(Q[54])); + +$_DLATCH_PP1_ ff55 (.E(E), .R(R), .D(D), .Q(Q[55])); +$_DLATCH_PN1_ ff56 (.E(E), .R(R), .D(D), .Q(Q[56])); +$_DLATCH_NP1_ ff57 (.E(E), .R(R), .D(D), .Q(Q[57])); + +$_DLATCHSR_PPP_ ff58 (.E(E), .R(R), .S(S), .D(D), .Q(Q[58])); +$_DLATCHSR_PPN_ ff59 (.E(E), .R(R), .S(S), .D(D), .Q(Q[59])); +$_DLATCHSR_PNP_ ff60 (.E(E), .R(R), .S(S), .D(D), .Q(Q[60])); +$_DLATCHSR_NPP_ ff61 (.E(E), .R(R), .S(S), .D(D), .Q(Q[61])); + +$_SR_PP_ ff62 (.R(R), .S(S), .Q(Q[62])); +$_SR_PN_ ff63 (.R(R), .S(S), .Q(Q[63])); +$_SR_NP_ ff64 (.R(R), .S(S), .Q(Q[64])); + +endmodule + +EOT + +design -save orig + +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_P_ x -cell $_DFFE_PP_ x -cell $_DFF_PP?_ x -cell $_DFFE_PP?P_ x -cell $_DFFSR_PPP_ x -cell $_DFFSRE_PPPP_ x -cell $_SDFF_PP?_ x -cell $_SDFFE_PP?P_ x -cell $_SDFFCE_PP?P_ x -cell $_DLATCH_P_ x -cell $_DLATCH_PP?_ x -cell $_DLATCHSR_PPP_ x -cell $_SR_PP_ x +design -load postopt + +select -assert-count 46 t:$_NOT_ +select -assert-count 2 t:$_DFF_P_ +select -assert-count 3 t:$_DFFE_PP_ +select -assert-count 3 t:$_DFF_PP0_ +select -assert-count 3 t:$_DFF_PP1_ +select -assert-count 4 t:$_DFFE_PP0P_ +select -assert-count 4 t:$_DFFE_PP1P_ +select -assert-count 4 t:$_DFFSR_PPP_ +select -assert-count 5 t:$_DFFSRE_PPPP_ +select -assert-count 3 t:$_SDFF_PP0_ +select -assert-count 3 t:$_SDFF_PP1_ +select -assert-count 4 t:$_SDFFE_PP0P_ +select -assert-count 4 t:$_SDFFE_PP1P_ +select -assert-count 4 t:$_SDFFCE_PP0P_ +select -assert-count 4 t:$_SDFFCE_PP1P_ +select -assert-count 2 t:$_DLATCH_P_ +select -assert-count 3 t:$_DLATCH_PP0_ +select -assert-count 3 t:$_DLATCH_PP1_ +select -assert-count 4 t:$_DLATCHSR_PPP_ +select -assert-count 3 t:$_SR_PP_ +select -assert-none t:$_DFF_P_ t:$_DFFE_PP_ t:$_DFF_PP?_ t:$_DFFE_PP?P_ t:$_DFFSR_PPP_ t:$_DFFSRE_PPPP_ t:$_SDFF_PP?_ t:$_SDFFE_PP?P_ t:$_SDFFCE_PP?P_ t:$_DLATCH_P_ t:$_DLATCH_PP?_ t:$_DLATCHSR_PPP_ t:$_SR_PP_ t:$_NOT_ %% %n t:* %i + +# Now try it again, targetting the opposite cells. + +design -load orig + +equiv_opt -assert -multiclock dfflegalize -cell $_DFF_N_ x -cell $_DFFE_NN_ x -cell $_DFF_NN?_ x -cell $_DFFE_NN?N_ x -cell $_DFFSR_NNN_ x -cell $_DFFSRE_NNNN_ x -cell $_SDFF_NN?_ x -cell $_SDFFE_NN?N_ x -cell $_SDFFCE_NN?N_ x -cell $_DLATCH_N_ x -cell $_DLATCH_NN?_ x -cell $_DLATCHSR_NNN_ x -cell $_SR_NN_ x +design -load postopt + +select -assert-count 122 t:$_NOT_ +select -assert-count 2 t:$_DFF_N_ +select -assert-count 3 t:$_DFFE_NN_ +select -assert-count 3 t:$_DFF_NN0_ +select -assert-count 3 t:$_DFF_NN1_ +select -assert-count 4 t:$_DFFE_NN0N_ +select -assert-count 4 t:$_DFFE_NN1N_ +select -assert-count 4 t:$_DFFSR_NNN_ +select -assert-count 5 t:$_DFFSRE_NNNN_ +select -assert-count 3 t:$_SDFF_NN0_ +select -assert-count 3 t:$_SDFF_NN1_ +select -assert-count 4 t:$_SDFFE_NN0N_ +select -assert-count 4 t:$_SDFFE_NN1N_ +select -assert-count 4 t:$_SDFFCE_NN0N_ +select -assert-count 4 t:$_SDFFCE_NN1N_ +select -assert-count 2 t:$_DLATCH_N_ +select -assert-count 3 t:$_DLATCH_NN0_ +select -assert-count 3 t:$_DLATCH_NN1_ +select -assert-count 4 t:$_DLATCHSR_NNN_ +select -assert-count 3 t:$_SR_NN_ +select -assert-none t:$_DFF_N_ t:$_DFFE_NN_ t:$_DFF_NN?_ t:$_DFFE_NN?N_ t:$_DFFSR_NNN_ t:$_DFFSRE_NNNN_ t:$_SDFF_NN?_ t:$_SDFFE_NN?N_ t:$_SDFFCE_NN?N_ t:$_DLATCH_N_ t:$_DLATCH_NN?_ t:$_DLATCHSR_NNN_ t:$_SR_NN_ t:$_NOT_ %% %n t:* %i + + +# Second test: make sure set/reset/enable are inverted before clock. + +design -reset + +read_verilog -icells <<EOT + +module top(input C, E, R, S, D, output [3:0] Q); + +$_DFFSRE_PPPP_ ff0 (.C(C), .E(E), .R(R), .S(S), .D(D), .Q(Q[0])); +$_DFFSRE_NPPP_ ff1 (.C(C), .E(E), .R(R), .S(S), .D(D), .Q(Q[1])); +$_DFFSRE_PNNN_ ff2 (.C(C), .E(E), .R(R), .S(S), .D(D), .Q(Q[2])); +$_DFFSRE_NNNN_ ff3 (.C(C), .E(E), .R(R), .S(S), .D(D), .Q(Q[3])); + +endmodule + +EOT + +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_NNNN_ x -cell $_DFFSRE_PPPP_ x +design -load postopt + +select -assert-count 6 t:$_NOT_ +select -assert-count 2 t:$_DFFSRE_PPPP_ +select -assert-count 2 t:$_DFFSRE_NNNN_ +select -assert-count 1 t:$_DFFSRE_PPPP_ n:ff0 %i +select -assert-count 1 t:$_DFFSRE_NNNN_ n:ff1 %i +select -assert-count 1 t:$_DFFSRE_PPPP_ n:ff2 %i +select -assert-count 1 t:$_DFFSRE_NNNN_ n:ff3 %i diff --git a/tests/techmap/dfflegalize_mince.ys b/tests/techmap/dfflegalize_mince.ys new file mode 100644 index 000000000..31c8d04fc --- /dev/null +++ b/tests/techmap/dfflegalize_mince.ys @@ -0,0 +1,53 @@ +read_verilog -icells <<EOT + +module top(input D, C, R, S, input [4:0] E, output [15:0] Q); +$_DFFE_PP_ ff0(.D(D), .C(C), .E(E[0]), .Q(Q[0])); +$_DFFE_PP0P_ ff1(.D(D), .C(C), .E(E[0]), .R(R), .Q(Q[1])); +$_DFFE_PP1P_ ff2(.D(D), .C(C), .E(E[0]), .R(R), .Q(Q[2])); +$_SDFFE_PP0P_ ff3(.D(D), .C(C), .E(E[0]), .R(R), .Q(Q[3])); +$_SDFFE_PP1P_ ff4(.D(D), .C(C), .E(E[0]), .R(R), .Q(Q[4])); +$_SDFFCE_PP0P_ ff5(.D(D), .C(C), .E(E[0]), .R(R), .Q(Q[5])); +$_SDFFCE_PP1P_ ff6(.D(D), .C(C), .E(E[0]), .R(R), .Q(Q[6])); +$_DFFSRE_PPPP_ ff7(.D(D), .C(C), .E(E[0]), .R(R), .S(S), .Q(Q[7])); +$_DFFE_PP_ ff8(.D(D), .C(C), .E(E[1]), .Q(Q[8])); +$_DFFE_PP0P_ ff9(.D(D), .C(C), .E(E[1]), .R(R), .Q(Q[9])); +$_DFFE_PP1P_ ff10(.D(D), .C(C), .E(E[2]), .R(R), .Q(Q[10])); +$_SDFFE_PP0P_ ff11(.D(D), .C(C), .E(E[2]), .R(R), .Q(Q[11])); +$_SDFFE_PP1P_ ff12(.D(D), .C(C), .E(E[3]), .R(R), .Q(Q[12])); +$_SDFFCE_PP0P_ ff13(.D(D), .C(C), .E(E[3]), .R(R), .Q(Q[13])); +$_SDFFCE_PP1P_ ff14(.D(D), .C(C), .E(E[4]), .R(R), .Q(Q[14])); +$_DFFSRE_PPPP_ ff15(.D(D), .C(C), .E(E[4]), .R(R), .S(S), .Q(Q[15])); +endmodule + +EOT + +design -save orig +equiv_opt -assert -multiclock dfflegalize -cell $_DFFE_PP_ x -cell $_DFFE_PP?P_ x -cell $_DFFSRE_PPPP_ x -cell $_SDFFE_PP?P_ x -cell $_SDFFCE_PP?P_ x -mince 3 +design -load postopt + +select -assert-count 4 t:$_DFFE_PP_ +select -assert-count 2 t:$_DFFE_PP0P_ +select -assert-count 2 t:$_DFFE_PP1P_ +select -assert-count 2 t:$_SDFFE_PP0P_ +select -assert-count 2 t:$_SDFFE_PP1P_ +select -assert-count 1 t:$_SDFFCE_PP0P_ +select -assert-count 1 t:$_SDFFCE_PP1P_ +select -assert-count 2 t:$_DFFSRE_PPPP_ +select -assert-count 10 t:$_MUX_ +select -assert-count 0 n:ff0 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff1 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff2 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff3 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff4 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff5 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff6 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff7 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff8 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff9 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff10 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff11 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff12 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff13 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff14 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff15 %ci %ci t:$_MUX_ %i +select -assert-none n:ff* t:$_MUX_ %% %n t:* %i diff --git a/tests/techmap/dfflegalize_minsrst.ys b/tests/techmap/dfflegalize_minsrst.ys new file mode 100644 index 000000000..0fc40dc08 --- /dev/null +++ b/tests/techmap/dfflegalize_minsrst.ys @@ -0,0 +1,43 @@ +read_verilog -icells <<EOT + +module top(input D, C, E, input [3:0] R, output [11:0] Q); +$_SDFF_PP0_ ff0(.D(D), .C(C), .R(R[0]), .Q(Q[0])); +$_SDFF_PP1_ ff1(.D(D), .C(C), .R(R[0]), .Q(Q[1])); +$_SDFFE_PP0P_ ff2(.D(D), .C(C), .R(R[0]), .E(E), .Q(Q[2])); +$_SDFFE_PP1P_ ff3(.D(D), .C(C), .R(R[0]), .E(E), .Q(Q[3])); +$_SDFFCE_PP0P_ ff4(.D(D), .C(C), .R(R[0]), .E(E), .Q(Q[4])); +$_SDFFCE_PP1P_ ff5(.D(D), .C(C), .R(R[0]), .E(E), .Q(Q[5])); +$_SDFF_PP0_ ff6(.D(D), .C(C), .R(R[1]), .Q(Q[6])); +$_SDFF_PP1_ ff7(.D(D), .C(C), .R(R[1]), .Q(Q[7])); +$_SDFFE_PP0P_ ff8(.D(D), .C(C), .R(R[2]), .E(E), .Q(Q[8])); +$_SDFFE_PP1P_ ff9(.D(D), .C(C), .R(R[2]), .E(E), .Q(Q[9])); +$_SDFFCE_PP0P_ ff10(.D(D), .C(C), .R(R[3]), .E(E), .Q(Q[10])); +$_SDFFCE_PP1P_ ff11(.D(D), .C(C), .R(R[3]), .E(E), .Q(Q[11])); +endmodule + +EOT + +design -save orig +equiv_opt -assert -multiclock dfflegalize -cell $_SDFF_PP?_ x -cell $_SDFFE_PP?P_ x -cell $_SDFFCE_PP?P_ x -minsrst 3 +design -load postopt + +select -assert-count 5 t:$_SDFF_PP0_ +select -assert-count 1 t:$_SDFF_PP1_ +select -assert-count 3 t:$_SDFFE_PP0P_ +select -assert-count 1 t:$_SDFFE_PP1P_ +select -assert-count 1 t:$_SDFFCE_PP0P_ +select -assert-count 1 t:$_SDFFCE_PP1P_ +select -assert-count 8 t:$_MUX_ +select -assert-count 0 n:ff0 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff1 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff2 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff3 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff4 %ci %ci t:$_MUX_ %i +select -assert-count 0 n:ff5 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff6 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff7 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff8 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff9 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff10 %ci %ci t:$_MUX_ %i +select -assert-count 1 n:ff11 %ci %ci t:$_MUX_ %i +select -assert-none n:ff* t:$_MUX_ %% %n t:* %i diff --git a/tests/techmap/dfflegalize_sr.ys b/tests/techmap/dfflegalize_sr.ys new file mode 100644 index 000000000..27e83be91 --- /dev/null +++ b/tests/techmap/dfflegalize_sr.ys @@ -0,0 +1,74 @@ +read_verilog -icells <<EOT + +module sr(input R, S, output [2:0] Q); +$_SR_PP_ ff0 (.R(R), .S(S), .Q(Q[0])); +$_SR_PN_ ff1 (.R(R), .S(S), .Q(Q[1])); +$_SR_NP_ ff2 (.R(R), .S(S), .Q(Q[2])); +endmodule + +EOT + +design -save orig +equiv_opt -assert -multiclock dfflegalize -cell $_SR_PP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP1_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ x +equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ x + + +# Convert everything to SRs. + +design -load orig +dfflegalize -cell $_SR_PP_ x + +select -assert-count 2 t:$_NOT_ +select -assert-count 3 t:$_SR_PP_ +select -assert-none t:$_SR_PP_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to ADLATCHs. + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ x + +select -assert-count 2 t:$_NOT_ +select -assert-count 3 t:$_DLATCH_PP0_ +select -assert-none t:$_DLATCH_PP0_ t:$_NOT_ %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP1_ x + +select -assert-count 8 t:$_NOT_ +select -assert-count 3 t:$_DLATCH_PP1_ +select -assert-none t:$_DLATCH_PP1_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to DLATCHSRs. + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ x + +select -assert-count 2 t:$_NOT_ +select -assert-count 3 t:$_DLATCHSR_PPP_ +select -assert-none t:$_DLATCHSR_PPP_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to DFFSRs. + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ x + +select -assert-count 2 t:$_NOT_ +select -assert-count 3 t:$_DFFSR_PPP_ +select -assert-none t:$_DFFSR_PPP_ t:$_NOT_ %% %n t:* %i + + +# Convert everything to DFFSREs. + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ x + +select -assert-count 2 t:$_NOT_ +select -assert-count 3 t:$_DFFSRE_PPPP_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ %% %n t:* %i diff --git a/tests/techmap/dfflegalize_sr_init.ys b/tests/techmap/dfflegalize_sr_init.ys new file mode 100644 index 000000000..52b797b9e --- /dev/null +++ b/tests/techmap/dfflegalize_sr_init.ys @@ -0,0 +1,230 @@ +read_verilog -icells <<EOT + +module sr0(input R, S, (* init = 3'h0 *) output [2:0] Q); +$_SR_PP_ ff0 (.R(R), .S(S), .Q(Q[0])); +$_SR_PN_ ff1 (.R(R), .S(S), .Q(Q[1])); +$_SR_NP_ ff2 (.R(R), .S(S), .Q(Q[2])); +endmodule + +module sr1(input R, S, (* init = 3'h7 *) output [2:0] Q); +$_SR_PP_ ff0 (.R(R), .S(S), .Q(Q[0])); +$_SR_PN_ ff1 (.R(R), .S(S), .Q(Q[1])); +$_SR_NP_ ff2 (.R(R), .S(S), .Q(Q[2])); +endmodule + +module top(input C, E, R, D, output [5:0] Q); +sr0 sr0_(.S(S), .R(R), .Q(Q[2:0])); +sr1 sr1_(.S(S), .R(R), .Q(Q[5:3])); +endmodule + +EOT + +design -save orig +flatten +#equiv_opt -assert -multiclock dfflegalize -cell $_SR_PP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_SR_PP_ 1 +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP0_ 1 +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP1_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCH_PP1_ 1 +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DLATCHSR_PPP_ 1 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFSR_PPP_ 1 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 0 +#equiv_opt -assert -multiclock dfflegalize -cell $_DFFSRE_PPPP_ 1 + + +# Convert everything to SRs. + +design -load orig +dfflegalize -cell $_SR_PP_ 0 + +select -assert-count 2 sr0/t:$_NOT_ +select -assert-count 5 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_SR_PP_ +select -assert-count 3 sr1/t:$_SR_PP_ +select -assert-count 0 sr0/t:$_ANDNOT_ +select -assert-count 1 sr1/t:$_ANDNOT_ +select -assert-count 0 sr0/t:$_AND_ +select -assert-count 1 sr1/t:$_AND_ +select -assert-count 0 sr0/t:$_OR_ +select -assert-count 1 sr1/t:$_OR_ +select -assert-none t:$_SR_PP_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_SR_PP_ 1 + +select -assert-count 5 sr0/t:$_NOT_ +select -assert-count 2 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_SR_PP_ +select -assert-count 3 sr1/t:$_SR_PP_ +select -assert-count 1 sr0/t:$_ANDNOT_ +select -assert-count 0 sr1/t:$_ANDNOT_ +select -assert-count 1 sr0/t:$_AND_ +select -assert-count 0 sr1/t:$_AND_ +select -assert-count 1 sr0/t:$_OR_ +select -assert-count 0 sr1/t:$_OR_ +select -assert-none t:$_SR_PP_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i + + +# Convert everything to ADLATCHs. + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ 0 + +select -assert-count 2 sr0/t:$_NOT_ +select -assert-count 5 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_DLATCH_PP0_ +select -assert-count 3 sr1/t:$_DLATCH_PP0_ +select -assert-count 0 sr0/t:$_ANDNOT_ +select -assert-count 1 sr1/t:$_ANDNOT_ +select -assert-count 0 sr0/t:$_AND_ +select -assert-count 1 sr1/t:$_AND_ +select -assert-count 0 sr0/t:$_OR_ +select -assert-count 1 sr1/t:$_OR_ +select -assert-none t:$_DLATCH_PP0_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP0_ 1 + +select -assert-count 5 sr0/t:$_NOT_ +select -assert-count 2 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_DLATCH_PP0_ +select -assert-count 3 sr1/t:$_DLATCH_PP0_ +select -assert-count 1 sr0/t:$_ANDNOT_ +select -assert-count 0 sr1/t:$_ANDNOT_ +select -assert-count 1 sr0/t:$_AND_ +select -assert-count 0 sr1/t:$_AND_ +select -assert-count 1 sr0/t:$_OR_ +select -assert-count 0 sr1/t:$_OR_ +select -assert-none t:$_DLATCH_PP0_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP1_ 0 + +select -assert-count 11 sr0/t:$_NOT_ +select -assert-count 8 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_DLATCH_PP1_ +select -assert-count 3 sr1/t:$_DLATCH_PP1_ +select -assert-count 1 sr0/t:$_ANDNOT_ +select -assert-count 0 sr1/t:$_ANDNOT_ +select -assert-count 1 sr0/t:$_AND_ +select -assert-count 0 sr1/t:$_AND_ +select -assert-count 1 sr0/t:$_OR_ +select -assert-count 0 sr1/t:$_OR_ +select -assert-none t:$_DLATCH_PP1_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCH_PP1_ 1 + +select -assert-count 8 sr0/t:$_NOT_ +select -assert-count 11 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_DLATCH_PP1_ +select -assert-count 3 sr1/t:$_DLATCH_PP1_ +select -assert-count 0 sr0/t:$_ANDNOT_ +select -assert-count 1 sr1/t:$_ANDNOT_ +select -assert-count 0 sr0/t:$_AND_ +select -assert-count 1 sr1/t:$_AND_ +select -assert-count 0 sr0/t:$_OR_ +select -assert-count 1 sr1/t:$_OR_ +select -assert-none t:$_DLATCH_PP1_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i + + +# Convert everything to DLATCHSRs. + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ 0 + +select -assert-count 2 sr0/t:$_NOT_ +select -assert-count 5 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_DLATCHSR_PPP_ +select -assert-count 3 sr1/t:$_DLATCHSR_PPP_ +select -assert-count 0 sr0/t:$_ANDNOT_ +select -assert-count 1 sr1/t:$_ANDNOT_ +select -assert-count 0 sr0/t:$_AND_ +select -assert-count 1 sr1/t:$_AND_ +select -assert-count 0 sr0/t:$_OR_ +select -assert-count 1 sr1/t:$_OR_ +select -assert-none t:$_DLATCHSR_PPP_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DLATCHSR_PPP_ 1 + +select -assert-count 5 sr0/t:$_NOT_ +select -assert-count 2 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_DLATCHSR_PPP_ +select -assert-count 3 sr1/t:$_DLATCHSR_PPP_ +select -assert-count 1 sr0/t:$_ANDNOT_ +select -assert-count 0 sr1/t:$_ANDNOT_ +select -assert-count 1 sr0/t:$_AND_ +select -assert-count 0 sr1/t:$_AND_ +select -assert-count 1 sr0/t:$_OR_ +select -assert-count 0 sr1/t:$_OR_ +select -assert-none t:$_DLATCHSR_PPP_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i + + +# Convert everything to DFFSRs. + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ 0 + +select -assert-count 2 sr0/t:$_NOT_ +select -assert-count 5 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_DFFSR_PPP_ +select -assert-count 3 sr1/t:$_DFFSR_PPP_ +select -assert-count 0 sr0/t:$_ANDNOT_ +select -assert-count 1 sr1/t:$_ANDNOT_ +select -assert-count 0 sr0/t:$_AND_ +select -assert-count 1 sr1/t:$_AND_ +select -assert-count 0 sr0/t:$_OR_ +select -assert-count 1 sr1/t:$_OR_ +select -assert-none t:$_DFFSR_PPP_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFSR_PPP_ 1 + +select -assert-count 5 sr0/t:$_NOT_ +select -assert-count 2 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_DFFSR_PPP_ +select -assert-count 3 sr1/t:$_DFFSR_PPP_ +select -assert-count 1 sr0/t:$_ANDNOT_ +select -assert-count 0 sr1/t:$_ANDNOT_ +select -assert-count 1 sr0/t:$_AND_ +select -assert-count 0 sr1/t:$_AND_ +select -assert-count 1 sr0/t:$_OR_ +select -assert-count 0 sr1/t:$_OR_ +select -assert-none t:$_DFFSR_PPP_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i + + +# Convert everything to DFFSREs. + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ 0 + +select -assert-count 2 sr0/t:$_NOT_ +select -assert-count 5 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_DFFSRE_PPPP_ +select -assert-count 3 sr1/t:$_DFFSRE_PPPP_ +select -assert-count 0 sr0/t:$_ANDNOT_ +select -assert-count 1 sr1/t:$_ANDNOT_ +select -assert-count 0 sr0/t:$_AND_ +select -assert-count 1 sr1/t:$_AND_ +select -assert-count 0 sr0/t:$_OR_ +select -assert-count 1 sr1/t:$_OR_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i + +design -load orig +dfflegalize -cell $_DFFSRE_PPPP_ 1 + +select -assert-count 5 sr0/t:$_NOT_ +select -assert-count 2 sr1/t:$_NOT_ +select -assert-count 3 sr0/t:$_DFFSRE_PPPP_ +select -assert-count 3 sr1/t:$_DFFSRE_PPPP_ +select -assert-count 1 sr0/t:$_ANDNOT_ +select -assert-count 0 sr1/t:$_ANDNOT_ +select -assert-count 1 sr0/t:$_AND_ +select -assert-count 0 sr1/t:$_AND_ +select -assert-count 1 sr0/t:$_OR_ +select -assert-count 0 sr1/t:$_OR_ +select -assert-none t:$_DFFSRE_PPPP_ t:$_NOT_ t:$_ANDNOT_ t:$_OR_ t:$_AND_ top/* %% %n t:* %i diff --git a/tests/techmap/dfflibmap-sim.v b/tests/techmap/dfflibmap-sim.v new file mode 100644 index 000000000..1788a683b --- /dev/null +++ b/tests/techmap/dfflibmap-sim.v @@ -0,0 +1,22 @@ +module dffn(input CLK, D, output reg Q, output QN); + +always @(negedge CLK) + Q <= D; + +assign QN = ~Q; + +endmodule + +module dffsr(input CLK, D, CLEAR, PRESET, output reg Q, output QN); + +always @(posedge CLK, posedge CLEAR, posedge PRESET) + if (CLEAR) + Q <= 0; + else if (PRESET) + Q <= 1; + else + Q <= D; + +assign QN = ~Q; + +endmodule diff --git a/tests/techmap/dfflibmap.lib b/tests/techmap/dfflibmap.lib new file mode 100644 index 000000000..ce460877e --- /dev/null +++ b/tests/techmap/dfflibmap.lib @@ -0,0 +1,55 @@ +library(test) { + /* D-type flip-flop with asynchronous reset and preset */ + cell (dffn) { + area : 6; + ff("IQ", "IQN") { + next_state : "D"; + clocked_on : "!CLK"; + } + pin(D) { + direction : input; + } + pin(CLK) { + direction : input; + } + pin(Q) { + direction: output; + function : "IQ"; + } + pin(QN) { + direction: output; + function : "IQN"; + } + } + cell (dffsr) { + area : 6; + ff("IQ", "IQN") { + next_state : "D"; + clocked_on : "CLK"; + clear : "CLEAR"; + preset : "PRESET"; + clear_preset_var1 : L; + clear_preset_var2 : L; + } + pin(D) { + direction : input; + } + pin(CLK) { + direction : input; + } + pin(CLEAR) { + direction : input; + } + pin(PRESET) { + direction : input; + } + pin(Q) { + direction: output; + function : "IQ"; + } + pin(QN) { + direction: output; + function : "IQN"; + } + } +} diff --git a/tests/techmap/dfflibmap.ys b/tests/techmap/dfflibmap.ys new file mode 100644 index 000000000..04477eb14 --- /dev/null +++ b/tests/techmap/dfflibmap.ys @@ -0,0 +1,58 @@ +read_verilog -icells <<EOT + +module top(input C, D, S, R, output [9:0] Q); + +$_DFF_P_ ff0 (.C(C), .D(D), .Q(Q[0])); +$_DFF_PP0_ ff1 (.C(C), .D(D), .R(R), .Q(Q[1])); +$_DFF_PP1_ ff2 (.C(C), .D(D), .R(R), .Q(Q[2])); +$_DFFSR_PPP_ ff3 (.C(C), .D(D), .R(R), .S(S), .Q(Q[3])); +$_DFFSR_NNN_ ff4 (.C(C), .D(D), .R(R), .S(S), .Q(Q[4])); + +assign Q[9:5] = ~Q[4:0]; + +endmodule + +EOT + +simplemap + +design -save orig + +#equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -liberty dfflibmap.lib +#equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -prepare -liberty dfflibmap.lib +dfflibmap -prepare -liberty dfflibmap.lib +equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -map-only -liberty dfflibmap.lib + +design -load orig +dfflibmap -liberty dfflibmap.lib +clean + +select -assert-count 4 t:$_NOT_ +select -assert-count 1 t:dffn +select -assert-count 4 t:dffsr +select -assert-none t:dffn t:dffsr t:$_NOT_ %% %n t:* %i + +design -load orig +dfflibmap -prepare -liberty dfflibmap.lib + +select -assert-count 9 t:$_NOT_ +select -assert-count 1 t:$_DFF_N_ +select -assert-count 4 t:$_DFFSR_PPP_ +select -assert-none t:$_DFF_N_ t:$_DFFSR_PPP_ t:$_NOT_ %% %n t:* %i + +design -load orig +dfflibmap -map-only -liberty dfflibmap.lib + +select -assert-count 5 t:$_NOT_ +select -assert-count 0 t:dffn +select -assert-count 1 t:dffsr + +design -load orig +dfflibmap -prepare -liberty dfflibmap.lib +dfflibmap -map-only -liberty dfflibmap.lib +clean + +select -assert-count 4 t:$_NOT_ +select -assert-count 1 t:dffn +select -assert-count 4 t:dffsr +select -assert-none t:dffn t:dffsr t:$_NOT_ %% %n t:* %i diff --git a/tests/techmap/dffunmap.ys b/tests/techmap/dffunmap.ys new file mode 100644 index 000000000..b813078ee --- /dev/null +++ b/tests/techmap/dffunmap.ys @@ -0,0 +1,100 @@ +read_verilog -icells << EOT + +module top(...); + +input C, R, E, S; +input [1:0] D; +output [20:0] Q; + +$dff #(.CLK_POLARITY(1'b0), .WIDTH(2)) ff0 (.CLK(C), .D(D), .Q(Q[1:0])); +$dffe #(.CLK_POLARITY(1'b0), .EN_POLARITY(1'b0), .WIDTH(2)) ff1 (.CLK(C), .EN(E), .D(D), .Q(Q[3:2])); +$sdff #(.CLK_POLARITY(1'b0), .WIDTH(2), .SRST_POLARITY(1'b0), .SRST_VALUE(2'h2)) ff2 (.CLK(C), .SRST(R), .D(D), .Q(Q[5:4])); +$sdffe #(.CLK_POLARITY(1'b0), .EN_POLARITY(1'b1), .WIDTH(2), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2)) ff3 (.CLK(C), .EN(E), .SRST(R), .D(D), .Q(Q[7:6])); +$sdffce #(.CLK_POLARITY(1'b0), .EN_POLARITY(1'b1), .WIDTH(2), .SRST_POLARITY(1'b1), .SRST_VALUE(2'h2)) ff4 (.CLK(C), .EN(E), .SRST(R), .D(D), .Q(Q[9:8])); +$adff #(.CLK_POLARITY(1'b0), .WIDTH(2), .ARST_POLARITY(1'b0), .ARST_VALUE(2'h2)) ff5 (.CLK(C), .ARST(R), .D(D), .Q(Q[11:10])); +$adffe #(.CLK_POLARITY(1'b0), .EN_POLARITY(1'b1), .WIDTH(2), .ARST_POLARITY(1'b1), .ARST_VALUE(2'h2)) ff6 (.CLK(C), .EN(E), .ARST(R), .D(D), .Q(Q[13:12])); +$dffsr #(.CLK_POLARITY(1'b0), .WIDTH(2), .CLR_POLARITY(1'b0), .SET_POLARITY(1'b1)) ff7 (.CLK(C), .CLR({R, S}), .SET({S, R}), .D(D), .Q(Q[15:14])); +$dffsre #(.CLK_POLARITY(1'b0), .EN_POLARITY(1'b1), .WIDTH(2), .CLR_POLARITY(1'b1), .SET_POLARITY(1'b0)) ff8 (.CLK(C), .EN(E), .CLR({R, R}), .SET({S, S}), .D(D), .Q(Q[17:16])); + +endmodule + +EOT + +design -save orig + +equiv_opt -assert -async2sync dffunmap +design -load postopt +select -assert-none t:$sdff t:$dffe t:$adffe t:$sdffe t:$sdffce t:$dffsre +select -assert-count 5 t:$dff +select -assert-count 2 t:$adff +select -assert-count 2 t:$dffsr + +design -load orig + +equiv_opt -assert -async2sync dffunmap -ce-only +design -load postopt +select -assert-none t:$dffe t:$adffe t:$sdffe t:$sdffce t:$dffsre +select -assert-count 3 t:$dff +select -assert-count 2 t:$sdff +select -assert-count 2 t:$adff +select -assert-count 2 t:$dffsr + +design -load orig + +equiv_opt -assert -async2sync dffunmap -srst-only +design -load postopt +select -assert-none t:$sdff t:$sdffe t:$sdffce +select -assert-count 3 t:$dff +select -assert-count 2 t:$dffe +select -assert-count 1 t:$adff +select -assert-count 1 t:$adffe +select -assert-count 1 t:$dffsr +select -assert-count 1 t:$dffsre + +design -load orig +simplemap + +equiv_opt -assert -async2sync dffunmap +design -load postopt +select -assert-none t:$_SDFF* t:$_DFFE_* t:$_DFFSRE_* +select -assert-count 10 t:$_DFF_N_ +select -assert-count 1 t:$_DFF_NP0_ +select -assert-count 1 t:$_DFF_NN0_ +select -assert-count 1 t:$_DFF_NP1_ +select -assert-count 1 t:$_DFF_NN1_ +select -assert-count 2 t:$_DFFSR_NPN_ +select -assert-count 2 t:$_DFFSR_NNP_ + +design -load orig +simplemap + +equiv_opt -assert -async2sync dffunmap -ce-only +design -load postopt +select -assert-none t:$_SDFFE_* t:$_SDFFCE_* t:$_DFFE_* t:$_DFFSRE_* +select -assert-count 6 t:$_DFF_N_ +select -assert-count 1 t:$_SDFF_NP0_ +select -assert-count 1 t:$_SDFF_NN0_ +select -assert-count 1 t:$_SDFF_NP1_ +select -assert-count 1 t:$_SDFF_NN1_ +select -assert-count 1 t:$_DFF_NP0_ +select -assert-count 1 t:$_DFF_NN0_ +select -assert-count 1 t:$_DFF_NP1_ +select -assert-count 1 t:$_DFF_NN1_ +select -assert-count 2 t:$_DFFSR_NPN_ +select -assert-count 2 t:$_DFFSR_NNP_ + +design -load orig +simplemap + +equiv_opt -assert -async2sync dffunmap -srst-only +design -load postopt +select -assert-none t:$sdff t:$sdffe t:$sdffce +select -assert-count 6 t:$_DFF_N_ +select -assert-count 2 t:$_DFFE_NP_ +select -assert-count 2 t:$_DFFE_NN_ +select -assert-count 1 t:$_DFF_NN0_ +select -assert-count 1 t:$_DFF_NN1_ +select -assert-count 1 t:$_DFFE_NP0P_ +select -assert-count 1 t:$_DFFE_NP1P_ +select -assert-count 2 t:$_DFFSR_NPN_ +select -assert-count 2 t:$_DFFSRE_NNPP_ diff --git a/tests/techmap/mem_simple_4x1_runtest.sh b/tests/techmap/mem_simple_4x1_runtest.sh index e2c6303da..9c41fa56a 100644 --- a/tests/techmap/mem_simple_4x1_runtest.sh +++ b/tests/techmap/mem_simple_4x1_runtest.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -ev +set -e ../../yosys -b 'verilog -noattr' -o mem_simple_4x1_synth.v -p 'proc; opt; memory -nomap; techmap -map mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v diff --git a/tests/techmap/recursive_runtest.sh b/tests/techmap/recursive_runtest.sh index 30c79bf03..0725ccf40 100644 --- a/tests/techmap/recursive_runtest.sh +++ b/tests/techmap/recursive_runtest.sh @@ -1,3 +1,3 @@ -set -ev +set -e ../../yosys -p 'hierarchy -top top; techmap -map recursive_map.v -max_iter 1; select -assert-count 2 t:sub; select -assert-count 2 t:bar' recursive.v diff --git a/tests/techmap/run-test.sh b/tests/techmap/run-test.sh index c16f204d9..581847ab0 100755 --- a/tests/techmap/run-test.sh +++ b/tests/techmap/run-test.sh @@ -1,20 +1,4 @@ #!/usr/bin/env bash -set -e -{ -echo "all::" -for x in *.ys; do - echo "all:: run-$x" - echo "run-$x:" - echo " @echo 'Running $x..'" - echo " @../../yosys -ql ${x%.ys}.log -e 'select out of bounds' $x" -done -for s in *.sh; do - if [ "$s" != "run-test.sh" ]; then - echo "all:: run-$s" - echo "run-$s:" - echo " @echo 'Running $s..'" - echo " @bash $s > ${s%.sh}.log 2>&1" - fi -done -} > run-test.mk -exec ${MAKE:-make} -f run-test.mk +set -eu +source ../gen-tests-makefile.sh +run_tests --yosys-scripts --bash --yosys-args "-e 'select out of bounds'" diff --git a/tests/techmap/shiftx2mux.ys b/tests/techmap/shiftx2mux.ys index eb29680f6..f749e79b2 100644 --- a/tests/techmap/shiftx2mux.ys +++ b/tests/techmap/shiftx2mux.ys @@ -74,12 +74,6 @@ design -save gold design -load gold -techmap -D NO_LSB_FIRST_SHIFT_SHIFTX -abc -lut 6 -select -assert-min 17 t:$lut - - -design -load gold techmap abc -lut 6 select -assert-count 16 t:$lut @@ -92,12 +86,6 @@ sat -verify -prove-asserts -show-ports miter design -load gold -techmap -D NO_LSB_FIRST_SHIFT_SHIFTX -abc9 -lut 6 -select -assert-min 17 t:$lut - - -design -load gold techmap abc9 -lut 6 select -assert-count 16 t:$lut diff --git a/tests/techmap/zinit.ys b/tests/techmap/zinit.ys index d0e41b4d2..1670573dd 100644 --- a/tests/techmap/zinit.ys +++ b/tests/techmap/zinit.ys @@ -61,32 +61,32 @@ design -reset read_verilog -icells <<EOT module top(input C, R, D, E, (* init = {24{1'b1}} *) output [23:0] Q); -$__DFFE_NN0 dff0 (.C(C), .D(D), .E(E), .R(R), .Q(Q[0])); -$__DFFE_NN1 dff1 (.C(C), .D(D), .E(E), .R(R), .Q(Q[1])); -$__DFFE_NP0 dff2 (.C(C), .D(D), .E(E), .R(R), .Q(Q[2])); -$__DFFE_NP1 dff3 (.C(C), .D(D), .E(E), .R(R), .Q(Q[3])); -$__DFFE_PN0 dff4 (.C(C), .D(D), .E(E), .R(R), .Q(Q[4])); -$__DFFE_PN1 dff5 (.C(C), .D(D), .E(E), .R(R), .Q(Q[5])); -$__DFFE_PP0 dff6 (.C(C), .D(D), .E(E), .R(R), .Q(Q[6])); -$__DFFE_PP1 dff7 (.C(C), .D(D), .E(E), .R(R), .Q(Q[7])); - -$__DFFS_NN0_ dff8 (.C(C), .D(D[0]), .R(R), .Q(Q[8])); -$__DFFS_NN1_ dff9 (.C(C), .D(D[0]), .R(R), .Q(Q[9])); -$__DFFS_NP0_ dff10(.C(C), .D(D[0]), .R(R), .Q(Q[10])); -$__DFFS_NP1_ dff11(.C(C), .D(D[0]), .R(R), .Q(Q[11])); -$__DFFS_PN0_ dff12(.C(C), .D(D[0]), .R(R), .Q(Q[12])); -$__DFFS_PN1_ dff13(.C(C), .D(D[0]), .R(R), .Q(Q[13])); -$__DFFS_PP0_ dff14(.C(C), .D(D[0]), .R(R), .Q(Q[14])); -$__DFFS_PP1_ dff15(.C(C), .D(D[0]), .R(R), .Q(Q[15])); - -$__DFFSE_NN0 dff16(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[16])); -$__DFFSE_NN1 dff17(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[17])); -$__DFFSE_NP0 dff18(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[18])); -$__DFFSE_NP1 dff19(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[19])); -$__DFFSE_PN0 dff20(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[20])); -$__DFFSE_PN1 dff21(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[21])); -$__DFFSE_PP0 dff22(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[22])); -$__DFFSE_PP1 dff23(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[23])); +$_DFFE_NN0P_ dff0 (.C(C), .D(D), .E(E), .R(R), .Q(Q[0])); +$_DFFE_NN1P_ dff1 (.C(C), .D(D), .E(E), .R(R), .Q(Q[1])); +$_DFFE_NP0P_ dff2 (.C(C), .D(D), .E(E), .R(R), .Q(Q[2])); +$_DFFE_NP1P_ dff3 (.C(C), .D(D), .E(E), .R(R), .Q(Q[3])); +$_DFFE_PN0P_ dff4 (.C(C), .D(D), .E(E), .R(R), .Q(Q[4])); +$_DFFE_PN1P_ dff5 (.C(C), .D(D), .E(E), .R(R), .Q(Q[5])); +$_DFFE_PP0P_ dff6 (.C(C), .D(D), .E(E), .R(R), .Q(Q[6])); +$_DFFE_PP1P_ dff7 (.C(C), .D(D), .E(E), .R(R), .Q(Q[7])); + +$_SDFF_NN0_ dff8 (.C(C), .D(D[0]), .R(R), .Q(Q[8])); +$_SDFF_NN1_ dff9 (.C(C), .D(D[0]), .R(R), .Q(Q[9])); +$_SDFF_NP0_ dff10(.C(C), .D(D[0]), .R(R), .Q(Q[10])); +$_SDFF_NP1_ dff11(.C(C), .D(D[0]), .R(R), .Q(Q[11])); +$_SDFF_PN0_ dff12(.C(C), .D(D[0]), .R(R), .Q(Q[12])); +$_SDFF_PN1_ dff13(.C(C), .D(D[0]), .R(R), .Q(Q[13])); +$_SDFF_PP0_ dff14(.C(C), .D(D[0]), .R(R), .Q(Q[14])); +$_SDFF_PP1_ dff15(.C(C), .D(D[0]), .R(R), .Q(Q[15])); + +$_SDFFE_NN0P_ dff16(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[16])); +$_SDFFE_NN1P_ dff17(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[17])); +$_SDFFE_NP0P_ dff18(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[18])); +$_SDFFE_NP1P_ dff19(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[19])); +$_SDFFE_PN0P_ dff20(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[20])); +$_SDFFE_PN1P_ dff21(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[21])); +$_SDFFE_PP0P_ dff22(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[22])); +$_SDFFE_PP1P_ dff23(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[23])); endmodule EOT @@ -95,45 +95,45 @@ EOT zinit select -assert-count 48 t:$_NOT_ -select -assert-count 1 w:Q a:init=24'bx %i -select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$__DFFE_??1 %i -select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$__DFFE_??0 %i -select -assert-count 4 c:dff8 c:dff10 c:dff12 c:dff14 %% t:$__DFFS_??1_ %i -select -assert-count 4 c:dff9 c:dff11 c:dff13 c:dff15 %% t:$__DFFS_??0_ %i -select -assert-count 4 c:dff16 c:dff18 c:dff20 c:dff22 %% t:$__DFFSE_??1 %i -select -assert-count 4 c:dff17 c:dff19 c:dff21 c:dff23 %% t:$__DFFSE_??0 %i +select -assert-count 0 w:Q a:init %i +select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$_DFFE_??1P_ %i +select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$_DFFE_??0P_ %i +select -assert-count 4 c:dff8 c:dff10 c:dff12 c:dff14 %% t:$_SDFF_??1_ %i +select -assert-count 4 c:dff9 c:dff11 c:dff13 c:dff15 %% t:$_SDFF_??0_ %i +select -assert-count 4 c:dff16 c:dff18 c:dff20 c:dff22 %% t:$_SDFFE_??1P_ %i +select -assert-count 4 c:dff17 c:dff19 c:dff21 c:dff23 %% t:$_SDFFE_??0P_ %i design -reset read_verilog -icells <<EOT module top(input C, R, D, E, (* init = {24{1'b0}} *) output [23:0] Q); -$__DFFE_NN0 dff0 (.C(C), .D(D), .E(E), .R(R), .Q(Q[0])); -$__DFFE_NN1 dff1 (.C(C), .D(D), .E(E), .R(R), .Q(Q[1])); -$__DFFE_NP0 dff2 (.C(C), .D(D), .E(E), .R(R), .Q(Q[2])); -$__DFFE_NP1 dff3 (.C(C), .D(D), .E(E), .R(R), .Q(Q[3])); -$__DFFE_PN0 dff4 (.C(C), .D(D), .E(E), .R(R), .Q(Q[4])); -$__DFFE_PN1 dff5 (.C(C), .D(D), .E(E), .R(R), .Q(Q[5])); -$__DFFE_PP0 dff6 (.C(C), .D(D), .E(E), .R(R), .Q(Q[6])); -$__DFFE_PP1 dff7 (.C(C), .D(D), .E(E), .R(R), .Q(Q[7])); - -$__DFFS_NN0_ dff8 (.C(C), .D(D[0]), .R(R), .Q(Q[8])); -$__DFFS_NN1_ dff9 (.C(C), .D(D[0]), .R(R), .Q(Q[9])); -$__DFFS_NP0_ dff10(.C(C), .D(D[0]), .R(R), .Q(Q[10])); -$__DFFS_NP1_ dff11(.C(C), .D(D[0]), .R(R), .Q(Q[11])); -$__DFFS_PN0_ dff12(.C(C), .D(D[0]), .R(R), .Q(Q[12])); -$__DFFS_PN1_ dff13(.C(C), .D(D[0]), .R(R), .Q(Q[13])); -$__DFFS_PP0_ dff14(.C(C), .D(D[0]), .R(R), .Q(Q[14])); -$__DFFS_PP1_ dff15(.C(C), .D(D[0]), .R(R), .Q(Q[15])); - -$__DFFSE_NN0 dff16(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[16])); -$__DFFSE_NN1 dff17(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[17])); -$__DFFSE_NP0 dff18(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[18])); -$__DFFSE_NP1 dff19(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[19])); -$__DFFSE_PN0 dff20(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[20])); -$__DFFSE_PN1 dff21(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[21])); -$__DFFSE_PP0 dff22(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[22])); -$__DFFSE_PP1 dff23(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[23])); +$_DFFE_NN0P_ dff0 (.C(C), .D(D), .E(E), .R(R), .Q(Q[0])); +$_DFFE_NN1P_ dff1 (.C(C), .D(D), .E(E), .R(R), .Q(Q[1])); +$_DFFE_NP0P_ dff2 (.C(C), .D(D), .E(E), .R(R), .Q(Q[2])); +$_DFFE_NP1P_ dff3 (.C(C), .D(D), .E(E), .R(R), .Q(Q[3])); +$_DFFE_PN0P_ dff4 (.C(C), .D(D), .E(E), .R(R), .Q(Q[4])); +$_DFFE_PN1P_ dff5 (.C(C), .D(D), .E(E), .R(R), .Q(Q[5])); +$_DFFE_PP0P_ dff6 (.C(C), .D(D), .E(E), .R(R), .Q(Q[6])); +$_DFFE_PP1P_ dff7 (.C(C), .D(D), .E(E), .R(R), .Q(Q[7])); + +$_SDFF_NN0_ dff8 (.C(C), .D(D[0]), .R(R), .Q(Q[8])); +$_SDFF_NN1_ dff9 (.C(C), .D(D[0]), .R(R), .Q(Q[9])); +$_SDFF_NP0_ dff10(.C(C), .D(D[0]), .R(R), .Q(Q[10])); +$_SDFF_NP1_ dff11(.C(C), .D(D[0]), .R(R), .Q(Q[11])); +$_SDFF_PN0_ dff12(.C(C), .D(D[0]), .R(R), .Q(Q[12])); +$_SDFF_PN1_ dff13(.C(C), .D(D[0]), .R(R), .Q(Q[13])); +$_SDFF_PP0_ dff14(.C(C), .D(D[0]), .R(R), .Q(Q[14])); +$_SDFF_PP1_ dff15(.C(C), .D(D[0]), .R(R), .Q(Q[15])); + +$_SDFFE_NN0P_ dff16(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[16])); +$_SDFFE_NN1P_ dff17(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[17])); +$_SDFFE_NP0P_ dff18(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[18])); +$_SDFFE_NP1P_ dff19(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[19])); +$_SDFFE_PN0P_ dff20(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[20])); +$_SDFFE_PN1P_ dff21(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[21])); +$_SDFFE_PP0P_ dff22(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[22])); +$_SDFFE_PP1P_ dff23(.C(C), .D(D[0]),.E(E), .R(R), .Q(Q[23])); endmodule EOT @@ -142,10 +142,10 @@ EOT zinit select -assert-count 0 t:$_NOT_ -select -assert-count 1 w:Q a:init=24'bx %i -select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$__DFFE_??0 %i -select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$__DFFE_??1 %i -select -assert-count 4 c:dff8 c:dff10 c:dff12 c:dff14 %% t:$__DFFS_??0_ %i -select -assert-count 4 c:dff9 c:dff11 c:dff13 c:dff15 %% t:$__DFFS_??1_ %i -select -assert-count 4 c:dff16 c:dff18 c:dff20 c:dff22 %% t:$__DFFSE_??0 %i -select -assert-count 4 c:dff17 c:dff19 c:dff21 c:dff23 %% t:$__DFFSE_??1 %i +select -assert-count 0 w:Q a:init %i +select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$_DFFE_??0P_ %i +select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$_DFFE_??1P_ %i +select -assert-count 4 c:dff8 c:dff10 c:dff12 c:dff14 %% t:$_SDFF_??0_ %i +select -assert-count 4 c:dff9 c:dff11 c:dff13 c:dff15 %% t:$_SDFF_??1_ %i +select -assert-count 4 c:dff16 c:dff18 c:dff20 c:dff22 %% t:$_SDFFE_??0P_ %i +select -assert-count 4 c:dff17 c:dff19 c:dff21 c:dff23 %% t:$_SDFFE_??1P_ %i diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 4d3478628..72a3d51eb 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -193,13 +193,13 @@ do elif [ "$frontend" = "verific_gates" ]; then test_passes -p "verific -vlog2k ${bn}_ref.${refext}; verific -import -gates -all; opt; memory;;" else - test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.${refext} + test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt -nodffe -nosdff; fsm; opt; memory; opt -full -fine" ${bn}_ref.${refext} test_passes -f "$frontend $include_opts" -p "hierarchy; synth -run coarse; techmap; opt; abc -dff" ${bn}_ref.${refext} if [ -n "$firrtl2verilog" ]; then if test -z "$xfirrtl" || ! grep "$fn" "$xfirrtl" ; then - "$toolsdir"/../../yosys -b "firrtl" -o ${bn}_ref.fir -f "$frontend $include_opts" -p "prep -nordff; proc; opt; memory; opt; fsm; opt -full -fine; pmuxtree" ${bn}_ref.${refext} + "$toolsdir"/../../yosys -b "firrtl" -o ${bn}_ref.fir -f "$frontend $include_opts" -p "prep -nordff; proc; opt -nodffe -nosdff; fsm; opt; memory; opt -full -fine; pmuxtree" ${bn}_ref.${refext} $firrtl2verilog -i ${bn}_ref.fir -o ${bn}_ref.fir.v - test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.fir.v + test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt -nodffe -nosdff; fsm; opt; memory; opt -full -fine" ${bn}_ref.fir.v fi fi fi diff --git a/tests/various/const_arg_loop.v b/tests/various/const_arg_loop.v new file mode 100644 index 000000000..3bfff4acd --- /dev/null +++ b/tests/various/const_arg_loop.v @@ -0,0 +1,64 @@ +module top; + function automatic [31:0] operation1; + input [4:0] rounds; + input integer num; + integer i; + begin + begin : shadow + integer rounds; + rounds = 0; + end + for (i = 0; i < rounds; i = i + 1) + num = num * 2; + operation1 = num; + end + endfunction + + function automatic [31:0] operation2; + input [4:0] var; + input integer num; + begin + var[0] = var[0] ^ 1; + operation2 = num * var; + end + endfunction + + function automatic [31:0] operation3; + input [4:0] rounds; + input integer num; + reg [4:0] rounds; + integer i; + begin + begin : shadow + integer rounds; + rounds = 0; + end + for (i = 0; i < rounds; i = i + 1) + num = num * 2; + operation3 = num; + end + endfunction + + wire [31:0] a; + assign a = 2; + + parameter A = 3; + + wire [31:0] x1; + assign x1 = operation1(A, a); + + wire [31:0] x2; + assign x2 = operation2(A, a); + + wire [31:0] x3; + assign x3 = operation3(A, a); + +// `define VERIFY +`ifdef VERIFY + assert property (a == 2); + assert property (A == 3); + assert property (x1 == 16); + assert property (x2 == 4); + assert property (x3 == 16); +`endif +endmodule diff --git a/tests/various/const_arg_loop.ys b/tests/various/const_arg_loop.ys new file mode 100644 index 000000000..b039bda10 --- /dev/null +++ b/tests/various/const_arg_loop.ys @@ -0,0 +1 @@ +read_verilog const_arg_loop.v diff --git a/tests/various/const_func.v b/tests/various/const_func.v new file mode 100644 index 000000000..541e63b19 --- /dev/null +++ b/tests/various/const_func.v @@ -0,0 +1,87 @@ +module Example(outA, outB, outC, outD); + parameter OUTPUT = "FOO"; + output wire [23:0] outA; + output wire [23:0] outB; + output reg outC, outD; + function automatic [23:0] flip; + input [23:0] inp; + flip = ~inp; + endfunction + + generate + if (flip(OUTPUT) == flip("BAR")) + assign outA = OUTPUT; + else + assign outA = 0; + + case (flip(OUTPUT)) + flip("FOO"): assign outB = OUTPUT; + flip("BAR"): assign outB = 0; + flip("BAZ"): assign outB = "HI"; + endcase + + genvar i; + initial outC = 0; + for (i = 0; i != flip(flip(OUTPUT[15:8])); i = i + 1) + if (i + 1 == flip(flip("O"))) + initial outC = 1; + endgenerate + + integer j; + initial begin + outD = 1; + for (j = 0; j != flip(flip(OUTPUT[15:8])); j = j + 1) + if (j + 1 == flip(flip("O"))) + outD = 0; + end +endmodule + +module top(out); + wire [23:0] a1, a2, a3, a4; + wire [23:0] b1, b2, b3, b4; + wire c1, c2, c3, c4; + wire d1, d2, d3, d4; + Example e1(a1, b1, c1, d1); + Example #("FOO") e2(a2, b2, c2, d2); + Example #("BAR") e3(a3, b3, c3, d3); + Example #("BAZ") e4(a4, b4, c4, d4); + + output wire [24 * 8 - 1 + 4 :0] out; + assign out = { + a1, a2, a3, a4, + b1, b2, b3, b4, + c1, c2, c3, c4, + d1, d2, d3, d4}; + + function signed [31:0] negate; + input integer inp; + negate = ~inp; + endfunction + parameter W = 10; + parameter X = 3; + localparam signed Y = $floor(W / X); + localparam signed Z = negate($floor(W / X)); + +// `define VERIFY +`ifdef VERIFY + assert property (a1 == 0); + assert property (a2 == 0); + assert property (a3 == "BAR"); + assert property (a4 == 0); + assert property (b1 == "FOO"); + assert property (b2 == "FOO"); + assert property (b3 == 0); + assert property (b4 == "HI"); + assert property (c1 == 1); + assert property (c2 == 1); + assert property (c3 == 0); + assert property (c4 == 0); + assert property (d1 == 0); + assert property (d2 == 0); + assert property (d3 == 1); + assert property (d4 == 1); + + assert property (Y == 3); + assert property (Z == ~3); +`endif +endmodule diff --git a/tests/various/const_func.ys b/tests/various/const_func.ys new file mode 100644 index 000000000..5e3c04105 --- /dev/null +++ b/tests/various/const_func.ys @@ -0,0 +1 @@ +read_verilog const_func.v diff --git a/tests/various/const_func_block_var.v b/tests/various/const_func_block_var.v new file mode 100644 index 000000000..cb60844ab --- /dev/null +++ b/tests/various/const_func_block_var.v @@ -0,0 +1,26 @@ +module top(out); + function integer operation; + input integer num; + localparam incr = 1; + localparam mult = 1; + begin + operation = 0; + begin : op_i + integer i; + for (i = 0; i * mult < 2; i = i + incr) + begin : op_j + integer j; + localparam other_mult = 2; + for (j = i; j < i * other_mult; j = j + incr) + num = num + incr; + end + num = num * 2; + end + operation = num; + end + endfunction + + localparam res = operation(4); + output wire [31:0] out; + assign out = res; +endmodule diff --git a/tests/various/const_func_block_var.ys b/tests/various/const_func_block_var.ys new file mode 100644 index 000000000..7c2e85c64 --- /dev/null +++ b/tests/various/const_func_block_var.ys @@ -0,0 +1 @@ +read_verilog const_func_block_var.v diff --git a/tests/various/equiv_opt_undef.ys b/tests/various/equiv_opt_undef.ys new file mode 100644 index 000000000..5d2c60d0a --- /dev/null +++ b/tests/various/equiv_opt_undef.ys @@ -0,0 +1,35 @@ +read_ilang << EOT + +module \top + wire $a + wire $b + wire input 1 \D + wire input 2 \EN + wire output 3 \Q + cell $mux $x + parameter \WIDTH 1 + connect \A \Q + connect \B \D + connect \S \EN + connect \Y $a + end + cell $ff $y + parameter \WIDTH 1 + connect \D $a + connect \Q $b + end + cell $and $z + parameter \A_SIGNED 0 + parameter \A_WIDTH 1 + parameter \B_SIGNED 0 + parameter \B_WIDTH 1 + parameter \Y_WIDTH 1 + connect \A $b + connect \B 1'x + connect \Y \Q + end +end + +EOT + +equiv_opt -assert -undef ls diff --git a/tests/various/integer_range_bad_syntax.ys b/tests/various/integer_range_bad_syntax.ys new file mode 100644 index 000000000..4f427211f --- /dev/null +++ b/tests/various/integer_range_bad_syntax.ys @@ -0,0 +1,6 @@ +logger -expect error "syntax error, unexpected" 1 +read_verilog -sv <<EOT +module test_integer_range(); +parameter integer [31:0] a = 0; +endmodule +EOT diff --git a/tests/various/integer_real_bad_syntax.ys b/tests/various/integer_real_bad_syntax.ys new file mode 100644 index 000000000..942d8de77 --- /dev/null +++ b/tests/various/integer_real_bad_syntax.ys @@ -0,0 +1,6 @@ +logger -expect error "syntax error, unexpected TOK_REAL" 1 +read_verilog -sv <<EOT +module test_integer_real(); +parameter integer real a = 0; +endmodule +EOT diff --git a/tests/various/logic_param_simple.ys b/tests/various/logic_param_simple.ys new file mode 100644 index 000000000..968564080 --- /dev/null +++ b/tests/various/logic_param_simple.ys @@ -0,0 +1,9 @@ +read_verilog -sv <<EOT +module test_logic_param(); +parameter logic a = 0; +parameter logic [31:0] e = 0; +parameter logic signed b = 0; +parameter logic unsigned c = 0; +parameter logic unsigned [31:0] d = 0; +endmodule +EOT diff --git a/tests/various/peepopt.ys b/tests/various/peepopt.ys index ee5ad8a1a..45e936a21 100644 --- a/tests/various/peepopt.ys +++ b/tests/various/peepopt.ys @@ -68,146 +68,3 @@ equiv_opt -assert peepopt design -load postopt clean select -assert-count 0 t:* - -#################### - -design -reset -read_verilog <<EOT -module peepopt_dffmuxext_unsigned(input clk, ce, input [1:0] i, output reg [3:0] o); - always @(posedge clk) if (ce) o <= i; -endmodule -EOT - -proc -equiv_opt -assert peepopt -design -load postopt -clean -select -assert-count 1 t:$dff r:WIDTH=2 %i -select -assert-count 1 t:$mux r:WIDTH=2 %i -select -assert-count 0 t:$dff t:$mux %% t:* %D - -#################### - -design -reset -read_verilog <<EOT -module peepopt_dffmuxext_signed(input clk, ce, input signed [1:0] i, output reg signed [3:0] o); - always @(posedge clk) if (ce) o <= i; -endmodule -EOT - -proc -equiv_opt -assert peepopt -design -load postopt -clean -select -assert-count 1 t:$dff r:WIDTH=2 %i -select -assert-count 1 t:$mux r:WIDTH=2 %i -select -assert-count 0 t:$dff t:$mux %% t:* %D - -################### - -design -reset -read_verilog <<EOT -module peepopt_dffmuxext_const(input clk, ce, input [1:0] i, output reg [5:0] o); - always @(posedge clk) if (ce) o <= {1'b0, i[1], 2'b1x, i[0], 1'bz}; -endmodule -EOT - -proc -equiv_opt -assert peepopt -design -load postopt -select -assert-count 1 t:$dff r:WIDTH=2 %i -select -assert-count 1 t:$mux r:WIDTH=2 %i -select -assert-count 0 t:$dff t:$mux %% t:* %D - -################### - -design -reset -read_verilog <<EOT -module peepopt_dffmuxext_const_init(input clk, ce, input [1:0] i, (* init=6'b0x00x1 *) output reg [5:0] o); - always @(posedge clk) if (ce) o <= {1'b0, i[1], 2'b1x, i[0], 1'bz}; -endmodule -EOT - -proc -equiv_opt -assert peepopt -design -load postopt -select -assert-count 1 t:$dff r:WIDTH=4 %i -select -assert-count 1 t:$mux r:WIDTH=4 %i -select -assert-count 0 t:$dff t:$mux %% t:* %D - -#################### - -design -reset -read_verilog <<EOT -module peepopt_dffmuxext_unsigned_rst(input clk, ce, rst, input [1:0] i, output reg [3:0] o); - always @(posedge clk) if (rst) o <= 0; else if (ce) o <= i; -endmodule -EOT - -proc -equiv_opt -assert peepopt -design -load postopt -wreduce -select -assert-count 1 t:$dff r:WIDTH=2 %i -select -assert-count 2 t:$mux -select -assert-count 2 t:$mux r:WIDTH=2 %i -select -assert-count 0 t:$dff t:$mux %% t:* %D - -#################### - -design -reset -read_verilog <<EOT -module peepopt_dffmuxext_signed_rst(input clk, ce, rstn, input signed [1:0] i, output reg signed [3:0] o); - always @(posedge clk) begin - if (ce) o <= i; - if (!rstn) o <= 4'b1111; - end -endmodule -EOT - -proc -equiv_opt -assert peepopt -design -load postopt -wreduce -select -assert-count 1 t:$dff r:WIDTH=2 %i -select -assert-count 2 t:$mux -select -assert-count 2 t:$mux r:WIDTH=2 %i -select -assert-count 0 t:$logic_not t:$dff t:$mux %% t:* %D - -#################### - -design -reset -read_verilog <<EOT -module peepopt_dffmuxext_signed_rst_init(input clk, ce, rstn, input signed [1:0] i, output reg signed [3:0] o); - initial o <= 4'b0010; - always @(posedge clk) begin - if (ce) o <= i; - if (!rstn) o <= 4'b1111; - end -endmodule -EOT - -proc -# NB: equiv_opt uses equiv_induct which covers -# only the induction half of temporal induction -# --- missing the base-case half -# This makes it akin to `sat -tempinduct-inductonly` -# instead of `sat -tempinduct-baseonly` or -# `sat -tempinduct` which is necessary for this -# testcase -#equiv_opt -assert peepopt - -design -save gold -peepopt -wreduce -design -stash gate -design -import gold -as gold -design -import gate -as gate -miter -equiv -flatten -make_assert -make_outputs gold gate miter -sat -tempinduct -verify -prove-asserts -show-ports miter - -design -load gate -select -assert-count 1 t:$dff r:WIDTH=4 %i -select -assert-count 2 t:$mux -select -assert-count 2 t:$mux r:WIDTH=4 %i -select -assert-count 0 t:$logic_not t:$dff t:$mux %% t:* %D diff --git a/tests/various/plugin.cc b/tests/various/plugin.cc index be305fbda..451484c50 100644 --- a/tests/various/plugin.cc +++ b/tests/various/plugin.cc @@ -4,7 +4,7 @@ YOSYS_NAMESPACE_BEGIN struct TestPass : public Pass { TestPass() : Pass("test", "test") { } - void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector<std::string> args, RTLIL::Design *design) override { size_t argidx = 1; extra_args(args, argidx, design); diff --git a/tests/various/run-test.sh b/tests/various/run-test.sh index ea56b70f0..2f91cf0fd 100755 --- a/tests/various/run-test.sh +++ b/tests/various/run-test.sh @@ -1,20 +1,4 @@ #!/usr/bin/env bash -set -e -{ -echo "all::" -for x in *.ys; do - echo "all:: run-$x" - echo "run-$x:" - echo " @echo 'Running $x..'" - echo " @../../yosys -ql ${x%.ys}.log $x" -done -for s in *.sh; do - if [ "$s" != "run-test.sh" ]; then - echo "all:: run-$s" - echo "run-$s:" - echo " @echo 'Running $s..'" - echo " @bash $s" - fi -done -} > run-test.mk -exec ${MAKE:-make} -f run-test.mk +set -eu +source ../gen-tests-makefile.sh +run_tests --yosys-scripts --bash diff --git a/tests/various/signed.ys b/tests/various/signed.ys new file mode 100644 index 000000000..2319a5da1 --- /dev/null +++ b/tests/various/signed.ys @@ -0,0 +1,28 @@ +# SV LRM A2.2.1 + +read_verilog -sv <<EOT +module test_signed(); +parameter integer signed a = 0; +parameter integer unsigned b = 0; + +endmodule +EOT + +design -reset +read_verilog -sv <<EOT +module test_signed(); +parameter logic signed [7:0] a = 0; +parameter logic unsigned [7:0] b = 0; + +endmodule +EOT + +design -reset +logger -expect error "syntax error, unexpected TOK_INTEGER" 1 +read_verilog -sv <<EOT +module test_signed(); +parameter signed integer a = 0; +parameter unsigned integer b = 0; + +endmodule +EOT diff --git a/tests/verilog/.gitignore b/tests/verilog/.gitignore index b48f808a1..34da23437 100644 --- a/tests/verilog/.gitignore +++ b/tests/verilog/.gitignore @@ -1,3 +1,5 @@ /*.log /*.out /run-test.mk +/const_arst.v +/const_sr.v diff --git a/tests/verilog/const_arst.ys b/tests/verilog/const_arst.ys new file mode 100644 index 000000000..df720575c --- /dev/null +++ b/tests/verilog/const_arst.ys @@ -0,0 +1,24 @@ +read_verilog <<EOT +module test ( + input clk, d, + output reg q +); +wire nop = 1'h0; +always @(posedge clk, posedge nop) begin + if (nop) q <= 1'b0; + else q <= d; +end +endmodule +EOT +prep -top test +write_verilog const_arst.v +design -stash gold +read_verilog const_arst.v +prep -top test +design -stash gate +design -copy-from gold -as gold A:top +design -copy-from gate -as gate A:top +miter -equiv -flatten -make_assert gold gate miter +prep -top miter +clk2fflogic +sat -set-init-zero -tempinduct -prove-asserts -verify diff --git a/tests/verilog/const_sr.ys b/tests/verilog/const_sr.ys new file mode 100644 index 000000000..c1406b0a0 --- /dev/null +++ b/tests/verilog/const_sr.ys @@ -0,0 +1,25 @@ +read_verilog <<EOT +module test ( + input clk, rst, d, + output reg q +); +wire nop = 1'h0; +always @(posedge clk, posedge nop, posedge rst) begin + if (rst) q <= 1'b0; + else if (nop) q <= 1'b1; + else q <= d; +end +endmodule +EOT +prep -top test +write_verilog const_sr.v +design -stash gold +read_verilog const_sr.v +prep -top test +design -stash gate +design -copy-from gold -as gold A:top +design -copy-from gate -as gate A:top +miter -equiv -flatten -make_assert gold gate miter +prep -top miter +clk2fflogic +sat -set-init-zero -tempinduct -prove-asserts -verify diff --git a/tests/verilog/run-test.sh b/tests/verilog/run-test.sh index ea56b70f0..2f91cf0fd 100755 --- a/tests/verilog/run-test.sh +++ b/tests/verilog/run-test.sh @@ -1,20 +1,4 @@ #!/usr/bin/env bash -set -e -{ -echo "all::" -for x in *.ys; do - echo "all:: run-$x" - echo "run-$x:" - echo " @echo 'Running $x..'" - echo " @../../yosys -ql ${x%.ys}.log $x" -done -for s in *.sh; do - if [ "$s" != "run-test.sh" ]; then - echo "all:: run-$s" - echo "run-$s:" - echo " @echo 'Running $s..'" - echo " @bash $s" - fi -done -} > run-test.mk -exec ${MAKE:-make} -f run-test.mk +set -eu +source ../gen-tests-makefile.sh +run_tests --yosys-scripts --bash |