diff --git a/.travis.yml b/.travis.yml index 957735f1d..09f380831 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,37 +36,10 @@ matrix: - libboost-system-dev - libboost-python-dev - libboost-filesystem-dev + - zlib1g-dev env: - MATRIX_EVAL="CONFIG=gcc && CC=gcc-4.8 && CXX=g++-4.8" - # Latest gcc-6 on Travis Linux - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-6 - - gperf - - build-essential - - bison - - flex - - libreadline-dev - - gawk - - tcl-dev - - libffi-dev - - git - - graphviz - - xdot - - pkg-config - - python - - python3 - - libboost-system-dev - - libboost-python-dev - - libboost-filesystem-dev - env: - - MATRIX_EVAL="CONFIG=gcc && CC=gcc-6 && CXX=g++-6" - # Latest gcc supported on Travis Linux - os: linux addons: @@ -74,7 +47,7 @@ matrix: sources: - ubuntu-toolchain-r-test packages: - - g++-7 + - g++-9 - gperf - build-essential - bison @@ -92,8 +65,9 @@ matrix: - libboost-system-dev - libboost-python-dev - libboost-filesystem-dev + - zlib1g-dev env: - - MATRIX_EVAL="CONFIG=gcc && CC=gcc-7 && CXX=g++-7" + - MATRIX_EVAL="CONFIG=gcc && CC=gcc-9 && CXX=g++-9" # Clang which ships on Trusty Linux - os: linux @@ -121,6 +95,7 @@ matrix: - libboost-system-dev - libboost-python-dev - libboost-filesystem-dev + - zlib1g-dev env: - MATRIX_EVAL="CONFIG=clang && CC=clang-3.8 && CXX=clang++-3.8" @@ -129,9 +104,9 @@ matrix: addons: apt: sources: - - llvm-toolchain-trusty-5.0 + - llvm-toolchain-xenial-8 packages: - - clang-5.0 + - clang-8 - gperf - build-essential - bison @@ -149,8 +124,9 @@ matrix: - libboost-system-dev - libboost-python-dev - libboost-filesystem-dev + - zlib1g-dev env: - - MATRIX_EVAL="CONFIG=clang && CC=clang-5.0 && CXX=clang++-5.0" + - MATRIX_EVAL="CONFIG=clang && CC=clang-8 && CXX=clang++-8" # # Latest clang on Mac OS X # - os: osx diff --git a/.travis/build-and-test.sh b/.travis/build-and-test.sh index b8c35041d..801407d1e 100755 --- a/.travis/build-and-test.sh +++ b/.travis/build-and-test.sh @@ -28,7 +28,7 @@ echo echo 'Building...' && echo -en 'travis_fold:start:script.build\\r' echo -make +make CC=$CC CXX=$CC LD=$CC echo echo -en 'travis_fold:end:script.build\\r' diff --git a/.travis/setup.sh b/.travis/setup.sh index 4af0b8ee9..02879b974 100755 --- a/.travis/setup.sh +++ b/.travis/setup.sh @@ -51,7 +51,7 @@ fi git clone git://github.com/steveicarus/iverilog.git cd iverilog autoconf - ./configure --prefix=$HOME/.local-bin + CC=gcc CXX=g++ ./configure --prefix=$HOME/.local-bin make make install echo diff --git a/CHANGELOG b/CHANGELOG index b82a62495..3bcb71b22 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,7 +18,14 @@ Yosys 0.9 .. Yosys 0.9-dev - Renamed labels/options in synth_ecp5 (e.g. dram -> map_lutram; -nodram -> -nolutram) - Renamed labels in synth_intel (e.g. bram -> map_bram) - Renamed labels/options in synth_xilinx (e.g. dram -> map_lutram; -nodram -> -nolutram) - + - Added automatic gzip decompression for frontends + - Added $_NMUX_ cell type + - Added automatic gzip compression (based on filename extension) for backends + - Improve attribute and parameter encoding in JSON to avoid ambiguities between + bit vectors and strings containing [01xz]* + - Added "opt_share" pass, run as part of "opt -full" + - Added "ice40_wrapcarry" to encapsulate SB_LUT+SB_CARRY pairs for techmapping + - Removed "ice40_unlut" Yosys 0.8 .. Yosys 0.8-dev -------------------------- diff --git a/Dockerfile b/Dockerfile index 3c7188d82..549c73c97 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,33 +1,57 @@ -FROM ubuntu:18.04 as builder -LABEL author="Abdelrahman Hosny " -ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && apt-get install -y build-essential \ +ARG IMAGE="python:3-slim-buster" + +#--- + +FROM $IMAGE AS base + +RUN apt-get update -qq \ + && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ + ca-certificates \ clang \ + curl \ + libffi-dev \ + libreadline-dev \ + tcl-dev \ + graphviz \ + xdot \ + && apt-get autoclean && apt-get clean && apt-get -y autoremove \ + && update-ca-certificates \ + && rm -rf /var/lib/apt/lists + +#--- + +FROM base AS build + +RUN apt-get update -qq \ + && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ bison \ flex \ - libreadline-dev \ gawk \ - tcl-dev \ - libffi-dev \ + gcc \ git \ + iverilog \ pkg-config \ - python3 && \ - rm -rf /var/lib/apt/lists -COPY . / -RUN make && \ - make install + && apt-get autoclean && apt-get clean && apt-get -y autoremove \ + && rm -rf /var/lib/apt/lists -FROM ubuntu:18.04 -ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && apt-get install -y libreadline-dev tcl-dev +COPY . /yosys -COPY --from=builder /yosys /build/yosys -COPY --from=builder /yosys-abc /build/yosys-abc -COPY --from=builder /yosys-config /build/yosys-config -COPY --from=builder /yosys-filterlib /build/yosys-filterlib -COPY --from=builder /yosys-smtbmc /build/yosys-smtbmc +ENV PREFIX /opt/yosys + +RUN cd /yosys \ + && make \ + && make install \ + && make test + +#--- + +FROM base + +COPY --from=build /opt/yosys /opt/yosys + +ENV PATH /opt/yosys/bin:$PATH -ENV PATH /build:$PATH RUN useradd -m yosys USER yosys -ENTRYPOINT ["yosys"] + +CMD ["yosys"] diff --git a/Makefile b/Makefile index 3bc119800..16341a268 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ ENABLE_VERIFIC := 0 ENABLE_COVER := 1 ENABLE_LIBYOSYS := 0 ENABLE_PROTOBUF := 0 +ENABLE_ZLIB := 1 # python wrappers ENABLE_PYOSYS := 0 @@ -260,7 +261,8 @@ CXXFLAGS := $(filter-out -fPIC,$(CXXFLAGS)) LDFLAGS := $(filter-out -rdynamic,$(LDFLAGS)) -s LDLIBS := $(filter-out -lrt,$(LDLIBS)) ABCMKARGS += ARCHFLAGS="-DWIN32_NO_DLL -DHAVE_STRUCT_TIMESPEC -fpermissive -w" -ABCMKARGS += LIBS="lib/x86/pthreadVC2.lib -s" ABC_USE_NO_READLINE=1 CC="/usr/local/src/mxe/usr/bin/i686-w64-mingw32.static-gcc" +# TODO: Try to solve pthread linking issue in more appropriate way +ABCMKARGS += LIBS="lib/x86/pthreadVC2.lib -s" LDFLAGS="-Wl,--allow-multiple-definition" ABC_USE_NO_READLINE=1 CC="/usr/local/src/mxe/usr/bin/i686-w64-mingw32.static-gcc" EXE = .exe else ifeq ($(CONFIG),msys2) @@ -384,6 +386,12 @@ ifeq ($(ENABLE_GLOB),1) CXXFLAGS += -DYOSYS_ENABLE_GLOB endif +ifeq ($(ENABLE_ZLIB),1) +CXXFLAGS += -DYOSYS_ENABLE_ZLIB +LDLIBS += -lz +endif + + ifeq ($(ENABLE_TCL),1) TCL_VERSION ?= tcl$(shell bash -c "tclsh <(echo 'puts [info tclversion]')") ifeq ($(OS), FreeBSD) @@ -394,7 +402,7 @@ endif ifeq ($(CONFIG),mxe) CXXFLAGS += -DYOSYS_ENABLE_TCL -LDLIBS += -ltcl86 -lwsock32 -lws2_32 -lnetapi32 -lz +LDLIBS += -ltcl86 -lwsock32 -lws2_32 -lnetapi32 -lz -luserenv else CXXFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --cflags tcl || echo -I$(TCL_INCLUDE)) -DYOSYS_ENABLE_TCL ifeq ($(OS), FreeBSD) @@ -674,10 +682,12 @@ endif test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/simple && bash run-test.sh $(SEEDOPT) + +cd tests/simple_abc9 && bash run-test.sh $(SEEDOPT) +cd tests/hana && bash run-test.sh $(SEEDOPT) +cd tests/asicworld && bash run-test.sh $(SEEDOPT) # +cd tests/realmath && bash run-test.sh $(SEEDOPT) +cd tests/share && bash run-test.sh $(SEEDOPT) + +cd tests/opt_share && bash run-test.sh $(SEEDOPT) +cd tests/fsm && bash run-test.sh $(SEEDOPT) +cd tests/techmap && bash run-test.sh +cd tests/memories && bash run-test.sh $(ABCOPT) $(SEEDOPT) @@ -688,7 +698,6 @@ test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/opt && bash run-test.sh +cd tests/aiger && bash run-test.sh $(ABCOPT) +cd tests/arch && bash run-test.sh - +cd tests/simple_abc9 && bash run-test.sh $(SEEDOPT) @echo "" @echo " Passed \"make test\"." @echo "" @@ -773,7 +782,7 @@ clean: rm -rf kernel/*.pyh if test -d manual; then cd manual && sh clean.sh; fi rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) $(PY_WRAP_INCLUDES) $(PY_WRAPPER_FILE).cc - rm -f kernel/version_*.o kernel/version_*.cc abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a + rm -f kernel/version_*.o kernel/version_*.cc rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d rm -rf tests/asicworld/*.out tests/asicworld/*.log rm -rf tests/hana/*.out tests/hana/*.log @@ -862,9 +871,11 @@ config-mxe: clean config-msys2: clean echo 'CONFIG := msys2' > Makefile.conf + echo 'ENABLE_PLUGINS := 0' >> Makefile.conf config-msys2-64: clean echo 'CONFIG := msys2-64' > Makefile.conf + echo 'ENABLE_PLUGINS := 0' >> Makefile.conf config-cygwin: clean echo 'CONFIG := cygwin' > Makefile.conf diff --git a/README.md b/README.md index 9e221be38..d9989eb29 100644 --- a/README.md +++ b/README.md @@ -67,13 +67,13 @@ prerequisites for building yosys: $ sudo apt-get install build-essential clang bison flex \ libreadline-dev gawk tcl-dev libffi-dev git \ graphviz xdot pkg-config python3 libboost-system-dev \ - libboost-python-dev libboost-filesystem-dev + libboost-python-dev libboost-filesystem-dev zlib1g-dev Similarily, on Mac OS X MacPorts or Homebrew can be used to install dependencies: $ brew tap Homebrew/bundle && brew bundle $ sudo port install bison flex readline gawk libffi \ - git graphviz pkgconfig python36 boost + git graphviz pkgconfig python36 boost zlib On FreeBSD use the following command to install all prerequisites: @@ -85,7 +85,7 @@ On FreeBSD system use gmake instead of make. To run tests use: For Cygwin use the following command to install all prerequisites, or select these additional packages: - setup-x86_64.exe -q --packages=bison,flex,gcc-core,gcc-g++,git,libffi-devel,libreadline-devel,make,pkg-config,python3,tcl-devel,boost-build + setup-x86_64.exe -q --packages=bison,flex,gcc-core,gcc-g++,git,libffi-devel,libreadline-devel,make,pkg-config,python3,tcl-devel,boost-build,zlib-devel There are also pre-compiled Yosys binary packages for Ubuntu and Win32 as well as a source distribution for Visual Studio. Visit the Yosys download page for @@ -130,18 +130,15 @@ commands and ``help `` to print details on the specified command: yosys> help help -reading the design using the Verilog frontend: +reading and elaborating the design using the Verilog frontend: - yosys> read_verilog tests/simple/fiedler-cooley.v + yosys> read -sv tests/simple/fiedler-cooley.v + yosys> hierarchy -top up3down5 writing the design to the console in Yosys's internal format: yosys> write_ilang -elaborate design hierarchy: - - yosys> hierarchy - convert processes (``always`` blocks) to netlist elements and perform some simple optimizations: @@ -163,51 +160,26 @@ write design netlist to a new Verilog file: yosys> write_verilog synth.v -a similar synthesis can be performed using yosys command line options only: - - $ ./yosys -o synth.v -p hierarchy -p proc -p opt \ - -p techmap -p opt tests/simple/fiedler-cooley.v - or using a simple synthesis script: $ cat synth.ys - read_verilog tests/simple/fiedler-cooley.v - hierarchy; proc; opt; techmap; opt + read -sv tests/simple/fiedler-cooley.v + hierarchy -top up3down5 + proc; opt; techmap; opt write_verilog synth.v $ ./yosys synth.ys -It is also possible to only have the synthesis commands but not the read/write -commands in the synthesis script: - - $ cat synth.ys - hierarchy; proc; opt; techmap; opt - - $ ./yosys -o synth.v tests/simple/fiedler-cooley.v synth.ys - -The following very basic synthesis script should work well with all designs: - - # check design hierarchy - hierarchy - - # translate processes (always blocks) - proc; opt - - # detect and optimize FSM encodings - fsm; opt - - # implement memories (arrays) - memory; opt - - # convert to gate logic - techmap; opt - If ABC is enabled in the Yosys build configuration and a cell library is given in the liberty file ``mycells.lib``, the following synthesis script will synthesize for the given cell library: + # read design + read -sv tests/simple/fiedler-cooley.v + hierarchy -top up3down5 + # the high-level stuff - hierarchy; proc; fsm; opt; memory; opt + proc; fsm; opt; memory; opt # mapping to internal cell library techmap; opt @@ -222,7 +194,8 @@ synthesize for the given cell library: clean If you do not have a liberty file but want to test this synthesis script, -you can use the file ``examples/cmos/cmos_cells.lib`` from the yosys sources. +you can use the file ``examples/cmos/cmos_cells.lib`` from the yosys sources +as simple example. Liberty file downloads for and information about free and open ASIC standard cell libraries can be found here: @@ -231,20 +204,18 @@ cell libraries can be found here: - http://www.vlsitechnology.org/synopsys/vsclib013.lib The command ``synth`` provides a good default synthesis script (see -``help synth``). If possible a synthesis script should borrow from ``synth``. -For example: +``help synth``): - # the high-level stuff - hierarchy - synth -run coarse + read -sv tests/simple/fiedler-cooley.v + synth -top up3down5 - # mapping to internal cells - techmap; opt -fast + # mapping to target cells dfflibmap -liberty mycells.lib abc -liberty mycells.lib clean -Yosys is under construction. A more detailed documentation will follow. +The command ``prep`` provides a good default word-level synthesis script, as +used in SMT-based formal verification. Unsupported Verilog-2005 Features diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 69f63486c..5e12e9a34 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -53,7 +53,7 @@ PRIVATE_NAMESPACE_BEGIN inline int32_t to_big_endian(int32_t i32) { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - return __builtin_bswap32(i32); + return bswap32(i32); #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ return i32; #else @@ -312,7 +312,7 @@ struct XAigerWriter #if 0 toposort.analyze_loops = true; #endif - bool no_loops = toposort.sort(); + bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); #if 0 unsigned i = 0; for (auto &it : toposort.loops) { @@ -388,11 +388,11 @@ struct XAigerWriter RTLIL::SigSpec rhs; if (it != cell->connections_.end()) { if (GetSize(it->second) < GetSize(w)) - it->second.append(RTLIL::SigSpec(RTLIL::S0, GetSize(w)-GetSize(it->second))); + it->second.append(RTLIL::SigSpec(State::S0, GetSize(w)-GetSize(it->second))); rhs = it->second; } else { - rhs = RTLIL::SigSpec(RTLIL::S0, GetSize(w)); + rhs = RTLIL::SigSpec(State::S0, GetSize(w)); cell->setPort(port_name, rhs); } @@ -400,10 +400,10 @@ struct XAigerWriter for (auto b : rhs.bits()) { SigBit I = sigmap(b); if (b == RTLIL::Sx) - b = RTLIL::S0; + b = State::S0; else if (I != b) { if (I == RTLIL::Sx) - alias_map[b] = RTLIL::S0; + alias_map[b] = State::S0; else alias_map[b] = I; } @@ -610,19 +610,18 @@ struct XAigerWriter std::stringstream h_buffer; auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); write_h_buffer(1); - log_debug("ciNum = %zu\n", input_bits.size() + ci_bits.size()); + log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); write_h_buffer(input_bits.size() + ci_bits.size()); - log_debug("coNum = %zu\n", output_bits.size() + co_bits.size()); + log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); write_h_buffer(output_bits.size() + co_bits.size()); - log_debug("piNum = %zu\n", input_bits.size()); + log_debug("piNum = %d\n", GetSize(input_bits)); write_h_buffer(input_bits.size()); - log_debug("poNum = %zu\n", output_bits.size()); + log_debug("poNum = %d\n", GetSize(output_bits)); write_h_buffer(output_bits.size()); - log_debug("boxNum = %zu\n", box_list.size()); + log_debug("boxNum = %d\n", GetSize(box_list)); write_h_buffer(box_list.size()); - RTLIL::Module *holes_module = nullptr; - holes_module = module->design->addModule("$__holes__"); + RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); int port_id = 1; @@ -672,7 +671,7 @@ struct XAigerWriter if (holes_cell) port_wire.append(holes_wire); else - holes_module->connect(holes_wire, RTLIL::S0); + holes_module->connect(holes_wire, State::S0); } if (!port_wire.empty()) holes_cell->setPort(w->name, port_wire); @@ -719,27 +718,33 @@ struct XAigerWriter Pass::call(holes_module->design, "flatten -wb"); // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, - // instead of per write_xaiger call + // instead of per write_xaiger call Pass::call(holes_module->design, "techmap"); Pass::call(holes_module->design, "aigmap"); for (auto cell : holes_module->cells()) if (!cell->type.in("$_NOT_", "$_AND_")) log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); - Pass::call(holes_module->design, "clean -purge"); + holes_module->design->selection_stack.pop_back(); + + // Move into a new (temporary) design so that "clean" will only + // operate (and run checks on) this one module + RTLIL::Design *holes_design = new RTLIL::Design; + holes_module->design->modules_.erase(holes_module->name); + holes_design->add(holes_module); + Pass::call(holes_design, "clean -purge"); std::stringstream a_buffer; XAigerWriter writer(holes_module, true /* holes_mode */); writer.write_aiger(a_buffer, false /*ascii_mode*/); - holes_module->design->selection_stack.pop_back(); + delete holes_design; f << "a"; std::string buffer_str = a_buffer.str(); int32_t buffer_size_be = to_big_endian(buffer_str.size()); f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); - holes_module->design->remove(holes_module); log_pop(); } @@ -772,7 +777,7 @@ struct XAigerWriter if (output_bits.count(b)) { int o = ordered_outputs.at(b); - output_lines[o] += stringf("output %lu %d %s\n", o - co_bits.size(), i, log_id(wire)); + output_lines[o] += stringf("output %d %d %s\n", o - GetSize(co_bits), i, log_id(wire)); continue; } diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index a1761b662..b6e38c16c 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -327,6 +327,13 @@ struct BlifDumper goto internal_cell; } + if (!config->icells_mode && cell->type == "$_NMUX_") { + f << stringf(".names %s %s %s %s\n0-0 1\n-01 1\n", + cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), + cstr(cell->getPort("\\S")), cstr(cell->getPort("\\Y"))); + goto internal_cell; + } + if (!config->icells_mode && cell->type == "$_FF_") { f << stringf(".latch %s %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")), cstr_init(cell->getPort("\\Q"))); @@ -370,7 +377,7 @@ struct BlifDumper f << stringf("\n"); RTLIL::SigSpec mask = cell->parameters.at("\\LUT"); for (int i = 0; i < (1 << width); i++) - if (mask[i] == RTLIL::S1) { + if (mask[i] == State::S1) { for (int j = width-1; j >= 0; j--) { f << ((i>>j)&1 ? '1' : '0'); } diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index a507b120b..7c054d655 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -496,7 +496,7 @@ struct BtorWorker goto okay; } - if (cell->type.in("$mux", "$_MUX_")) + if (cell->type.in("$mux", "$_MUX_", "$_NMUX_")) { SigSpec sig_a = sigmap(cell->getPort("\\A")); SigSpec sig_b = sigmap(cell->getPort("\\B")); @@ -511,6 +511,12 @@ struct BtorWorker int nid = next_nid++; btorf("%d ite %d %d %d %d\n", nid, sid, nid_s, nid_b, nid_a); + if (cell->type == "$_NMUX_") { + int tmp = nid; + nid = next_nid++; + btorf("%d not %d %d\n", nid, sid, tmp); + } + add_nid_sig(nid, sig_y); goto okay; } @@ -610,8 +616,8 @@ struct BtorWorker if (initstate_nid < 0) { int sid = get_bv_sid(1); - int one_nid = get_sig_nid(Const(1, 1)); - int zero_nid = get_sig_nid(Const(0, 1)); + int one_nid = get_sig_nid(State::S1); + int zero_nid = get_sig_nid(State::S0); initstate_nid = next_nid++; btorf("%d state %d\n", initstate_nid, sid); btorf("%d init %d %d %d\n", next_nid++, sid, initstate_nid, one_nid); diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 1c7a7351f..87db0edf7 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -122,9 +122,9 @@ struct FirrtlWorker // Current (3/13/2019) conventions: // generate a constant 0 for clock and a constant 1 for enable if they are undefined. if (!clk.is_fully_def()) - this->clk = SigSpec(RTLIL::Const(0, 1)); + this->clk = SigSpec(State::S0); if (!ena.is_fully_def()) - this->ena = SigSpec(RTLIL::Const(1, 1)); + this->ena = SigSpec(State::S1); } string gen_read(const char * indent) { string addr_expr = make_expr(addr); @@ -297,7 +297,7 @@ struct FirrtlWorker std::string cell_type = fid(cell->type); std::string instanceOf; // If this is a parameterized module, its parent module is encoded in the cell type - if (cell->type.substr(0, 8) == "$paramod") + if (cell->type.begins_with("$paramod")) { std::string::iterator it; for (it = cell_type.begin(); it < cell_type.end(); it++) @@ -363,7 +363,7 @@ struct FirrtlWorker } // Check for subfield assignment. std::string bitsString = "bits("; - if (sinkExpr.substr(0, bitsString.length()) == bitsString ) { + if (sinkExpr.compare(0, bitsString.length(), bitsString) == 0) { if (sinkSig == nullptr) log_error("Unknown subfield %s.%s\n", cell_type.c_str(), sinkExpr.c_str()); // Don't generate the assignment here. @@ -381,10 +381,10 @@ struct FirrtlWorker // Given an expression for a shift amount, and a maximum width, // generate the FIRRTL expression for equivalent dynamic shift taking into account FIRRTL shift semantics. - std::string gen_dshl(const string b_expr, const int b_padded_width) + std::string gen_dshl(const string b_expr, const int b_width) { string result = b_expr; - if (b_padded_width >= FIRRTL_MAX_DSH_WIDTH_ERROR) { + if (b_width >= FIRRTL_MAX_DSH_WIDTH_ERROR) { int max_shift_width_bits = FIRRTL_MAX_DSH_WIDTH_ERROR - 1; string max_shift_string = stringf("UInt<%d>(%d)", max_shift_width_bits, (1<cells()) { - bool extract_y_bits = false; // Assume no extraction of final bits will be required. + static Const ndef(0, 0); + // Is this cell is a module instance? if (cell->type[0] != '$') { process_instance(cell, wire_exprs); continue; } + // Not a module instance. Set up cell properties + bool extract_y_bits = false; // Assume no extraction of final bits will be required. + int a_width = cell->parameters.at("\\A_WIDTH", ndef).as_int(); // The width of "A" + int b_width = cell->parameters.at("\\B_WIDTH", ndef).as_int(); // The width of "A" + const int y_width = cell->parameters.at("\\Y_WIDTH", ndef).as_int(); // The width of the result + const bool a_signed = cell->parameters.at("\\A_SIGNED", ndef).as_bool(); + const bool b_signed = cell->parameters.at("\\B_SIGNED", ndef).as_bool(); + bool firrtl_is_signed = a_signed; // The result is signed (subsequent code may change this). + int firrtl_width = 0; + string primop; + bool always_uint = false; + string y_id = make_id(cell->name); + if (cell->type.in("$not", "$logic_not", "$neg", "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_bool", "$reduce_xnor")) { - string y_id = make_id(cell->name); - bool is_signed = cell->parameters.at("\\A_SIGNED").as_bool(); - int y_width = cell->parameters.at("\\Y_WIDTH").as_int(); string a_expr = make_expr(cell->getPort("\\A")); wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width)); - if (cell->parameters.at("\\A_SIGNED").as_bool()) { + if (a_signed) { a_expr = "asSInt(" + a_expr + ")"; } @@ -446,12 +457,13 @@ struct FirrtlWorker a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width); } - string primop; - bool always_uint = false; + // Assume the FIRRTL width is a single bit. + firrtl_width = 1; if (cell->type == "$not") primop = "not"; else if (cell->type == "$neg") { primop = "neg"; - is_signed = true; // Result of "neg" is signed (an SInt). + firrtl_is_signed = true; // Result of "neg" is signed (an SInt). + firrtl_width = a_width; } else if (cell->type == "$logic_not") { primop = "eq"; a_expr = stringf("%s, UInt(0)", a_expr.c_str()); @@ -466,14 +478,12 @@ struct FirrtlWorker else if (cell->type == "$reduce_bool") { primop = "neq"; // Use the sign of the a_expr and its width as the type (UInt/SInt) and width of the comparand. - bool a_signed = cell->parameters.at("\\A_SIGNED").as_bool(); - int a_width = cell->parameters.at("\\A_WIDTH").as_int(); a_expr = stringf("%s, %cInt<%d>(0)", a_expr.c_str(), a_signed ? 'S' : 'U', a_width); } string expr = stringf("%s(%s)", primop.c_str(), a_expr.c_str()); - if ((is_signed && !always_uint)) + if ((firrtl_is_signed && !always_uint)) expr = stringf("asUInt(%s)", expr.c_str()); cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str())); @@ -481,81 +491,121 @@ struct FirrtlWorker continue; } - if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$xor", "$and", "$or", "$eq", "$eqx", + if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$xor", "$xnor", "$and", "$or", "$eq", "$eqx", "$gt", "$ge", "$lt", "$le", "$ne", "$nex", "$shr", "$sshr", "$sshl", "$shl", - "$logic_and", "$logic_or")) + "$logic_and", "$logic_or", "$pow")) { - string y_id = make_id(cell->name); - bool is_signed = cell->parameters.at("\\A_SIGNED").as_bool(); - int y_width = cell->parameters.at("\\Y_WIDTH").as_int(); string a_expr = make_expr(cell->getPort("\\A")); string b_expr = make_expr(cell->getPort("\\B")); - int b_padded_width = cell->parameters.at("\\B_WIDTH").as_int(); wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width)); - if (cell->parameters.at("\\A_SIGNED").as_bool()) { + if (a_signed) { a_expr = "asSInt(" + a_expr + ")"; - } - // Shift amount is always unsigned, and needn't be padded to result width. - if (!cell->type.in("$shr", "$sshr", "$shl", "$sshl")) { - if (cell->parameters.at("\\B_SIGNED").as_bool()) { - b_expr = "asSInt(" + b_expr + ")"; + // Expand the "A" operand to the result width + if (a_width < y_width) { + a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width); + a_width = y_width; } - if (b_padded_width < y_width) { - auto b_sig = cell->getPort("\\B"); - b_padded_width = y_width; + } + // Shift amount is always unsigned, and needn't be padded to result width, + // otherwise, we need to cast the b_expr appropriately + if (b_signed && !cell->type.in("$shr", "$sshr", "$shl", "$sshl", "$pow")) { + b_expr = "asSInt(" + b_expr + ")"; + // Expand the "B" operand to the result width + if (b_width < y_width) { + b_expr = stringf("pad(%s, %d)", b_expr.c_str(), y_width); + b_width = y_width; } } + // For the arithmetic ops, expand operand widths to result widths befor performing the operation. + // This corresponds (according to iverilog) to what verilog compilers implement. + if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$xor", "$xnor", "$and", "$or")) + { + if (a_width < y_width) { + a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width); + a_width = y_width; + } + if (b_width < y_width) { + b_expr = stringf("pad(%s, %d)", b_expr.c_str(), y_width); + b_width = y_width; + } + } + // Assume the FIRRTL width is the width of "A" + firrtl_width = a_width; auto a_sig = cell->getPort("\\A"); - if (cell->parameters.at("\\A_SIGNED").as_bool() & (cell->type == "$shr")) { - a_expr = "asUInt(" + a_expr + ")"; + if (cell->type == "$add") { + primop = "add"; + firrtl_is_signed = a_signed | b_signed; + firrtl_width = max(a_width, b_width); + } else if (cell->type == "$sub") { + primop = "sub"; + firrtl_is_signed = true; + int a_widthInc = (!a_signed && b_signed) ? 2 : (a_signed && !b_signed) ? 1 : 0; + int b_widthInc = (a_signed && !b_signed) ? 2 : (!a_signed && b_signed) ? 1 : 0; + firrtl_width = max(a_width + a_widthInc, b_width + b_widthInc); + } else if (cell->type == "$mul") { + primop = "mul"; + firrtl_is_signed = a_signed | b_signed; + firrtl_width = a_width + b_width; + } else if (cell->type == "$div") { + primop = "div"; + firrtl_is_signed = a_signed | b_signed; + firrtl_width = a_width; + } else if (cell->type == "$mod") { + primop = "rem"; + firrtl_width = min(a_width, b_width); + } else if (cell->type == "$and") { + primop = "and"; + always_uint = true; + firrtl_width = max(a_width, b_width); } - - string primop; - bool always_uint = false; - if (cell->type == "$add") primop = "add"; - else if (cell->type == "$sub") primop = "sub"; - else if (cell->type == "$mul") primop = "mul"; - else if (cell->type == "$div") primop = "div"; - else if (cell->type == "$mod") primop = "rem"; - else if (cell->type == "$and") { - primop = "and"; - always_uint = true; - } else if (cell->type == "$or" ) { - primop = "or"; - always_uint = true; - } + primop = "or"; + always_uint = true; + firrtl_width = max(a_width, b_width); + } else if (cell->type == "$xor") { - primop = "xor"; - always_uint = true; - } + primop = "xor"; + always_uint = true; + firrtl_width = max(a_width, b_width); + } + else if (cell->type == "$xnor") { + primop = "xnor"; + always_uint = true; + firrtl_width = max(a_width, b_width); + } else if ((cell->type == "$eq") | (cell->type == "$eqx")) { - primop = "eq"; - always_uint = true; - } + primop = "eq"; + always_uint = true; + firrtl_width = 1; + } else if ((cell->type == "$ne") | (cell->type == "$nex")) { - primop = "neq"; - always_uint = true; - } + primop = "neq"; + always_uint = true; + firrtl_width = 1; + } else if (cell->type == "$gt") { - primop = "gt"; - always_uint = true; - } + primop = "gt"; + always_uint = true; + firrtl_width = 1; + } else if (cell->type == "$ge") { - primop = "geq"; - always_uint = true; - } + primop = "geq"; + always_uint = true; + firrtl_width = 1; + } else if (cell->type == "$lt") { - primop = "lt"; - always_uint = true; - } + primop = "lt"; + always_uint = true; + firrtl_width = 1; + } else if (cell->type == "$le") { - primop = "leq"; - always_uint = true; - } + primop = "leq"; + always_uint = true; + firrtl_width = 1; + } else if ((cell->type == "$shl") | (cell->type == "$sshl")) { // FIRRTL will widen the result (y) by the amount of the shift. // We'll need to offset this by extracting the un-widened portion as Verilog would do. @@ -564,11 +614,14 @@ struct FirrtlWorker auto b_sig = cell->getPort("\\B"); if (b_sig.is_fully_const()) { primop = "shl"; - b_expr = std::to_string(b_sig.as_int()); + int shift_amount = b_sig.as_int(); + b_expr = std::to_string(shift_amount); + firrtl_width = a_width + shift_amount; } else { primop = "dshl"; // Convert from FIRRTL left shift semantics. - b_expr = gen_dshl(b_expr, b_padded_width); + b_expr = gen_dshl(b_expr, b_width); + firrtl_width = a_width + (1 << b_width) - 1; } } else if ((cell->type == "$shr") | (cell->type == "$sshr")) { @@ -578,36 +631,86 @@ struct FirrtlWorker auto b_sig = cell->getPort("\\B"); if (b_sig.is_fully_const()) { primop = "shr"; - b_expr = std::to_string(b_sig.as_int()); + int shift_amount = b_sig.as_int(); + b_expr = std::to_string(shift_amount); + firrtl_width = max(1, a_width - shift_amount); } else { primop = "dshr"; + firrtl_width = a_width; + } + // We'll need to do some special fixups if the source (and thus result) is signed. + if (firrtl_is_signed) { + // If this is a "logical" shift right, pretend the source is unsigned. + if (cell->type == "$shr") { + a_expr = "asUInt(" + a_expr + ")"; + } } } else if ((cell->type == "$logic_and")) { - primop = "and"; - a_expr = "neq(" + a_expr + ", UInt(0))"; - b_expr = "neq(" + b_expr + ", UInt(0))"; - always_uint = true; - } + primop = "and"; + a_expr = "neq(" + a_expr + ", UInt(0))"; + b_expr = "neq(" + b_expr + ", UInt(0))"; + always_uint = true; + firrtl_width = 1; + } else if ((cell->type == "$logic_or")) { - primop = "or"; - a_expr = "neq(" + a_expr + ", UInt(0))"; - b_expr = "neq(" + b_expr + ", UInt(0))"; - always_uint = true; - } + primop = "or"; + a_expr = "neq(" + a_expr + ", UInt(0))"; + b_expr = "neq(" + b_expr + ", UInt(0))"; + always_uint = true; + firrtl_width = 1; + } + else if ((cell->type == "$pow")) { + if (a_sig.is_fully_const() && a_sig.as_int() == 2) { + // We'll convert this to a shift. To simplify things, change the a_expr to "1" + // so we can use b_expr directly as a shift amount. + // Only support 2 ** N (i.e., shift left) + // FIRRTL will widen the result (y) by the amount of the shift. + // We'll need to offset this by extracting the un-widened portion as Verilog would do. + a_expr = firrtl_is_signed ? "SInt(1)" : "UInt(1)"; + extract_y_bits = true; + // Is the shift amount constant? + auto b_sig = cell->getPort("\\B"); + if (b_sig.is_fully_const()) { + primop = "shl"; + int shiftAmount = b_sig.as_int(); + if (shiftAmount < 0) { + log_error("Negative power exponent - %d: %s.%s\n", shiftAmount, log_id(module), log_id(cell)); + } + b_expr = std::to_string(shiftAmount); + firrtl_width = a_width + shiftAmount; + } else { + primop = "dshl"; + // Convert from FIRRTL left shift semantics. + b_expr = gen_dshl(b_expr, b_width); + firrtl_width = a_width + (1 << b_width) - 1; + } + } else { + log_error("Non power 2: %s.%s\n", log_id(module), log_id(cell)); + } + } if (!cell->parameters.at("\\B_SIGNED").as_bool()) { b_expr = "asUInt(" + b_expr + ")"; } - string expr = stringf("%s(%s, %s)", primop.c_str(), a_expr.c_str(), b_expr.c_str()); - - // Deal with FIRRTL's "shift widens" semantics - if (extract_y_bits) { - expr = stringf("bits(%s, %d, 0)", expr.c_str(), y_width - 1); + string expr; + // Deal with $xnor == ~^ (not xor) + if (primop == "xnor") { + expr = stringf("not(xor(%s, %s))", a_expr.c_str(), b_expr.c_str()); + } else { + expr = stringf("%s(%s, %s)", primop.c_str(), a_expr.c_str(), b_expr.c_str()); } - if ((is_signed && !always_uint) || cell->type.in("$sub")) + // Deal with FIRRTL's "shift widens" semantics, or the need to widen the FIRRTL result. + // If the operation is signed, the FIRRTL width will be 1 one bit larger. + if (extract_y_bits) { + expr = stringf("bits(%s, %d, 0)", expr.c_str(), y_width - 1); + } else if (firrtl_is_signed && (firrtl_width + 1) < y_width) { + expr = stringf("pad(%s, %d)", expr.c_str(), y_width); + } + + if ((firrtl_is_signed && !always_uint)) expr = stringf("asUInt(%s)", expr.c_str()); cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str())); @@ -618,7 +721,6 @@ struct FirrtlWorker if (cell->type.in("$mux")) { - string y_id = make_id(cell->name); int width = cell->parameters.at("\\WIDTH").as_int(); string a_expr = make_expr(cell->getPort("\\A")); string b_expr = make_expr(cell->getPort("\\B")); @@ -762,21 +864,20 @@ struct FirrtlWorker if (clkpol == false) log_error("Negative edge clock on FF %s.%s.\n", log_id(module), log_id(cell)); - string q_id = make_id(cell->name); int width = cell->parameters.at("\\WIDTH").as_int(); string expr = make_expr(cell->getPort("\\D")); string clk_expr = "asClock(" + make_expr(cell->getPort("\\CLK")) + ")"; - wire_decls.push_back(stringf(" reg %s: UInt<%d>, %s\n", q_id.c_str(), width, clk_expr.c_str())); + wire_decls.push_back(stringf(" reg %s: UInt<%d>, %s\n", y_id.c_str(), width, clk_expr.c_str())); - cell_exprs.push_back(stringf(" %s <= %s\n", q_id.c_str(), expr.c_str())); - register_reverse_wire_map(q_id, cell->getPort("\\Q")); + cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str())); + register_reverse_wire_map(y_id, cell->getPort("\\Q")); continue; } // This may be a parameterized module - paramod. - if (cell->type.substr(0, 8) == "$paramod") + if (cell->type.begins_with("$paramod")) { process_instance(cell, wire_exprs); continue; @@ -785,8 +886,6 @@ struct FirrtlWorker // assign y = a[b +: y_width]; // We'll extract the correct bits as part of the primop. - string y_id = make_id(cell->name); - int y_width = cell->parameters.at("\\Y_WIDTH").as_int(); string a_expr = make_expr(cell->getPort("\\A")); // Get the initial bit selector string b_expr = make_expr(cell->getPort("\\B")); @@ -808,18 +907,15 @@ struct FirrtlWorker // assign y = a >> b; // where b may be negative - string y_id = make_id(cell->name); - int y_width = cell->parameters.at("\\Y_WIDTH").as_int(); string a_expr = make_expr(cell->getPort("\\A")); string b_expr = make_expr(cell->getPort("\\B")); auto b_string = b_expr.c_str(); - int b_padded_width = cell->parameters.at("\\B_WIDTH").as_int(); string expr; wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width)); if (cell->getParam("\\B_SIGNED").as_bool()) { // We generate a left or right shift based on the sign of b. - std::string dshl = stringf("bits(dshl(%s, %s), 0, %d)", a_expr.c_str(), gen_dshl(b_expr, b_padded_width).c_str(), y_width); + std::string dshl = stringf("bits(dshl(%s, %s), 0, %d)", a_expr.c_str(), gen_dshl(b_expr, b_width).c_str(), y_width); std::string dshr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string); expr = stringf("mux(%s < 0, %s, %s)", b_string, @@ -833,7 +929,21 @@ struct FirrtlWorker register_reverse_wire_map(y_id, cell->getPort("\\Y")); continue; } - log_warning("Cell type not supported: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); + if (cell->type == "$pos") { + // assign y = a; +// printCell(cell); + string a_expr = make_expr(cell->getPort("\\A")); + // Verilog appears to treat the result as signed, so if the result is wider than "A", + // we need to pad. + 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())); + register_reverse_wire_map(y_id, cell->getPort("\\Y")); + continue; + } + log_error("Cell type not supported: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); } for (auto conn : module->connections()) diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index 313af7d5c..e06786220 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -40,8 +40,8 @@ void ILANG_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi for (int i = 0; i < width; i++) { log_assert(offset+i < (int)data.bits.size()); switch (data.bits[offset+i]) { - case RTLIL::S0: break; - case RTLIL::S1: val |= 1 << i; break; + case State::S0: break; + case State::S1: val |= 1 << i; break; default: val = -1; break; } } @@ -54,8 +54,8 @@ void ILANG_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi for (int i = offset+width-1; i >= offset; i--) { log_assert(i < (int)data.bits.size()); switch (data.bits[i]) { - case RTLIL::S0: f << stringf("0"); break; - case RTLIL::S1: f << stringf("1"); break; + case State::S0: f << stringf("0"); break; + case State::S1: f << stringf("1"); break; case RTLIL::Sx: f << stringf("x"); break; case RTLIL::Sz: f << stringf("z"); break; case RTLIL::Sa: f << stringf("-"); break; diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index b0e3cd252..809a0fa09 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -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.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); + Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog")); libs.push_back(lib); } @@ -183,7 +183,7 @@ struct IntersynthBackend : public Backend { if (param.second.bits.size() != 32) { node_code += stringf(" %s '", RTLIL::id2cstr(param.first)); for (int i = param.second.bits.size()-1; i >= 0; i--) - node_code += param.second.bits[i] == RTLIL::S1 ? "1" : "0"; + node_code += param.second.bits[i] == State::S1 ? "1" : "0"; } else node_code += stringf(" %s 0x%x", RTLIL::id2cstr(param.first), param.second.as_int()); } diff --git a/backends/json/json.cc b/backends/json/json.cc index dda4dfedd..107009ee4 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -83,20 +83,43 @@ struct JsonWriter return str + " ]"; } + void write_parameter_value(const Const &value) + { + if ((value.flags & RTLIL::ConstFlags::CONST_FLAG_STRING) != 0) { + string str = value.decode_string(); + int state = 0; + for (char c : str) { + if (state == 0) { + if (c == '0' || c == '1' || c == 'x' || c == 'z') + state = 0; + else if (c == ' ') + state = 1; + else + state = 2; + } else if (state == 1 && c != ' ') + state = 2; + } + if (state < 2) + str += " "; + f << get_string(str); + } else + if (GetSize(value) == 32 && value.is_fully_def()) { + if ((value.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) != 0) + f << stringf("%d", value.as_int()); + else + f << stringf("%u", value.as_int()); + } else { + f << get_string(value.as_string()); + } + } + void write_parameters(const dict ¶meters, bool for_module=false) { bool first = true; for (auto ¶m : parameters) { f << stringf("%s\n", first ? "" : ","); f << stringf(" %s%s: ", for_module ? "" : " ", get_name(param.first).c_str()); - if ((param.second.flags & RTLIL::ConstFlags::CONST_FLAG_STRING) != 0) - f << get_string(param.second.decode_string()); - else if (GetSize(param.second.bits) > 32) - f << get_string(param.second.as_string()); - else if ((param.second.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) != 0) - f << stringf("%d", param.second.as_int()); - else - f << stringf("%u", param.second.as_int()); + write_parameter_value(param.second); first = false; } } @@ -342,12 +365,13 @@ struct JsonBackend : public Backend { log("Module and cell ports and nets can be single bit wide or vectors of multiple\n"); log("bits. Each individual signal bit is assigned a unique integer. The \n"); log("values referenced above are vectors of this integers. Signal bits that are\n"); - log("connected to a constant driver are denoted as string \"0\" or \"1\" instead of\n"); - log("a number.\n"); + log("connected to a constant driver are denoted as string \"0\", \"1\", \"x\", or\n"); + log("\"z\" instead of a number.\n"); log("\n"); - log("Numeric parameter and attribute values up to 32 bits are written as decimal\n"); - log("values. Numbers larger than that are written as string holding the binary\n"); - log("representation of the value.\n"); + log("Numeric 32-bit parameter and attribute values are written as decimal values.\n"); + log("Bit verctors of different sizes, or ones containing 'x' or 'z' bits, are written\n"); + log("as string holding the binary representation of the value. Strings are written\n"); + log("as strings, with an appended blank in cases of strings of the form /[01xz]* */.\n"); log("\n"); log("For example the following Verilog code:\n"); log("\n"); diff --git a/backends/simplec/simplec.cc b/backends/simplec/simplec.cc index 6f2ccbe20..54dbb84af 100644 --- a/backends/simplec/simplec.cc +++ b/backends/simplec/simplec.cc @@ -472,7 +472,7 @@ struct SimplecWorker return; } - if (cell->type == "$_MUX_") + if (cell->type.in("$_MUX_", "$_NMUX_")) { SigBit a = sigmaps.at(work->module)(cell->getPort("\\A")); SigBit b = sigmaps.at(work->module)(cell->getPort("\\B")); @@ -484,7 +484,9 @@ struct SimplecWorker string s_expr = s.wire ? util_get_bit(work->prefix + cid(s.wire->name), s.wire->width, s.offset) : s.data ? "1" : "0"; // casts to bool are a workaround for CBMC bug (https://github.com/diffblue/cbmc/issues/933) - string expr = stringf("%s ? (bool)%s : (bool)%s", s_expr.c_str(), b_expr.c_str(), a_expr.c_str()); + string expr = stringf("%s ? %s(bool)%s : %s(bool)%s", s_expr.c_str(), + cell->type == "$_NMUX_" ? "!" : "", b_expr.c_str(), + cell->type == "$_NMUX_" ? "!" : "", a_expr.c_str()); log_assert(y.wire); funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) + diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index e318a4051..081dcda99 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -510,6 +510,7 @@ struct Smt2Worker if (cell->type == "$_ANDNOT_") return export_gate(cell, "(and A (not B))"); if (cell->type == "$_ORNOT_") return export_gate(cell, "(or A (not B))"); if (cell->type == "$_MUX_") return export_gate(cell, "(ite S B A)"); + if (cell->type == "$_NMUX_") return export_gate(cell, "(not (ite S B A))"); if (cell->type == "$_AOI3_") return export_gate(cell, "(not (or (and A B) C))"); if (cell->type == "$_OAI3_") return export_gate(cell, "(not (and (or A B) C))"); if (cell->type == "$_AOI4_") return export_gate(cell, "(not (or (and A B) (and C D)))"); @@ -600,7 +601,7 @@ struct Smt2Worker if (cell->type == "$logic_and") return export_reduce(cell, "(and (or A) (or B))", false); if (cell->type == "$logic_or") return export_reduce(cell, "(or A B)", false); - if (cell->type == "$mux" || cell->type == "$pmux") + if (cell->type.in("$mux", "$pmux")) { int width = GetSize(cell->getPort("\\Y")); std::string processed_expr = get_bv(cell->getPort("\\A")); @@ -1475,7 +1476,7 @@ struct Smt2Backend : public Backend { int indent = 0; while (indent < GetSize(line) && (line[indent] == ' ' || line[indent] == '\t')) indent++; - if (line.substr(indent, 2) == "%%") + if (line.compare(indent, 2, "%%") == 0) break; *f << line << std::endl; } diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc index d75456c1b..f755307bf 100644 --- a/backends/smv/smv.cc +++ b/backends/smv/smv.cc @@ -61,7 +61,7 @@ struct SmvWorker { string name = stringf("_%s", id.c_str()); - if (name.substr(0, 2) == "_\\") + if (name.compare(0, 2, "_\\") == 0) name = "_" + name.substr(2); for (auto &c : name) { @@ -537,6 +537,13 @@ struct SmvWorker continue; } + if (cell->type == "$_NMUX_") + { + definitions.push_back(stringf("%s := !(bool(%s) ? %s : %s);", lvalue(cell->getPort("\\Y")), + rvalue(cell->getPort("\\S")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\A")))); + continue; + } + if (cell->type == "$_AOI3_") { definitions.push_back(stringf("%s := !((%s & %s) | %s);", lvalue(cell->getPort("\\Y")), diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index e0b3a6f80..7b1db4776 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -200,9 +200,9 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o int32_t val = 0; for (int i = offset+width-1; i >= offset; i--) { log_assert(i < (int)data.bits.size()); - if (data.bits[i] != RTLIL::S0 && data.bits[i] != RTLIL::S1) + if (data.bits[i] != State::S0 && data.bits[i] != State::S1) goto dump_hex; - if (data.bits[i] == RTLIL::S1) + if (data.bits[i] == State::S1) val |= 1 << (i - offset); } if (decimal) @@ -219,8 +219,8 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o for (int i = offset; i < offset+width; i++) { log_assert(i < (int)data.bits.size()); switch (data.bits[i]) { - case RTLIL::S0: bin_digits.push_back('0'); break; - case RTLIL::S1: bin_digits.push_back('1'); break; + case State::S0: bin_digits.push_back('0'); break; + case State::S1: bin_digits.push_back('1'); break; case RTLIL::Sx: bin_digits.push_back('x'); break; case RTLIL::Sz: bin_digits.push_back('z'); break; case RTLIL::Sa: bin_digits.push_back('?'); break; @@ -273,8 +273,8 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o for (int i = offset+width-1; i >= offset; i--) { log_assert(i < (int)data.bits.size()); switch (data.bits[i]) { - case RTLIL::S0: f << stringf("0"); break; - case RTLIL::S1: f << stringf("1"); break; + case State::S0: f << stringf("0"); break; + case State::S1: f << stringf("1"); break; case RTLIL::Sx: f << stringf("x"); break; case RTLIL::Sz: f << stringf("z"); break; case RTLIL::Sa: f << stringf("?"); break; @@ -380,9 +380,9 @@ void dump_attributes(std::ostream &f, std::string indent, dictfirst).c_str()); f << stringf(" = "); - if (modattr && (it->second == Const(0, 1) || it->second == Const(0))) + if (modattr && (it->second == State::S0 || it->second == Const(0))) f << stringf(" 0 "); - else if (modattr && (it->second == Const(1, 1) || it->second == Const(1))) + else if (modattr && (it->second == State::S1 || it->second == Const(1))) f << stringf(" 1 "); else dump_const(f, it->second, -1, 0, false, as_comment); @@ -558,6 +558,20 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } + if (cell->type == "$_NMUX_") { + f << stringf("%s" "assign ", indent.c_str()); + dump_sigspec(f, cell->getPort("\\Y")); + f << stringf(" = !("); + dump_cell_expr_port(f, cell, "S", false); + f << stringf(" ? "); + dump_attributes(f, "", cell->attributes, ' '); + dump_cell_expr_port(f, cell, "B", false); + f << stringf(" : "); + dump_cell_expr_port(f, cell, "A", false); + f << stringf(");\n"); + return true; + } + if (cell->type.in("$_AOI3_", "$_OAI3_")) { f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); @@ -590,7 +604,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } - if (cell->type.substr(0, 6) == "$_DFF_") + if (cell->type.begins_with("$_DFF_")) { std::string reg_name = cellname(cell); bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name); @@ -631,7 +645,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } - if (cell->type.substr(0, 8) == "$_DFFSR_") + if (cell->type.begins_with("$_DFFSR_")) { char pol_c = cell->type[8], pol_s = cell->type[9], pol_r = cell->type[10]; @@ -935,7 +949,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } - if (cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffe") + if (cell->type.in("$dff", "$adff", "$dffe")) { RTLIL::SigSpec sig_clk, sig_arst, sig_en, val_arst; bool pol_clk, pol_arst = false, pol_en = false; diff --git a/examples/mimas2/README b/examples/mimas2/README new file mode 100644 index 000000000..b12875cbc --- /dev/null +++ b/examples/mimas2/README @@ -0,0 +1,8 @@ +A simple example design, based on the Numato Labs Mimas V2 board +================================================================ + +This example uses Yosys for synthesis and Xilinx ISE +for place&route and bit-stream creation. + +To synthesize: + bash run.sh diff --git a/examples/mimas2/example.ucf b/examples/mimas2/example.ucf new file mode 100644 index 000000000..4e31b74ab --- /dev/null +++ b/examples/mimas2/example.ucf @@ -0,0 +1,13 @@ +CONFIG VCCAUX = "3.3" ; + + +NET "CLK" LOC = D9 | IOSTANDARD = LVCMOS33 | PERIOD = 12MHz ; + +NET "LED[7]" LOC = P15 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; +NET "LED[6]" LOC = P16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; +NET "LED[5]" LOC = N15 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; +NET "LED[4]" LOC = N16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; +NET "LED[3]" LOC = U17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; +NET "LED[2]" LOC = U18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; +NET "LED[1]" LOC = T17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; +NET "LED[0]" LOC = T18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; diff --git a/examples/mimas2/example.v b/examples/mimas2/example.v new file mode 100644 index 000000000..2a9117393 --- /dev/null +++ b/examples/mimas2/example.v @@ -0,0 +1,14 @@ +module example( + input wire CLK, + output wire [7:0] LED +); + +reg [27:0] ctr; +initial ctr = 0; + +always @(posedge CLK) + ctr <= ctr + 1; + +assign LED = ctr[27:20]; + +endmodule diff --git a/examples/mimas2/run.sh b/examples/mimas2/run.sh new file mode 100644 index 000000000..aafde78ed --- /dev/null +++ b/examples/mimas2/run.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -e +yosys run_yosys.ys +edif2ngd example.edif +ngdbuild example -uc example.ucf -p xc6slx9csg324-3 +map -w example +par -w example.ncd example_par.ncd +bitgen -w example_par.ncd -g StartupClk:JTAGClk diff --git a/examples/mimas2/run_yosys.ys b/examples/mimas2/run_yosys.ys new file mode 100644 index 000000000..b3204b1ca --- /dev/null +++ b/examples/mimas2/run_yosys.ys @@ -0,0 +1,4 @@ +read_verilog example.v +synth_xilinx -top example -family xc6s +iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I +write_edif -pvector bra example.edif diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 03c541b7c..06522939f 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -30,6 +30,7 @@ #include #define __builtin_bswap32 OSSwapInt32 #endif +#define __STDC_FORMAT_MACROS #include #include "kernel/yosys.h" @@ -66,7 +67,7 @@ struct ConstEvalAig continue; for (auto &it2 : it.second->connections()) if (yosys_celltypes.cell_output(it.second->type, it2.first)) { - auto r = sig2driver.insert(std::make_pair(it2.second, it.second)); + auto r YS_ATTRIBUTE(unused) = sig2driver.insert(std::make_pair(it2.second, it.second)); log_assert(r.second); } } @@ -151,12 +152,12 @@ struct ConstEvalAig RTLIL::State eval_ret = RTLIL::Sx; if (cell->type == "$_NOT_") { - if (sig_a == RTLIL::S0) eval_ret = RTLIL::S1; - else if (sig_a == RTLIL::S1) eval_ret = RTLIL::S0; + if (sig_a == State::S0) eval_ret = State::S1; + else if (sig_a == State::S1) eval_ret = State::S0; } else if (cell->type == "$_AND_") { - if (sig_a == RTLIL::S0) { - eval_ret = RTLIL::S0; + if (sig_a == State::S0) { + eval_ret = State::S0; goto eval_end; } @@ -164,15 +165,15 @@ struct ConstEvalAig RTLIL::SigBit sig_b = cell->getPort("\\B"); if (!eval(sig_b)) return false; - if (sig_b == RTLIL::S0) { - eval_ret = RTLIL::S0; + if (sig_b == State::S0) { + eval_ret = State::S0; goto eval_end; } - if (sig_a != RTLIL::S1 || sig_b != RTLIL::S1) + if (sig_a != State::S1 || sig_b != State::S1) goto eval_end; - eval_ret = RTLIL::S1; + eval_ret = State::S1; } } else log_abort(); @@ -256,7 +257,7 @@ end_of_header: RTLIL::Wire* n0 = module->wire("\\__0__"); if (n0) - module->connect(n0, RTLIL::S0); + module->connect(n0, State::S0); // Parse footer (symbol table, comments, etc.) unsigned l1; @@ -301,7 +302,11 @@ static uint32_t parse_xaiger_literal(std::istream &f) uint32_t l; f.read(reinterpret_cast(&l), sizeof(l)); if (f.gcount() != sizeof(l)) +#if defined(_WIN32) && defined(__MINGW32__) + log_error("Offset %I64d: unable to read literal!\n", static_cast(f.tellg())); +#else log_error("Offset %" PRId64 ": unable to read literal!\n", static_cast(f.tellg())); +#endif return from_big_endian(l); } @@ -333,7 +338,7 @@ static RTLIL::Wire* createWireIfNotExists(RTLIL::Module *module, unsigned litera return wire; } -void AigerReader::parse_xaiger() +void AigerReader::parse_xaiger(const dict &box_lookup) { std::string header; f >> header; @@ -367,22 +372,7 @@ void AigerReader::parse_xaiger() RTLIL::Wire* n0 = module->wire("\\__0__"); if (n0) - module->connect(n0, RTLIL::S0); - - dict box_lookup; - for (auto m : design->modules()) { - auto it = m->attributes.find("\\abc_box_id"); - if (it == m->attributes.end()) - continue; - if (m->name.begins_with("$paramod")) - continue; - auto id = it->second.as_int(); - auto r = box_lookup.insert(std::make_pair(id, m->name)); - if (!r.second) - log_error("Module '%s' has the same abc_box_id = %d value as '%s'.\n", - log_id(m), id, log_id(r.first->second)); - log_assert(r.second); - } + module->connect(n0, State::S0); // Parse footer (symbol table, comments, etc.) std::string s; @@ -399,9 +389,9 @@ void AigerReader::parse_xaiger() f.ignore(1); // XAIGER extensions if (c == 'm') { - uint32_t dataSize = parse_xaiger_literal(f); + uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); uint32_t lutNum = parse_xaiger_literal(f); - uint32_t lutSize = parse_xaiger_literal(f); + uint32_t lutSize YS_ATTRIBUTE(unused) = 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) { @@ -426,7 +416,7 @@ void AigerReader::parse_xaiger() int gray = j ^ (j >> 1); ce.set_incremental(input_sig, RTLIL::Const{gray, static_cast(cutLeavesM)}); RTLIL::SigBit o(output_sig); - bool success = ce.eval(o); + bool success YS_ATTRIBUTE(unused) = ce.eval(o); log_assert(success); log_assert(o.wire == nullptr); lut_mask[gray] = o.data; @@ -438,7 +428,7 @@ void AigerReader::parse_xaiger() } } else if (c == 'r') { - uint32_t dataSize = parse_xaiger_literal(f); + uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); flopNum = parse_xaiger_literal(f); log_assert(dataSize == (flopNum+1) * sizeof(uint32_t)); f.ignore(flopNum * sizeof(uint32_t)); @@ -450,18 +440,18 @@ void AigerReader::parse_xaiger() } else if (c == 'h') { f.ignore(sizeof(uint32_t)); - uint32_t version = parse_xaiger_literal(f); + uint32_t version YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); log_assert(version == 1); - uint32_t ciNum = parse_xaiger_literal(f); + uint32_t ciNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); log_debug("ciNum = %u\n", ciNum); - uint32_t coNum = parse_xaiger_literal(f); + uint32_t coNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); log_debug("coNum = %u\n", coNum); piNum = parse_xaiger_literal(f); log_debug("piNum = %u\n", piNum); - uint32_t poNum = parse_xaiger_literal(f); + uint32_t poNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); log_debug("poNum = %u\n", poNum); uint32_t boxNum = parse_xaiger_literal(f); - log_debug("boxNum = %u\n", poNum); + log_debug("boxNum = %u\n", boxNum); for (unsigned i = 0; i < boxNum; i++) { f.ignore(2*sizeof(uint32_t)); uint32_t boxUniqueId = parse_xaiger_literal(f); @@ -531,9 +521,9 @@ void AigerReader::parse_aiger_ascii() log_error("Line %u cannot be interpreted as a latch!\n", line_count); if (l3 == 0) - q_wire->attributes["\\init"] = RTLIL::S0; + q_wire->attributes["\\init"] = State::S0; else if (l3 == 1) - q_wire->attributes["\\init"] = RTLIL::S1; + q_wire->attributes["\\init"] = State::S1; else if (l3 == l1) { //q_wire->attributes["\\init"] = RTLIL::Sx; } @@ -542,7 +532,7 @@ void AigerReader::parse_aiger_ascii() } else { // AIGER latches are assumed to be initialized to zero - q_wire->attributes["\\init"] = RTLIL::S0; + q_wire->attributes["\\init"] = State::S0; } latches.push_back(q_wire); } @@ -656,9 +646,9 @@ void AigerReader::parse_aiger_binary() log_error("Line %u cannot be interpreted as a latch!\n", line_count); if (l3 == 0) - q_wire->attributes["\\init"] = RTLIL::S0; + q_wire->attributes["\\init"] = State::S0; else if (l3 == 1) - q_wire->attributes["\\init"] = RTLIL::S1; + q_wire->attributes["\\init"] = State::S1; else if (l3 == l1) { //q_wire->attributes["\\init"] = RTLIL::Sx; } @@ -667,7 +657,7 @@ void AigerReader::parse_aiger_binary() } else { // AIGER latches are assumed to be initialized to zero - q_wire->attributes["\\init"] = RTLIL::S0; + q_wire->attributes["\\init"] = State::S0; } latches.push_back(q_wire); } @@ -911,9 +901,6 @@ void AigerReader::post_process() RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable)); if (cell) { // ABC could have optimised this box away module->rename(cell, escaped_s); - RTLIL::Module* box_module = design->module(cell->type); - log_assert(box_module); - for (const auto &i : cell->connections()) { RTLIL::IdString port_name = i.first; RTLIL::SigSpec rhs = i.second; @@ -982,16 +969,17 @@ void AigerReader::post_process() } module->fixup_ports(); + + // Insert into a new (temporary) design so that "clean" will only + // operate (and run checks on) this one module + RTLIL::Design *mapped_design = new RTLIL::Design; + mapped_design->add(module); + Pass::call(mapped_design, "clean"); + mapped_design->modules_.erase(module->name); + delete mapped_design; + design->add(module); - design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = design->selection_stack.back(); - sel.select(module); - - Pass::call(design, "clean"); - - design->selection_stack.pop_back(); - for (auto cell : module->cells().to_vector()) { if (cell->type != "$lut") continue; auto y_port = cell->getPort("\\Y").as_bit(); diff --git a/frontends/aiger/aigerparse.h b/frontends/aiger/aigerparse.h index de3c3efbc..583c9d0f9 100644 --- a/frontends/aiger/aigerparse.h +++ b/frontends/aiger/aigerparse.h @@ -47,7 +47,7 @@ struct AigerReader AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name, std::string map_filename, bool wideports); void parse_aiger(); - void parse_xaiger(); + void parse_xaiger(const dict &box_lookup); void parse_aiger_ascii(); void parse_aiger_binary(); void post_process(); diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 3d066af53..0d6626b19 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -283,8 +283,8 @@ void AstNode::dumpAst(FILE *f, std::string indent) const if (!bits.empty()) { fprintf(f, " bits='"); for (size_t i = bits.size(); i > 0; i--) - fprintf(f, "%c", bits[i-1] == RTLIL::S0 ? '0' : - bits[i-1] == RTLIL::S1 ? '1' : + fprintf(f, "%c", bits[i-1] == State::S0 ? '0' : + bits[i-1] == State::S1 ? '1' : bits[i-1] == RTLIL::Sx ? 'x' : bits[i-1] == RTLIL::Sz ? 'z' : '?'); fprintf(f, "'(%d)", GetSize(bits)); @@ -716,7 +716,7 @@ AstNode *AstNode::mkconst_int(uint32_t v, bool is_signed, int width) node->integer = v; node->is_signed = is_signed; for (int i = 0; i < width; i++) { - node->bits.push_back((v & 1) ? RTLIL::S1 : RTLIL::S0); + node->bits.push_back((v & 1) ? State::S1 : State::S0); v = v >> 1; } node->range_valid = true; @@ -733,9 +733,9 @@ AstNode *AstNode::mkconst_bits(const std::vector &v, bool is_signe node->bits = v; for (size_t i = 0; i < 32; i++) { if (i < node->bits.size()) - node->integer |= (node->bits[i] == RTLIL::S1) << i; + node->integer |= (node->bits[i] == State::S1) << i; else if (is_signed && !node->bits.empty()) - node->integer |= (node->bits.back() == RTLIL::S1) << i; + node->integer |= (node->bits.back() == State::S1) << i; } node->range_valid = true; node->range_left = node->bits.size()-1; @@ -767,7 +767,7 @@ AstNode *AstNode::mkconst_str(const std::string &str) for (size_t i = 0; i < str.size(); i++) { unsigned char ch = str[str.size() - i - 1]; for (int j = 0; j < 8; j++) { - data.push_back((ch & 1) ? RTLIL::S1 : RTLIL::S0); + data.push_back((ch & 1) ? State::S1 : State::S0); ch = ch >> 1; } } @@ -780,7 +780,7 @@ AstNode *AstNode::mkconst_str(const std::string &str) bool AstNode::bits_only_01() const { for (auto bit : bits) - if (bit != RTLIL::S0 && bit != RTLIL::S1) + if (bit != State::S0 && bit != State::S1) return false; return true; } @@ -1164,7 +1164,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump } } - if (flag_icells && (*it)->str.substr(0, 2) == "\\$") + if (flag_icells && (*it)->str.compare(0, 2, "\\$") == 0) (*it)->str = (*it)->str.substr(1); if (defer) @@ -1172,7 +1172,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump if (design->has((*it)->str)) { RTLIL::Module *existing_mod = design->module((*it)->str); - if (!nooverwrite && !overwrite && !existing_mod->get_bool_attribute("\\blackbox")) { + if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) { log_file_error((*it)->filename, (*it)->linenum, "Re-definition of module `%s'!\n", (*it)->str.c_str()); } else if (nooverwrite) { log("Ignoring re-definition of module `%s' at %s:%d.\n", @@ -1463,7 +1463,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, dictnomeminit = nomeminit; new_mod->nomem2reg = nomem2reg; new_mod->mem2reg = mem2reg; + new_mod->noblackbox = noblackbox; new_mod->lib = lib; + new_mod->nowb = nowb; new_mod->noopt = noopt; new_mod->icells = icells; new_mod->pwires = pwires; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 571ddd988..407a34472 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1516,7 +1516,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) AstNode *child = *it; if (child->type == AST_CELLTYPE) { cell->type = child->str; - if (flag_icells && cell->type.substr(0, 2) == "\\$") + if (flag_icells && cell->type.begins_with("\\$")) cell->type = cell->type.substr(1); continue; } diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index e947125bf..54b9efaad 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2319,7 +2319,7 @@ skip_dynamic_range_lvalue_expansion:; if (attr.first.str().rfind("\\via_celltype_defparam_", 0) == 0) { AstNode *cell_arg = new AstNode(AST_PARASET, attr.second->clone()); - cell_arg->str = RTLIL::escape_id(attr.first.str().substr(strlen("\\via_celltype_defparam_"))); + cell_arg->str = RTLIL::escape_id(attr.first.substr(strlen("\\via_celltype_defparam_"))); cell->children.push_back(cell_arg); } @@ -2793,13 +2793,13 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m std::getline(f, line); for (int i = 0; i < GetSize(line); i++) { - if (in_comment && line.substr(i, 2) == "*/") { + if (in_comment && line.compare(i, 2, "*/") == 0) { line[i] = ' '; line[i+1] = ' '; in_comment = false; continue; } - if (!in_comment && line.substr(i, 2) == "/*") + if (!in_comment && line.compare(i, 2, "/*") == 0) in_comment = true; if (in_comment) line[i] = ' '; @@ -2808,7 +2808,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m while (1) { token = next_token(line, " \t\r\n"); - if (token.empty() || token.substr(0, 2) == "//") + if (token.empty() || token.compare(0, 2, "//") == 0) break; if (token[0] == '@') { @@ -3439,19 +3439,11 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) { std::map backup_scope; std::map variables; - bool delete_temp_block = false; - AstNode *block = NULL; + AstNode *block = new AstNode(AST_BLOCK); size_t argidx = 0; for (auto child : children) { - if (child->type == AST_BLOCK) - { - log_assert(block == NULL); - block = child; - continue; - } - if (child->type == AST_WIRE) { while (child->simplify(true, false, false, 1, -1, false, true)) { } @@ -3468,13 +3460,9 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } - log_assert(block == NULL); - delete_temp_block = true; - block = new AstNode(AST_BLOCK); block->children.push_back(child->clone()); } - log_assert(block != NULL); log_assert(variables.count(str) != 0); while (!block->children.empty()) @@ -3642,8 +3630,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) log_abort(); } - if (delete_temp_block) - delete block; + delete block; for (auto &it : backup_scope) if (it.second == NULL) diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc index a6a07863f..d17cacf29 100644 --- a/frontends/blif/blifparse.cc +++ b/frontends/blif/blifparse.cc @@ -78,7 +78,7 @@ failed: return std::pair("\\" + name, 0); } -void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bool run_clean, bool sop_mode, bool wideports) +void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool run_clean, bool sop_mode, bool wideports) { RTLIL::Module *module = nullptr; RTLIL::Const *lutptr = NULL; diff --git a/frontends/blif/blifparse.h b/frontends/blif/blifparse.h index 955b6aacf..2b84cb795 100644 --- a/frontends/blif/blifparse.h +++ b/frontends/blif/blifparse.h @@ -24,7 +24,7 @@ YOSYS_NAMESPACE_BEGIN -extern void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, +extern void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool run_clean = false, bool sop_mode = false, bool wideports = false); YOSYS_NAMESPACE_END diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc index f5ae8eb72..7aceffbfc 100644 --- a/frontends/json/jsonparse.cc +++ b/frontends/json/jsonparse.cc @@ -25,7 +25,7 @@ struct JsonNode { char type; // S=String, N=Number, A=Array, D=Dict string data_string; - int data_number; + int64_t data_number; vector data_array; dict data_dict; vector data_dict_keys; @@ -206,6 +206,38 @@ struct JsonNode } }; +Const json_parse_attr_param_value(JsonNode *node) +{ + Const value; + + if (node->type == 'S') { + string &s = node->data_string; + size_t cursor = s.find_first_not_of("01xz"); + if (cursor == string::npos) { + value = Const::from_string(s); + } else if (s.find_first_not_of(' ', cursor) == string::npos) { + value = Const(s.substr(0, GetSize(s)-1)); + } else { + value = Const(s); + } + } else + if (node->type == 'N') { + value = Const(node->data_number, 32); + if (node->data_number < 0) + value.flags |= RTLIL::CONST_FLAG_SIGNED; + } else + if (node->type == 'A') { + log_error("JSON attribute or parameter value is an array.\n"); + } else + if (node->type == 'D') { + log_error("JSON attribute or parameter value is a dict.\n"); + } else { + log_abort(); + } + + return value; +} + void json_parse_attr_param(dict &results, JsonNode *node) { if (node->type != 'D') @@ -214,28 +246,7 @@ void json_parse_attr_param(dict &results, JsonNode *node) for (auto it : node->data_dict) { IdString key = RTLIL::escape_id(it.first.c_str()); - JsonNode *value_node = it.second; - Const value; - - if (value_node->type == 'S') { - string &s = value_node->data_string; - if (s.find_first_not_of("01xz") == string::npos) - value = Const::from_string(s); - else - value = Const(s); - } else - if (value_node->type == 'N') { - value = Const(value_node->data_number, 32); - } else - if (value_node->type == 'A') { - log_error("JSON attribute or parameter value is an array.\n"); - } else - if (value_node->type == 'D') { - log_error("JSON attribute or parameter value is a dict.\n"); - } else { - log_abort(); - } - + Const value = json_parse_attr_param_value(it.second); results[key] = value; } } diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 2bf99e58e..c5eef4b55 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -19,6 +19,7 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" +#include "kernel/celltypes.h" #include "kernel/log.h" #include #include @@ -111,9 +112,10 @@ string get_full_netlist_name(Netlist *nl) // ================================================================== -VerificImporter::VerificImporter(bool mode_gates, bool mode_keep, bool mode_nosva, bool mode_names, bool mode_verific, bool mode_autocover) : +VerificImporter::VerificImporter(bool mode_gates, bool mode_keep, bool mode_nosva, bool mode_names, bool mode_verific, bool mode_autocover, bool mode_fullinit) : mode_gates(mode_gates), mode_keep(mode_keep), mode_nosva(mode_nosva), - mode_names(mode_names), mode_verific(mode_verific), mode_autocover(mode_autocover) + mode_names(mode_names), mode_verific(mode_verific), mode_autocover(mode_autocover), + mode_fullinit(mode_fullinit) { } @@ -1454,6 +1456,50 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se merge_past_ffs(past_ffs); } + + if (!mode_fullinit) + { + pool non_ff_bits; + CellTypes ff_types; + + ff_types.setup_internals_ff(); + ff_types.setup_stdcells_mem(); + + for (auto cell : module->cells()) + { + if (ff_types.cell_known(cell->type)) + continue; + + for (auto conn : cell->connections()) + { + if (!cell->output(conn.first)) + continue; + + for (auto bit : conn.second) + if (bit.wire != nullptr) + non_ff_bits.insert(bit); + } + } + + for (auto wire : module->wires()) + { + if (!wire->attributes.count("\\init")) + continue; + + Const &initval = wire->attributes.at("\\init"); + for (int i = 0; i < GetSize(initval); i++) + { + if (initval[i] != State::S0 && initval[i] != State::S1) + continue; + + if (non_ff_bits.count(SigBit(wire, i))) + initval[i] = State::Sx; + } + + if (initval.is_fully_undef()) + wire->attributes.erase("\\init"); + } + } } // ================================================================== @@ -1743,7 +1789,7 @@ struct VerificExtNets new_net = new Net(name.c_str()); nl->Add(new_net); - Net *n = route_up(new_net, port->IsOutput(), ca_nl, ca_net); + Net *n YS_ATTRIBUTE(unused) = route_up(new_net, port->IsOutput(), ca_nl, ca_net); log_assert(n == ca_net); } @@ -1829,7 +1875,7 @@ void verific_import(Design *design, const std::map &par while (!nl_todo.empty()) { Netlist *nl = *nl_todo.begin(); if (nl_done.count(nl) == 0) { - VerificImporter importer(false, false, false, false, false, false); + VerificImporter importer(false, false, false, false, false, false, false); importer.import_netlist(design, nl, nl_todo); } nl_todo.erase(nl); @@ -1952,6 +1998,9 @@ struct VerificPass : public Pass { log(" -autocover\n"); log(" Generate automatic cover statements for all asserts\n"); log("\n"); + log(" -fullinit\n"); + log(" Keep all register initializations, even those for non-FF registers.\n"); + log("\n"); log(" -chparam name value \n"); log(" Elaborate the specified top modules (all modules when -all given) using\n"); log(" this parameter value. Modules on which this parameter does not exist will\n"); @@ -2140,7 +2189,7 @@ struct VerificPass : public Pass { veri_file::DefineMacro("VERIFIC"); veri_file::DefineMacro(args[argidx] == "-formal" ? "FORMAL" : "SYNTHESIS"); - for (argidx++; argidx < GetSize(args) && GetSize(args[argidx]) >= 2 && args[argidx].substr(0, 2) == "-D"; argidx++) { + for (argidx++; argidx < GetSize(args) && GetSize(args[argidx]) >= 2 && args[argidx].compare(0, 2, "-D") == 0; argidx++) { std::string name = args[argidx].substr(2); if (args[argidx] == "-D") { if (++argidx >= GetSize(args)) @@ -2213,7 +2262,7 @@ struct VerificPass : public Pass { std::set nl_todo, nl_done; bool mode_all = false, mode_gates = false, mode_keep = false; bool mode_nosva = false, mode_names = false, mode_verific = false; - bool mode_autocover = false; + bool mode_autocover = false, mode_fullinit = false; bool flatten = false, extnets = false; string dumpfile; Map parameters(STRING_HASH); @@ -2255,6 +2304,10 @@ struct VerificPass : public Pass { mode_autocover = true; continue; } + if (args[argidx] == "-fullinit") { + mode_fullinit = true; + continue; + } if (args[argidx] == "-chparam" && argidx+2 < GetSize(args)) { const std::string &key = args[++argidx]; const std::string &value = args[++argidx]; @@ -2283,7 +2336,7 @@ struct VerificPass : public Pass { break; } - if (argidx > GetSize(args) && args[argidx].substr(0, 1) == "-") + if (argidx > GetSize(args) && args[argidx].compare(0, 1, "-") == 0) cmd_error(args, argidx, "unknown option"); if (mode_all) @@ -2378,7 +2431,7 @@ struct VerificPass : public Pass { Netlist *nl = *nl_todo.begin(); if (nl_done.count(nl) == 0) { VerificImporter importer(mode_gates, mode_keep, mode_nosva, - mode_names, mode_verific, mode_autocover); + mode_names, mode_verific, mode_autocover, mode_fullinit); importer.import_netlist(design, nl, nl_todo); } nl_todo.erase(nl); @@ -2484,7 +2537,7 @@ struct ReadPass : public Pass { args[0] = "verific"; } else { args[0] = "read_verilog"; - args.erase(args.begin()+1, args.begin()+2); + args[1] = "-defer"; } Pass::call(design, args); return; @@ -2498,6 +2551,7 @@ struct ReadPass : public Pass { if (args[1] == "-formal") args.insert(args.begin()+1, std::string()); args[1] = "-sv"; + args.insert(args.begin()+1, "-defer"); } Pass::call(design, args); return; diff --git a/frontends/verific/verific.h b/frontends/verific/verific.h index 88a6cc0ba..5cbd78f7b 100644 --- a/frontends/verific/verific.h +++ b/frontends/verific/verific.h @@ -72,9 +72,9 @@ struct VerificImporter pool any_all_nets; bool mode_gates, mode_keep, mode_nosva, mode_names, mode_verific; - bool mode_autocover; + bool mode_autocover, mode_fullinit; - VerificImporter(bool mode_gates, bool mode_keep, bool mode_nosva, bool mode_names, bool mode_verific, bool mode_autocover); + VerificImporter(bool mode_gates, bool mode_keep, bool mode_nosva, bool mode_names, bool mode_verific, bool mode_autocover, bool mode_fullinit); RTLIL::SigBit net_map_at(Verific::Net *net); diff --git a/frontends/verific/verificsva.cc b/frontends/verific/verificsva.cc index 8ea8372d3..909e9b4f1 100644 --- a/frontends/verific/verificsva.cc +++ b/frontends/verific/verificsva.cc @@ -357,7 +357,7 @@ struct SvaFsm for (int i = 0; i < GetSize(nodes); i++) { if (next_state_sig[i] != State::S0) { - clocking.addDff(NEW_ID, next_state_sig[i], state_wire[i], Const(0, 1)); + clocking.addDff(NEW_ID, next_state_sig[i], state_wire[i], State::S0); } else { module->connect(state_wire[i], State::S0); } diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index f6a17b242..4bf5b1cf5 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -99,7 +99,7 @@ static void my_strtobin(std::vector &data, const char *str, int le if (base == 10) { while (!digits.empty()) - data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0); + data.push_back(my_decimal_div_by_two(digits) ? State::S1 : State::S0); } else { int bits_per_digit = my_ilog2(base-1); for (auto it = digits.rbegin(), e = digits.rend(); it != e; it++) { @@ -115,17 +115,17 @@ static void my_strtobin(std::vector &data, const char *str, int le else if (*it == 0xf2) data.push_back(RTLIL::Sa); else - data.push_back((*it & bitmask) ? RTLIL::S1 : RTLIL::S0); + data.push_back((*it & bitmask) ? State::S1 : State::S0); } } } int len = GetSize(data); - RTLIL::State msb = data.empty() ? RTLIL::S0 : data.back(); + RTLIL::State msb = data.empty() ? State::S0 : data.back(); if (len_in_bits < 0) { if (len < 32) - data.resize(32, msb == RTLIL::S0 || msb == RTLIL::S1 ? RTLIL::S0 : msb); + data.resize(32, msb == State::S0 || msb == State::S1 ? RTLIL::S0 : msb); return; } @@ -133,11 +133,11 @@ static void my_strtobin(std::vector &data, const char *str, int le log_file_error(current_filename, get_line_num(), "Unsized constant must have width of 1 bit, but have %d bits!\n", len); for (len = len - 1; len >= 0; len--) - if (data[len] == RTLIL::S1) + if (data[len] == State::S1) break; - if (msb == RTLIL::S0 || msb == RTLIL::S1) { + if (msb == State::S0 || msb == State::S1) { len += 1; - data.resize(len_in_bits, RTLIL::S0); + data.resize(len_in_bits, State::S0); } else { len += 2; data.resize(len_in_bits, msb); @@ -169,7 +169,7 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn for (int i = 0; i < len; i++) { unsigned char ch = str[len - i]; for (int j = 0; j < 8; j++) { - data.push_back((ch & 1) ? RTLIL::S1 : RTLIL::S0); + data.push_back((ch & 1) ? State::S1 : State::S0); ch = ch >> 1; } } @@ -190,8 +190,8 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn if (*endptr == 0) { std::vector data; my_strtobin(data, str, -1, 10, case_type, false); - if (data.back() == RTLIL::S1) - data.push_back(RTLIL::S0); + if (data.back() == State::S1) + data.push_back(State::S0); return AstNode::mkconst_bits(data, true); } @@ -237,8 +237,8 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn } } if (len_in_bits < 0) { - if (is_signed && data.back() == RTLIL::S1) - data.push_back(RTLIL::S0); + if (is_signed && data.back() == State::S1) + data.push_back(State::S0); } return AstNode::mkconst_bits(data, is_signed, is_unsized); } diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 951d9c66f..57e55b1f4 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -70,6 +70,9 @@ YOSYS_NAMESPACE_END #define YY_INPUT(buf,result,max_size) \ result = readsome(*VERILOG_FRONTEND::lexin, buf, max_size) +#undef YY_BUF_SIZE +#define YY_BUF_SIZE 65536 + %} %option yylineno diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 0fec445fa..4afd72b73 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -274,7 +274,7 @@ hierarchical_id: $$ = $1; } | hierarchical_id TOK_PACKAGESEP TOK_ID { - if ($3->substr(0, 1) == "\\") + if ($3->compare(0, 1, "\\") == 0) *$1 += "::" + $3->substr(1); else *$1 += "::" + *$3; @@ -282,7 +282,7 @@ hierarchical_id: $$ = $1; } | hierarchical_id '.' TOK_ID { - if ($3->substr(0, 1) == "\\") + if ($3->compare(0, 1, "\\") == 0) *$1 += "." + $3->substr(1); else *$1 += "." + *$3; @@ -2184,7 +2184,7 @@ basic_expr: $$ = $1; } | '(' expr ')' TOK_CONSTVAL { - if ($4->substr(0, 1) != "'") + if ($4->compare(0, 1, "'") != 0) frontend_verilog_yyerror("Cast operation must be applied on sized constants e.g. () , while %s is not a sized constant.", $4->c_str()); AstNode *bits = $2; AstNode *val = const2ast(*$4, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode); @@ -2194,7 +2194,7 @@ basic_expr: delete $4; } | hierarchical_id TOK_CONSTVAL { - if ($2->substr(0, 1) != "'") + if ($2->compare(0, 1, "'") != 0) frontend_verilog_yyerror("Cast operation must be applied on sized constants, e.g. \'d0, while %s is not a sized constant.", $2->c_str()); AstNode *bits = new AstNode(AST_IDENTIFIER); bits->str = *$1; diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc index 26c625f89..02854edb2 100644 --- a/kernel/cellaigs.cc +++ b/kernel/cellaigs.cc @@ -268,9 +268,9 @@ Aig::Aig(Cell *cell) cell->parameters.sort(); for (auto p : cell->parameters) { - if (p.first == "\\A_WIDTH" && mkname_a_signed) { + if (p.first == ID(A_WIDTH) && mkname_a_signed) { name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U'); - } else if (p.first == "\\B_WIDTH" && mkname_b_signed) { + } else if (p.first == ID(B_WIDTH) && mkname_b_signed) { name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U'); } else { mkname_last = name; @@ -280,181 +280,183 @@ Aig::Aig(Cell *cell) mkname_a_signed = false; mkname_b_signed = false; mkname_is_signed = false; - if (p.first == "\\A_SIGNED") { + if (p.first == ID(A_SIGNED)) { mkname_a_signed = true; mkname_is_signed = p.second.as_bool(); } - if (p.first == "\\B_SIGNED") { + if (p.first == ID(B_SIGNED)) { mkname_b_signed = true; mkname_is_signed = p.second.as_bool(); } } - if (cell->type.in("$not", "$_NOT_", "$pos", "$_BUF_")) + if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($_BUF_))) { - for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) { - int A = mk.inport("\\A", i); - int Y = cell->type.in("$not", "$_NOT_") ? mk.not_gate(A) : A; - mk.outport(Y, "\\Y", i); + for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) { + int A = mk.inport(ID::A, i); + int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A; + mk.outport(Y, ID::Y, i); } goto optimize; } - if (cell->type.in("$and", "$_AND_", "$_NAND_", "$or", "$_OR_", "$_NOR_", "$xor", "$xnor", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_")) + if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_), ID($or), ID($_OR_), ID($_NOR_), ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) { - for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) { - int A = mk.inport("\\A", i); - int B = mk.inport("\\B", i); - int Y = cell->type.in("$and", "$_AND_") ? mk.and_gate(A, B) : - cell->type.in("$_NAND_") ? mk.nand_gate(A, B) : - cell->type.in("$or", "$_OR_") ? mk.or_gate(A, B) : - cell->type.in("$_NOR_") ? mk.nor_gate(A, B) : - cell->type.in("$xor", "$_XOR_") ? mk.xor_gate(A, B) : - cell->type.in("$xnor", "$_XNOR_") ? mk.xnor_gate(A, B) : - cell->type.in("$_ANDNOT_") ? mk.andnot_gate(A, B) : - cell->type.in("$_ORNOT_") ? mk.ornot_gate(A, B) : -1; - mk.outport(Y, "\\Y", i); + for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) { + int A = mk.inport(ID::A, i); + int B = mk.inport(ID::B, i); + int Y = cell->type.in(ID($and), ID($_AND_)) ? mk.and_gate(A, B) : + cell->type.in(ID($_NAND_)) ? mk.nand_gate(A, B) : + cell->type.in(ID($or), ID($_OR_)) ? mk.or_gate(A, B) : + cell->type.in(ID($_NOR_)) ? mk.nor_gate(A, B) : + cell->type.in(ID($xor), ID($_XOR_)) ? mk.xor_gate(A, B) : + cell->type.in(ID($xnor), ID($_XNOR_)) ? mk.xnor_gate(A, B) : + cell->type.in(ID($_ANDNOT_)) ? mk.andnot_gate(A, B) : + cell->type.in(ID($_ORNOT_)) ? mk.ornot_gate(A, B) : -1; + mk.outport(Y, ID::Y, i); } goto optimize; } - if (cell->type.in("$mux", "$_MUX_")) + if (cell->type.in(ID($mux), ID($_MUX_))) { - int S = mk.inport("\\S"); - for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) { - int A = mk.inport("\\A", i); - int B = mk.inport("\\B", i); + int S = mk.inport(ID(S)); + for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) { + int A = mk.inport(ID::A, i); + int B = mk.inport(ID::B, i); int Y = mk.mux_gate(A, B, S); - mk.outport(Y, "\\Y", i); + if (cell->type == ID($_NMUX_)) + Y = mk.not_gate(Y); + mk.outport(Y, ID::Y, i); } goto optimize; } - if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool")) + if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) { - int Y = mk.inport("\\A", 0); - for (int i = 1; i < GetSize(cell->getPort("\\A")); i++) { - int A = mk.inport("\\A", i); - if (cell->type == "$reduce_and") Y = mk.and_gate(A, Y); - if (cell->type == "$reduce_or") Y = mk.or_gate(A, Y); - if (cell->type == "$reduce_bool") Y = mk.or_gate(A, Y); - if (cell->type == "$reduce_xor") Y = mk.xor_gate(A, Y); - if (cell->type == "$reduce_xnor") Y = mk.xor_gate(A, Y); + int Y = mk.inport(ID::A, 0); + for (int i = 1; i < GetSize(cell->getPort(ID::A)); i++) { + int A = mk.inport(ID::A, i); + if (cell->type == ID($reduce_and)) Y = mk.and_gate(A, Y); + if (cell->type == ID($reduce_or)) Y = mk.or_gate(A, Y); + if (cell->type == ID($reduce_bool)) Y = mk.or_gate(A, Y); + if (cell->type == ID($reduce_xor)) Y = mk.xor_gate(A, Y); + if (cell->type == ID($reduce_xnor)) Y = mk.xor_gate(A, Y); } - if (cell->type == "$reduce_xnor") + if (cell->type == ID($reduce_xnor)) Y = mk.not_gate(Y); - mk.outport(Y, "\\Y", 0); - for (int i = 1; i < GetSize(cell->getPort("\\Y")); i++) - mk.outport(mk.bool_node(false), "\\Y", i); + mk.outport(Y, ID::Y, 0); + for (int i = 1; i < GetSize(cell->getPort(ID::Y)); i++) + mk.outport(mk.bool_node(false), ID::Y, i); goto optimize; } - if (cell->type.in("$logic_not", "$logic_and", "$logic_or")) + if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or))) { - int A = mk.inport("\\A", 0), Y = -1; - for (int i = 1; i < GetSize(cell->getPort("\\A")); i++) - A = mk.or_gate(mk.inport("\\A", i), A); - if (cell->type.in("$logic_and", "$logic_or")) { - int B = mk.inport("\\B", 0); - for (int i = 1; i < GetSize(cell->getPort("\\B")); i++) - B = mk.or_gate(mk.inport("\\B", i), B); - if (cell->type == "$logic_and") Y = mk.and_gate(A, B); - if (cell->type == "$logic_or") Y = mk.or_gate(A, B); + int A = mk.inport(ID::A, 0), Y = -1; + for (int i = 1; i < GetSize(cell->getPort(ID::A)); i++) + A = mk.or_gate(mk.inport(ID::A, i), A); + if (cell->type.in(ID($logic_and), ID($logic_or))) { + int B = mk.inport(ID::B, 0); + for (int i = 1; i < GetSize(cell->getPort(ID::B)); i++) + B = mk.or_gate(mk.inport(ID::B, i), B); + if (cell->type == ID($logic_and)) Y = mk.and_gate(A, B); + if (cell->type == ID($logic_or)) Y = mk.or_gate(A, B); } else { - if (cell->type == "$logic_not") Y = mk.not_gate(A); + if (cell->type == ID($logic_not)) Y = mk.not_gate(A); } - mk.outport_bool(Y, "\\Y"); + mk.outport_bool(Y, ID::Y); goto optimize; } - if (cell->type.in("$add", "$sub")) + if (cell->type.in(ID($add), ID($sub))) { - int width = GetSize(cell->getPort("\\Y")); - vector A = mk.inport_vec("\\A", width); - vector B = mk.inport_vec("\\B", width); + int width = GetSize(cell->getPort(ID::Y)); + vector A = mk.inport_vec(ID::A, width); + vector B = mk.inport_vec(ID::B, width); int carry = mk.bool_node(false); - if (cell->type == "$sub") { + if (cell->type == ID($sub)) { for (auto &n : B) n = mk.not_gate(n); carry = mk.not_gate(carry); } vector Y = mk.adder(A, B, carry); - mk.outport_vec(Y, "\\Y"); + mk.outport_vec(Y, ID::Y); goto optimize; } - if (cell->type == "$alu") + if (cell->type == ID($alu)) { - int width = GetSize(cell->getPort("\\Y")); - vector A = mk.inport_vec("\\A", width); - vector B = mk.inport_vec("\\B", width); - int carry = mk.inport("\\CI"); - int binv = mk.inport("\\BI"); + int width = GetSize(cell->getPort(ID::Y)); + vector A = mk.inport_vec(ID::A, width); + vector B = mk.inport_vec(ID::B, width); + int carry = mk.inport(ID(CI)); + int binv = mk.inport(ID(BI)); for (auto &n : B) n = mk.xor_gate(n, binv); vector X(width), CO(width); vector Y = mk.adder(A, B, carry, &X, &CO); for (int i = 0; i < width; i++) X[i] = mk.xor_gate(A[i], B[i]); - mk.outport_vec(Y, "\\Y"); - mk.outport_vec(X, "\\X"); - mk.outport_vec(CO, "\\CO"); + mk.outport_vec(Y, ID::Y); + mk.outport_vec(X, ID(X)); + mk.outport_vec(CO, ID(CO)); goto optimize; } - if (cell->type.in("$eq", "$ne")) + if (cell->type.in(ID($eq), ID($ne))) { - int width = max(GetSize(cell->getPort("\\A")), GetSize(cell->getPort("\\B"))); - vector A = mk.inport_vec("\\A", width); - vector B = mk.inport_vec("\\B", width); + int width = max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::B))); + vector A = mk.inport_vec(ID::A, width); + vector B = mk.inport_vec(ID::B, width); int Y = mk.bool_node(false); for (int i = 0; i < width; i++) Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i])); - if (cell->type == "$eq") + if (cell->type == ID($eq)) Y = mk.not_gate(Y); - mk.outport_bool(Y, "\\Y"); + mk.outport_bool(Y, ID::Y); goto optimize; } - if (cell->type == "$_AOI3_") + if (cell->type == ID($_AOI3_)) { - int A = mk.inport("\\A"); - int B = mk.inport("\\B"); - int C = mk.inport("\\C"); + int A = mk.inport(ID::A); + int B = mk.inport(ID::B); + int C = mk.inport(ID(C)); int Y = mk.nor_gate(mk.and_gate(A, B), C); - mk.outport(Y, "\\Y"); + mk.outport(Y, ID::Y); goto optimize; } - if (cell->type == "$_OAI3_") + if (cell->type == ID($_OAI3_)) { - int A = mk.inport("\\A"); - int B = mk.inport("\\B"); - int C = mk.inport("\\C"); + int A = mk.inport(ID::A); + int B = mk.inport(ID::B); + int C = mk.inport(ID(C)); int Y = mk.nand_gate(mk.or_gate(A, B), C); - mk.outport(Y, "\\Y"); + mk.outport(Y, ID::Y); goto optimize; } - if (cell->type == "$_AOI4_") + if (cell->type == ID($_AOI4_)) { - int A = mk.inport("\\A"); - int B = mk.inport("\\B"); - int C = mk.inport("\\C"); - int D = mk.inport("\\D"); + int A = mk.inport(ID::A); + int B = mk.inport(ID::B); + int C = mk.inport(ID(C)); + int D = mk.inport(ID(D)); int Y = mk.nor_gate(mk.and_gate(A, B), mk.and_gate(C, D)); - mk.outport(Y, "\\Y"); + mk.outport(Y, ID::Y); goto optimize; } - if (cell->type == "$_OAI4_") + if (cell->type == ID($_OAI4_)) { - int A = mk.inport("\\A"); - int B = mk.inport("\\B"); - int C = mk.inport("\\C"); - int D = mk.inport("\\D"); + int A = mk.inport(ID::A); + int B = mk.inport(ID::B); + int C = mk.inport(ID(C)); + int D = mk.inport(ID(D)); int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D)); - mk.outport(Y, "\\Y"); + mk.outport(Y, ID::Y); goto optimize; } diff --git a/kernel/celledges.cc b/kernel/celledges.cc index 556e8b826..d0bb99e83 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -24,9 +24,9 @@ PRIVATE_NAMESPACE_BEGIN void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = "\\A", Y = "\\Y"; + IdString A = ID::A, Y = ID::Y; - bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); int a_width = GetSize(cell->getPort(A)); int y_width = GetSize(cell->getPort(Y)); @@ -41,14 +41,14 @@ void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = "\\A", B = "\\B", Y = "\\Y"; + IdString A = ID::A, B = ID::B, Y = ID::Y; - bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); int a_width = GetSize(cell->getPort(A)); int b_width = GetSize(cell->getPort(B)); int y_width = GetSize(cell->getPort(Y)); - if (cell->type == "$and" && !is_signed) { + if (cell->type == ID($and) && !is_signed) { if (a_width > b_width) a_width = b_width; else @@ -71,9 +71,9 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = "\\A", Y = "\\Y"; + IdString A = ID::A, Y = ID::Y; - bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); int a_width = GetSize(cell->getPort(A)); int y_width = GetSize(cell->getPort(Y)); @@ -87,14 +87,14 @@ void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = "\\A", B = "\\B", Y = "\\Y"; + IdString A = ID::A, B = ID::B, Y = ID::Y; - bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); int a_width = GetSize(cell->getPort(A)); int b_width = GetSize(cell->getPort(B)); int y_width = GetSize(cell->getPort(Y)); - if (!is_signed && cell->type != "$sub") { + if (!is_signed && cell->type != ID($sub)) { int ab_width = std::max(a_width, b_width); y_width = std::min(y_width, ab_width+1); } @@ -114,7 +114,7 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = "\\A", Y = "\\Y"; + IdString A = ID::A, Y = ID::Y; int a_width = GetSize(cell->getPort(A)); @@ -124,7 +124,7 @@ void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = "\\A", B = "\\B", Y = "\\Y"; + IdString A = ID::A, B = ID::B, Y = ID::Y; int a_width = GetSize(cell->getPort(A)); int b_width = GetSize(cell->getPort(B)); @@ -138,7 +138,7 @@ void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y"; + IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y; int a_width = GetSize(cell->getPort(A)); int b_width = GetSize(cell->getPort(B)); @@ -160,43 +160,43 @@ PRIVATE_NAMESPACE_END bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell) { - if (cell->type.in("$not", "$pos")) { + if (cell->type.in(ID($not), ID($pos))) { bitwise_unary_op(this, cell); return true; } - if (cell->type.in("$and", "$or", "$xor", "$xnor")) { + if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) { bitwise_binary_op(this, cell); return true; } - if (cell->type == "$neg") { + if (cell->type == ID($neg)) { arith_neg_op(this, cell); return true; } - if (cell->type.in("$add", "$sub")) { + if (cell->type.in(ID($add), ID($sub))) { arith_binary_op(this, cell); return true; } - if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", "$logic_not")) { + if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) { reduce_op(this, cell); return true; } // FIXME: - // if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx")) { + // if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { // shift_op(this, cell); // return true; // } - if (cell->type.in("$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt")) { + if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) { compare_op(this, cell); return true; } - if (cell->type.in("$mux", "$pmux")) { + if (cell->type.in(ID($mux), ID($pmux))) { mux_op(this, cell); return true; } diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 758661c02..bc96fd602 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -84,46 +84,46 @@ struct CellTypes { setup_internals_eval(); - IdString A = "\\A", B = "\\B", EN = "\\EN", Y = "\\Y"; - IdString SRC = "\\SRC", DST = "\\DST", DAT = "\\DAT"; - IdString EN_SRC = "\\EN_SRC", EN_DST = "\\EN_DST"; + IdString A = ID::A, B = ID::B, EN = ID(EN), Y = ID::Y; + IdString SRC = ID(SRC), DST = ID(DST), DAT = ID(DAT); + IdString EN_SRC = ID(EN_SRC), EN_DST = ID(EN_DST); - setup_type("$tribuf", {A, EN}, {Y}, true); + setup_type(ID($tribuf), {A, EN}, {Y}, true); - setup_type("$assert", {A, EN}, pool(), true); - setup_type("$assume", {A, EN}, pool(), true); - setup_type("$live", {A, EN}, pool(), true); - setup_type("$fair", {A, EN}, pool(), true); - setup_type("$cover", {A, EN}, pool(), true); - setup_type("$initstate", pool(), {Y}, true); - setup_type("$anyconst", pool(), {Y}, true); - setup_type("$anyseq", pool(), {Y}, true); - setup_type("$allconst", pool(), {Y}, true); - setup_type("$allseq", pool(), {Y}, true); - setup_type("$equiv", {A, B}, {Y}, true); - setup_type("$specify2", {EN, SRC, DST}, pool(), true); - setup_type("$specify3", {EN, SRC, DST, DAT}, pool(), true); - setup_type("$specrule", {EN_SRC, EN_DST, SRC, DST}, pool(), true); + setup_type(ID($assert), {A, EN}, pool(), true); + setup_type(ID($assume), {A, EN}, pool(), true); + setup_type(ID($live), {A, EN}, pool(), true); + setup_type(ID($fair), {A, EN}, pool(), true); + setup_type(ID($cover), {A, EN}, pool(), true); + setup_type(ID($initstate), pool(), {Y}, true); + setup_type(ID($anyconst), pool(), {Y}, true); + setup_type(ID($anyseq), pool(), {Y}, true); + setup_type(ID($allconst), pool(), {Y}, true); + setup_type(ID($allseq), pool(), {Y}, true); + setup_type(ID($equiv), {A, B}, {Y}, true); + setup_type(ID($specify2), {EN, SRC, DST}, pool(), true); + setup_type(ID($specify3), {EN, SRC, DST, DAT}, pool(), true); + setup_type(ID($specrule), {EN_SRC, EN_DST, SRC, DST}, pool(), true); } void setup_internals_eval() { std::vector unary_ops = { - "$not", "$pos", "$neg", - "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", - "$logic_not", "$slice", "$lut", "$sop" + ID($not), ID($pos), ID($neg), + ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), + ID($logic_not), ID($slice), ID($lut), ID($sop) }; std::vector binary_ops = { - "$and", "$or", "$xor", "$xnor", - "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", - "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", - "$add", "$sub", "$mul", "$div", "$mod", "$pow", - "$logic_and", "$logic_or", "$concat", "$macc" + ID($and), ID($or), ID($xor), ID($xnor), + ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), + 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($pow), + ID($logic_and), ID($logic_or), ID($concat), ID($macc) }; - IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y"; - IdString P = "\\P", G = "\\G", C = "\\C", X = "\\X"; - IdString BI = "\\BI", CI = "\\CI", CO = "\\CO", EN = "\\EN"; + IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y; + IdString P = ID(P), G = ID(G), C = ID(C), X = ID(X); + IdString BI = ID(BI), CI = ID(CI), CO = ID(CO), EN = ID(EN); for (auto type : unary_ops) setup_type(type, {A}, {Y}, true); @@ -131,81 +131,91 @@ struct CellTypes for (auto type : binary_ops) setup_type(type, {A, B}, {Y}, true); - for (auto type : std::vector({"$mux", "$pmux"})) + for (auto type : std::vector({ID($mux), ID($pmux)})) setup_type(type, {A, B, S}, {Y}, true); - setup_type("$lcu", {P, G, CI}, {CO}, true); - setup_type("$alu", {A, B, CI, BI}, {X, Y, CO}, true); - setup_type("$fa", {A, B, C}, {X, Y}, true); + setup_type(ID($lcu), {P, G, CI}, {CO}, true); + setup_type(ID($alu), {A, B, CI, BI}, {X, Y, CO}, true); + setup_type(ID($fa), {A, B, C}, {X, Y}, true); + } + + void setup_internals_ff() + { + IdString SET = ID(SET), CLR = ID(CLR), CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN); + IdString Q = ID(Q), D = ID(D); + + setup_type(ID($sr), {SET, CLR}, {Q}); + setup_type(ID($ff), {D}, {Q}); + setup_type(ID($dff), {CLK, D}, {Q}); + setup_type(ID($dffe), {CLK, EN, D}, {Q}); + setup_type(ID($dffsr), {CLK, SET, CLR, D}, {Q}); + setup_type(ID($adff), {CLK, ARST, D}, {Q}); + setup_type(ID($dlatch), {EN, D}, {Q}); + setup_type(ID($dlatchsr), {EN, SET, CLR, D}, {Q}); + } void setup_internals_mem() { - IdString SET = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN"; - IdString Q = "\\Q", D = "\\D", ADDR = "\\ADDR", DATA = "\\DATA", RD_EN = "\\RD_EN"; - IdString RD_CLK = "\\RD_CLK", RD_ADDR = "\\RD_ADDR", WR_CLK = "\\WR_CLK", WR_EN = "\\WR_EN"; - IdString WR_ADDR = "\\WR_ADDR", WR_DATA = "\\WR_DATA", RD_DATA = "\\RD_DATA"; - IdString CTRL_IN = "\\CTRL_IN", CTRL_OUT = "\\CTRL_OUT"; + setup_internals_ff(); - setup_type("$sr", {SET, CLR}, {Q}); - setup_type("$ff", {D}, {Q}); - setup_type("$dff", {CLK, D}, {Q}); - setup_type("$dffe", {CLK, EN, D}, {Q}); - setup_type("$dffsr", {CLK, SET, CLR, D}, {Q}); - setup_type("$adff", {CLK, ARST, D}, {Q}); - setup_type("$dlatch", {EN, D}, {Q}); - setup_type("$dlatchsr", {EN, SET, CLR, D}, {Q}); + IdString CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN); + IdString ADDR = ID(ADDR), DATA = ID(DATA), RD_EN = ID(RD_EN); + IdString RD_CLK = ID(RD_CLK), RD_ADDR = ID(RD_ADDR), WR_CLK = ID(WR_CLK), WR_EN = ID(WR_EN); + IdString WR_ADDR = ID(WR_ADDR), WR_DATA = ID(WR_DATA), RD_DATA = ID(RD_DATA); + IdString CTRL_IN = ID(CTRL_IN), CTRL_OUT = ID(CTRL_OUT); - setup_type("$memrd", {CLK, EN, ADDR}, {DATA}); - setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool()); - setup_type("$meminit", {ADDR, DATA}, pool()); - setup_type("$mem", {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA}); + setup_type(ID($memrd), {CLK, EN, ADDR}, {DATA}); + setup_type(ID($memwr), {CLK, EN, ADDR, DATA}, pool()); + setup_type(ID($meminit), {ADDR, DATA}, pool()); + setup_type(ID($mem), {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA}); - setup_type("$fsm", {CLK, ARST, CTRL_IN}, {CTRL_OUT}); + setup_type(ID($fsm), {CLK, ARST, CTRL_IN}, {CTRL_OUT}); } void setup_stdcells() { setup_stdcells_eval(); - IdString A = "\\A", E = "\\E", Y = "\\Y"; + IdString A = ID::A, E = ID(E), Y = ID::Y; - setup_type("$_TBUF_", {A, E}, {Y}, true); + setup_type(ID($_TBUF_), {A, E}, {Y}, true); } void setup_stdcells_eval() { - IdString A = "\\A", B = "\\B", C = "\\C", D = "\\D"; - IdString E = "\\E", F = "\\F", G = "\\G", H = "\\H"; - IdString I = "\\I", J = "\\J", K = "\\K", L = "\\L"; - IdString M = "\\M", N = "\\N", O = "\\O", P = "\\P"; - IdString S = "\\S", T = "\\T", U = "\\U", V = "\\V"; - IdString Y = "\\Y"; + IdString A = ID::A, B = ID::B, C = ID(C), D = ID(D); + IdString E = ID(E), F = ID(F), G = ID(G), H = ID(H); + IdString I = ID(I), J = ID(J), K = ID(K), L = ID(L); + IdString M = ID(M), N = ID(N), O = ID(O), P = ID(P); + IdString S = ID(S), T = ID(T), U = ID(U), V = ID(V); + IdString Y = ID::Y; - setup_type("$_BUF_", {A}, {Y}, true); - setup_type("$_NOT_", {A}, {Y}, true); - setup_type("$_AND_", {A, B}, {Y}, true); - setup_type("$_NAND_", {A, B}, {Y}, true); - setup_type("$_OR_", {A, B}, {Y}, true); - setup_type("$_NOR_", {A, B}, {Y}, true); - setup_type("$_XOR_", {A, B}, {Y}, true); - setup_type("$_XNOR_", {A, B}, {Y}, true); - setup_type("$_ANDNOT_", {A, B}, {Y}, true); - setup_type("$_ORNOT_", {A, B}, {Y}, true); - setup_type("$_MUX_", {A, B, S}, {Y}, true); - setup_type("$_MUX4_", {A, B, C, D, S, T}, {Y}, true); - setup_type("$_MUX8_", {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true); - setup_type("$_MUX16_", {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true); - setup_type("$_AOI3_", {A, B, C}, {Y}, true); - setup_type("$_OAI3_", {A, B, C}, {Y}, true); - setup_type("$_AOI4_", {A, B, C, D}, {Y}, true); - setup_type("$_OAI4_", {A, B, C, D}, {Y}, true); + setup_type(ID($_BUF_), {A}, {Y}, true); + setup_type(ID($_NOT_), {A}, {Y}, true); + setup_type(ID($_AND_), {A, B}, {Y}, true); + setup_type(ID($_NAND_), {A, B}, {Y}, true); + setup_type(ID($_OR_), {A, B}, {Y}, true); + setup_type(ID($_NOR_), {A, B}, {Y}, true); + setup_type(ID($_XOR_), {A, B}, {Y}, true); + setup_type(ID($_XNOR_), {A, B}, {Y}, true); + setup_type(ID($_ANDNOT_), {A, B}, {Y}, true); + setup_type(ID($_ORNOT_), {A, B}, {Y}, true); + setup_type(ID($_MUX_), {A, B, S}, {Y}, true); + setup_type(ID($_NMUX_), {A, B, S}, {Y}, true); + setup_type(ID($_MUX4_), {A, B, C, D, S, T}, {Y}, true); + setup_type(ID($_MUX8_), {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true); + setup_type(ID($_MUX16_), {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true); + setup_type(ID($_AOI3_), {A, B, C}, {Y}, true); + setup_type(ID($_OAI3_), {A, B, C}, {Y}, true); + setup_type(ID($_AOI4_), {A, B, C, D}, {Y}, true); + setup_type(ID($_OAI4_), {A, B, C, D}, {Y}, true); } void setup_stdcells_mem() { - IdString S = "\\S", R = "\\R", C = "\\C"; - IdString D = "\\D", Q = "\\Q", E = "\\E"; + IdString S = ID(S), R = ID(R), C = ID(C); + IdString D = ID(D), Q = ID(Q), E = ID(E); std::vector list_np = {'N', 'P'}, list_01 = {'0', '1'}; @@ -213,7 +223,7 @@ struct CellTypes for (auto c2 : list_np) setup_type(stringf("$_SR_%c%c_", c1, c2), {S, R}, {Q}); - setup_type("$_FF_", {D}, {Q}); + setup_type(ID($_FF_), {D}, {Q}); for (auto c1 : list_np) setup_type(stringf("$_DFF_%c_", c1), {C, D}, {Q}); @@ -272,20 +282,20 @@ struct CellTypes static RTLIL::Const eval_not(RTLIL::Const v) { for (auto &bit : v.bits) - if (bit == RTLIL::S0) bit = RTLIL::S1; - else if (bit == RTLIL::S1) bit = RTLIL::S0; + if (bit == State::S0) bit = State::S1; + else if (bit == State::S1) bit = State::S0; return v; } static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr) { - if (type == "$sshr" && !signed1) - type = "$shr"; - if (type == "$sshl" && !signed1) - type = "$shl"; + if (type == ID($sshr) && !signed1) + type = ID($shr); + if (type == ID($sshl) && !signed1) + type = ID($shl); - if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" && type != "$shift" && type != "$shiftx" && - type != "$pos" && type != "$neg" && type != "$not") { + if (type != ID($sshr) && type != ID($sshl) && type != ID($shr) && type != ID($shl) && type != ID($shift) && type != ID($shiftx) && + type != ID($pos) && type != ID($neg) && type != ID($not)) { if (!signed1 || !signed2) signed1 = false, signed2 = false; } @@ -328,25 +338,25 @@ struct CellTypes HANDLE_CELL_TYPE(neg) #undef HANDLE_CELL_TYPE - if (type == "$_BUF_") + if (type == ID($_BUF_)) return arg1; - if (type == "$_NOT_") + if (type == ID($_NOT_)) return eval_not(arg1); - if (type == "$_AND_") + if (type == ID($_AND_)) return const_and(arg1, arg2, false, false, 1); - if (type == "$_NAND_") + if (type == ID($_NAND_)) return eval_not(const_and(arg1, arg2, false, false, 1)); - if (type == "$_OR_") + if (type == ID($_OR_)) return const_or(arg1, arg2, false, false, 1); - if (type == "$_NOR_") + if (type == ID($_NOR_)) return eval_not(const_or(arg1, arg2, false, false, 1)); - if (type == "$_XOR_") + if (type == ID($_XOR_)) return const_xor(arg1, arg2, false, false, 1); - if (type == "$_XNOR_") + if (type == ID($_XNOR_)) return const_xnor(arg1, arg2, false, false, 1); - if (type == "$_ANDNOT_") + if (type == ID($_ANDNOT_)) return const_and(arg1, eval_not(arg2), false, false, 1); - if (type == "$_ORNOT_") + if (type == ID($_ORNOT_)) return const_or(arg1, eval_not(arg2), false, false, 1); if (errp != nullptr) { @@ -359,35 +369,35 @@ struct CellTypes static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr) { - if (cell->type == "$slice") { + if (cell->type == ID($slice)) { RTLIL::Const ret; - int width = cell->parameters.at("\\Y_WIDTH").as_int(); - int offset = cell->parameters.at("\\OFFSET").as_int(); + int width = cell->parameters.at(ID(Y_WIDTH)).as_int(); + int offset = cell->parameters.at(ID(OFFSET)).as_int(); ret.bits.insert(ret.bits.end(), arg1.bits.begin()+offset, arg1.bits.begin()+offset+width); return ret; } - if (cell->type == "$concat") { + if (cell->type == ID($concat)) { RTLIL::Const ret = arg1; ret.bits.insert(ret.bits.end(), arg2.bits.begin(), arg2.bits.end()); return ret; } - if (cell->type == "$lut") + if (cell->type == ID($lut)) { - int width = cell->parameters.at("\\WIDTH").as_int(); + int width = cell->parameters.at(ID(WIDTH)).as_int(); - std::vector t = cell->parameters.at("\\LUT").bits; + std::vector t = cell->parameters.at(ID(LUT)).bits; while (GetSize(t) < (1 << width)) - t.push_back(RTLIL::S0); + t.push_back(State::S0); t.resize(1 << width); for (int i = width-1; i >= 0; i--) { RTLIL::State sel = arg1.bits.at(i); std::vector new_t; - if (sel == RTLIL::S0) + if (sel == State::S0) new_t = std::vector(t.begin(), t.begin() + GetSize(t)/2); - else if (sel == RTLIL::S1) + else if (sel == State::S1) new_t = std::vector(t.begin() + GetSize(t)/2, t.end()); else for (int j = 0; j < GetSize(t)/2; j++) @@ -399,14 +409,14 @@ struct CellTypes return t; } - if (cell->type == "$sop") + if (cell->type == ID($sop)) { - int width = cell->parameters.at("\\WIDTH").as_int(); - int depth = cell->parameters.at("\\DEPTH").as_int(); - std::vector t = cell->parameters.at("\\TABLE").bits; + int width = cell->parameters.at(ID(WIDTH)).as_int(); + int depth = cell->parameters.at(ID(DEPTH)).as_int(); + std::vector t = cell->parameters.at(ID(TABLE)).bits; while (GetSize(t) < width*depth*2) - t.push_back(RTLIL::S0); + t.push_back(State::S0); RTLIL::State default_ret = State::S0; @@ -437,15 +447,15 @@ struct CellTypes return default_ret; } - bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool(); - bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool(); - int result_len = cell->parameters.count("\\Y_WIDTH") > 0 ? cell->parameters["\\Y_WIDTH"].as_int() : -1; + bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool(); + bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool(); + int result_len = cell->parameters.count(ID(Y_WIDTH)) > 0 ? cell->parameters[ID(Y_WIDTH)].as_int() : -1; return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp); } static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr) { - if (cell->type.in("$mux", "$pmux", "$_MUX_")) { + if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) { RTLIL::Const ret = arg1; for (size_t i = 0; i < arg3.bits.size(); i++) if (arg3.bits[i] == RTLIL::State::S1) { @@ -455,9 +465,9 @@ struct CellTypes return ret; } - if (cell->type == "$_AOI3_") + if (cell->type == ID($_AOI3_)) return eval_not(const_or(const_and(arg1, arg2, false, false, 1), arg3, false, false, 1)); - if (cell->type == "$_OAI3_") + if (cell->type == ID($_OAI3_)) return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1)); log_assert(arg3.bits.size() == 0); @@ -466,9 +476,9 @@ struct CellTypes static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4, bool *errp = nullptr) { - if (cell->type == "$_AOI4_") + if (cell->type == ID($_AOI4_)) return eval_not(const_or(const_and(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1)); - if (cell->type == "$_OAI4_") + if (cell->type == ID($_OAI4_)) return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_or(arg3, arg4, false, false, 1), false, false, 1)); log_assert(arg4.bits.size() == 0); diff --git a/kernel/consteval.h b/kernel/consteval.h index 154373a8d..7a83d28e7 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -89,12 +89,12 @@ struct ConstEval bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef) { - if (cell->type == "$lcu") + if (cell->type == ID($lcu)) { - RTLIL::SigSpec sig_p = cell->getPort("\\P"); - RTLIL::SigSpec sig_g = cell->getPort("\\G"); - RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); - RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort("\\CO"))); + RTLIL::SigSpec sig_p = cell->getPort(ID(P)); + RTLIL::SigSpec sig_g = cell->getPort(ID(G)); + RTLIL::SigSpec sig_ci = cell->getPort(ID(CI)); + RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort(ID(CO)))); if (sig_co.is_fully_const()) return true; @@ -114,8 +114,8 @@ struct ConstEval bool carry = sig_ci.as_bool(); for (int i = 0; i < GetSize(coval); i++) { - carry = (sig_g[i] == RTLIL::S1) || (sig_p[i] == RTLIL::S1 && carry); - coval.bits[i] = carry ? RTLIL::S1 : RTLIL::S0; + carry = (sig_g[i] == State::S1) || (sig_p[i] == RTLIL::S1 && carry); + coval.bits[i] = carry ? State::S1 : State::S0; } set(sig_co, coval); @@ -128,24 +128,24 @@ struct ConstEval RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; - log_assert(cell->hasPort("\\Y")); - sig_y = values_map(assign_map(cell->getPort("\\Y"))); + log_assert(cell->hasPort(ID::Y)); + sig_y = values_map(assign_map(cell->getPort(ID::Y))); if (sig_y.is_fully_const()) return true; - if (cell->hasPort("\\S")) { - sig_s = cell->getPort("\\S"); + if (cell->hasPort(ID(S))) { + sig_s = cell->getPort(ID(S)); if (!eval(sig_s, undef, cell)) return false; } - if (cell->hasPort("\\A")) - sig_a = cell->getPort("\\A"); + if (cell->hasPort(ID::A)) + sig_a = cell->getPort(ID::A); - if (cell->hasPort("\\B")) - sig_b = cell->getPort("\\B"); + if (cell->hasPort(ID::B)) + sig_b = cell->getPort(ID::B); - if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_") + if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_))) { std::vector y_candidates; int count_maybe_set_s_bits = 0; @@ -175,7 +175,10 @@ struct ConstEval for (auto &yc : y_candidates) { if (!eval(yc, undef, cell)) return false; - y_values.push_back(yc.as_const()); + if (cell->type == ID($_NMUX_)) + y_values.push_back(RTLIL::const_not(yc.as_const(), Const(), false, false, GetSize(yc))); + else + y_values.push_back(yc.as_const()); } if (y_values.size() > 1) @@ -195,10 +198,10 @@ struct ConstEval else set(sig_y, y_values.front()); } - else if (cell->type == "$fa") + else if (cell->type == ID($fa)) { - RTLIL::SigSpec sig_c = cell->getPort("\\C"); - RTLIL::SigSpec sig_x = cell->getPort("\\X"); + RTLIL::SigSpec sig_c = cell->getPort(ID(C)); + RTLIL::SigSpec sig_x = cell->getPort(ID(X)); int width = GetSize(sig_c); if (!eval(sig_a, undef, cell)) @@ -224,13 +227,13 @@ struct ConstEval set(sig_y, val_y); set(sig_x, val_x); } - else if (cell->type == "$alu") + else if (cell->type == ID($alu)) { - bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool(); - bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool(); + bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool(); + bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool(); - RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); - RTLIL::SigSpec sig_bi = cell->getPort("\\BI"); + RTLIL::SigSpec sig_ci = cell->getPort(ID(CI)); + RTLIL::SigSpec sig_bi = cell->getPort(ID(BI)); if (!eval(sig_a, undef, cell)) return false; @@ -244,15 +247,15 @@ struct ConstEval if (!eval(sig_bi, undef, cell)) return false; - RTLIL::SigSpec sig_x = cell->getPort("\\X"); - RTLIL::SigSpec sig_co = cell->getPort("\\CO"); + RTLIL::SigSpec sig_x = cell->getPort(ID(X)); + RTLIL::SigSpec sig_co = cell->getPort(ID(CO)); bool any_input_undef = !(sig_a.is_fully_def() && sig_b.is_fully_def() && sig_ci.is_fully_def() && sig_bi.is_fully_def()); sig_a.extend_u0(GetSize(sig_y), signed_a); sig_b.extend_u0(GetSize(sig_y), signed_b); - bool carry = sig_ci[0] == RTLIL::S1; - bool b_inv = sig_bi[0] == RTLIL::S1; + bool carry = sig_ci[0] == State::S1; + bool b_inv = sig_bi[0] == State::S1; for (int i = 0; i < GetSize(sig_y); i++) { @@ -261,26 +264,26 @@ struct ConstEval if (!x_inputs.is_fully_def()) { set(sig_x[i], RTLIL::Sx); } else { - bool bit_a = sig_a[i] == RTLIL::S1; - bool bit_b = (sig_b[i] == RTLIL::S1) != b_inv; + bool bit_a = sig_a[i] == State::S1; + bool bit_b = (sig_b[i] == State::S1) != b_inv; bool bit_x = bit_a != bit_b; - set(sig_x[i], bit_x ? RTLIL::S1 : RTLIL::S0); + set(sig_x[i], bit_x ? State::S1 : State::S0); } if (any_input_undef) { set(sig_y[i], RTLIL::Sx); set(sig_co[i], RTLIL::Sx); } else { - bool bit_a = sig_a[i] == RTLIL::S1; - bool bit_b = (sig_b[i] == RTLIL::S1) != b_inv; + bool bit_a = sig_a[i] == State::S1; + bool bit_b = (sig_b[i] == State::S1) != b_inv; bool bit_y = (bit_a != bit_b) != carry; carry = (bit_a && bit_b) || (bit_a && carry) || (bit_b && carry); - set(sig_y[i], bit_y ? RTLIL::S1 : RTLIL::S0); - set(sig_co[i], carry ? RTLIL::S1 : RTLIL::S0); + set(sig_y[i], bit_y ? State::S1 : State::S0); + set(sig_co[i], carry ? State::S1 : State::S0); } } } - else if (cell->type == "$macc") + else if (cell->type == ID($macc)) { Macc macc; macc.from_cell(cell); @@ -295,21 +298,21 @@ struct ConstEval return false; } - RTLIL::Const result(0, GetSize(cell->getPort("\\Y"))); + RTLIL::Const result(0, GetSize(cell->getPort(ID::Y))); if (!macc.eval(result)) log_abort(); - set(cell->getPort("\\Y"), result); + set(cell->getPort(ID::Y), result); } else { RTLIL::SigSpec sig_c, sig_d; - if (cell->type.in("$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_")) { - if (cell->hasPort("\\C")) - sig_c = cell->getPort("\\C"); - if (cell->hasPort("\\D")) - sig_d = cell->getPort("\\D"); + if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) { + if (cell->hasPort(ID(C))) + sig_c = cell->getPort(ID(C)); + if (cell->hasPort(ID(D))) + sig_d = cell->getPort(ID(D)); } if (sig_a.size() > 0 && !eval(sig_a, undef, cell)) diff --git a/kernel/cost.h b/kernel/cost.h index 41a09eb63..ea2a4c1f0 100644 --- a/kernel/cost.h +++ b/kernel/cost.h @@ -24,62 +24,92 @@ YOSYS_NAMESPACE_BEGIN -int get_cell_cost(RTLIL::Cell *cell, dict *mod_cost_cache = nullptr); - -inline int get_cell_cost(RTLIL::IdString type, const dict ¶meters = dict(), - RTLIL::Design *design = nullptr, dict *mod_cost_cache = nullptr) +struct CellCosts { - static dict gate_cost = { - { "$_BUF_", 1 }, - { "$_NOT_", 2 }, - { "$_AND_", 4 }, - { "$_NAND_", 4 }, - { "$_OR_", 4 }, - { "$_NOR_", 4 }, - { "$_ANDNOT_", 4 }, - { "$_ORNOT_", 4 }, - { "$_XOR_", 8 }, - { "$_XNOR_", 8 }, - { "$_AOI3_", 6 }, - { "$_OAI3_", 6 }, - { "$_AOI4_", 8 }, - { "$_OAI4_", 8 }, - { "$_MUX_", 4 } - }; - - if (gate_cost.count(type)) - return gate_cost.at(type); - - if (parameters.empty() && design && design->module(type)) - { - RTLIL::Module *mod = design->module(type); - - if (mod->attributes.count("\\cost")) - return mod->attributes.at("\\cost").as_int(); - - dict local_mod_cost_cache; - if (mod_cost_cache == nullptr) - mod_cost_cache = &local_mod_cost_cache; - - if (mod_cost_cache->count(mod->name)) - return mod_cost_cache->at(mod->name); - - int module_cost = 1; - for (auto c : mod->cells()) - module_cost += get_cell_cost(c, mod_cost_cache); - - (*mod_cost_cache)[mod->name] = module_cost; - return module_cost; + static const dict& default_gate_cost() { + static const dict db = { + { ID($_BUF_), 1 }, + { ID($_NOT_), 2 }, + { ID($_AND_), 4 }, + { ID($_NAND_), 4 }, + { ID($_OR_), 4 }, + { ID($_NOR_), 4 }, + { ID($_ANDNOT_), 4 }, + { ID($_ORNOT_), 4 }, + { ID($_XOR_), 5 }, + { ID($_XNOR_), 5 }, + { ID($_AOI3_), 6 }, + { ID($_OAI3_), 6 }, + { ID($_AOI4_), 7 }, + { ID($_OAI4_), 7 }, + { ID($_MUX_), 4 }, + { ID($_NMUX_), 4 } + }; + return db; } - log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(type), GetSize(parameters)); - return 1; -} + static const dict& cmos_gate_cost() { + static const dict db = { + { ID($_BUF_), 1 }, + { ID($_NOT_), 2 }, + { ID($_AND_), 6 }, + { ID($_NAND_), 4 }, + { ID($_OR_), 6 }, + { ID($_NOR_), 4 }, + { ID($_ANDNOT_), 6 }, + { ID($_ORNOT_), 6 }, + { ID($_XOR_), 12 }, + { ID($_XNOR_), 12 }, + { ID($_AOI3_), 6 }, + { ID($_OAI3_), 6 }, + { ID($_AOI4_), 8 }, + { ID($_OAI4_), 8 }, + { ID($_MUX_), 12 }, + { ID($_NMUX_), 10 } + }; + return db; + } -inline int get_cell_cost(RTLIL::Cell *cell, dict *mod_cost_cache) -{ - return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache); -} + dict mod_cost_cache; + const dict *gate_cost = nullptr; + Design *design = nullptr; + + int get(RTLIL::IdString type) const + { + if (gate_cost && gate_cost->count(type)) + return gate_cost->at(type); + + log_warning("Can't determine cost of %s cell.\n", log_id(type)); + return 1; + } + + int get(RTLIL::Cell *cell) + { + if (gate_cost && gate_cost->count(cell->type)) + return gate_cost->at(cell->type); + + if (design && design->module(cell->type) && cell->parameters.empty()) + { + RTLIL::Module *mod = design->module(cell->type); + + if (mod->attributes.count(ID(cost))) + return mod->attributes.at(ID(cost)).as_int(); + + if (mod_cost_cache.count(mod->name)) + return mod_cost_cache.at(mod->name); + + int module_cost = 1; + for (auto c : mod->cells()) + module_cost += get(c); + + mod_cost_cache[mod->name] = module_cost; + return module_cost; + } + + log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(cell->type), GetSize(cell->parameters)); + return 1; + } +}; YOSYS_NAMESPACE_END diff --git a/kernel/driver.cc b/kernel/driver.cc index f273057dd..70a97c4b9 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -522,6 +522,12 @@ int main(int argc, char **argv) if (!backend_command.empty()) run_backend(output_filename, backend_command); + yosys_design->check(); + for (auto it : saved_designs) + it.second->check(); + for (auto it : pushed_designs) + it->check(); + if (!depsfile.empty()) { FILE *f = fopen(depsfile.c_str(), "wt"); diff --git a/kernel/log.h b/kernel/log.h index 3e1facae8..5f53f533a 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -91,7 +91,7 @@ YS_NORETURN void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(prin 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 n = 0) { return false; } +static inline bool ys_debug(int = 0) { return false; } # define log_debug(_fmt, ...) do { } while (0) #endif diff --git a/kernel/macc.h b/kernel/macc.h index 286ce567f..371f6737d 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -70,9 +70,9 @@ struct Macc while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == port.in_b[GetSize(port.in_b)-2]) port.in_b.remove(GetSize(port.in_b)-1); } else { - while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == RTLIL::S0) + while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == State::S0) port.in_a.remove(GetSize(port.in_a)-1); - while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == RTLIL::S0) + while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == State::S0) port.in_b.remove(GetSize(port.in_b)-1); } @@ -80,9 +80,9 @@ struct Macc } for (auto &bit : bit_ports) - if (bit == RTLIL::S1) + if (bit == State::S1) off = const_add(off, RTLIL::Const(1, width), false, false, width); - else if (bit != RTLIL::S0) + else if (bit != State::S0) new_bit_ports.append(bit); if (off.as_bool()) { @@ -99,24 +99,24 @@ struct Macc void from_cell(RTLIL::Cell *cell) { - RTLIL::SigSpec port_a = cell->getPort("\\A"); + RTLIL::SigSpec port_a = cell->getPort(ID::A); ports.clear(); - bit_ports = cell->getPort("\\B"); + bit_ports = cell->getPort(ID::B); - std::vector config_bits = cell->getParam("\\CONFIG").bits; + std::vector config_bits = cell->getParam(ID(CONFIG)).bits; int config_cursor = 0; #ifndef NDEBUG - int config_width = cell->getParam("\\CONFIG_WIDTH").as_int(); + 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++] == RTLIL::S1) num_bits |= 1; - if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 2; - if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 4; - if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 8; + if (config_bits[config_cursor++] == State::S1) num_bits |= 1; + if (config_bits[config_cursor++] == State::S1) num_bits |= 2; + if (config_bits[config_cursor++] == State::S1) num_bits |= 4; + if (config_bits[config_cursor++] == State::S1) num_bits |= 8; int port_a_cursor = 0; while (port_a_cursor < GetSize(port_a)) @@ -124,12 +124,12 @@ struct Macc log_assert(config_cursor + 2 + 2*num_bits <= config_width); port_t this_port; - this_port.is_signed = config_bits[config_cursor++] == RTLIL::S1; - this_port.do_subtract = config_bits[config_cursor++] == RTLIL::S1; + this_port.is_signed = config_bits[config_cursor++] == State::S1; + this_port.do_subtract = config_bits[config_cursor++] == State::S1; int size_a = 0; for (int i = 0; i < num_bits; i++) - if (config_bits[config_cursor++] == RTLIL::S1) + if (config_bits[config_cursor++] == State::S1) size_a |= 1 << i; this_port.in_a = port_a.extract(port_a_cursor, size_a); @@ -137,7 +137,7 @@ struct Macc int size_b = 0; for (int i = 0; i < num_bits; i++) - if (config_bits[config_cursor++] == RTLIL::S1) + if (config_bits[config_cursor++] == State::S1) size_b |= 1 << i; this_port.in_b = port_a.extract(port_a_cursor, size_b); @@ -166,43 +166,43 @@ struct Macc num_bits++, max_size /= 2; log_assert(num_bits < 16); - config_bits.push_back(num_bits & 1 ? RTLIL::S1 : RTLIL::S0); - config_bits.push_back(num_bits & 2 ? RTLIL::S1 : RTLIL::S0); - config_bits.push_back(num_bits & 4 ? RTLIL::S1 : RTLIL::S0); - config_bits.push_back(num_bits & 8 ? RTLIL::S1 : RTLIL::S0); + config_bits.push_back(num_bits & 1 ? State::S1 : State::S0); + config_bits.push_back(num_bits & 2 ? State::S1 : State::S0); + config_bits.push_back(num_bits & 4 ? State::S1 : State::S0); + config_bits.push_back(num_bits & 8 ? State::S1 : State::S0); for (auto &port : ports) { if (GetSize(port.in_a) == 0) continue; - config_bits.push_back(port.is_signed ? RTLIL::S1 : RTLIL::S0); - config_bits.push_back(port.do_subtract ? RTLIL::S1 : RTLIL::S0); + config_bits.push_back(port.is_signed ? State::S1 : State::S0); + config_bits.push_back(port.do_subtract ? State::S1 : State::S0); int size_a = GetSize(port.in_a); for (int i = 0; i < num_bits; i++) - config_bits.push_back(size_a & (1 << i) ? RTLIL::S1 : RTLIL::S0); + config_bits.push_back(size_a & (1 << i) ? State::S1 : State::S0); int size_b = GetSize(port.in_b); for (int i = 0; i < num_bits; i++) - config_bits.push_back(size_b & (1 << i) ? RTLIL::S1 : RTLIL::S0); + config_bits.push_back(size_b & (1 << i) ? State::S1 : State::S0); port_a.append(port.in_a); port_a.append(port.in_b); } - cell->setPort("\\A", port_a); - cell->setPort("\\B", bit_ports); - cell->setParam("\\CONFIG", config_bits); - cell->setParam("\\CONFIG_WIDTH", GetSize(config_bits)); - cell->setParam("\\A_WIDTH", GetSize(port_a)); - cell->setParam("\\B_WIDTH", GetSize(bit_ports)); + cell->setPort(ID::A, port_a); + cell->setPort(ID::B, bit_ports); + cell->setParam(ID(CONFIG), config_bits); + cell->setParam(ID(CONFIG_WIDTH), GetSize(config_bits)); + cell->setParam(ID(A_WIDTH), GetSize(port_a)); + cell->setParam(ID(B_WIDTH), GetSize(bit_ports)); } bool eval(RTLIL::Const &result) const { for (auto &bit : result.bits) - bit = RTLIL::S0; + bit = State::S0; for (auto &port : ports) { diff --git a/kernel/register.cc b/kernel/register.cc index 26da96b95..1fd1bad1d 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -25,6 +25,65 @@ #include #include +#ifdef YOSYS_ENABLE_ZLIB +#include + +PRIVATE_NAMESPACE_BEGIN +#define GZ_BUFFER_SIZE 8192 +void decompress_gzip(const std::string &filename, std::stringstream &out) +{ + char buffer[GZ_BUFFER_SIZE]; + int bytes_read; + gzFile gzf = gzopen(filename.c_str(), "rb"); + while(!gzeof(gzf)) { + bytes_read = gzread(gzf, reinterpret_cast(buffer), GZ_BUFFER_SIZE); + out.write(buffer, bytes_read); + } + gzclose(gzf); +} + +/* +An output stream that uses a stringbuf to buffer data internally, +using zlib to write gzip-compressed data every time the stream is flushed. +*/ +class gzip_ostream : public std::ostream { +public: + gzip_ostream() + { + rdbuf(&outbuf); + } + bool open(const std::string &filename) + { + return outbuf.open(filename); + } +private: + class gzip_streambuf : public std::stringbuf { + public: + gzip_streambuf() { }; + bool open(const std::string &filename) + { + gzf = gzopen(filename.c_str(), "wb"); + return gzf != nullptr; + } + virtual int sync() override + { + gzwrite(gzf, reinterpret_cast(str().c_str()), unsigned(str().size())); + str(""); + return 0; + } + ~gzip_streambuf() + { + sync(); + gzclose(gzf); + } + private: + gzFile gzf = nullptr; + } outbuf; +}; +PRIVATE_NAMESPACE_END + +#endif + YOSYS_NAMESPACE_BEGIN #define MAX_REG_COUNT 1000 @@ -141,7 +200,7 @@ void Pass::extra_args(std::vector args, size_t argidx, RTLIL::Desig { std::string arg = args[argidx]; - if (arg.substr(0, 1) == "-") + if (arg.compare(0, 1, "-") == 0) cmd_error(args, argidx, "Unknown option or option in arguments."); if (!select) @@ -236,8 +295,6 @@ void Pass::call(RTLIL::Design *design, std::vector args) pass_register[args[0]]->post_execute(state); while (design->selection_stack.size() > orig_sel_stack_pos) design->selection_stack.pop_back(); - - design->check(); } void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command) @@ -319,8 +376,10 @@ void ScriptPass::run(std::string command, std::string info) log(" %s\n", command.c_str()); else log(" %s %s\n", command.c_str(), info.c_str()); - } else + } else { Pass::call(active_design, command); + active_design->check(); + } } void ScriptPass::run_script(RTLIL::Design *design, std::string run_from, std::string run_to) @@ -390,7 +449,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector(magic), 3); + if (n == 3 && magic[0] == 0x1f && magic[1] == 0x8b) { + #ifdef YOSYS_ENABLE_ZLIB + log("Found gzip magic in file `%s', decompressing using zlib.\n", filename.c_str()); + if (magic[2] != 8) + log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n", + filename.c_str(), unsigned(magic[2])); + delete ff; + std::stringstream *df = new std::stringstream(); + decompress_gzip(filename, *df); + f = df; + #else + log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str()); + #endif + } else { + ff->clear(); + ff->seekg(0, std::ios::beg); + } + } } if (f == NULL) log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); for (size_t i = argidx+1; i < args.size(); i++) - if (args[i].substr(0, 1) == "-") + if (args[i].compare(0, 1, "-") == 0) cmd_error(args, i, "Found option, expected arguments."); if (argidx+1 < args.size()) { @@ -492,8 +573,6 @@ void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string args.push_back(filename); frontend_register[args[0]]->execute(args, design); } - - design->check(); } Backend::Backend(std::string name, std::string short_help) : @@ -533,7 +612,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vectoropen(filename.c_str(), std::ofstream::trunc); - yosys_output_files.insert(filename); - if (ff->fail()) { - delete ff; - log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".gz") == 0) { +#ifdef YOSYS_ENABLE_ZLIB + gzip_ostream *gf = new gzip_ostream; + if (!gf->open(filename)) { + delete gf; + log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + } + yosys_output_files.insert(filename); + f = gf; +#else + log_cmd_error("Yosys is compiled without zlib support, unable to write gzip output.\n"); +#endif + } else { + std::ofstream *ff = new std::ofstream; + ff->open(filename.c_str(), std::ofstream::trunc); + yosys_output_files.insert(filename); + if (ff->fail()) { + delete ff; + log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + } + f = ff; } - f = ff; } if (called_with_fp) @@ -603,8 +696,6 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f while (design->selection_stack.size() > orig_sel_stack_pos) design->selection_stack.pop_back(); - - design->check(); } static struct CellHelpMessages { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a09f4a0d1..1d380135b 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -29,12 +29,23 @@ YOSYS_NAMESPACE_BEGIN RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard; -std::vector RTLIL::IdString::global_refcount_storage_; std::vector RTLIL::IdString::global_id_storage_; dict RTLIL::IdString::global_id_index_; +#ifndef YOSYS_NO_IDS_REFCNT +std::vector RTLIL::IdString::global_refcount_storage_; std::vector RTLIL::IdString::global_free_idx_list_; +#endif +#ifdef YOSYS_USE_STICKY_IDS int RTLIL::IdString::last_created_idx_[8]; int RTLIL::IdString::last_created_idx_ptr_; +#endif + +IdString RTLIL::ID::A; +IdString RTLIL::ID::B; +IdString RTLIL::ID::Y; +IdString RTLIL::ID::keep; +IdString RTLIL::ID::whitebox; +IdString RTLIL::ID::blackbox; RTLIL::Const::Const() { @@ -47,7 +58,7 @@ RTLIL::Const::Const(std::string str) for (int i = str.size()-1; i >= 0; i--) { unsigned char ch = str[i]; for (int j = 0; j < 8; j++) { - bits.push_back((ch & 1) != 0 ? RTLIL::S1 : RTLIL::S0); + bits.push_back((ch & 1) != 0 ? State::S1 : State::S0); ch = ch >> 1; } } @@ -57,7 +68,7 @@ RTLIL::Const::Const(int val, int width) { flags = RTLIL::CONST_FLAG_NONE; for (int i = 0; i < width; i++) { - bits.push_back((val & 1) != 0 ? RTLIL::S1 : RTLIL::S0); + bits.push_back((val & 1) != 0 ? State::S1 : State::S0); val = val >> 1; } } @@ -73,7 +84,7 @@ RTLIL::Const::Const(const std::vector &bits) { flags = RTLIL::CONST_FLAG_NONE; for (auto b : bits) - this->bits.push_back(b ? RTLIL::S1 : RTLIL::S0); + this->bits.push_back(b ? State::S1 : State::S0); } RTLIL::Const::Const(const RTLIL::Const &c) @@ -106,7 +117,7 @@ bool RTLIL::Const::operator !=(const RTLIL::Const &other) const bool RTLIL::Const::as_bool() const { for (size_t i = 0; i < bits.size(); i++) - if (bits[i] == RTLIL::S1) + if (bits[i] == State::S1) return true; return false; } @@ -115,9 +126,9 @@ int RTLIL::Const::as_int(bool is_signed) const { int32_t ret = 0; for (size_t i = 0; i < bits.size() && i < 32; i++) - if (bits[i] == RTLIL::S1) + if (bits[i] == State::S1) ret |= 1 << i; - if (is_signed && bits.back() == RTLIL::S1) + if (is_signed && bits.back() == State::S1) for (size_t i = bits.size(); i < 32; i++) ret |= 1 << i; return ret; @@ -264,16 +275,16 @@ pool RTLIL::AttrObject::get_strpool_attribute(RTLIL::IdString id) const void RTLIL::AttrObject::set_src_attribute(const std::string &src) { if (src.empty()) - attributes.erase("\\src"); + attributes.erase(ID(src)); else - attributes["\\src"] = src; + attributes[ID(src)] = src; } std::string RTLIL::AttrObject::get_src_attribute() const { std::string src; - if (attributes.count("\\src")) - src = attributes.at("\\src").decode_string(); + if (attributes.count(ID(src))) + src = attributes.at(ID(src)).decode_string(); return src; } @@ -417,7 +428,7 @@ RTLIL::Module *RTLIL::Design::top_module() int module_count = 0; for (auto mod : selected_modules()) { - if (mod->get_bool_attribute("\\top")) + if (mod->get_bool_attribute(ID(top))) return mod; module_count++; module = mod; @@ -706,7 +717,7 @@ void RTLIL::Module::makeblackbox() processes.clear(); remove(delwires); - set_bool_attribute("\\blackbox"); + set_bool_attribute(ID::blackbox); } void RTLIL::Module::reprocess_module(RTLIL::Design *, dict) @@ -754,7 +765,7 @@ namespace { cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, buf.str().c_str()); } - int param(const char *name) + int param(RTLIL::IdString name) { if (cell->parameters.count(name) == 0) error(__LINE__); @@ -762,7 +773,7 @@ namespace { return cell->parameters.at(name).as_int(); } - int param_bool(const char *name) + int param_bool(RTLIL::IdString name) { int v = param(name); if (cell->parameters.at(name).bits.size() > 32) @@ -772,14 +783,14 @@ namespace { return v; } - void param_bits(const char *name, int width) + void param_bits(RTLIL::IdString name, int width) { param(name); if (int(cell->parameters.at(name).bits.size()) != width) error(__LINE__); } - void port(const char *name, int width) + void port(RTLIL::IdString name, int width) { if (!cell->hasPort(name)) error(__LINE__); @@ -797,9 +808,9 @@ namespace { if (expected_ports.count(conn.first) == 0) error(__LINE__); - if (expected_params.count("\\A_SIGNED") != 0 && expected_params.count("\\B_SIGNED") && check_matched_sign) { - bool a_is_signed = param("\\A_SIGNED") != 0; - bool b_is_signed = param("\\B_SIGNED") != 0; + if (expected_params.count(ID(A_SIGNED)) != 0 && expected_params.count(ID(B_SIGNED)) && check_matched_sign) { + bool a_is_signed = param(ID(A_SIGNED)) != 0; + bool b_is_signed = param(ID(B_SIGNED)) != 0; if (a_is_signed != b_is_signed) error(__LINE__); } @@ -828,481 +839,482 @@ namespace { void check() { - if (cell->type.substr(0, 1) != "$" || cell->type.substr(0, 3) == "$__" || cell->type.substr(0, 8) == "$paramod" || cell->type.substr(0,10) == "$fmcombine" || - cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:" || cell->type.substr(0, 8) == "$extern:") + if (!cell->type.begins_with("$") || cell->type.begins_with("$__") || cell->type.begins_with("$paramod") || cell->type.begins_with("$fmcombine") || + cell->type.begins_with("$verific$") || cell->type.begins_with("$array:") || cell->type.begins_with("$extern:")) return; - if (cell->type.in("$not", "$pos", "$neg")) { - param_bool("\\A_SIGNED"); - port("\\A", param("\\A_WIDTH")); - port("\\Y", param("\\Y_WIDTH")); + if (cell->type.in(ID($not), ID($pos), ID($neg))) { + param_bool(ID(A_SIGNED)); + port(ID::A, param(ID(A_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); return; } - if (cell->type.in("$and", "$or", "$xor", "$xnor")) { - param_bool("\\A_SIGNED"); - param_bool("\\B_SIGNED"); - port("\\A", param("\\A_WIDTH")); - port("\\B", param("\\B_WIDTH")); - port("\\Y", param("\\Y_WIDTH")); + if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) { + param_bool(ID(A_SIGNED)); + param_bool(ID(B_SIGNED)); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); return; } - if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool")) { - param_bool("\\A_SIGNED"); - port("\\A", param("\\A_WIDTH")); - port("\\Y", param("\\Y_WIDTH")); + if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) { + param_bool(ID(A_SIGNED)); + port(ID::A, param(ID(A_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); return; } - if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx")) { - param_bool("\\A_SIGNED"); - param_bool("\\B_SIGNED"); - port("\\A", param("\\A_WIDTH")); - port("\\B", param("\\B_WIDTH")); - port("\\Y", param("\\Y_WIDTH")); + if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { + param_bool(ID(A_SIGNED)); + param_bool(ID(B_SIGNED)); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(false); return; } - if (cell->type.in("$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt")) { - param_bool("\\A_SIGNED"); - param_bool("\\B_SIGNED"); - port("\\A", param("\\A_WIDTH")); - port("\\B", param("\\B_WIDTH")); - port("\\Y", param("\\Y_WIDTH")); + if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) { + param_bool(ID(A_SIGNED)); + param_bool(ID(B_SIGNED)); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); return; } - if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$pow")) { - param_bool("\\A_SIGNED"); - param_bool("\\B_SIGNED"); - port("\\A", param("\\A_WIDTH")); - port("\\B", param("\\B_WIDTH")); - port("\\Y", param("\\Y_WIDTH")); - check_expected(cell->type != "$pow"); + if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) { + param_bool(ID(A_SIGNED)); + param_bool(ID(B_SIGNED)); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); + check_expected(cell->type != ID($pow)); return; } - if (cell->type == "$fa") { - port("\\A", param("\\WIDTH")); - port("\\B", param("\\WIDTH")); - port("\\C", param("\\WIDTH")); - port("\\X", param("\\WIDTH")); - port("\\Y", param("\\WIDTH")); + if (cell->type == ID($fa)) { + port(ID::A, param(ID(WIDTH))); + port(ID::B, param(ID(WIDTH))); + port(ID(C), param(ID(WIDTH))); + port(ID(X), param(ID(WIDTH))); + port(ID::Y, param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$lcu") { - port("\\P", param("\\WIDTH")); - port("\\G", param("\\WIDTH")); - port("\\CI", 1); - port("\\CO", param("\\WIDTH")); + if (cell->type == ID($lcu)) { + port(ID(P), param(ID(WIDTH))); + port(ID(G), param(ID(WIDTH))); + port(ID(CI), 1); + port(ID(CO), param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$alu") { - param_bool("\\A_SIGNED"); - param_bool("\\B_SIGNED"); - port("\\A", param("\\A_WIDTH")); - port("\\B", param("\\B_WIDTH")); - port("\\CI", 1); - port("\\BI", 1); - port("\\X", param("\\Y_WIDTH")); - port("\\Y", param("\\Y_WIDTH")); - port("\\CO", param("\\Y_WIDTH")); + if (cell->type == ID($alu)) { + param_bool(ID(A_SIGNED)); + param_bool(ID(B_SIGNED)); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID(CI), 1); + port(ID(BI), 1); + port(ID(X), param(ID(Y_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); + port(ID(CO), param(ID(Y_WIDTH))); check_expected(); return; } - if (cell->type == "$macc") { - param("\\CONFIG"); - param("\\CONFIG_WIDTH"); - port("\\A", param("\\A_WIDTH")); - port("\\B", param("\\B_WIDTH")); - port("\\Y", param("\\Y_WIDTH")); + if (cell->type == ID($macc)) { + param(ID(CONFIG)); + param(ID(CONFIG_WIDTH)); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); Macc().from_cell(cell); return; } - if (cell->type == "$logic_not") { - param_bool("\\A_SIGNED"); - port("\\A", param("\\A_WIDTH")); - port("\\Y", param("\\Y_WIDTH")); + if (cell->type == ID($logic_not)) { + param_bool(ID(A_SIGNED)); + port(ID::A, param(ID(A_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); return; } - if (cell->type == "$logic_and" || cell->type == "$logic_or") { - param_bool("\\A_SIGNED"); - param_bool("\\B_SIGNED"); - port("\\A", param("\\A_WIDTH")); - port("\\B", param("\\B_WIDTH")); - port("\\Y", param("\\Y_WIDTH")); + if (cell->type.in(ID($logic_and), ID($logic_or))) { + param_bool(ID(A_SIGNED)); + param_bool(ID(B_SIGNED)); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(false); return; } - if (cell->type == "$slice") { - param("\\OFFSET"); - port("\\A", param("\\A_WIDTH")); - port("\\Y", param("\\Y_WIDTH")); - if (param("\\OFFSET") + param("\\Y_WIDTH") > param("\\A_WIDTH")) + if (cell->type == ID($slice)) { + param(ID(OFFSET)); + port(ID::A, param(ID(A_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); + if (param(ID(OFFSET)) + param(ID(Y_WIDTH)) > param(ID(A_WIDTH))) error(__LINE__); check_expected(); return; } - if (cell->type == "$concat") { - port("\\A", param("\\A_WIDTH")); - port("\\B", param("\\B_WIDTH")); - port("\\Y", param("\\A_WIDTH") + param("\\B_WIDTH")); + if (cell->type == ID($concat)) { + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(A_WIDTH)) + param(ID(B_WIDTH))); check_expected(); return; } - if (cell->type == "$mux") { - port("\\A", param("\\WIDTH")); - port("\\B", param("\\WIDTH")); - port("\\S", 1); - port("\\Y", param("\\WIDTH")); + if (cell->type == ID($mux)) { + port(ID::A, param(ID(WIDTH))); + port(ID::B, param(ID(WIDTH))); + port(ID(S), 1); + port(ID::Y, param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$pmux") { - port("\\A", param("\\WIDTH")); - port("\\B", param("\\WIDTH") * param("\\S_WIDTH")); - port("\\S", param("\\S_WIDTH")); - port("\\Y", param("\\WIDTH")); + if (cell->type == ID($pmux)) { + port(ID::A, param(ID(WIDTH))); + port(ID::B, param(ID(WIDTH)) * param(ID(S_WIDTH))); + port(ID(S), param(ID(S_WIDTH))); + port(ID::Y, param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$lut") { - param("\\LUT"); - port("\\A", param("\\WIDTH")); - port("\\Y", 1); + if (cell->type == ID($lut)) { + param(ID(LUT)); + port(ID::A, param(ID(WIDTH))); + port(ID::Y, 1); check_expected(); return; } - if (cell->type == "$sop") { - param("\\DEPTH"); - param("\\TABLE"); - port("\\A", param("\\WIDTH")); - port("\\Y", 1); + if (cell->type == ID($sop)) { + param(ID(DEPTH)); + param(ID(TABLE)); + port(ID::A, param(ID(WIDTH))); + port(ID::Y, 1); check_expected(); return; } - if (cell->type == "$sr") { - param_bool("\\SET_POLARITY"); - param_bool("\\CLR_POLARITY"); - port("\\SET", param("\\WIDTH")); - port("\\CLR", param("\\WIDTH")); - port("\\Q", param("\\WIDTH")); + if (cell->type == ID($sr)) { + param_bool(ID(SET_POLARITY)); + param_bool(ID(CLR_POLARITY)); + port(ID(SET), param(ID(WIDTH))); + port(ID(CLR), param(ID(WIDTH))); + port(ID(Q), param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$ff") { - port("\\D", param("\\WIDTH")); - port("\\Q", param("\\WIDTH")); + if (cell->type == ID($ff)) { + port(ID(D), param(ID(WIDTH))); + port(ID(Q), param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$dff") { - param_bool("\\CLK_POLARITY"); - port("\\CLK", 1); - port("\\D", param("\\WIDTH")); - port("\\Q", param("\\WIDTH")); + if (cell->type == ID($dff)) { + param_bool(ID(CLK_POLARITY)); + port(ID(CLK), 1); + port(ID(D), param(ID(WIDTH))); + port(ID(Q), param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$dffe") { - param_bool("\\CLK_POLARITY"); - param_bool("\\EN_POLARITY"); - port("\\CLK", 1); - port("\\EN", 1); - port("\\D", param("\\WIDTH")); - port("\\Q", param("\\WIDTH")); + if (cell->type == ID($dffe)) { + param_bool(ID(CLK_POLARITY)); + param_bool(ID(EN_POLARITY)); + port(ID(CLK), 1); + port(ID(EN), 1); + port(ID(D), param(ID(WIDTH))); + port(ID(Q), param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$dffsr") { - param_bool("\\CLK_POLARITY"); - param_bool("\\SET_POLARITY"); - param_bool("\\CLR_POLARITY"); - port("\\CLK", 1); - port("\\SET", param("\\WIDTH")); - port("\\CLR", param("\\WIDTH")); - port("\\D", param("\\WIDTH")); - port("\\Q", param("\\WIDTH")); + if (cell->type == ID($dffsr)) { + param_bool(ID(CLK_POLARITY)); + param_bool(ID(SET_POLARITY)); + param_bool(ID(CLR_POLARITY)); + port(ID(CLK), 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 == "$adff") { - param_bool("\\CLK_POLARITY"); - param_bool("\\ARST_POLARITY"); - param_bits("\\ARST_VALUE", param("\\WIDTH")); - port("\\CLK", 1); - port("\\ARST", 1); - port("\\D", param("\\WIDTH")); - port("\\Q", param("\\WIDTH")); + if (cell->type == ID($adff)) { + param_bool(ID(CLK_POLARITY)); + param_bool(ID(ARST_POLARITY)); + param_bits(ID(ARST_VALUE), param(ID(WIDTH))); + port(ID(CLK), 1); + port(ID(ARST), 1); + port(ID(D), param(ID(WIDTH))); + port(ID(Q), param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$dlatch") { - param_bool("\\EN_POLARITY"); - port("\\EN", 1); - port("\\D", param("\\WIDTH")); - port("\\Q", param("\\WIDTH")); + if (cell->type == ID($dlatch)) { + param_bool(ID(EN_POLARITY)); + port(ID(EN), 1); + port(ID(D), param(ID(WIDTH))); + port(ID(Q), param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$dlatchsr") { - param_bool("\\EN_POLARITY"); - param_bool("\\SET_POLARITY"); - param_bool("\\CLR_POLARITY"); - port("\\EN", 1); - port("\\SET", param("\\WIDTH")); - port("\\CLR", param("\\WIDTH")); - port("\\D", param("\\WIDTH")); - port("\\Q", param("\\WIDTH")); + if (cell->type == ID($dlatchsr)) { + param_bool(ID(EN_POLARITY)); + param_bool(ID(SET_POLARITY)); + param_bool(ID(CLR_POLARITY)); + 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 == "$fsm") { - param("\\NAME"); - param_bool("\\CLK_POLARITY"); - param_bool("\\ARST_POLARITY"); - param("\\STATE_BITS"); - param("\\STATE_NUM"); - param("\\STATE_NUM_LOG2"); - param("\\STATE_RST"); - param_bits("\\STATE_TABLE", param("\\STATE_BITS") * param("\\STATE_NUM")); - param("\\TRANS_NUM"); - param_bits("\\TRANS_TABLE", param("\\TRANS_NUM") * (2*param("\\STATE_NUM_LOG2") + param("\\CTRL_IN_WIDTH") + param("\\CTRL_OUT_WIDTH"))); - port("\\CLK", 1); - port("\\ARST", 1); - port("\\CTRL_IN", param("\\CTRL_IN_WIDTH")); - port("\\CTRL_OUT", param("\\CTRL_OUT_WIDTH")); + if (cell->type == ID($fsm)) { + param(ID(NAME)); + param_bool(ID(CLK_POLARITY)); + param_bool(ID(ARST_POLARITY)); + param(ID(STATE_BITS)); + param(ID(STATE_NUM)); + param(ID(STATE_NUM_LOG2)); + param(ID(STATE_RST)); + param_bits(ID(STATE_TABLE), param(ID(STATE_BITS)) * param(ID(STATE_NUM))); + param(ID(TRANS_NUM)); + param_bits(ID(TRANS_TABLE), param(ID(TRANS_NUM)) * (2*param(ID(STATE_NUM_LOG2)) + param(ID(CTRL_IN_WIDTH)) + param(ID(CTRL_OUT_WIDTH)))); + port(ID(CLK), 1); + port(ID(ARST), 1); + port(ID(CTRL_IN), param(ID(CTRL_IN_WIDTH))); + port(ID(CTRL_OUT), param(ID(CTRL_OUT_WIDTH))); check_expected(); return; } - if (cell->type == "$memrd") { - param("\\MEMID"); - param_bool("\\CLK_ENABLE"); - param_bool("\\CLK_POLARITY"); - param_bool("\\TRANSPARENT"); - port("\\CLK", 1); - port("\\EN", 1); - port("\\ADDR", param("\\ABITS")); - port("\\DATA", param("\\WIDTH")); + if (cell->type == ID($memrd)) { + param(ID(MEMID)); + param_bool(ID(CLK_ENABLE)); + param_bool(ID(CLK_POLARITY)); + param_bool(ID(TRANSPARENT)); + port(ID(CLK), 1); + port(ID(EN), 1); + port(ID(ADDR), param(ID(ABITS))); + port(ID(DATA), param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$memwr") { - param("\\MEMID"); - param_bool("\\CLK_ENABLE"); - param_bool("\\CLK_POLARITY"); - param("\\PRIORITY"); - port("\\CLK", 1); - port("\\EN", param("\\WIDTH")); - port("\\ADDR", param("\\ABITS")); - port("\\DATA", param("\\WIDTH")); + if (cell->type == ID($memwr)) { + param(ID(MEMID)); + param_bool(ID(CLK_ENABLE)); + param_bool(ID(CLK_POLARITY)); + param(ID(PRIORITY)); + port(ID(CLK), 1); + port(ID(EN), param(ID(WIDTH))); + port(ID(ADDR), param(ID(ABITS))); + port(ID(DATA), param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$meminit") { - param("\\MEMID"); - param("\\PRIORITY"); - port("\\ADDR", param("\\ABITS")); - port("\\DATA", param("\\WIDTH") * param("\\WORDS")); + if (cell->type == ID($meminit)) { + param(ID(MEMID)); + param(ID(PRIORITY)); + port(ID(ADDR), param(ID(ABITS))); + port(ID(DATA), param(ID(WIDTH)) * param(ID(WORDS))); check_expected(); return; } - if (cell->type == "$mem") { - param("\\MEMID"); - param("\\SIZE"); - param("\\OFFSET"); - param("\\INIT"); - param_bits("\\RD_CLK_ENABLE", max(1, param("\\RD_PORTS"))); - param_bits("\\RD_CLK_POLARITY", max(1, param("\\RD_PORTS"))); - param_bits("\\RD_TRANSPARENT", max(1, param("\\RD_PORTS"))); - param_bits("\\WR_CLK_ENABLE", max(1, param("\\WR_PORTS"))); - param_bits("\\WR_CLK_POLARITY", max(1, param("\\WR_PORTS"))); - port("\\RD_CLK", param("\\RD_PORTS")); - port("\\RD_EN", param("\\RD_PORTS")); - port("\\RD_ADDR", param("\\RD_PORTS") * param("\\ABITS")); - port("\\RD_DATA", param("\\RD_PORTS") * param("\\WIDTH")); - port("\\WR_CLK", param("\\WR_PORTS")); - port("\\WR_EN", param("\\WR_PORTS") * param("\\WIDTH")); - port("\\WR_ADDR", param("\\WR_PORTS") * param("\\ABITS")); - port("\\WR_DATA", param("\\WR_PORTS") * param("\\WIDTH")); + if (cell->type == ID($mem)) { + param(ID(MEMID)); + param(ID(SIZE)); + param(ID(OFFSET)); + param(ID(INIT)); + param_bits(ID(RD_CLK_ENABLE), max(1, param(ID(RD_PORTS)))); + param_bits(ID(RD_CLK_POLARITY), max(1, param(ID(RD_PORTS)))); + param_bits(ID(RD_TRANSPARENT), max(1, param(ID(RD_PORTS)))); + param_bits(ID(WR_CLK_ENABLE), max(1, param(ID(WR_PORTS)))); + param_bits(ID(WR_CLK_POLARITY), max(1, param(ID(WR_PORTS)))); + port(ID(RD_CLK), param(ID(RD_PORTS))); + port(ID(RD_EN), param(ID(RD_PORTS))); + port(ID(RD_ADDR), param(ID(RD_PORTS)) * param(ID(ABITS))); + port(ID(RD_DATA), param(ID(RD_PORTS)) * param(ID(WIDTH))); + port(ID(WR_CLK), param(ID(WR_PORTS))); + port(ID(WR_EN), param(ID(WR_PORTS)) * param(ID(WIDTH))); + port(ID(WR_ADDR), param(ID(WR_PORTS)) * param(ID(ABITS))); + port(ID(WR_DATA), param(ID(WR_PORTS)) * param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$tribuf") { - port("\\A", param("\\WIDTH")); - port("\\Y", param("\\WIDTH")); - port("\\EN", 1); + if (cell->type == ID($tribuf)) { + port(ID::A, param(ID(WIDTH))); + port(ID::Y, param(ID(WIDTH))); + port(ID(EN), 1); check_expected(); return; } - if (cell->type.in("$assert", "$assume", "$live", "$fair", "$cover")) { - port("\\A", 1); - port("\\EN", 1); + if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) { + port(ID::A, 1); + port(ID(EN), 1); check_expected(); return; } - if (cell->type == "$initstate") { - port("\\Y", 1); + if (cell->type == ID($initstate)) { + port(ID::Y, 1); check_expected(); return; } - if (cell->type.in("$anyconst", "$anyseq", "$allconst", "$allseq")) { - port("\\Y", param("\\WIDTH")); + if (cell->type.in(ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))) { + port(ID::Y, param(ID(WIDTH))); check_expected(); return; } - if (cell->type == "$equiv") { - port("\\A", 1); - port("\\B", 1); - port("\\Y", 1); + if (cell->type == ID($equiv)) { + port(ID::A, 1); + port(ID::B, 1); + port(ID::Y, 1); check_expected(); return; } - if (cell->type.in("$specify2", "$specify3")) { - param_bool("\\FULL"); - param_bool("\\SRC_DST_PEN"); - param_bool("\\SRC_DST_POL"); - param("\\T_RISE_MIN"); - param("\\T_RISE_TYP"); - param("\\T_RISE_MAX"); - param("\\T_FALL_MIN"); - param("\\T_FALL_TYP"); - param("\\T_FALL_MAX"); - port("\\EN", 1); - port("\\SRC", param("\\SRC_WIDTH")); - port("\\DST", param("\\DST_WIDTH")); - if (cell->type == "$specify3") { - param_bool("\\EDGE_EN"); - param_bool("\\EDGE_POL"); - param_bool("\\DAT_DST_PEN"); - param_bool("\\DAT_DST_POL"); - port("\\DAT", param("\\DST_WIDTH")); + if (cell->type.in(ID($specify2), ID($specify3))) { + param_bool(ID(FULL)); + param_bool(ID(SRC_DST_PEN)); + param_bool(ID(SRC_DST_POL)); + param(ID(T_RISE_MIN)); + param(ID(T_RISE_TYP)); + param(ID(T_RISE_MAX)); + param(ID(T_FALL_MIN)); + param(ID(T_FALL_TYP)); + param(ID(T_FALL_MAX)); + port(ID(EN), 1); + port(ID(SRC), param(ID(SRC_WIDTH))); + port(ID(DST), param(ID(DST_WIDTH))); + if (cell->type == ID($specify3)) { + param_bool(ID(EDGE_EN)); + param_bool(ID(EDGE_POL)); + param_bool(ID(DAT_DST_PEN)); + param_bool(ID(DAT_DST_POL)); + port(ID(DAT), param(ID(DST_WIDTH))); } check_expected(); return; } - if (cell->type == "$specrule") { - param("\\TYPE"); - param_bool("\\SRC_PEN"); - param_bool("\\SRC_POL"); - param_bool("\\DST_PEN"); - param_bool("\\DST_POL"); - param("\\T_LIMIT"); - param("\\T_LIMIT2"); - port("\\SRC_EN", 1); - port("\\DST_EN", 1); - port("\\SRC", param("\\SRC_WIDTH")); - port("\\DST", param("\\DST_WIDTH")); + if (cell->type == ID($specrule)) { + param(ID(TYPE)); + param_bool(ID(SRC_PEN)); + param_bool(ID(SRC_POL)); + param_bool(ID(DST_PEN)); + param_bool(ID(DST_POL)); + param(ID(T_LIMIT)); + param(ID(T_LIMIT2)); + port(ID(SRC_EN), 1); + port(ID(DST_EN), 1); + port(ID(SRC), param(ID(SRC_WIDTH))); + port(ID(DST), param(ID(DST_WIDTH))); check_expected(); return; } - if (cell->type == "$_BUF_") { check_gate("AY"); return; } - if (cell->type == "$_NOT_") { check_gate("AY"); return; } - if (cell->type == "$_AND_") { check_gate("ABY"); return; } - if (cell->type == "$_NAND_") { check_gate("ABY"); return; } - if (cell->type == "$_OR_") { check_gate("ABY"); return; } - if (cell->type == "$_NOR_") { check_gate("ABY"); return; } - if (cell->type == "$_XOR_") { check_gate("ABY"); return; } - if (cell->type == "$_XNOR_") { check_gate("ABY"); return; } - if (cell->type == "$_ANDNOT_") { check_gate("ABY"); return; } - if (cell->type == "$_ORNOT_") { check_gate("ABY"); return; } - if (cell->type == "$_MUX_") { check_gate("ABSY"); return; } - if (cell->type == "$_AOI3_") { check_gate("ABCY"); return; } - if (cell->type == "$_OAI3_") { check_gate("ABCY"); return; } - if (cell->type == "$_AOI4_") { check_gate("ABCDY"); return; } - if (cell->type == "$_OAI4_") { check_gate("ABCDY"); return; } + if (cell->type == ID($_BUF_)) { check_gate("AY"); return; } + if (cell->type == ID($_NOT_)) { check_gate("AY"); return; } + if (cell->type == ID($_AND_)) { check_gate("ABY"); return; } + if (cell->type == ID($_NAND_)) { check_gate("ABY"); return; } + if (cell->type == ID($_OR_)) { check_gate("ABY"); return; } + if (cell->type == ID($_NOR_)) { check_gate("ABY"); return; } + if (cell->type == ID($_XOR_)) { check_gate("ABY"); return; } + if (cell->type == ID($_XNOR_)) { check_gate("ABY"); return; } + if (cell->type == ID($_ANDNOT_)) { check_gate("ABY"); return; } + if (cell->type == ID($_ORNOT_)) { check_gate("ABY"); return; } + if (cell->type == ID($_MUX_)) { check_gate("ABSY"); return; } + if (cell->type == ID($_NMUX_)) { check_gate("ABSY"); return; } + if (cell->type == ID($_AOI3_)) { check_gate("ABCY"); return; } + if (cell->type == ID($_OAI3_)) { check_gate("ABCY"); return; } + if (cell->type == ID($_AOI4_)) { check_gate("ABCDY"); return; } + if (cell->type == ID($_OAI4_)) { check_gate("ABCDY"); return; } - if (cell->type == "$_TBUF_") { check_gate("AYE"); return; } + if (cell->type == ID($_TBUF_)) { check_gate("AYE"); return; } - if (cell->type == "$_MUX4_") { check_gate("ABCDSTY"); return; } - if (cell->type == "$_MUX8_") { check_gate("ABCDEFGHSTUY"); return; } - if (cell->type == "$_MUX16_") { check_gate("ABCDEFGHIJKLMNOPSTUVY"); return; } + if (cell->type == ID($_MUX4_)) { check_gate("ABCDSTY"); return; } + if (cell->type == ID($_MUX8_)) { check_gate("ABCDEFGHSTUY"); return; } + if (cell->type == ID($_MUX16_)) { check_gate("ABCDEFGHIJKLMNOPSTUVY"); return; } - if (cell->type == "$_SR_NN_") { check_gate("SRQ"); return; } - if (cell->type == "$_SR_NP_") { check_gate("SRQ"); return; } - if (cell->type == "$_SR_PN_") { check_gate("SRQ"); return; } - if (cell->type == "$_SR_PP_") { check_gate("SRQ"); return; } + if (cell->type == ID($_SR_NN_)) { check_gate("SRQ"); return; } + if (cell->type == ID($_SR_NP_)) { check_gate("SRQ"); return; } + if (cell->type == ID($_SR_PN_)) { check_gate("SRQ"); return; } + if (cell->type == ID($_SR_PP_)) { check_gate("SRQ"); return; } - if (cell->type == "$_FF_") { check_gate("DQ"); return; } - if (cell->type == "$_DFF_N_") { check_gate("DQC"); return; } - if (cell->type == "$_DFF_P_") { check_gate("DQC"); return; } + if (cell->type == ID($_FF_)) { check_gate("DQ"); return; } + if (cell->type == ID($_DFF_N_)) { check_gate("DQC"); return; } + if (cell->type == ID($_DFF_P_)) { check_gate("DQC"); return; } - if (cell->type == "$_DFFE_NN_") { check_gate("DQCE"); return; } - if (cell->type == "$_DFFE_NP_") { check_gate("DQCE"); return; } - if (cell->type == "$_DFFE_PN_") { check_gate("DQCE"); return; } - if (cell->type == "$_DFFE_PP_") { check_gate("DQCE"); return; } + if (cell->type == ID($_DFFE_NN_)) { check_gate("DQCE"); return; } + if (cell->type == ID($_DFFE_NP_)) { check_gate("DQCE"); return; } + if (cell->type == ID($_DFFE_PN_)) { check_gate("DQCE"); return; } + if (cell->type == ID($_DFFE_PP_)) { check_gate("DQCE"); return; } - if (cell->type == "$_DFF_NN0_") { check_gate("DQCR"); return; } - if (cell->type == "$_DFF_NN1_") { check_gate("DQCR"); return; } - if (cell->type == "$_DFF_NP0_") { check_gate("DQCR"); return; } - if (cell->type == "$_DFF_NP1_") { check_gate("DQCR"); return; } - if (cell->type == "$_DFF_PN0_") { check_gate("DQCR"); return; } - if (cell->type == "$_DFF_PN1_") { check_gate("DQCR"); return; } - if (cell->type == "$_DFF_PP0_") { check_gate("DQCR"); return; } - if (cell->type == "$_DFF_PP1_") { check_gate("DQCR"); return; } + if (cell->type == ID($_DFF_NN0_)) { check_gate("DQCR"); return; } + if (cell->type == ID($_DFF_NN1_)) { check_gate("DQCR"); return; } + if (cell->type == ID($_DFF_NP0_)) { check_gate("DQCR"); return; } + if (cell->type == ID($_DFF_NP1_)) { check_gate("DQCR"); return; } + if (cell->type == ID($_DFF_PN0_)) { check_gate("DQCR"); return; } + if (cell->type == ID($_DFF_PN1_)) { check_gate("DQCR"); return; } + if (cell->type == ID($_DFF_PP0_)) { check_gate("DQCR"); return; } + if (cell->type == ID($_DFF_PP1_)) { check_gate("DQCR"); return; } - if (cell->type == "$_DFFSR_NNN_") { check_gate("CSRDQ"); return; } - if (cell->type == "$_DFFSR_NNP_") { check_gate("CSRDQ"); return; } - if (cell->type == "$_DFFSR_NPN_") { check_gate("CSRDQ"); return; } - if (cell->type == "$_DFFSR_NPP_") { check_gate("CSRDQ"); return; } - if (cell->type == "$_DFFSR_PNN_") { check_gate("CSRDQ"); return; } - if (cell->type == "$_DFFSR_PNP_") { check_gate("CSRDQ"); return; } - if (cell->type == "$_DFFSR_PPN_") { check_gate("CSRDQ"); return; } - if (cell->type == "$_DFFSR_PPP_") { check_gate("CSRDQ"); return; } + if (cell->type == ID($_DFFSR_NNN_)) { check_gate("CSRDQ"); return; } + if (cell->type == ID($_DFFSR_NNP_)) { check_gate("CSRDQ"); return; } + if (cell->type == ID($_DFFSR_NPN_)) { check_gate("CSRDQ"); return; } + if (cell->type == ID($_DFFSR_NPP_)) { check_gate("CSRDQ"); return; } + if (cell->type == ID($_DFFSR_PNN_)) { check_gate("CSRDQ"); return; } + if (cell->type == ID($_DFFSR_PNP_)) { check_gate("CSRDQ"); return; } + if (cell->type == ID($_DFFSR_PPN_)) { check_gate("CSRDQ"); return; } + if (cell->type == ID($_DFFSR_PPP_)) { check_gate("CSRDQ"); return; } - if (cell->type == "$_DLATCH_N_") { check_gate("EDQ"); return; } - if (cell->type == "$_DLATCH_P_") { check_gate("EDQ"); return; } + if (cell->type == ID($_DLATCH_N_)) { check_gate("EDQ"); return; } + if (cell->type == ID($_DLATCH_P_)) { check_gate("EDQ"); return; } - if (cell->type == "$_DLATCHSR_NNN_") { check_gate("ESRDQ"); return; } - if (cell->type == "$_DLATCHSR_NNP_") { check_gate("ESRDQ"); return; } - if (cell->type == "$_DLATCHSR_NPN_") { check_gate("ESRDQ"); return; } - if (cell->type == "$_DLATCHSR_NPP_") { check_gate("ESRDQ"); return; } - if (cell->type == "$_DLATCHSR_PNN_") { check_gate("ESRDQ"); return; } - if (cell->type == "$_DLATCHSR_PNP_") { check_gate("ESRDQ"); return; } - if (cell->type == "$_DLATCHSR_PPN_") { check_gate("ESRDQ"); return; } - if (cell->type == "$_DLATCHSR_PPP_") { check_gate("ESRDQ"); return; } + if (cell->type == ID($_DLATCHSR_NNN_)) { check_gate("ESRDQ"); return; } + if (cell->type == ID($_DLATCHSR_NNP_)) { check_gate("ESRDQ"); return; } + if (cell->type == ID($_DLATCHSR_NPN_)) { check_gate("ESRDQ"); return; } + if (cell->type == ID($_DLATCHSR_NPP_)) { check_gate("ESRDQ"); return; } + if (cell->type == ID($_DLATCHSR_PNN_)) { check_gate("ESRDQ"); return; } + if (cell->type == ID($_DLATCHSR_PNP_)) { check_gate("ESRDQ"); return; } + if (cell->type == ID($_DLATCHSR_PPN_)) { check_gate("ESRDQ"); return; } + if (cell->type == ID($_DLATCHSR_PPP_)) { check_gate("ESRDQ"); return; } error(__LINE__); } @@ -1816,11 +1828,11 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth #define DEF_METHOD(_func, _y_size, _type) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ - cell->parameters["\\A_SIGNED"] = is_signed; \ - cell->parameters["\\A_WIDTH"] = sig_a.size(); \ - cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ - cell->setPort("\\A", sig_a); \ - cell->setPort("\\Y", sig_y); \ + cell->parameters[ID(A_SIGNED)] = is_signed; \ + cell->parameters[ID(A_WIDTH)] = sig_a.size(); \ + cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::Y, sig_y); \ cell->set_src_attribute(src); \ return cell; \ } \ @@ -1829,28 +1841,28 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth add ## _func(name, sig_a, sig_y, is_signed, src); \ return sig_y; \ } -DEF_METHOD(Not, sig_a.size(), "$not") -DEF_METHOD(Pos, sig_a.size(), "$pos") -DEF_METHOD(Neg, sig_a.size(), "$neg") -DEF_METHOD(ReduceAnd, 1, "$reduce_and") -DEF_METHOD(ReduceOr, 1, "$reduce_or") -DEF_METHOD(ReduceXor, 1, "$reduce_xor") -DEF_METHOD(ReduceXnor, 1, "$reduce_xnor") -DEF_METHOD(ReduceBool, 1, "$reduce_bool") -DEF_METHOD(LogicNot, 1, "$logic_not") +DEF_METHOD(Not, sig_a.size(), ID($not)) +DEF_METHOD(Pos, sig_a.size(), ID($pos)) +DEF_METHOD(Neg, sig_a.size(), ID($neg)) +DEF_METHOD(ReduceAnd, 1, ID($reduce_and)) +DEF_METHOD(ReduceOr, 1, ID($reduce_or)) +DEF_METHOD(ReduceXor, 1, ID($reduce_xor)) +DEF_METHOD(ReduceXnor, 1, ID($reduce_xnor)) +DEF_METHOD(ReduceBool, 1, ID($reduce_bool)) +DEF_METHOD(LogicNot, 1, ID($logic_not)) #undef DEF_METHOD #define DEF_METHOD(_func, _y_size, _type) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ - cell->parameters["\\A_SIGNED"] = is_signed; \ - cell->parameters["\\B_SIGNED"] = is_signed; \ - cell->parameters["\\A_WIDTH"] = sig_a.size(); \ - cell->parameters["\\B_WIDTH"] = sig_b.size(); \ - cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ - cell->setPort("\\A", sig_a); \ - cell->setPort("\\B", sig_b); \ - cell->setPort("\\Y", sig_y); \ + cell->parameters[ID(A_SIGNED)] = is_signed; \ + cell->parameters[ID(B_SIGNED)] = is_signed; \ + cell->parameters[ID(A_WIDTH)] = sig_a.size(); \ + cell->parameters[ID(B_WIDTH)] = sig_b.size(); \ + cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::B, sig_b); \ + cell->setPort(ID::Y, sig_y); \ cell->set_src_attribute(src); \ return cell; \ } \ @@ -1859,42 +1871,42 @@ DEF_METHOD(LogicNot, 1, "$logic_not") add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ return sig_y; \ } -DEF_METHOD(And, max(sig_a.size(), sig_b.size()), "$and") -DEF_METHOD(Or, max(sig_a.size(), sig_b.size()), "$or") -DEF_METHOD(Xor, max(sig_a.size(), sig_b.size()), "$xor") -DEF_METHOD(Xnor, max(sig_a.size(), sig_b.size()), "$xnor") -DEF_METHOD(Shl, sig_a.size(), "$shl") -DEF_METHOD(Shr, sig_a.size(), "$shr") -DEF_METHOD(Sshl, sig_a.size(), "$sshl") -DEF_METHOD(Sshr, sig_a.size(), "$sshr") -DEF_METHOD(Shift, sig_a.size(), "$shift") -DEF_METHOD(Shiftx, sig_a.size(), "$shiftx") -DEF_METHOD(Lt, 1, "$lt") -DEF_METHOD(Le, 1, "$le") -DEF_METHOD(Eq, 1, "$eq") -DEF_METHOD(Ne, 1, "$ne") -DEF_METHOD(Eqx, 1, "$eqx") -DEF_METHOD(Nex, 1, "$nex") -DEF_METHOD(Ge, 1, "$ge") -DEF_METHOD(Gt, 1, "$gt") -DEF_METHOD(Add, max(sig_a.size(), sig_b.size()), "$add") -DEF_METHOD(Sub, max(sig_a.size(), sig_b.size()), "$sub") -DEF_METHOD(Mul, max(sig_a.size(), sig_b.size()), "$mul") -DEF_METHOD(Div, max(sig_a.size(), sig_b.size()), "$div") -DEF_METHOD(Mod, max(sig_a.size(), sig_b.size()), "$mod") -DEF_METHOD(LogicAnd, 1, "$logic_and") -DEF_METHOD(LogicOr, 1, "$logic_or") +DEF_METHOD(And, max(sig_a.size(), sig_b.size()), ID($and)) +DEF_METHOD(Or, max(sig_a.size(), sig_b.size()), ID($or)) +DEF_METHOD(Xor, max(sig_a.size(), sig_b.size()), ID($xor)) +DEF_METHOD(Xnor, max(sig_a.size(), sig_b.size()), ID($xnor)) +DEF_METHOD(Shl, sig_a.size(), ID($shl)) +DEF_METHOD(Shr, sig_a.size(), ID($shr)) +DEF_METHOD(Sshl, sig_a.size(), ID($sshl)) +DEF_METHOD(Sshr, sig_a.size(), ID($sshr)) +DEF_METHOD(Shift, sig_a.size(), ID($shift)) +DEF_METHOD(Shiftx, sig_a.size(), ID($shiftx)) +DEF_METHOD(Lt, 1, ID($lt)) +DEF_METHOD(Le, 1, ID($le)) +DEF_METHOD(Eq, 1, ID($eq)) +DEF_METHOD(Ne, 1, ID($ne)) +DEF_METHOD(Eqx, 1, ID($eqx)) +DEF_METHOD(Nex, 1, ID($nex)) +DEF_METHOD(Ge, 1, ID($ge)) +DEF_METHOD(Gt, 1, ID($gt)) +DEF_METHOD(Add, max(sig_a.size(), sig_b.size()), ID($add)) +DEF_METHOD(Sub, max(sig_a.size(), sig_b.size()), ID($sub)) +DEF_METHOD(Mul, max(sig_a.size(), sig_b.size()), ID($mul)) +DEF_METHOD(Div, max(sig_a.size(), sig_b.size()), ID($div)) +DEF_METHOD(Mod, max(sig_a.size(), sig_b.size()), ID($mod)) +DEF_METHOD(LogicAnd, 1, ID($logic_and)) +DEF_METHOD(LogicOr, 1, ID($logic_or)) #undef DEF_METHOD #define DEF_METHOD(_func, _type, _pmux) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src) { \ RTLIL::Cell *cell = addCell(name, _type); \ - cell->parameters["\\WIDTH"] = sig_a.size(); \ - if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.size(); \ - cell->setPort("\\A", sig_a); \ - cell->setPort("\\B", sig_b); \ - cell->setPort("\\S", sig_s); \ - cell->setPort("\\Y", sig_y); \ + cell->parameters[ID(WIDTH)] = sig_a.size(); \ + if (_pmux) cell->parameters[ID(S_WIDTH)] = sig_s.size(); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::B, sig_b); \ + cell->setPort(ID(S), sig_s); \ + cell->setPort(ID::Y, sig_y); \ cell->set_src_attribute(src); \ return cell; \ } \ @@ -1903,8 +1915,8 @@ DEF_METHOD(LogicOr, 1, "$logic_or") add ## _func(name, sig_a, sig_b, sig_s, sig_y, src); \ return sig_y; \ } -DEF_METHOD(Mux, "$mux", 0) -DEF_METHOD(Pmux, "$pmux", 1) +DEF_METHOD(Mux, ID($mux), 0) +DEF_METHOD(Pmux, ID($pmux), 1) #undef DEF_METHOD #define DEF_METHOD_2(_func, _type, _P1, _P2) \ @@ -1965,21 +1977,22 @@ DEF_METHOD(Pmux, "$pmux", 1) add ## _func(name, sig1, sig2, sig3, sig4, sig5, src); \ return sig5; \ } -DEF_METHOD_2(BufGate, "$_BUF_", A, Y) -DEF_METHOD_2(NotGate, "$_NOT_", A, Y) -DEF_METHOD_3(AndGate, "$_AND_", A, B, Y) -DEF_METHOD_3(NandGate, "$_NAND_", A, B, Y) -DEF_METHOD_3(OrGate, "$_OR_", A, B, Y) -DEF_METHOD_3(NorGate, "$_NOR_", A, B, Y) -DEF_METHOD_3(XorGate, "$_XOR_", A, B, Y) -DEF_METHOD_3(XnorGate, "$_XNOR_", A, B, Y) -DEF_METHOD_3(AndnotGate, "$_ANDNOT_", A, B, Y) -DEF_METHOD_3(OrnotGate, "$_ORNOT_", A, B, Y) -DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y) -DEF_METHOD_4(Aoi3Gate, "$_AOI3_", A, B, C, Y) -DEF_METHOD_4(Oai3Gate, "$_OAI3_", A, B, C, Y) -DEF_METHOD_5(Aoi4Gate, "$_AOI4_", A, B, C, D, Y) -DEF_METHOD_5(Oai4Gate, "$_OAI4_", A, B, C, D, Y) +DEF_METHOD_2(BufGate, ID($_BUF_), A, Y) +DEF_METHOD_2(NotGate, ID($_NOT_), A, Y) +DEF_METHOD_3(AndGate, ID($_AND_), A, B, Y) +DEF_METHOD_3(NandGate, ID($_NAND_), A, B, Y) +DEF_METHOD_3(OrGate, ID($_OR_), A, B, Y) +DEF_METHOD_3(NorGate, ID($_NOR_), A, B, Y) +DEF_METHOD_3(XorGate, ID($_XOR_), A, B, Y) +DEF_METHOD_3(XnorGate, ID($_XNOR_), A, B, Y) +DEF_METHOD_3(AndnotGate, ID($_ANDNOT_), A, B, Y) +DEF_METHOD_3(OrnotGate, ID($_ORNOT_), A, B, Y) +DEF_METHOD_4(MuxGate, ID($_MUX_), A, B, S, Y) +DEF_METHOD_4(NmuxGate, ID($_NMUX_), A, B, S, Y) +DEF_METHOD_4(Aoi3Gate, ID($_AOI3_), A, B, C, Y) +DEF_METHOD_4(Oai3Gate, ID($_OAI3_), A, B, C, Y) +DEF_METHOD_5(Aoi4Gate, ID($_AOI4_), A, B, C, D, Y) +DEF_METHOD_5(Oai4Gate, ID($_OAI4_), A, B, C, D, Y) #undef DEF_METHOD_2 #undef DEF_METHOD_3 #undef DEF_METHOD_4 @@ -1987,165 +2000,165 @@ DEF_METHOD_5(Oai4Gate, "$_OAI4_", A, B, C, D, Y) RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed, bool b_signed, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$pow"); - cell->parameters["\\A_SIGNED"] = a_signed; - cell->parameters["\\B_SIGNED"] = b_signed; - cell->parameters["\\A_WIDTH"] = sig_a.size(); - cell->parameters["\\B_WIDTH"] = sig_b.size(); - cell->parameters["\\Y_WIDTH"] = sig_y.size(); - cell->setPort("\\A", sig_a); - cell->setPort("\\B", sig_b); - cell->setPort("\\Y", sig_y); + RTLIL::Cell *cell = addCell(name, ID($pow)); + cell->parameters[ID(A_SIGNED)] = a_signed; + cell->parameters[ID(B_SIGNED)] = b_signed; + cell->parameters[ID(A_WIDTH)] = sig_a.size(); + cell->parameters[ID(B_WIDTH)] = sig_b.size(); + cell->parameters[ID(Y_WIDTH)] = sig_y.size(); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$slice"); - cell->parameters["\\A_WIDTH"] = sig_a.size(); - cell->parameters["\\Y_WIDTH"] = sig_y.size(); - cell->parameters["\\OFFSET"] = offset; - cell->setPort("\\A", sig_a); - cell->setPort("\\Y", sig_y); + RTLIL::Cell *cell = addCell(name, ID($slice)); + cell->parameters[ID(A_WIDTH)] = sig_a.size(); + cell->parameters[ID(Y_WIDTH)] = sig_y.size(); + cell->parameters[ID(OFFSET)] = offset; + cell->setPort(ID::A, sig_a); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$concat"); - cell->parameters["\\A_WIDTH"] = sig_a.size(); - cell->parameters["\\B_WIDTH"] = sig_b.size(); - cell->setPort("\\A", sig_a); - cell->setPort("\\B", sig_b); - cell->setPort("\\Y", sig_y); + RTLIL::Cell *cell = addCell(name, ID($concat)); + cell->parameters[ID(A_WIDTH)] = sig_a.size(); + cell->parameters[ID(B_WIDTH)] = sig_b.size(); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const lut, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$lut"); - cell->parameters["\\LUT"] = lut; - cell->parameters["\\WIDTH"] = sig_a.size(); - cell->setPort("\\A", sig_a); - cell->setPort("\\Y", sig_y); + RTLIL::Cell *cell = addCell(name, ID($lut)); + cell->parameters[ID(LUT)] = lut; + cell->parameters[ID(WIDTH)] = sig_a.size(); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_y, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$tribuf"); - cell->parameters["\\WIDTH"] = sig_a.size(); - cell->setPort("\\A", sig_a); - cell->setPort("\\EN", sig_en); - cell->setPort("\\Y", sig_y); + RTLIL::Cell *cell = addCell(name, ID($tribuf)); + cell->parameters[ID(WIDTH)] = sig_a.size(); + cell->setPort(ID::A, sig_a); + cell->setPort(ID(EN), sig_en); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$assert"); - cell->setPort("\\A", sig_a); - cell->setPort("\\EN", sig_en); + RTLIL::Cell *cell = addCell(name, ID($assert)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID(EN), sig_en); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$assume"); - cell->setPort("\\A", sig_a); - cell->setPort("\\EN", sig_en); + RTLIL::Cell *cell = addCell(name, ID($assume)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID(EN), sig_en); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$live"); - cell->setPort("\\A", sig_a); - cell->setPort("\\EN", sig_en); + RTLIL::Cell *cell = addCell(name, ID($live)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID(EN), sig_en); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$fair"); - cell->setPort("\\A", sig_a); - cell->setPort("\\EN", sig_en); + RTLIL::Cell *cell = addCell(name, ID($fair)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID(EN), sig_en); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$cover"); - cell->setPort("\\A", sig_a); - cell->setPort("\\EN", sig_en); + RTLIL::Cell *cell = addCell(name, ID($cover)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID(EN), sig_en); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$equiv"); - cell->setPort("\\A", sig_a); - cell->setPort("\\B", sig_b); - cell->setPort("\\Y", sig_y); + RTLIL::Cell *cell = addCell(name, ID($equiv)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity, bool clr_polarity, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$sr"); - cell->parameters["\\SET_POLARITY"] = set_polarity; - cell->parameters["\\CLR_POLARITY"] = clr_polarity; - cell->parameters["\\WIDTH"] = sig_q.size(); - cell->setPort("\\SET", sig_set); - cell->setPort("\\CLR", sig_clr); - cell->setPort("\\Q", sig_q); + RTLIL::Cell *cell = addCell(name, ID($sr)); + cell->parameters[ID(SET_POLARITY)] = set_polarity; + cell->parameters[ID(CLR_POLARITY)] = clr_polarity; + cell->parameters[ID(WIDTH)] = sig_q.size(); + cell->setPort(ID(SET), sig_set); + cell->setPort(ID(CLR), sig_clr); + cell->setPort(ID(Q), sig_q); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addFf(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$ff"); - cell->parameters["\\WIDTH"] = sig_q.size(); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + RTLIL::Cell *cell = addCell(name, ID($ff)); + cell->parameters[ID(WIDTH)] = sig_q.size(); + cell->setPort(ID(D), sig_d); + cell->setPort(ID(Q), sig_q); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$dff"); - cell->parameters["\\CLK_POLARITY"] = clk_polarity; - cell->parameters["\\WIDTH"] = sig_q.size(); - cell->setPort("\\CLK", sig_clk); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + RTLIL::Cell *cell = addCell(name, ID($dff)); + cell->parameters[ID(CLK_POLARITY)] = clk_polarity; + cell->parameters[ID(WIDTH)] = sig_q.size(); + cell->setPort(ID(CLK), sig_clk); + cell->setPort(ID(D), sig_d); + cell->setPort(ID(Q), sig_q); cell->set_src_attribute(src); return cell; } RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$dffe"); - cell->parameters["\\CLK_POLARITY"] = clk_polarity; - cell->parameters["\\EN_POLARITY"] = en_polarity; - cell->parameters["\\WIDTH"] = sig_q.size(); - cell->setPort("\\CLK", sig_clk); - cell->setPort("\\EN", sig_en); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + RTLIL::Cell *cell = addCell(name, ID($dffe)); + cell->parameters[ID(CLK_POLARITY)] = clk_polarity; + cell->parameters[ID(EN_POLARITY)] = en_polarity; + cell->parameters[ID(WIDTH)] = sig_q.size(); + cell->setPort(ID(CLK), sig_clk); + cell->setPort(ID(EN), sig_en); + cell->setPort(ID(D), sig_d); + cell->setPort(ID(Q), sig_q); cell->set_src_attribute(src); return cell; } @@ -2153,16 +2166,16 @@ RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$dffsr"); - cell->parameters["\\CLK_POLARITY"] = clk_polarity; - cell->parameters["\\SET_POLARITY"] = set_polarity; - cell->parameters["\\CLR_POLARITY"] = clr_polarity; - cell->parameters["\\WIDTH"] = sig_q.size(); - cell->setPort("\\CLK", sig_clk); - cell->setPort("\\SET", sig_set); - cell->setPort("\\CLR", sig_clr); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + RTLIL::Cell *cell = addCell(name, ID($dffsr)); + cell->parameters[ID(CLK_POLARITY)] = clk_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(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; } @@ -2170,27 +2183,27 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_cl RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$adff"); - cell->parameters["\\CLK_POLARITY"] = clk_polarity; - cell->parameters["\\ARST_POLARITY"] = arst_polarity; - cell->parameters["\\ARST_VALUE"] = arst_value; - cell->parameters["\\WIDTH"] = sig_q.size(); - cell->setPort("\\CLK", sig_clk); - cell->setPort("\\ARST", sig_arst); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + RTLIL::Cell *cell = addCell(name, ID($adff)); + cell->parameters[ID(CLK_POLARITY)] = clk_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(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::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$dlatch"); - cell->parameters["\\EN_POLARITY"] = en_polarity; - cell->parameters["\\WIDTH"] = sig_q.size(); - cell->setPort("\\EN", sig_en); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + RTLIL::Cell *cell = addCell(name, ID($dlatch)); + cell->parameters[ID(EN_POLARITY)] = en_polarity; + cell->parameters[ID(WIDTH)] = sig_q.size(); + cell->setPort(ID(EN), sig_en); + cell->setPort(ID(D), sig_d); + cell->setPort(ID(Q), sig_q); cell->set_src_attribute(src); return cell; } @@ -2198,25 +2211,25 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$dlatchsr"); - cell->parameters["\\EN_POLARITY"] = en_polarity; - cell->parameters["\\SET_POLARITY"] = set_polarity; - cell->parameters["\\CLR_POLARITY"] = clr_polarity; - cell->parameters["\\WIDTH"] = sig_q.size(); - cell->setPort("\\EN", sig_en); - cell->setPort("\\SET", sig_set); - cell->setPort("\\CLR", sig_clr); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + RTLIL::Cell *cell = addCell(name, ID($dlatchsr)); + 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(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::addFfGate(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src) { - RTLIL::Cell *cell = addCell(name, "$_FF_"); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + RTLIL::Cell *cell = addCell(name, ID($_FF_)); + cell->setPort(ID(D), sig_d); + cell->setPort(ID(Q), sig_q); cell->set_src_attribute(src); return cell; } @@ -2224,9 +2237,9 @@ RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, RTLIL::SigSpec sig_d RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')); - cell->setPort("\\C", sig_clk); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + cell->setPort(ID(C), sig_clk); + cell->setPort(ID(D), sig_d); + cell->setPort(ID(Q), sig_q); cell->set_src_attribute(src); return cell; } @@ -2234,10 +2247,10 @@ RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_ RTLIL::Cell* RTLIL::Module::addDffeGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); - cell->setPort("\\C", sig_clk); - cell->setPort("\\E", sig_en); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + cell->setPort(ID(C), sig_clk); + 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; } @@ -2246,11 +2259,11 @@ RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec si RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); - cell->setPort("\\C", sig_clk); - cell->setPort("\\S", sig_set); - cell->setPort("\\R", sig_clr); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + cell->setPort(ID(C), sig_clk); + cell->setPort(ID(S), sig_set); + cell->setPort(ID(R), sig_clr); + cell->setPort(ID(D), sig_d); + cell->setPort(ID(Q), sig_q); cell->set_src_attribute(src); return cell; } @@ -2259,10 +2272,10 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig bool arst_value, bool clk_polarity, bool arst_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); - cell->setPort("\\C", sig_clk); - cell->setPort("\\R", sig_arst); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + cell->setPort(ID(C), sig_clk); + 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; } @@ -2270,9 +2283,9 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')); - cell->setPort("\\E", sig_en); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + 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; } @@ -2281,11 +2294,11 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src) { RTLIL::Cell *cell = addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); - cell->setPort("\\E", sig_en); - cell->setPort("\\S", sig_set); - cell->setPort("\\R", sig_clr); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + cell->setPort(ID(E), sig_en); + cell->setPort(ID(S), sig_set); + cell->setPort(ID(R), sig_clr); + cell->setPort(ID(D), sig_d); + cell->setPort(ID(Q), sig_q); cell->set_src_attribute(src); return cell; } @@ -2293,9 +2306,9 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const std::string &src) { RTLIL::SigSpec sig = addWire(NEW_ID, width); - Cell *cell = addCell(name, "$anyconst"); - cell->setParam("\\WIDTH", width); - cell->setPort("\\Y", sig); + Cell *cell = addCell(name, ID($anyconst)); + cell->setParam(ID(WIDTH), width); + cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } @@ -2303,9 +2316,9 @@ RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const st RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const std::string &src) { RTLIL::SigSpec sig = addWire(NEW_ID, width); - Cell *cell = addCell(name, "$anyseq"); - cell->setParam("\\WIDTH", width); - cell->setPort("\\Y", sig); + Cell *cell = addCell(name, ID($anyseq)); + cell->setParam(ID(WIDTH), width); + cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } @@ -2313,9 +2326,9 @@ RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const std: RTLIL::SigSpec RTLIL::Module::Allconst(RTLIL::IdString name, int width, const std::string &src) { RTLIL::SigSpec sig = addWire(NEW_ID, width); - Cell *cell = addCell(name, "$allconst"); - cell->setParam("\\WIDTH", width); - cell->setPort("\\Y", sig); + Cell *cell = addCell(name, ID($allconst)); + cell->setParam(ID(WIDTH), width); + cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } @@ -2323,9 +2336,9 @@ RTLIL::SigSpec RTLIL::Module::Allconst(RTLIL::IdString name, int width, const st RTLIL::SigSpec RTLIL::Module::Allseq(RTLIL::IdString name, int width, const std::string &src) { RTLIL::SigSpec sig = addWire(NEW_ID, width); - Cell *cell = addCell(name, "$allseq"); - cell->setParam("\\WIDTH", width); - cell->setPort("\\Y", sig); + Cell *cell = addCell(name, ID($allseq)); + cell->setParam(ID(WIDTH), width); + cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } @@ -2333,8 +2346,8 @@ RTLIL::SigSpec RTLIL::Module::Allseq(RTLIL::IdString name, int width, const std: RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const std::string &src) { RTLIL::SigSpec sig = addWire(NEW_ID); - Cell *cell = addCell(name, "$initstate"); - cell->setPort("\\Y", sig); + Cell *cell = addCell(name, ID($initstate)); + cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } @@ -2551,60 +2564,60 @@ void RTLIL::Cell::check() void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) { - if (type.substr(0, 1) != "$" || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" || type.substr(0,10) == "$fmcombine" || - type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:") + if (!type.begins_with("$") || type.begins_with("$_") || type.begins_with("$paramod") || type.begins_with("$fmcombine") || + type.begins_with("$verific$") || type.begins_with("$array:") || type.begins_with("$extern:")) return; - if (type == "$mux" || type == "$pmux") { - parameters["\\WIDTH"] = GetSize(connections_["\\Y"]); - if (type == "$pmux") - parameters["\\S_WIDTH"] = GetSize(connections_["\\S"]); + if (type == ID($mux) || type == ID($pmux)) { + parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]); + if (type == ID($pmux)) + parameters[ID(S_WIDTH)] = GetSize(connections_[ID(S)]); check(); return; } - if (type == "$lut" || type == "$sop") { - parameters["\\WIDTH"] = GetSize(connections_["\\A"]); + if (type == ID($lut) || type == ID($sop)) { + parameters[ID(WIDTH)] = GetSize(connections_[ID::A]); return; } - if (type == "$fa") { - parameters["\\WIDTH"] = GetSize(connections_["\\Y"]); + if (type == ID($fa)) { + parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]); return; } - if (type == "$lcu") { - parameters["\\WIDTH"] = GetSize(connections_["\\CO"]); + if (type == ID($lcu)) { + parameters[ID(WIDTH)] = GetSize(connections_[ID(CO)]); return; } - bool signedness_ab = !type.in("$slice", "$concat", "$macc"); + bool signedness_ab = !type.in(ID($slice), ID($concat), ID($macc)); - if (connections_.count("\\A")) { + if (connections_.count(ID::A)) { if (signedness_ab) { if (set_a_signed) - parameters["\\A_SIGNED"] = true; - else if (parameters.count("\\A_SIGNED") == 0) - parameters["\\A_SIGNED"] = false; + parameters[ID(A_SIGNED)] = true; + else if (parameters.count(ID(A_SIGNED)) == 0) + parameters[ID(A_SIGNED)] = false; } - parameters["\\A_WIDTH"] = GetSize(connections_["\\A"]); + parameters[ID(A_WIDTH)] = GetSize(connections_[ID::A]); } - if (connections_.count("\\B")) { + if (connections_.count(ID::B)) { if (signedness_ab) { if (set_b_signed) - parameters["\\B_SIGNED"] = true; - else if (parameters.count("\\B_SIGNED") == 0) - parameters["\\B_SIGNED"] = false; + parameters[ID(B_SIGNED)] = true; + else if (parameters.count(ID(B_SIGNED)) == 0) + parameters[ID(B_SIGNED)] = false; } - parameters["\\B_WIDTH"] = GetSize(connections_["\\B"]); + parameters[ID(B_WIDTH)] = GetSize(connections_[ID::B]); } - if (connections_.count("\\Y")) - parameters["\\Y_WIDTH"] = GetSize(connections_["\\Y"]); + if (connections_.count(ID::Y)) + parameters[ID(Y_WIDTH)] = GetSize(connections_[ID::Y]); - if (connections_.count("\\Q")) - parameters["\\WIDTH"] = GetSize(connections_["\\Q"]); + if (connections_.count(ID(Q))) + parameters[ID(WIDTH)] = GetSize(connections_[ID(Q)]); check(); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 82cbfaf28..c08653b65 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -78,6 +78,8 @@ namespace RTLIL { #undef YOSYS_XTRACE_GET_PUT #undef YOSYS_SORT_ID_FREE_LIST + #undef YOSYS_USE_STICKY_IDS + #undef YOSYS_NO_IDS_REFCNT // the global id string cache @@ -87,13 +89,17 @@ namespace RTLIL ~destruct_guard_t() { ok = false; } } destruct_guard; - static std::vector global_refcount_storage_; static std::vector global_id_storage_; static dict global_id_index_; + #ifndef YOSYS_NO_IDS_REFCNT + static std::vector global_refcount_storage_; static std::vector global_free_idx_list_; + #endif + #ifdef YOSYS_USE_STICKY_IDS static int last_created_idx_ptr_; static int last_created_idx_[8]; + #endif static inline void xtrace_db_dump() { @@ -110,12 +116,14 @@ namespace RTLIL static inline void checkpoint() { + #ifdef YOSYS_USE_STICKY_IDS last_created_idx_ptr_ = 0; for (int i = 0; i < 8; i++) { if (last_created_idx_[i]) put_reference(last_created_idx_[i]); last_created_idx_[i] = 0; } + #endif #ifdef YOSYS_SORT_ID_FREE_LIST std::sort(global_free_idx_list_.begin(), global_free_idx_list_.end(), std::greater()); #endif @@ -123,36 +131,47 @@ namespace RTLIL static inline int get_reference(int idx) { - global_refcount_storage_.at(idx)++; - #ifdef YOSYS_XTRACE_GET_PUT - if (yosys_xtrace) { - log("#X# GET-BY-INDEX '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); - } + if (idx) { + #ifndef YOSYS_NO_IDS_REFCNT + global_refcount_storage_[idx]++; #endif + #ifdef YOSYS_XTRACE_GET_PUT + if (yosys_xtrace) + log("#X# GET-BY-INDEX '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); + #endif + } return idx; } - static inline int get_reference(const char *p) + static int get_reference(const char *p) { log_assert(destruct_guard.ok); - if (p[0]) { - log_assert(p[1] != 0); - log_assert(p[0] == '$' || p[0] == '\\'); - } + if (!p[0]) + return 0; + + log_assert(p[0] == '$' || p[0] == '\\'); + log_assert(p[1] != 0); auto it = global_id_index_.find((char*)p); if (it != global_id_index_.end()) { + #ifndef YOSYS_NO_IDS_REFCNT global_refcount_storage_.at(it->second)++; + #endif #ifdef YOSYS_XTRACE_GET_PUT - if (yosys_xtrace) { + if (yosys_xtrace) log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(it->second), it->second, global_refcount_storage_.at(it->second)); - } #endif return it->second; } + #ifndef YOSYS_NO_IDS_REFCNT if (global_free_idx_list_.empty()) { + if (global_id_storage_.empty()) { + global_refcount_storage_.push_back(0); + global_id_storage_.push_back((char*)""); + global_id_index_[global_id_storage_.back()] = 0; + } log_assert(global_id_storage_.size() < 0x40000000); global_free_idx_list_.push_back(global_id_storage_.size()); global_id_storage_.push_back(nullptr); @@ -164,13 +183,15 @@ namespace RTLIL global_id_storage_.at(idx) = strdup(p); global_id_index_[global_id_storage_.at(idx)] = idx; global_refcount_storage_.at(idx)++; - - // Avoid Create->Delete->Create pattern - if (last_created_idx_[last_created_idx_ptr_]) - put_reference(last_created_idx_[last_created_idx_ptr_]); - last_created_idx_[last_created_idx_ptr_] = idx; - get_reference(last_created_idx_[last_created_idx_ptr_]); - last_created_idx_ptr_ = (last_created_idx_ptr_ + 1) & 7; + #else + if (global_id_storage_.empty()) { + global_id_storage_.push_back((char*)""); + global_id_index_[global_id_storage_.back()] = 0; + } + int idx = global_id_storage_.size(); + global_id_storage_.push_back(strdup(p)); + global_id_index_[global_id_storage_.back()] = idx; + #endif if (yosys_xtrace) { log("#X# New IdString '%s' with index %d.\n", p, idx); @@ -178,18 +199,28 @@ namespace RTLIL } #ifdef YOSYS_XTRACE_GET_PUT - if (yosys_xtrace) { + if (yosys_xtrace) log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); - } #endif + + #ifdef YOSYS_USE_STICKY_IDS + // Avoid Create->Delete->Create pattern + if (last_created_idx_[last_created_idx_ptr_]) + put_reference(last_created_idx_[last_created_idx_ptr_]); + last_created_idx_[last_created_idx_ptr_] = idx; + get_reference(last_created_idx_[last_created_idx_ptr_]); + last_created_idx_ptr_ = (last_created_idx_ptr_ + 1) & 7; + #endif + return idx; } + #ifndef YOSYS_NO_IDS_REFCNT static inline void put_reference(int idx) { // put_reference() may be called from destructors after the destructor of // global_refcount_storage_ has been run. in this case we simply do nothing. - if (!destruct_guard.ok) + if (!destruct_guard.ok || !idx) return; #ifdef YOSYS_XTRACE_GET_PUT @@ -198,11 +229,13 @@ namespace RTLIL } #endif - log_assert(global_refcount_storage_.at(idx) > 0); + int &refcount = global_refcount_storage_[idx]; - if (--global_refcount_storage_.at(idx) != 0) + if (--refcount > 0) return; + log_assert(refcount == 0); + if (yosys_xtrace) { log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx); log_backtrace("-X- ", yosys_xtrace-1); @@ -213,46 +246,50 @@ namespace RTLIL global_id_storage_.at(idx) = nullptr; global_free_idx_list_.push_back(idx); } + #else + static inline void put_reference(int) { } + #endif // the actual IdString object is just is a single int int index_; - IdString() : index_(get_reference("")) { } - IdString(const char *str) : index_(get_reference(str)) { } - IdString(const IdString &str) : index_(get_reference(str.index_)) { } - IdString(const std::string &str) : index_(get_reference(str.c_str())) { } - ~IdString() { put_reference(index_); } + inline IdString() : index_(0) { } + inline IdString(const char *str) : index_(get_reference(str)) { } + inline IdString(const IdString &str) : index_(get_reference(str.index_)) { } + inline IdString(IdString &&str) : index_(str.index_) { str.index_ = 0; } + inline IdString(const std::string &str) : index_(get_reference(str.c_str())) { } + inline ~IdString() { put_reference(index_); } - void operator=(const IdString &rhs) { + inline void operator=(const IdString &rhs) { put_reference(index_); index_ = get_reference(rhs.index_); } - void operator=(const char *rhs) { + inline void operator=(const char *rhs) { IdString id(rhs); *this = id; } - void operator=(const std::string &rhs) { + inline void operator=(const std::string &rhs) { IdString id(rhs); *this = id; } - const char *c_str() const { + inline const char *c_str() const { return global_id_storage_.at(index_); } - std::string str() const { + inline std::string str() const { return std::string(global_id_storage_.at(index_)); } - bool operator<(const IdString &rhs) const { + inline bool operator<(const IdString &rhs) const { return index_ < rhs.index_; } - bool operator==(const IdString &rhs) const { return index_ == rhs.index_; } - bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; } + inline bool operator==(const IdString &rhs) const { return index_ == rhs.index_; } + inline bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; } // The methods below are just convenience functions for better compatibility with std::string. @@ -276,20 +313,24 @@ namespace RTLIL return std::string(c_str() + pos, len); } + int compare(size_t pos, size_t len, const char* s) const { + return strncmp(c_str()+pos, s, len); + } + bool begins_with(const char* prefix) const { size_t len = strlen(prefix); if (size() < len) return false; - return substr(0, len) == prefix; + return compare(0, len, prefix) == 0; } bool ends_with(const char* suffix) const { size_t len = strlen(suffix); if (size() < len) return false; - return substr(size()-len) == suffix; + return compare(size()-len, len, suffix) == 0; } size_t size() const { - return str().size(); + return strlen(c_str()); } bool empty() const { @@ -328,6 +369,14 @@ namespace RTLIL bool in(const pool &rhs) const { return rhs.count(*this) != 0; } }; + namespace ID { + // defined in rtlil.cc, initialized in yosys.cc + extern IdString A, B, Y; + extern IdString keep; + extern IdString whitebox; + extern IdString blackbox; + }; + static inline std::string escape_id(std::string str) { if (str.size() > 0 && str[0] != '\\' && str[0] != '$') return "\\" + str; @@ -420,8 +469,12 @@ namespace RTLIL // It maintains a reference counter that is used to make sure that the container is not modified while being iterated over. template - struct ObjIterator - { + struct ObjIterator { + using iterator_category = std::forward_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; typename dict::iterator it; dict *list_p; int *refcount_p; @@ -474,13 +527,25 @@ namespace RTLIL return it != other.it; } - inline void operator++() { + + inline bool operator==(const RTLIL::ObjIterator &other) const { + return !(*this != other); + } + + inline ObjIterator& operator++() { log_assert(list_p != nullptr); if (++it == list_p->end()) { (*refcount_p)--; list_p = nullptr; refcount_p = nullptr; } + return *this; + } + + inline const ObjIterator operator++(int) { + ObjIterator result(*this); + ++(*this); + return result; } }; @@ -584,7 +649,7 @@ struct RTLIL::AttrObject bool get_bool_attribute(RTLIL::IdString id) const; bool get_blackbox_attribute(bool ignore_wb=false) const { - return get_bool_attribute("\\blackbox") || (!ignore_wb && get_bool_attribute("\\whitebox")); + return get_bool_attribute(ID::blackbox) || (!ignore_wb && get_bool_attribute(ID::whitebox)); } void set_strpool_attribute(RTLIL::IdString id, const pool &data); @@ -772,6 +837,7 @@ public: RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const; RTLIL::SigSpec extract(const pool &pattern, const RTLIL::SigSpec *other = NULL) const; RTLIL::SigSpec extract(int offset, int length = 1) const; + RTLIL::SigSpec extract_end(int offset) const { return extract(offset, width_ - offset); } void append(const RTLIL::SigSpec &signal); void append_bit(const RTLIL::SigBit &bit); @@ -818,6 +884,7 @@ public: operator std::vector() const { return chunks(); } operator std::vector() const { return bits(); } + RTLIL::SigBit at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; } unsigned int hash() const { if (!hash_) updhash(); return hash_; }; @@ -1138,6 +1205,7 @@ public: RTLIL::Cell* addAndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); RTLIL::Cell* addOrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = ""); + RTLIL::Cell* addNmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = ""); RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = ""); RTLIL::Cell* addOai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = ""); RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y, const std::string &src = ""); @@ -1213,6 +1281,7 @@ public: RTLIL::SigBit AndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); RTLIL::SigBit OrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); RTLIL::SigBit MuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = ""); + RTLIL::SigBit NmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = ""); RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = ""); RTLIL::SigBit Oai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = ""); RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, const std::string &src = ""); @@ -1315,8 +1384,8 @@ public: void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); bool has_keep_attr() const { - return get_bool_attribute("\\keep") || (module && module->design && module->design->module(type) && - module->design->module(type)->get_bool_attribute("\\keep")); + return get_bool_attribute(ID::keep) || (module && module->design && module->design->module(type) && + module->design->module(type)->get_bool_attribute(ID::keep)); } template void rewrite_sigspecs(T &functor); @@ -1384,7 +1453,7 @@ struct RTLIL::Process : public RTLIL::AttrObject inline RTLIL::SigBit::SigBit() : wire(NULL), data(RTLIL::State::S0) { } inline RTLIL::SigBit::SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } -inline RTLIL::SigBit::SigBit(bool bit) : wire(NULL), data(bit ? RTLIL::S1 : RTLIL::S0) { } +inline RTLIL::SigBit::SigBit(bool bit) : wire(NULL), data(bit ? State::S1 : State::S0) { } inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); } inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); } inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } diff --git a/kernel/satgen.h b/kernel/satgen.h index 210cca3f3..133389eee 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -224,8 +224,8 @@ struct SatGen void extendSignalWidth(std::vector &vec_a, std::vector &vec_b, RTLIL::Cell *cell, size_t y_width = 0, bool forced_signed = false) { bool is_signed = forced_signed; - if (!forced_signed && cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters.count("\\B_SIGNED") > 0) - is_signed = cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool(); + if (!forced_signed && cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters.count(ID(B_SIGNED)) > 0) + is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool(); while (vec_a.size() < vec_b.size() || vec_a.size() < y_width) vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE); while (vec_b.size() < vec_a.size() || vec_b.size() < y_width) @@ -241,7 +241,7 @@ struct SatGen void extendSignalWidthUnary(std::vector &vec_a, std::vector &vec_y, RTLIL::Cell *cell, bool forced_signed = false) { - bool is_signed = forced_signed || (cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool()); + bool is_signed = forced_signed || (cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool()); while (vec_a.size() < vec_y.size()) vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE); while (vec_y.size() < vec_a.size()) @@ -277,13 +277,13 @@ struct SatGen bool importCell(RTLIL::Cell *cell, int timestep = -1) { bool arith_undef_handled = false; - bool is_arith_compare = cell->type.in("$lt", "$le", "$ge", "$gt"); + bool is_arith_compare = cell->type.in(ID($lt), ID($le), ID($ge), ID($gt)); - if (model_undef && (cell->type.in("$add", "$sub", "$mul", "$div", "$mod") || is_arith_compare)) + if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod)) || is_arith_compare)) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); if (is_arith_compare) extendSignalWidth(undef_a, undef_b, cell, true); else @@ -293,8 +293,8 @@ struct SatGen 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 == "$div" || cell->type == "$mod") { - std::vector b = importSigSpec(cell->getPort("\\B"), timestep); + if (cell->type.in(ID($div), ID($mod))) { + std::vector b = importSigSpec(cell->getPort(ID::B), timestep); undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b))); } @@ -310,68 +310,68 @@ struct SatGen arith_undef_handled = true; } - if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_", - "$and", "$or", "$xor", "$xnor", "$add", "$sub")) + 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 a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; - if (cell->type == "$and" || cell->type == "$_AND_") + if (cell->type.in(ID($and), ID($_AND_))) ez->assume(ez->vec_eq(ez->vec_and(a, b), yy)); - if (cell->type == "$_NAND_") + if (cell->type == ID($_NAND_)) ez->assume(ez->vec_eq(ez->vec_not(ez->vec_and(a, b)), yy)); - if (cell->type == "$or" || cell->type == "$_OR_") + if (cell->type.in(ID($or), ID($_OR_))) ez->assume(ez->vec_eq(ez->vec_or(a, b), yy)); - if (cell->type == "$_NOR_") + if (cell->type == ID($_NOR_)) ez->assume(ez->vec_eq(ez->vec_not(ez->vec_or(a, b)), yy)); - if (cell->type == "$xor" || cell->type == "$_XOR_") + if (cell->type.in(ID($xor), ID($_XOR_))) ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy)); - if (cell->type == "$xnor" || cell->type == "$_XNOR_") + 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 == "$_ANDNOT_") + if (cell->type == ID($_ANDNOT_)) ez->assume(ez->vec_eq(ez->vec_and(a, ez->vec_not(b)), yy)); - if (cell->type == "$_ORNOT_") + if (cell->type == ID($_ORNOT_)) ez->assume(ez->vec_eq(ez->vec_or(a, ez->vec_not(b)), yy)); - if (cell->type == "$add") + if (cell->type == ID($add)) ez->assume(ez->vec_eq(ez->vec_add(a, b), yy)); - if (cell->type == "$sub") + if (cell->type == ID($sub)) ez->assume(ez->vec_eq(ez->vec_sub(a, b), yy)); if (model_undef && !arith_undef_handled) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(undef_a, undef_b, undef_y, cell, false); - if (cell->type.in("$and", "$_AND_", "$_NAND_")) { + if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_))) { std::vector a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)); std::vector b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b)); std::vector 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("$or", "$_OR_", "$_NOR_")) { + else if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_))) { std::vector a1 = ez->vec_and(a, ez->vec_not(undef_a)); std::vector b1 = ez->vec_and(b, ez->vec_not(undef_b)); std::vector 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("$xor", "$xnor", "$_XOR_", "$_XNOR_")) { + else if (cell->type.in(ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_))) { std::vector yX = ez->vec_or(undef_a, undef_b); ez->assume(ez->vec_eq(yX, undef_y)); } - else if (cell->type == "$_ANDNOT_") { + else if (cell->type == ID($_ANDNOT_)) { std::vector a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)); std::vector b1 = ez->vec_and(b, ez->vec_not(undef_b)); std::vector 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 == "$_ORNOT_") { + else if (cell->type == ID($_ORNOT_)) { std::vector a1 = ez->vec_and(a, ez->vec_not(undef_a)); std::vector b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b)); std::vector yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b0))); @@ -384,36 +384,36 @@ struct SatGen } else if (model_undef) { - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); undefGating(y, yy, undef_y); } return true; } - if (cell->type.in("$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_")) + if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) { - bool aoi_mode = cell->type.in("$_AOI3_", "$_AOI4_"); - bool three_mode = cell->type.in("$_AOI3_", "$_OAI3_"); + 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("\\A"), timestep).at(0); - int b = importDefSigSpec(cell->getPort("\\B"), timestep).at(0); - int c = importDefSigSpec(cell->getPort("\\C"), timestep).at(0); - int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort("\\D"), timestep).at(0); - int y = importDefSigSpec(cell->getPort("\\Y"), timestep).at(0); + 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("$_AOI3_", "$_AOI4_")) + 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("\\A"), timestep).at(0); - int undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep).at(0); - int undef_c = importUndefSigSpec(cell->getPort("\\C"), timestep).at(0); - int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort("\\D"), timestep).at(0); - int undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep).at(0); + 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) { @@ -456,18 +456,18 @@ struct SatGen return true; } - if (cell->type == "$_NOT_" || cell->type == "$not") + if (cell->type.in(ID($_NOT_), ID($not))) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; ez->assume(ez->vec_eq(ez->vec_not(a), yy)); if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector 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); @@ -475,22 +475,25 @@ struct SatGen return true; } - if (cell->type == "$_MUX_" || cell->type == "$mux") + if (cell->type.in(ID($_MUX_), ID($mux), ID($_NMUX_))) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); - std::vector s = importDefSigSpec(cell->getPort("\\S"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector s = importDefSigSpec(cell->getPort(ID(S)), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; - ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy)); + 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 undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); - std::vector undef_s = importUndefSigSpec(cell->getPort("\\S"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); std::vector unequal_ab = ez->vec_not(ez->vec_iff(a, b)); std::vector undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b)); @@ -501,12 +504,12 @@ struct SatGen return true; } - if (cell->type == "$pmux") + if (cell->type == ID($pmux)) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); - std::vector s = importDefSigSpec(cell->getPort("\\S"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector s = importDefSigSpec(cell->getPort(ID(S)), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -519,10 +522,10 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); - std::vector undef_s = importUndefSigSpec(cell->getPort("\\S"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); int maybe_a = ez->CONST_TRUE; @@ -552,15 +555,15 @@ struct SatGen return true; } - if (cell->type == "$pos" || cell->type == "$neg") + if (cell->type.in(ID($pos), ID($neg))) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; - if (cell->type == "$pos") { + if (cell->type == ID($pos)) { ez->assume(ez->vec_eq(a, yy)); } else { std::vector zero(a.size(), ez->CONST_FALSE); @@ -569,11 +572,11 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidthUnary(undef_a, undef_y, cell); - if (cell->type == "$pos") { + 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); @@ -586,42 +589,41 @@ struct SatGen return true; } - if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_xor" || - cell->type == "$reduce_xnor" || cell->type == "$reduce_bool" || cell->type == "$logic_not") + if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; - if (cell->type == "$reduce_and") + if (cell->type == ID($reduce_and)) ez->SET(ez->expression(ez->OpAnd, a), yy.at(0)); - if (cell->type == "$reduce_or" || cell->type == "$reduce_bool") + if (cell->type.in(ID($reduce_or), ID($reduce_bool))) ez->SET(ez->expression(ez->OpOr, a), yy.at(0)); - if (cell->type == "$reduce_xor") + if (cell->type == ID($reduce_xor)) ez->SET(ez->expression(ez->OpXor, a), yy.at(0)); - if (cell->type == "$reduce_xnor") + if (cell->type == ID($reduce_xnor)) ez->SET(ez->NOT(ez->expression(ez->OpXor, a)), yy.at(0)); - if (cell->type == "$logic_not") + 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 undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); int aX = ez->expression(ezSAT::OpOr, undef_a); - if (cell->type == "$reduce_and") { + 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 == "$reduce_or" || cell->type == "$reduce_bool" || cell->type == "$logic_not") { + 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 == "$reduce_xor" || cell->type == "$reduce_xnor") { + else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { ez->assume(ez->IFF(aX, undef_y.at(0))); } else log_abort(); @@ -634,18 +636,18 @@ struct SatGen return true; } - if (cell->type == "$logic_and" || cell->type == "$logic_or") + if (cell->type.in(ID($logic_and), ID($logic_or))) { - std::vector vec_a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector vec_b = importDefSigSpec(cell->getPort("\\B"), timestep); + std::vector vec_a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector 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 y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; - if (cell->type == "$logic_and") + 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)); @@ -654,9 +656,9 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector 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))); @@ -665,9 +667,9 @@ struct SatGen int aX = ez->expression(ezSAT::OpOr, undef_a); int bX = ez->expression(ezSAT::OpOr, undef_b); - if (cell->type == "$logic_and") + 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 == "$logic_or") + 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(); @@ -680,47 +682,47 @@ struct SatGen return true; } - if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt") + 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["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool(); - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + bool is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool(); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(a, b, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; - if (model_undef && (cell->type == "$eqx" || cell->type == "$nex")) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + if (model_undef && cell->type.in(ID($eqx), ID($nex))) { + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector 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 == "$lt") + 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 == "$le") + 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 == "$eq" || cell->type == "$eqx") + if (cell->type.in(ID($eq), ID($eqx))) ez->SET(ez->vec_eq(a, b), yy.at(0)); - if (cell->type == "$ne" || cell->type == "$nex") + if (cell->type.in(ID($ne), ID($nex))) ez->SET(ez->vec_ne(a, b), yy.at(0)); - if (cell->type == "$ge") + 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 == "$gt") + 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 == "$eqx" || cell->type == "$nex")) + if (model_undef && cell->type.in(ID($eqx), ID($nex))) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(undef_a, undef_b, cell, true); - if (cell->type == "$eqx") + 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)); @@ -730,11 +732,11 @@ struct SatGen ez->assume(ez->vec_eq(y, yy)); } - else if (model_undef && (cell->type == "$eq" || cell->type == "$ne")) + else if (model_undef && cell->type.in(ID($eq), ID($ne))) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector 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); @@ -756,7 +758,7 @@ struct SatGen else { if (model_undef) { - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); undefGating(y, yy, undef_y); } log_assert(!model_undef || arith_undef_handled); @@ -764,15 +766,15 @@ struct SatGen return true; } - if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") + if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); int extend_bit = ez->CONST_FALSE; - if (!cell->type.in("$shift", "$shiftx") && cell->parameters["\\A_SIGNED"].as_bool()) + if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID(A_SIGNED)].as_bool()) extend_bit = a.back(); while (y.size() < a.size()) @@ -783,29 +785,29 @@ struct SatGen std::vector yy = model_undef ? ez->vec_var(y.size()) : y; std::vector shifted_a; - if (cell->type == "$shl" || cell->type == "$sshl") + 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 == "$shr") + if (cell->type == ID($shr)) shifted_a = ez->vec_shift_right(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); - if (cell->type == "$sshr") - shifted_a = ez->vec_shift_right(a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? a.back() : 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 == "$shift" || cell->type == "$shiftx") - shifted_a = ez->vec_shift_right(a, b, cell->parameters["\\B_SIGNED"].as_bool(), 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 undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); std::vector undef_a_shifted; - extend_bit = cell->type == "$shiftx" ? ez->CONST_TRUE : ez->CONST_FALSE; - if (!cell->type.in("$shift", "$shiftx") && cell->parameters["\\A_SIGNED"].as_bool()) + 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()) @@ -813,20 +815,20 @@ struct SatGen while (undef_y.size() > undef_a.size()) undef_a.push_back(extend_bit); - if (cell->type == "$shl" || cell->type == "$sshl") + 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 == "$shr") + 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 == "$sshr") - undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? undef_a.back() : 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 == "$shift") - undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), 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 == "$shiftx") - undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE); + 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 undef_all_y_bits(undef_y.size(), undef_any_b); @@ -836,11 +838,11 @@ struct SatGen return true; } - if (cell->type == "$mul") + if (cell->type == ID($mul)) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -857,17 +859,17 @@ struct SatGen if (model_undef) { log_assert(arith_undef_handled); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); undefGating(y, yy, undef_y); } return true; } - if (cell->type == "$macc") + if (cell->type == ID($macc)) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); Macc macc; macc.from_cell(cell); @@ -916,13 +918,13 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector 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 undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); ez->assume(ez->vec_eq(undef_y, std::vector(GetSize(y), ez->OR(undef_any_a, undef_any_b)))); undefGating(y, tmp, undef_y); @@ -933,17 +935,17 @@ struct SatGen return true; } - if (cell->type == "$div" || cell->type == "$mod") + if (cell->type.in(ID($div), ID($mod))) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; std::vector a_u, b_u; - if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) { + 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 { @@ -968,13 +970,13 @@ struct SatGen } std::vector y_tmp = ignore_div_by_zero ? yy : ez->vec_var(y.size()); - if (cell->type == "$div") { - if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) + 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->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) + 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(a.back(), ez->vec_neg(chain_buf), chain_buf))); else ez->assume(ez->vec_eq(y_tmp, chain_buf)); @@ -984,20 +986,20 @@ struct SatGen ez->assume(ez->expression(ezSAT::OpOr, b)); } else { std::vector div_zero_result; - if (cell->type == "$div") { - if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) { + if (cell->type == ID($div)) { + if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool()) { std::vector all_ones(y.size(), ez->CONST_TRUE); std::vector 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("\\A").size(), ez->CONST_TRUE); + 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 { - int copy_a_bits = min(cell->getPort("\\A").size(), cell->getPort("\\B").size()); + 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["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) + 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); @@ -1007,27 +1009,27 @@ struct SatGen if (model_undef) { log_assert(arith_undef_handled); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); undefGating(y, yy, undef_y); } return true; } - if (cell->type == "$lut") + if (cell->type == ID($lut)) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector lut; - for (auto bit : cell->getParam("\\LUT").bits) - lut.push_back(bit == RTLIL::S1 ? ez->CONST_TRUE : ez->CONST_FALSE); + 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 undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); std::vector t(lut), u(GetSize(t), ez->CONST_FALSE); for (int i = GetSize(a)-1; i >= 0; i--) @@ -1045,7 +1047,7 @@ struct SatGen log_assert(GetSize(t) == 1); log_assert(GetSize(u) == 1); undefGating(y, t, u); - ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort("\\Y"), timestep), u)); + ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort(ID::Y), timestep), u)); } else { @@ -1063,15 +1065,15 @@ struct SatGen return true; } - if (cell->type == "$sop") + if (cell->type == ID($sop)) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - int y = importDefSigSpec(cell->getPort("\\Y"), timestep).at(0); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0); - int width = cell->getParam("\\WIDTH").as_int(); - int depth = cell->getParam("\\DEPTH").as_int(); + int width = cell->getParam(ID(WIDTH)).as_int(); + int depth = cell->getParam(ID(DEPTH)).as_int(); - vector table_raw = cell->getParam("\\TABLE").bits; + vector table_raw = cell->getParam(ID(TABLE)).bits; while (GetSize(table_raw) < 2*width*depth) table_raw.push_back(State::S0); @@ -1094,8 +1096,8 @@ struct SatGen if (model_undef) { std::vector products, undef_products; - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - int undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep).at(0); + std::vector 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++) { @@ -1145,13 +1147,13 @@ struct SatGen return true; } - if (cell->type == "$fa") + if (cell->type == ID($fa)) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); - std::vector c = importDefSigSpec(cell->getPort("\\C"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); - std::vector x = importDefSigSpec(cell->getPort("\\X"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector c = importDefSigSpec(cell->getPort(ID(C)), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); + std::vector x = importDefSigSpec(cell->getPort(ID(X)), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; std::vector xx = model_undef ? ez->vec_var(x.size()) : x; @@ -1165,12 +1167,12 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); - std::vector undef_c = importUndefSigSpec(cell->getPort("\\C"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); - std::vector undef_x = importUndefSigSpec(cell->getPort("\\X"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + std::vector 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)); @@ -1181,12 +1183,12 @@ struct SatGen return true; } - if (cell->type == "$lcu") + if (cell->type == ID($lcu)) { - std::vector p = importDefSigSpec(cell->getPort("\\P"), timestep); - std::vector g = importDefSigSpec(cell->getPort("\\G"), timestep); - std::vector ci = importDefSigSpec(cell->getPort("\\CI"), timestep); - std::vector co = importDefSigSpec(cell->getPort("\\CO"), timestep); + std::vector p = importDefSigSpec(cell->getPort(ID(P)), timestep); + std::vector g = importDefSigSpec(cell->getPort(ID(G)), timestep); + std::vector ci = importDefSigSpec(cell->getPort(ID(CI)), timestep); + std::vector co = importDefSigSpec(cell->getPort(ID(CO)), timestep); std::vector yy = model_undef ? ez->vec_var(co.size()) : co; @@ -1195,10 +1197,10 @@ struct SatGen if (model_undef) { - std::vector undef_p = importUndefSigSpec(cell->getPort("\\P"), timestep); - std::vector undef_g = importUndefSigSpec(cell->getPort("\\G"), timestep); - std::vector undef_ci = importUndefSigSpec(cell->getPort("\\CI"), timestep); - std::vector undef_co = importUndefSigSpec(cell->getPort("\\CO"), timestep); + std::vector undef_p = importUndefSigSpec(cell->getPort(ID(P)), timestep); + std::vector undef_g = importUndefSigSpec(cell->getPort(ID(G)), timestep); + std::vector undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep); + std::vector 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); @@ -1213,15 +1215,15 @@ struct SatGen return true; } - if (cell->type == "$alu") + if (cell->type == ID($alu)) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); - std::vector x = importDefSigSpec(cell->getPort("\\X"), timestep); - std::vector ci = importDefSigSpec(cell->getPort("\\CI"), timestep); - std::vector bi = importDefSigSpec(cell->getPort("\\BI"), timestep); - std::vector co = importDefSigSpec(cell->getPort("\\CO"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); + std::vector x = importDefSigSpec(cell->getPort(ID(X)), timestep); + std::vector ci = importDefSigSpec(cell->getPort(ID(CI)), timestep); + std::vector bi = importDefSigSpec(cell->getPort(ID(BI)), timestep); + std::vector co = importDefSigSpec(cell->getPort(ID(CO)), timestep); extendSignalWidth(a, b, y, cell); extendSignalWidth(a, b, x, cell); @@ -1246,14 +1248,14 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); - std::vector undef_ci = importUndefSigSpec(cell->getPort("\\CI"), timestep); - std::vector undef_bi = importUndefSigSpec(cell->getPort("\\BI"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep); + std::vector undef_bi = importUndefSigSpec(cell->getPort(ID(BI)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); - std::vector undef_x = importUndefSigSpec(cell->getPort("\\X"), timestep); - std::vector undef_co = importUndefSigSpec(cell->getPort("\\CO"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); + std::vector undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep); + std::vector undef_co = importUndefSigSpec(cell->getPort(ID(CO)), timestep); extendSignalWidth(undef_a, undef_b, undef_y, cell); extendSignalWidth(undef_a, undef_b, undef_x, cell); @@ -1279,19 +1281,19 @@ struct SatGen return true; } - if (cell->type == "$slice") + if (cell->type == ID($slice)) { - RTLIL::SigSpec a = cell->getPort("\\A"); - RTLIL::SigSpec y = cell->getPort("\\Y"); - ez->assume(signals_eq(a.extract(cell->parameters.at("\\OFFSET").as_int(), y.size()), y, timestep)); + 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 == "$concat") + if (cell->type == ID($concat)) { - RTLIL::SigSpec a = cell->getPort("\\A"); - RTLIL::SigSpec b = cell->getPort("\\B"); - RTLIL::SigSpec y = cell->getPort("\\Y"); + 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); @@ -1300,24 +1302,24 @@ struct SatGen return true; } - if (timestep > 0 && cell->type.in("$ff", "$dff", "$_FF_", "$_DFF_N_", "$_DFF_P_")) + 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("\\Q"))); + initial_state.add((*sigmap)(cell->getPort(ID(Q)))); } else { - std::vector d = importDefSigSpec(cell->getPort("\\D"), timestep-1); - std::vector q = importDefSigSpec(cell->getPort("\\Q"), timestep); + std::vector d = importDefSigSpec(cell->getPort(ID(D)), timestep-1); + std::vector q = importDefSigSpec(cell->getPort(ID(Q)), timestep); std::vector qq = model_undef ? ez->vec_var(q.size()) : q; ez->assume(ez->vec_eq(d, qq)); if (model_undef) { - std::vector undef_d = importUndefSigSpec(cell->getPort("\\D"), timestep-1); - std::vector undef_q = importUndefSigSpec(cell->getPort("\\Q"), timestep); + std::vector undef_d = importUndefSigSpec(cell->getPort(ID(D)), timestep-1); + std::vector undef_q = importUndefSigSpec(cell->getPort(ID(Q)), timestep); ez->assume(ez->vec_eq(undef_d, undef_q)); undefGating(q, qq, undef_q); @@ -1326,21 +1328,21 @@ struct SatGen return true; } - if (cell->type == "$anyconst") + if (cell->type == ID($anyconst)) { if (timestep < 2) return true; - std::vector d = importDefSigSpec(cell->getPort("\\Y"), timestep-1); - std::vector q = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector d = importDefSigSpec(cell->getPort(ID::Y), timestep-1); + std::vector q = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector qq = model_undef ? ez->vec_var(q.size()) : q; ez->assume(ez->vec_eq(d, qq)); if (model_undef) { - std::vector undef_d = importUndefSigSpec(cell->getPort("\\Y"), timestep-1); - std::vector undef_q = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_d = importUndefSigSpec(cell->getPort(ID::Y), timestep-1); + std::vector undef_q = importUndefSigSpec(cell->getPort(ID::Y), timestep); ez->assume(ez->vec_eq(undef_d, undef_q)); undefGating(q, qq, undef_q); @@ -1348,23 +1350,23 @@ struct SatGen return true; } - if (cell->type == "$anyseq") + if (cell->type == ID($anyseq)) { return true; } - if (cell->type == "$_BUF_" || cell->type == "$equiv") + if (cell->type.in(ID($_BUF_), ID($equiv))) { - std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; ez->assume(ez->vec_eq(a, yy)); if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector 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); @@ -1372,18 +1374,18 @@ struct SatGen return true; } - if (cell->type == "$initstate") + if (cell->type == ID($initstate)) { auto key = make_pair(prefix, timestep); if (initstates.count(key) == 0) initstates[key] = false; - std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector 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 undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); log_assert(GetSize(undef_y) == 1); ez->SET(undef_y[0], ez->CONST_FALSE); } @@ -1391,19 +1393,19 @@ struct SatGen return true; } - if (cell->type == "$assert") + if (cell->type == ID($assert)) { std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); - asserts_a[pf].append((*sigmap)(cell->getPort("\\A"))); - asserts_en[pf].append((*sigmap)(cell->getPort("\\EN"))); + asserts_a[pf].append((*sigmap)(cell->getPort(ID::A))); + asserts_en[pf].append((*sigmap)(cell->getPort(ID(EN)))); return true; } - if (cell->type == "$assume") + if (cell->type == ID($assume)) { std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); - assumes_a[pf].append((*sigmap)(cell->getPort("\\A"))); - assumes_en[pf].append((*sigmap)(cell->getPort("\\EN"))); + assumes_a[pf].append((*sigmap)(cell->getPort(ID::A))); + assumes_en[pf].append((*sigmap)(cell->getPort(ID(EN)))); return true; } diff --git a/kernel/yosys.cc b/kernel/yosys.cc index a42a7c0b8..747f2d739 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -510,10 +510,13 @@ void yosys_setup() if(already_setup) return; already_setup = true; - // if there are already IdString objects then we have a global initialization order bug - IdString empty_id; - log_assert(empty_id.index_ == 0); - IdString::get_reference(empty_id.index_); + + RTLIL::ID::A = "\\A"; + RTLIL::ID::B = "\\B"; + RTLIL::ID::Y = "\\Y"; + RTLIL::ID::keep = "\\keep"; + RTLIL::ID::whitebox = "\\whitebox"; + RTLIL::ID::blackbox = "\\blackbox"; #ifdef WITH_PYTHON PyImport_AppendInittab((char*)"libyosys", INIT_MODULE); @@ -575,9 +578,6 @@ void yosys_shutdown() #ifdef WITH_PYTHON Py_Finalize(); #endif - - IdString empty_id; - IdString::put_reference(empty_id.index_); } RTLIL::IdString new_id(std::string file, int line, std::string func) @@ -647,12 +647,12 @@ std::vector glob_filename(const std::string &filename_pattern) void rewrite_filename(std::string &filename) { - if (filename.substr(0, 1) == "\"" && filename.substr(GetSize(filename)-1) == "\"") + if (filename.compare(0, 1, "\"") == 0 && filename.compare(GetSize(filename)-1, std::string::npos, "\"") == 0) filename = filename.substr(1, GetSize(filename)-2); - if (filename.substr(0, 2) == "+/") + if (filename.compare(0, 2, "+/") == 0) filename = proc_share_dirname() + filename.substr(2); #ifndef _WIN32 - if (filename.substr(0, 2) == "~/") + if (filename.compare(0, 2, "~/") == 0) filename = filename.replace(0, 1, getenv("HOME")); #endif } @@ -894,23 +894,26 @@ void run_frontend(std::string filename, std::string command, std::string *backen design = yosys_design; if (command == "auto") { - if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") + std::string filename_trim = filename; + if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".gz") == 0) + filename_trim.erase(filename_trim.size()-3); + if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-2, std::string::npos, ".v") == 0) command = "verilog"; - else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv") + else if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".sv") == 0) command = "verilog -sv"; - else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".vhd") + else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".vhd") == 0) command = "vhdl"; - else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".blif") + else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".blif") == 0) command = "blif"; - else if (filename.size() > 5 && filename.substr(filename.size()-6) == ".eblif") + else if (filename_trim.size() > 5 && filename_trim.compare(filename_trim.size()-6, std::string::npos, ".eblif") == 0) command = "blif"; - else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".json") + else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".json") == 0) command = "json"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") + else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".il") == 0) command = "ilang"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys") + else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".ys") == 0) command = "script"; - else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".tcl") + else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".tcl") == 0) command = "tcl"; else if (filename == "-") command = "script"; @@ -961,14 +964,18 @@ void run_frontend(std::string filename, std::string command, std::string *backen command += next_line; } handle_label(command, from_to_active, run_from, run_to); - if (from_to_active) + if (from_to_active) { Pass::call(design, command); + design->check(); + } } if (!command.empty()) { handle_label(command, from_to_active, run_from, run_to); - if (from_to_active) + if (from_to_active) { Pass::call(design, command); + design->check(); + } } } catch (...) { @@ -997,6 +1004,7 @@ void run_frontend(std::string filename, std::string command, std::string *backen Pass::call(design, vector({command, filename})); else Frontend::frontend_call(design, NULL, filename, command); + design->check(); } void run_frontend(std::string filename, std::string command, RTLIL::Design *design) @@ -1020,17 +1028,17 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig design = yosys_design; if (command == "auto") { - if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") + if (filename.size() > 2 && filename.compare(filename.size()-2, std::string::npos, ".v") == 0) command = "verilog"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") + else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0) command = "ilang"; - else if (filename.size() > 4 && filename.substr(filename.size()-4) == ".aig") + else if (filename.size() > 4 && filename.compare(filename.size()-4, std::string::npos, ".aig") == 0) command = "aiger"; - else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".blif") + else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".blif") == 0) command = "blif"; - else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".edif") + else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".edif") == 0) command = "edif"; - else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".json") + else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".json") == 0) command = "json"; else if (filename == "-") command = "ilang"; @@ -1064,7 +1072,7 @@ static char *readline_cmd_generator(const char *text, int state) } for (; it != pass_register.end(); it++) { - if (it->first.substr(0, len) == text) + if (it->first.compare(0, len, text) == 0) return strdup((it++)->first.c_str()); } return NULL; @@ -1086,7 +1094,7 @@ static char *readline_obj_generator(const char *text, int state) if (design->selected_active_module.empty()) { for (auto &it : design->modules_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) + if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); } else @@ -1095,19 +1103,19 @@ static char *readline_obj_generator(const char *text, int state) RTLIL::Module *module = design->modules_.at(design->selected_active_module); for (auto &it : module->wires_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) + if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); for (auto &it : module->memories) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) + if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); for (auto &it : module->cells_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) + if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); for (auto &it : module->processes) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) + if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0) obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); } @@ -1180,6 +1188,7 @@ void shell(RTLIL::Design *design) design->selection_stack.pop_back(); log_reset_stack(); } + design->check(); } if (command == NULL) printf("exit\n"); diff --git a/kernel/yosys.h b/kernel/yosys.h index c7b671724..a80cb00b4 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -87,6 +88,10 @@ extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName); extern void Tcl_Finalize(void); extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr); extern const char *Tcl_GetStringResult(Tcl_Interp *interp); +extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length); +extern Tcl_Obj *Tcl_NewIntObj(int intValue); +extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]); +extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); # endif #endif @@ -300,8 +305,17 @@ RTLIL::IdString new_id(std::string file, int line, std::string func); #define NEW_ID \ YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) -#define ID(_str) \ - ([]() { static YOSYS_NAMESPACE_PREFIX RTLIL::IdString _id(_str); return _id; })() +// Create a statically allocated IdString object, using for example ID(A) or ID($add). +// +// Recipe for Converting old code that is using conversion of strings like "\\A" and +// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for +// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary. +// +// sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' +// +#define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \ + static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })() +namespace ID = RTLIL::ID; RTLIL::Design *yosys_get_design(); std::string proc_self_dirname(); diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index cb1bcf1be..0106059b6 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -494,6 +494,6 @@ Add information about {\tt \$\_DFFE\_??\_}, {\tt \$\_DFFSR\_???\_}, {\tt \$\_DLA \end{fixme} \begin{fixme} -Add information about {\tt \$\_AOI3\_}, {\tt \$\_OAI3\_}, {\tt \$\_AOI4\_}, and {\tt \$\_OAI4\_} cells. +Add information about {\tt \$\_AOI3\_}, {\tt \$\_OAI3\_}, {\tt \$\_AOI4\_}, {\tt \$\_OAI4\_}, and {\tt \$\_NMUX\_} cells. \end{fixme} diff --git a/misc/launcher.c b/misc/launcher.c index 157d68cf3..e0d8208f1 100644 --- a/misc/launcher.c +++ b/misc/launcher.c @@ -61,6 +61,7 @@ SOFTWARE. */ #include #include #include +#include int child_pid=0; @@ -338,7 +339,7 @@ int run(int argc, char **argv, int is_gui) { if (is_gui) { /* Use exec, we don't need to wait for the GUI to finish */ - execv(ptr, (const char * const *)(newargs)); + execv(ptr, (char * const *)(newargs)); return fail("Could not exec %s", ptr); /* shouldn't get here! */ } diff --git a/passes/cmds/cover.cc b/passes/cmds/cover.cc index 1128116b4..628ac4c5e 100644 --- a/passes/cmds/cover.cc +++ b/passes/cmds/cover.cc @@ -121,7 +121,7 @@ struct CoverPass : public Pass { } break; } - while (argidx < args.size() && args[argidx].substr(0, 1) != "-") + while (argidx < args.size() && args[argidx].compare(0, 1, "-") != 0) patterns.push_back(args[argidx++]); extra_args(args, argidx, design); diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index f8d91ea48..5822c09f8 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -107,7 +107,7 @@ struct DeletePass : public Pass { for (auto &it : module->cells_) { if (design->selected(module, it.second)) delete_cells.insert(it.second); - if ((it.second->type == "$memrd" || it.second->type == "$memwr") && + if (it.second->type.in("$memrd", "$memwr") && delete_mems.count(it.second->parameters.at("\\MEMID").decode_string()) != 0) delete_cells.insert(it.second); } diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index b5e8ef1af..59d10a1b8 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -34,7 +34,7 @@ static bool match_ids(RTLIL::IdString id, std::string pattern) { if (id == pattern) return true; - if (id.size() > 0 && id[0] == '\\' && id.substr(1) == pattern) + if (id.size() > 0 && id[0] == '\\' && id.compare(1, std::string::npos, pattern.c_str()) == 0) return true; if (patmatch(pattern.c_str(), id.c_str())) return true; @@ -124,11 +124,11 @@ static bool match_attr(const dict &attributes, st size_t pos = match_expr.find_first_of(""); if (pos != std::string::npos) { - if (match_expr.substr(pos, 2) == "!=") + if (match_expr.compare(pos, 2, "!=") == 0) return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '!'); - if (match_expr.substr(pos, 2) == "<=") + if (match_expr.compare(pos, 2, "<=") == 0) return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '['); - if (match_expr.substr(pos, 2) == ">=") + if (match_expr.compare(pos, 2, ">=") == 0) return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), ']'); return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+1), match_expr[pos]); } @@ -711,32 +711,32 @@ static void select_stmt(RTLIL::Design *design, std::string arg) log_cmd_error("Must have at least one element on the stack for operator %%a.\n"); select_op_alias(design, work_stack[work_stack.size()-1]); } else - if (arg == "%x" || (arg.size() > 2 && arg.substr(0, 2) == "%x" && (arg[2] == ':' || arg[2] == '*' || arg[2] == '.' || ('0' <= arg[2] && arg[2] <= '9')))) { + if (arg == "%x" || (arg.size() > 2 && arg.compare(0, 2, "%x") == 0 && (arg[2] == ':' || arg[2] == '*' || arg[2] == '.' || ('0' <= arg[2] && arg[2] <= '9')))) { if (work_stack.size() < 1) log_cmd_error("Must have at least one element on the stack for operator %%x.\n"); select_op_expand(design, arg, 'x', false); } else - if (arg == "%ci" || (arg.size() > 3 && arg.substr(0, 3) == "%ci" && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { + if (arg == "%ci" || (arg.size() > 3 && arg.compare(0, 3, "%ci") == 0 && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { if (work_stack.size() < 1) log_cmd_error("Must have at least one element on the stack for operator %%ci.\n"); select_op_expand(design, arg, 'i', false); } else - if (arg == "%co" || (arg.size() > 3 && arg.substr(0, 3) == "%co" && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { + if (arg == "%co" || (arg.size() > 3 && arg.compare(0, 3, "%co") == 0 && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { if (work_stack.size() < 1) log_cmd_error("Must have at least one element on the stack for operator %%co.\n"); select_op_expand(design, arg, 'o', false); } else - if (arg == "%xe" || (arg.size() > 3 && arg.substr(0, 3) == "%xe" && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { + if (arg == "%xe" || (arg.size() > 3 && arg.compare(0, 3, "%xe") == 0 && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) { if (work_stack.size() < 1) log_cmd_error("Must have at least one element on the stack for operator %%xe.\n"); select_op_expand(design, arg, 'x', true); } else - if (arg == "%cie" || (arg.size() > 4 && arg.substr(0, 4) == "%cie" && (arg[4] == ':' || arg[4] == '*' || arg[4] == '.' || ('0' <= arg[4] && arg[4] <= '9')))) { + if (arg == "%cie" || (arg.size() > 4 && arg.compare(0, 4, "%cie") == 0 && (arg[4] == ':' || arg[4] == '*' || arg[4] == '.' || ('0' <= arg[4] && arg[4] <= '9')))) { if (work_stack.size() < 1) log_cmd_error("Must have at least one element on the stack for operator %%cie.\n"); select_op_expand(design, arg, 'i', true); } else - if (arg == "%coe" || (arg.size() > 4 && arg.substr(0, 4) == "%coe" && (arg[4] == ':' || arg[4] == '*' || arg[4] == '.' || ('0' <= arg[4] && arg[4] <= '9')))) { + if (arg == "%coe" || (arg.size() > 4 && arg.compare(0, 4, "%coe") == 0 && (arg[4] == ':' || arg[4] == '*' || arg[4] == '.' || ('0' <= arg[4] && arg[4] <= '9')))) { if (work_stack.size() < 1) log_cmd_error("Must have at least one element on the stack for operator %%coe.\n"); select_op_expand(design, arg, 'o', true); @@ -766,7 +766,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) } else { size_t pos = arg.find('/'); if (pos == std::string::npos) { - if (arg.find(':') == std::string::npos || arg.substr(0, 1) == "A") + if (arg.find(':') == std::string::npos || arg.compare(0, 1, "A") == 0) arg_mod = arg; else arg_mod = "*", arg_memb = arg; @@ -787,7 +787,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) sel.full_selection = false; for (auto &mod_it : design->modules_) { - if (arg_mod.substr(0, 2) == "A:") { + if (arg_mod.compare(0, 2, "A:") == 0) { if (!match_attr(mod_it.second->attributes, arg_mod.substr(2))) continue; } else @@ -800,27 +800,27 @@ static void select_stmt(RTLIL::Design *design, std::string arg) } RTLIL::Module *mod = mod_it.second; - if (arg_memb.substr(0, 2) == "w:") { + if (arg_memb.compare(0, 2, "w:") == 0) { for (auto &it : mod->wires_) if (match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else - if (arg_memb.substr(0, 2) == "i:") { + if (arg_memb.compare(0, 2, "i:") == 0) { for (auto &it : mod->wires_) if (it.second->port_input && match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else - if (arg_memb.substr(0, 2) == "o:") { + if (arg_memb.compare(0, 2, "o:") == 0) { for (auto &it : mod->wires_) if (it.second->port_output && match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else - if (arg_memb.substr(0, 2) == "x:") { + if (arg_memb.compare(0, 2, "x:") == 0) { for (auto &it : mod->wires_) if ((it.second->port_input || it.second->port_output) && match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else - if (arg_memb.substr(0, 2) == "s:") { + if (arg_memb.compare(0, 2, "s:") == 0) { size_t delim = arg_memb.substr(2).find(':'); if (delim == std::string::npos) { int width = atoi(arg_memb.substr(2).c_str()); @@ -837,27 +837,27 @@ static void select_stmt(RTLIL::Design *design, std::string arg) sel.selected_members[mod->name].insert(it.first); } } else - if (arg_memb.substr(0, 2) == "m:") { + if (arg_memb.compare(0, 2, "m:") == 0) { for (auto &it : mod->memories) if (match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else - if (arg_memb.substr(0, 2) == "c:") { + if (arg_memb.compare(0, 2, "c:") ==0) { for (auto &it : mod->cells_) if (match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else - if (arg_memb.substr(0, 2) == "t:") { + if (arg_memb.compare(0, 2, "t:") == 0) { for (auto &it : mod->cells_) if (match_ids(it.second->type, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else - if (arg_memb.substr(0, 2) == "p:") { + if (arg_memb.compare(0, 2, "p:") == 0) { for (auto &it : mod->processes) if (match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else - if (arg_memb.substr(0, 2) == "a:") { + if (arg_memb.compare(0, 2, "a:") == 0) { for (auto &it : mod->wires_) if (match_attr(it.second->attributes, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); @@ -871,12 +871,12 @@ static void select_stmt(RTLIL::Design *design, std::string arg) if (match_attr(it.second->attributes, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else - if (arg_memb.substr(0, 2) == "r:") { + if (arg_memb.compare(0, 2, "r:") == 0) { for (auto &it : mod->cells_) if (match_attr(it.second->parameters, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else { - if (arg_memb.substr(0, 2) == "n:") + if (arg_memb.compare(0, 2, "n:") == 0) arg_memb = arg_memb.substr(2); for (auto &it : mod->wires_) if (match_ids(it.first, arg_memb)) @@ -927,7 +927,7 @@ void handle_extra_select_args(Pass *pass, vector args, size_t argidx, si { work_stack.clear(); for (; argidx < args_size; argidx++) { - if (args[argidx].substr(0, 1) == "-") { + if (args[argidx].compare(0, 1, "-") == 0) { if (pass != NULL) pass->cmd_error(args, argidx, "Unexpected option in selection arguments."); else diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index b9fcc3e7a..1ccfc2e86 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -34,7 +34,7 @@ struct setunset_t setunset_t(std::string set_name, std::string set_value) : name(RTLIL::escape_id(set_name)), value(), unset(false) { - if (set_value.substr(0, 1) == "\"" && set_value.substr(GetSize(set_value)-1) == "\"") { + if (set_value.compare(0, 1, "\"") == 0 && set_value.compare(GetSize(set_value)-1, std::string::npos, "\"") == 0) { value = RTLIL::Const(set_value.substr(1, GetSize(set_value)-2)); } else { RTLIL::SigSpec sig_value; diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index cf729215f..2e9fc72af 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -527,11 +527,11 @@ struct ShowWorker { currentColor = xorshift32(currentColor); if (wires_on_demand.count(it.first) > 0) { - if (it.second.in.size() == 1 && it.second.out.size() > 1 && it.second.in.begin()->substr(0, 1) == "p") + if (it.second.in.size() == 1 && it.second.out.size() > 1 && it.second.in.begin()->compare(0, 1, "p") == 0) it.second.out.erase(*it.second.in.begin()); if (it.second.in.size() == 1 && it.second.out.size() == 1) { std::string from = *it.second.in.begin(), to = *it.second.out.begin(); - if (from != to || from.substr(0, 1) != "p") + if (from != to || from.compare(0, 1, "p") != 0) fprintf(f, "%s:e -> %s:w [%s, %s];\n", from.c_str(), to.c_str(), nextColor(it.second.color).c_str(), widthLabel(it.second.bits).c_str()); continue; } @@ -808,7 +808,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.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); + Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog")); libs.push_back(lib); } diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 27c5fb60c..c8e4f3981 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -17,11 +17,10 @@ * */ -#include "kernel/register.h" +#include "kernel/yosys.h" #include "kernel/celltypes.h" #include "passes/techmap/libparse.h" - -#include "kernel/log.h" +#include "kernel/cost.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -223,6 +222,28 @@ struct statdata_t log("\n"); log(" Estimated number of LCs: %10d\n", lc_cnt); } + + if (tech == "cmos") + { + int tran_cnt = 0; + bool tran_cnt_exact = true; + auto &gate_costs = CellCosts::cmos_gate_cost(); + + for (auto it : num_cells_by_type) { + auto ctype = it.first; + auto cnum = it.second; + + if (gate_costs.count(ctype)) + tran_cnt += cnum * gate_costs.at(ctype); + else if (ctype.in("$_DFF_P_", "$_DFF_N_")) + tran_cnt += cnum * 16; + else + tran_cnt_exact = false; + } + + log("\n"); + log(" Estimated number of transistors: %10d%s\n", tran_cnt, tran_cnt_exact ? "" : "+"); + } } }; @@ -286,7 +307,7 @@ struct StatPass : public Pass { log("\n"); log(" -tech \n"); log(" print area estemate for the specified technology. Currently supported\n"); - log(" values for : xilinx\n"); + log(" values for : xilinx, cmos\n"); log("\n"); log(" -width\n"); log(" annotate internal cell types with their word width.\n"); @@ -330,7 +351,7 @@ struct StatPass : public Pass { } extra_args(args, argidx, design); - if (techname != "" && techname != "xilinx") + if (techname != "" && techname != "xilinx" && techname != "cmos") log_cmd_error("Unsupported technology: '%s'\n", techname.c_str()); for (auto mod : design->selected_modules()) diff --git a/passes/equiv/equiv_opt.cc b/passes/equiv/equiv_opt.cc index 3596dfd7b..19d1c25ac 100644 --- a/passes/equiv/equiv_opt.cc +++ b/passes/equiv/equiv_opt.cc @@ -97,7 +97,7 @@ struct EquivOptPass:public ScriptPass for (; argidx < args.size(); argidx++) { if (command.empty()) { - if (args[argidx].substr(0, 1) == "-") + if (args[argidx].compare(0, 1, "-") == 0) cmd_error(args, argidx, "Unknown option."); } else { command += " "; diff --git a/passes/equiv/equiv_struct.cc b/passes/equiv/equiv_struct.cc index a7973fd04..6672948b9 100644 --- a/passes/equiv/equiv_struct.cc +++ b/passes/equiv/equiv_struct.cc @@ -215,9 +215,9 @@ struct EquivStructWorker if (c != nullptr) { string n = cell_name.str(); cells_type = c->type; - if (GetSize(n) > 5 && n.substr(GetSize(n)-5) == "_gold") + if (GetSize(n) > 5 && n.compare(GetSize(n)-5, std::string::npos, "_gold") == 0) gold_cells.push_back(c); - else if (GetSize(n) > 5 && n.substr(GetSize(n)-5) == "_gate") + else if (GetSize(n) > 5 && n.compare(GetSize(n)-5, std::string::npos, "_gate") == 0) gate_cells.push_back(c); else other_cells.push_back(c); diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index c34d0c15c..1610ec751 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -50,7 +50,7 @@ struct FsmExpand if (full_mode || cell->type == "$_MUX_") return true; - if (cell->type == "$mux" || cell->type == "$pmux") + if (cell->type.in("$mux", "$pmux")) if (cell->getPort("\\A").size() < 2) return true; diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 6095eaf30..a85c3bec0 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -168,7 +168,7 @@ undef_bit_in_next_state: ctrl_in_bit_indices[ctrl_in[i]] = i; for (auto &it : ctrl_in_bit_indices) - if (tr.ctrl_in.bits.at(it.second) == RTLIL::S1 && exclusive_ctrls.count(it.first) != 0) + if (tr.ctrl_in.bits.at(it.second) == State::S1 && exclusive_ctrls.count(it.first) != 0) for (auto &dc_bit : exclusive_ctrls.at(it.first)) if (ctrl_in_bit_indices.count(dc_bit)) tr.ctrl_in.bits.at(ctrl_in_bit_indices.at(dc_bit)) = RTLIL::State::Sa; @@ -216,13 +216,13 @@ undef_bit_in_next_state: ce.push(); dont_care.append(undef); ce.set(undef, constval.as_const()); - if (exclusive_ctrls.count(undef) && constval == RTLIL::S1) + if (exclusive_ctrls.count(undef) && constval == State::S1) for (auto &bit : exclusive_ctrls.at(undef)) { RTLIL::SigSpec bitval = bit; - if (ce.eval(bitval) && bitval != RTLIL::S0) + if (ce.eval(bitval) && bitval != State::S0) goto found_contradiction_1; else - ce.set(bit, RTLIL::S0); + ce.set(bit, State::S0); } find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); found_contradiction_1: @@ -231,21 +231,21 @@ undef_bit_in_next_state: else { ce.push(), ce_nostop.push(); - ce.set(undef, RTLIL::S0); - ce_nostop.set(undef, RTLIL::S0); + ce.set(undef, State::S0); + ce_nostop.set(undef, State::S0); find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); ce.pop(), ce_nostop.pop(); ce.push(), ce_nostop.push(); - ce.set(undef, RTLIL::S1); - ce_nostop.set(undef, RTLIL::S1); + ce.set(undef, State::S1); + ce_nostop.set(undef, State::S1); if (exclusive_ctrls.count(undef)) for (auto &bit : exclusive_ctrls.at(undef)) { RTLIL::SigSpec bitval = bit; - if ((ce.eval(bitval) || ce_nostop.eval(bitval)) && bitval != RTLIL::S0) + if ((ce.eval(bitval) || ce_nostop.eval(bitval)) && bitval != State::S0) goto found_contradiction_2; else - ce.set(bit, RTLIL::S0), ce_nostop.set(bit, RTLIL::S0); + ce.set(bit, State::S0), ce_nostop.set(bit, RTLIL::S0); } find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); found_contradiction_2: @@ -263,8 +263,8 @@ static void extract_fsm(RTLIL::Wire *wire) RTLIL::SigSpec dff_in(RTLIL::State::Sm, wire->width); RTLIL::Const reset_state(RTLIL::State::Sx, wire->width); - RTLIL::SigSpec clk = RTLIL::S0; - RTLIL::SigSpec arst = RTLIL::S0; + RTLIL::SigSpec clk = State::S0; + RTLIL::SigSpec arst = State::S0; bool clk_polarity = true; bool arst_polarity = true; @@ -371,8 +371,8 @@ static void extract_fsm(RTLIL::Wire *wire) RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), "$fsm"); fsm_cell->setPort("\\CLK", clk); fsm_cell->setPort("\\ARST", arst); - fsm_cell->parameters["\\CLK_POLARITY"] = clk_polarity ? RTLIL::S1 : RTLIL::S0; - fsm_cell->parameters["\\ARST_POLARITY"] = arst_polarity ? RTLIL::S1 : RTLIL::S0; + fsm_cell->parameters["\\CLK_POLARITY"] = clk_polarity ? State::S1 : State::S0; + fsm_cell->parameters["\\ARST_POLARITY"] = arst_polarity ? State::S1 : State::S0; fsm_cell->setPort("\\CTRL_IN", ctrl_in); fsm_cell->setPort("\\CTRL_OUT", ctrl_out); fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name.str()); diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 90c958912..80913fda8 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -133,7 +133,7 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapconnect(RTLIL::SigSig(output, cases_vector)); } else { - module->connect(RTLIL::SigSig(output, RTLIL::SigSpec(0, 1))); + module->connect(RTLIL::SigSig(output, State::S0)); } } diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 213437c01..fd95b94b2 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -48,7 +48,7 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, RTLIL::Cell *cell = i2.second; if (design->has(cell->type)) continue; - if (cell->type.substr(0, 1) == "$" && cell->type.substr(0, 3) != "$__") + if (cell->type.begins_with("$__")) continue; for (auto &pattern : celltypes) if (patmatch(pattern.c_str(), RTLIL::unescape_id(cell->type).c_str())) @@ -143,7 +143,7 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, // Return the "basic" type for an array item. std::string basic_cell_type(const std::string celltype, int pos[3] = nullptr) { std::string basicType = celltype; - if (celltype.substr(0, 7) == "$array:") { + if (celltype.compare(0, strlen("$array:"), "$array:") == 0) { int pos_idx = celltype.find_first_of(':'); int pos_num = celltype.find_first_of(':', pos_idx + 1); int pos_type = celltype.find_first_of(':', pos_num + 1); @@ -194,16 +194,16 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check std::vector connections_to_add_name; std::vector connections_to_add_signal; - if (cell->type.substr(0, 7) == "$array:") { + if (cell->type.begins_with("$array:")) { int pos[3]; basic_cell_type(cell->type.str(), pos); int pos_idx = pos[0]; int pos_num = pos[1]; int pos_type = pos[2]; - int idx = atoi(cell->type.str().substr(pos_idx + 1, pos_num).c_str()); - int num = atoi(cell->type.str().substr(pos_num + 1, pos_type).c_str()); + int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str()); + int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str()); array_cells[cell] = std::pair(idx, num); - cell->type = cell->type.str().substr(pos_type + 1); + cell->type = cell->type.substr(pos_type + 1); } dict interfaces_to_add_to_submodule; dict modports_used_in_submodule; @@ -422,7 +422,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check for (auto &conn : cell->connections_) { int conn_size = conn.second.size(); RTLIL::IdString portname = conn.first; - if (portname.substr(0, 1) == "$") { + if (portname.begins_with("$")) { int port_id = atoi(portname.substr(1).c_str()); for (auto &wire_it : mod->wires_) if (wire_it.second->port_id == port_id) { @@ -457,9 +457,8 @@ void hierarchy_worker(RTLIL::Design *design, std::setcells()) { std::string celltype = cell->type.str(); - if (celltype.substr(0, 7) == "$array:") { + if (celltype.compare(0, strlen("$array:"), "$array:") == 0) celltype = basic_cell_type(celltype); - } if (design->module(celltype)) hierarchy_worker(design, used, design->module(celltype), indent+4); } @@ -521,9 +520,8 @@ int find_top_mod_score(Design *design, Module *module, dict &db) for (auto cell : module->cells()) { std::string celltype = cell->type.str(); // Is this an array instance - if (celltype.substr(0, 7) == "$array:") { + if (celltype.compare(0, strlen("$array:"), "$array:") == 0) celltype = basic_cell_type(celltype); - } // Is this cell a module instance? auto instModule = design->module(celltype); // If there is no instance for this, issue a warning. diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 369fcc84e..6acbce62f 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -194,8 +194,8 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory) log_assert(sig_wr_en.size() == wr_ports * memory->width); mem->parameters["\\WR_PORTS"] = Const(wr_ports); - mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : Const(0, 1); - mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : Const(0, 1); + mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : State::S0; + mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : State::S0; mem->setPort("\\WR_CLK", sig_wr_clk); mem->setPort("\\WR_ADDR", sig_wr_addr); @@ -209,9 +209,9 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory) log_assert(sig_rd_data.size() == rd_ports * memory->width); mem->parameters["\\RD_PORTS"] = Const(rd_ports); - mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.as_const() : Const(0, 1); - mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : Const(0, 1); - mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : Const(0, 1); + mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.as_const() : State::S0; + mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : State::S0; + mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : State::S0; mem->setPort("\\RD_CLK", sig_rd_clk); mem->setPort("\\RD_ADDR", sig_rd_addr); diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 32b97f27a..be4b3c100 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -262,7 +262,7 @@ struct MemoryDffWorker mux_cells_a[sigmap(cell->getPort("\\A"))] = cell; mux_cells_b[sigmap(cell->getPort("\\B"))] = cell; } - if (cell->type == "$not" || cell->type == "$_NOT_" || (cell->type == "$logic_not" && GetSize(cell->getPort("\\A")) == 1)) { + if (cell->type.in("$not", "$_NOT_") || (cell->type == "$logic_not" && GetSize(cell->getPort("\\A")) == 1)) { SigSpec sig_a = cell->getPort("\\A"); SigSpec sig_y = cell->getPort("\\Y"); if (cell->type == "$not") diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index a0b808e56..65bccb5ef 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -301,7 +301,7 @@ struct MemoryMapWorker RTLIL::Wire *w = w_seladdr; - if (wr_bit != RTLIL::SigSpec(1, 1)) + if (wr_bit != State::S1) { RTLIL::Cell *c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), "$and"); c->parameters["\\A_SIGNED"] = RTLIL::Const(0); diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 172afe0cb..eb912cfd4 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -155,7 +155,7 @@ struct MemoryShareWorker { bool ignore_data_port = false; - if (cell->type == "$mux" || cell->type == "$pmux") + if (cell->type.in("$mux", "$pmux")) { std::vector sig_a = sigmap(cell->getPort("\\A")); std::vector sig_b = sigmap(cell->getPort("\\B")); @@ -173,7 +173,7 @@ struct MemoryShareWorker continue; } - if ((cell->type == "$memwr" || cell->type == "$memrd") && + if (cell->type.in("$memwr", "$memrd") && cell->parameters.at("\\MEMID").decode_string() == memid) ignore_data_port = true; @@ -690,7 +690,7 @@ struct MemoryShareWorker sigmap_xmux.add(cell->getPort("\\Y"), sig_a); } - if (cell->type == "$mux" || cell->type == "$pmux") + if (cell->type.in("$mux", "$pmux")) { std::vector sig_y = sigmap(cell->getPort("\\Y")); for (int i = 0; i < int(sig_y.size()); i++) diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index ea3646330..eb07e9452 100644 --- a/passes/opt/Makefile.inc +++ b/passes/opt/Makefile.inc @@ -4,6 +4,7 @@ OBJS += passes/opt/opt_merge.o OBJS += passes/opt/opt_muxtree.o OBJS += passes/opt/opt_reduce.o OBJS += passes/opt/opt_rmdff.o +OBJS += passes/opt/opt_share.o OBJS += passes/opt/opt_clean.o OBJS += passes/opt/opt_expr.o @@ -16,4 +17,3 @@ OBJS += passes/opt/opt_lut.o OBJS += passes/opt/pmux2shiftx.o OBJS += passes/opt/muxpack.o endif - diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index 6697d6ca1..c40c02acd 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -37,22 +37,22 @@ struct ExclusiveDatabase SigBit y_port; pool reduce_or; for (auto cell : module->cells()) { - if (cell->type == "$eq") { - nonconst_sig = sigmap(cell->getPort("\\A")); - const_sig = sigmap(cell->getPort("\\B")); + if (cell->type == ID($eq)) { + nonconst_sig = sigmap(cell->getPort(ID::A)); + const_sig = sigmap(cell->getPort(ID::B)); if (!const_sig.is_fully_const()) { if (!nonconst_sig.is_fully_const()) continue; std::swap(nonconst_sig, const_sig); } - y_port = sigmap(cell->getPort("\\Y")); + y_port = sigmap(cell->getPort(ID::Y)); } - else if (cell->type == "$logic_not") { - nonconst_sig = sigmap(cell->getPort("\\A")); - const_sig = Const(RTLIL::S0, GetSize(nonconst_sig)); - y_port = sigmap(cell->getPort("\\Y")); + else if (cell->type == ID($logic_not)) { + nonconst_sig = sigmap(cell->getPort(ID::A)); + const_sig = Const(State::S0, GetSize(nonconst_sig)); + y_port = sigmap(cell->getPort(ID::Y)); } - else if (cell->type == "$reduce_or") { + else if (cell->type == ID($reduce_or)) { reduce_or.insert(cell); continue; } @@ -66,7 +66,7 @@ struct ExclusiveDatabase for (auto cell : reduce_or) { nonconst_sig = SigSpec(); std::vector values; - SigSpec a_port = sigmap(cell->getPort("\\A")); + SigSpec a_port = sigmap(cell->getPort(ID::A)); for (auto bit : a_port) { auto it = sig_cmp_prev.find(bit); if (it == sig_cmp_prev.end()) { @@ -84,7 +84,7 @@ struct ExclusiveDatabase } if (nonconst_sig.empty()) continue; - y_port = sigmap(cell->getPort("\\Y")); + y_port = sigmap(cell->getPort(ID::Y)); sig_cmp_prev[y_port] = std::make_pair(nonconst_sig,std::move(values)); } } @@ -135,7 +135,7 @@ struct MuxpackWorker { for (auto wire : module->wires()) { - if (wire->port_output || wire->get_bool_attribute("\\keep")) { + if (wire->port_output || wire->get_bool_attribute(ID::keep)) { for (auto bit : sigmap(wire)) sigbit_with_non_chain_users.insert(bit); } @@ -143,13 +143,13 @@ struct MuxpackWorker for (auto cell : module->cells()) { - if (cell->type.in("$mux", "$pmux") && !cell->get_bool_attribute("\\keep")) + if (cell->type.in(ID($mux), ID($pmux)) && !cell->get_bool_attribute(ID::keep)) { - SigSpec a_sig = sigmap(cell->getPort("\\A")); + SigSpec a_sig = sigmap(cell->getPort(ID::A)); SigSpec b_sig; - if (cell->type == "$mux") - b_sig = sigmap(cell->getPort("\\B")); - SigSpec y_sig = sigmap(cell->getPort("\\Y")); + if (cell->type == ID($mux)) + b_sig = sigmap(cell->getPort(ID::B)); + SigSpec y_sig = sigmap(cell->getPort(ID::Y)); if (sig_chain_next.count(a_sig)) for (auto a_bit : a_sig.bits()) @@ -186,16 +186,16 @@ struct MuxpackWorker { log_debug("Considering %s (%s)\n", log_id(cell), log_id(cell->type)); - SigSpec a_sig = sigmap(cell->getPort("\\A")); - if (cell->type == "$mux") { - SigSpec b_sig = sigmap(cell->getPort("\\B")); + SigSpec a_sig = sigmap(cell->getPort(ID::A)); + if (cell->type == ID($mux)) { + SigSpec b_sig = sigmap(cell->getPort(ID::B)); if (sig_chain_prev.count(a_sig) + sig_chain_prev.count(b_sig) != 1) goto start_cell; if (!sig_chain_prev.count(a_sig)) a_sig = b_sig; } - else if (cell->type == "$pmux") { + else if (cell->type == ID($pmux)) { if (!sig_chain_prev.count(a_sig)) goto start_cell; } @@ -208,8 +208,8 @@ struct MuxpackWorker { Cell *prev_cell = sig_chain_prev.at(a_sig); log_assert(prev_cell); - SigSpec s_sig = sigmap(cell->getPort("\\S")); - s_sig.append(sigmap(prev_cell->getPort("\\S"))); + SigSpec s_sig = sigmap(cell->getPort(ID(S))); + s_sig.append(sigmap(prev_cell->getPort(ID(S)))); if (!excl_db.query(s_sig)) goto start_cell; } @@ -230,7 +230,7 @@ struct MuxpackWorker { chain.push_back(c); - SigSpec y_sig = sigmap(c->getPort("\\Y")); + SigSpec y_sig = sigmap(c->getPort(ID::Y)); if (sig_chain_next.count(y_sig) == 0) break; @@ -269,29 +269,29 @@ struct MuxpackWorker mux_count += cases; pmux_count += 1; - first_cell->type = "$pmux"; - SigSpec b_sig = first_cell->getPort("\\B"); - SigSpec s_sig = first_cell->getPort("\\S"); + first_cell->type = ID($pmux); + SigSpec b_sig = first_cell->getPort(ID::B); + SigSpec s_sig = first_cell->getPort(ID(S)); for (int i = 1; i < cases; i++) { Cell* prev_cell = chain[cursor+i-1]; Cell* cursor_cell = chain[cursor+i]; - if (sigmap(prev_cell->getPort("\\Y")) == sigmap(cursor_cell->getPort("\\A"))) { - b_sig.append(cursor_cell->getPort("\\B")); - s_sig.append(cursor_cell->getPort("\\S")); + if (sigmap(prev_cell->getPort(ID::Y)) == sigmap(cursor_cell->getPort(ID::A))) { + b_sig.append(cursor_cell->getPort(ID::B)); + s_sig.append(cursor_cell->getPort(ID(S))); } else { - log_assert(cursor_cell->type == "$mux"); - b_sig.append(cursor_cell->getPort("\\A")); - s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort("\\S"))); + log_assert(cursor_cell->type == ID($mux)); + b_sig.append(cursor_cell->getPort(ID::A)); + s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort(ID(S)))); } remove_cells.insert(cursor_cell); } - first_cell->setPort("\\B", b_sig); - first_cell->setPort("\\S", s_sig); - first_cell->setParam("\\S_WIDTH", GetSize(s_sig)); - first_cell->setPort("\\Y", last_cell->getPort("\\Y")); + first_cell->setPort(ID::B, b_sig); + first_cell->setPort(ID(S), s_sig); + first_cell->setParam(ID(S_WIDTH), GetSize(s_sig)); + first_cell->setPort(ID::Y, last_cell->getPort(ID::Y)); cursor += cases; } diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc index e9a43e0f3..396819883 100644 --- a/passes/opt/opt.cc +++ b/passes/opt/opt.cc @@ -44,6 +44,7 @@ struct OptPass : public Pass { 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_clean [-purge]\n"); log(" opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc]\n"); @@ -70,6 +71,7 @@ struct OptPass : public Pass { std::string opt_reduce_args; std::string opt_merge_args; std::string opt_rmdff_args; + bool opt_share = false; bool fast_mode = false; log_header(design, "Executing OPT pass (performing simple optimizations).\n"); @@ -105,6 +107,7 @@ struct OptPass : public Pass { if (args[argidx] == "-full") { opt_expr_args += " -full"; opt_reduce_args += " -full"; + opt_share = true; continue; } if (args[argidx] == "-keepdc") { @@ -151,6 +154,8 @@ struct OptPass : public Pass { Pass::call(design, "opt_muxtree"); Pass::call(design, "opt_reduce" + opt_reduce_args); Pass::call(design, "opt_merge" + opt_merge_args); + if (opt_share) + Pass::call(design, "opt_share"); Pass::call(design, "opt_rmdff" + opt_rmdff_args); Pass::call(design, "opt_clean" + opt_clean_args); Pass::call(design, "opt_expr" + opt_expr_args); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index a8a8e0bc7..2f69b3d4c 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -52,7 +52,7 @@ struct keep_cache_t return cache.at(module); cache[module] = true; - if (!module->get_bool_attribute("\\keep")) { + if (!module->get_bool_attribute(ID::keep)) { bool found_keep = false; for (auto cell : module->cells()) if (query(cell)) found_keep = true; @@ -64,7 +64,7 @@ struct keep_cache_t bool query(Cell *cell) { - if (cell->type.in("$memwr", "$meminit", "$assert", "$assume", "$live", "$fair", "$cover", "$specify2", "$specify3", "$specrule")) + if (cell->type.in(ID($memwr), ID($meminit), ID($assert), ID($assume), ID($live), ID($fair), ID($cover), ID($specify2), ID($specify3), ID($specrule))) return true; if (cell->has_keep_attr()) @@ -122,7 +122,7 @@ void rmunused_module_cells(Module *module, bool verbose) for (auto &it : module->wires_) { Wire *wire = it.second; - if (wire->port_output || wire->get_bool_attribute("\\keep")) { + if (wire->port_output || wire->get_bool_attribute(ID::keep)) { for (auto bit : sigmap(wire)) for (auto c : wire2driver[bit]) queue.insert(c), unused.erase(c); @@ -177,8 +177,8 @@ void rmunused_module_cells(Module *module, bool verbose) int count_nontrivial_wire_attrs(RTLIL::Wire *w) { int count = w->attributes.size(); - count -= w->attributes.count("\\src"); - count -= w->attributes.count("\\unused_bits"); + count -= w->attributes.count(ID(src)); + count -= w->attributes.count(ID(unused_bits)); return count; } @@ -222,10 +222,10 @@ bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool ®s, SigPoo bool check_public_name(RTLIL::IdString id) { - const std::string &id_str = id.str(); - if (id_str[0] == '$') + if (id.begins_with("$")) return false; - if (id_str.substr(0, 2) == "\\_" && (id_str[id_str.size()-1] == '_' || id_str.find("_[") != std::string::npos)) + const std::string &id_str = id.str(); + if (id.begins_with("\\_") && (id.ends_with("_") || id_str.find("_[") != std::string::npos)) return false; if (id_str.find(".$") != std::string::npos) return false; @@ -297,7 +297,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos if (!wire->port_input) used_signals_nodrivers.add(sig); } - if (wire->get_bool_attribute("\\keep")) { + if (wire->get_bool_attribute(ID::keep)) { RTLIL::SigSpec sig = RTLIL::SigSpec(wire); assign_map.apply(sig); used_signals.add(sig); @@ -311,19 +311,19 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos log_assert(GetSize(s1) == GetSize(s2)); Const initval; - if (wire->attributes.count("\\init")) - initval = wire->attributes.at("\\init"); + if (wire->attributes.count(ID(init))) + initval = wire->attributes.at(ID(init)); if (GetSize(initval) != GetSize(wire)) initval.bits.resize(GetSize(wire), State::Sx); if (initval.is_fully_undef()) - wire->attributes.erase("\\init"); + wire->attributes.erase(ID(init)); if (GetSize(wire) == 0) { // delete zero-width wires, unless they are module ports if (wire->port_id == 0) goto delete_this_wire; } else - if (wire->port_id != 0 || wire->get_bool_attribute("\\keep") || !initval.is_fully_undef()) { + if (wire->port_id != 0 || wire->get_bool_attribute(ID::keep) || !initval.is_fully_undef()) { // do not delete anything with "keep" or module ports or initialized wires } else if (!purge_mode && check_public_name(wire->name) && (raw_used_signals.check_any(s1) || used_signals.check_any(s2) || s1 != s2)) { @@ -357,9 +357,9 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos } if (new_conn.first.size() > 0) { if (initval.is_fully_undef()) - wire->attributes.erase("\\init"); + wire->attributes.erase(ID(init)); else - wire->attributes.at("\\init") = initval; + wire->attributes.at(ID(init)) = initval; used_signals.add(new_conn.first); used_signals.add(new_conn.second); module->connect(new_conn); @@ -377,11 +377,11 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos } } if (unused_bits.empty() || wire->port_id != 0) - wire->attributes.erase("\\unused_bits"); + wire->attributes.erase(ID(unused_bits)); else - wire->attributes["\\unused_bits"] = RTLIL::Const(unused_bits); + wire->attributes[ID(unused_bits)] = RTLIL::Const(unused_bits); } else { - wire->attributes.erase("\\unused_bits"); + wire->attributes.erase(ID(unused_bits)); } } } @@ -413,18 +413,18 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose) dict qbits; for (auto cell : module->cells()) - if (fftypes.cell_known(cell->type) && cell->hasPort("\\Q")) + if (fftypes.cell_known(cell->type) && cell->hasPort(ID(Q))) { - SigSpec sig = cell->getPort("\\Q"); + SigSpec sig = cell->getPort(ID(Q)); for (int i = 0; i < GetSize(sig); i++) { SigBit bit = sig[i]; - if (bit.wire == nullptr || bit.wire->attributes.count("\\init") == 0) + if (bit.wire == nullptr || bit.wire->attributes.count(ID(init)) == 0) continue; - Const init = bit.wire->attributes.at("\\init"); + Const init = bit.wire->attributes.at(ID(init)); if (i >= GetSize(init) || init[i] == State::Sx || init[i] == State::Sz) continue; @@ -439,10 +439,10 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose) if (!purge_mode && wire->name[0] == '\\') continue; - if (wire->attributes.count("\\init") == 0) + if (wire->attributes.count(ID(init)) == 0) continue; - Const init = wire->attributes.at("\\init"); + Const init = wire->attributes.at(ID(init)); for (int i = 0; i < GetSize(wire) && i < GetSize(init); i++) { @@ -465,7 +465,7 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose) if (verbose) log_debug(" removing redundant init attribute on %s.\n", log_id(wire)); - wire->attributes.erase("\\init"); + wire->attributes.erase(ID(init)); did_something = true; next_wire:; } @@ -480,10 +480,10 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool std::vector delcells; for (auto cell : module->cells()) - if (cell->type.in("$pos", "$_BUF_") && !cell->has_keep_attr()) { - bool is_signed = cell->type == "$pos" && cell->getParam("\\A_SIGNED").as_bool(); - RTLIL::SigSpec a = cell->getPort("\\A"); - RTLIL::SigSpec y = cell->getPort("\\Y"); + if (cell->type.in(ID($pos), ID($_BUF_)) && !cell->has_keep_attr()) { + bool is_signed = cell->type == ID($pos) && cell->getParam(ID(A_SIGNED)).as_bool(); + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec y = cell->getPort(ID::Y); a.extend_u0(GetSize(y), is_signed); module->connect(y, a); delcells.push_back(cell); @@ -491,7 +491,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool for (auto cell : delcells) { if (verbose) log_debug(" removing buffer cell `%s': %s = %s\n", cell->name.c_str(), - log_signal(cell->getPort("\\Y")), log_signal(cell->getPort("\\A"))); + log_signal(cell->getPort(ID::Y)), log_signal(cell->getPort(ID::A))); module->remove(cell); } if (!delcells.empty()) diff --git a/passes/opt/opt_demorgan.cc b/passes/opt/opt_demorgan.cc index 1699a6454..4bc82815b 100644 --- a/passes/opt/opt_demorgan.cc +++ b/passes/opt/opt_demorgan.cc @@ -35,10 +35,10 @@ void demorgan_worker( //TODO: Add support for reduce_xor //DeMorgan of XOR is either XOR (if even number of inputs) or XNOR (if odd number) - if( (cell->type != "$reduce_and") && (cell->type != "$reduce_or") ) + if( (cell->type != ID($reduce_and)) && (cell->type != ID($reduce_or)) ) return; - auto insig = sigmap(cell->getPort("\\A")); + auto insig = sigmap(cell->getPort(ID::A)); log("Inspecting %s cell %s (%d inputs)\n", log_id(cell->type), log_id(cell->name), GetSize(insig)); int num_inverted = 0; for(int i=0; itype == "$_NOT_") + if(x.port == ID::Y && x.cell->type == ID($_NOT_)) { inverted = true; break; @@ -85,7 +85,7 @@ void demorgan_worker( RTLIL::Cell* srcinv = NULL; for(auto x : ports) { - if(x.port == "\\Y" && x.cell->type == "$_NOT_") + if(x.port == ID::Y && x.cell->type == ID($_NOT_)) { srcinv = x.cell; break; @@ -103,7 +103,7 @@ void demorgan_worker( //We ARE inverted - bypass it //Don't automatically delete the inverter since other stuff might still use it else - insig[i] = srcinv->getPort("\\A"); + insig[i] = srcinv->getPort(ID::A); } //Cosmetic fixup: If our input is just a scrambled version of one bus, rearrange it @@ -151,20 +151,20 @@ void demorgan_worker( } //Push the new input signal back to the reduction (after bypassing/adding inverters) - cell->setPort("\\A", insig); + cell->setPort(ID::A, insig); //Change the cell type - if(cell->type == "$reduce_and") - cell->type = "$reduce_or"; - else if(cell->type == "$reduce_or") - cell->type = "$reduce_and"; + if(cell->type == ID($reduce_and)) + cell->type = ID($reduce_or); + else if(cell->type == ID($reduce_or)) + cell->type = ID($reduce_and); //don't change XOR //Add an inverter to the output - auto inverted_output = cell->getPort("\\Y"); + auto inverted_output = cell->getPort(ID::Y); auto uninverted_output = m->addWire(NEW_ID); m->addNot(NEW_ID, RTLIL::SigSpec(uninverted_output), inverted_output); - cell->setPort("\\Y", uninverted_output); + cell->setPort(ID::Y, uninverted_output); } struct OptDemorganPass : public Pass { diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 512ef0cbf..858b3560c 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -51,9 +51,9 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) } for (auto wire : module->wires()) { - if (wire->attributes.count("\\init")) { + if (wire->attributes.count(ID(init))) { SigSpec sig = sigmap(wire); - Const initval = wire->attributes.at("\\init"); + 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) initbits[sig[i]] = make_pair(wire, initval[i]); @@ -61,7 +61,7 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) } if (wire->port_input) driven_signals.add(sigmap(wire)); - if (wire->port_output || wire->get_bool_attribute("\\keep")) + if (wire->port_output || wire->get_bool_attribute(ID::keep)) used_signals.add(sigmap(wire)); all_signals.add(sigmap(wire)); } @@ -99,25 +99,26 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) for (auto wire : revisit_initwires) { SigSpec sig = sm2(wire); - Const initval = wire->attributes.at("\\init"); + Const initval = wire->attributes.at(ID(init)); for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) { if (SigBit(initval[i]) == sig[i]) initval[i] = State::Sx; } if (initval.is_fully_undef()) { log_debug("Removing init attribute from %s/%s.\n", log_id(module), log_id(wire)); - wire->attributes.erase("\\init"); + wire->attributes.erase(ID(init)); did_something = true; - } else if (initval != wire->attributes.at("\\init")) { + } else if (initval != wire->attributes.at(ID(init))) { log_debug("Updating init attribute on %s/%s: %s\n", log_id(module), log_id(wire), log_signal(initval)); - wire->attributes["\\init"] = initval; + wire->attributes[ID(init)] = initval; did_something = true; } } } } -void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) +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) { RTLIL::SigSpec Y = cell->getPort(out_port); out_val.extend_u0(Y.size(), false); @@ -134,14 +135,14 @@ void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutative, SigMap &sigmap) { - std::string b_name = cell->hasPort("\\B") ? "\\B" : "\\A"; + IdString b_name = cell->hasPort(ID::B) ? ID::B : ID::A; - bool a_signed = cell->parameters.at("\\A_SIGNED").as_bool(); - bool b_signed = cell->parameters.at(b_name + "_SIGNED").as_bool(); + bool a_signed = cell->parameters.at(ID(A_SIGNED)).as_bool(); + bool b_signed = cell->parameters.at(b_name.str() + "_SIGNED").as_bool(); - RTLIL::SigSpec sig_a = sigmap(cell->getPort("\\A")); + RTLIL::SigSpec sig_a = sigmap(cell->getPort(ID::A)); RTLIL::SigSpec sig_b = sigmap(cell->getPort(b_name)); - RTLIL::SigSpec sig_y = sigmap(cell->getPort("\\Y")); + RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y)); sig_a.extend_u0(sig_y.size(), a_signed); sig_b.extend_u0(sig_y.size(), b_signed); @@ -156,10 +157,10 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ int group_idx = GRP_DYN; RTLIL::SigBit bit_a = bits_a[i], bit_b = bits_b[i]; - if (cell->type == "$or" && (bit_a == RTLIL::State::S1 || bit_b == RTLIL::State::S1)) + if (cell->type == ID($or) && (bit_a == RTLIL::State::S1 || bit_b == RTLIL::State::S1)) bit_a = bit_b = RTLIL::State::S1; - if (cell->type == "$and" && (bit_a == RTLIL::State::S0 || bit_b == RTLIL::State::S0)) + if (cell->type == ID($and) && (bit_a == RTLIL::State::S0 || bit_b == RTLIL::State::S0)) bit_a = bit_b = RTLIL::State::S0; if (bit_a.wire == NULL && bit_b.wire == NULL) @@ -199,7 +200,7 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ new_b.append_bit(it.first.second); } - if (cell->type.in("$and", "$or") && i == GRP_CONST_A) { + if (cell->type.in(ID($and), ID($or)) && i == GRP_CONST_A) { log_debug(" Direct Connection: %s (%s with %s)\n", log_signal(new_b), log_id(cell->type), log_signal(new_a)); module->connect(new_y, new_b); module->connect(new_conn); @@ -208,24 +209,24 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ RTLIL::Cell *c = module->addCell(NEW_ID, cell->type); - c->setPort("\\A", new_a); - c->parameters["\\A_WIDTH"] = new_a.size(); - c->parameters["\\A_SIGNED"] = false; + c->setPort(ID::A, new_a); + c->parameters[ID(A_WIDTH)] = new_a.size(); + c->parameters[ID(A_SIGNED)] = false; - if (b_name == "\\B") { - c->setPort("\\B", new_b); - c->parameters["\\B_WIDTH"] = new_b.size(); - c->parameters["\\B_SIGNED"] = false; + if (b_name == ID::B) { + c->setPort(ID::B, new_b); + c->parameters[ID(B_WIDTH)] = new_b.size(); + c->parameters[ID(B_SIGNED)] = false; } - c->setPort("\\Y", new_y); - c->parameters["\\Y_WIDTH"] = new_y->width; + c->setPort(ID::Y, new_y); + c->parameters[ID(Y_WIDTH)] = new_y->width; c->check(); module->connect(new_conn); log_debug(" New cell `%s': A=%s", log_id(c), log_signal(new_a)); - if (b_name == "\\B") + if (b_name == ID::B) log_debug(", B=%s", log_signal(new_b)); log_debug("\n"); } @@ -367,11 +368,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons for (auto cell : module->cells()) if (design->selected(module, cell) && cell->type[0] == '$') { - if ((cell->type == "$_NOT_" || cell->type == "$not" || cell->type == "$logic_not") && - cell->getPort("\\A").size() == 1 && cell->getPort("\\Y").size() == 1) - invert_map[assign_map(cell->getPort("\\Y"))] = assign_map(cell->getPort("\\A")); - if ((cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\A") == SigSpec(State::S1) && cell->getPort("\\B") == SigSpec(State::S0)) - invert_map[assign_map(cell->getPort("\\Y"))] = assign_map(cell->getPort("\\S")); + if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && + cell->getPort(ID::A).size() == 1 && cell->getPort(ID::Y).size() == 1) + invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A)); + if (cell->type.in(ID($mux), ID($_MUX_)) && + cell->getPort(ID::A) == SigSpec(State::S1) && cell->getPort(ID::B) == SigSpec(State::S0)) + invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID(S))); if (ct_combinational.cell_known(cell->type)) for (auto &conn : cell->connections()) { RTLIL::SigSpec sig = assign_map(conn.second); @@ -395,66 +397,66 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons for (auto cell : cells.sorted) { #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("\\Y", RTLIL::SigSpec(RTLIL::State::S ## _v_)) +#define ACTION_DO_Y(_v_) ACTION_DO(ID::Y, RTLIL::SigSpec(RTLIL::State::S ## _v_)) if (clkinv) { - if (cell->type.in("$dff", "$dffe", "$dffsr", "$adff", "$fsm", "$memrd", "$memwr")) - handle_polarity_inv(cell, "\\CLK", "\\CLK_POLARITY", assign_map, invert_map); + if (cell->type.in(ID($dff), ID($dffe), ID($dffsr), ID($adff), ID($fsm), ID($memrd), ID($memwr))) + handle_polarity_inv(cell, ID(CLK), ID(CLK_POLARITY), assign_map, invert_map); - if (cell->type.in("$sr", "$dffsr", "$dlatchsr")) { - handle_polarity_inv(cell, "\\SET", "\\SET_POLARITY", assign_map, invert_map); - handle_polarity_inv(cell, "\\CLR", "\\CLR_POLARITY", assign_map, invert_map); + if (cell->type.in(ID($sr), ID($dffsr), 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("$dffe", "$dlatch", "$dlatchsr")) - handle_polarity_inv(cell, "\\EN", "\\EN_POLARITY", assign_map, invert_map); + if (cell->type.in(ID($dffe), ID($dlatch), ID($dlatchsr))) + handle_polarity_inv(cell, ID(EN), ID(EN_POLARITY), assign_map, invert_map); - handle_clkpol_celltype_swap(cell, "$_SR_N?_", "$_SR_P?_", "\\S", assign_map, invert_map); - handle_clkpol_celltype_swap(cell, "$_SR_?N_", "$_SR_?P_", "\\R", assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_SR_N?_", "$_SR_P?_", ID(S), assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_SR_?N_", "$_SR_?P_", ID(R), assign_map, invert_map); - handle_clkpol_celltype_swap(cell, "$_DFF_N_", "$_DFF_P_", "\\C", assign_map, invert_map); + handle_clkpol_celltype_swap(cell, "$_DFF_N_", "$_DFF_P_", ID(C), assign_map, invert_map); - handle_clkpol_celltype_swap(cell, "$_DFFE_N?_", "$_DFFE_P?_", "\\C", assign_map, invert_map); - handle_clkpol_celltype_swap(cell, "$_DFFE_?N_", "$_DFFE_?P_", "\\E", 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(E), assign_map, invert_map); - handle_clkpol_celltype_swap(cell, "$_DFF_N??_", "$_DFF_P??_", "\\C", assign_map, invert_map); - handle_clkpol_celltype_swap(cell, "$_DFF_?N?_", "$_DFF_?P?_", "\\R", assign_map, invert_map); + 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, "$_DFFSR_N??_", "$_DFFSR_P??_", "\\C", assign_map, invert_map); - handle_clkpol_celltype_swap(cell, "$_DFFSR_?N?_", "$_DFFSR_?P?_", "\\S", assign_map, invert_map); - handle_clkpol_celltype_swap(cell, "$_DFFSR_??N_", "$_DFFSR_??P_", "\\R", 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, "$_DLATCH_N_", "$_DLATCH_P_", "\\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, "$_DLATCHSR_N??_", "$_DLATCHSR_P??_", "\\E", assign_map, invert_map); - handle_clkpol_celltype_swap(cell, "$_DLATCHSR_?N?_", "$_DLATCHSR_?P?_", "\\S", assign_map, invert_map); - handle_clkpol_celltype_swap(cell, "$_DLATCHSR_??N_", "$_DLATCHSR_??P_", "\\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); } bool detect_const_and = false; bool detect_const_or = false; - if (cell->type.in("$reduce_and", "$_AND_")) + if (cell->type.in(ID($reduce_and), ID($_AND_))) detect_const_and = true; - if (cell->type.in("$and", "$logic_and") && GetSize(cell->getPort("\\A")) == 1 && GetSize(cell->getPort("\\B")) == 1 && !cell->getParam("\\A_SIGNED").as_bool()) + if (cell->type.in(ID($and), ID($logic_and)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool()) detect_const_and = true; - if (cell->type.in("$reduce_or", "$reduce_bool", "$_OR_")) + if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($_OR_))) detect_const_or = true; - if (cell->type.in("$or", "$logic_or") && GetSize(cell->getPort("\\A")) == 1 && GetSize(cell->getPort("\\B")) == 1 && !cell->getParam("\\A_SIGNED").as_bool()) + if (cell->type.in(ID($or), ID($logic_or)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool()) detect_const_or = true; if (detect_const_and || detect_const_or) { - pool input_bits = assign_map(cell->getPort("\\A")).to_sigbit_pool(); + pool input_bits = assign_map(cell->getPort(ID::A)).to_sigbit_pool(); bool found_zero = false, found_one = false, found_undef = false, found_inv = false, many_conconst = false; SigBit non_const_input = State::Sm; - if (cell->hasPort("\\B")) { - vector more_bits = assign_map(cell->getPort("\\B")).to_sigbit_vector(); + if (cell->hasPort(ID::B)) { + vector more_bits = assign_map(cell->getPort(ID::B)).to_sigbit_vector(); input_bits.insert(more_bits.begin(), more_bits.end()); } @@ -477,52 +479,50 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (detect_const_and && (found_zero || found_inv)) { cover("opt.opt_expr.const_and"); - replace_cell(assign_map, module, cell, "const_and", "\\Y", RTLIL::State::S0); + replace_cell(assign_map, module, cell, "const_and", ID::Y, RTLIL::State::S0); goto next_cell; } if (detect_const_or && (found_one || found_inv)) { cover("opt.opt_expr.const_or"); - replace_cell(assign_map, module, cell, "const_or", "\\Y", RTLIL::State::S1); + replace_cell(assign_map, module, cell, "const_or", ID::Y, RTLIL::State::S1); goto next_cell; } if (non_const_input != State::Sm && !found_undef) { cover("opt.opt_expr.and_or_buffer"); - replace_cell(assign_map, module, cell, "and_or_buffer", "\\Y", non_const_input); + replace_cell(assign_map, module, cell, "and_or_buffer", ID::Y, non_const_input); goto next_cell; } } - if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool", "$reduce_xor", "$reduce_xnor", "$neg") && - GetSize(cell->getPort("\\A")) == 1 && GetSize(cell->getPort("\\Y")) == 1) + if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($reduce_xor), ID($reduce_xnor), ID($neg)) && + GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1) { - if (cell->type == "$reduce_xnor") { + if (cell->type == ID($reduce_xnor)) { cover("opt.opt_expr.reduce_xnor_not"); log_debug("Replacing %s cell `%s' in module `%s' with $not cell.\n", log_id(cell->type), log_id(cell->name), log_id(module)); - cell->type = "$not"; + cell->type = ID($not); did_something = true; } else { cover("opt.opt_expr.unary_buffer"); - replace_cell(assign_map, module, cell, "unary_buffer", "\\Y", cell->getPort("\\A")); + replace_cell(assign_map, module, cell, "unary_buffer", ID::Y, cell->getPort(ID::A)); } goto next_cell; } if (do_fine) { - if (cell->type == "$not" || cell->type == "$pos" || - cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor") + if (cell->type.in(ID($not), ID($pos), ID($and), ID($or), ID($xor), ID($xnor))) if (group_cell_inputs(module, cell, true, assign_map)) goto next_cell; - if (cell->type == "$logic_not" || cell->type == "$logic_and" || cell->type == "$logic_or" || - cell->type == "$reduce_or" || cell->type == "$reduce_and" || cell->type == "$reduce_bool") + if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or), ID($reduce_or), ID($reduce_and), ID($reduce_bool))) { - SigBit neutral_bit = cell->type == "$reduce_and" ? State::S1 : State::S0; + SigBit neutral_bit = cell->type == ID($reduce_and) ? State::S1 : State::S0; - RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); RTLIL::SigSpec new_sig_a; for (auto bit : sig_a) @@ -535,17 +535,17 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.fine.neutral_A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_and", "$reduce_bool", cell->type.str()); log_debug("Replacing port A of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_sig_a)); - cell->setPort("\\A", new_sig_a); - cell->parameters.at("\\A_WIDTH") = GetSize(new_sig_a); + cell->setPort(ID::A, new_sig_a); + cell->parameters.at(ID(A_WIDTH)) = GetSize(new_sig_a); did_something = true; } } - if (cell->type == "$logic_and" || cell->type == "$logic_or") + if (cell->type.in(ID($logic_and), ID($logic_or))) { SigBit neutral_bit = State::S0; - RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); RTLIL::SigSpec new_sig_b; for (auto bit : sig_b) @@ -558,15 +558,15 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.fine.neutral_B", "$logic_and", "$logic_or", cell->type.str()); log_debug("Replacing port B of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_sig_b)); - cell->setPort("\\B", new_sig_b); - cell->parameters.at("\\B_WIDTH") = GetSize(new_sig_b); + cell->setPort(ID::B, new_sig_b); + cell->parameters.at(ID(B_WIDTH)) = GetSize(new_sig_b); did_something = true; } } - if (cell->type == "$reduce_and") + if (cell->type == ID($reduce_and)) { - RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); RTLIL::State new_a = RTLIL::State::S1; for (auto &bit : sig_a.to_sigbit_vector()) @@ -584,15 +584,15 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover("opt.opt_expr.fine.$reduce_and"); log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->setPort("\\A", sig_a = new_a); - cell->parameters.at("\\A_WIDTH") = 1; + cell->setPort(ID::A, sig_a = new_a); + cell->parameters.at(ID(A_WIDTH)) = 1; did_something = true; } } - if (cell->type == "$logic_not" || cell->type == "$logic_and" || cell->type == "$logic_or" || cell->type == "$reduce_or" || cell->type == "$reduce_bool") + if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or), ID($reduce_or), ID($reduce_bool))) { - RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); RTLIL::State new_a = RTLIL::State::S0; for (auto &bit : sig_a.to_sigbit_vector()) @@ -610,15 +610,15 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.fine.A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool", cell->type.str()); log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->setPort("\\A", sig_a = new_a); - cell->parameters.at("\\A_WIDTH") = 1; + cell->setPort(ID::A, sig_a = new_a); + cell->parameters.at(ID(A_WIDTH)) = 1; did_something = true; } } - if (cell->type == "$logic_and" || cell->type == "$logic_or") + if (cell->type.in(ID($logic_and), ID($logic_or))) { - RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); RTLIL::State new_b = RTLIL::State::S0; for (auto &bit : sig_b.to_sigbit_vector()) @@ -636,23 +636,93 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.fine.B", "$logic_and", "$logic_or", cell->type.str()); log_debug("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b)); - cell->setPort("\\B", sig_b = new_b); - cell->parameters.at("\\B_WIDTH") = 1; + cell->setPort(ID::B, sig_b = new_b); + cell->parameters.at(ID(B_WIDTH)) = 1; + did_something = true; + } + } + + if (cell->type.in(ID($add), ID($sub))) + { + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); + bool sub = cell->type == ID($sub); + + int i; + for (i = 0; i < GetSize(sig_y); i++) { + if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx) + module->connect(sig_y[i], sig_a[i]); + else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx) + module->connect(sig_y[i], sig_b[i]); + else + break; + } + if (i > 0) { + cover_list("opt.opt_expr.fine", "$add", "$sub", cell->type.str()); + cell->setPort(ID::A, sig_a.extract_end(i)); + cell->setPort(ID::B, sig_b.extract_end(i)); + cell->setPort(ID::Y, sig_y.extract_end(i)); + cell->fixup_parameters(); + did_something = true; + } + } + + if (cell->type == "$alu") + { + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); + RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID(CI))); + RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID(BI))); + RTLIL::SigSpec sig_x = cell->getPort(ID(X)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); + RTLIL::SigSpec sig_co = cell->getPort(ID(CO)); + + if (sig_ci.wire || sig_bi.wire) + goto next_cell; + + bool sub = (sig_ci == State::S1 && sig_bi == State::S1); + + // If not a subtraction, yet there is a carry or B is inverted + // then no optimisation is possible as carry will not be constant + if (!sub && (sig_ci != State::S0 || sig_bi != State::S0)) + goto next_cell; + + int i; + for (i = 0; i < GetSize(sig_y); i++) { + if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx) { + module->connect(sig_x[i], sub ? module->Not(NEW_ID, sig_a[i]).as_bit() : sig_a[i]); + module->connect(sig_y[i], sig_a[i]); + module->connect(sig_co[i], sub ? State::S1 : State::S0); + } + else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx) { + module->connect(sig_x[i], sig_b[i]); + module->connect(sig_y[i], sig_b[i]); + module->connect(sig_co[i], State::S0); + } + else + break; + } + if (i > 0) { + cover("opt.opt_expr.fine.$alu"); + cell->setPort(ID::A, sig_a.extract_end(i)); + cell->setPort(ID::B, sig_b.extract_end(i)); + cell->setPort(ID(X), sig_x.extract_end(i)); + cell->setPort(ID::Y, sig_y.extract_end(i)); + cell->setPort(ID(CO), sig_co.extract_end(i)); + cell->fixup_parameters(); did_something = true; } } } - if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$shift" || cell->type == "$shiftx" || - cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || - cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt" || - cell->type == "$neg" || cell->type == "$add" || cell->type == "$sub" || - cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod" || cell->type == "$pow") + if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($shift), ID($shiftx), ID($shl), ID($shr), ID($sshl), ID($sshr), + ID($lt), ID($le), ID($ge), ID($gt), ID($neg), ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) { - RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); - RTLIL::SigSpec sig_b = cell->hasPort("\\B") ? assign_map(cell->getPort("\\B")) : RTLIL::SigSpec(); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = cell->hasPort(ID::B) ? assign_map(cell->getPort(ID::B)) : RTLIL::SigSpec(); - if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") + if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) sig_a = RTLIL::SigSpec(); for (auto &bit : sig_a.to_sigbit_vector()) @@ -667,45 +737,44 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons found_the_x_bit: cover_list("opt.opt_expr.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$lt", "$le", "$ge", "$gt", "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type.str()); - if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || - cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") - replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); + if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($lt), ID($le), ID($ge), ID($gt))) + replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::State::Sx); else - replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort("\\Y").size())); + replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort(ID::Y).size())); goto next_cell; } } - if ((cell->type == "$_NOT_" || cell->type == "$not" || cell->type == "$logic_not") && cell->getPort("\\Y").size() == 1 && - invert_map.count(assign_map(cell->getPort("\\A"))) != 0) { + if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID::Y).size() == 1 && + invert_map.count(assign_map(cell->getPort(ID::A))) != 0) { cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str()); - replace_cell(assign_map, module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->getPort("\\A")))); + replace_cell(assign_map, module, cell, "double_invert", ID::Y, invert_map.at(assign_map(cell->getPort(ID::A)))); goto next_cell; } - if ((cell->type == "$_MUX_" || cell->type == "$mux") && invert_map.count(assign_map(cell->getPort("\\S"))) != 0) { + if (cell->type.in(ID($_MUX_), ID($mux)) && invert_map.count(assign_map(cell->getPort(ID(S)))) != 0) { cover_list("opt.opt_expr.invert.muxsel", "$_MUX_", "$mux", cell->type.str()); log_debug("Optimizing away select inverter for %s cell `%s' in module `%s'.\n", log_id(cell->type), log_id(cell), log_id(module)); - RTLIL::SigSpec tmp = cell->getPort("\\A"); - cell->setPort("\\A", cell->getPort("\\B")); - cell->setPort("\\B", tmp); - cell->setPort("\\S", invert_map.at(assign_map(cell->getPort("\\S")))); + RTLIL::SigSpec tmp = cell->getPort(ID::A); + cell->setPort(ID::A, cell->getPort(ID::B)); + cell->setPort(ID::B, tmp); + cell->setPort(ID(S), invert_map.at(assign_map(cell->getPort(ID(S))))); did_something = true; goto next_cell; } - if (cell->type == "$_NOT_") { - RTLIL::SigSpec input = cell->getPort("\\A"); + if (cell->type == ID($_NOT_)) { + RTLIL::SigSpec input = cell->getPort(ID::A); assign_map.apply(input); if (input.match("1")) ACTION_DO_Y(0); if (input.match("0")) ACTION_DO_Y(1); if (input.match("*")) ACTION_DO_Y(x); } - if (cell->type == "$_AND_") { + if (cell->type == ID($_AND_)) { RTLIL::SigSpec input; - input.append(cell->getPort("\\B")); - input.append(cell->getPort("\\A")); + input.append(cell->getPort(ID::B)); + input.append(cell->getPort(ID::A)); assign_map.apply(input); if (input.match(" 0")) ACTION_DO_Y(0); if (input.match("0 ")) ACTION_DO_Y(0); @@ -717,14 +786,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (input.match(" *")) ACTION_DO_Y(0); if (input.match("* ")) ACTION_DO_Y(0); } - if (input.match(" 1")) ACTION_DO("\\Y", input.extract(1, 1)); - if (input.match("1 ")) ACTION_DO("\\Y", input.extract(0, 1)); + if (input.match(" 1")) ACTION_DO(ID::Y, input.extract(1, 1)); + if (input.match("1 ")) ACTION_DO(ID::Y, input.extract(0, 1)); } - if (cell->type == "$_OR_") { + if (cell->type == ID($_OR_)) { RTLIL::SigSpec input; - input.append(cell->getPort("\\B")); - input.append(cell->getPort("\\A")); + input.append(cell->getPort(ID::B)); + input.append(cell->getPort(ID::A)); assign_map.apply(input); if (input.match(" 1")) ACTION_DO_Y(1); if (input.match("1 ")) ACTION_DO_Y(1); @@ -736,14 +805,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (input.match(" *")) ACTION_DO_Y(1); if (input.match("* ")) ACTION_DO_Y(1); } - if (input.match(" 0")) ACTION_DO("\\Y", input.extract(1, 1)); - if (input.match("0 ")) ACTION_DO("\\Y", input.extract(0, 1)); + if (input.match(" 0")) ACTION_DO(ID::Y, input.extract(1, 1)); + if (input.match("0 ")) ACTION_DO(ID::Y, input.extract(0, 1)); } - if (cell->type == "$_XOR_") { + if (cell->type == ID($_XOR_)) { RTLIL::SigSpec input; - input.append(cell->getPort("\\B")); - input.append(cell->getPort("\\A")); + input.append(cell->getPort(ID::B)); + input.append(cell->getPort(ID::A)); assign_map.apply(input); if (input.match("00")) ACTION_DO_Y(0); if (input.match("01")) ACTION_DO_Y(1); @@ -751,27 +820,27 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (input.match("11")) ACTION_DO_Y(0); if (input.match(" *")) ACTION_DO_Y(x); if (input.match("* ")) ACTION_DO_Y(x); - if (input.match(" 0")) ACTION_DO("\\Y", input.extract(1, 1)); - if (input.match("0 ")) ACTION_DO("\\Y", input.extract(0, 1)); + if (input.match(" 0")) ACTION_DO(ID::Y, input.extract(1, 1)); + if (input.match("0 ")) ACTION_DO(ID::Y, input.extract(0, 1)); } - if (cell->type == "$_MUX_") { + if (cell->type == ID($_MUX_)) { RTLIL::SigSpec input; - input.append(cell->getPort("\\S")); - input.append(cell->getPort("\\B")); - input.append(cell->getPort("\\A")); + input.append(cell->getPort(ID(S))); + input.append(cell->getPort(ID::B)); + input.append(cell->getPort(ID::A)); assign_map.apply(input); if (input.extract(2, 1) == input.extract(1, 1)) - ACTION_DO("\\Y", input.extract(2, 1)); - if (input.match(" 0")) ACTION_DO("\\Y", input.extract(2, 1)); - if (input.match(" 1")) ACTION_DO("\\Y", input.extract(1, 1)); - if (input.match("01 ")) ACTION_DO("\\Y", input.extract(0, 1)); + ACTION_DO(ID::Y, input.extract(2, 1)); + if (input.match(" 0")) ACTION_DO(ID::Y, input.extract(2, 1)); + if (input.match(" 1")) ACTION_DO(ID::Y, input.extract(1, 1)); + if (input.match("01 ")) ACTION_DO(ID::Y, input.extract(0, 1)); if (input.match("10 ")) { cover("opt.opt_expr.mux_to_inv"); - cell->type = "$_NOT_"; - cell->setPort("\\A", input.extract(0, 1)); - cell->unsetPort("\\B"); - cell->unsetPort("\\S"); + cell->type = ID($_NOT_); + cell->setPort(ID::A, input.extract(0, 1)); + cell->unsetPort(ID::B); + cell->unsetPort(ID(S)); goto next_cell; } if (input.match("11 ")) ACTION_DO_Y(1); @@ -780,38 +849,38 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (input.match("01*")) ACTION_DO_Y(x); if (input.match("10*")) ACTION_DO_Y(x); if (mux_undef) { - if (input.match("* ")) ACTION_DO("\\Y", input.extract(1, 1)); - if (input.match(" * ")) ACTION_DO("\\Y", input.extract(2, 1)); - if (input.match(" *")) ACTION_DO("\\Y", input.extract(2, 1)); + if (input.match("* ")) ACTION_DO(ID::Y, input.extract(1, 1)); + if (input.match(" * ")) ACTION_DO(ID::Y, input.extract(2, 1)); + if (input.match(" *")) ACTION_DO(ID::Y, input.extract(2, 1)); } } - if (cell->type == "$_TBUF_" || cell->type == "$tribuf") { - RTLIL::SigSpec input = cell->getPort(cell->type == "$_TBUF_" ? "\\E" : "\\EN"); - RTLIL::SigSpec a = cell->getPort("\\A"); + if (cell->type.in(ID($_TBUF_), ID($tribuf))) { + RTLIL::SigSpec input = cell->getPort(cell->type == ID($_TBUF_) ? ID(E) : ID(EN)); + RTLIL::SigSpec a = cell->getPort(ID::A); assign_map.apply(input); assign_map.apply(a); if (input == State::S1) - ACTION_DO("\\Y", cell->getPort("\\A")); + ACTION_DO(ID::Y, cell->getPort(ID::A)); if (input == State::S0 && !a.is_fully_undef()) { cover("opt.opt_expr.action_" S__LINE__); log_debug("Replacing data input of %s cell `%s' in module `%s' with constant undef.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); - cell->setPort("\\A", SigSpec(State::Sx, GetSize(a))); + cell->setPort(ID::A, SigSpec(State::Sx, GetSize(a))); did_something = true; goto next_cell; } } - if (cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex") + if (cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex))) { - RTLIL::SigSpec a = cell->getPort("\\A"); - RTLIL::SigSpec b = cell->getPort("\\B"); + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec b = cell->getPort(ID::B); - if (cell->parameters["\\A_WIDTH"].as_int() != cell->parameters["\\B_WIDTH"].as_int()) { - int width = max(cell->parameters["\\A_WIDTH"].as_int(), cell->parameters["\\B_WIDTH"].as_int()); - a.extend_u0(width, cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()); - b.extend_u0(width, cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()); + if (cell->parameters[ID(A_WIDTH)].as_int() != cell->parameters[ID(B_WIDTH)].as_int()) { + int width = max(cell->parameters[ID(A_WIDTH)].as_int(), cell->parameters[ID(B_WIDTH)].as_int()); + a.extend_u0(width, cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool()); + b.extend_u0(width, cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool()); } RTLIL::SigSpec new_a, new_b; @@ -820,9 +889,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons for (int i = 0; i < GetSize(a); i++) { if (a[i].wire == NULL && b[i].wire == NULL && a[i] != b[i] && a[i].data <= RTLIL::State::S1 && b[i].data <= RTLIL::State::S1) { cover_list("opt.opt_expr.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); - RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S0 : RTLIL::State::S1); - new_y.extend_u0(cell->parameters["\\Y_WIDTH"].as_int(), false); - replace_cell(assign_map, module, cell, "isneq", "\\Y", new_y); + RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ? RTLIL::State::S0 : RTLIL::State::S1); + new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false); + replace_cell(assign_map, module, cell, "isneq", ID::Y, new_y); goto next_cell; } if (a[i] == b[i]) @@ -833,83 +902,83 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (new_a.size() == 0) { cover_list("opt.opt_expr.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); - RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S1 : RTLIL::State::S0); - new_y.extend_u0(cell->parameters["\\Y_WIDTH"].as_int(), false); - replace_cell(assign_map, module, cell, "empty", "\\Y", new_y); + RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ? RTLIL::State::S1 : RTLIL::State::S0); + new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false); + replace_cell(assign_map, module, cell, "empty", ID::Y, new_y); goto next_cell; } if (new_a.size() < a.size() || new_b.size() < b.size()) { cover_list("opt.opt_expr.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); - cell->setPort("\\A", new_a); - cell->setPort("\\B", new_b); - cell->parameters["\\A_WIDTH"] = new_a.size(); - cell->parameters["\\B_WIDTH"] = new_b.size(); + cell->setPort(ID::A, new_a); + cell->setPort(ID::B, new_b); + cell->parameters[ID(A_WIDTH)] = new_a.size(); + cell->parameters[ID(B_WIDTH)] = new_b.size(); } } - if ((cell->type == "$eq" || cell->type == "$ne") && cell->parameters["\\Y_WIDTH"].as_int() == 1 && - cell->parameters["\\A_WIDTH"].as_int() == 1 && cell->parameters["\\B_WIDTH"].as_int() == 1) + if (cell->type.in(ID($eq), ID($ne)) && cell->parameters[ID(Y_WIDTH)].as_int() == 1 && + cell->parameters[ID(A_WIDTH)].as_int() == 1 && cell->parameters[ID(B_WIDTH)].as_int() == 1) { - RTLIL::SigSpec a = assign_map(cell->getPort("\\A")); - RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); if (a.is_fully_const() && !b.is_fully_const()) { cover_list("opt.opt_expr.eqneq.swapconst", "$eq", "$ne", cell->type.str()); - cell->setPort("\\A", b); - cell->setPort("\\B", a); + cell->setPort(ID::A, b); + cell->setPort(ID::B, a); std::swap(a, b); } if (b.is_fully_const()) { - if (b.as_bool() == (cell->type == "$eq")) { + if (b.as_bool() == (cell->type == ID($eq))) { RTLIL::SigSpec input = b; - ACTION_DO("\\Y", cell->getPort("\\A")); + ACTION_DO(ID::Y, cell->getPort(ID::A)); } else { cover_list("opt.opt_expr.eqneq.isnot", "$eq", "$ne", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); - cell->type = "$not"; - cell->parameters.erase("\\B_WIDTH"); - cell->parameters.erase("\\B_SIGNED"); - cell->unsetPort("\\B"); + cell->type = ID($not); + cell->parameters.erase(ID(B_WIDTH)); + cell->parameters.erase(ID(B_SIGNED)); + cell->unsetPort(ID::B); did_something = true; } goto next_cell; } } - if ((cell->type == "$eq" || cell->type == "$ne") && - (assign_map(cell->getPort("\\A")).is_fully_zero() || assign_map(cell->getPort("\\B")).is_fully_zero())) + if (cell->type.in(ID($eq), ID($ne)) && + (assign_map(cell->getPort(ID::A)).is_fully_zero() || assign_map(cell->getPort(ID::B)).is_fully_zero())) { cover_list("opt.opt_expr.eqneq.cmpzero", "$eq", "$ne", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with %s.\n", log_id(cell->type), log_id(cell), log_id(module), "$eq" ? "$logic_not" : "$reduce_bool"); - cell->type = cell->type == "$eq" ? "$logic_not" : "$reduce_bool"; - if (assign_map(cell->getPort("\\A")).is_fully_zero()) { - cell->setPort("\\A", cell->getPort("\\B")); - cell->setParam("\\A_SIGNED", cell->getParam("\\B_SIGNED")); - cell->setParam("\\A_WIDTH", cell->getParam("\\B_WIDTH")); + cell->type = cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool); + if (assign_map(cell->getPort(ID::A)).is_fully_zero()) { + cell->setPort(ID::A, cell->getPort(ID::B)); + cell->setParam(ID(A_SIGNED), cell->getParam(ID(B_SIGNED))); + cell->setParam(ID(A_WIDTH), cell->getParam(ID(B_WIDTH))); } - cell->unsetPort("\\B"); - cell->unsetParam("\\B_SIGNED"); - cell->unsetParam("\\B_WIDTH"); + cell->unsetPort(ID::B); + cell->unsetParam(ID(B_SIGNED)); + cell->unsetParam(ID(B_WIDTH)); did_something = true; goto next_cell; } - if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx") && assign_map(cell->getPort("\\B")).is_fully_const()) + if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)) && assign_map(cell->getPort(ID::B)).is_fully_const()) { - bool sign_ext = cell->type == "$sshr" && cell->getParam("\\A_SIGNED").as_bool(); - int shift_bits = assign_map(cell->getPort("\\B")).as_int(cell->type.in("$shift", "$shiftx") && cell->getParam("\\B_SIGNED").as_bool()); + bool sign_ext = cell->type == ID($sshr) && cell->getParam(ID(A_SIGNED)).as_bool(); + int shift_bits = assign_map(cell->getPort(ID::B)).as_int(cell->type.in(ID($shift), ID($shiftx)) && cell->getParam(ID(B_SIGNED)).as_bool()); - if (cell->type.in("$shl", "$sshl")) + if (cell->type.in(ID($shl), ID($sshl))) shift_bits *= -1; - RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); - RTLIL::SigSpec sig_y(cell->type == "$shiftx" ? RTLIL::State::Sx : RTLIL::State::S0, cell->getParam("\\Y_WIDTH").as_int()); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_y(cell->type == ID($shiftx) ? RTLIL::State::Sx : RTLIL::State::S0, cell->getParam(ID(Y_WIDTH)).as_int()); if (GetSize(sig_a) < GetSize(sig_y)) - sig_a.extend_u0(GetSize(sig_y), cell->getParam("\\A_SIGNED").as_bool()); + sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID(A_SIGNED)).as_bool()); for (int i = 0; i < GetSize(sig_y); i++) { int idx = i + shift_bits; @@ -922,9 +991,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.constshift", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", cell->type.str()); log_debug("Replacing %s cell `%s' (B=%s, SHR=%d) in module `%s' with fixed wiring: %s\n", - log_id(cell->type), log_id(cell), log_signal(assign_map(cell->getPort("\\B"))), shift_bits, log_id(module), log_signal(sig_y)); + log_id(cell->type), log_id(cell), log_signal(assign_map(cell->getPort(ID::B))), shift_bits, log_id(module), log_signal(sig_y)); - module->connect(cell->getPort("\\Y"), sig_y); + module->connect(cell->getPort(ID::Y), sig_y); module->remove(cell); did_something = true; @@ -937,41 +1006,41 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons bool identity_wrt_b = false; bool arith_inverse = false; - if (cell->type == "$add" || cell->type == "$sub" || cell->type == "$or" || cell->type == "$xor") + if (cell->type.in(ID($add), ID($sub), ID($or), ID($xor))) { - RTLIL::SigSpec a = assign_map(cell->getPort("\\A")); - RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); - if (cell->type != "$sub" && a.is_fully_const() && a.as_bool() == false) + if (cell->type != ID($sub) && a.is_fully_const() && a.as_bool() == false) identity_wrt_b = true; if (b.is_fully_const() && b.as_bool() == false) identity_wrt_a = true; } - if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") + if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { - RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); if (b.is_fully_const() && b.as_bool() == false) identity_wrt_a = true; } - if (cell->type == "$mul") + if (cell->type == ID($mul)) { - RTLIL::SigSpec a = assign_map(cell->getPort("\\A")); - RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); - if (a.is_fully_const() && is_one_or_minus_one(a.as_const(), cell->getParam("\\A_SIGNED").as_bool(), arith_inverse)) + if (a.is_fully_const() && is_one_or_minus_one(a.as_const(), cell->getParam(ID(A_SIGNED)).as_bool(), arith_inverse)) identity_wrt_b = true; else - if (b.is_fully_const() && is_one_or_minus_one(b.as_const(), cell->getParam("\\B_SIGNED").as_bool(), arith_inverse)) + if (b.is_fully_const() && is_one_or_minus_one(b.as_const(), cell->getParam(ID(B_SIGNED)).as_bool(), arith_inverse)) identity_wrt_a = true; } - if (cell->type == "$div") + if (cell->type == ID($div)) { - RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); if (b.is_fully_const() && b.size() <= 32 && b.as_int() == 1) identity_wrt_a = true; @@ -988,15 +1057,15 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); if (!identity_wrt_a) { - cell->setPort("\\A", cell->getPort("\\B")); - cell->parameters.at("\\A_WIDTH") = cell->parameters.at("\\B_WIDTH"); - cell->parameters.at("\\A_SIGNED") = cell->parameters.at("\\B_SIGNED"); + cell->setPort(ID::A, cell->getPort(ID::B)); + cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH)); + cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED)); } - cell->type = arith_inverse ? "$neg" : "$pos"; - cell->unsetPort("\\B"); - cell->parameters.erase("\\B_WIDTH"); - cell->parameters.erase("\\B_SIGNED"); + cell->type = arith_inverse ? ID($neg) : ID($pos); + cell->unsetPort(ID::B); + cell->parameters.erase(ID(B_WIDTH)); + cell->parameters.erase(ID(B_SIGNED)); cell->check(); did_something = true; @@ -1004,91 +1073,91 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } - if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && - cell->getPort("\\A") == RTLIL::SigSpec(0, 1) && cell->getPort("\\B") == RTLIL::SigSpec(1, 1)) { + if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && + cell->getPort(ID::A) == State::S0 && cell->getPort(ID::B) == State::S1) { cover_list("opt.opt_expr.mux_bool", "$mux", "$_MUX_", cell->type.str()); - replace_cell(assign_map, module, cell, "mux_bool", "\\Y", cell->getPort("\\S")); + replace_cell(assign_map, module, cell, "mux_bool", ID::Y, cell->getPort(ID(S))); goto next_cell; } - if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && - cell->getPort("\\A") == RTLIL::SigSpec(1, 1) && cell->getPort("\\B") == RTLIL::SigSpec(0, 1)) { + if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && + cell->getPort(ID::A) == State::S1 && cell->getPort(ID::B) == State::S0) { cover_list("opt.opt_expr.mux_invert", "$mux", "$_MUX_", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); - cell->setPort("\\A", cell->getPort("\\S")); - cell->unsetPort("\\B"); - cell->unsetPort("\\S"); - if (cell->type == "$mux") { - Const width = cell->parameters["\\WIDTH"]; - cell->parameters["\\A_WIDTH"] = width; - cell->parameters["\\Y_WIDTH"] = width; - cell->parameters["\\A_SIGNED"] = 0; - cell->parameters.erase("\\WIDTH"); - cell->type = "$not"; + cell->setPort(ID::A, cell->getPort(ID(S))); + cell->unsetPort(ID::B); + cell->unsetPort(ID(S)); + if (cell->type == ID($mux)) { + Const width = cell->parameters[ID(WIDTH)]; + cell->parameters[ID(A_WIDTH)] = width; + cell->parameters[ID(Y_WIDTH)] = width; + cell->parameters[ID(A_SIGNED)] = 0; + cell->parameters.erase(ID(WIDTH)); + cell->type = ID($not); } else - cell->type = "$_NOT_"; + cell->type = ID($_NOT_); did_something = true; goto next_cell; } - if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\A") == RTLIL::SigSpec(0, 1)) { + if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::A) == State::S0) { cover_list("opt.opt_expr.mux_and", "$mux", "$_MUX_", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with and-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); - cell->setPort("\\A", cell->getPort("\\S")); - cell->unsetPort("\\S"); - if (cell->type == "$mux") { - Const width = cell->parameters["\\WIDTH"]; - cell->parameters["\\A_WIDTH"] = width; - cell->parameters["\\B_WIDTH"] = width; - cell->parameters["\\Y_WIDTH"] = width; - cell->parameters["\\A_SIGNED"] = 0; - cell->parameters["\\B_SIGNED"] = 0; - cell->parameters.erase("\\WIDTH"); - cell->type = "$and"; + cell->setPort(ID::A, cell->getPort(ID(S))); + cell->unsetPort(ID(S)); + if (cell->type == ID($mux)) { + Const width = cell->parameters[ID(WIDTH)]; + cell->parameters[ID(A_WIDTH)] = width; + cell->parameters[ID(B_WIDTH)] = width; + cell->parameters[ID(Y_WIDTH)] = width; + cell->parameters[ID(A_SIGNED)] = 0; + cell->parameters[ID(B_SIGNED)] = 0; + cell->parameters.erase(ID(WIDTH)); + cell->type = ID($and); } else - cell->type = "$_AND_"; + cell->type = ID($_AND_); did_something = true; goto next_cell; } - if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\B") == RTLIL::SigSpec(1, 1)) { + if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::B) == State::S1) { cover_list("opt.opt_expr.mux_or", "$mux", "$_MUX_", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with or-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); - cell->setPort("\\B", cell->getPort("\\S")); - cell->unsetPort("\\S"); - if (cell->type == "$mux") { - Const width = cell->parameters["\\WIDTH"]; - cell->parameters["\\A_WIDTH"] = width; - cell->parameters["\\B_WIDTH"] = width; - cell->parameters["\\Y_WIDTH"] = width; - cell->parameters["\\A_SIGNED"] = 0; - cell->parameters["\\B_SIGNED"] = 0; - cell->parameters.erase("\\WIDTH"); - cell->type = "$or"; + cell->setPort(ID::B, cell->getPort(ID(S))); + cell->unsetPort(ID(S)); + if (cell->type == ID($mux)) { + Const width = cell->parameters[ID(WIDTH)]; + cell->parameters[ID(A_WIDTH)] = width; + cell->parameters[ID(B_WIDTH)] = width; + cell->parameters[ID(Y_WIDTH)] = width; + cell->parameters[ID(A_SIGNED)] = 0; + cell->parameters[ID(B_SIGNED)] = 0; + cell->parameters.erase(ID(WIDTH)); + cell->type = ID($or); } else - cell->type = "$_OR_"; + cell->type = ID($_OR_); did_something = true; goto next_cell; } - if (mux_undef && (cell->type == "$mux" || cell->type == "$pmux")) { + if (mux_undef && cell->type.in(ID($mux), ID($pmux))) { RTLIL::SigSpec new_a, new_b, new_s; - int width = cell->getPort("\\A").size(); - if ((cell->getPort("\\A").is_fully_undef() && cell->getPort("\\B").is_fully_undef()) || - cell->getPort("\\S").is_fully_undef()) { + int width = cell->getPort(ID::A).size(); + if ((cell->getPort(ID::A).is_fully_undef() && cell->getPort(ID::B).is_fully_undef()) || + cell->getPort(ID(S)).is_fully_undef()) { cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str()); - replace_cell(assign_map, module, cell, "mux_undef", "\\Y", cell->getPort("\\A")); + replace_cell(assign_map, module, cell, "mux_undef", ID::Y, cell->getPort(ID::A)); goto next_cell; } - for (int i = 0; i < cell->getPort("\\S").size(); i++) { - RTLIL::SigSpec old_b = cell->getPort("\\B").extract(i*width, width); - RTLIL::SigSpec old_s = cell->getPort("\\S").extract(i, 1); + for (int i = 0; i < cell->getPort(ID(S)).size(); i++) { + RTLIL::SigSpec old_b = cell->getPort(ID::B).extract(i*width, width); + RTLIL::SigSpec old_s = cell->getPort(ID(S)).extract(i, 1); if (old_b.is_fully_undef() || old_s.is_fully_undef()) continue; new_b.append(old_b); new_s.append(old_s); } - new_a = cell->getPort("\\A"); + new_a = cell->getPort(ID::A); if (new_a.is_fully_undef() && new_s.size() > 0) { new_a = new_b.extract((new_s.size()-1)*width, width); new_b = new_b.extract(0, (new_s.size()-1)*width); @@ -1096,27 +1165,27 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } if (new_s.size() == 0) { cover_list("opt.opt_expr.mux_empty", "$mux", "$pmux", cell->type.str()); - replace_cell(assign_map, module, cell, "mux_empty", "\\Y", new_a); + replace_cell(assign_map, module, cell, "mux_empty", ID::Y, new_a); goto next_cell; } if (new_a == RTLIL::SigSpec(RTLIL::State::S0) && new_b == RTLIL::SigSpec(RTLIL::State::S1)) { cover_list("opt.opt_expr.mux_sel01", "$mux", "$pmux", cell->type.str()); - replace_cell(assign_map, module, cell, "mux_sel01", "\\Y", new_s); + replace_cell(assign_map, module, cell, "mux_sel01", ID::Y, new_s); goto next_cell; } - if (cell->getPort("\\S").size() != new_s.size()) { + if (cell->getPort(ID(S)).size() != new_s.size()) { cover_list("opt.opt_expr.mux_reduce", "$mux", "$pmux", cell->type.str()); log_debug("Optimized away %d select inputs of %s cell `%s' in module `%s'.\n", - GetSize(cell->getPort("\\S")) - GetSize(new_s), log_id(cell->type), log_id(cell), log_id(module)); - cell->setPort("\\A", new_a); - cell->setPort("\\B", new_b); - cell->setPort("\\S", new_s); + GetSize(cell->getPort(ID(S))) - GetSize(new_s), log_id(cell->type), log_id(cell), log_id(module)); + cell->setPort(ID::A, new_a); + cell->setPort(ID::B, new_b); + cell->setPort(ID(S), new_s); if (new_s.size() > 1) { - cell->type = "$pmux"; - cell->parameters["\\S_WIDTH"] = new_s.size(); + cell->type = ID($pmux); + cell->parameters[ID(S_WIDTH)] = new_s.size(); } else { - cell->type = "$mux"; - cell->parameters.erase("\\S_WIDTH"); + cell->type = ID($mux); + cell->parameters.erase(ID(S_WIDTH)); } did_something = true; } @@ -1124,30 +1193,30 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons #define FOLD_1ARG_CELL(_t) \ if (cell->type == "$" #_t) { \ - RTLIL::SigSpec a = cell->getPort("\\A"); \ + RTLIL::SigSpec a = cell->getPort(ID::A); \ assign_map.apply(a); \ if (a.is_fully_const()) { \ RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \ RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), dummy_arg, \ - cell->parameters["\\A_SIGNED"].as_bool(), false, \ - cell->parameters["\\Y_WIDTH"].as_int())); \ + cell->parameters[ID(A_SIGNED)].as_bool(), false, \ + cell->parameters[ID(Y_WIDTH)].as_int())); \ cover("opt.opt_expr.const.$" #_t); \ - replace_cell(assign_map, module, cell, stringf("%s", log_signal(a)), "\\Y", y); \ + replace_cell(assign_map, module, cell, stringf("%s", log_signal(a)), ID::Y, y); \ goto next_cell; \ } \ } #define FOLD_2ARG_CELL(_t) \ if (cell->type == "$" #_t) { \ - RTLIL::SigSpec a = cell->getPort("\\A"); \ - RTLIL::SigSpec b = cell->getPort("\\B"); \ + RTLIL::SigSpec a = cell->getPort(ID::A); \ + RTLIL::SigSpec b = cell->getPort(ID::B); \ assign_map.apply(a), assign_map.apply(b); \ if (a.is_fully_const() && b.is_fully_const()) { \ RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), b.as_const(), \ - cell->parameters["\\A_SIGNED"].as_bool(), \ - cell->parameters["\\B_SIGNED"].as_bool(), \ - cell->parameters["\\Y_WIDTH"].as_int())); \ + cell->parameters[ID(A_SIGNED)].as_bool(), \ + cell->parameters[ID(B_SIGNED)].as_bool(), \ + cell->parameters[ID(Y_WIDTH)].as_int())); \ cover("opt.opt_expr.const.$" #_t); \ - replace_cell(assign_map, module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), "\\Y", y); \ + replace_cell(assign_map, module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), ID::Y, y); \ goto next_cell; \ } \ } @@ -1193,25 +1262,25 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons FOLD_1ARG_CELL(neg) // be very conservative with optimizing $mux cells as we do not want to break mux trees - if (cell->type == "$mux") { - RTLIL::SigSpec input = assign_map(cell->getPort("\\S")); - RTLIL::SigSpec inA = assign_map(cell->getPort("\\A")); - RTLIL::SigSpec inB = assign_map(cell->getPort("\\B")); + if (cell->type == ID($mux)) { + RTLIL::SigSpec input = assign_map(cell->getPort(ID(S))); + RTLIL::SigSpec inA = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec inB = assign_map(cell->getPort(ID::B)); if (input.is_fully_const()) - ACTION_DO("\\Y", input.as_bool() ? cell->getPort("\\B") : cell->getPort("\\A")); + ACTION_DO(ID::Y, input.as_bool() ? cell->getPort(ID::B) : cell->getPort(ID::A)); else if (inA == inB) - ACTION_DO("\\Y", cell->getPort("\\A")); + ACTION_DO(ID::Y, cell->getPort(ID::A)); } - if (!keepdc && cell->type == "$mul") + if (!keepdc && cell->type == ID($mul)) { - bool a_signed = cell->parameters["\\A_SIGNED"].as_bool(); - bool b_signed = cell->parameters["\\B_SIGNED"].as_bool(); + bool a_signed = cell->parameters[ID(A_SIGNED)].as_bool(); + bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool(); bool swapped_ab = false; - RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); - RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); - RTLIL::SigSpec sig_y = assign_map(cell->getPort("\\Y")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); + RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y)); if (sig_b.is_fully_const() && sig_b.size() <= 32) std::swap(sig_a, sig_b), std::swap(a_signed, b_signed), swapped_ab = true; @@ -1246,9 +1315,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons a_val, cell->name.c_str(), module->name.c_str(), i); if (!swapped_ab) { - cell->setPort("\\A", cell->getPort("\\B")); - cell->parameters.at("\\A_WIDTH") = cell->parameters.at("\\B_WIDTH"); - cell->parameters.at("\\A_SIGNED") = cell->parameters.at("\\B_SIGNED"); + cell->setPort(ID::A, cell->getPort(ID::B)); + cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH)); + cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED)); } std::vector new_b = RTLIL::SigSpec(i, 6); @@ -1256,10 +1325,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons while (GetSize(new_b) > 1 && new_b.back() == RTLIL::State::S0) new_b.pop_back(); - cell->type = "$shl"; - cell->parameters["\\B_WIDTH"] = GetSize(new_b); - cell->parameters["\\B_SIGNED"] = false; - cell->setPort("\\B", new_b); + cell->type = ID($shl); + cell->parameters[ID(B_WIDTH)] = GetSize(new_b); + cell->parameters[ID(B_SIGNED)] = false; + cell->setPort(ID::B, new_b); cell->check(); did_something = true; @@ -1268,11 +1337,11 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } - if (!keepdc && cell->type.in("$div", "$mod")) + if (!keepdc && cell->type.in(ID($div), ID($mod))) { - bool b_signed = cell->parameters["\\B_SIGNED"].as_bool(); - SigSpec sig_b = assign_map(cell->getPort("\\B")); - SigSpec sig_y = assign_map(cell->getPort("\\Y")); + bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool(); + SigSpec sig_b = assign_map(cell->getPort(ID::B)); + SigSpec sig_y = assign_map(cell->getPort(ID::Y)); if (sig_b.is_fully_def() && sig_b.size() <= 32) { @@ -1295,7 +1364,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons for (int i = 1; i < (b_signed ? sig_b.size()-1 : sig_b.size()); i++) if (b_val == (1 << i)) { - if (cell->type == "$div") + if (cell->type == ID($div)) { cover("opt.opt_expr.div_shift"); @@ -1307,10 +1376,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons while (GetSize(new_b) > 1 && new_b.back() == RTLIL::State::S0) new_b.pop_back(); - cell->type = "$shr"; - cell->parameters["\\B_WIDTH"] = GetSize(new_b); - cell->parameters["\\B_SIGNED"] = false; - cell->setPort("\\B", new_b); + cell->type = ID($shr); + cell->parameters[ID(B_WIDTH)] = GetSize(new_b); + cell->parameters[ID(B_SIGNED)] = false; + cell->setPort(ID::B, new_b); cell->check(); } else @@ -1325,9 +1394,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (b_signed) new_b.push_back(State::S0); - cell->type = "$and"; - cell->parameters["\\B_WIDTH"] = GetSize(new_b); - cell->setPort("\\B", new_b); + cell->type = ID($and); + cell->parameters[ID(B_WIDTH)] = GetSize(new_b); + cell->setPort(ID::B, new_b); cell->check(); } @@ -1339,7 +1408,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons // remove redundant pairs of bits in ==, ===, !=, and !== // replace cell with const driver if inputs can't be equal - if (do_fine && cell->type.in("$eq", "$ne", "$eqx", "$nex")) + if (do_fine && cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex))) { pool> redundant_cache; mfp contradiction_cache; @@ -1347,14 +1416,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons contradiction_cache.promote(State::S0); contradiction_cache.promote(State::S1); - int a_width = cell->getParam("\\A_WIDTH").as_int(); - int b_width = cell->getParam("\\B_WIDTH").as_int(); + int a_width = cell->getParam(ID(A_WIDTH)).as_int(); + int b_width = cell->getParam(ID(B_WIDTH)).as_int(); - bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); int width = is_signed ? std::min(a_width, b_width) : std::max(a_width, b_width); - SigSpec sig_a = cell->getPort("\\A"); - SigSpec sig_b = cell->getPort("\\B"); + SigSpec sig_a = cell->getPort(ID::A); + SigSpec sig_b = cell->getPort(ID::B); int redundant_bits = 0; @@ -1384,8 +1453,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (contradiction_cache.find(State::S0) == contradiction_cache.find(State::S1)) { - SigSpec y_sig = cell->getPort("\\Y"); - Const y_value(cell->type.in("$eq", "$eqx") ? 0 : 1, GetSize(y_sig)); + SigSpec y_sig = cell->getPort(ID::Y); + Const y_value(cell->type.in(ID($eq), ID($eqx)) ? 0 : 1, GetSize(y_sig)); log_debug("Replacing cell `%s' in module `%s' with constant driver %s.\n", log_id(cell), log_id(module), log_signal(y_value)); @@ -1402,10 +1471,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons log_debug("Removed %d redundant input bits from %s cell `%s' in module `%s'.\n", redundant_bits, log_id(cell->type), log_id(cell), log_id(module)); - cell->setPort("\\A", sig_a); - cell->setPort("\\B", sig_b); - cell->setParam("\\A_WIDTH", GetSize(sig_a)); - cell->setParam("\\B_WIDTH", GetSize(sig_b)); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); + cell->setParam(ID(A_WIDTH), GetSize(sig_a)); + cell->setParam(ID(B_WIDTH), GetSize(sig_b)); did_something = true; goto next_cell; @@ -1413,57 +1482,57 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } // simplify comparisons - if (do_fine && (cell->type == "$lt" || cell->type == "$ge" || cell->type == "$gt" || cell->type == "$le")) + if (do_fine && cell->type.in(ID($lt), ID($ge), ID($gt), ID($le))) { IdString cmp_type = cell->type; - SigSpec var_sig = cell->getPort("\\A"); - SigSpec const_sig = cell->getPort("\\B"); - int var_width = cell->parameters["\\A_WIDTH"].as_int(); - int const_width = cell->parameters["\\B_WIDTH"].as_int(); - bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + SigSpec var_sig = cell->getPort(ID::A); + SigSpec const_sig = cell->getPort(ID::B); + int var_width = cell->parameters[ID(A_WIDTH)].as_int(); + int const_width = cell->parameters[ID(B_WIDTH)].as_int(); + bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); if (!const_sig.is_fully_const()) { std::swap(var_sig, const_sig); std::swap(var_width, const_width); - if (cmp_type == "$gt") - cmp_type = "$lt"; - else if (cmp_type == "$lt") - cmp_type = "$gt"; - else if (cmp_type == "$ge") - cmp_type = "$le"; - else if (cmp_type == "$le") - cmp_type = "$ge"; + if (cmp_type == ID($gt)) + cmp_type = ID($lt); + else if (cmp_type == ID($lt)) + cmp_type = ID($gt); + else if (cmp_type == ID($ge)) + cmp_type = ID($le); + else if (cmp_type == ID($le)) + cmp_type = ID($ge); } if (const_sig.is_fully_def() && const_sig.is_fully_const()) { std::string condition, replacement; - SigSpec replace_sig(State::S0, GetSize(cell->getPort("\\Y"))); + SigSpec replace_sig(State::S0, GetSize(cell->getPort(ID::Y))); bool replace = false; bool remove = false; if (!is_signed) { /* unsigned */ - if (const_sig.is_fully_zero() && cmp_type == "$lt") { + if (const_sig.is_fully_zero() && cmp_type == ID($lt)) { condition = "unsigned X<0"; replacement = "constant 0"; replace_sig[0] = State::S0; replace = true; } - if (const_sig.is_fully_zero() && cmp_type == "$ge") { + if (const_sig.is_fully_zero() && cmp_type == ID($ge)) { condition = "unsigned X>=0"; replacement = "constant 1"; replace_sig[0] = State::S1; replace = true; } - if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$gt") { + if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == ID($gt)) { condition = "unsigned X>~0"; replacement = "constant 0"; replace_sig[0] = State::S0; replace = true; } - if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$le") { + if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == ID($le)) { condition = "unsigned X<=~0"; replacement = "constant 1"; replace_sig[0] = State::S1; @@ -1478,18 +1547,18 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons var_high_sig[i - const_bit_hot] = var_sig[i]; } - if (cmp_type == "$lt") + if (cmp_type == ID($lt)) { condition = stringf("unsigned X<%s", log_signal(const_sig)); replacement = stringf("!X[%d:%d]", var_width - 1, const_bit_hot); - module->addLogicNot(NEW_ID, var_high_sig, cell->getPort("\\Y")); + module->addLogicNot(NEW_ID, var_high_sig, cell->getPort(ID::Y)); remove = true; } - if (cmp_type == "$ge") + if (cmp_type == ID($ge)) { condition = stringf("unsigned X>=%s", log_signal(const_sig)); replacement = stringf("|X[%d:%d]", var_width - 1, const_bit_hot); - module->addReduceOr(NEW_ID, var_high_sig, cell->getPort("\\Y")); + module->addReduceOr(NEW_ID, var_high_sig, cell->getPort(ID::Y)); remove = true; } } @@ -1498,19 +1567,19 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if(const_bit_set >= var_width) { string cmp_name; - if (cmp_type == "$lt" || cmp_type == "$le") + if (cmp_type == ID($lt) || cmp_type == ID($le)) { - if (cmp_type == "$lt") cmp_name = "<"; - if (cmp_type == "$le") cmp_name = "<="; + if (cmp_type == ID($lt)) cmp_name = "<"; + if (cmp_type == ID($le)) cmp_name = "<="; condition = stringf("unsigned X[%d:0]%s%s", var_width - 1, cmp_name.c_str(), log_signal(const_sig)); replacement = "constant 1"; replace_sig[0] = State::S1; replace = true; } - if (cmp_type == "$gt" || cmp_type == "$ge") + if (cmp_type == ID($gt) || cmp_type == ID($ge)) { - if (cmp_type == "$gt") cmp_name = ">"; - if (cmp_type == "$ge") cmp_name = ">="; + if (cmp_type == ID($gt)) cmp_name = ">"; + if (cmp_type == ID($ge)) cmp_name = ">="; condition = stringf("unsigned X[%d:0]%s%s", var_width - 1, cmp_name.c_str(), log_signal(const_sig)); replacement = "constant 0"; replace_sig[0] = State::S0; @@ -1520,18 +1589,18 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } else { /* signed */ - if (const_sig.is_fully_zero() && cmp_type == "$lt") + if (const_sig.is_fully_zero() && cmp_type == ID($lt)) { condition = "signed X<0"; replacement = stringf("X[%d]", var_width - 1); replace_sig[0] = var_sig[var_width - 1]; replace = true; } - if (const_sig.is_fully_zero() && cmp_type == "$ge") + if (const_sig.is_fully_zero() && cmp_type == ID($ge)) { condition = "signed X>=0"; replacement = stringf("X[%d]", var_width - 1); - module->addNot(NEW_ID, var_sig[var_width - 1], cell->getPort("\\Y")); + module->addNot(NEW_ID, var_sig[var_width - 1], cell->getPort(ID::Y)); remove = true; } } @@ -1541,7 +1610,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons log_debug("Replacing %s cell `%s' (implementing %s) with %s.\n", log_id(cell->type), log_id(cell), condition.c_str(), replacement.c_str()); if (replace) - module->connect(cell->getPort("\\Y"), replace_sig); + module->connect(cell->getPort(ID::Y), replace_sig); module->remove(cell); did_something = true; goto next_cell; diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index 182f63d99..c4f278706 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -40,9 +40,9 @@ struct OptLutWorker bool evaluate_lut(RTLIL::Cell *lut, dict inputs) { - SigSpec lut_input = sigmap(lut->getPort("\\A")); - int lut_width = lut->getParam("\\WIDTH").as_int(); - Const lut_table = lut->getParam("\\LUT"); + SigSpec lut_input = sigmap(lut->getPort(ID::A)); + int lut_width = lut->getParam(ID(WIDTH)).as_int(); + Const lut_table = lut->getParam(ID(LUT)); int lut_index = 0; for (int i = 0; i < lut_width; i++) @@ -81,7 +81,7 @@ struct OptLutWorker } } - log("Number of LUTs: %8zu\n", luts.size()); + log("Number of LUTs: %8d\n", GetSize(luts)); for (int arity = 1; arity <= max_arity; arity++) { if (arity_counts[arity]) @@ -99,10 +99,16 @@ struct OptLutWorker log("Discovering LUTs.\n"); for (auto cell : module->selected_cells()) { - if (cell->type == "$lut") + if (cell->type == ID($lut)) { - int lut_width = cell->getParam("\\WIDTH").as_int(); - SigSpec lut_input = cell->getPort("\\A"); + if (cell->has_keep_attr()) + continue; + SigBit lut_output = cell->getPort(ID::Y); + if (lut_output.wire->get_bool_attribute(ID::keep)) + continue; + + int lut_width = cell->getParam(ID(WIDTH)).as_int(); + SigSpec lut_input = cell->getPort(ID::A); int lut_arity = 0; log_debug("Found $lut\\WIDTH=%d cell %s.%s.\n", lut_width, log_id(module), log_id(cell)); @@ -199,7 +205,7 @@ struct OptLutWorker } auto lut = worklist.pop(); - SigSpec lut_input = sigmap(lut->getPort("\\A")); + SigSpec lut_input = sigmap(lut->getPort(ID::A)); pool &lut_dlogic_inputs = luts_dlogic_inputs[lut]; vector lut_inputs; @@ -261,7 +267,7 @@ struct OptLutWorker log_debug(" Not eliminating cell (connected to dedicated logic).\n"); else { - SigSpec lut_output = lut->getPort("\\Y"); + SigSpec lut_output = lut->getPort(ID::Y); for (auto &port : index.query_ports(lut_output)) { if (port.cell != lut && luts.count(port.cell)) @@ -297,13 +303,13 @@ struct OptLutWorker } auto lutA = worklist.pop(); - SigSpec lutA_input = sigmap(lutA->getPort("\\A")); - SigSpec lutA_output = sigmap(lutA->getPort("\\Y")[0]); - int lutA_width = lutA->getParam("\\WIDTH").as_int(); + SigSpec lutA_input = sigmap(lutA->getPort(ID::A)); + SigSpec lutA_output = sigmap(lutA->getPort(ID::Y)[0]); + int lutA_width = lutA->getParam(ID(WIDTH)).as_int(); int lutA_arity = luts_arity[lutA]; pool &lutA_dlogic_inputs = luts_dlogic_inputs[lutA]; - auto lutA_output_ports = index.query_ports(lutA->getPort("\\Y")); + auto lutA_output_ports = index.query_ports(lutA->getPort(ID::Y)); if (lutA_output_ports.size() != 2) continue; @@ -315,15 +321,15 @@ struct OptLutWorker if (luts.count(port.cell)) { auto lutB = port.cell; - SigSpec lutB_input = sigmap(lutB->getPort("\\A")); - SigSpec lutB_output = sigmap(lutB->getPort("\\Y")[0]); - int lutB_width = lutB->getParam("\\WIDTH").as_int(); + SigSpec lutB_input = sigmap(lutB->getPort(ID::A)); + SigSpec lutB_output = sigmap(lutB->getPort(ID::Y)[0]); + int lutB_width = lutB->getParam(ID(WIDTH)).as_int(); int lutB_arity = luts_arity[lutB]; pool &lutB_dlogic_inputs = luts_dlogic_inputs[lutB]; log_debug("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB)); - if (index.query_is_output(lutA->getPort("\\Y"))) + if (index.query_is_output(lutA->getPort(ID::Y))) { log_debug(" Not combining LUTs (cascade connection feeds module output).\n"); continue; @@ -351,14 +357,14 @@ struct OptLutWorker int lutM_arity = lutA_arity + lutB_arity - 1 - common_inputs.size(); if (lutA_dlogic_inputs.size()) - log_debug(" Cell A is a %d-LUT with %zu dedicated connections. ", lutA_arity, lutA_dlogic_inputs.size()); + log_debug(" Cell A is a %d-LUT with %d dedicated connections. ", lutA_arity, GetSize(lutA_dlogic_inputs)); else log_debug(" Cell A is a %d-LUT. ", lutA_arity); if (lutB_dlogic_inputs.size()) - log_debug("Cell B is a %d-LUT with %zu dedicated connections.\n", lutB_arity, lutB_dlogic_inputs.size()); + log_debug("Cell B is a %d-LUT with %d dedicated connections.\n", lutB_arity, GetSize(lutB_dlogic_inputs)); else log_debug("Cell B is a %d-LUT.\n", lutB_arity); - log_debug(" Cells share %zu input(s) and can be merged into one %d-LUT.\n", common_inputs.size(), lutM_arity); + log_debug(" Cells share %d input(s) and can be merged into one %d-LUT.\n", GetSize(common_inputs), lutM_arity); const int COMBINE_A = 1, COMBINE_B = 2, COMBINE_EITHER = COMBINE_A | COMBINE_B; int combine_mask = 0; @@ -366,7 +372,7 @@ struct OptLutWorker log_debug(" Not combining LUTs into cell A (combined LUT wider than cell A).\n"); else if (lutB_dlogic_inputs.size() > 0) log_debug(" Not combining LUTs into cell A (cell B is connected to dedicated logic).\n"); - else if (lutB->get_bool_attribute("\\lut_keep")) + else if (lutB->get_bool_attribute(ID(lut_keep))) log_debug(" Not combining LUTs into cell A (cell B has attribute \\lut_keep).\n"); else combine_mask |= COMBINE_A; @@ -374,7 +380,7 @@ struct OptLutWorker log_debug(" Not combining LUTs into cell B (combined LUT wider than cell B).\n"); else if (lutA_dlogic_inputs.size() > 0) log_debug(" Not combining LUTs into cell B (cell A is connected to dedicated logic).\n"); - else if (lutA->get_bool_attribute("\\lut_keep")) + else if (lutA->get_bool_attribute(ID(lut_keep))) log_debug(" Not combining LUTs into cell B (cell A has attribute \\lut_keep).\n"); else combine_mask |= COMBINE_B; @@ -434,8 +440,8 @@ struct OptLutWorker lutR_unique.insert(bit); } - int lutM_width = lutM->getParam("\\WIDTH").as_int(); - SigSpec lutM_input = sigmap(lutM->getPort("\\A")); + int lutM_width = lutM->getParam(ID(WIDTH)).as_int(); + SigSpec lutM_input = sigmap(lutM->getPort(ID::A)); std::vector lutM_new_inputs; for (int i = 0; i < lutM_width; i++) { @@ -476,13 +482,13 @@ struct OptLutWorker lutM_new_table[eval] = (RTLIL::State) evaluate_lut(lutB, eval_inputs); } - log_debug(" Cell A truth table: %s.\n", lutA->getParam("\\LUT").as_string().c_str()); - log_debug(" Cell B truth table: %s.\n", lutB->getParam("\\LUT").as_string().c_str()); + log_debug(" Cell A truth table: %s.\n", lutA->getParam(ID(LUT)).as_string().c_str()); + log_debug(" Cell B truth table: %s.\n", lutB->getParam(ID(LUT)).as_string().c_str()); log_debug(" Merged truth table: %s.\n", lutM_new_table.as_string().c_str()); - lutM->setParam("\\LUT", lutM_new_table); - lutM->setPort("\\A", lutM_new_inputs); - lutM->setPort("\\Y", lutB_output); + lutM->setParam(ID(LUT), lutM_new_table); + lutM->setPort(ID::A, lutM_new_inputs); + lutM->setPort(ID::Y, lutB_output); luts_arity[lutM] = lutM_arity; luts.erase(lutR); diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index 7567d4657..aaea6159e 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -47,8 +47,8 @@ struct OptMergeWorker static void sort_pmux_conn(dict &conn) { - SigSpec sig_s = conn.at("\\S"); - SigSpec sig_b = conn.at("\\B"); + SigSpec sig_s = conn.at(ID(S)); + SigSpec sig_b = conn.at(ID::B); int s_width = GetSize(sig_s); int width = GetSize(sig_b) / s_width; @@ -59,12 +59,12 @@ struct OptMergeWorker std::sort(sb_pairs.begin(), sb_pairs.end()); - conn["\\S"] = SigSpec(); - conn["\\B"] = SigSpec(); + conn[ID(S)] = SigSpec(); + conn[ID::B] = SigSpec(); for (auto &it : sb_pairs) { - conn["\\S"].append(it.first); - conn["\\B"].append(it.second); + conn[ID(S)].append(it.first); + conn[ID::B].append(it.second); } } @@ -94,32 +94,32 @@ struct OptMergeWorker const dict *conn = &cell->connections(); dict alt_conn; - if (cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || cell->type == "$add" || cell->type == "$mul" || - cell->type == "$logic_and" || cell->type == "$logic_or" || cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") { + if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($mul), + ID($logic_and), ID($logic_or), ID($_AND_), ID($_OR_), ID($_XOR_))) { alt_conn = *conn; - if (assign_map(alt_conn.at("\\A")) < assign_map(alt_conn.at("\\B"))) { - alt_conn["\\A"] = conn->at("\\B"); - alt_conn["\\B"] = conn->at("\\A"); + if (assign_map(alt_conn.at(ID::A)) < assign_map(alt_conn.at(ID::B))) { + alt_conn[ID::A] = conn->at(ID::B); + alt_conn[ID::B] = conn->at(ID::A); } conn = &alt_conn; } else - if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor") { + if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { alt_conn = *conn; - assign_map.apply(alt_conn.at("\\A")); - alt_conn.at("\\A").sort(); + assign_map.apply(alt_conn.at(ID::A)); + alt_conn.at(ID::A).sort(); conn = &alt_conn; } else - if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_bool") { + if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool))) { alt_conn = *conn; - assign_map.apply(alt_conn.at("\\A")); - alt_conn.at("\\A").sort_and_unify(); + assign_map.apply(alt_conn.at(ID::A)); + alt_conn.at(ID::A).sort_and_unify(); conn = &alt_conn; } else - if (cell->type == "$pmux") { + if (cell->type == ID($pmux)) { alt_conn = *conn; - assign_map.apply(alt_conn.at("\\A")); - assign_map.apply(alt_conn.at("\\B")); - assign_map.apply(alt_conn.at("\\S")); + assign_map.apply(alt_conn.at(ID::A)); + assign_map.apply(alt_conn.at(ID::B)); + assign_map.apply(alt_conn.at(ID(S))); sort_pmux_conn(alt_conn); conn = &alt_conn; } @@ -189,28 +189,28 @@ struct OptMergeWorker assign_map.apply(it.second); } - if (cell1->type == "$and" || cell1->type == "$or" || cell1->type == "$xor" || cell1->type == "$xnor" || cell1->type == "$add" || cell1->type == "$mul" || - cell1->type == "$logic_and" || cell1->type == "$logic_or" || cell1->type == "$_AND_" || cell1->type == "$_OR_" || cell1->type == "$_XOR_") { - if (conn1.at("\\A") < conn1.at("\\B")) { - RTLIL::SigSpec tmp = conn1["\\A"]; - conn1["\\A"] = conn1["\\B"]; - conn1["\\B"] = tmp; + if (cell1->type == ID($and) || cell1->type == ID($or) || cell1->type == ID($xor) || cell1->type == ID($xnor) || cell1->type == ID($add) || cell1->type == ID($mul) || + cell1->type == ID($logic_and) || cell1->type == ID($logic_or) || cell1->type == ID($_AND_) || cell1->type == ID($_OR_) || cell1->type == ID($_XOR_)) { + if (conn1.at(ID::A) < conn1.at(ID::B)) { + RTLIL::SigSpec tmp = conn1[ID::A]; + conn1[ID::A] = conn1[ID::B]; + conn1[ID::B] = tmp; } - if (conn2.at("\\A") < conn2.at("\\B")) { - RTLIL::SigSpec tmp = conn2["\\A"]; - conn2["\\A"] = conn2["\\B"]; - conn2["\\B"] = tmp; + if (conn2.at(ID::A) < conn2.at(ID::B)) { + RTLIL::SigSpec tmp = conn2[ID::A]; + conn2[ID::A] = conn2[ID::B]; + conn2[ID::B] = tmp; } } else - if (cell1->type == "$reduce_xor" || cell1->type == "$reduce_xnor") { - conn1["\\A"].sort(); - conn2["\\A"].sort(); + if (cell1->type == ID($reduce_xor) || cell1->type == ID($reduce_xnor)) { + conn1[ID::A].sort(); + conn2[ID::A].sort(); } else - if (cell1->type == "$reduce_and" || cell1->type == "$reduce_or" || cell1->type == "$reduce_bool") { - conn1["\\A"].sort_and_unify(); - conn2["\\A"].sort_and_unify(); + if (cell1->type == ID($reduce_and) || cell1->type == ID($reduce_or) || cell1->type == ID($reduce_bool)) { + conn1[ID::A].sort_and_unify(); + conn2[ID::A].sort_and_unify(); } else - if (cell1->type == "$pmux") { + if (cell1->type == ID($pmux)) { sort_pmux_conn(conn1); sort_pmux_conn(conn2); } @@ -222,9 +222,9 @@ struct OptMergeWorker return true; } - if (cell1->type.substr(0, 1) == "$" && conn1.count("\\Q") != 0) { - std::vector q1 = dff_init_map(cell1->getPort("\\Q")).to_sigbit_vector(); - std::vector q2 = dff_init_map(cell2->getPort("\\Q")).to_sigbit_vector(); + if (cell1->type.begins_with("$") && conn1.count(ID(Q)) != 0) { + std::vector q1 = dff_init_map(cell1->getPort(ID(Q))).to_sigbit_vector(); + std::vector q2 = dff_init_map(cell2->getPort(ID(Q))).to_sigbit_vector(); for (size_t i = 0; i < q1.size(); i++) if ((q1.at(i).wire == NULL || q2.at(i).wire == NULL) && q1.at(i) != q2.at(i)) { lt = q1.at(i) < q2.at(i); @@ -271,24 +271,24 @@ struct OptMergeWorker ct.setup_stdcells_mem(); if (mode_nomux) { - ct.cell_types.erase("$mux"); - ct.cell_types.erase("$pmux"); + ct.cell_types.erase(ID($mux)); + ct.cell_types.erase(ID($pmux)); } - ct.cell_types.erase("$tribuf"); - ct.cell_types.erase("$_TBUF_"); - ct.cell_types.erase("$anyseq"); - ct.cell_types.erase("$anyconst"); - ct.cell_types.erase("$allseq"); - ct.cell_types.erase("$allconst"); + ct.cell_types.erase(ID($tribuf)); + ct.cell_types.erase(ID($_TBUF_)); + ct.cell_types.erase(ID($anyseq)); + ct.cell_types.erase(ID($anyconst)); + ct.cell_types.erase(ID($allseq)); + ct.cell_types.erase(ID($allconst)); log("Finding identical cells in module `%s'.\n", module->name.c_str()); assign_map.set(module); dff_init_map.set(module); for (auto &it : module->wires_) - if (it.second->attributes.count("\\init") != 0) { - Const initval = it.second->attributes.at("\\init"); + if (it.second->attributes.count(ID(init)) != 0) { + Const initval = it.second->attributes.at(ID(init)); for (int i = 0; i < GetSize(initval) && i < GetSize(it.second); i++) if (initval[i] == State::S0 || initval[i] == State::S1) dff_init_map.add(SigBit(it.second, i), initval[i]); diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 6511e091b..3c486bbcc 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -84,12 +84,12 @@ struct OptMuxtreeWorker // .const_deactivated for (auto cell : module->cells()) { - if (cell->type == "$mux" || cell->type == "$pmux") + if (cell->type.in(ID($mux), ID($pmux))) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_s = cell->getPort("\\S"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_s = cell->getPort(ID(S)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); muxinfo_t muxinfo; muxinfo.cell = cell; @@ -137,7 +137,7 @@ struct OptMuxtreeWorker } } for (auto wire : module->wires()) { - if (wire->port_output || wire->get_bool_attribute("\\keep")) + if (wire->port_output || wire->get_bool_attribute(ID::keep)) for (int idx : sig2bits(RTLIL::SigSpec(wire))) bit2info[idx].seen_non_mux = true; } @@ -227,10 +227,10 @@ struct OptMuxtreeWorker continue; } - RTLIL::SigSpec sig_a = mi.cell->getPort("\\A"); - RTLIL::SigSpec sig_b = mi.cell->getPort("\\B"); - RTLIL::SigSpec sig_s = mi.cell->getPort("\\S"); - RTLIL::SigSpec sig_y = mi.cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = mi.cell->getPort(ID::A); + RTLIL::SigSpec sig_b = mi.cell->getPort(ID::B); + RTLIL::SigSpec sig_s = mi.cell->getPort(ID(S)); + RTLIL::SigSpec sig_y = mi.cell->getPort(ID::Y); RTLIL::SigSpec sig_ports = sig_b; sig_ports.append(sig_a); @@ -255,14 +255,14 @@ struct OptMuxtreeWorker } } - mi.cell->setPort("\\A", new_sig_a); - mi.cell->setPort("\\B", new_sig_b); - mi.cell->setPort("\\S", new_sig_s); + mi.cell->setPort(ID::A, new_sig_a); + mi.cell->setPort(ID::B, new_sig_b); + mi.cell->setPort(ID(S), new_sig_s); if (GetSize(new_sig_s) == 1) { - mi.cell->type = "$mux"; - mi.cell->parameters.erase("\\S_WIDTH"); + mi.cell->type = ID($mux); + mi.cell->parameters.erase(ID(S_WIDTH)); } else { - mi.cell->parameters["\\S_WIDTH"] = RTLIL::Const(GetSize(new_sig_s)); + mi.cell->parameters[ID(S_WIDTH)] = RTLIL::Const(GetSize(new_sig_s)); } } } @@ -364,9 +364,9 @@ struct OptMuxtreeWorker int width = 0; idict ctrl_bits; - if (portname == "\\B") - width = GetSize(muxinfo.cell->getPort("\\A")); - for (int bit : sig2bits(muxinfo.cell->getPort("\\S"), false)) + if (portname == ID::B) + width = GetSize(muxinfo.cell->getPort(ID::A)); + for (int bit : sig2bits(muxinfo.cell->getPort(ID(S)), false)) ctrl_bits(bit); int port_idx = 0, port_off = 0; @@ -414,8 +414,8 @@ struct OptMuxtreeWorker // set input ports to constants if we find known active or inactive signals if (do_replace_known) { - replace_known(knowledge, muxinfo, "\\A"); - replace_known(knowledge, muxinfo, "\\B"); + replace_known(knowledge, muxinfo, ID::A); + replace_known(knowledge, muxinfo, ID::B); } // if there is a constant activated port we just use it diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index d99f1ca6a..6a8d8cabd 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -43,13 +43,13 @@ struct OptReduceWorker return; cells.erase(cell); - RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); pool new_sig_a_bits; for (auto &bit : sig_a.to_sigbit_set()) { if (bit == RTLIL::State::S0) { - if (cell->type == "$reduce_and") { + if (cell->type == ID($reduce_and)) { new_sig_a_bits.clear(); new_sig_a_bits.insert(RTLIL::State::S0); break; @@ -57,7 +57,7 @@ struct OptReduceWorker continue; } if (bit == RTLIL::State::S1) { - if (cell->type == "$reduce_or") { + if (cell->type == ID($reduce_or)) { new_sig_a_bits.clear(); new_sig_a_bits.insert(RTLIL::State::S1); break; @@ -73,8 +73,8 @@ struct OptReduceWorker for (auto child_cell : drivers.find(bit)) { if (child_cell->type == cell->type) { opt_reduce(cells, drivers, child_cell); - if (child_cell->getPort("\\Y")[0] == bit) { - pool child_sig_a_bits = assign_map(child_cell->getPort("\\A")).to_sigbit_pool(); + if (child_cell->getPort(ID::Y)[0] == bit) { + pool child_sig_a_bits = assign_map(child_cell->getPort(ID::A)).to_sigbit_pool(); new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end()); } else new_sig_a_bits.insert(RTLIL::State::S0); @@ -87,22 +87,22 @@ struct OptReduceWorker RTLIL::SigSpec new_sig_a(new_sig_a_bits); - if (new_sig_a != sig_a || sig_a.size() != cell->getPort("\\A").size()) { + if (new_sig_a != sig_a || sig_a.size() != cell->getPort(ID::A).size()) { log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); did_something = true; total_count++; } - cell->setPort("\\A", new_sig_a); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(new_sig_a.size()); + cell->setPort(ID::A, new_sig_a); + cell->parameters[ID(A_WIDTH)] = RTLIL::Const(new_sig_a.size()); return; } void opt_mux(RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); - RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); - RTLIL::SigSpec sig_s = assign_map(cell->getPort("\\S")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); + RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID(S))); RTLIL::SigSpec new_sig_b, new_sig_s; pool handled_sig; @@ -123,15 +123,15 @@ struct OptReduceWorker if (this_s.size() > 1) { - RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, "$reduce_or"); - reduce_or_cell->setPort("\\A", this_s); - reduce_or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - reduce_or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(this_s.size()); - reduce_or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); + RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, ID($reduce_or)); + reduce_or_cell->setPort(ID::A, this_s); + reduce_or_cell->parameters[ID(A_SIGNED)] = RTLIL::Const(0); + reduce_or_cell->parameters[ID(A_WIDTH)] = RTLIL::Const(this_s.size()); + reduce_or_cell->parameters[ID(Y_WIDTH)] = RTLIL::Const(1); RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID); this_s = RTLIL::SigSpec(reduce_or_wire); - reduce_or_cell->setPort("\\Y", this_s); + reduce_or_cell->setPort(ID::Y, this_s); } new_sig_b.append(this_b); @@ -147,28 +147,28 @@ struct OptReduceWorker if (new_sig_s.size() == 0) { - module->connect(RTLIL::SigSig(cell->getPort("\\Y"), cell->getPort("\\A"))); - assign_map.add(cell->getPort("\\Y"), cell->getPort("\\A")); + module->connect(RTLIL::SigSig(cell->getPort(ID::Y), cell->getPort(ID::A))); + assign_map.add(cell->getPort(ID::Y), cell->getPort(ID::A)); module->remove(cell); } else { - cell->setPort("\\B", new_sig_b); - cell->setPort("\\S", new_sig_s); + cell->setPort(ID::B, new_sig_b); + cell->setPort(ID(S), new_sig_s); if (new_sig_s.size() > 1) { - cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.size()); + cell->parameters[ID(S_WIDTH)] = RTLIL::Const(new_sig_s.size()); } else { - cell->type = "$mux"; - cell->parameters.erase("\\S_WIDTH"); + cell->type = ID($mux); + cell->parameters.erase(ID(S_WIDTH)); } } } void opt_mux_bits(RTLIL::Cell *cell) { - std::vector sig_a = assign_map(cell->getPort("\\A")).to_sigbit_vector(); - std::vector sig_b = assign_map(cell->getPort("\\B")).to_sigbit_vector(); - std::vector sig_y = assign_map(cell->getPort("\\Y")).to_sigbit_vector(); + std::vector sig_a = assign_map(cell->getPort(ID::A)).to_sigbit_vector(); + std::vector sig_b = assign_map(cell->getPort(ID::B)).to_sigbit_vector(); + std::vector sig_y = assign_map(cell->getPort(ID::Y)).to_sigbit_vector(); std::vector new_sig_y; RTLIL::SigSig old_sig_conn; @@ -209,29 +209,29 @@ struct OptReduceWorker if (new_sig_y.size() != sig_y.size()) { log(" Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str()); - log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort("\\A")), - log_signal(cell->getPort("\\B")), log_signal(cell->getPort("\\Y"))); + log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID::A)), + log_signal(cell->getPort(ID::B)), log_signal(cell->getPort(ID::Y))); - cell->setPort("\\A", RTLIL::SigSpec()); + cell->setPort(ID::A, RTLIL::SigSpec()); for (auto &in_tuple : consolidated_in_tuples) { - RTLIL::SigSpec new_a = cell->getPort("\\A"); + RTLIL::SigSpec new_a = cell->getPort(ID::A); new_a.append(in_tuple.at(0)); - cell->setPort("\\A", new_a); + cell->setPort(ID::A, new_a); } - cell->setPort("\\B", RTLIL::SigSpec()); - for (int i = 1; i <= cell->getPort("\\S").size(); i++) + cell->setPort(ID::B, RTLIL::SigSpec()); + for (int i = 1; i <= cell->getPort(ID(S)).size(); i++) for (auto &in_tuple : consolidated_in_tuples) { - RTLIL::SigSpec new_b = cell->getPort("\\B"); + RTLIL::SigSpec new_b = cell->getPort(ID::B); new_b.append(in_tuple.at(i)); - cell->setPort("\\B", new_b); + cell->setPort(ID::B, new_b); } - cell->parameters["\\WIDTH"] = RTLIL::Const(new_sig_y.size()); - cell->setPort("\\Y", new_sig_y); + cell->parameters[ID(WIDTH)] = RTLIL::Const(new_sig_y.size()); + cell->setPort(ID::Y, new_sig_y); - log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort("\\A")), - log_signal(cell->getPort("\\B")), log_signal(cell->getPort("\\Y"))); + log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID::A)), + log_signal(cell->getPort(ID::B)), log_signal(cell->getPort(ID::Y))); log(" New connections: %s = %s\n", log_signal(old_sig_conn.first), log_signal(old_sig_conn.second)); module->connect(old_sig_conn); @@ -253,15 +253,15 @@ struct OptReduceWorker SigPool mem_wren_sigs; for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$mem") - mem_wren_sigs.add(assign_map(cell->getPort("\\WR_EN"))); - if (cell->type == "$memwr") - mem_wren_sigs.add(assign_map(cell->getPort("\\EN"))); + if (cell->type == ID($mem)) + mem_wren_sigs.add(assign_map(cell->getPort(ID(WR_EN)))); + if (cell->type == ID($memwr)) + mem_wren_sigs.add(assign_map(cell->getPort(ID(EN)))); } for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$dff" && mem_wren_sigs.check_any(assign_map(cell->getPort("\\Q")))) - mem_wren_sigs.add(assign_map(cell->getPort("\\D"))); + if (cell->type == ID($dff) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Q))))) + mem_wren_sigs.add(assign_map(cell->getPort(ID(D)))); } bool keep_expanding_mem_wren_sigs = true; @@ -269,12 +269,12 @@ struct OptReduceWorker keep_expanding_mem_wren_sigs = false; for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$mux" && mem_wren_sigs.check_any(assign_map(cell->getPort("\\Y")))) { - if (!mem_wren_sigs.check_all(assign_map(cell->getPort("\\A"))) || - !mem_wren_sigs.check_all(assign_map(cell->getPort("\\B")))) + if (cell->type == ID($mux) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID::Y)))) { + if (!mem_wren_sigs.check_all(assign_map(cell->getPort(ID::A))) || + !mem_wren_sigs.check_all(assign_map(cell->getPort(ID::B)))) keep_expanding_mem_wren_sigs = true; - mem_wren_sigs.add(assign_map(cell->getPort("\\A"))); - mem_wren_sigs.add(assign_map(cell->getPort("\\B"))); + mem_wren_sigs.add(assign_map(cell->getPort(ID::A))); + mem_wren_sigs.add(assign_map(cell->getPort(ID::B))); } } } @@ -286,7 +286,7 @@ struct OptReduceWorker // merge trees of reduce_* cells to one single cell and unify input vectors // (only handle reduce_and and reduce_or for various reasons) - const char *type_list[] = { "$reduce_or", "$reduce_and" }; + const IdString type_list[] = { ID($reduce_or), ID($reduce_and) }; for (auto type : type_list) { SigSet drivers; @@ -296,7 +296,7 @@ struct OptReduceWorker RTLIL::Cell *cell = cell_it.second; if (cell->type != type || !design->selected(module, cell)) continue; - drivers.insert(assign_map(cell->getPort("\\Y")), cell); + drivers.insert(assign_map(cell->getPort(ID::Y)), cell); cells.insert(cell); } @@ -311,14 +311,14 @@ struct OptReduceWorker std::vector cells; for (auto &it : module->cells_) - if ((it.second->type == "$mux" || it.second->type == "$pmux") && design->selected(module, it.second)) + if ((it.second->type == ID($mux) || it.second->type == ID($pmux)) && design->selected(module, it.second)) cells.push_back(it.second); for (auto cell : cells) { // this optimization is to aggressive for most coarse-grain applications. // but we always want it for multiplexers driving write enable ports. - if (do_fine || mem_wren_sigs.check_any(assign_map(cell->getPort("\\Y")))) + if (do_fine || mem_wren_sigs.check_any(assign_map(cell->getPort(ID::Y)))) opt_mux_bits(cell); opt_mux(cell); diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index be6ac2d30..0bf74098a 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -41,7 +41,7 @@ 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("\\init")[wbit.offset] = State::Sx; + wbit.wire->attributes.at(ID(init))[wbit.offset] = State::Sx; } bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) @@ -49,39 +49,39 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) SigSpec sig_set, sig_clr; State pol_set, pol_clr; - if (cell->hasPort("\\S")) - sig_set = cell->getPort("\\S"); + if (cell->hasPort(ID(S))) + sig_set = cell->getPort(ID(S)); - if (cell->hasPort("\\R")) - sig_clr = cell->getPort("\\R"); + if (cell->hasPort(ID(R))) + sig_clr = cell->getPort(ID(R)); - if (cell->hasPort("\\SET")) - sig_set = cell->getPort("\\SET"); + if (cell->hasPort(ID(SET))) + sig_set = cell->getPort(ID(SET)); - if (cell->hasPort("\\CLR")) - sig_clr = cell->getPort("\\CLR"); + if (cell->hasPort(ID(CLR))) + sig_clr = cell->getPort(ID(CLR)); log_assert(GetSize(sig_set) == GetSize(sig_clr)); - if (cell->type.substr(0,8) == "$_DFFSR_") { + 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.substr(0,11) == "$_DLATCHSR_") { + 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 == "$dffsr" || cell->type == "$dlatchsr") { - pol_set = cell->parameters["\\SET_POLARITY"].as_bool() ? State::S1 : State::S0; - pol_clr = cell->parameters["\\CLR_POLARITY"].as_bool() ? State::S1 : State::S0; + 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("\\D"); - SigSpec sig_q = cell->getPort("\\Q"); + SigSpec sig_d = cell->getPort(ID(D)); + SigSpec sig_q = cell->getPort(ID(Q)); bool did_something = false; bool proper_sr = false; @@ -137,20 +137,20 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) return true; } - if (cell->type == "$dffsr" || cell->type == "$dlatchsr") + if (cell->type.in(ID($dffsr), ID($dlatchsr))) { - cell->setParam("\\WIDTH", GetSize(sig_d)); - cell->setPort("\\SET", sig_set); - cell->setPort("\\CLR", sig_clr); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + 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("\\S", sig_set); - cell->setPort("\\R", sig_clr); - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + 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) @@ -159,36 +159,36 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) if (used_pol_set && used_pol_clr && pol_set != pol_clr) return did_something; - if (cell->type == "$dlatchsr") + if (cell->type == ID($dlatchsr)) return did_something; State unified_pol = used_pol_set ? pol_set : pol_clr; - if (cell->type == "$dffsr") + 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 = "$adff"; - cell->setParam("\\ARST_POLARITY", unified_pol); - cell->setParam("\\ARST_VALUE", reset_val); - cell->setPort("\\ARST", sig_reset); + 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("\\SET_POLARITY"); - cell->unsetParam("\\CLR_POLARITY"); - cell->unsetPort("\\SET"); - cell->unsetPort("\\CLR"); + 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 = "$dff"; - cell->unsetParam("\\SET_POLARITY"); - cell->unsetParam("\\CLR_POLARITY"); - cell->unsetPort("\\SET"); - cell->unsetPort("\\CLR"); + cell->type = ID($dff); + cell->unsetParam(ID(SET_POLARITY)); + cell->unsetParam(ID(CLR_POLARITY)); + cell->unsetPort(ID(SET)); + cell->unsetPort(ID(CLR)); } return true; @@ -198,9 +198,9 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) { IdString new_type; - if (cell->type.substr(0,8) == "$_DFFSR_") + if (cell->type.begins_with("$_DFFSR_")) new_type = stringf("$_DFF_%c_", cell->type[8]); - else if (cell->type.substr(0,11) == "$_DLATCHSR_") + else if (cell->type.begins_with("$_DLATCHSR_")) new_type = stringf("$_DLATCH_%c_", cell->type[11]); else log_abort(); @@ -208,8 +208,8 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell) 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("\\S"); - cell->unsetPort("\\R"); + cell->unsetPort(ID(S)); + cell->unsetPort(ID(R)); return true; } @@ -222,18 +222,18 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch) SigSpec sig_e; State on_state, off_state; - if (dlatch->type == "$dlatch") { - sig_e = assign_map(dlatch->getPort("\\EN")); - on_state = dlatch->getParam("\\EN_POLARITY").as_bool() ? State::S1 : State::S0; - off_state = dlatch->getParam("\\EN_POLARITY").as_bool() ? State::S0 : State::S1; + 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 == "$_DLATCH_P_") { - sig_e = assign_map(dlatch->getPort("\\E")); + 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 == "$_DLATCH_N_") { - sig_e = assign_map(dlatch->getPort("\\E")); + if (dlatch->type == ID($_DLATCH_N_)) { + sig_e = assign_map(dlatch->getPort(ID(E))); on_state = State::S0; off_state = State::S1; } else @@ -242,15 +242,15 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch) if (sig_e == off_state) { RTLIL::Const val_init; - for (auto bit : dff_init_map(dlatch->getPort("\\Q"))) + 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("\\Q"), val_init); + mod->connect(dlatch->getPort(ID(Q)), val_init); goto delete_dlatch; } if (sig_e == on_state) { - mod->connect(dlatch->getPort("\\Q"), dlatch->getPort("\\D")); + mod->connect(dlatch->getPort(ID(Q)), dlatch->getPort(ID(D))); goto delete_dlatch; } @@ -258,7 +258,7 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch) 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("\\Q")); + remove_init_attr(dlatch->getPort(ID(Q))); mod->remove(dlatch); return true; } @@ -268,64 +268,64 @@ 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 == "$_FF_") { - sig_d = dff->getPort("\\D"); - sig_q = dff->getPort("\\Q"); + if (dff->type == ID($_FF_)) { + sig_d = dff->getPort(ID(D)); + sig_q = dff->getPort(ID(Q)); } - else if (dff->type == "$_DFF_N_" || dff->type == "$_DFF_P_") { - sig_d = dff->getPort("\\D"); - sig_q = dff->getPort("\\Q"); - sig_c = dff->getPort("\\C"); - val_cp = RTLIL::Const(dff->type == "$_DFF_P_", 1); + 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.substr(0,6) == "$_DFF_" && dff->type.substr(9) == "_" && + 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("\\D"); - sig_q = dff->getPort("\\Q"); - sig_c = dff->getPort("\\C"); - sig_r = dff->getPort("\\R"); + 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.substr(0,7) == "$_DFFE_" && dff->type.substr(9) == "_" && + 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("\\D"); - sig_q = dff->getPort("\\Q"); - sig_c = dff->getPort("\\C"); - sig_e = dff->getPort("\\E"); + 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 == "$ff") { - sig_d = dff->getPort("\\D"); - sig_q = dff->getPort("\\Q"); + else if (dff->type == ID($ff)) { + sig_d = dff->getPort(ID(D)); + sig_q = dff->getPort(ID(Q)); } - else if (dff->type == "$dff") { - sig_d = dff->getPort("\\D"); - sig_q = dff->getPort("\\Q"); - sig_c = dff->getPort("\\CLK"); - val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); + 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 == "$dffe") { - sig_e = dff->getPort("\\EN"); - sig_d = dff->getPort("\\D"); - sig_q = dff->getPort("\\Q"); - sig_c = dff->getPort("\\CLK"); - val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); - val_ep = RTLIL::Const(dff->parameters["\\EN_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 == "$adff") { - sig_d = dff->getPort("\\D"); - sig_q = dff->getPort("\\Q"); - sig_c = dff->getPort("\\CLK"); - sig_r = dff->getPort("\\ARST"); - val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); - val_rp = RTLIL::Const(dff->parameters["\\ARST_POLARITY"].as_bool(), 1); - val_rv = dff->parameters["\\ARST_VALUE"]; + 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(); @@ -343,12 +343,12 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) val_init.bits.push_back(bit.wire == NULL ? bit.data : RTLIL::State::Sx); } - if (dff->type.in("$ff", "$dff") && mux_drivers.has(sig_d)) { + if (dff->type.in(ID($ff), ID($dff)) && mux_drivers.has(sig_d)) { std::set muxes; mux_drivers.find(sig_d, muxes); for (auto mux : muxes) { - RTLIL::SigSpec sig_a = assign_map(mux->getPort("\\A")); - RTLIL::SigSpec sig_b = assign_map(mux->getPort("\\B")); + 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; @@ -420,17 +420,17 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *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 == "$adff") { - dff->type = "$dff"; - dff->unsetPort("\\ARST"); - dff->unsetParam("\\ARST_POLARITY"); - dff->unsetParam("\\ARST_VALUE"); + 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.substr(0,6) == "$_DFF_"); + log_assert(dff->type.begins_with("$_DFF_")); dff->type = stringf("$_DFF_%c_", + dff->type[6]); - dff->unsetPort("\\R"); + dff->unsetPort(ID(R)); } // If enable signal is present, and is fully constant @@ -445,16 +445,16 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *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 == "$dffe") { - dff->type = "$dff"; - dff->unsetPort("\\EN"); - dff->unsetParam("\\EN_POLARITY"); + if (dff->type == ID($dffe)) { + dff->type = ID($dff); + dff->unsetPort(ID(EN)); + dff->unsetParam(ID(EN_POLARITY)); return true; } - log_assert(dff->type.substr(0,7) == "$_DFFE_"); + log_assert(dff->type.begins_with("$_DFFE_")); dff->type = stringf("$_DFF_%c_", + dff->type[7]); - dff->unsetPort("\\E"); + dff->unsetPort(ID(E)); } if (sat && has_init && (!sig_r.size() || val_init == val_rv)) @@ -509,9 +509,9 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) 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("\\D"); + SigSpec tmp = dff->getPort(ID(D)); tmp[position] = sigbit_init_val; - dff->setPort("\\D", tmp); + dff->setPort(ID(D), tmp); removed_sigbits = true; } @@ -528,7 +528,7 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) 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("\\Q")); + remove_init_attr(dff->getPort(ID(Q))); mod->remove(dff); for (auto &entry : bit2driver) @@ -588,8 +588,8 @@ struct OptRmdffPass : public Pass { for (auto wire : module->wires()) { - if (wire->attributes.count("\\init") != 0) { - Const initval = wire->attributes.at("\\init"); + 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]); @@ -624,29 +624,29 @@ struct OptRmdffPass : public Pass { } } - if (cell->type == "$mux" || cell->type == "$pmux") { - if (cell->getPort("\\A").size() == cell->getPort("\\B").size()) - mux_drivers.insert(assign_map(cell->getPort("\\Y")), cell); + 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("$_DFFSR_NNN_", "$_DFFSR_NNP_", "$_DFFSR_NPN_", "$_DFFSR_NPP_", - "$_DFFSR_PNN_", "$_DFFSR_PNP_", "$_DFFSR_PPN_", "$_DFFSR_PPP_", "$dffsr", - "$_DLATCHSR_NNN_", "$_DLATCHSR_NNP_", "$_DLATCHSR_NPN_", "$_DLATCHSR_NPP_", - "$_DLATCHSR_PNN_", "$_DLATCHSR_PNP_", "$_DLATCHSR_PPN_", "$_DLATCHSR_PPP_", "$dlatchsr")) + 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("$_FF_", "$_DFF_N_", "$_DFF_P_", - "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", - "$_DFF_PN0_", "$_DFF_PN1_", "$_DFF_PP0_", "$_DFF_PP1_", - "$_DFFE_NN_", "$_DFFE_NP_", "$_DFFE_PN_", "$_DFFE_PP_", - "$ff", "$dff", "$dffe", "$adff")) + 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("$dlatch", "$_DLATCH_P_", "$_DLATCH_N_")) + if (cell->type.in(ID($dlatch), ID($_DLATCH_P_), ID($_DLATCH_N_))) dlatch_list.push_back(cell->name); } diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc new file mode 100644 index 000000000..c53fb3113 --- /dev/null +++ b/passes/opt/opt_share.cc @@ -0,0 +1,649 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * 2019 Bogdan Vukobratovic + * + * 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/sigtools.h" +#include + +#include +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +SigMap assign_map; + +struct OpMuxConn { + RTLIL::SigSpec sig; + RTLIL::Cell *mux; + RTLIL::Cell *op; + int mux_port_id; + int mux_port_offset; + int op_outsig_offset; + + bool operator<(const OpMuxConn &other) const + { + if (mux != other.mux) + return mux < other.mux; + + if (mux_port_id != other.mux_port_id) + return mux_port_id < other.mux_port_id; + + return mux_port_offset < other.mux_port_offset; + } +}; + +// Helper class to track additiona information about a SigSpec, like whether it is signed and the semantics of the port it is connected to +struct ExtSigSpec { + RTLIL::SigSpec sig; + RTLIL::SigSpec sign; + bool is_signed; + RTLIL::IdString semantics; + + ExtSigSpec() {} + + ExtSigSpec(RTLIL::SigSpec s, RTLIL::SigSpec sign = RTLIL::Const(0, 1), bool is_signed = false, RTLIL::IdString semantics = RTLIL::IdString()) : sig(s), sign(sign), is_signed(is_signed), semantics(semantics) {} + + bool empty() const { return sig.empty(); } + + bool operator<(const ExtSigSpec &other) const + { + if (sig != other.sig) + return sig < other.sig; + + if (sign != other.sign) + return sign < other.sign; + + if (is_signed != other.is_signed) + return is_signed < other.is_signed; + + return semantics < other.semantics; + } + + bool operator==(const RTLIL::SigSpec &other) const { return (sign != RTLIL::Const(0, 1)) ? false : sig == other; } + bool operator==(const ExtSigSpec &other) const { return is_signed == other.is_signed && sign == other.sign && sig == other.sig && semantics == other.semantics; } +}; + +#define BITWISE_OPS ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($and), ID($or), ID($xor), ID($xnor) + +#define REDUCTION_OPS ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($reduce_nand) + +#define LOGICAL_OPS ID($logic_and), ID($logic_or) + +#define SHIFT_OPS ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx) + +#define RELATIONAL_OPS ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt) + +bool cell_supported(RTLIL::Cell *cell) +{ + if (cell->type.in(ID($alu))) { + RTLIL::SigSpec sig_bi = cell->getPort(ID(BI)); + RTLIL::SigSpec sig_ci = cell->getPort(ID(CI)); + + if (sig_bi.is_fully_const() && sig_ci.is_fully_const() && sig_bi == sig_ci) + return true; + } else if (cell->type.in(LOGICAL_OPS, SHIFT_OPS, BITWISE_OPS, RELATIONAL_OPS, ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($concat))) { + return true; + } + + return false; +} + +std::map mergeable_type_map{ + {ID($sub), ID($add)}, +}; + +bool mergeable(RTLIL::Cell *a, RTLIL::Cell *b) +{ + auto a_type = a->type; + if (mergeable_type_map.count(a_type)) + a_type = mergeable_type_map.at(a_type); + + auto b_type = b->type; + if (mergeable_type_map.count(b_type)) + b_type = mergeable_type_map.at(b_type); + + return a_type == b_type; +} + +RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_name) +{ + if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt), ID($div), ID($mod), ID($concat), SHIFT_OPS) && port_name == ID::B) + return port_name; + + return ""; +} + +RTLIL::SigSpec decode_port_sign(RTLIL::Cell *cell, RTLIL::IdString port_name) { + + if (cell->type == ID($alu) && port_name == ID::B) + return cell->getPort(ID(BI)); + else if (cell->type == ID($sub) && port_name == ID::B) + return RTLIL::Const(1, 1); + + return RTLIL::Const(0, 1); +} + +bool decode_port_signed(RTLIL::Cell *cell, RTLIL::IdString port_name) +{ + if (cell->type.in(BITWISE_OPS, LOGICAL_OPS)) + return false; + + if (cell->hasParam(port_name.str() + "_SIGNED")) + return cell->getParam(port_name.str() + "_SIGNED").as_bool(); + + return false; +} + +ExtSigSpec decode_port(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sigmap) +{ + 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); + + bool is_signed = decode_port_signed(cell, port_name); + + return ExtSigSpec(sig, sign, is_signed, semantics); +} + +void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector &ports, const ExtSigSpec &operand) +{ + std::vector muxed_operands; + int max_width = 0; + for (const auto& p : ports) { + auto op = p.op; + + RTLIL::IdString muxed_port_name = ID::A; + if (decode_port(op, ID::A, &assign_map) == operand) + muxed_port_name = ID::B; + + auto operand = decode_port(op, muxed_port_name, &assign_map); + if (operand.sig.size() > max_width) + max_width = operand.sig.size(); + + muxed_operands.push_back(operand); + } + + 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()); + + + for (auto &operand : muxed_operands) + operand.sig.extend_u0(max_width, operand.is_signed); + + for (const auto& p : ports) { + auto op = p.op; + if (op == shared_op) + continue; + 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)); + + 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)); + + if (mux->type == ID($pmux)) { + shared_pmux_s = RTLIL::SigSpec(); + + for (const auto &p : ports) { + 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)); + } + } 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); + + 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->setParam(ID(Y_WIDTH), conn_width); + + if (decode_port(shared_op, ID::A, &assign_map) == operand) { + shared_op->setPort(ID::B, mux_to_oper); + shared_op->setParam(ID(B_WIDTH), max_width); + } else { + shared_op->setPort(ID::A, mux_to_oper); + shared_op->setParam(ID(A_WIDTH), max_width); + } +} + +typedef struct { + RTLIL::Cell *mux; + std::vector ports; + ExtSigSpec shared_operand; +} merged_op_t; + + +template void remove_val(std::vector &v, const std::vector &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 &ports, const ExtSigSpec &shared_operand) +{ + auto it = ports.begin(); + ExtSigSpec seed; + + while (it != ports.end()) { + auto p = *it; + auto op = p->op; + + RTLIL::IdString muxed_port_name = ID::A; + if (decode_port(op, ID::A, &assign_map) == shared_operand) { + muxed_port_name = ID::B; + } + + auto operand = decode_port(op, muxed_port_name, &assign_map); + + if (seed.empty()) + seed = operand; + + if (operand.is_signed != seed.is_signed) { + ports.erase(it); + } else { + ++it; + } + } +} + +ExtSigSpec find_shared_operand(const OpMuxConn* seed, std::vector &ports, const std::map> &operand_to_users) +{ + std::set ops_using_operand; + std::set ops_set; + for(const auto& p: ports) + ops_set.insert(p->op); + + ExtSigSpec oper; + + auto op_a = seed->op; + + for (RTLIL::IdString port_name : {ID::A, ID::B}) { + oper = decode_port(op_a, port_name, &assign_map); + auto operand_users = operand_to_users.at(oper); + + if (operand_users.size() == 1) + continue; + + ops_using_operand.clear(); + for (auto mux_ops: ops_set) + if (operand_users.count(mux_ops)) + ops_using_operand.insert(mux_ops); + + if (ops_using_operand.size() > 1) { + ports.erase(std::remove_if(ports.begin(), ports.end(), [&](const OpMuxConn *p) { return !ops_using_operand.count(p->op); }), + ports.end()); + return oper; + } + } + + return ExtSigSpec(); +} + +dict find_valid_op_mux_conns(RTLIL::Module *module, dict &op_outbit_to_outsig, + dict outsig_to_operator, + dict &op_aux_to_outsig) +{ + dict op_outsig_user_track; + dict op_mux_conn_map; + + std::function 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 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 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 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 + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" opt_share [selection]\n"); + log("\n"); + + log("This pass identifies mutually exclusive cells of the same type that:\n"); + log(" (a) share an input signal,\n"); + log(" (b) drive the same $mux, $_MUX_, or $pmux multiplexing cell,\n"); + log("\n"); + log("allowing the cell to be merged and the multiplexer to be moved from\n"); + log("multiplexing its output to multiplexing the non-shared input signals.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_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); + + std::map> operand_to_users; + dict outsig_to_operator; + dict op_outbit_to_outsig; + dict op_aux_to_outsig; + bool any_shared_operands = false; + std::vector op_insigs; + + for (auto cell : module->cells()) { + if (!cell_supported(cell)) + continue; + + 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; + } + } + + 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; + + 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); + operand_to_users[op_insig].insert(cell); + if (operand_to_users[op_insig].size() > 1) + any_shared_operands = true; + } + } + + if (!any_shared_operands) + continue; + + // 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 op_mux_conn_map = + find_valid_op_mux_conns(module, op_outbit_to_outsig, outsig_to_operator, op_aux_to_outsig); + + // Group op connections connected to same ports of the same $mux. Sort them in ascending order of their port offset + dict>> 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]; + + if (mux_port_conns.size() == 0) { + int mux_port_num; + + if (p.mux->type.in(ID($mux), ID($_MUX_))) + mux_port_num = 2; + else + mux_port_num = p.mux->getPort(ID(S)).size(); + + mux_port_conns.resize(mux_port_num); + } + + mux_port_conns[p.mux_port_id].insert(p); + } + + std::vector merged_ops; + for (auto& val: mux_port_op_conns) { + + RTLIL::Cell* cell = val.first; + auto &mux_port_conns = val.second; + + const OpMuxConn *seed = NULL; + + // Look through the bits of the $mux inputs and see which of them are connected to the operator + // results. Operator results can be concatenated with other signals before led to the $mux. + while (true) { + + // Remove either the merged ports from the last iteration or the seed that failed to yield a merger + if (seed != NULL) { + mux_port_conns[seed->mux_port_id].erase(*seed); + seed = NULL; + } + + // For a new merger, find the seed op connection that starts at lowest port offset among port connections + for (auto &port_conns : mux_port_conns) { + if (!port_conns.size()) + continue; + + const OpMuxConn *next_p = &(*port_conns.begin()); + + if ((seed == NULL) || (seed->mux_port_offset > next_p->mux_port_offset)) + seed = next_p; + } + + // Cannot find the seed -> nothing to do for this $mux anymore + if (seed == NULL) + break; + + // Find all other op connections that start from the same port offset, and whose ops can be merged with the seed op + std::vector mergeable_conns; + for (auto &port_conns : mux_port_conns) { + if (!port_conns.size()) + continue; + + const OpMuxConn *next_p = &(*port_conns.begin()); + + if ((next_p->op_outsig_offset == seed->op_outsig_offset) && + (next_p->mux_port_offset == seed->mux_port_offset) && mergeable(next_p->op, seed->op) && + next_p->sig.size() == seed->sig.size()) + mergeable_conns.push_back(next_p); + } + + // We need at least two mergeable connections for the merger + if (mergeable_conns.size() < 2) + 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); + + if (shared_operand.empty()) + continue; + + check_muxed_operands(mergeable_conns, shared_operand); + + if (mergeable_conns.size() < 2) + continue; + + // Remember the combination for the merger + std::vector merged_ports; + for (auto p : mergeable_conns) { + merged_ports.push_back(*p); + mux_port_conns[p->mux_port_id].erase(*p); + } + + seed = NULL; + + merged_ops.push_back(merged_op_t{cell, merged_ports, shared_operand}); + + design->scratchpad_set_bool("opt.did_something", true); + } + + } + + for (auto &shared : merged_ops) { + log(" Found cells that share an operand and can be merged by moving the %s %s in front " + "of " + "them:\n", + log_id(shared.mux->type), log_id(shared.mux)); + for (const auto& op : shared.ports) + log(" %s\n", log_id(op.op)); + log("\n"); + + merge_operators(module, shared.mux, shared.ports, shared.shared_operand); + } + } + } + +} OptSharePass; + +PRIVATE_NAMESPACE_END diff --git a/passes/opt/pmux2shiftx.cc b/passes/opt/pmux2shiftx.cc index 65d8b8f32..92b5794ac 100644 --- a/passes/opt/pmux2shiftx.cc +++ b/passes/opt/pmux2shiftx.cc @@ -46,7 +46,7 @@ struct OnehotDatabase for (auto wire : module->wires()) { - auto it = wire->attributes.find("\\init"); + auto it = wire->attributes.find(ID(init)); if (it == wire->attributes.end()) continue; @@ -63,19 +63,19 @@ struct OnehotDatabase vector inputs; SigSpec output; - if (cell->type.in("$adff", "$dff", "$dffe", "$dlatch", "$ff")) + if (cell->type.in(ID($adff), ID($dff), ID($dffe), ID($dlatch), ID($ff))) { - output = cell->getPort("\\Q"); - if (cell->type == "$adff") - inputs.push_back(cell->getParam("\\ARST_VALUE")); - inputs.push_back(cell->getPort("\\D")); + output = cell->getPort(ID(Q)); + if (cell->type == ID($adff)) + inputs.push_back(cell->getParam(ID(ARST_VALUE))); + inputs.push_back(cell->getPort(ID(D))); } - if (cell->type.in("$mux", "$pmux")) + if (cell->type.in(ID($mux), ID($pmux))) { - output = cell->getPort("\\Y"); - inputs.push_back(cell->getPort("\\A")); - SigSpec B = cell->getPort("\\B"); + output = cell->getPort(ID::Y); + inputs.push_back(cell->getPort(ID::A)); + SigSpec B = cell->getPort(ID::B); for (int i = 0; i < GetSize(B); i += GetSize(output)) inputs.push_back(B.extract(i, GetSize(output))); } @@ -292,23 +292,23 @@ struct Pmux2ShiftxPass : public Pass { for (auto cell : module->cells()) { - if (cell->type == "$eq") + if (cell->type == ID($eq)) { dict bits; - SigSpec A = sigmap(cell->getPort("\\A")); - SigSpec B = sigmap(cell->getPort("\\B")); + SigSpec A = sigmap(cell->getPort(ID::A)); + SigSpec B = sigmap(cell->getPort(ID::B)); - int a_width = cell->getParam("\\A_WIDTH").as_int(); - int b_width = cell->getParam("\\B_WIDTH").as_int(); + int a_width = cell->getParam(ID(A_WIDTH)).as_int(); + int b_width = cell->getParam(ID(B_WIDTH)).as_int(); if (a_width < b_width) { - bool a_signed = cell->getParam("\\A_SIGNED").as_int(); + bool a_signed = cell->getParam(ID(A_SIGNED)).as_int(); A.extend_u0(b_width, a_signed); } if (b_width < a_width) { - bool b_signed = cell->getParam("\\B_SIGNED").as_int(); + bool b_signed = cell->getParam(ID(B_SIGNED)).as_int(); B.extend_u0(a_width, b_signed); } @@ -335,15 +335,15 @@ struct Pmux2ShiftxPass : public Pass { entry.second.bits.push_back(it.second); } - eqdb[sigmap(cell->getPort("\\Y")[0])] = entry; + eqdb[sigmap(cell->getPort(ID::Y)[0])] = entry; goto next_cell; } - if (cell->type == "$logic_not") + if (cell->type == ID($logic_not)) { dict bits; - SigSpec A = sigmap(cell->getPort("\\A")); + SigSpec A = sigmap(cell->getPort(ID::A)); for (int i = 0; i < GetSize(A); i++) bits[A[i]] = State::S0; @@ -356,7 +356,7 @@ struct Pmux2ShiftxPass : public Pass { entry.second.bits.push_back(it.second); } - eqdb[sigmap(cell->getPort("\\Y")[0])] = entry; + eqdb[sigmap(cell->getPort(ID::Y)[0])] = entry; goto next_cell; } next_cell:; @@ -364,11 +364,11 @@ struct Pmux2ShiftxPass : public Pass { for (auto cell : module->selected_cells()) { - if (cell->type != "$pmux") + if (cell->type != ID($pmux)) continue; string src = cell->get_src_attribute(); - int width = cell->getParam("\\WIDTH").as_int(); + int width = cell->getParam(ID(WIDTH)).as_int(); int width_bits = ceil_log2(width); int extwidth = width; @@ -377,9 +377,9 @@ struct Pmux2ShiftxPass : public Pass { dict> seldb; - SigSpec A = cell->getPort("\\A"); - SigSpec B = cell->getPort("\\B"); - SigSpec S = sigmap(cell->getPort("\\S")); + SigSpec A = cell->getPort(ID::A); + SigSpec B = cell->getPort(ID::B); + SigSpec S = sigmap(cell->getPort(ID(S))); for (int i = 0; i < GetSize(S); i++) { if (!eqdb.count(S[i])) @@ -400,8 +400,8 @@ struct Pmux2ShiftxPass : public Pass { log(" data width: %d (next power-of-2 = %d, log2 = %d)\n", width, extwidth, width_bits); } - SigSpec updated_S = cell->getPort("\\S"); - SigSpec updated_B = cell->getPort("\\B"); + SigSpec updated_S = cell->getPort(ID(S)); + SigSpec updated_B = cell->getPort(ID::B); while (!seldb.empty()) { @@ -727,9 +727,9 @@ struct Pmux2ShiftxPass : public Pass { } // update $pmux cell - cell->setPort("\\S", updated_S); - cell->setPort("\\B", updated_B); - cell->setParam("\\S_WIDTH", GetSize(updated_S)); + cell->setPort(ID(S), updated_S); + cell->setPort(ID::B, updated_B); + cell->setParam(ID(S_WIDTH), GetSize(updated_S)); } } } @@ -779,22 +779,22 @@ struct OnehotPass : public Pass { for (auto cell : module->selected_cells()) { - if (cell->type != "$eq") + if (cell->type != ID($eq)) continue; - SigSpec A = sigmap(cell->getPort("\\A")); - SigSpec B = sigmap(cell->getPort("\\B")); + SigSpec A = sigmap(cell->getPort(ID::A)); + SigSpec B = sigmap(cell->getPort(ID::B)); - int a_width = cell->getParam("\\A_WIDTH").as_int(); - int b_width = cell->getParam("\\B_WIDTH").as_int(); + int a_width = cell->getParam(ID(A_WIDTH)).as_int(); + int b_width = cell->getParam(ID(B_WIDTH)).as_int(); if (a_width < b_width) { - bool a_signed = cell->getParam("\\A_SIGNED").as_int(); + bool a_signed = cell->getParam(ID(A_SIGNED)).as_int(); A.extend_u0(b_width, a_signed); } if (b_width < a_width) { - bool b_signed = cell->getParam("\\B_SIGNED").as_int(); + bool b_signed = cell->getParam(ID(B_SIGNED)).as_int(); B.extend_u0(a_width, b_signed); } @@ -830,7 +830,7 @@ struct OnehotPass : public Pass { continue; } - SigSpec Y = cell->getPort("\\Y"); + SigSpec Y = cell->getPort(ID::Y); if (not_onehot) { diff --git a/passes/opt/rmports.cc b/passes/opt/rmports.cc index fc1596ebf..32363dd68 100644 --- a/passes/opt/rmports.cc +++ b/passes/opt/rmports.cc @@ -171,7 +171,7 @@ struct RmportsPassPass : public Pass { wire->port_output = false; wire->port_id = 0; } - log("Removed %zu unused ports.\n", unused_ports.size()); + log("Removed %d unused ports.\n", GetSize(unused_ports)); // Re-number all of the wires that DO have ports still on them for(size_t i=0; iports.size(); i++) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index c85c27427..92ce3fd11 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -89,8 +89,8 @@ struct ShareWorker queue_bits.clear(); for (auto &pbit : portbits) { - if (pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") { - pool bits = modwalker.sigmap(pbit.cell->getPort("\\S")).to_sigbit_pool(); + if (pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) { + pool bits = modwalker.sigmap(pbit.cell->getPort(ID(S))).to_sigbit_pool(); terminal_bits.insert(bits.begin(), bits.end()); queue_bits.insert(bits.begin(), bits.end()); visited_cells.insert(pbit.cell); @@ -128,7 +128,7 @@ struct ShareWorker static int bits_macc(RTLIL::Cell *c) { Macc m(c); - int width = GetSize(c->getPort("\\Y")); + int width = GetSize(c->getPort(ID::Y)); return bits_macc(m, width); } @@ -242,7 +242,7 @@ struct ShareWorker { Macc m1(c1), m2(c2), supermacc; - int w1 = GetSize(c1->getPort("\\Y")), w2 = GetSize(c2->getPort("\\Y")); + int w1 = GetSize(c1->getPort(ID::Y)), w2 = GetSize(c2->getPort(ID::Y)); int width = max(w1, w2); m1.optimize(w1); @@ -328,11 +328,11 @@ struct ShareWorker { RTLIL::SigSpec sig_y = module->addWire(NEW_ID, width); - supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort("\\Y"))); - supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort("\\Y"))); + supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort(ID::Y))); + supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort(ID::Y))); - supercell->setParam("\\Y_WIDTH", width); - supercell->setPort("\\Y", sig_y); + supercell->setParam(ID(Y_WIDTH), width); + supercell->setPort(ID::Y, sig_y); supermacc.optimize(width); supermacc.to_cell(supercell); @@ -368,22 +368,22 @@ struct ShareWorker continue; } - if (cell->type == "$memrd") { - if (cell->parameters.at("\\CLK_ENABLE").as_bool()) + if (cell->type == ID($memrd)) { + if (cell->parameters.at(ID(CLK_ENABLE)).as_bool()) continue; - if (config.opt_aggressive || !modwalker.sigmap(cell->getPort("\\ADDR")).is_fully_const()) + if (config.opt_aggressive || !modwalker.sigmap(cell->getPort(ID(ADDR))).is_fully_const()) shareable_cells.insert(cell); continue; } - if (cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod") { - if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 4) + if (cell->type.in(ID($mul), ID($div), ID($mod))) { + if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 4) shareable_cells.insert(cell); continue; } - if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { - if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 8) + if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) { + if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 8) shareable_cells.insert(cell); continue; } @@ -401,9 +401,9 @@ struct ShareWorker if (c1->type != c2->type) return false; - if (c1->type == "$memrd") + if (c1->type == ID($memrd)) { - if (c1->parameters.at("\\MEMID").decode_string() != c2->parameters.at("\\MEMID").decode_string()) + if (c1->parameters.at(ID(MEMID)).decode_string() != c2->parameters.at(ID(MEMID)).decode_string()) return false; return true; @@ -413,11 +413,11 @@ struct ShareWorker { if (!config.opt_aggressive) { - int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); - int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); + int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int(); + int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int(); - int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); - int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); + int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int(); + int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int(); if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false; if (max(y1_width, y2_width) > 2 * min(y1_width, y2_width)) return false; @@ -426,17 +426,17 @@ struct ShareWorker return true; } - if (config.generic_bin_ops.count(c1->type) || c1->type == "$alu") + if (config.generic_bin_ops.count(c1->type) || c1->type == ID($alu)) { if (!config.opt_aggressive) { - int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); - int b1_width = c1->parameters.at("\\B_WIDTH").as_int(); - int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); + int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int(); + int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int(); + int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int(); - int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); - int b2_width = c2->parameters.at("\\B_WIDTH").as_int(); - int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); + int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int(); + int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int(); + int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int(); if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false; if (max(b1_width, b2_width) > 2 * min(b1_width, b2_width)) return false; @@ -450,13 +450,13 @@ struct ShareWorker { if (!config.opt_aggressive) { - int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); - int b1_width = c1->parameters.at("\\B_WIDTH").as_int(); - int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); + int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int(); + int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int(); + int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int(); - int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); - int b2_width = c2->parameters.at("\\B_WIDTH").as_int(); - int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); + int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int(); + int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int(); + int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int(); int min1_width = min(a1_width, b1_width); int max1_width = max(a1_width, b1_width); @@ -472,7 +472,7 @@ struct ShareWorker return true; } - if (c1->type == "$macc") + if (c1->type == ID($macc)) { if (!config.opt_aggressive) if (share_macc(c1, c2) > 2 * min(bits_macc(c1), bits_macc(c2))) return false; @@ -510,27 +510,27 @@ struct ShareWorker if (config.generic_uni_ops.count(c1->type)) { - if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) + if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool()) { - RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->getPort("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { - unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; - RTLIL::SigSpec new_a = unsigned_cell->getPort("\\A"); + RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1; + if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) { + unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1; + RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A); new_a.append_bit(RTLIL::State::S0); - unsigned_cell->setPort("\\A", new_a); + unsigned_cell->setPort(ID::A, new_a); } - unsigned_cell->parameters.at("\\A_SIGNED") = true; + unsigned_cell->parameters.at(ID(A_SIGNED)) = true; unsigned_cell->check(); } - bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); - log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool()); + bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool(); + log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool()); - RTLIL::SigSpec a1 = c1->getPort("\\A"); - RTLIL::SigSpec y1 = c1->getPort("\\Y"); + RTLIL::SigSpec a1 = c1->getPort(ID::A); + RTLIL::SigSpec y1 = c1->getPort(ID::Y); - RTLIL::SigSpec a2 = c2->getPort("\\A"); - RTLIL::SigSpec y2 = c2->getPort("\\Y"); + RTLIL::SigSpec a2 = c2->getPort(ID::A); + RTLIL::SigSpec y2 = c2->getPort(ID::Y); int a_width = max(a1.size(), a2.size()); int y_width = max(y1.size(), y2.size()); @@ -544,11 +544,11 @@ struct ShareWorker RTLIL::Wire *y = module->addWire(NEW_ID, y_width); RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); - supercell->parameters["\\A_SIGNED"] = a_signed; - supercell->parameters["\\A_WIDTH"] = a_width; - supercell->parameters["\\Y_WIDTH"] = y_width; - supercell->setPort("\\A", a); - supercell->setPort("\\Y", y); + supercell->parameters[ID(A_SIGNED)] = a_signed; + supercell->parameters[ID(A_WIDTH)] = a_width; + supercell->parameters[ID(Y_WIDTH)] = y_width; + supercell->setPort(ID::A, a); + supercell->setPort(ID::Y, y); supercell_aux.insert(module->addPos(NEW_ID, y, y1)); supercell_aux.insert(module->addPos(NEW_ID, y, y2)); @@ -557,54 +557,54 @@ struct ShareWorker return supercell; } - if (config.generic_bin_ops.count(c1->type) || config.generic_cbin_ops.count(c1->type) || c1->type == "$alu") + if (config.generic_bin_ops.count(c1->type) || config.generic_cbin_ops.count(c1->type) || c1->type == ID($alu)) { bool modified_src_cells = false; if (config.generic_cbin_ops.count(c1->type)) { - int score_unflipped = max(c1->parameters.at("\\A_WIDTH").as_int(), c2->parameters.at("\\A_WIDTH").as_int()) + - max(c1->parameters.at("\\B_WIDTH").as_int(), c2->parameters.at("\\B_WIDTH").as_int()); + int score_unflipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int()) + + max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int()); - int score_flipped = max(c1->parameters.at("\\A_WIDTH").as_int(), c2->parameters.at("\\B_WIDTH").as_int()) + - max(c1->parameters.at("\\B_WIDTH").as_int(), c2->parameters.at("\\A_WIDTH").as_int()); + int score_flipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int()) + + max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int()); if (score_flipped < score_unflipped) { - RTLIL::SigSpec tmp = c2->getPort("\\A"); - c2->setPort("\\A", c2->getPort("\\B")); - c2->setPort("\\B", tmp); + RTLIL::SigSpec tmp = c2->getPort(ID::A); + c2->setPort(ID::A, c2->getPort(ID::B)); + c2->setPort(ID::B, tmp); - std::swap(c2->parameters.at("\\A_WIDTH"), c2->parameters.at("\\B_WIDTH")); - std::swap(c2->parameters.at("\\A_SIGNED"), c2->parameters.at("\\B_SIGNED")); + std::swap(c2->parameters.at(ID(A_WIDTH)), c2->parameters.at(ID(B_WIDTH))); + std::swap(c2->parameters.at(ID(A_SIGNED)), c2->parameters.at(ID(B_SIGNED))); modified_src_cells = true; } } - if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) + if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool()) { - RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->getPort("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { - unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; - RTLIL::SigSpec new_a = unsigned_cell->getPort("\\A"); + RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1; + if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) { + unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1; + RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A); new_a.append_bit(RTLIL::State::S0); - unsigned_cell->setPort("\\A", new_a); + unsigned_cell->setPort(ID::A, new_a); } - unsigned_cell->parameters.at("\\A_SIGNED") = true; + unsigned_cell->parameters.at(ID(A_SIGNED)) = true; modified_src_cells = true; } - if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool()) + if (c1->parameters.at(ID(B_SIGNED)).as_bool() != c2->parameters.at(ID(B_SIGNED)).as_bool()) { - RTLIL::Cell *unsigned_cell = c1->parameters.at("\\B_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->getPort("\\B").to_sigbit_vector().back() != RTLIL::State::S0) { - unsigned_cell->parameters.at("\\B_WIDTH") = unsigned_cell->parameters.at("\\B_WIDTH").as_int() + 1; - RTLIL::SigSpec new_b = unsigned_cell->getPort("\\B"); + RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(B_SIGNED)).as_bool() ? c2 : c1; + if (unsigned_cell->getPort(ID::B).to_sigbit_vector().back() != RTLIL::State::S0) { + unsigned_cell->parameters.at(ID(B_WIDTH)) = unsigned_cell->parameters.at(ID(B_WIDTH)).as_int() + 1; + RTLIL::SigSpec new_b = unsigned_cell->getPort(ID::B); new_b.append_bit(RTLIL::State::S0); - unsigned_cell->setPort("\\B", new_b); + unsigned_cell->setPort(ID::B, new_b); } - unsigned_cell->parameters.at("\\B_SIGNED") = true; + unsigned_cell->parameters.at(ID(B_SIGNED)) = true; modified_src_cells = true; } @@ -613,28 +613,28 @@ struct ShareWorker c2->check(); } - bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); - bool b_signed = c1->parameters.at("\\B_SIGNED").as_bool(); + bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool(); + bool b_signed = c1->parameters.at(ID(B_SIGNED)).as_bool(); - log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool()); - log_assert(b_signed == c2->parameters.at("\\B_SIGNED").as_bool()); + log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool()); + log_assert(b_signed == c2->parameters.at(ID(B_SIGNED)).as_bool()); - if (c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") + if (c1->type == ID($shl) || c1->type == ID($shr) || c1->type == ID($sshl) || c1->type == ID($sshr)) b_signed = false; - RTLIL::SigSpec a1 = c1->getPort("\\A"); - RTLIL::SigSpec b1 = c1->getPort("\\B"); - RTLIL::SigSpec y1 = c1->getPort("\\Y"); + RTLIL::SigSpec a1 = c1->getPort(ID::A); + RTLIL::SigSpec b1 = c1->getPort(ID::B); + RTLIL::SigSpec y1 = c1->getPort(ID::Y); - RTLIL::SigSpec a2 = c2->getPort("\\A"); - RTLIL::SigSpec b2 = c2->getPort("\\B"); - RTLIL::SigSpec y2 = c2->getPort("\\Y"); + RTLIL::SigSpec a2 = c2->getPort(ID::A); + RTLIL::SigSpec b2 = c2->getPort(ID::B); + RTLIL::SigSpec y2 = c2->getPort(ID::Y); int a_width = max(a1.size(), a2.size()); int b_width = max(b1.size(), b2.size()); int y_width = max(y1.size(), y2.size()); - if (c1->type == "$shr" && a_signed) + if (c1->type == ID($shr) && a_signed) { a_width = max(y_width, a_width); @@ -660,43 +660,43 @@ struct ShareWorker supercell_aux.insert(module->addMux(NEW_ID, b2, b1, act, b)); RTLIL::Wire *y = module->addWire(NEW_ID, y_width); - RTLIL::Wire *x = c1->type == "$alu" ? module->addWire(NEW_ID, y_width) : nullptr; - RTLIL::Wire *co = c1->type == "$alu" ? module->addWire(NEW_ID, y_width) : nullptr; + RTLIL::Wire *x = c1->type == ID($alu) ? module->addWire(NEW_ID, y_width) : nullptr; + RTLIL::Wire *co = c1->type == ID($alu) ? module->addWire(NEW_ID, y_width) : nullptr; RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); - supercell->parameters["\\A_SIGNED"] = a_signed; - supercell->parameters["\\B_SIGNED"] = b_signed; - supercell->parameters["\\A_WIDTH"] = a_width; - supercell->parameters["\\B_WIDTH"] = b_width; - supercell->parameters["\\Y_WIDTH"] = y_width; - supercell->setPort("\\A", a); - supercell->setPort("\\B", b); - supercell->setPort("\\Y", y); - if (c1->type == "$alu") { + supercell->parameters[ID(A_SIGNED)] = a_signed; + supercell->parameters[ID(B_SIGNED)] = b_signed; + supercell->parameters[ID(A_WIDTH)] = a_width; + supercell->parameters[ID(B_WIDTH)] = b_width; + supercell->parameters[ID(Y_WIDTH)] = y_width; + supercell->setPort(ID::A, a); + supercell->setPort(ID::B, b); + supercell->setPort(ID::Y, y); + if (c1->type == ID($alu)) { RTLIL::Wire *ci = module->addWire(NEW_ID), *bi = module->addWire(NEW_ID); - supercell_aux.insert(module->addMux(NEW_ID, c2->getPort("\\CI"), c1->getPort("\\CI"), act, ci)); - supercell_aux.insert(module->addMux(NEW_ID, c2->getPort("\\BI"), c1->getPort("\\BI"), act, bi)); - supercell->setPort("\\CI", ci); - supercell->setPort("\\BI", bi); - supercell->setPort("\\CO", co); - supercell->setPort("\\X", x); + supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(CI)), c1->getPort(ID(CI)), act, ci)); + supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(BI)), c1->getPort(ID(BI)), act, bi)); + supercell->setPort(ID(CI), ci); + supercell->setPort(ID(BI), bi); + supercell->setPort(ID(CO), co); + supercell->setPort(ID(X), x); } supercell->check(); supercell_aux.insert(module->addPos(NEW_ID, y, y1)); supercell_aux.insert(module->addPos(NEW_ID, y, y2)); - if (c1->type == "$alu") { - supercell_aux.insert(module->addPos(NEW_ID, co, c1->getPort("\\CO"))); - supercell_aux.insert(module->addPos(NEW_ID, co, c2->getPort("\\CO"))); - supercell_aux.insert(module->addPos(NEW_ID, x, c1->getPort("\\X"))); - supercell_aux.insert(module->addPos(NEW_ID, x, c2->getPort("\\X"))); + if (c1->type == ID($alu)) { + supercell_aux.insert(module->addPos(NEW_ID, co, c1->getPort(ID(CO)))); + supercell_aux.insert(module->addPos(NEW_ID, co, c2->getPort(ID(CO)))); + supercell_aux.insert(module->addPos(NEW_ID, x, c1->getPort(ID(X)))); + supercell_aux.insert(module->addPos(NEW_ID, x, c2->getPort(ID(X)))); } supercell_aux.insert(supercell); return supercell; } - if (c1->type == "$macc") + if (c1->type == ID($macc)) { RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); supercell_aux.insert(supercell); @@ -705,18 +705,18 @@ struct ShareWorker return supercell; } - if (c1->type == "$memrd") + if (c1->type == ID($memrd)) { RTLIL::Cell *supercell = module->addCell(NEW_ID, c1); - RTLIL::SigSpec addr1 = c1->getPort("\\ADDR"); - RTLIL::SigSpec addr2 = c2->getPort("\\ADDR"); + RTLIL::SigSpec addr1 = c1->getPort(ID(ADDR)); + RTLIL::SigSpec addr2 = c2->getPort(ID(ADDR)); if (GetSize(addr1) < GetSize(addr2)) addr1.extend_u0(GetSize(addr2)); else addr2.extend_u0(GetSize(addr1)); - supercell->setPort("\\ADDR", addr1 != addr2 ? module->Mux(NEW_ID, addr2, addr1, act) : addr1); - supercell->parameters["\\ABITS"] = RTLIL::Const(GetSize(addr1)); - supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort("\\DATA"), c2->getPort("\\DATA"))); + supercell->setPort(ID(ADDR), addr1 != addr2 ? module->Mux(NEW_ID, addr2, addr1, act) : addr1); + supercell->parameters[ID(ABITS)] = RTLIL::Const(GetSize(addr1)); + supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort(ID(DATA)), c2->getPort(ID(DATA)))); supercell_aux.insert(supercell); return supercell; } @@ -747,8 +747,8 @@ struct ShareWorker modwalker.get_consumers(pbits, modwalker.cell_outputs[cell]); for (auto &bit : pbits) { - if ((bit.cell->type == "$mux" || bit.cell->type == "$pmux") && bit.port == "\\S") - forbidden_controls_cache[cell].insert(bit.cell->getPort("\\S").extract(bit.offset, 1)); + if ((bit.cell->type == ID($mux) || bit.cell->type == ID($pmux)) && bit.port == ID(S)) + forbidden_controls_cache[cell].insert(bit.cell->getPort(ID(S)).extract(bit.offset, 1)); consumer_cells.insert(bit.cell); } @@ -874,7 +874,7 @@ struct ShareWorker } for (auto &pbit : modwalker.signal_consumers[bit]) { log_assert(fwd_ct.cell_known(pbit.cell->type)); - if ((pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") && (pbit.port == "\\A" || pbit.port == "\\B")) + if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && (pbit.port == ID::A || pbit.port == ID::B)) driven_data_muxes.insert(pbit.cell); else driven_cells.insert(pbit.cell); @@ -890,10 +890,10 @@ struct ShareWorker bool used_in_a = false; std::set used_in_b_parts; - int width = c->parameters.at("\\WIDTH").as_int(); - std::vector sig_a = modwalker.sigmap(c->getPort("\\A")); - std::vector sig_b = modwalker.sigmap(c->getPort("\\B")); - std::vector sig_s = modwalker.sigmap(c->getPort("\\S")); + int width = c->parameters.at(ID(WIDTH)).as_int(); + std::vector sig_a = modwalker.sigmap(c->getPort(ID::A)); + std::vector sig_b = modwalker.sigmap(c->getPort(ID::B)); + std::vector sig_s = modwalker.sigmap(c->getPort(ID(S))); for (auto &bit : sig_a) if (cell_out_bits.count(bit)) @@ -1132,14 +1132,14 @@ struct ShareWorker fwd_ct.setup_internals(); cone_ct.setup_internals(); - cone_ct.cell_types.erase("$mul"); - cone_ct.cell_types.erase("$mod"); - cone_ct.cell_types.erase("$div"); - cone_ct.cell_types.erase("$pow"); - cone_ct.cell_types.erase("$shl"); - cone_ct.cell_types.erase("$shr"); - cone_ct.cell_types.erase("$sshl"); - cone_ct.cell_types.erase("$sshr"); + cone_ct.cell_types.erase(ID($mul)); + cone_ct.cell_types.erase(ID($mod)); + cone_ct.cell_types.erase(ID($div)); + cone_ct.cell_types.erase(ID($pow)); + cone_ct.cell_types.erase(ID($shl)); + cone_ct.cell_types.erase(ID($shr)); + cone_ct.cell_types.erase(ID($sshl)); + cone_ct.cell_types.erase(ID($sshr)); modwalker.setup(design, module); @@ -1153,9 +1153,9 @@ struct ShareWorker GetSize(shareable_cells), log_id(module)); for (auto cell : module->cells()) - if (cell->type == "$pmux") - for (auto bit : cell->getPort("\\S")) - for (auto other_bit : cell->getPort("\\S")) + if (cell->type == ID($pmux)) + for (auto bit : cell->getPort(ID(S))) + for (auto other_bit : cell->getPort(ID(S))) if (bit < other_bit) exclusive_ctrls.push_back(std::pair(bit, other_bit)); @@ -1466,43 +1466,43 @@ struct SharePass : public Pass { config.opt_aggressive = false; config.opt_fast = false; - config.generic_uni_ops.insert("$not"); - // config.generic_uni_ops.insert("$pos"); - config.generic_uni_ops.insert("$neg"); + config.generic_uni_ops.insert(ID($not)); + // config.generic_uni_ops.insert(ID($pos)); + config.generic_uni_ops.insert(ID($neg)); - config.generic_cbin_ops.insert("$and"); - config.generic_cbin_ops.insert("$or"); - config.generic_cbin_ops.insert("$xor"); - config.generic_cbin_ops.insert("$xnor"); + config.generic_cbin_ops.insert(ID($and)); + config.generic_cbin_ops.insert(ID($or)); + config.generic_cbin_ops.insert(ID($xor)); + config.generic_cbin_ops.insert(ID($xnor)); - config.generic_bin_ops.insert("$shl"); - config.generic_bin_ops.insert("$shr"); - config.generic_bin_ops.insert("$sshl"); - config.generic_bin_ops.insert("$sshr"); + config.generic_bin_ops.insert(ID($shl)); + config.generic_bin_ops.insert(ID($shr)); + config.generic_bin_ops.insert(ID($sshl)); + config.generic_bin_ops.insert(ID($sshr)); - config.generic_bin_ops.insert("$lt"); - config.generic_bin_ops.insert("$le"); - config.generic_bin_ops.insert("$eq"); - config.generic_bin_ops.insert("$ne"); - config.generic_bin_ops.insert("$eqx"); - config.generic_bin_ops.insert("$nex"); - config.generic_bin_ops.insert("$ge"); - config.generic_bin_ops.insert("$gt"); + config.generic_bin_ops.insert(ID($lt)); + config.generic_bin_ops.insert(ID($le)); + config.generic_bin_ops.insert(ID($eq)); + config.generic_bin_ops.insert(ID($ne)); + config.generic_bin_ops.insert(ID($eqx)); + config.generic_bin_ops.insert(ID($nex)); + config.generic_bin_ops.insert(ID($ge)); + config.generic_bin_ops.insert(ID($gt)); - config.generic_cbin_ops.insert("$add"); - config.generic_cbin_ops.insert("$mul"); + config.generic_cbin_ops.insert(ID($add)); + config.generic_cbin_ops.insert(ID($mul)); - config.generic_bin_ops.insert("$sub"); - config.generic_bin_ops.insert("$div"); - config.generic_bin_ops.insert("$mod"); - // config.generic_bin_ops.insert("$pow"); + config.generic_bin_ops.insert(ID($sub)); + config.generic_bin_ops.insert(ID($div)); + config.generic_bin_ops.insert(ID($mod)); + // config.generic_bin_ops.insert(ID($pow)); - config.generic_uni_ops.insert("$logic_not"); - config.generic_cbin_ops.insert("$logic_and"); - config.generic_cbin_ops.insert("$logic_or"); + config.generic_uni_ops.insert(ID($logic_not)); + config.generic_cbin_ops.insert(ID($logic_and)); + config.generic_cbin_ops.insert(ID($logic_or)); - config.generic_other_ops.insert("$alu"); - config.generic_other_ops.insert("$macc"); + config.generic_other_ops.insert(ID($alu)); + config.generic_other_ops.insert(ID($macc)); log_header(design, "Executing SHARE pass (SAT-based resource sharing).\n"); diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 1fbc41082..c02c355cb 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -22,7 +22,6 @@ #include "kernel/modtools.h" USING_YOSYS_NAMESPACE -using namespace RTLIL; PRIVATE_NAMESPACE_BEGIN @@ -34,13 +33,13 @@ struct WreduceConfig WreduceConfig() { supported_cell_types = pool({ - "$not", "$pos", "$neg", - "$and", "$or", "$xor", "$xnor", - "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", - "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", - "$add", "$sub", "$mul", // "$div", "$mod", "$pow", - "$mux", "$pmux", - "$dff", "$adff" + ID($not), ID($pos), ID($neg), + ID($and), ID($or), ID($xor), ID($xnor), + ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), + 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($pow), + ID($mux), ID($pmux), + ID($dff), ID($adff) }); } }; @@ -64,10 +63,10 @@ struct WreduceWorker { // Reduce size of MUX if inputs agree on a value for a bit or a output bit is unused - SigSpec sig_a = mi.sigmap(cell->getPort("\\A")); - SigSpec sig_b = mi.sigmap(cell->getPort("\\B")); - SigSpec sig_s = mi.sigmap(cell->getPort("\\S")); - SigSpec sig_y = mi.sigmap(cell->getPort("\\Y")); + SigSpec sig_a = mi.sigmap(cell->getPort(ID::A)); + SigSpec sig_b = mi.sigmap(cell->getPort(ID::B)); + SigSpec sig_s = mi.sigmap(cell->getPort(ID(S))); + SigSpec sig_y = mi.sigmap(cell->getPort(ID::Y)); std::vector bits_removed; if (sig_y.has_const()) @@ -77,15 +76,15 @@ struct WreduceWorker { auto info = mi.query(sig_y[i]); if (!info->is_output && GetSize(info->ports) <= 1 && !keep_bits.count(mi.sigmap(sig_y[i]))) { - bits_removed.push_back(Sx); + bits_removed.push_back(State::Sx); continue; } SigBit ref = sig_a[i]; for (int k = 0; k < GetSize(sig_s); k++) { - if ((config->keepdc || (ref != Sx && sig_b[k*GetSize(sig_a) + i] != Sx)) && ref != sig_b[k*GetSize(sig_a) + i]) + if ((config->keepdc || (ref != State::Sx && sig_b[k*GetSize(sig_a) + i] != State::Sx)) && ref != sig_b[k*GetSize(sig_a) + i]) goto no_match_ab; - if (sig_b[k*GetSize(sig_a) + i] != Sx) + if (sig_b[k*GetSize(sig_a) + i] != State::Sx) ref = sig_b[k*GetSize(sig_a) + i]; } if (0) @@ -130,9 +129,9 @@ struct WreduceWorker for (auto bit : new_work_queue_bits) work_queue_bits.insert(bit); - cell->setPort("\\A", new_sig_a); - cell->setPort("\\B", new_sig_b); - cell->setPort("\\Y", new_sig_y); + cell->setPort(ID::A, new_sig_a); + cell->setPort(ID::B, new_sig_b); + cell->setPort(ID::Y, new_sig_y); cell->fixup_parameters(); module->connect(sig_y.extract(n_kept, n_removed), sig_removed); @@ -142,8 +141,8 @@ struct WreduceWorker { // Reduce size of FF if inputs are just sign/zero extended or output bit is not used - SigSpec sig_d = mi.sigmap(cell->getPort("\\D")); - SigSpec sig_q = mi.sigmap(cell->getPort("\\Q")); + SigSpec sig_d = mi.sigmap(cell->getPort(ID(D))); + SigSpec sig_q = mi.sigmap(cell->getPort(ID(Q))); Const initval; int width_before = GetSize(sig_q); @@ -214,14 +213,14 @@ struct WreduceWorker work_queue_bits.insert(bit); // Narrow ARST_VALUE parameter to new size. - if (cell->parameters.count("\\ARST_VALUE")) { - Const arst_value = cell->getParam("\\ARST_VALUE"); + if (cell->parameters.count(ID(ARST_VALUE))) { + Const arst_value = cell->getParam(ID(ARST_VALUE)); arst_value.bits.resize(GetSize(sig_q)); - cell->setParam("\\ARST_VALUE", arst_value); + cell->setParam(ID(ARST_VALUE), arst_value); } - cell->setPort("\\D", sig_d); - cell->setPort("\\Q", sig_q); + cell->setPort(ID(D), sig_d); + cell->setPort(ID(Q), sig_q); cell->fixup_parameters(); } @@ -230,7 +229,7 @@ struct WreduceWorker port_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool(); SigSpec sig = mi.sigmap(cell->getPort(stringf("\\%c", port))); - if (port == 'B' && cell->type.in("$shl", "$shr", "$sshl", "$sshr")) + if (port == 'B' && cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) port_signed = false; int bits_removed = 0; @@ -245,7 +244,7 @@ struct WreduceWorker while (GetSize(sig) > 1 && sig[GetSize(sig)-1] == sig[GetSize(sig)-2]) work_queue_bits.insert(sig[GetSize(sig)-1]), sig.remove(GetSize(sig)-1), bits_removed++; } else { - while (GetSize(sig) > 1 && sig[GetSize(sig)-1] == S0) + while (GetSize(sig) > 1 && sig[GetSize(sig)-1] == State::S0) work_queue_bits.insert(sig[GetSize(sig)-1]), sig.remove(GetSize(sig)-1), bits_removed++; } @@ -264,13 +263,13 @@ struct WreduceWorker if (!cell->type.in(config->supported_cell_types)) return; - if (cell->type.in("$mux", "$pmux")) + if (cell->type.in(ID($mux), ID($pmux))) return run_cell_mux(cell); - if (cell->type.in("$dff", "$adff")) + if (cell->type.in(ID($dff), ID($adff))) return run_cell_dff(cell); - SigSpec sig = mi.sigmap(cell->getPort("\\Y")); + SigSpec sig = mi.sigmap(cell->getPort(ID::Y)); if (sig.has_const()) return; @@ -278,10 +277,10 @@ struct WreduceWorker // Reduce size of ports A and B based on constant input bits and size of output port - int max_port_a_size = cell->hasPort("\\A") ? GetSize(cell->getPort("\\A")) : -1; - int max_port_b_size = cell->hasPort("\\B") ? GetSize(cell->getPort("\\B")) : -1; + int max_port_a_size = cell->hasPort(ID::A) ? GetSize(cell->getPort(ID::A)) : -1; + int max_port_b_size = cell->hasPort(ID::B) ? GetSize(cell->getPort(ID::B)) : -1; - if (cell->type.in("$not", "$pos", "$neg", "$and", "$or", "$xor", "$add", "$sub")) { + if (cell->type.in(ID($not), ID($pos), ID($neg), ID($and), ID($or), ID($xor), ID($add), ID($sub))) { max_port_a_size = min(max_port_a_size, GetSize(sig)); max_port_b_size = min(max_port_b_size, GetSize(sig)); } @@ -289,32 +288,32 @@ struct WreduceWorker bool port_a_signed = false; bool port_b_signed = false; - if (max_port_a_size >= 0 && cell->type != "$shiftx") + if (max_port_a_size >= 0 && cell->type != ID($shiftx)) run_reduce_inport(cell, 'A', max_port_a_size, port_a_signed, did_something); if (max_port_b_size >= 0) run_reduce_inport(cell, 'B', max_port_b_size, port_b_signed, did_something); - if (cell->hasPort("\\A") && cell->hasPort("\\B") && port_a_signed && port_b_signed) { - SigSpec sig_a = mi.sigmap(cell->getPort("\\A")), sig_b = mi.sigmap(cell->getPort("\\B")); + if (cell->hasPort(ID::A) && cell->hasPort(ID::B) && port_a_signed && port_b_signed) { + SigSpec sig_a = mi.sigmap(cell->getPort(ID::A)), sig_b = mi.sigmap(cell->getPort(ID::B)); if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0 && GetSize(sig_b) > 0 && sig_b[GetSize(sig_b)-1] == State::S0) { log("Converting cell %s.%s (%s) from signed to unsigned.\n", log_id(module), log_id(cell), log_id(cell->type)); - cell->setParam("\\A_SIGNED", 0); - cell->setParam("\\B_SIGNED", 0); + cell->setParam(ID(A_SIGNED), 0); + cell->setParam(ID(B_SIGNED), 0); port_a_signed = false; port_b_signed = false; did_something = true; } } - if (cell->hasPort("\\A") && !cell->hasPort("\\B") && port_a_signed) { - SigSpec sig_a = mi.sigmap(cell->getPort("\\A")); + if (cell->hasPort(ID::A) && !cell->hasPort(ID::B) && port_a_signed) { + SigSpec sig_a = mi.sigmap(cell->getPort(ID::A)); if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0) { log("Converting cell %s.%s (%s) from signed to unsigned.\n", log_id(module), log_id(cell), log_id(cell->type)); - cell->setParam("\\A_SIGNED", 0); + cell->setParam(ID(A_SIGNED), 0); port_a_signed = false; did_something = true; } @@ -324,7 +323,7 @@ struct WreduceWorker // Reduce size of port Y based on sizes for A and B and unused bits in Y int bits_removed = 0; - if (port_a_signed && cell->type == "$shr") { + if (port_a_signed && cell->type == ID($shr)) { // do not reduce size of output on $shr cells with signed A inputs } else { while (GetSize(sig) > 0) @@ -342,24 +341,24 @@ struct WreduceWorker } } - if (cell->type.in("$pos", "$add", "$mul", "$and", "$or", "$xor")) + if (cell->type.in(ID($pos), ID($add), ID($mul), ID($and), ID($or), ID($xor), ID($sub))) { - bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool() || cell->type == ID($sub); int a_size = 0, b_size = 0; - if (cell->hasPort("\\A")) a_size = GetSize(cell->getPort("\\A")); - if (cell->hasPort("\\B")) b_size = GetSize(cell->getPort("\\B")); + if (cell->hasPort(ID::A)) a_size = GetSize(cell->getPort(ID::A)); + if (cell->hasPort(ID::B)) b_size = GetSize(cell->getPort(ID::B)); int max_y_size = max(a_size, b_size); - if (cell->type == "$add") + if (cell->type.in(ID($add), ID($sub))) max_y_size++; - if (cell->type == "$mul") + if (cell->type == ID($mul)) max_y_size = a_size + b_size; while (GetSize(sig) > 1 && GetSize(sig) > max_y_size) { - module->connect(sig[GetSize(sig)-1], is_signed ? sig[GetSize(sig)-2] : S0); + module->connect(sig[GetSize(sig)-1], is_signed ? sig[GetSize(sig)-2] : State::S0); sig.remove(GetSize(sig)-1); bits_removed++; } @@ -374,7 +373,7 @@ struct WreduceWorker if (bits_removed) { log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n", bits_removed, GetSize(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type)); - cell->setPort("\\Y", sig); + cell->setPort(ID::Y, sig); did_something = true; } @@ -387,8 +386,8 @@ struct WreduceWorker static int count_nontrivial_wire_attrs(RTLIL::Wire *w) { int count = w->attributes.size(); - count -= w->attributes.count("\\src"); - count -= w->attributes.count("\\unused_bits"); + count -= w->attributes.count(ID(src)); + count -= w->attributes.count(ID(unused_bits)); return count; } @@ -398,11 +397,11 @@ struct WreduceWorker SigMap init_attr_sigmap = mi.sigmap; for (auto w : module->wires()) { - if (w->get_bool_attribute("\\keep")) + if (w->get_bool_attribute(ID::keep)) for (auto bit : mi.sigmap(w)) keep_bits.insert(bit); - if (w->attributes.count("\\init")) { - Const initval = w->attributes.at("\\init"); + 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++) @@ -459,8 +458,8 @@ struct WreduceWorker if (!remove_init_bits.empty()) { for (auto w : module->wires()) { - if (w->attributes.count("\\init")) { - Const initval = w->attributes.at("\\init"); + 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)); @@ -468,7 +467,7 @@ struct WreduceWorker if (!remove_init_bits.count(initsig[i])) new_initval[i] = initval[i]; } - w->attributes.at("\\init") = new_initval; + w->attributes.at(ID(init)) = new_initval; } } } @@ -528,23 +527,23 @@ struct WreducePass : public Pass { for (auto c : module->selected_cells()) { - if (c->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", - "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", - "$logic_not", "$logic_and", "$logic_or") && GetSize(c->getPort("\\Y")) > 1) { - SigSpec sig = c->getPort("\\Y"); + if (c->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), + ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), + ID($logic_not), ID($logic_and), ID($logic_or)) && GetSize(c->getPort(ID::Y)) > 1) { + SigSpec sig = c->getPort(ID::Y); if (!sig.has_const()) { - c->setPort("\\Y", sig[0]); - c->setParam("\\Y_WIDTH", 1); + c->setPort(ID::Y, sig[0]); + c->setParam(ID(Y_WIDTH), 1); sig.remove(0); module->connect(sig, Const(0, GetSize(sig))); } } - if (c->type.in("$div", "$mod", "$pow")) + if (c->type.in(ID($div), ID($mod), ID($pow))) { - SigSpec A = c->getPort("\\A"); + SigSpec A = c->getPort(ID::A); int original_a_width = GetSize(A); - if (c->getParam("\\A_SIGNED").as_bool()) { + if (c->getParam(ID(A_SIGNED)).as_bool()) { while (GetSize(A) > 1 && A[GetSize(A)-1] == State::S0 && A[GetSize(A)-2] == State::S0) A.remove(GetSize(A)-1, 1); } else { @@ -554,13 +553,13 @@ struct WreducePass : public Pass { if (original_a_width != GetSize(A)) { log("Removed top %d bits (of %d) from port A of cell %s.%s (%s).\n", original_a_width-GetSize(A), original_a_width, log_id(module), log_id(c), log_id(c->type)); - c->setPort("\\A", A); - c->setParam("\\A_WIDTH", GetSize(A)); + c->setPort(ID::A, A); + c->setParam(ID(A_WIDTH), GetSize(A)); } - SigSpec B = c->getPort("\\B"); + SigSpec B = c->getPort(ID::B); int original_b_width = GetSize(B); - if (c->getParam("\\B_SIGNED").as_bool()) { + if (c->getParam(ID(B_SIGNED)).as_bool()) { while (GetSize(B) > 1 && B[GetSize(B)-1] == State::S0 && B[GetSize(B)-2] == State::S0) B.remove(GetSize(B)-1, 1); } else { @@ -570,24 +569,24 @@ struct WreducePass : public Pass { if (original_b_width != GetSize(B)) { log("Removed top %d bits (of %d) from port B of cell %s.%s (%s).\n", original_b_width-GetSize(B), original_b_width, log_id(module), log_id(c), log_id(c->type)); - c->setPort("\\B", B); - c->setParam("\\B_WIDTH", GetSize(B)); + c->setPort(ID::B, B); + c->setParam(ID(B_WIDTH), GetSize(B)); } } - if (!opt_memx && c->type.in("$memrd", "$memwr", "$meminit")) { - IdString memid = c->getParam("\\MEMID").decode_string(); + if (!opt_memx && c->type.in(ID($memrd), ID($memwr), ID($meminit))) { + IdString memid = c->getParam(ID(MEMID)).decode_string(); RTLIL::Memory *mem = module->memories.at(memid); if (mem->start_offset >= 0) { - int cur_addrbits = c->getParam("\\ABITS").as_int(); + int cur_addrbits = c->getParam(ID(ABITS)).as_int(); int max_addrbits = ceil_log2(mem->start_offset + mem->size); if (cur_addrbits > max_addrbits) { log("Removed top %d address bits (of %d) from memory %s port %s.%s (%s).\n", cur_addrbits-max_addrbits, cur_addrbits, - c->type == "$memrd" ? "read" : c->type == "$memwr" ? "write" : "init", + c->type == ID($memrd) ? "read" : c->type == ID($memwr) ? "write" : "init", log_id(module), log_id(c), log_id(memid)); - c->setParam("\\ABITS", max_addrbits); - c->setPort("\\ADDR", c->getPort("\\ADDR").extract(0, max_addrbits)); + c->setParam(ID(ABITS), max_addrbits); + c->setPort(ID(ADDR), c->getPort(ID(ADDR)).extract(0, max_addrbits)); } } } diff --git a/passes/pmgen/.gitignore b/passes/pmgen/.gitignore index 0ad36ea2c..e52f3282f 100644 --- a/passes/pmgen/.gitignore +++ b/passes/pmgen/.gitignore @@ -1,2 +1 @@ -/ice40_dsp_pm.h -/peepopt_pm.h +/*_pm.h diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index 7911132db..c03606152 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -1,4 +1,5 @@ OBJS += passes/pmgen/ice40_dsp.o +OBJS += passes/pmgen/ice40_wrapcarry.o OBJS += passes/pmgen/peepopt.o # -------------------------------------- @@ -12,6 +13,15 @@ passes/pmgen/ice40_dsp_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_dsp.pmg # -------------------------------------- +passes/pmgen/ice40_wrapcarry.o: passes/pmgen/ice40_wrapcarry_pm.h +EXTRA_OBJS += passes/pmgen/ice40_wrapcarry_pm.h +.SECONDARY: passes/pmgen/ice40_wrapcarry_pm.h + +passes/pmgen/ice40_wrapcarry_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_wrapcarry.pmg + $(P) mkdir -p passes/pmgen && python3 $< -o $@ -p ice40_wrapcarry $(filter-out $<,$^) + +# -------------------------------------- + passes/pmgen/peepopt.o: passes/pmgen/peepopt_pm.h EXTRA_OBJS += passes/pmgen/peepopt_pm.h .SECONDARY: passes/pmgen/peepopt_pm.h diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc new file mode 100644 index 000000000..69ef3cd82 --- /dev/null +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -0,0 +1,90 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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 + +#include "passes/pmgen/ice40_wrapcarry_pm.h" + +void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm) +{ + auto &st = pm.st_ice40_wrapcarry; + +#if 0 + log("\n"); + log("carry: %s\n", log_id(st.carry, "--")); + log("lut: %s\n", log_id(st.lut, "--")); +#endif + + log(" replacing SB_LUT + SB_CARRY with $__ICE40_CARRY_WRAPPER cell.\n"); + + Cell *cell = pm.module->addCell(NEW_ID, "$__ICE40_CARRY_WRAPPER"); + pm.module->swap_names(cell, st.carry); + + cell->setPort("\\A", st.carry->getPort("\\I0")); + cell->setPort("\\B", st.carry->getPort("\\I1")); + cell->setPort("\\CI", st.carry->getPort("\\CI")); + cell->setPort("\\CO", st.carry->getPort("\\CO")); + + cell->setPort("\\I0", st.lut->getPort("\\I0")); + cell->setPort("\\I3", st.lut->getPort("\\I3")); + cell->setPort("\\O", st.lut->getPort("\\O")); + cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT")); + + pm.autoremove(st.carry); + pm.autoremove(st.lut); +} + +struct Ice40WrapCarryPass : public Pass { + Ice40WrapCarryPass() : Pass("ice40_wrapcarry", "iCE40: wrap carries") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" ice40_wrapcarry [selection]\n"); + log("\n"); + log("Wrap manually instantiated SB_CARRY cells, along with their associated SB_LUTs,\n"); + log("into an internal $__ICE40_CARRY_WRAPPER cell for preservation across technology\n"); + log("mapping."); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing ICE40_WRAPCARRY pass (wrap carries).\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()) + ice40_wrapcarry_pm(module, module->selected_cells()).run_ice40_wrapcarry(create_ice40_wrapcarry); + } +} Ice40WrapCarryPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/pmgen/ice40_wrapcarry.pmg b/passes/pmgen/ice40_wrapcarry.pmg new file mode 100644 index 000000000..9e64c7467 --- /dev/null +++ b/passes/pmgen/ice40_wrapcarry.pmg @@ -0,0 +1,11 @@ +pattern ice40_wrapcarry + +match carry + select carry->type.in(\SB_CARRY) +endmatch + +match lut + select lut->type.in(\SB_LUT4) + index port(lut, \I1) === port(carry, \I0) + index port(lut, \I2) === port(carry, \I1) +endmatch diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index d069f152a..c606deb88 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -55,7 +55,7 @@ bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, return check_signal(mod, cell->getPort("\\A"), ref, polarity); } - if ((cell->type == "$eq" || cell->type == "$eqx") && cell->getPort("\\Y") == signal) { + if (cell->type.in("$eq", "$eqx") && cell->getPort("\\Y") == signal) { if (cell->getPort("\\A").is_fully_const()) { if (!cell->getPort("\\A").as_bool()) polarity = !polarity; @@ -68,7 +68,7 @@ bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, } } - if ((cell->type == "$ne" || cell->type == "$nex") && cell->getPort("\\Y") == signal) { + if (cell->type.in("$ne", "$nex") && cell->getPort("\\Y") == signal) { if (cell->getPort("\\A").is_fully_const()) { if (cell->getPort("\\A").as_bool()) polarity = !polarity; diff --git a/passes/proc/proc_prune.cc b/passes/proc/proc_prune.cc index 9e00b0a8a..d4aee9df0 100644 --- a/passes/proc/proc_prune.cc +++ b/passes/proc/proc_prune.cc @@ -65,8 +65,7 @@ struct PruneWorker pool sw_assigned = do_switch((*it), assigned, affected); assigned.insert(sw_assigned.begin(), sw_assigned.end()); } - pool remove; - for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ++it) { + for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ) { RTLIL::SigSpec lhs = sigmap(it->first); bool redundant = true; for (auto &bit : lhs) { @@ -75,22 +74,32 @@ struct PruneWorker break; } } + bool remove = false; if (redundant) { removed_count++; - remove.insert(*it); + remove = true; } else { if (root) { bool promotable = true; for (auto &bit : lhs) { - if (bit.wire && affected[bit]) { + if (bit.wire && affected[bit] && !assigned[bit]) { promotable = false; break; } } if (promotable) { + RTLIL::SigSpec rhs = sigmap(it->second); + RTLIL::SigSig conn; + for (int i = 0; i < GetSize(lhs); i++) { + RTLIL::SigBit lhs_bit = lhs[i]; + if (lhs_bit.wire && !assigned[lhs_bit]) { + conn.first.append_bit(lhs_bit); + conn.second.append(rhs.extract(i)); + } + } promoted_count++; - module->connect(*it); - remove.insert(*it); + module->connect(conn); + remove = true; } } for (auto &bit : lhs) @@ -100,11 +109,9 @@ struct PruneWorker if (bit.wire) affected.insert(bit); } - } - for (auto it = cs->actions.begin(); it != cs->actions.end(); ) { - if (remove[*it]) { - it = cs->actions.erase(it); - } else it++; + if (remove) + cs->actions.erase((it++).base() - 1); + else it++; } return assigned; } diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 008cd2dfa..e0bb439f4 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -47,8 +47,8 @@ struct BruteForceEquivChecker { if (inputs.size() < mod1_inputs.size()) { RTLIL::SigSpec inputs0 = inputs, inputs1 = inputs; - inputs0.append(RTLIL::Const(0, 1)); - inputs1.append(RTLIL::Const(1, 1)); + inputs0.append(State::S0); + inputs1.append(State::S1); run_checker(inputs0); run_checker(inputs1); return; diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 71ce1683d..29dfc7b19 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -143,7 +143,7 @@ void create_dff_dq_map(std::map &map, RTLIL::De continue; } - if (info.cell->type == "$_DFF_N_" || info.cell->type == "$_DFF_P_") { + if (info.cell->type.in("$_DFF_N_", "$_DFF_P_")) { info.bit_clk = sigmap(info.cell->getPort("\\C")).as_bit(); info.clk_polarity = info.cell->type == "$_DFF_P_"; info.bit_d = sigmap(info.cell->getPort("\\D")).as_bit(); @@ -151,7 +151,7 @@ void create_dff_dq_map(std::map &map, RTLIL::De continue; } - if (info.cell->type.size() == 10 && info.cell->type.substr(0, 6) == "$_DFF_") { + if (info.cell->type.size() == 10 && info.cell->type.begins_with("$_DFF_")) { info.bit_clk = sigmap(info.cell->getPort("\\C")).as_bit(); info.bit_arst = sigmap(info.cell->getPort("\\R")).as_bit(); info.clk_polarity = info.cell->type[6] == 'P'; diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 1a886af70..49ef40061 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -59,7 +59,7 @@ void create_miter_equiv(struct Pass *that, std::vector args, RTLIL: } break; } - if (argidx+3 != args.size() || args[argidx].substr(0, 1) == "-") + if (argidx+3 != args.size() || args[argidx].compare(0, 1, "-") == 0) that->cmd_error(args, argidx, "command argument error"); RTLIL::IdString gold_name = RTLIL::escape_id(args[argidx++]); @@ -236,7 +236,7 @@ void create_miter_equiv(struct Pass *that, std::vector args, RTLIL: if (flag_make_assert) { RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, "$assert"); assert_cell->setPort("\\A", all_conditions); - assert_cell->setPort("\\EN", RTLIL::SigSpec(1, 1)); + assert_cell->setPort("\\EN", State::S1); } RTLIL::Wire *w_trigger = miter_module->addWire("\\trigger"); @@ -279,7 +279,7 @@ void create_miter_assert(struct Pass *that, std::vector args, RTLIL } break; } - if ((argidx+1 != args.size() && argidx+2 != args.size()) || args[argidx].substr(0, 1) == "-") + if ((argidx+1 != args.size() && argidx+2 != args.size()) || args[argidx].compare(0, 1, "-") == 0) that->cmd_error(args, argidx, "command argument error"); IdString module_name = RTLIL::escape_id(args[argidx++]); diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index e4654d835..dd56d8c71 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -519,7 +519,7 @@ struct SatHelper for (auto &p : d->connections()) { if (d->type == "$dff" && p.first == "\\CLK") continue; - if (d->type.substr(0, 6) == "$_DFF_" && p.first == "\\C") + if (d->type.begins_with("$_DFF_") && p.first == "\\C") continue; queued_signals.add(handled_signals.remove(sigmap(p.second))); } @@ -797,7 +797,7 @@ struct SatHelper vector data; string name = wd.first.c_str(); - while (name.substr(0, 1) == "\\") + while (name.compare(0, 1, "\\") == 0) name = name.substr(1); fprintf(f, " { \"name\": \"%s\", \"wave\": \"", name.c_str()); @@ -1353,7 +1353,7 @@ struct SatPass : public Pass { if (show_regs) { pool reg_wires; for (auto cell : module->cells()) { - if (cell->type == "$dff" || cell->type.substr(0, 6) == "$_DFF_") + if (cell->type == "$dff" || cell->type.begins_with("$_DFF_")) for (auto bit : cell->getPort("\\Q")) if (bit.wire) reg_wires.insert(bit.wire); diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 65c7d1bb8..b29480e26 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -81,6 +82,7 @@ enum class gate_type_t { G_ANDNOT, G_ORNOT, G_MUX, + G_NMUX, G_AOI3, G_OAI3, G_AOI4, @@ -111,7 +113,7 @@ std::vector signal_list; std::map signal_map; std::map signal_init; pool enabled_gates; -bool recover_init; +bool recover_init, cmos_cost; bool clk_polarity, en_polarity; RTLIL::SigSpec clk_sig, en_sig; @@ -164,39 +166,39 @@ void mark_port(RTLIL::SigSpec sig) void extract_cell(RTLIL::Cell *cell, bool keepff) { - if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") + if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) { - if (clk_polarity != (cell->type == "$_DFF_P_")) + if (clk_polarity != (cell->type == ID($_DFF_P_))) return; - if (clk_sig != assign_map(cell->getPort("\\C"))) + if (clk_sig != assign_map(cell->getPort(ID(C)))) return; if (GetSize(en_sig) != 0) return; goto matching_dff; } - if (cell->type == "$_DFFE_NN_" || cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_") + if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) { - if (clk_polarity != (cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_")) + if (clk_polarity != cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_))) return; - if (en_polarity != (cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PP_")) + if (en_polarity != cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_))) return; - if (clk_sig != assign_map(cell->getPort("\\C"))) + if (clk_sig != assign_map(cell->getPort(ID(C)))) return; - if (en_sig != assign_map(cell->getPort("\\E"))) + if (en_sig != assign_map(cell->getPort(ID(E)))) return; goto matching_dff; } if (0) { matching_dff: - RTLIL::SigSpec sig_d = cell->getPort("\\D"); - RTLIL::SigSpec sig_q = cell->getPort("\\Q"); + RTLIL::SigSpec sig_d = cell->getPort(ID(D)); + RTLIL::SigSpec sig_q = cell->getPort(ID(Q)); if (keepff) for (auto &c : sig_q.chunks()) if (c.wire != NULL) - c.wire->attributes["\\keep"] = 1; + c.wire->attributes[ID::keep] = 1; assign_map.apply(sig_d); assign_map.apply(sig_q); @@ -207,25 +209,25 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) return; } - if (cell->type.in("$_BUF_", "$_NOT_")) + if (cell->type.in(ID($_BUF_), ID($_NOT_))) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); assign_map.apply(sig_a); assign_map.apply(sig_y); - map_signal(sig_y, cell->type == "$_BUF_" ? G(BUF) : G(NOT), map_signal(sig_a)); + map_signal(sig_y, cell->type == ID($_BUF_) ? G(BUF) : G(NOT), map_signal(sig_a)); module->remove(cell); return; } - if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_")) + if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -234,21 +236,21 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) int mapped_a = map_signal(sig_a); int mapped_b = map_signal(sig_b); - if (cell->type == "$_AND_") + if (cell->type == ID($_AND_)) map_signal(sig_y, G(AND), mapped_a, mapped_b); - else if (cell->type == "$_NAND_") + else if (cell->type == ID($_NAND_)) map_signal(sig_y, G(NAND), mapped_a, mapped_b); - else if (cell->type == "$_OR_") + else if (cell->type == ID($_OR_)) map_signal(sig_y, G(OR), mapped_a, mapped_b); - else if (cell->type == "$_NOR_") + else if (cell->type == ID($_NOR_)) map_signal(sig_y, G(NOR), mapped_a, mapped_b); - else if (cell->type == "$_XOR_") + else if (cell->type == ID($_XOR_)) map_signal(sig_y, G(XOR), mapped_a, mapped_b); - else if (cell->type == "$_XNOR_") + else if (cell->type == ID($_XNOR_)) map_signal(sig_y, G(XNOR), mapped_a, mapped_b); - else if (cell->type == "$_ANDNOT_") + else if (cell->type == ID($_ANDNOT_)) map_signal(sig_y, G(ANDNOT), mapped_a, mapped_b); - else if (cell->type == "$_ORNOT_") + else if (cell->type == ID($_ORNOT_)) map_signal(sig_y, G(ORNOT), mapped_a, mapped_b); else log_abort(); @@ -257,12 +259,12 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) return; } - if (cell->type == "$_MUX_") + if (cell->type.in(ID($_MUX_), ID($_NMUX_))) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_s = cell->getPort("\\S"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_s = cell->getPort(ID(S)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -273,18 +275,18 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) int mapped_b = map_signal(sig_b); int mapped_s = map_signal(sig_s); - map_signal(sig_y, G(MUX), mapped_a, mapped_b, mapped_s); + map_signal(sig_y, cell->type == ID($_MUX_) ? G(MUX) : G(NMUX), mapped_a, mapped_b, mapped_s); module->remove(cell); return; } - if (cell->type.in("$_AOI3_", "$_OAI3_")) + if (cell->type.in(ID($_AOI3_), ID($_OAI3_))) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_c = cell->getPort("\\C"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_c = cell->getPort(ID(C)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -295,19 +297,19 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) int mapped_b = map_signal(sig_b); int mapped_c = map_signal(sig_c); - map_signal(sig_y, cell->type == "$_AOI3_" ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c); + map_signal(sig_y, cell->type == ID($_AOI3_) ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c); module->remove(cell); return; } - if (cell->type.in("$_AOI4_", "$_OAI4_")) + if (cell->type.in(ID($_AOI4_), ID($_OAI4_))) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_c = cell->getPort("\\C"); - RTLIL::SigSpec sig_d = cell->getPort("\\D"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_c = cell->getPort(ID(C)); + RTLIL::SigSpec sig_d = cell->getPort(ID(D)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -320,7 +322,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) int mapped_c = map_signal(sig_c); int mapped_d = map_signal(sig_d); - map_signal(sig_y, cell->type == "$_AOI4_" ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d); + map_signal(sig_y, cell->type == ID($_AOI4_) ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d); module->remove(cell); return; @@ -331,17 +333,17 @@ std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullp { std::string abc_sname = abc_name.substr(1); bool isnew = false; - if (abc_sname.substr(0, 4) == "new_") + if (abc_sname.compare(0, 4, "new_") == 0) { abc_sname.erase(0, 4); isnew = true; } - if (abc_sname.substr(0, 5) == "ys__n") + if (abc_sname.compare(0, 5, "ys__n") == 0) { abc_sname.erase(0, 5); if (std::isdigit(abc_sname.at(0))) { - int sid = std::stoi(abc_sname); + int sid = std::atoi(abc_sname.c_str()); size_t postfix_start = abc_sname.find_first_not_of("0123456789"); std::string postfix = postfix_start != std::string::npos ? abc_sname.substr(postfix_start) : ""; @@ -350,23 +352,20 @@ std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullp auto sig = signal_list.at(sid); if (sig.bit.wire != nullptr) { - std::stringstream sstr; - sstr << "$abc$" << map_autoidx << "$" << sig.bit.wire->name.substr(1); + std::string s = stringf("$abc$%d$%s", map_autoidx, sig.bit.wire->name.c_str()+1); if (sig.bit.wire->width != 1) - sstr << "[" << sig.bit.offset << "]"; + s += stringf("[%d]", sig.bit.offset); if (isnew) - sstr << "_new"; - sstr << postfix; + s += "_new"; + s += postfix; if (orig_wire != nullptr) *orig_wire = sig.bit.wire; - return sstr.str(); + return s; } } } } - std::stringstream sstr; - sstr << "$abc$" << map_autoidx << "$" << abc_name.substr(1); - return sstr.str(); + return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1); } void dump_loop_graph(FILE *f, int &nr, std::map> &edges, std::set &workpool, std::vector &in_counts) @@ -788,7 +787,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin extract_cell(c, keepff); for (auto &wire_it : module->wires_) { - if (wire_it.second->port_id > 0 || wire_it.second->get_bool_attribute("\\keep")) + if (wire_it.second->port_id > 0 || wire_it.second->get_bool_attribute(ID::keep)) mark_port(RTLIL::SigSpec(wire_it.second)); } @@ -885,6 +884,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin fprintf(f, ".names ys__n%d ys__n%d ys__n%d ys__n%d\n", si.in1, si.in2, si.in3, si.id); fprintf(f, "1-0 1\n"); fprintf(f, "-11 1\n"); + } else if (si.type == G(NMUX)) { + fprintf(f, ".names ys__n%d ys__n%d ys__n%d ys__n%d\n", si.in1, si.in2, si.in3, si.id); + fprintf(f, "0-0 1\n"); + fprintf(f, "-01 1\n"); } else if (si.type == G(AOI3)) { fprintf(f, ".names ys__n%d ys__n%d ys__n%d ys__n%d\n", si.in1, si.in2, si.in3, si.id); fprintf(f, "-00 1\n"); @@ -925,46 +928,50 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin { log_header(design, "Executing ABC.\n"); + auto &cell_cost = cmos_cost ? CellCosts::cmos_gate_cost() : CellCosts::default_gate_cost(); + buffer = stringf("%s/stdcells.genlib", tempdir_name.c_str()); f = fopen(buffer.c_str(), "wt"); if (f == NULL) log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); fprintf(f, "GATE ZERO 1 Y=CONST0;\n"); fprintf(f, "GATE ONE 1 Y=CONST1;\n"); - fprintf(f, "GATE BUF %d Y=A; PIN * NONINV 1 999 1 0 1 0\n", get_cell_cost("$_BUF_")); - fprintf(f, "GATE NOT %d Y=!A; PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_NOT_")); - if (enabled_gates.empty() || enabled_gates.count("AND")) - fprintf(f, "GATE AND %d Y=A*B; PIN * NONINV 1 999 1 0 1 0\n", get_cell_cost("$_AND_")); - if (enabled_gates.empty() || enabled_gates.count("NAND")) - fprintf(f, "GATE NAND %d Y=!(A*B); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_NAND_")); - if (enabled_gates.empty() || enabled_gates.count("OR")) - fprintf(f, "GATE OR %d Y=A+B; PIN * NONINV 1 999 1 0 1 0\n", get_cell_cost("$_OR_")); - if (enabled_gates.empty() || enabled_gates.count("NOR")) - fprintf(f, "GATE NOR %d Y=!(A+B); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_NOR_")); - if (enabled_gates.empty() || enabled_gates.count("XOR")) - fprintf(f, "GATE XOR %d Y=(A*!B)+(!A*B); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_XOR_")); - if (enabled_gates.empty() || enabled_gates.count("XNOR")) - fprintf(f, "GATE XNOR %d Y=(A*B)+(!A*!B); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_XNOR_")); - if (enabled_gates.empty() || enabled_gates.count("ANDNOT")) - fprintf(f, "GATE ANDNOT %d Y=A*!B; PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_ANDNOT_")); - if (enabled_gates.empty() || enabled_gates.count("ORNOT")) - fprintf(f, "GATE ORNOT %d Y=A+!B; PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_ORNOT_")); - if (enabled_gates.empty() || enabled_gates.count("AOI3")) - fprintf(f, "GATE AOI3 %d Y=!((A*B)+C); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_AOI3_")); - if (enabled_gates.empty() || enabled_gates.count("OAI3")) - fprintf(f, "GATE OAI3 %d Y=!((A+B)*C); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_OAI3_")); - if (enabled_gates.empty() || enabled_gates.count("AOI4")) - fprintf(f, "GATE AOI4 %d Y=!((A*B)+(C*D)); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_AOI4_")); - if (enabled_gates.empty() || enabled_gates.count("OAI4")) - fprintf(f, "GATE OAI4 %d Y=!((A+B)*(C+D)); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_OAI4_")); - if (enabled_gates.empty() || enabled_gates.count("MUX")) - fprintf(f, "GATE MUX %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_MUX_")); + fprintf(f, "GATE BUF %d Y=A; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at(ID($_BUF_))); + fprintf(f, "GATE NOT %d Y=!A; PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_NOT_))); + if (enabled_gates.count("AND")) + fprintf(f, "GATE AND %d Y=A*B; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at(ID($_AND_))); + if (enabled_gates.count("NAND")) + fprintf(f, "GATE NAND %d Y=!(A*B); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_NAND_))); + if (enabled_gates.count("OR")) + fprintf(f, "GATE OR %d Y=A+B; PIN * NONINV 1 999 1 0 1 0\n", cell_cost.at(ID($_OR_))); + if (enabled_gates.count("NOR")) + fprintf(f, "GATE NOR %d Y=!(A+B); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_NOR_))); + if (enabled_gates.count("XOR")) + fprintf(f, "GATE XOR %d Y=(A*!B)+(!A*B); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_XOR_))); + if (enabled_gates.count("XNOR")) + fprintf(f, "GATE XNOR %d Y=(A*B)+(!A*!B); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_XNOR_))); + if (enabled_gates.count("ANDNOT")) + fprintf(f, "GATE ANDNOT %d Y=A*!B; PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_ANDNOT_))); + if (enabled_gates.count("ORNOT")) + fprintf(f, "GATE ORNOT %d Y=A+!B; PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_ORNOT_))); + if (enabled_gates.count("AOI3")) + fprintf(f, "GATE AOI3 %d Y=!((A*B)+C); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_AOI3_))); + if (enabled_gates.count("OAI3")) + fprintf(f, "GATE OAI3 %d Y=!((A+B)*C); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_OAI3_))); + if (enabled_gates.count("AOI4")) + fprintf(f, "GATE AOI4 %d Y=!((A*B)+(C*D)); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_AOI4_))); + if (enabled_gates.count("OAI4")) + fprintf(f, "GATE OAI4 %d Y=!((A+B)*(C+D)); PIN * INV 1 999 1 0 1 0\n", cell_cost.at(ID($_OAI4_))); + if (enabled_gates.count("MUX")) + fprintf(f, "GATE MUX %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_MUX_))); + if (enabled_gates.count("NMUX")) + fprintf(f, "GATE NMUX %d Y=!((A*B)+(S*B)+(!S*A)); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_NMUX_))); if (map_mux4) - fprintf(f, "GATE MUX4 %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*get_cell_cost("$_MUX_")); + fprintf(f, "GATE MUX4 %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*cell_cost.at(ID($_MUX_))); if (map_mux8) - fprintf(f, "GATE MUX8 %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*get_cell_cost("$_MUX_")); + fprintf(f, "GATE MUX8 %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*cell_cost.at(ID($_MUX_))); if (map_mux16) - fprintf(f, "GATE MUX16 %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*get_cell_cost("$_MUX_")); + fprintf(f, "GATE MUX16 %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*cell_cost.at(ID($_MUX_))); fclose(f); if (!lut_costs.empty()) { @@ -1009,21 +1016,21 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin bool builtin_lib = liberty_file.empty(); RTLIL::Design *mapped_design = new RTLIL::Design; - parse_blif(mapped_design, ifs, builtin_lib ? "\\DFF" : "\\_dff_", false, sop_mode); + parse_blif(mapped_design, ifs, builtin_lib ? ID(DFF) : ID(_dff_), false, sop_mode); ifs.close(); log_header(design, "Re-integrating ABC results.\n"); - RTLIL::Module *mapped_mod = mapped_design->modules_["\\netlist"]; + RTLIL::Module *mapped_mod = mapped_design->modules_[ID(netlist)]; if (mapped_mod == NULL) log_error("ABC output file does not contain a module `netlist'.\n"); for (auto &it : mapped_mod->wires_) { RTLIL::Wire *w = it.second; RTLIL::Wire *orig_wire = nullptr; RTLIL::Wire *wire = module->addWire(remap_name(w->name, &orig_wire)); - if (orig_wire != nullptr && orig_wire->attributes.count("\\src")) - wire->attributes["\\src"] = orig_wire->attributes["\\src"]; - if (markgroups) wire->attributes["\\abcgroup"] = map_autoidx; + if (orig_wire != nullptr && orig_wire->attributes.count(ID(src))) + wire->attributes[ID(src)] = orig_wire->attributes[ID(src)]; + if (markgroups) wire->attributes[ID(abcgroup)] = map_autoidx; design->select(module, wire); } @@ -1033,141 +1040,140 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin if (builtin_lib) { cell_stats[RTLIL::unescape_id(c->type)]++; - if (c->type == "\\ZERO" || c->type == "\\ONE") { + if (c->type.in(ID(ZERO), ID(ONE))) { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]); - conn.second = RTLIL::SigSpec(c->type == "\\ZERO" ? 0 : 1, 1); + conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]); + conn.second = RTLIL::SigSpec(c->type == ID(ZERO) ? 0 : 1, 1); module->connect(conn); continue; } - if (c->type == "\\BUF") { + if (c->type == ID(BUF)) { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]); - conn.second = RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]); + conn.second = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]); module->connect(conn); continue; } - if (c->type == "\\NOT") { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_NOT_"); - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; - cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); - cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); + if (c->type == ID(NOT)) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_NOT_)); + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } - if (c->type == "\\AND" || c->type == "\\OR" || c->type == "\\XOR" || c->type == "\\NAND" || c->type == "\\NOR" || - c->type == "\\XNOR" || c->type == "\\ANDNOT" || c->type == "\\ORNOT") { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; - cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); - cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); - cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); + if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } - if (c->type == "\\MUX") { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX_"); - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; - cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); - cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); - cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); - cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); + if (c->type.in(ID(MUX), ID(NMUX))) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); + cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } - if (c->type == "\\MUX4") { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX4_"); - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; - cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); - cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); - cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); - cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); - cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); - cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)])); - cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); + if (c->type == ID(MUX4)) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_)); + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); + cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)])); + cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)])); + cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)])); + cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } - if (c->type == "\\MUX8") { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX8_"); - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; - cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); - cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); - cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); - cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); - cell->setPort("\\E", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\E").as_wire()->name)])); - cell->setPort("\\F", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\F").as_wire()->name)])); - cell->setPort("\\G", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\G").as_wire()->name)])); - cell->setPort("\\H", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\H").as_wire()->name)])); - cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); - cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)])); - cell->setPort("\\U", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\U").as_wire()->name)])); - cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); + if (c->type == ID(MUX8)) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_)); + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); + cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)])); + cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)])); + cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)])); + cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)])); + cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)])); + cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)])); + cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)])); + cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)])); + cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } - if (c->type == "\\MUX16") { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX16_"); - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; - cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); - cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); - cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); - cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); - cell->setPort("\\E", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\E").as_wire()->name)])); - cell->setPort("\\F", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\F").as_wire()->name)])); - cell->setPort("\\G", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\G").as_wire()->name)])); - cell->setPort("\\H", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\H").as_wire()->name)])); - cell->setPort("\\I", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\I").as_wire()->name)])); - cell->setPort("\\J", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\J").as_wire()->name)])); - cell->setPort("\\K", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\K").as_wire()->name)])); - cell->setPort("\\L", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\L").as_wire()->name)])); - cell->setPort("\\M", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\M").as_wire()->name)])); - cell->setPort("\\N", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\N").as_wire()->name)])); - cell->setPort("\\O", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\O").as_wire()->name)])); - cell->setPort("\\P", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\P").as_wire()->name)])); - cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); - cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)])); - cell->setPort("\\U", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\U").as_wire()->name)])); - cell->setPort("\\V", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\V").as_wire()->name)])); - cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); + if (c->type == ID(MUX16)) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_)); + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); + cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)])); + cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)])); + cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)])); + cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)])); + cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)])); + cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)])); + cell->setPort(ID(I), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(I)).as_wire()->name)])); + cell->setPort(ID(J), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(J)).as_wire()->name)])); + cell->setPort(ID(K), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(K)).as_wire()->name)])); + cell->setPort(ID(L), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(L)).as_wire()->name)])); + cell->setPort(ID(M), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(M)).as_wire()->name)])); + cell->setPort(ID(N), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(N)).as_wire()->name)])); + cell->setPort(ID(O), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(O)).as_wire()->name)])); + cell->setPort(ID(P), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(P)).as_wire()->name)])); + cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)])); + cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)])); + cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)])); + cell->setPort(ID(V), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(V)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } - if (c->type == "\\AOI3" || c->type == "\\OAI3") { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; - cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); - cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); - cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); - cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); + if (c->type.in(ID(AOI3), ID(OAI3))) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); + cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } - if (c->type == "\\AOI4" || c->type == "\\OAI4") { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; - cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); - cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); - cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); - cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); - cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); + if (c->type.in(ID(AOI4), ID(OAI4))) { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); + cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)])); + cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } - if (c->type == "\\DFF") { + if (c->type == ID(DFF)) { log_assert(clk_sig.size() == 1); RTLIL::Cell *cell; if (en_sig.size() == 0) { - cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); + cell = module->addCell(remap_name(c->name), clk_polarity ? ID($_DFF_P_) : ID($_DFF_N_)); } else { log_assert(en_sig.size() == 1); cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); - cell->setPort("\\E", en_sig); + cell->setPort(ID(E), en_sig); } - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; - cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); - cell->setPort("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Q").as_wire()->name)])); - cell->setPort("\\C", clk_sig); + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)])); + cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)])); + cell->setPort(ID(C), clk_sig); design->select(module, cell); continue; } @@ -1175,41 +1181,41 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin else cell_stats[RTLIL::unescape_id(c->type)]++; - if (c->type == "\\_const0_" || c->type == "\\_const1_") { + if (c->type.in(ID(_const0_), ID(_const1_))) { RTLIL::SigSig conn; conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->connections().begin()->second.as_wire()->name)]); - conn.second = RTLIL::SigSpec(c->type == "\\_const0_" ? 0 : 1, 1); + conn.second = RTLIL::SigSpec(c->type == ID(_const0_) ? 0 : 1, 1); module->connect(conn); continue; } - if (c->type == "\\_dff_") { + if (c->type == ID(_dff_)) { log_assert(clk_sig.size() == 1); RTLIL::Cell *cell; if (en_sig.size() == 0) { - cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); + cell = module->addCell(remap_name(c->name), clk_polarity ? ID($_DFF_P_) : ID($_DFF_N_)); } else { log_assert(en_sig.size() == 1); cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); - cell->setPort("\\E", en_sig); + cell->setPort(ID(E), en_sig); } - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; - cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); - cell->setPort("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Q").as_wire()->name)])); - cell->setPort("\\C", clk_sig); + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; + cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)])); + cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)])); + cell->setPort(ID(C), clk_sig); design->select(module, cell); continue; } - if (c->type == "$lut" && GetSize(c->getPort("\\A")) == 1 && c->getParam("\\LUT").as_int() == 2) { - SigSpec my_a = module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]; - SigSpec my_y = module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]; + if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)).as_int() == 2) { + SigSpec my_a = module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]; + SigSpec my_y = module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]; module->connect(my_y, my_a); continue; } RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type); - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; cell->parameters = c->parameters; for (auto &conn : c->connections()) { RTLIL::SigSpec newsig; @@ -1234,10 +1240,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin if (recover_init) for (auto wire : mapped_mod->wires()) { - if (wire->attributes.count("\\init")) { + if (wire->attributes.count(ID(init))) { Wire *w = module->wires_[remap_name(wire->name)]; - log_assert(w->attributes.count("\\init") == 0); - w->attributes["\\init"] = wire->attributes.at("\\init"); + log_assert(w->attributes.count(ID(init)) == 0); + w->attributes[ID(init)] = wire->attributes.at(ID(init)); } } @@ -1401,20 +1407,27 @@ struct AbcPass : public Pass { // log("\n"); log(" -g type1,type2,...\n"); log(" Map to the specified list of gate types. Supported gates types are:\n"); - log(" AND, NAND, OR, NOR, XOR, XNOR, ANDNOT, ORNOT, MUX, AOI3, OAI3, AOI4, OAI4.\n"); + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log(" AND, NAND, OR, NOR, XOR, XNOR, ANDNOT, ORNOT, MUX,\n"); + log(" NMUX, AOI3, OAI3, AOI4, OAI4.\n"); log(" (The NOT gate is always added to this list automatically.)\n"); log("\n"); log(" The following aliases can be used to reference common sets of gate types:\n"); log(" simple: AND OR XOR MUX\n"); - log(" cmos2: NAND NOR\n"); - log(" cmos3: NAND NOR AOI3 OAI3\n"); - log(" cmos4: NAND NOR AOI3 OAI3 AOI4 OAI4\n"); - log(" gates: AND NAND OR NOR XOR XNOR ANDNOT ORNOT\n"); - log(" aig: AND NAND OR NOR ANDNOT ORNOT\n"); + log(" cmos2: NAND NOR\n"); + log(" cmos3: NAND NOR AOI3 OAI3\n"); + log(" cmos4: NAND NOR AOI3 OAI3 AOI4 OAI4\n"); + log(" cmos: NAND NOR AOI3 OAI3 AOI4 OAI4 NMUX MUX XOR XNOR\n"); + log(" gates: AND NAND OR NOR XOR XNOR ANDNOT ORNOT\n"); + log(" aig: AND NAND OR NOR ANDNOT ORNOT\n"); + log("\n"); + log(" The alias 'all' represent the full set of all gate types.\n"); log("\n"); log(" Prefix a gate type with a '-' to remove it from the list. For example\n"); log(" the arguments 'AND,OR,XOR' and 'simple,-MUX' are equivalent.\n"); log("\n"); + log(" The default is 'all,-NMUX,-AOI3,-OAI3,-AOI4,-OAI4'.\n"); + log("\n"); log(" -dff\n"); log(" also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); log(" clock domains are automatically partitioned in clock domains and each\n"); @@ -1488,6 +1501,7 @@ struct AbcPass : public Pass { map_mux8 = false; map_mux16 = false; enabled_gates.clear(); + cmos_cost = false; #ifdef _WIN32 #ifndef ABCEXTERNAL @@ -1572,7 +1586,7 @@ struct AbcPass : public Pass { else if (GetSize(parts) == 1) lut_costs.push_back(atoi(parts.at(0).c_str())); else if (GetSize(parts) == 2) - while (GetSize(lut_costs) < atoi(parts.at(0).c_str())) + while (GetSize(lut_costs) < std::atoi(parts.at(0).c_str())) lut_costs.push_back(atoi(parts.at(1).c_str())); else log_cmd_error("Invalid -luts syntax.\n"); @@ -1616,6 +1630,7 @@ struct AbcPass : public Pass { if (g == "ANDNOT") goto ok_gate; if (g == "ORNOT") goto ok_gate; if (g == "MUX") goto ok_gate; + if (g == "NMUX") goto ok_gate; if (g == "AOI3") goto ok_gate; if (g == "OAI3") goto ok_gate; if (g == "AOI4") goto ok_gate; @@ -1628,11 +1643,15 @@ struct AbcPass : public Pass { goto ok_alias; } if (g == "cmos2") { + if (!remove_gates) + cmos_cost = true; gate_list.push_back("NAND"); gate_list.push_back("NOR"); goto ok_alias; } if (g == "cmos3") { + if (!remove_gates) + cmos_cost = true; gate_list.push_back("NAND"); gate_list.push_back("NOR"); gate_list.push_back("AOI3"); @@ -1640,6 +1659,8 @@ struct AbcPass : public Pass { goto ok_alias; } if (g == "cmos4") { + if (!remove_gates) + cmos_cost = true; gate_list.push_back("NAND"); gate_list.push_back("NOR"); gate_list.push_back("AOI3"); @@ -1648,6 +1669,21 @@ struct AbcPass : public Pass { gate_list.push_back("OAI4"); goto ok_alias; } + if (g == "cmos") { + if (!remove_gates) + cmos_cost = true; + gate_list.push_back("NAND"); + gate_list.push_back("NOR"); + gate_list.push_back("AOI3"); + gate_list.push_back("OAI3"); + gate_list.push_back("AOI4"); + gate_list.push_back("OAI4"); + gate_list.push_back("NMUX"); + gate_list.push_back("MUX"); + gate_list.push_back("XOR"); + gate_list.push_back("XNOR"); + goto ok_alias; + } if (g == "gates") { gate_list.push_back("AND"); gate_list.push_back("NAND"); @@ -1668,6 +1704,22 @@ struct AbcPass : public Pass { gate_list.push_back("ORNOT"); goto ok_alias; } + if (g == "all") { + gate_list.push_back("AND"); + gate_list.push_back("NAND"); + gate_list.push_back("OR"); + gate_list.push_back("NOR"); + gate_list.push_back("XOR"); + gate_list.push_back("XNOR"); + gate_list.push_back("ANDNOT"); + gate_list.push_back("ORNOT"); + gate_list.push_back("AOI3"); + gate_list.push_back("OAI3"); + gate_list.push_back("AOI4"); + gate_list.push_back("OAI4"); + gate_list.push_back("MUX"); + gate_list.push_back("NMUX"); + } cmd_error(args, argidx, stringf("Unsupported gate type: %s", g.c_str())); ok_gate: gate_list.push_back(g); @@ -1719,6 +1771,23 @@ struct AbcPass : public Pass { if (!constr_file.empty() && liberty_file.empty()) log_cmd_error("Got -constr but no -liberty!\n"); + if (enabled_gates.empty()) { + enabled_gates.insert("AND"); + enabled_gates.insert("NAND"); + enabled_gates.insert("OR"); + enabled_gates.insert("NOR"); + enabled_gates.insert("XOR"); + enabled_gates.insert("XNOR"); + enabled_gates.insert("ANDNOT"); + enabled_gates.insert("ORNOT"); + // enabled_gates.insert("AOI3"); + // enabled_gates.insert("OAI3"); + // enabled_gates.insert("AOI4"); + // enabled_gates.insert("OAI4"); + enabled_gates.insert("MUX"); + // enabled_gates.insert("NMUX"); + } + for (auto mod : design->selected_modules()) { if (mod->processes.size() > 0) { @@ -1730,9 +1799,9 @@ struct AbcPass : public Pass { signal_init.clear(); for (Wire *wire : mod->wires()) - if (wire->attributes.count("\\init")) { + if (wire->attributes.count(ID(init))) { SigSpec initsig = assign_map(wire); - Const initval = wire->attributes.at("\\init"); + Const initval = wire->attributes.at(ID(init)); for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++) switch (initval[i]) { case State::S0: @@ -1789,16 +1858,16 @@ struct AbcPass : public Pass { } } - if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") + if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) { - key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\C")), true, RTLIL::SigSpec()); + key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); } else - if (cell->type == "$_DFFE_NN_" || cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_") + if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) { - bool this_clk_pol = cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_"; - bool this_en_pol = cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PP_"; - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort("\\C")), this_en_pol, assign_map(cell->getPort("\\E"))); + bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); + bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E)))); } else continue; diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 658bb1225..c1d4fff2d 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -71,25 +71,23 @@ RTLIL::Module *module; bool clk_polarity, en_polarity; RTLIL::SigSpec clk_sig, en_sig; -std::string remap_name(RTLIL::IdString abc_name) +inline std::string remap_name(RTLIL::IdString abc_name) { - std::stringstream sstr; - sstr << "$abc$" << map_autoidx << "$" << abc_name.substr(1); - return sstr.str(); + return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1); } void handle_loops(RTLIL::Design *design) { Pass::call(design, "scc -set_attr abc_scc_id {}"); - dict> abc_scc_break; + dict> abc_scc_break; // For every unique SCC found, (arbitrarily) find the first // cell in the component, and select (and mark) all its output // wires pool ids_seen; for (auto cell : module->cells()) { - auto it = cell->attributes.find("\\abc_scc_id"); + auto it = cell->attributes.find(ID(abc_scc_id)); if (it != cell->attributes.end()) { auto r = ids_seen.insert(it->second); if (r.second) { @@ -109,7 +107,7 @@ void handle_loops(RTLIL::Design *design) log_assert(w->port_input); log_assert(b.offset < GetSize(w)); } - w->set_bool_attribute("\\abc_scc_break"); + w->set_bool_attribute(ID(abc_scc_break)); module->swap_names(b.wire, w); c.second = RTLIL::SigBit(w, b.offset); } @@ -123,7 +121,7 @@ void handle_loops(RTLIL::Design *design) std::vector ports; RTLIL::Module* box_module = design->module(cell->type); if (box_module) { - auto ports_csv = box_module->attributes.at("\\abc_scc_break", RTLIL::Const::from_string("")).decode_string(); + auto ports_csv = box_module->attributes.at(ID(abc_scc_break), RTLIL::Const::from_string("")).decode_string(); for (const auto &port_name : split_tokens(ports_csv, ",")) { auto port_id = RTLIL::escape_id(port_name); auto kt = cell->connections_.find(port_id); @@ -142,7 +140,7 @@ void handle_loops(RTLIL::Design *design) Wire *w = b.wire; if (!w) continue; w->port_output = true; - w->set_bool_attribute("\\abc_scc_break"); + w->set_bool_attribute(ID(abc_scc_break)); w = module->wire(stringf("%s.abci", w->name.c_str())); if (!w) { w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire)); @@ -290,7 +288,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, bool show_tempdir, std::string box_file, std::string lut_file, - std::string wire_delay) + std::string wire_delay, const dict &box_lookup) { module = current_module; map_autoidx = autoidx++; @@ -429,10 +427,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::Selection& sel = design->selection_stack.back(); sel.select(module); - Pass::call(design, "aigmap"); - handle_loops(design); + Pass::call(design, "aigmap"); + //log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n", // count_gates, GetSize(signal_list), count_input, count_output); @@ -446,14 +444,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (ifs.fail()) log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); - log_assert(!design->module("$__abc9__")); + log_assert(!design->module(ID($__abc9__))); { - AigerReader reader(design, ifs, "$__abc9__", "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); + AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); reader.parse_xaiger(); } ifs.close(); Pass::call(design, stringf("write_verilog -noexpr -norename")); - design->remove(design->module("$__abc9__")); + design->remove(design->module(ID($__abc9__))); #endif design->selection_stack.pop_back(); @@ -462,7 +460,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri // the expose operation -- remove them from PO/PI // and re-connecting them back together for (auto wire : module->wires()) { - auto it = wire->attributes.find("\\abc_scc_break"); + auto it = wire->attributes.find(ID(abc_scc_break)); if (it != wire->attributes.end()) { wire->attributes.erase(it); log_assert(wire->port_output); @@ -476,7 +474,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } module->fixup_ports(); - log_header(design, "Executing ABC9.\n"); if (!lut_costs.empty()) { @@ -519,9 +516,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); - log_assert(!design->module("$__abc9__")); - AigerReader reader(design, ifs, "$__abc9__", "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); - reader.parse_xaiger(); + log_assert(!design->module(ID($__abc9__))); + + AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); + reader.parse_xaiger(box_lookup); ifs.close(); #if 0 @@ -529,7 +527,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri #endif log_header(design, "Re-integrating ABC9 results.\n"); - RTLIL::Module *mapped_mod = design->module("$__abc9__"); + RTLIL::Module *mapped_mod = design->module(ID($__abc9__)); if (mapped_mod == NULL) log_error("ABC output file does not contain a module `$__abc9__'.\n"); @@ -537,7 +535,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (auto &it : mapped_mod->wires_) { RTLIL::Wire *w = it.second; RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w)); - if (markgroups) remap_wire->attributes["\\abcgroup"] = map_autoidx; + if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; if (w->port_output) { RTLIL::Wire *wire = module->wire(w->name); log_assert(wire); @@ -559,14 +557,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri vector boxes; for (const auto &it : module->cells_) { auto cell = it.second; - if (cell->type.in("$_AND_", "$_NOT_")) { + if (cell->type.in(ID($_AND_), ID($_NOT_))) { module->remove(cell); continue; } auto jt = abc_box.find(cell->type); if (jt == abc_box.end()) { RTLIL::Module* box_module = design->module(cell->type); - jt = abc_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count("\\abc_box_id"))).first; + jt = abc_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc_box_id)))).first; } if (jt->second) boxes.emplace_back(cell); @@ -577,23 +575,23 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri dict not2drivers; dict> bit2sinks; - std::map cell_stats; + std::map cell_stats; for (auto c : mapped_mod->cells()) { toposort.node(c->name); RTLIL::Cell *cell = nullptr; - if (c->type == "$_NOT_") { - RTLIL::SigBit a_bit = c->getPort("\\A"); - RTLIL::SigBit y_bit = c->getPort("\\Y"); + if (c->type == ID($_NOT_)) { + RTLIL::SigBit a_bit = c->getPort(ID::A); + RTLIL::SigBit y_bit = c->getPort(ID::Y); bit_users[a_bit].insert(c->name); bit_drivers[y_bit].insert(c->name); if (!a_bit.wire) { - c->setPort("\\Y", module->addWire(NEW_ID)); + c->setPort(ID::Y, module->addWire(NEW_ID)); RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); log_assert(wire); - module->connect(RTLIL::SigBit(wire, y_bit.offset), RTLIL::S1); + module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1); } else if (!lut_costs.empty() || !lut_file.empty()) { RTLIL::Cell* driver_lut = nullptr; @@ -618,8 +616,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset), RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), RTLIL::Const::from_string("01")); - bit2sinks[cell->getPort("\\A")].push_back(cell); - cell_stats["$lut"]++; + bit2sinks[cell->getPort(ID::A)].push_back(cell); + cell_stats[ID($lut)]++; } else not2drivers[c] = driver_lut; @@ -627,18 +625,18 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } else log_abort(); - if (cell && markgroups) cell->attributes["\\abcgroup"] = map_autoidx; + if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; continue; } - cell_stats[RTLIL::unescape_id(c->type)]++; + cell_stats[c->type]++; RTLIL::Cell *existing_cell = nullptr; - if (c->type == "$lut") { - if (GetSize(c->getPort("\\A")) == 1 && c->getParam("\\LUT") == RTLIL::Const::from_string("01")) { - SigSpec my_a = module->wires_.at(remap_name(c->getPort("\\A").as_wire()->name)); - SigSpec my_y = module->wires_.at(remap_name(c->getPort("\\Y").as_wire()->name)); + if (c->type == ID($lut)) { + if (GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { + SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID::A).as_wire()->name)); + SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID::Y).as_wire()->name)); module->connect(my_y, my_a); - if (markgroups) c->attributes["\\abcgroup"] = map_autoidx; + if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx; log_abort(); continue; } @@ -646,11 +644,12 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } else { existing_cell = module->cell(c->name); + log_assert(existing_cell); cell = module->addCell(remap_name(c->name), c->type); module->swap_names(cell, existing_cell); } - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; if (existing_cell) { cell->parameters = existing_cell->parameters; cell->attributes = existing_cell->attributes; @@ -740,20 +739,20 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (auto driver_cell : bit_drivers.at(it.first)) for (auto user_cell : it.second) toposort.edge(driver_cell, user_cell); - bool no_loops = toposort.sort(); + bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); log_assert(no_loops); for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { RTLIL::Cell *not_cell = mapped_mod->cell(*ii); log_assert(not_cell); - if (not_cell->type != "$_NOT_") + if (not_cell->type != ID($_NOT_)) continue; auto it = not2drivers.find(not_cell); if (it == not2drivers.end()) continue; RTLIL::Cell *driver_lut = it->second; - RTLIL::SigBit a_bit = not_cell->getPort("\\A"); - RTLIL::SigBit y_bit = not_cell->getPort("\\Y"); + RTLIL::SigBit a_bit = not_cell->getPort(ID::A); + RTLIL::SigBit y_bit = not_cell->getPort(ID::Y); RTLIL::Const driver_mask; a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); @@ -764,13 +763,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri goto clone_lut; for (auto sink_cell : jt->second) - if (sink_cell->type != "$lut") + if (sink_cell->type != ID($lut)) goto clone_lut; // Push downstream LUTs past inverter for (auto sink_cell : jt->second) { - SigSpec A = sink_cell->getPort("\\A"); - RTLIL::Const mask = sink_cell->getParam("\\LUT"); + SigSpec A = sink_cell->getPort(ID::A); + RTLIL::Const mask = sink_cell->getParam(ID(LUT)); int index = 0; for (; index < GetSize(A); index++) if (A[index] == a_bit) @@ -783,8 +782,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri i += 1 << (index+1); } A[index] = y_bit; - sink_cell->setPort("\\A", A); - sink_cell->setParam("\\LUT", mask); + sink_cell->setPort(ID::A, A); + sink_cell->setParam(ID(LUT), mask); } // Since we have rewritten all sinks (which we know @@ -793,16 +792,16 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri // that the original driving LUT will become dangling // and get cleaned away clone_lut: - driver_mask = driver_lut->getParam("\\LUT"); + driver_mask = driver_lut->getParam(ID(LUT)); for (auto &b : driver_mask.bits) { if (b == RTLIL::State::S0) b = RTLIL::State::S1; else if (b == RTLIL::State::S1) b = RTLIL::State::S0; } auto cell = module->addLut(NEW_ID, - driver_lut->getPort("\\A"), + driver_lut->getPort(ID::A), y_bit, driver_mask); - for (auto &bit : cell->connections_.at("\\A")) { + for (auto &bit : cell->connections_.at(ID::A)) { bit.wire = module->wires_.at(remap_name(bit.wire->name)); bit2sinks[bit].push_back(cell); } @@ -1081,9 +1080,24 @@ struct Abc9Pass : public Pass { } extra_args(args, argidx, design); + dict box_lookup; + for (auto m : design->modules()) { + auto it = m->attributes.find(ID(abc_box_id)); + if (it == m->attributes.end()) + continue; + if (m->name.begins_with("$paramod")) + continue; + auto id = it->second.as_int(); + auto r = box_lookup.insert(std::make_pair(id, m->name)); + if (!r.second) + log_error("Module '%s' has the same abc_box_id = %d value as '%s'.\n", + log_id(m), id, log_id(r.first->second)); + log_assert(r.second); + } + for (auto mod : design->selected_modules()) { - if (mod->attributes.count("\\abc_box_id")) + if (mod->attributes.count(ID(abc_box_id))) continue; if (mod->processes.size() > 0) { @@ -1096,7 +1110,7 @@ struct Abc9Pass : public Pass { if (!dff_mode || !clk_str.empty()) { abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff, delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay); + box_file, lut_file, wire_delay, box_lookup); continue; } @@ -1137,16 +1151,16 @@ struct Abc9Pass : public Pass { } } - if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") + if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) { - key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\C")), true, RTLIL::SigSpec()); + key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); } else - if (cell->type == "$_DFFE_NN_" || cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_") + if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) { - bool this_clk_pol = cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_"; - bool this_en_pol = cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PP_"; - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort("\\C")), this_en_pol, assign_map(cell->getPort("\\E"))); + bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); + bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E)))); } else continue; @@ -1242,15 +1256,16 @@ struct Abc9Pass : public Pass { en_sig = assign_map(std::get<3>(it.first)); abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$", keepff, delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay); + box_file, lut_file, wire_delay, box_lookup); assign_map.set(mod); } } - Pass::call(design, "clean"); - assign_map.clear(); + // The "clean" pass also contains a design->check() call + Pass::call(design, "clean"); + log_pop(); } } Abc9Pass; diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index 35df2ff79..1d5e1286b 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -66,10 +66,10 @@ struct AigmapPass : public Pass { { Aig aig(cell); - if (cell->type == "$_AND_" || cell->type == "$_NOT_") + if (cell->type.in(ID($_AND_), ID($_NOT_))) aig.name.clear(); - if (nand_mode && cell->type == "$_NAND_") + if (nand_mode && cell->type == ID($_NAND_)) aig.name.clear(); if (aig.name.empty()) { diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index dc7d416b0..5b168d524 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -61,7 +61,7 @@ struct AlumaccWorker RTLIL::SigSpec get_eq() { if (GetSize(cached_eq) == 0) - cached_eq = alu_cell->module->ReduceAnd(NEW_ID, alu_cell->getPort("\\X"), false, alu_cell->get_src_attribute()); + cached_eq = alu_cell->module->ReduceAnd(NEW_ID, alu_cell->getPort(ID(X)), false, alu_cell->get_src_attribute()); return cached_eq; } @@ -73,7 +73,7 @@ struct AlumaccWorker RTLIL::SigSpec get_cf() { if (GetSize(cached_cf) == 0) { - cached_cf = alu_cell->getPort("\\CO"); + cached_cf = alu_cell->getPort(ID(CO)); log_assert(GetSize(cached_cf) >= 1); cached_cf = alu_cell->module->Not(NEW_ID, cached_cf[GetSize(cached_cf)-1], false, alu_cell->get_src_attribute()); } @@ -82,7 +82,7 @@ struct AlumaccWorker RTLIL::SigSpec get_of() { if (GetSize(cached_of) == 0) { - cached_of = {alu_cell->getPort("\\CO"), alu_cell->getPort("\\CI")}; + cached_of = {alu_cell->getPort(ID(CO)), alu_cell->getPort(ID(CI))}; log_assert(GetSize(cached_of) >= 2); cached_of = alu_cell->module->Xor(NEW_ID, cached_of[GetSize(cached_of)-1], cached_of[GetSize(cached_of)-2]); } @@ -91,7 +91,7 @@ struct AlumaccWorker RTLIL::SigSpec get_sf() { if (GetSize(cached_sf) == 0) { - cached_sf = alu_cell->getPort("\\Y"); + cached_sf = alu_cell->getPort(ID::Y); cached_sf = cached_sf[GetSize(cached_sf)-1]; } return cached_sf; @@ -125,7 +125,7 @@ struct AlumaccWorker { for (auto cell : module->selected_cells()) { - if (!cell->type.in("$pos", "$neg", "$add", "$sub", "$mul")) + if (!cell->type.in(ID($pos), ID($neg), ID($add), ID($sub), ID($mul))) continue; log(" creating $macc model for %s (%s).\n", log_id(cell), log_id(cell->type)); @@ -134,38 +134,38 @@ struct AlumaccWorker Macc::port_t new_port; n->cell = cell; - n->y = sigmap(cell->getPort("\\Y")); + n->y = sigmap(cell->getPort(ID::Y)); n->users = 0; for (auto bit : n->y) n->users = max(n->users, bit_users.at(bit) - 1); - if (cell->type.in("$pos", "$neg")) + if (cell->type.in(ID($pos), ID($neg))) { - new_port.in_a = sigmap(cell->getPort("\\A")); - new_port.is_signed = cell->getParam("\\A_SIGNED").as_bool(); - new_port.do_subtract = cell->type == "$neg"; + new_port.in_a = sigmap(cell->getPort(ID::A)); + new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); + new_port.do_subtract = cell->type == ID($neg); n->macc.ports.push_back(new_port); } - if (cell->type.in("$add", "$sub")) + if (cell->type.in(ID($add), ID($sub))) { - new_port.in_a = sigmap(cell->getPort("\\A")); - new_port.is_signed = cell->getParam("\\A_SIGNED").as_bool(); + new_port.in_a = sigmap(cell->getPort(ID::A)); + new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); new_port.do_subtract = false; n->macc.ports.push_back(new_port); - new_port.in_a = sigmap(cell->getPort("\\B")); - new_port.is_signed = cell->getParam("\\B_SIGNED").as_bool(); - new_port.do_subtract = cell->type == "$sub"; + new_port.in_a = sigmap(cell->getPort(ID::B)); + new_port.is_signed = cell->getParam(ID(B_SIGNED)).as_bool(); + new_port.do_subtract = cell->type == ID($sub); n->macc.ports.push_back(new_port); } - if (cell->type.in("$mul")) + if (cell->type.in(ID($mul))) { - new_port.in_a = sigmap(cell->getPort("\\A")); - new_port.in_b = sigmap(cell->getPort("\\B")); - new_port.is_signed = cell->getParam("\\A_SIGNED").as_bool(); + new_port.in_a = sigmap(cell->getPort(ID::A)); + new_port.in_b = sigmap(cell->getPort(ID::B)); + new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); new_port.do_subtract = false; n->macc.ports.push_back(new_port); } @@ -315,7 +315,7 @@ struct AlumaccWorker } if (subtract_b) - C.append(RTLIL::S1); + C.append(State::S1); if (GetSize(C) > 1) goto next_macc; @@ -351,7 +351,7 @@ struct AlumaccWorker for (auto &it : sig_macc) { auto n = it.second; - auto cell = module->addCell(NEW_ID, "$macc"); + auto cell = module->addCell(NEW_ID, ID($macc)); macc_counter++; @@ -361,7 +361,7 @@ struct AlumaccWorker n->macc.optimize(GetSize(n->y)); n->macc.to_cell(cell); - cell->setPort("\\Y", n->y); + cell->setPort(ID::Y, n->y); cell->fixup_parameters(); module->remove(n->cell); delete n; @@ -376,9 +376,9 @@ struct AlumaccWorker for (auto cell : module->selected_cells()) { - if (cell->type.in("$lt", "$le", "$ge", "$gt")) + if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt))) lge_cells.push_back(cell); - if (cell->type.in("$eq", "$eqx", "$ne", "$nex")) + if (cell->type.in(ID($eq), ID($eqx), ID($ne), ID($nex))) eq_cells.push_back(cell); } @@ -386,13 +386,13 @@ struct AlumaccWorker { log(" creating $alu model for %s (%s):", log_id(cell), log_id(cell->type)); - bool cmp_less = cell->type.in("$lt", "$le"); - bool cmp_equal = cell->type.in("$le", "$ge"); - bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + bool cmp_less = cell->type.in(ID($lt), ID($le)); + bool cmp_equal = cell->type.in(ID($le), ID($ge)); + bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); - RTLIL::SigSpec A = sigmap(cell->getPort("\\A")); - RTLIL::SigSpec B = sigmap(cell->getPort("\\B")); - RTLIL::SigSpec Y = sigmap(cell->getPort("\\Y")); + RTLIL::SigSpec A = sigmap(cell->getPort(ID::A)); + RTLIL::SigSpec B = sigmap(cell->getPort(ID::B)); + RTLIL::SigSpec Y = sigmap(cell->getPort(ID::Y)); if (B < A && GetSize(B)) { cmp_less = !cmp_less; @@ -402,7 +402,7 @@ struct AlumaccWorker alunode_t *n = nullptr; for (auto node : sig_alu[RTLIL::SigSig(A, B)]) - if (node->is_signed == is_signed && node->invert_b && node->c == RTLIL::S1) { + if (node->is_signed == is_signed && node->invert_b && node->c == State::S1) { n = node; break; } @@ -411,7 +411,7 @@ struct AlumaccWorker n = new alunode_t; n->a = A; n->b = B; - n->c = RTLIL::S1; + n->c = State::S1; n->y = module->addWire(NEW_ID, max(GetSize(A), GetSize(B))); n->is_signed = is_signed; n->invert_b = true; @@ -427,12 +427,12 @@ struct AlumaccWorker for (auto cell : eq_cells) { - bool cmp_equal = cell->type.in("$eq", "$eqx"); - bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + bool cmp_equal = cell->type.in(ID($eq), ID($eqx)); + bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); - RTLIL::SigSpec A = sigmap(cell->getPort("\\A")); - RTLIL::SigSpec B = sigmap(cell->getPort("\\B")); - RTLIL::SigSpec Y = sigmap(cell->getPort("\\Y")); + RTLIL::SigSpec A = sigmap(cell->getPort(ID::A)); + RTLIL::SigSpec B = sigmap(cell->getPort(ID::B)); + RTLIL::SigSpec Y = sigmap(cell->getPort(ID::Y)); if (B < A && GetSize(B)) std::swap(A, B); @@ -440,7 +440,7 @@ struct AlumaccWorker alunode_t *n = nullptr; for (auto node : sig_alu[RTLIL::SigSig(A, B)]) - if (node->is_signed == is_signed && node->invert_b && node->c == RTLIL::S1) { + if (node->is_signed == is_signed && node->invert_b && node->c == State::S1) { n = node; break; } @@ -471,7 +471,7 @@ struct AlumaccWorker goto delete_node; } - n->alu_cell = module->addCell(NEW_ID, "$alu"); + n->alu_cell = module->addCell(NEW_ID, ID($alu)); alu_counter++; log(" creating $alu cell for "); @@ -482,13 +482,13 @@ struct AlumaccWorker if (n->cells.size() > 0) n->alu_cell->set_src_attribute(n->cells[0]->get_src_attribute()); - n->alu_cell->setPort("\\A", n->a); - n->alu_cell->setPort("\\B", n->b); - n->alu_cell->setPort("\\CI", GetSize(n->c) ? n->c : RTLIL::S0); - n->alu_cell->setPort("\\BI", n->invert_b ? RTLIL::S1 : RTLIL::S0); - n->alu_cell->setPort("\\Y", n->y); - n->alu_cell->setPort("\\X", module->addWire(NEW_ID, GetSize(n->y))); - n->alu_cell->setPort("\\CO", module->addWire(NEW_ID, GetSize(n->y))); + n->alu_cell->setPort(ID::A, n->a); + n->alu_cell->setPort(ID::B, n->b); + n->alu_cell->setPort(ID(CI), GetSize(n->c) ? n->c : State::S0); + n->alu_cell->setPort(ID(BI), n->invert_b ? State::S1 : State::S0); + n->alu_cell->setPort(ID::Y, n->y); + n->alu_cell->setPort(ID(X), module->addWire(NEW_ID, GetSize(n->y))); + n->alu_cell->setPort(ID(CO), module->addWire(NEW_ID, GetSize(n->y))); n->alu_cell->fixup_parameters(n->is_signed, n->is_signed); for (auto &it : n->cmp) diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc index 47d0ff416..b976b401b 100644 --- a/passes/techmap/deminout.cc +++ b/passes/techmap/deminout.cc @@ -83,13 +83,13 @@ struct DeminoutPass : public Pass { for (auto bit : sigmap(conn.second)) bits_used.insert(bit); - if (conn.first == "\\Y" && cell->type.in("$mux", "$pmux", "$_MUX_", "$_TBUF_", "$tribuf")) + if (conn.first == ID::Y && cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_TBUF_), ID($tribuf))) { - bool tribuf = (cell->type == "$_TBUF_" || cell->type == "$tribuf"); + bool tribuf = cell->type.in(ID($_TBUF_), ID($tribuf)); if (!tribuf) { for (auto &c : cell->connections()) { - if (!c.first.in("\\A", "\\B")) + if (!c.first.in(ID::A, ID::B)) continue; for (auto b : sigmap(c.second)) if (b == State::Sz) diff --git a/passes/techmap/dff2dffe.cc b/passes/techmap/dff2dffe.cc index 7e1040963..0242256e5 100644 --- a/passes/techmap/dff2dffe.cc +++ b/passes/techmap/dff2dffe.cc @@ -52,13 +52,13 @@ struct Dff2dffeWorker } for (auto cell : module->cells()) { - if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_") { - RTLIL::SigSpec sig_y = sigmap(cell->getPort("\\Y")); + 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 == "$dff" || cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") + if (cell->type.in(ID($dff), ID($_DFF_N_), ID($_DFF_P_))) dff_cells.push_back(cell); } else { if (direct_dict.count(cell->type)) @@ -86,9 +86,9 @@ struct Dff2dffeWorker return ret; cell_int_t mux_cell_int = bit2mux.at(d); - RTLIL::SigSpec sig_a = sigmap(mux_cell_int.first->getPort("\\A")); - RTLIL::SigSpec sig_b = sigmap(mux_cell_int.first->getPort("\\B")); - RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort("\\S")); + 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++) @@ -97,9 +97,9 @@ struct Dff2dffeWorker 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("\\B"); + RTLIL::SigSpec s = mux_cell_int.first->getPort(ID::B); s[i*width + index] = RTLIL::Sx; - mux_cell_int.first->setPort("\\B", s); + mux_cell_int.first->setPort(ID::B, s); } return ret; @@ -120,9 +120,9 @@ struct Dff2dffeWorker ret.insert(pat); if (sig_b[i*width + index] == q) { - RTLIL::SigSpec s = mux_cell_int.first->getPort("\\B"); + RTLIL::SigSpec s = mux_cell_int.first->getPort(ID::B); s[i*width + index] = RTLIL::Sx; - mux_cell_int.first->setPort("\\B", s); + mux_cell_int.first->setPort(ID::B, s); } } @@ -130,9 +130,9 @@ struct Dff2dffeWorker ret.insert(pat); if (sig_a[index] == q) { - RTLIL::SigSpec s = mux_cell_int.first->getPort("\\A"); + RTLIL::SigSpec s = mux_cell_int.first->getPort(ID::A); s[index] = RTLIL::Sx; - mux_cell_int.first->setPort("\\A", s); + mux_cell_int.first->setPort(ID::A, s); } return ret; @@ -167,7 +167,7 @@ struct Dff2dffeWorker } if (GetSize(or_input) == 0) - return RTLIL::S1; + return State::S1; if (GetSize(or_input) == 1) return or_input; @@ -185,8 +185,8 @@ struct Dff2dffeWorker void handle_dff_cell(RTLIL::Cell *dff_cell) { - RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort("\\D")); - RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort("\\Q")); + RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort(ID(D))); + RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort(ID(Q))); std::map> grouped_patterns; std::set remaining_indices; @@ -208,16 +208,16 @@ struct Dff2dffeWorker } 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("\\E", make_patterns_logic(it.first, true)); + 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 == "$dff") { - RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort("\\CLK"), make_patterns_logic(it.first, false), - new_sig_d, new_sig_q, dff_cell->getParam("\\CLK_POLARITY").as_bool(), true); + 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("\\C"), make_patterns_logic(it.first, true), - new_sig_d, new_sig_q, dff_cell->type == "$_DFF_P_", true); + 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)); } } @@ -235,9 +235,9 @@ struct Dff2dffeWorker new_sig_d.append(sig_d[i]); new_sig_q.append(sig_q[i]); } - dff_cell->setPort("\\D", new_sig_d); - dff_cell->setPort("\\Q", new_sig_q); - dff_cell->setParam("\\WIDTH", GetSize(remaining_indices)); + dff_cell->setPort(ID(D), new_sig_d); + dff_cell->setPort(ID(Q), new_sig_q); + dff_cell->setParam(ID(WIDTH), GetSize(remaining_indices)); } } @@ -265,7 +265,7 @@ struct Dff2dffePass : public Pass { 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 ignore in unmap mode.\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"); @@ -304,7 +304,7 @@ struct Dff2dffePass : public Pass { } if (args[argidx] == "-unmap-mince" && argidx + 1 < args.size()) { unmap_mode = true; - min_ce_use = std::stoi(args[++argidx]); + min_ce_use = atoi(args[++argidx].c_str()); continue; } if (args[argidx] == "-direct" && argidx + 2 < args.size()) { @@ -316,25 +316,25 @@ struct Dff2dffePass : public Pass { 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["$_DFF_P_" ] = "$_DFFE_PP_"; - if (patmatch(pattern, "$_DFF_N_" )) found_match = true, direct_dict["$_DFF_N_" ] = "$_DFFE_NP_"; - if (patmatch(pattern, "$_DFF_NN0_")) found_match = true, direct_dict["$_DFF_NN0_"] = "$__DFFE_NN0"; - if (patmatch(pattern, "$_DFF_NN1_")) found_match = true, direct_dict["$_DFF_NN1_"] = "$__DFFE_NN1"; - if (patmatch(pattern, "$_DFF_NP0_")) found_match = true, direct_dict["$_DFF_NP0_"] = "$__DFFE_NP0"; - if (patmatch(pattern, "$_DFF_NP1_")) found_match = true, direct_dict["$_DFF_NP1_"] = "$__DFFE_NP1"; - if (patmatch(pattern, "$_DFF_PN0_")) found_match = true, direct_dict["$_DFF_PN0_"] = "$__DFFE_PN0"; - if (patmatch(pattern, "$_DFF_PN1_")) found_match = true, direct_dict["$_DFF_PN1_"] = "$__DFFE_PN1"; - if (patmatch(pattern, "$_DFF_PP0_")) found_match = true, direct_dict["$_DFF_PP0_"] = "$__DFFE_PP0"; - if (patmatch(pattern, "$_DFF_PP1_")) found_match = true, direct_dict["$_DFF_PP1_"] = "$__DFFE_PP1"; + 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["$__DFFS_NN0_"] = "$__DFFSE_NN0"; - if (patmatch(pattern, "$__DFFS_NN1_")) found_match = true, direct_dict["$__DFFS_NN1_"] = "$__DFFSE_NN1"; - if (patmatch(pattern, "$__DFFS_NP0_")) found_match = true, direct_dict["$__DFFS_NP0_"] = "$__DFFSE_NP0"; - if (patmatch(pattern, "$__DFFS_NP1_")) found_match = true, direct_dict["$__DFFS_NP1_"] = "$__DFFSE_NP1"; - if (patmatch(pattern, "$__DFFS_PN0_")) found_match = true, direct_dict["$__DFFS_PN0_"] = "$__DFFSE_PN0"; - if (patmatch(pattern, "$__DFFS_PN1_")) found_match = true, direct_dict["$__DFFS_PN1_"] = "$__DFFSE_PN1"; - if (patmatch(pattern, "$__DFFS_PP0_")) found_match = true, direct_dict["$__DFFS_PP0_"] = "$__DFFSE_PP0"; - if (patmatch(pattern, "$__DFFS_PP1_")) found_match = true, direct_dict["$__DFFS_PP1_"] = "$__DFFSE_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; @@ -355,49 +355,49 @@ struct Dff2dffePass : public Pass { if (unmap_mode) { SigMap sigmap(mod); for (auto cell : mod->selected_cells()) { - if (cell->type == "$dffe") { + 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("\\EN")) == sigmap(cell_other->getPort("\\EN"))) + 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("\\D"))); - mod->addDff(NEW_ID, cell->getPort("\\CLK"), tmp, cell->getPort("\\Q"), cell->getParam("\\CLK_POLARITY").as_bool()); - if (cell->getParam("\\EN_POLARITY").as_bool()) - mod->addMux(NEW_ID, cell->getPort("\\Q"), cell->getPort("\\D"), cell->getPort("\\EN"), tmp); + 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("\\D"), cell->getPort("\\Q"), cell->getPort("\\EN"), tmp); + mod->addMux(NEW_ID, cell->getPort(ID(D)), cell->getPort(ID(Q)), cell->getPort(ID(EN)), tmp); mod->remove(cell); continue; } - if (cell->type.substr(0, 7) == "$_DFFE_") { + 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("\\E")) == sigmap(cell_other->getPort("\\E"))) + 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.substr(7, 1) == "P"; - bool en_pol = cell->type.substr(8, 1) == "P"; + 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("\\C"), tmp, cell->getPort("\\Q"), clk_pol); + mod->addDff(NEW_ID, cell->getPort(ID(C)), tmp, cell->getPort(ID(Q)), clk_pol); if (en_pol) - mod->addMux(NEW_ID, cell->getPort("\\Q"), cell->getPort("\\D"), cell->getPort("\\E"), tmp); + mod->addMux(NEW_ID, cell->getPort(ID(Q)), cell->getPort(ID(D)), cell->getPort(ID(E)), tmp); else - mod->addMux(NEW_ID, cell->getPort("\\D"), cell->getPort("\\Q"), cell->getPort("\\E"), tmp); + mod->addMux(NEW_ID, cell->getPort(ID(D)), cell->getPort(ID(Q)), cell->getPort(ID(E)), tmp); mod->remove(cell); continue; } diff --git a/passes/techmap/dff2dffs.cc b/passes/techmap/dff2dffs.cc index 39a4f6ade..0ea033513 100644 --- a/passes/techmap/dff2dffs.cc +++ b/passes/techmap/dff2dffs.cc @@ -51,8 +51,8 @@ struct Dff2dffsPass : public Pass { extra_args(args, argidx, design); pool dff_types; - dff_types.insert("$_DFF_N_"); - dff_types.insert("$_DFF_P_"); + dff_types.insert(ID($_DFF_N_)); + dff_types.insert(ID($_DFF_P_)); for (auto module : design->selected_modules()) { @@ -69,19 +69,19 @@ struct Dff2dffsPass : public Pass { continue; } - if (cell->type != "$_MUX_") + if (cell->type != ID($_MUX_)) continue; - SigBit bit_a = sigmap(cell->getPort("\\A")); - SigBit bit_b = sigmap(cell->getPort("\\B")); + 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("\\Y"))] = cell; + sr_muxes[sigmap(cell->getPort(ID::Y))] = cell; } for (auto cell : ff_cells) { - SigSpec sig_d = cell->getPort("\\D"); + SigSpec sig_d = cell->getPort(ID(D)); if (GetSize(sig_d) < 1) continue; @@ -92,9 +92,9 @@ struct Dff2dffsPass : public Pass { continue; Cell *mux_cell = sr_muxes.at(bit_d); - SigBit bit_a = sigmap(mux_cell->getPort("\\A")); - SigBit bit_b = sigmap(mux_cell->getPort("\\B")); - SigBit bit_s = sigmap(mux_cell->getPort("\\S")); + 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)); @@ -114,26 +114,26 @@ struct Dff2dffsPass : public Pass { } if (sr_val == State::S1) { - if (cell->type == "$_DFF_N_") { - if (invert_sr) cell->type = "$__DFFS_NN1_"; - else cell->type = "$__DFFS_NP1_"; + 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 == "$_DFF_P_"); - if (invert_sr) cell->type = "$__DFFS_PN1_"; - else cell->type = "$__DFFS_PP1_"; + 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 == "$_DFF_N_") { - if (invert_sr) cell->type = "$__DFFS_NN0_"; - else cell->type = "$__DFFS_NP0_"; + 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 == "$_DFF_P_"); - if (invert_sr) cell->type = "$__DFFS_PN0_"; - else cell->type = "$__DFFS_PP0_"; + log_assert(cell->type == ID($_DFF_P_)); + if (invert_sr) cell->type = ID($__DFFS_PN0_); + else cell->type = ID($__DFFS_PP0_); } } - cell->setPort("\\R", sr_sig); - cell->setPort("\\D", bit_d); + cell->setPort(ID(R), sr_sig); + cell->setPort(ID(D), bit_d); } } } diff --git a/passes/techmap/dffinit.cc b/passes/techmap/dffinit.cc index 0ad33dc0e..cf9301442 100644 --- a/passes/techmap/dffinit.cc +++ b/passes/techmap/dffinit.cc @@ -99,8 +99,8 @@ struct DffinitPass : public Pass { pool used_bits; for (auto wire : module->selected_wires()) { - if (wire->attributes.count("\\init")) { - Const value = wire->attributes.at("\\init"); + 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]; @@ -161,8 +161,8 @@ struct DffinitPass : public Pass { } for (auto wire : module->selected_wires()) - if (wire->attributes.count("\\init")) { - Const &value = wire->attributes.at("\\init"); + 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)); @@ -173,7 +173,7 @@ struct DffinitPass : public Pass { } if (do_cleanup) { log("Removing init attribute from wire %s.%s.\n", log_id(module), log_id(wire)); - wire->attributes.erase("\\init"); + wire->attributes.erase(ID(init)); } } } diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index b5c0498d0..b15109cd3 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -27,12 +27,12 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct cell_mapping { - std::string cell_name; + IdString cell_name; std::map ports; }; static std::map cell_mappings; -static void logmap(std::string dff) +static void logmap(IdString dff) { if (cell_mappings.count(dff) == 0) { log(" unmapped dff cell: %s\n", dff.c_str()); @@ -54,26 +54,26 @@ static void logmap(std::string dff) static void logmap_all() { - logmap("$_DFF_N_"); - logmap("$_DFF_P_"); + logmap(ID($_DFF_N_)); + logmap(ID($_DFF_P_)); - logmap("$_DFF_NN0_"); - logmap("$_DFF_NN1_"); - logmap("$_DFF_NP0_"); - logmap("$_DFF_NP1_"); - logmap("$_DFF_PN0_"); - logmap("$_DFF_PN1_"); - logmap("$_DFF_PP0_"); - logmap("$_DFF_PP1_"); + logmap(ID($_DFF_NN0_)); + logmap(ID($_DFF_NN1_)); + logmap(ID($_DFF_NP0_)); + logmap(ID($_DFF_NP1_)); + logmap(ID($_DFF_PN0_)); + logmap(ID($_DFF_PN1_)); + logmap(ID($_DFF_PP0_)); + logmap(ID($_DFF_PP1_)); - logmap("$_DFFSR_NNN_"); - logmap("$_DFFSR_NNP_"); - logmap("$_DFFSR_NPN_"); - logmap("$_DFFSR_NPP_"); - logmap("$_DFFSR_PNN_"); - logmap("$_DFFSR_PNP_"); - logmap("$_DFFSR_PPN_"); - logmap("$_DFFSR_PPP_"); + logmap(ID($_DFFSR_NNN_)); + logmap(ID($_DFFSR_NNP_)); + logmap(ID($_DFFSR_NPN_)); + logmap(ID($_DFFSR_NPP_)); + logmap(ID($_DFFSR_PNN_)); + logmap(ID($_DFFSR_PNP_)); + logmap(ID($_DFFSR_PPN_)); + logmap(ID($_DFFSR_PPP_)); } static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol) @@ -115,7 +115,7 @@ static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, return false; } -static void find_cell(LibertyAst *ast, std::string 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, bool prepare_mode) { LibertyAst *best_cell = NULL; std::map best_cell_ports; @@ -230,13 +230,13 @@ static void find_cell(LibertyAst *ast, std::string cell_type, bool clkpol, bool cell_mappings[cell_type].ports["D"] = 'D'; cell_mappings[cell_type].ports["Q"] = 'Q'; } else { - cell_mappings[cell_type].cell_name = best_cell->args[0]; + 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, std::string 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, bool prepare_mode) { LibertyAst *best_cell = NULL; std::map best_cell_ports; @@ -347,7 +347,7 @@ static void find_cell_sr(LibertyAst *ast, std::string cell_type, bool clkpol, bo cell_mappings[cell_type].ports["D"] = 'D'; cell_mappings[cell_type].ports["Q"] = 'Q'; } else { - cell_mappings[cell_type].cell_name = best_cell->args[0]; + cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]); cell_mappings[cell_type].ports = best_cell_ports; } } @@ -404,7 +404,7 @@ static bool expand_cellmap(std::string pattern, std::string inv) return return_status; } -static void map_sr_to_arst(const char *from, const char *to) +static void map_sr_to_arst(IdString from, IdString to) { if (!cell_mappings.count(from) || cell_mappings.count(to) > 0) return; @@ -419,7 +419,7 @@ static void map_sr_to_arst(const char *from, const char *to) 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, from); + 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; @@ -450,7 +450,7 @@ static void map_sr_to_arst(const char *from, const char *to) } } -static void map_adff_to_dff(const char *from, const char *to) +static void map_adff_to_dff(IdString from, IdString to) { if (!cell_mappings.count(from) || cell_mappings.count(to) > 0) return; @@ -461,7 +461,7 @@ static void map_adff_to_dff(const char *from, const char *to) log_assert(from_clk_pol == to_clk_pol); - log(" create mapping for %s from mapping for %s.\n", to, from); + 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; @@ -484,8 +484,8 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare for (auto &it : module->cells_) { if (design->selected(module, it.second) && cell_mappings.count(it.second->type) > 0) cell_list.push_back(it.second); - if (it.second->type == "$_NOT_") - notmap[sigmap(it.second->getPort("\\A"))].insert(it.second); + if (it.second->type == ID($_NOT_)) + notmap[sigmap(it.second->getPort(ID::A))].insert(it.second); } std::map stats; @@ -499,7 +499,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, prepare_mode ? cm.cell_name : cm.cell_name); new_cell->set_src_attribute(src); @@ -519,8 +519,8 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare sig = module->addWire(NEW_ID, GetSize(old_sig)); if (has_q && has_qn) { for (auto &it : notmap[sigmap(old_sig)]) { - module->connect(it->getPort("\\Y"), sig); - it->setPort("\\Y", module->addWire(NEW_ID, GetSize(old_sig))); + module->connect(it->getPort(ID::Y), sig); + it->setPort(ID::Y, module->addWire(NEW_ID, GetSize(old_sig))); } } else { module->addNotGate(NEW_ID, sig, old_sig); @@ -599,26 +599,26 @@ struct DfflibmapPass : public Pass { LibertyParser libparser(f); f.close(); - find_cell(libparser.ast, "$_DFF_N_", false, false, false, false, prepare_mode); - find_cell(libparser.ast, "$_DFF_P_", true, false, false, false, prepare_mode); + 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, "$_DFF_NN0_", false, true, false, false, prepare_mode); - find_cell(libparser.ast, "$_DFF_NN1_", false, true, false, true, prepare_mode); - find_cell(libparser.ast, "$_DFF_NP0_", false, true, true, false, prepare_mode); - find_cell(libparser.ast, "$_DFF_NP1_", false, true, true, true, prepare_mode); - find_cell(libparser.ast, "$_DFF_PN0_", true, true, false, false, prepare_mode); - find_cell(libparser.ast, "$_DFF_PN1_", true, true, false, true, prepare_mode); - find_cell(libparser.ast, "$_DFF_PP0_", true, true, true, false, prepare_mode); - find_cell(libparser.ast, "$_DFF_PP1_", true, true, true, true, 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, "$_DFFSR_NNN_", false, false, false, prepare_mode); - find_cell_sr(libparser.ast, "$_DFFSR_NNP_", false, false, true, prepare_mode); - find_cell_sr(libparser.ast, "$_DFFSR_NPN_", false, true, false, prepare_mode); - find_cell_sr(libparser.ast, "$_DFFSR_NPP_", false, true, true, prepare_mode); - find_cell_sr(libparser.ast, "$_DFFSR_PNN_", true, false, false, prepare_mode); - find_cell_sr(libparser.ast, "$_DFFSR_PNP_", true, false, true, prepare_mode); - find_cell_sr(libparser.ast, "$_DFFSR_PPN_", true, true, false, prepare_mode); - find_cell_sr(libparser.ast, "$_DFFSR_PPP_", 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 @@ -642,23 +642,23 @@ struct DfflibmapPass : public Pass { break; } - map_sr_to_arst("$_DFFSR_NNN_", "$_DFF_NN0_"); - map_sr_to_arst("$_DFFSR_NNN_", "$_DFF_NN1_"); - map_sr_to_arst("$_DFFSR_NPP_", "$_DFF_NP0_"); - map_sr_to_arst("$_DFFSR_NPP_", "$_DFF_NP1_"); - map_sr_to_arst("$_DFFSR_PNN_", "$_DFF_PN0_"); - map_sr_to_arst("$_DFFSR_PNN_", "$_DFF_PN1_"); - map_sr_to_arst("$_DFFSR_PPP_", "$_DFF_PP0_"); - map_sr_to_arst("$_DFFSR_PPP_", "$_DFF_PP1_"); + 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("$_DFF_NN0_", "$_DFF_N_"); - map_adff_to_dff("$_DFF_NN1_", "$_DFF_N_"); - map_adff_to_dff("$_DFF_NP0_", "$_DFF_N_"); - map_adff_to_dff("$_DFF_NP1_", "$_DFF_N_"); - map_adff_to_dff("$_DFF_PN0_", "$_DFF_P_"); - map_adff_to_dff("$_DFF_PN1_", "$_DFF_P_"); - map_adff_to_dff("$_DFF_PP0_", "$_DFF_P_"); - map_adff_to_dff("$_DFF_PP1_", "$_DFF_P_"); + 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_)); log(" final dff cell mappings:\n"); logmap_all(); diff --git a/passes/techmap/dffsr2dff.cc b/passes/techmap/dffsr2dff.cc index 086a1d2fa..61b06fdc1 100644 --- a/passes/techmap/dffsr2dff.cc +++ b/passes/techmap/dffsr2dff.cc @@ -25,17 +25,17 @@ PRIVATE_NAMESPACE_BEGIN void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell) { - if (cell->type == "$dffsr") + if (cell->type == ID($dffsr)) { - int width = cell->getParam("\\WIDTH").as_int(); - bool setpol = cell->getParam("\\SET_POLARITY").as_bool(); - bool clrpol = cell->getParam("\\CLR_POLARITY").as_bool(); + int width = cell->getParam(ID(WIDTH)).as_int(); + bool setpol = cell->getParam(ID(SET_POLARITY)).as_bool(); + bool clrpol = cell->getParam(ID(CLR_POLARITY)).as_bool(); SigBit setunused = setpol ? State::S0 : State::S1; SigBit clrunused = clrpol ? State::S0 : State::S1; - SigSpec setsig = sigmap(cell->getPort("\\SET")); - SigSpec clrsig = sigmap(cell->getPort("\\CLR")); + SigSpec setsig = sigmap(cell->getPort(ID(SET))); + SigSpec clrsig = sigmap(cell->getPort(ID(CLR))); Const reset_val; SigSpec setctrl, clrctrl; @@ -78,32 +78,32 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell) log("Converting %s cell %s.%s to $adff.\n", log_id(cell->type), log_id(module), log_id(cell)); if (GetSize(setctrl) == 1) { - cell->setPort("\\ARST", setctrl); - cell->setParam("\\ARST_POLARITY", setpol); + cell->setPort(ID(ARST), setctrl); + cell->setParam(ID(ARST_POLARITY), setpol); } else { - cell->setPort("\\ARST", clrctrl); - cell->setParam("\\ARST_POLARITY", clrpol); + cell->setPort(ID(ARST), clrctrl); + cell->setParam(ID(ARST_POLARITY), clrpol); } - cell->type = "$adff"; - cell->unsetPort("\\SET"); - cell->unsetPort("\\CLR"); - cell->setParam("\\ARST_VALUE", reset_val); - cell->unsetParam("\\SET_POLARITY"); - cell->unsetParam("\\CLR_POLARITY"); + cell->type = ID($adff); + cell->unsetPort(ID(SET)); + cell->unsetPort(ID(CLR)); + cell->setParam(ID(ARST_VALUE), reset_val); + cell->unsetParam(ID(SET_POLARITY)); + cell->unsetParam(ID(CLR_POLARITY)); return; } - if (cell->type.in("$_DFFSR_NNN_", "$_DFFSR_NNP_", "$_DFFSR_NPN_", "$_DFFSR_NPP_", - "$_DFFSR_PNN_", "$_DFFSR_PNP_", "$_DFFSR_PPN_", "$_DFFSR_PPP_")) + 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_))) { char clkpol = cell->type.c_str()[8]; char setpol = cell->type.c_str()[9]; char clrpol = cell->type.c_str()[10]; - SigBit setbit = sigmap(cell->getPort("\\S")); - SigBit clrbit = sigmap(cell->getPort("\\R")); + SigBit setbit = sigmap(cell->getPort(ID(S))); + SigBit clrbit = sigmap(cell->getPort(ID(R))); SigBit setunused = setpol == 'P' ? State::S0 : State::S1; SigBit clrunused = clrpol == 'P' ? State::S0 : State::S1; @@ -112,14 +112,14 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell) if (setbit == setunused) { cell->type = stringf("$_DFF_%c%c0_", clkpol, clrpol); - cell->unsetPort("\\S"); + cell->unsetPort(ID(S)); goto converted_gate; } if (clrbit == clrunused) { cell->type = stringf("$_DFF_%c%c1_", clkpol, setpol); - cell->setPort("\\R", cell->getPort("\\S")); - cell->unsetPort("\\S"); + cell->setPort(ID(R), cell->getPort(ID(S))); + cell->unsetPort(ID(S)); goto converted_gate; } @@ -133,32 +133,32 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell) void adff_worker(SigMap &sigmap, Module *module, Cell *cell) { - if (cell->type == "$adff") + if (cell->type == ID($adff)) { - bool rstpol = cell->getParam("\\ARST_POLARITY").as_bool(); + bool rstpol = cell->getParam(ID(ARST_POLARITY)).as_bool(); SigBit rstunused = rstpol ? State::S0 : State::S1; - SigSpec rstsig = sigmap(cell->getPort("\\ARST")); + SigSpec rstsig = sigmap(cell->getPort(ID(ARST))); if (rstsig != rstunused) return; log("Converting %s cell %s.%s to $dff.\n", log_id(cell->type), log_id(module), log_id(cell)); - cell->type = "$dff"; - cell->unsetPort("\\ARST"); - cell->unsetParam("\\ARST_VALUE"); - cell->unsetParam("\\ARST_POLARITY"); + cell->type = ID($dff); + cell->unsetPort(ID(ARST)); + cell->unsetParam(ID(ARST_VALUE)); + cell->unsetParam(ID(ARST_POLARITY)); return; } - if (cell->type.in("$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", - "$_DFF_PN0_", "$_DFF_PN1_", "$_DFF_PP0_", "$_DFF_PP1_")) + 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_))) { char clkpol = cell->type.c_str()[6]; char rstpol = cell->type.c_str()[7]; - SigBit rstbit = sigmap(cell->getPort("\\R")); + SigBit rstbit = sigmap(cell->getPort(ID(R))); SigBit rstunused = rstpol == 'P' ? State::S0 : State::S1; if (rstbit != rstunused) @@ -168,7 +168,7 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell) log("Converting %s cell %s.%s to %s.\n", log_id(cell->type), log_id(module), log_id(cell), log_id(newtype)); cell->type = newtype; - cell->unsetPort("\\R"); + cell->unsetPort(ID(R)); return; } diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index fff90f13c..f8798eea5 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -54,40 +54,40 @@ public: RTLIL::Const unified_param(RTLIL::IdString cell_type, RTLIL::IdString param, RTLIL::Const value) { - if (cell_type.substr(0, 1) != "$" || cell_type.substr(0, 2) == "$_") + if (!cell_type.begins_with("$") || cell_type.begins_with("$_")) return value; #define param_bool(_n) if (param == _n) return value.as_bool(); - param_bool("\\ARST_POLARITY"); - param_bool("\\A_SIGNED"); - param_bool("\\B_SIGNED"); - param_bool("\\CLK_ENABLE"); - param_bool("\\CLK_POLARITY"); - param_bool("\\CLR_POLARITY"); - param_bool("\\EN_POLARITY"); - param_bool("\\SET_POLARITY"); - param_bool("\\TRANSPARENT"); + param_bool(ID(ARST_POLARITY)); + param_bool(ID(A_SIGNED)); + param_bool(ID(B_SIGNED)); + param_bool(ID(CLK_ENABLE)); + param_bool(ID(CLK_POLARITY)); + param_bool(ID(CLR_POLARITY)); + param_bool(ID(EN_POLARITY)); + param_bool(ID(SET_POLARITY)); + param_bool(ID(TRANSPARENT)); #undef param_bool #define param_int(_n) if (param == _n) return value.as_int(); - param_int("\\ABITS") - param_int("\\A_WIDTH") - param_int("\\B_WIDTH") - param_int("\\CTRL_IN_WIDTH") - param_int("\\CTRL_OUT_WIDTH") - param_int("\\OFFSET") - param_int("\\PRIORITY") - param_int("\\RD_PORTS") - param_int("\\SIZE") - param_int("\\STATE_BITS") - param_int("\\STATE_NUM") - param_int("\\STATE_NUM_LOG2") - param_int("\\STATE_RST") - param_int("\\S_WIDTH") - param_int("\\TRANS_NUM") - param_int("\\WIDTH") - param_int("\\WR_PORTS") - param_int("\\Y_WIDTH") + param_int(ID(ABITS)) + param_int(ID(A_WIDTH)) + param_int(ID(B_WIDTH)) + param_int(ID(CTRL_IN_WIDTH)) + param_int(ID(CTRL_OUT_WIDTH)) + param_int(ID(OFFSET)) + param_int(ID(PRIORITY)) + param_int(ID(RD_PORTS)) + param_int(ID(SIZE)) + param_int(ID(STATE_BITS)) + param_int(ID(STATE_NUM)) + param_int(ID(STATE_NUM_LOG2)) + param_int(ID(STATE_RST)) + param_int(ID(S_WIDTH)) + param_int(ID(TRANS_NUM)) + param_int(ID(WIDTH)) + param_int(ID(WR_PORTS)) + param_int(ID(Y_WIDTH)) #undef param_int return value; @@ -203,7 +203,7 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports, continue; std::string type = cell->type.str(); - if (sel == NULL && type.substr(0, 2) == "\\$") + if (sel == NULL && type.compare(0, 2, "\\$") == 0) type = type.substr(1); graph.createNode(cell->name.str(), type, (void*)cell); @@ -341,10 +341,10 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit: bool compareSortNeedleList(RTLIL::Module *left, RTLIL::Module *right) { int left_idx = 0, right_idx = 0; - if (left->attributes.count("\\extract_order") > 0) - left_idx = left->attributes.at("\\extract_order").as_int(); - if (right->attributes.count("\\extract_order") > 0) - right_idx = right->attributes.at("\\extract_order").as_int(); + if (left->attributes.count(ID(extract_order)) > 0) + left_idx = left->attributes.at(ID(extract_order)).as_int(); + if (right->attributes.count(ID(extract_order)) > 0) + right_idx = right->attributes.at(ID(extract_order)).as_int(); if (left_idx != right_idx) return left_idx < right_idx; return left->name < right->name; @@ -594,7 +594,7 @@ struct ExtractPass : public Pass { map = new RTLIL::Design; for (auto &filename : map_filenames) { - if (filename.substr(0, 1) == "%") + if (filename.compare(0, 1, "%") == 0) { if (!saved_designs.count(filename.substr(1))) { delete map; @@ -613,10 +613,10 @@ 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.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); + Frontend::frontend_call(map, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog")); f.close(); - if (filename.size() <= 3 || filename.substr(filename.size()-3) != ".il") { + if (filename.size() <= 3 || filename.compare(filename.size()-3, std::string::npos, ".il") != 0) { Pass::call(map, "proc"); Pass::call(map, "opt_clean"); } diff --git a/passes/techmap/extract_counter.cc b/passes/techmap/extract_counter.cc index a8d0bc834..17a99493d 100644 --- a/passes/techmap/extract_counter.cc +++ b/passes/techmap/extract_counter.cc @@ -120,71 +120,71 @@ int counter_tryextract( //A counter with less than 2 bits makes no sense //TODO: configurable min threshold - int a_width = cell->getParam("\\A_WIDTH").as_int(); + int a_width = cell->getParam(ID(A_WIDTH)).as_int(); extract.width = a_width; if( (a_width < 2) || (a_width > maxwidth) ) return 1; //Second input must be a single bit - int b_width = cell->getParam("\\B_WIDTH").as_int(); + int b_width = cell->getParam(ID(B_WIDTH)).as_int(); if(b_width != 1) return 2; //Both inputs must be unsigned, so don't extract anything with a signed input - bool a_sign = cell->getParam("\\A_SIGNED").as_bool(); - bool b_sign = cell->getParam("\\B_SIGNED").as_bool(); + bool a_sign = cell->getParam(ID(A_SIGNED)).as_bool(); + bool b_sign = cell->getParam(ID(B_SIGNED)).as_bool(); if(a_sign || b_sign) return 3; //To be a counter, one input of the ALU must be a constant 1 //TODO: can A or B be swapped in synthesized RTL or is B always the 1? - const RTLIL::SigSpec b_port = sigmap(cell->getPort("\\B")); + const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B)); if(!b_port.is_fully_const() || (b_port.as_int() != 1) ) return 4; //BI and CI must be constant 1 as well - const RTLIL::SigSpec bi_port = sigmap(cell->getPort("\\BI")); + const RTLIL::SigSpec bi_port = sigmap(cell->getPort(ID(BI))); if(!bi_port.is_fully_const() || (bi_port.as_int() != 1) ) return 5; - const RTLIL::SigSpec ci_port = sigmap(cell->getPort("\\CI")); + const RTLIL::SigSpec ci_port = sigmap(cell->getPort(ID(CI))); if(!ci_port.is_fully_const() || (ci_port.as_int() != 1) ) return 6; //CO and X must be unconnected (exactly one connection to each port) - if(!is_unconnected(sigmap(cell->getPort("\\CO")), index)) + if(!is_unconnected(sigmap(cell->getPort(ID(CO))), index)) return 7; - if(!is_unconnected(sigmap(cell->getPort("\\X")), index)) + if(!is_unconnected(sigmap(cell->getPort(ID(X))), index)) return 8; //Y must have exactly one connection, and it has to be a $mux cell. //We must have a direct bus connection from our Y to their A. - const RTLIL::SigSpec aluy = sigmap(cell->getPort("\\Y")); + const RTLIL::SigSpec aluy = sigmap(cell->getPort(ID::Y)); pool y_loads = get_other_cells(aluy, index, cell); if(y_loads.size() != 1) return 9; Cell* count_mux = *y_loads.begin(); extract.count_mux = count_mux; - if(count_mux->type != "$mux") + if(count_mux->type != ID($mux)) return 10; - if(!is_full_bus(aluy, index, cell, "\\Y", count_mux, "\\A")) + if(!is_full_bus(aluy, index, cell, ID::Y, count_mux, ID::A)) return 11; //B connection of the mux is our underflow value - const RTLIL::SigSpec underflow = sigmap(count_mux->getPort("\\B")); + const RTLIL::SigSpec underflow = sigmap(count_mux->getPort(ID::B)); if(!underflow.is_fully_const()) return 12; extract.count_value = underflow.as_int(); //S connection of the mux must come from an inverter (need not be the only load) - const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort("\\S")); + const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort(ID(S))); extract.outsig = muxsel; pool muxsel_conns = get_other_cells(muxsel, index, count_mux); Cell* underflow_inv = NULL; for(auto c : muxsel_conns) { - if(c->type != "$logic_not") + if(c->type != ID($logic_not)) continue; - if(!is_full_bus(muxsel, index, c, "\\Y", count_mux, "\\S", true)) + if(!is_full_bus(muxsel, index, c, ID::Y, count_mux, ID(S), true)) continue; underflow_inv = c; @@ -196,7 +196,7 @@ int counter_tryextract( //Y connection of the mux must have exactly one load, the counter's internal register, if there's no clock enable //If we have a clock enable, Y drives the B input of a mux. A of that mux must come from our register - const RTLIL::SigSpec muxy = sigmap(count_mux->getPort("\\Y")); + const RTLIL::SigSpec muxy = sigmap(count_mux->getPort(ID::Y)); pool muxy_loads = get_other_cells(muxy, index, count_mux); if(muxy_loads.size() != 1) return 14; @@ -204,12 +204,12 @@ int counter_tryextract( Cell* count_reg = muxload; Cell* cemux = NULL; RTLIL::SigSpec cey; - if(muxload->type == "$mux") + if(muxload->type == ID($mux)) { //This mux is probably a clock enable mux. //Find our count register (should be our only load) cemux = muxload; - cey = sigmap(cemux->getPort("\\Y")); + cey = sigmap(cemux->getPort(ID::Y)); pool cey_loads = get_other_cells(cey, index, cemux); if(cey_loads.size() != 1) return 24; @@ -217,32 +217,32 @@ int counter_tryextract( //Mux should have A driven by count Q, and B by muxy //TODO: if A and B are swapped, CE polarity is inverted - if(sigmap(cemux->getPort("\\B")) != muxy) + if(sigmap(cemux->getPort(ID::B)) != muxy) return 24; - if(sigmap(cemux->getPort("\\A")) != sigmap(count_reg->getPort("\\Q"))) + if(sigmap(cemux->getPort(ID::A)) != sigmap(count_reg->getPort(ID(Q)))) return 24; - if(sigmap(cemux->getPort("\\Y")) != sigmap(count_reg->getPort("\\D"))) + if(sigmap(cemux->getPort(ID::Y)) != sigmap(count_reg->getPort(ID(D)))) return 24; //Select of the mux is our clock enable extract.has_ce = true; - extract.ce = sigmap(cemux->getPort("\\S")); + extract.ce = sigmap(cemux->getPort(ID(S))); } else extract.has_ce = false; extract.count_reg = count_reg; - if(count_reg->type == "$dff") + if(count_reg->type == ID($dff)) extract.has_reset = false; - else if(count_reg->type == "$adff") + else if(count_reg->type == ID($adff)) { extract.has_reset = true; //Check polarity of reset - we may have to add an inverter later on! - extract.rst_inverted = (count_reg->getParam("\\ARST_POLARITY").as_int() != 1); + extract.rst_inverted = (count_reg->getParam(ID(ARST_POLARITY)).as_int() != 1); //Verify ARST_VALUE is zero or full scale - int rst_value = count_reg->getParam("\\ARST_VALUE").as_int(); + int rst_value = count_reg->getParam(ID(ARST_VALUE)).as_int(); if(rst_value == 0) extract.rst_to_max = false; else if(rst_value == extract.count_value) @@ -251,7 +251,7 @@ int counter_tryextract( return 23; //Save the reset - extract.rst = sigmap(count_reg->getPort("\\ARST")); + extract.rst = sigmap(count_reg->getPort(ID(ARST))); } //TODO: support synchronous reset else @@ -260,12 +260,12 @@ int counter_tryextract( //Sanity check that we use the ALU output properly if(extract.has_ce) { - if(!is_full_bus(muxy, index, count_mux, "\\Y", cemux, "\\B")) + if(!is_full_bus(muxy, index, count_mux, ID::Y, cemux, ID::B)) return 16; - if(!is_full_bus(cey, index, cemux, "\\Y", count_reg, "\\D")) + if(!is_full_bus(cey, index, cemux, ID::Y, count_reg, ID(D))) return 16; } - else if(!is_full_bus(muxy, index, count_mux, "\\Y", count_reg, "\\D")) + else if(!is_full_bus(muxy, index, count_mux, ID::Y, count_reg, ID(D))) return 16; //TODO: Verify count_reg CLK_POLARITY is 1 @@ -273,7 +273,7 @@ int counter_tryextract( //Register output must have exactly two loads, the inverter and ALU //(unless we have a parallel output!) //If we have a clock enable, 3 is OK - const RTLIL::SigSpec qport = count_reg->getPort("\\Q"); + const RTLIL::SigSpec qport = count_reg->getPort(ID(Q)); const RTLIL::SigSpec cnout = sigmap(qport); pool cnout_loads = get_other_cells(cnout, index, count_reg); unsigned int max_loads = 2; @@ -312,19 +312,19 @@ int counter_tryextract( } } } - if(!is_full_bus(cnout, index, count_reg, "\\Q", underflow_inv, "\\A", true)) + if(!is_full_bus(cnout, index, count_reg, ID(Q), underflow_inv, ID::A, true)) return 18; - if(!is_full_bus(cnout, index, count_reg, "\\Q", cell, "\\A", true)) + if(!is_full_bus(cnout, index, count_reg, ID(Q), cell, ID::A, true)) return 19; //Look up the clock from the register - extract.clk = sigmap(count_reg->getPort("\\CLK")); + extract.clk = sigmap(count_reg->getPort(ID(CLK))); //Register output net must have an INIT attribute equal to the count value extract.rwire = cnout.as_wire(); - if(extract.rwire->attributes.find("\\init") == extract.rwire->attributes.end()) + if(extract.rwire->attributes.find(ID(init)) == extract.rwire->attributes.end()) return 20; - int rinit = extract.rwire->attributes["\\init"].as_int(); + int rinit = extract.rwire->attributes[ID(init)].as_int(); if(rinit != extract.count_value) return 21; @@ -343,21 +343,21 @@ void counter_worker( SigMap& sigmap = index.sigmap; //Core of the counter must be an ALU - if (cell->type != "$alu") + if (cell->type != ID($alu)) return; //A input is the count value. Check if it has COUNT_EXTRACT set. //If it's not a wire, don't even try - auto port = sigmap(cell->getPort("\\A")); + auto port = sigmap(cell->getPort(ID::A)); if(!port.is_wire()) return; RTLIL::Wire* a_wire = port.as_wire(); bool force_extract = false; bool never_extract = false; - string count_reg_src = a_wire->attributes["\\src"].decode_string().c_str(); - if(a_wire->attributes.find("\\COUNT_EXTRACT") != a_wire->attributes.end()) + string count_reg_src = a_wire->attributes[ID(src)].decode_string().c_str(); + if(a_wire->attributes.find(ID(COUNT_EXTRACT)) != a_wire->attributes.end()) { - pool sa = a_wire->get_strpool_attribute("\\COUNT_EXTRACT"); + pool sa = a_wire->get_strpool_attribute(ID(COUNT_EXTRACT)); string extract_value; if(sa.size() >= 1) { @@ -434,66 +434,66 @@ void counter_worker( string countname = string("$COUNTx$") + log_id(extract.rwire->name.str()); //Wipe all of the old connections to the ALU - cell->unsetPort("\\A"); - cell->unsetPort("\\B"); - cell->unsetPort("\\BI"); - cell->unsetPort("\\CI"); - cell->unsetPort("\\CO"); - cell->unsetPort("\\X"); - cell->unsetPort("\\Y"); - cell->unsetParam("\\A_SIGNED"); - cell->unsetParam("\\A_WIDTH"); - cell->unsetParam("\\B_SIGNED"); - cell->unsetParam("\\B_WIDTH"); - cell->unsetParam("\\Y_WIDTH"); + cell->unsetPort(ID::A); + cell->unsetPort(ID::B); + cell->unsetPort(ID(BI)); + cell->unsetPort(ID(CI)); + cell->unsetPort(ID(CO)); + cell->unsetPort(ID(X)); + cell->unsetPort(ID::Y); + cell->unsetParam(ID(A_SIGNED)); + cell->unsetParam(ID(A_WIDTH)); + cell->unsetParam(ID(B_SIGNED)); + cell->unsetParam(ID(B_WIDTH)); + cell->unsetParam(ID(Y_WIDTH)); //Change the cell type - cell->type = "$__COUNT_"; + cell->type = ID($__COUNT_); //Hook up resets if(extract.has_reset) { //TODO: support other kinds of reset - cell->setParam("\\RESET_MODE", RTLIL::Const("LEVEL")); + cell->setParam(ID(RESET_MODE), RTLIL::Const("LEVEL")); //If the reset is active low, infer an inverter ($__COUNT_ cells always have active high reset) if(extract.rst_inverted) { auto realreset = cell->module->addWire(NEW_ID); cell->module->addNot(NEW_ID, extract.rst, RTLIL::SigSpec(realreset)); - cell->setPort("\\RST", realreset); + cell->setPort(ID(RST), realreset); } else - cell->setPort("\\RST", extract.rst); + cell->setPort(ID(RST), extract.rst); } else { - cell->setParam("\\RESET_MODE", RTLIL::Const("RISING")); - cell->setPort("\\RST", RTLIL::SigSpec(false)); + cell->setParam(ID(RESET_MODE), RTLIL::Const("RISING")); + cell->setPort(ID(RST), RTLIL::SigSpec(false)); } //Hook up other stuff - //cell->setParam("\\CLKIN_DIVIDE", RTLIL::Const(1)); - cell->setParam("\\COUNT_TO", RTLIL::Const(extract.count_value)); - cell->setParam("\\WIDTH", RTLIL::Const(extract.width)); - cell->setPort("\\CLK", extract.clk); - cell->setPort("\\OUT", extract.outsig); + //cell->setParam(ID(CLKIN_DIVIDE), RTLIL::Const(1)); + cell->setParam(ID(COUNT_TO), RTLIL::Const(extract.count_value)); + cell->setParam(ID(WIDTH), RTLIL::Const(extract.width)); + cell->setPort(ID(CLK), extract.clk); + cell->setPort(ID(OUT), extract.outsig); //Hook up clock enable if(extract.has_ce) { - cell->setParam("\\HAS_CE", RTLIL::Const(1)); - cell->setPort("\\CE", extract.ce); + cell->setParam(ID(HAS_CE), RTLIL::Const(1)); + cell->setPort(ID(CE), extract.ce); } else - cell->setParam("\\HAS_CE", RTLIL::Const(0)); + cell->setParam(ID(HAS_CE), RTLIL::Const(0)); //Hook up hard-wired ports (for now up/down are not supported), default to no parallel output - cell->setParam("\\HAS_POUT", RTLIL::Const(0)); - cell->setParam("\\RESET_TO_MAX", RTLIL::Const(0)); - cell->setParam("\\DIRECTION", RTLIL::Const("DOWN")); - cell->setPort("\\CE", RTLIL::Const(1)); - cell->setPort("\\UP", RTLIL::Const(0)); + cell->setParam(ID(HAS_POUT), RTLIL::Const(0)); + cell->setParam(ID(RESET_TO_MAX), RTLIL::Const(0)); + cell->setParam(ID(DIRECTION), RTLIL::Const("DOWN")); + cell->setPort(ID(CE), RTLIL::Const(1)); + cell->setPort(ID(UP), RTLIL::Const(0)); //Hook up any parallel outputs for(auto load : extract.pouts) @@ -505,8 +505,8 @@ void counter_worker( //Connect it to our parallel output //(this is OK to do more than once b/c they all go to the same place) - cell->setPort("\\POUT", sig); - cell->setParam("\\HAS_POUT", RTLIL::Const(1)); + cell->setPort(ID(POUT), sig); + cell->setParam(ID(HAS_POUT), RTLIL::Const(1)); } //Delete the cells we've replaced (let opt_clean handle deleting the now-redundant wires) @@ -546,7 +546,7 @@ void counter_worker( int newbits = ceil(log2(extract.count_value)); if(extract.width != newbits) { - cell->setParam("\\WIDTH", RTLIL::Const(newbits)); + cell->setParam(ID(WIDTH), RTLIL::Const(newbits)); log(" Optimizing out %d unused high-order bits (new width is %d)\n", extract.width - newbits, newbits); diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc index 591bc43dd..29700c37b 100644 --- a/passes/techmap/extract_fa.cc +++ b/passes/techmap/extract_fa.cc @@ -85,11 +85,11 @@ struct ExtractFaWorker { for (auto cell : module->selected_cells()) { - if (cell->type.in( "$_BUF_", "$_NOT_", "$_AND_", "$_NAND_", "$_OR_", "$_NOR_", - "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_", "$_MUX_", - "$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_")) + if (cell->type.in( ID($_BUF_), ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), + ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_), + ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) { - SigBit y = sigmap(SigBit(cell->getPort("\\Y"))); + SigBit y = sigmap(SigBit(cell->getPort(ID::Y))); log_assert(driver.count(y) == 0); driver[y] = cell; } @@ -262,10 +262,10 @@ struct ExtractFaWorker pool new_leaves = leaves; new_leaves.erase(bit); - if (cell->hasPort("\\A")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\A")))); - if (cell->hasPort("\\B")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\B")))); - if (cell->hasPort("\\C")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\C")))); - if (cell->hasPort("\\D")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\D")))); + if (cell->hasPort(ID::A)) new_leaves.insert(sigmap(SigBit(cell->getPort(ID::A)))); + if (cell->hasPort(ID::B)) new_leaves.insert(sigmap(SigBit(cell->getPort(ID::B)))); + if (cell->hasPort(ID(C))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(C))))); + if (cell->hasPort(ID(D))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(D))))); if (GetSize(new_leaves) > maxbreadth) continue; @@ -277,8 +277,8 @@ struct ExtractFaWorker void assign_new_driver(SigBit bit, SigBit new_driver) { Cell *cell = driver.at(bit); - if (sigmap(cell->getPort("\\Y")) == bit) { - cell->setPort("\\Y", module->addWire(NEW_ID)); + if (sigmap(cell->getPort(ID::Y)) == bit) { + cell->setPort(ID::Y, module->addWire(NEW_ID)); module->connect(bit, new_driver); } } @@ -289,7 +289,7 @@ struct ExtractFaWorker for (auto it : driver) { - if (it.second->type.in("$_BUF_", "$_NOT_")) + if (it.second->type.in(ID($_BUF_), ID($_NOT_))) continue; SigBit root = it.first; @@ -390,20 +390,20 @@ struct ExtractFaWorker } else { - Cell *cell = module->addCell(NEW_ID, "$fa"); - cell->setParam("\\WIDTH", 1); + Cell *cell = module->addCell(NEW_ID, ID($fa)); + cell->setParam(ID(WIDTH), 1); log(" Created $fa cell %s.\n", log_id(cell)); - cell->setPort("\\A", f3i.inv_a ? module->NotGate(NEW_ID, A) : A); - cell->setPort("\\B", f3i.inv_b ? module->NotGate(NEW_ID, B) : B); - cell->setPort("\\C", f3i.inv_c ? module->NotGate(NEW_ID, C) : C); + cell->setPort(ID::A, f3i.inv_a ? module->NotGate(NEW_ID, A) : A); + cell->setPort(ID::B, f3i.inv_b ? module->NotGate(NEW_ID, B) : B); + cell->setPort(ID(C), f3i.inv_c ? module->NotGate(NEW_ID, C) : C); X = module->addWire(NEW_ID); Y = module->addWire(NEW_ID); - cell->setPort("\\X", X); - cell->setPort("\\Y", Y); + cell->setPort(ID(X), X); + cell->setPort(ID::Y, Y); facache[fakey] = make_tuple(X, Y, cell); } @@ -496,30 +496,30 @@ struct ExtractFaWorker } else { - Cell *cell = module->addCell(NEW_ID, "$fa"); - cell->setParam("\\WIDTH", 1); + Cell *cell = module->addCell(NEW_ID, ID($fa)); + cell->setParam(ID(WIDTH), 1); log(" Created $fa cell %s.\n", log_id(cell)); - cell->setPort("\\A", f2i.inv_a ? module->NotGate(NEW_ID, A) : A); - cell->setPort("\\B", f2i.inv_b ? module->NotGate(NEW_ID, B) : B); - cell->setPort("\\C", State::S0); + cell->setPort(ID::A, f2i.inv_a ? module->NotGate(NEW_ID, A) : A); + cell->setPort(ID::B, f2i.inv_b ? module->NotGate(NEW_ID, B) : B); + cell->setPort(ID(C), State::S0); X = module->addWire(NEW_ID); Y = module->addWire(NEW_ID); - cell->setPort("\\X", X); - cell->setPort("\\Y", Y); + cell->setPort(ID(X), X); + cell->setPort(ID::Y, Y); } if (func2.at(key).count(xor2_func)) { - SigBit YY = invert_xy ? module->NotGate(NEW_ID, Y) : Y; + SigBit YY = invert_xy || (f2i.inv_a && !f2i.inv_b) || (!f2i.inv_a && f2i.inv_b) ? module->NotGate(NEW_ID, Y) : Y; for (auto bit : func2.at(key).at(xor2_func)) assign_new_driver(bit, YY); } if (func2.at(key).count(xnor2_func)) { - SigBit YY = invert_xy ? Y : module->NotGate(NEW_ID, Y); + SigBit YY = invert_xy || (f2i.inv_a && !f2i.inv_b) || (!f2i.inv_a && f2i.inv_b) ? Y : module->NotGate(NEW_ID, Y); for (auto bit : func2.at(key).at(xnor2_func)) assign_new_driver(bit, YY); } diff --git a/passes/techmap/extract_reduce.cc b/passes/techmap/extract_reduce.cc index a77bbc0b7..11cfddcd9 100644 --- a/passes/techmap/extract_reduce.cc +++ b/passes/techmap/extract_reduce.cc @@ -58,9 +58,9 @@ struct ExtractReducePass : public Pass inline bool IsRightType(Cell* cell, GateType gt) { - return (cell->type == "$_AND_" && gt == GateType::And) || - (cell->type == "$_OR_" && gt == GateType::Or) || - (cell->type == "$_XOR_" && gt == GateType::Xor); + return (cell->type == ID($_AND_) && gt == GateType::And) || + (cell->type == ID($_OR_) && gt == GateType::Or) || + (cell->type == ID($_XOR_) && gt == GateType::Xor); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE @@ -124,11 +124,11 @@ struct ExtractReducePass : public Pass GateType gt; - if (cell->type == "$_AND_") + if (cell->type == ID($_AND_)) gt = GateType::And; - else if (cell->type == "$_OR_") + else if (cell->type == ID($_OR_)) gt = GateType::Or; - else if (cell->type == "$_XOR_") + else if (cell->type == ID($_XOR_)) gt = GateType::Xor; else continue; @@ -148,7 +148,7 @@ struct ExtractReducePass : public Pass head_cell = x; - auto y = sigmap(x->getPort("\\Y")); + auto y = sigmap(x->getPort(ID::Y)); log_assert(y.size() == 1); // Should only continue if there is one fanout back into a cell (not to a port) @@ -166,7 +166,7 @@ struct ExtractReducePass : public Pass { //BFS, following all chains until they hit a cell of a different type //Pick the longest one - auto y = sigmap(cell->getPort("\\Y")); + auto y = sigmap(cell->getPort(ID::Y)); pool current_loads = sig_to_sink[y]; pool next_loads; @@ -233,7 +233,7 @@ struct ExtractReducePass : public Pass cur_supercell.insert(x); - auto a = sigmap(x->getPort("\\A")); + auto a = sigmap(x->getPort(ID::A)); log_assert(a.size() == 1); // Must have only one sink unless we're going off chain @@ -249,7 +249,7 @@ struct ExtractReducePass : public Pass } } - auto b = sigmap(x->getPort("\\B")); + auto b = sigmap(x->getPort(ID::B)); log_assert(b.size() == 1); // Must have only one sink @@ -279,26 +279,26 @@ struct ExtractReducePass : public Pass pool input_pool_intermed; for (auto x : cur_supercell) { - input_pool.insert(sigmap(x->getPort("\\A"))[0]); - input_pool.insert(sigmap(x->getPort("\\B"))[0]); - input_pool_intermed.insert(sigmap(x->getPort("\\Y"))[0]); + input_pool.insert(sigmap(x->getPort(ID::A))[0]); + input_pool.insert(sigmap(x->getPort(ID::B))[0]); + input_pool_intermed.insert(sigmap(x->getPort(ID::Y))[0]); } SigSpec input; for (auto b : input_pool) if (input_pool_intermed.count(b) == 0) input.append_bit(b); - SigBit output = sigmap(head_cell->getPort("\\Y")[0]); + SigBit output = sigmap(head_cell->getPort(ID::Y)[0]); auto new_reduce_cell = module->addCell(NEW_ID, - gt == GateType::And ? "$reduce_and" : - gt == GateType::Or ? "$reduce_or" : - gt == GateType::Xor ? "$reduce_xor" : ""); - new_reduce_cell->setParam("\\A_SIGNED", 0); - new_reduce_cell->setParam("\\A_WIDTH", input.size()); - new_reduce_cell->setParam("\\Y_WIDTH", 1); - new_reduce_cell->setPort("\\A", input); - new_reduce_cell->setPort("\\Y", output); + gt == GateType::And ? ID($reduce_and) : + gt == GateType::Or ? ID($reduce_or) : + gt == GateType::Xor ? ID($reduce_xor) : ""); + new_reduce_cell->setParam(ID(A_SIGNED), 0); + new_reduce_cell->setParam(ID(A_WIDTH), input.size()); + new_reduce_cell->setParam(ID(Y_WIDTH), 1); + new_reduce_cell->setPort(ID::A, input); + new_reduce_cell->setPort(ID::Y, output); if(allow_off_chain) consumed_cells.insert(head_cell); diff --git a/passes/techmap/flowmap.cc b/passes/techmap/flowmap.cc index f5892a60e..5807178dd 100644 --- a/passes/techmap/flowmap.cc +++ b/passes/techmap/flowmap.cc @@ -671,8 +671,8 @@ struct FlowmapWorker labels[node] = -1; for (auto input : inputs) { - if (input.wire->attributes.count("\\$flowmap_level")) - labels[input] = input.wire->attributes["\\$flowmap_level"].as_int(); + if (input.wire->attributes.count(ID($flowmap_level))) + labels[input] = input.wire->attributes[ID($flowmap_level)].as_int(); else labels[input] = 0; } @@ -783,7 +783,7 @@ struct FlowmapWorker int depth = 0; for (auto label : labels) depth = max(depth, label.second); - log("Mapped to %zu LUTs with maximum depth %d.\n", lut_nodes.size(), depth); + log("Mapped to %d LUTs with maximum depth %d.\n", GetSize(lut_nodes), depth); if (debug) { @@ -1195,7 +1195,7 @@ struct FlowmapWorker bool relax_depth_for_bound(bool first, int depth_bound, dict> &lut_critical_outputs) { - size_t initial_count = lut_nodes.size(); + int initial_count = GetSize(lut_nodes); for (auto node : lut_nodes) { @@ -1215,7 +1215,7 @@ struct FlowmapWorker if (potentials.empty()) { - log(" Relaxed to %zu (+%zu) LUTs.\n", lut_nodes.size(), lut_nodes.size() - initial_count); + log(" Relaxed to %d (+%d) LUTs.\n", GetSize(lut_nodes), GetSize(lut_nodes) - initial_count); if (!first && break_num == 1) { log(" Design fully relaxed.\n"); @@ -1412,16 +1412,16 @@ struct FlowmapWorker for (auto gate_node : lut_gates[node]) { auto gate_origin = node_origins[gate_node]; - lut->add_strpool_attribute("\\src", gate_origin.cell->get_strpool_attribute("\\src")); + lut->add_strpool_attribute(ID(src), gate_origin.cell->get_strpool_attribute(ID(src))); packed_count++; } lut_count++; lut_area += lut_table.size(); if ((int)input_nodes.size() >= minlut) - log(" Packed into a %zu-LUT %s.%s.\n", input_nodes.size(), log_id(module), log_id(lut)); + log(" Packed into a %d-LUT %s.%s.\n", GetSize(input_nodes), log_id(module), log_id(lut)); else - log(" Packed into a %zu-LUT %s.%s (implemented as %d-LUT).\n", input_nodes.size(), log_id(module), log_id(lut), minlut); + log(" Packed into a %d-LUT %s.%s (implemented as %d-LUT).\n", GetSize(input_nodes), log_id(module), log_id(lut), minlut); } for (auto node : mapped_nodes) @@ -1586,7 +1586,7 @@ struct FlowmapPass : public Pass { } else { - cell_types = {"$_NOT_", "$_AND_", "$_OR_", "$_XOR_", "$_MUX_"}; + cell_types = {ID($_NOT_), ID($_AND_), ID($_OR_), ID($_XOR_), ID($_MUX_)}; } const char *algo_r = relax ? "-r" : ""; diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index efcc082d5..a2551316f 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -179,8 +179,8 @@ struct IopadmapPass : public Pass { SigMap rewrites; for (auto cell : module->cells()) - if (cell->type == "$_TBUF_") { - SigBit bit = sigmap(cell->getPort("\\Y").as_bit()); + if (cell->type == ID($_TBUF_)) { + SigBit bit = sigmap(cell->getPort(ID::Y).as_bit()); tbuf_bits[bit].first = cell->name; } @@ -212,8 +212,8 @@ struct IopadmapPass : public Pass { if (tbuf_cell == nullptr) continue; - SigBit en_sig = tbuf_cell->getPort("\\E").as_bit(); - SigBit data_sig = tbuf_cell->getPort("\\A").as_bit(); + SigBit en_sig = tbuf_cell->getPort(ID(E)).as_bit(); + SigBit data_sig = tbuf_cell->getPort(ID::A).as_bit(); if (wire->port_input && !tinoutpad_celltype.empty()) { @@ -226,7 +226,7 @@ struct IopadmapPass : public Pass { cell->setPort(RTLIL::escape_id(tinoutpad_portname2), owire); cell->setPort(RTLIL::escape_id(tinoutpad_portname3), data_sig); cell->setPort(RTLIL::escape_id(tinoutpad_portname4), wire_bit); - cell->attributes["\\keep"] = RTLIL::Const(1); + cell->attributes[ID::keep] = RTLIL::Const(1); for (auto cn : tbuf_cache.second) { auto c = module->cell(cn); @@ -263,7 +263,7 @@ struct IopadmapPass : public Pass { cell->setPort(RTLIL::escape_id(toutpad_portname), en_sig); cell->setPort(RTLIL::escape_id(toutpad_portname2), data_sig); cell->setPort(RTLIL::escape_id(toutpad_portname3), wire_bit); - cell->attributes["\\keep"] = RTLIL::Const(1); + cell->attributes[ID::keep] = RTLIL::Const(1); for (auto cn : tbuf_cache.second) { auto c = module->cell(cn); @@ -390,7 +390,7 @@ struct IopadmapPass : public Pass { cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); if (!nameparam.empty()) cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(stringf("%s[%d]", RTLIL::id2cstr(wire->name), i)); - cell->attributes["\\keep"] = RTLIL::Const(1); + cell->attributes[ID::keep] = RTLIL::Const(1); } } else @@ -403,7 +403,7 @@ struct IopadmapPass : public Pass { cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); if (!nameparam.empty()) cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(RTLIL::id2cstr(wire->name)); - cell->attributes["\\keep"] = RTLIL::Const(1); + cell->attributes[ID::keep] = RTLIL::Const(1); } wire->port_id = 0; diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc index a4ed79550..c6618fc9d 100644 --- a/passes/techmap/lut2mux.cc +++ b/passes/techmap/lut2mux.cc @@ -25,9 +25,9 @@ PRIVATE_NAMESPACE_BEGIN int lut2mux(Cell *cell) { - SigSpec sig_a = cell->getPort("\\A"); - SigSpec sig_y = cell->getPort("\\Y"); - Const lut = cell->getParam("\\LUT"); + SigSpec sig_a = cell->getPort(ID::A); + SigSpec sig_y = cell->getPort(ID::Y); + Const lut = cell->getParam(ID(LUT)); int count = 1; if (GetSize(sig_a) == 1) @@ -81,7 +81,7 @@ struct Lut2muxPass : public Pass { for (auto module : design->selected_modules()) for (auto cell : module->selected_cells()) { - if (cell->type == "$lut") { + if (cell->type == ID($lut)) { IdString cell_name = cell->name; int count = lut2mux(cell); log("Converted %s.%s to %d MUX cells.\n", log_id(module), log_id(cell_name), count); diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc index 3e8e59e6b..09f61927c 100644 --- a/passes/techmap/maccmap.cc +++ b/passes/techmap/maccmap.cc @@ -36,7 +36,7 @@ struct MaccmapWorker void add(RTLIL::SigBit bit, int position) { - if (position >= width || bit == RTLIL::S0) + if (position >= width || bit == State::S0) return; if (bits.at(position).count(bit)) { @@ -53,7 +53,7 @@ struct MaccmapWorker if (do_subtract) { a = module->Not(NEW_ID, a); - add(RTLIL::S1, 0); + add(State::S1, 0); } for (int i = 0; i < width; i++) @@ -80,7 +80,7 @@ struct MaccmapWorker else { add(module->And(NEW_ID, a, RTLIL::SigSpec(b[i], width)), false, do_subtract); - a = {a.extract(0, width-1), RTLIL::S0}; + a = {a.extract(0, width-1), State::S0}; } } @@ -88,10 +88,10 @@ struct MaccmapWorker { int start_index = 0, stop_index = GetSize(in1); - while (start_index < stop_index && in1[start_index] == RTLIL::S0 && in2[start_index] == RTLIL::S0 && in3[start_index] == RTLIL::S0) + while (start_index < stop_index && in1[start_index] == State::S0 && in2[start_index] == RTLIL::S0 && in3[start_index] == RTLIL::S0) start_index++; - while (start_index < stop_index && in1[stop_index-1] == RTLIL::S0 && in2[stop_index-1] == RTLIL::S0 && in3[stop_index-1] == RTLIL::S0) + while (start_index < stop_index && in1[stop_index-1] == State::S0 && in2[stop_index-1] == RTLIL::S0 && in3[stop_index-1] == RTLIL::S0) stop_index--; if (start_index == stop_index) @@ -111,13 +111,13 @@ struct MaccmapWorker RTLIL::Wire *w1 = module->addWire(NEW_ID, width); RTLIL::Wire *w2 = module->addWire(NEW_ID, width); - RTLIL::Cell *cell = module->addCell(NEW_ID, "$fa"); - cell->setParam("\\WIDTH", width); - cell->setPort("\\A", in1); - cell->setPort("\\B", in2); - cell->setPort("\\C", in3); - cell->setPort("\\Y", w1); - cell->setPort("\\X", w2); + RTLIL::Cell *cell = module->addCell(NEW_ID, ID($fa)); + cell->setParam(ID(WIDTH), width); + cell->setPort(ID::A, in1); + cell->setPort(ID::B, in2); + cell->setPort(ID(C), in3); + cell->setPort(ID::Y, w1); + cell->setPort(ID(X), w2); out1 = {out_zeros_msb, w1, out_zeros_lsb}; out2 = {out_zeros_msb, w2, out_zeros_lsb}; @@ -222,7 +222,7 @@ struct MaccmapWorker RTLIL::SigSpec in3 = summands[i+2]; RTLIL::SigSpec out1, out2; fulladd(in1, in2, in3, out1, out2); - RTLIL::SigBit extra_bit = RTLIL::S0; + RTLIL::SigBit extra_bit = State::S0; if (!tree_sum_bits.empty()) { extra_bit = tree_sum_bits.back(); tree_sum_bits.pop_back(); @@ -237,23 +237,23 @@ struct MaccmapWorker } - RTLIL::Cell *c = module->addCell(NEW_ID, "$alu"); - c->setPort("\\A", summands.front()); - c->setPort("\\B", summands.back()); - c->setPort("\\CI", RTLIL::S0); - c->setPort("\\BI", RTLIL::S0); - c->setPort("\\Y", module->addWire(NEW_ID, width)); - c->setPort("\\X", module->addWire(NEW_ID, width)); - c->setPort("\\CO", module->addWire(NEW_ID, width)); + RTLIL::Cell *c = module->addCell(NEW_ID, ID($alu)); + c->setPort(ID::A, summands.front()); + c->setPort(ID::B, summands.back()); + c->setPort(ID(CI), State::S0); + c->setPort(ID(BI), State::S0); + c->setPort(ID::Y, module->addWire(NEW_ID, width)); + c->setPort(ID(X), module->addWire(NEW_ID, width)); + c->setPort(ID(CO), module->addWire(NEW_ID, width)); c->fixup_parameters(); if (!tree_sum_bits.empty()) { - c->setPort("\\CI", tree_sum_bits.back()); + c->setPort(ID(CI), tree_sum_bits.back()); tree_sum_bits.pop_back(); } log_assert(tree_sum_bits.empty()); - return c->getPort("\\Y"); + return c->getPort(ID::Y); } }; @@ -264,17 +264,17 @@ extern void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap = false void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap) { - int width = GetSize(cell->getPort("\\Y")); + int width = GetSize(cell->getPort(ID::Y)); Macc macc; macc.from_cell(cell); RTLIL::SigSpec all_input_bits; - all_input_bits.append(cell->getPort("\\A")); - all_input_bits.append(cell->getPort("\\B")); + all_input_bits.append(cell->getPort(ID::A)); + all_input_bits.append(cell->getPort(ID::B)); if (all_input_bits.to_sigbit_set().count(RTLIL::Sx)) { - module->connect(cell->getPort("\\Y"), RTLIL::SigSpec(RTLIL::Sx, width)); + module->connect(cell->getPort(ID::Y), RTLIL::SigSpec(RTLIL::Sx, width)); return; } @@ -339,9 +339,9 @@ void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap) } if (summands.front().second) - module->addNeg(NEW_ID, summands.front().first, cell->getPort("\\Y")); + module->addNeg(NEW_ID, summands.front().first, cell->getPort(ID::Y)); else - module->connect(cell->getPort("\\Y"), summands.front().first); + module->connect(cell->getPort(ID::Y), summands.front().first); } else { @@ -356,7 +356,7 @@ void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap) for (auto &bit : macc.bit_ports) worker.add(bit, 0); - module->connect(cell->getPort("\\Y"), worker.synth()); + module->connect(cell->getPort(ID::Y), worker.synth()); } } @@ -393,7 +393,7 @@ struct MaccmapPass : public Pass { for (auto mod : design->selected_modules()) for (auto cell : mod->selected_cells()) - if (cell->type == "$macc") { + if (cell->type == ID($macc)) { log("Mapping %s.%s (%s).\n", log_id(mod), log_id(cell), log_id(cell->type)); maccmap(mod, cell, unmap_mode); mod->remove(cell); diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index d53378a29..5541b6122 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -116,13 +116,13 @@ struct MuxcoverWorker if (!cell->input(conn.first)) continue; for (auto bit : sigmap(conn.second)) { - if (used_once.count(bit) || cell->type != "$_MUX_" || conn.first == "\\S") + if (used_once.count(bit) || cell->type != ID($_MUX_) || conn.first == ID(S)) roots.insert(bit); used_once.insert(bit); } } - if (cell->type == "$_MUX_") - sig_to_mux[sigmap(cell->getPort("\\Y"))] = cell; + if (cell->type == ID($_MUX_)) + sig_to_mux[sigmap(cell->getPort(ID::Y))] = cell; } log(" Treeifying %d MUXes:\n", GetSize(sig_to_mux)); @@ -141,8 +141,8 @@ struct MuxcoverWorker if (sig_to_mux.count(bit) && (bit == rootsig || !roots.count(bit))) { Cell *c = sig_to_mux.at(bit); tree.muxes[bit] = c; - wavefront.insert(sigmap(c->getPort("\\A"))); - wavefront.insert(sigmap(c->getPort("\\B"))); + wavefront.insert(sigmap(c->getPort(ID::A))); + wavefront.insert(sigmap(c->getPort(ID::B))); } } @@ -516,69 +516,69 @@ struct MuxcoverWorker if (GetSize(mux.inputs) == 2) { count_muxes_by_type[0]++; - Cell *cell = module->addCell(NEW_ID, "$_MUX_"); - cell->setPort("\\A", mux.inputs[0]); - cell->setPort("\\B", mux.inputs[1]); - cell->setPort("\\S", mux.selects[0]); - cell->setPort("\\Y", bit); + Cell *cell = module->addCell(NEW_ID, ID($_MUX_)); + cell->setPort(ID::A, mux.inputs[0]); + cell->setPort(ID::B, mux.inputs[1]); + cell->setPort(ID(S), mux.selects[0]); + cell->setPort(ID::Y, bit); return; } if (GetSize(mux.inputs) == 4) { count_muxes_by_type[1]++; - Cell *cell = module->addCell(NEW_ID, "$_MUX4_"); - cell->setPort("\\A", mux.inputs[0]); - cell->setPort("\\B", mux.inputs[1]); - cell->setPort("\\C", mux.inputs[2]); - cell->setPort("\\D", mux.inputs[3]); - cell->setPort("\\S", mux.selects[0]); - cell->setPort("\\T", mux.selects[1]); - cell->setPort("\\Y", bit); + Cell *cell = module->addCell(NEW_ID, ID($_MUX4_)); + cell->setPort(ID::A, mux.inputs[0]); + cell->setPort(ID::B, mux.inputs[1]); + cell->setPort(ID(C), mux.inputs[2]); + cell->setPort(ID(D), mux.inputs[3]); + cell->setPort(ID(S), mux.selects[0]); + cell->setPort(ID(T), mux.selects[1]); + cell->setPort(ID::Y, bit); return; } if (GetSize(mux.inputs) == 8) { count_muxes_by_type[2]++; - Cell *cell = module->addCell(NEW_ID, "$_MUX8_"); - cell->setPort("\\A", mux.inputs[0]); - cell->setPort("\\B", mux.inputs[1]); - cell->setPort("\\C", mux.inputs[2]); - cell->setPort("\\D", mux.inputs[3]); - cell->setPort("\\E", mux.inputs[4]); - cell->setPort("\\F", mux.inputs[5]); - cell->setPort("\\G", mux.inputs[6]); - cell->setPort("\\H", mux.inputs[7]); - cell->setPort("\\S", mux.selects[0]); - cell->setPort("\\T", mux.selects[1]); - cell->setPort("\\U", mux.selects[2]); - cell->setPort("\\Y", bit); + Cell *cell = module->addCell(NEW_ID, ID($_MUX8_)); + cell->setPort(ID::A, mux.inputs[0]); + cell->setPort(ID::B, mux.inputs[1]); + cell->setPort(ID(C), mux.inputs[2]); + cell->setPort(ID(D), mux.inputs[3]); + cell->setPort(ID(E), mux.inputs[4]); + cell->setPort(ID(F), mux.inputs[5]); + cell->setPort(ID(G), mux.inputs[6]); + cell->setPort(ID(H), mux.inputs[7]); + cell->setPort(ID(S), mux.selects[0]); + cell->setPort(ID(T), mux.selects[1]); + cell->setPort(ID(U), mux.selects[2]); + cell->setPort(ID::Y, bit); return; } if (GetSize(mux.inputs) == 16) { count_muxes_by_type[3]++; - Cell *cell = module->addCell(NEW_ID, "$_MUX16_"); - cell->setPort("\\A", mux.inputs[0]); - cell->setPort("\\B", mux.inputs[1]); - cell->setPort("\\C", mux.inputs[2]); - cell->setPort("\\D", mux.inputs[3]); - cell->setPort("\\E", mux.inputs[4]); - cell->setPort("\\F", mux.inputs[5]); - cell->setPort("\\G", mux.inputs[6]); - cell->setPort("\\H", mux.inputs[7]); - cell->setPort("\\I", mux.inputs[8]); - cell->setPort("\\J", mux.inputs[9]); - cell->setPort("\\K", mux.inputs[10]); - cell->setPort("\\L", mux.inputs[11]); - cell->setPort("\\M", mux.inputs[12]); - cell->setPort("\\N", mux.inputs[13]); - cell->setPort("\\O", mux.inputs[14]); - cell->setPort("\\P", mux.inputs[15]); - cell->setPort("\\S", mux.selects[0]); - cell->setPort("\\T", mux.selects[1]); - cell->setPort("\\U", mux.selects[2]); - cell->setPort("\\V", mux.selects[3]); - cell->setPort("\\Y", bit); + Cell *cell = module->addCell(NEW_ID, ID($_MUX16_)); + cell->setPort(ID::A, mux.inputs[0]); + cell->setPort(ID::B, mux.inputs[1]); + cell->setPort(ID(C), mux.inputs[2]); + cell->setPort(ID(D), mux.inputs[3]); + cell->setPort(ID(E), mux.inputs[4]); + cell->setPort(ID(F), mux.inputs[5]); + cell->setPort(ID(G), mux.inputs[6]); + cell->setPort(ID(H), mux.inputs[7]); + cell->setPort(ID(I), mux.inputs[8]); + cell->setPort(ID(J), mux.inputs[9]); + cell->setPort(ID(K), mux.inputs[10]); + cell->setPort(ID(L), mux.inputs[11]); + cell->setPort(ID(M), mux.inputs[12]); + cell->setPort(ID(N), mux.inputs[13]); + cell->setPort(ID(O), mux.inputs[14]); + cell->setPort(ID(P), mux.inputs[15]); + cell->setPort(ID(S), mux.selects[0]); + cell->setPort(ID(T), mux.selects[1]); + cell->setPort(ID(U), mux.selects[2]); + cell->setPort(ID(V), mux.selects[3]); + cell->setPort(ID::Y, bit); return; } @@ -675,36 +675,36 @@ struct MuxcoverPass : public Pass { for (argidx = 1; argidx < args.size(); argidx++) { const auto &arg = args[argidx]; - if (arg.size() >= 6 && arg.substr(0,6) == "-mux2=") { - cost_mux2 = std::stoi(arg.substr(6)); + if (arg.size() >= 6 && arg.compare(0,6,"-mux2=") == 0) { + cost_mux2 = atoi(arg.substr(6).c_str()); continue; } - if (arg.size() >= 5 && arg.substr(0,5) == "-mux4") { + if (arg.size() >= 5 && arg.compare(0,5,"-mux4") == 0) { use_mux4 = true; if (arg.size() > 5) { if (arg[5] != '=') break; - cost_mux4 = std::stoi(arg.substr(6)); + cost_mux4 = atoi(arg.substr(6).c_str()); } continue; } - if (arg.size() >= 5 && arg.substr(0,5) == "-mux8") { + if (arg.size() >= 5 && arg.compare(0,5,"-mux8") == 0) { use_mux8 = true; if (arg.size() > 5) { if (arg[5] != '=') break; - cost_mux8 = std::stoi(arg.substr(6)); + cost_mux8 = atoi(arg.substr(6).c_str()); } continue; } - if (arg.size() >= 6 && arg.substr(0,6) == "-mux16") { + if (arg.size() >= 6 && arg.compare(0,6,"-mux16") == 0) { use_mux16 = true; if (arg.size() > 6) { if (arg[6] != '=') break; - cost_mux16 = std::stoi(arg.substr(7)); + cost_mux16 = atoi(arg.substr(7).c_str()); } continue; } - if (arg.size() >= 6 && arg.substr(0,6) == "-dmux=") { - cost_dmux = std::stoi(arg.substr(6)); + if (arg.size() >= 6 && arg.compare(0,6,"-dmux=") == 0) { + cost_dmux = atoi(arg.substr(6).c_str()); continue; } if (arg == "-nodecode") { diff --git a/passes/techmap/nlutmap.cc b/passes/techmap/nlutmap.cc index cc765d89c..798d82248 100644 --- a/passes/techmap/nlutmap.cc +++ b/passes/techmap/nlutmap.cc @@ -82,10 +82,10 @@ struct NlutmapWorker for (auto cell : module->cells()) { - if (cell->type != "$lut" || mapped_cells.count(cell)) + if (cell->type != ID($lut) || mapped_cells.count(cell)) continue; - if (GetSize(cell->getPort("\\A")) == lut_size || lut_size == 2) + if (GetSize(cell->getPort(ID::A)) == lut_size || lut_size == 2) candidate_ratings[cell] = 0; for (auto &conn : cell->connections()) @@ -119,7 +119,7 @@ struct NlutmapWorker if (config.assert_mode) { for (auto cell : module->cells()) - if (cell->type == "$lut" && !mapped_cells.count(cell)) + if (cell->type == ID($lut) && !mapped_cells.count(cell)) log_error("Insufficient number of LUTs to map all logic cells!\n"); } diff --git a/passes/techmap/pmuxtree.cc b/passes/techmap/pmuxtree.cc index 6a923f481..31ab13cec 100644 --- a/passes/techmap/pmuxtree.cc +++ b/passes/techmap/pmuxtree.cc @@ -89,21 +89,21 @@ struct PmuxtreePass : public Pass { for (auto module : design->selected_modules()) for (auto cell : module->selected_cells()) { - if (cell->type != "$pmux") + if (cell->type != ID($pmux)) continue; - SigSpec sig_data = cell->getPort("\\B"); - SigSpec sig_sel = cell->getPort("\\S"); + SigSpec sig_data = cell->getPort(ID::B); + SigSpec sig_sel = cell->getPort(ID(S)); - if (!cell->getPort("\\A").is_fully_undef()) { - sig_data.append(cell->getPort("\\A")); + if (!cell->getPort(ID::A).is_fully_undef()) { + sig_data.append(cell->getPort(ID::A)); SigSpec sig_sel_or = module->ReduceOr(NEW_ID, sig_sel); sig_sel.append(module->Not(NEW_ID, sig_sel_or)); } SigSpec result, result_or; result = recursive_mux_generator(module, sig_data, sig_sel, result_or); - module->connect(cell->getPort("\\Y"), result); + module->connect(cell->getPort(ID::Y), result); module->remove(cell); } } diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 004ab1eb9..5e298d8dd 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -73,22 +73,22 @@ struct ShregmapTechGreenpak4 : ShregmapTech bool fixup(Cell *cell, dict &taps) { - auto D = cell->getPort("\\D"); - auto C = cell->getPort("\\C"); + auto D = cell->getPort(ID(D)); + auto C = cell->getPort(ID(C)); - auto newcell = cell->module->addCell(NEW_ID, "\\GP_SHREG"); - newcell->setPort("\\nRST", State::S1); - newcell->setPort("\\CLK", C); - newcell->setPort("\\IN", D); + auto newcell = cell->module->addCell(NEW_ID, ID(GP_SHREG)); + newcell->setPort(ID(nRST), State::S1); + newcell->setPort(ID(CLK), C); + newcell->setPort(ID(IN), D); int i = 0; for (auto tap : taps) { - newcell->setPort(i ? "\\OUTB" : "\\OUTA", tap.second); - newcell->setParam(i ? "\\OUTB_TAP" : "\\OUTA_TAP", tap.first + 1); + newcell->setPort(i ? ID(OUTB) : ID(OUTA), tap.second); + newcell->setParam(i ? ID(OUTB_TAP) : ID(OUTA_TAP), tap.first + 1); i++; } - cell->setParam("\\OUTA_INVERT", 0); + cell->setParam(ID(OUTA_INVERT), 0); return false; } }; @@ -104,19 +104,19 @@ struct ShregmapTechXilinx7 : ShregmapTech { for (const auto &i : module->cells_) { auto cell = i.second; - if (cell->type == "$shiftx") { - if (cell->getParam("\\Y_WIDTH") != 1) continue; + if (cell->type == ID($shiftx)) { + if (cell->getParam(ID(Y_WIDTH)) != 1) continue; int j = 0; - for (auto bit : sigmap(cell->getPort("\\A"))) + for (auto bit : sigmap(cell->getPort(ID::A))) sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, j++, 0); - log_assert(j == cell->getParam("\\A_WIDTH").as_int()); + log_assert(j == cell->getParam(ID(A_WIDTH)).as_int()); } - else if (cell->type == "$mux") { + else if (cell->type == ID($mux)) { int j = 0; - for (auto bit : sigmap(cell->getPort("\\A"))) + for (auto bit : sigmap(cell->getPort(ID::A))) sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 0, j++); j = 0; - for (auto bit : sigmap(cell->getPort("\\B"))) + for (auto bit : sigmap(cell->getPort(ID::B))) sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 1, j++); } } @@ -128,9 +128,9 @@ struct ShregmapTechXilinx7 : ShregmapTech if (it == sigbit_to_shiftx_offset.end()) return; if (cell) { - if (cell->type == "$shiftx" && port == "\\A") + if (cell->type == ID($shiftx) && port == ID::A) return; - if (cell->type == "$mux" && (port == "\\A" || port == "\\B")) + if (cell->type == ID($mux) && port.in(ID::A, ID::B)) return; } sigbit_to_shiftx_offset.erase(it); @@ -177,21 +177,21 @@ struct ShregmapTechXilinx7 : ShregmapTech log_assert(shiftx); // Only map if $shiftx exclusively covers the shift register - if (shiftx->type == "$shiftx") { - if (GetSize(taps) > shiftx->getParam("\\A_WIDTH").as_int()) + if (shiftx->type == ID($shiftx)) { + if (GetSize(taps) > shiftx->getParam(ID(A_WIDTH)).as_int()) return false; // Due to padding the most significant bits of A may be 1'bx, // and if so, discount them - if (GetSize(taps) < shiftx->getParam("\\A_WIDTH").as_int()) { - const SigSpec A = shiftx->getPort("\\A"); - const int A_width = shiftx->getParam("\\A_WIDTH").as_int(); + if (GetSize(taps) < shiftx->getParam(ID(A_WIDTH)).as_int()) { + const SigSpec A = shiftx->getPort(ID::A); + const int A_width = shiftx->getParam(ID(A_WIDTH)).as_int(); for (int i = GetSize(taps); i < A_width; ++i) if (A[i] != RTLIL::Sx) return false; } - else if (GetSize(taps) != shiftx->getParam("\\A_WIDTH").as_int()) + else if (GetSize(taps) != shiftx->getParam(ID(A_WIDTH)).as_int()) return false; } - else if (shiftx->type == "$mux") { + else if (shiftx->type == ID($mux)) { if (GetSize(taps) != 2) return false; } @@ -208,34 +208,34 @@ struct ShregmapTechXilinx7 : ShregmapTech auto it = sigbit_to_shiftx_offset.find(bit); log_assert(it != sigbit_to_shiftx_offset.end()); - auto newcell = cell->module->addCell(NEW_ID, "$__XILINX_SHREG_"); + auto newcell = cell->module->addCell(NEW_ID, ID($__XILINX_SHREG_)); newcell->set_src_attribute(cell->get_src_attribute()); - newcell->setParam("\\DEPTH", cell->getParam("\\DEPTH")); - newcell->setParam("\\INIT", cell->getParam("\\INIT")); - newcell->setParam("\\CLKPOL", cell->getParam("\\CLKPOL")); - newcell->setParam("\\ENPOL", cell->getParam("\\ENPOL")); + newcell->setParam(ID(DEPTH), cell->getParam(ID(DEPTH))); + newcell->setParam(ID(INIT), cell->getParam(ID(INIT))); + newcell->setParam(ID(CLKPOL), cell->getParam(ID(CLKPOL))); + newcell->setParam(ID(ENPOL), cell->getParam(ID(ENPOL))); - newcell->setPort("\\C", cell->getPort("\\C")); - newcell->setPort("\\D", cell->getPort("\\D")); - if (cell->hasPort("\\E")) - newcell->setPort("\\E", cell->getPort("\\E")); + newcell->setPort(ID(C), cell->getPort(ID(C))); + newcell->setPort(ID(D), cell->getPort(ID(D))); + if (cell->hasPort(ID(E))) + newcell->setPort(ID(E), cell->getPort(ID(E))); Cell* shiftx = std::get<0>(it->second); RTLIL::SigSpec l_wire, q_wire; - if (shiftx->type == "$shiftx") { - l_wire = shiftx->getPort("\\B"); - q_wire = shiftx->getPort("\\Y"); - shiftx->setPort("\\Y", cell->module->addWire(NEW_ID)); + if (shiftx->type == ID($shiftx)) { + l_wire = shiftx->getPort(ID::B); + q_wire = shiftx->getPort(ID::Y); + shiftx->setPort(ID::Y, cell->module->addWire(NEW_ID)); } - else if (shiftx->type == "$mux") { - l_wire = shiftx->getPort("\\S"); - q_wire = shiftx->getPort("\\Y"); - shiftx->setPort("\\Y", cell->module->addWire(NEW_ID)); + else if (shiftx->type == ID($mux)) { + l_wire = shiftx->getPort(ID(S)); + q_wire = shiftx->getPort(ID::Y); + shiftx->setPort(ID::Y, cell->module->addWire(NEW_ID)); } else log_abort(); - newcell->setPort("\\Q", q_wire); - newcell->setPort("\\L", l_wire); + newcell->setPort(ID(Q), q_wire); + newcell->setPort(ID(L), l_wire); return false; } @@ -263,16 +263,16 @@ struct ShregmapWorker { for (auto wire : module->wires()) { - if (wire->port_output || wire->get_bool_attribute("\\keep")) { + if (wire->port_output || wire->get_bool_attribute(ID::keep)) { for (auto bit : sigmap(wire)) { sigbit_with_non_chain_users.insert(bit); if (opts.tech) opts.tech->non_chain_user(bit, nullptr, {}); } } - if (wire->attributes.count("\\init")) { + if (wire->attributes.count(ID(init))) { SigSpec initsig = sigmap(wire); - Const initval = wire->attributes.at("\\init"); + 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; @@ -283,7 +283,7 @@ struct ShregmapWorker for (auto cell : module->cells()) { - if (opts.ffcells.count(cell->type) && !cell->get_bool_attribute("\\keep")) + if (opts.ffcells.count(cell->type) && !cell->get_bool_attribute(ID::keep)) { IdString d_port = opts.ffcells.at(cell->type).first; IdString q_port = opts.ffcells.at(cell->type).second; @@ -474,7 +474,7 @@ struct ShregmapWorker initval.push_back(State::S0); remove_init.insert(bit); } - first_cell->setParam("\\INIT", initval); + first_cell->setParam(ID(INIT), initval); } if (opts.zinit) @@ -488,22 +488,22 @@ struct ShregmapWorker int param_clkpol = -1; int param_enpol = 2; - if (first_cell->type == "$_DFF_N_") param_clkpol = 0; - if (first_cell->type == "$_DFF_P_") param_clkpol = 1; + if (first_cell->type == ID($_DFF_N_)) param_clkpol = 0; + if (first_cell->type == ID($_DFF_P_)) param_clkpol = 1; - if (first_cell->type == "$_DFFE_NN_") param_clkpol = 0, param_enpol = 0; - if (first_cell->type == "$_DFFE_NP_") param_clkpol = 0, param_enpol = 1; - if (first_cell->type == "$_DFFE_PN_") param_clkpol = 1, param_enpol = 0; - if (first_cell->type == "$_DFFE_PP_") param_clkpol = 1, param_enpol = 1; + if (first_cell->type == ID($_DFFE_NN_)) param_clkpol = 0, param_enpol = 0; + if (first_cell->type == ID($_DFFE_NP_)) param_clkpol = 0, param_enpol = 1; + if (first_cell->type == ID($_DFFE_PN_)) param_clkpol = 1, param_enpol = 0; + if (first_cell->type == ID($_DFFE_PP_)) param_clkpol = 1, param_enpol = 1; log_assert(param_clkpol >= 0); - first_cell->setParam("\\CLKPOL", param_clkpol); - if (opts.ffe) first_cell->setParam("\\ENPOL", param_enpol); + first_cell->setParam(ID(CLKPOL), param_clkpol); + if (opts.ffe) first_cell->setParam(ID(ENPOL), param_enpol); } first_cell->type = shreg_cell_type_str; first_cell->setPort(q_port, last_cell->getPort(q_port)); - first_cell->setParam("\\DEPTH", depth); + first_cell->setParam(ID(DEPTH), depth); if (opts.tech != nullptr && !opts.tech->fixup(first_cell, taps_dict)) remove_cells.insert(first_cell); @@ -521,18 +521,18 @@ struct ShregmapWorker for (auto wire : module->wires()) { - if (wire->attributes.count("\\init") == 0) + if (wire->attributes.count(ID(init)) == 0) continue; SigSpec initsig = sigmap(wire); - Const &initval = wire->attributes.at("\\init"); + 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("\\init"); + wire->attributes.erase(ID(init)); } remove_cells.clear(); @@ -717,19 +717,19 @@ struct ShregmapPass : public Pass { bool en_neg = enpol == "neg" || enpol == "any" || enpol == "any_or_none"; if (clk_pos && en_none) - opts.ffcells["$_DFF_P_"] = make_pair(IdString("\\D"), IdString("\\Q")); + opts.ffcells[ID($_DFF_P_)] = make_pair(IdString(ID(D)), IdString(ID(Q))); if (clk_neg && en_none) - opts.ffcells["$_DFF_N_"] = make_pair(IdString("\\D"), IdString("\\Q")); + opts.ffcells[ID($_DFF_N_)] = make_pair(IdString(ID(D)), IdString(ID(Q))); if (clk_pos && en_pos) - opts.ffcells["$_DFFE_PP_"] = make_pair(IdString("\\D"), IdString("\\Q")); + opts.ffcells[ID($_DFFE_PP_)] = make_pair(IdString(ID(D)), IdString(ID(Q))); if (clk_pos && en_neg) - opts.ffcells["$_DFFE_PN_"] = make_pair(IdString("\\D"), IdString("\\Q")); + opts.ffcells[ID($_DFFE_PN_)] = make_pair(IdString(ID(D)), IdString(ID(Q))); if (clk_neg && en_pos) - opts.ffcells["$_DFFE_NP_"] = make_pair(IdString("\\D"), IdString("\\Q")); + opts.ffcells[ID($_DFFE_NP_)] = make_pair(IdString(ID(D)), IdString(ID(Q))); if (clk_neg && en_neg) - opts.ffcells["$_DFFE_NN_"] = make_pair(IdString("\\D"), IdString("\\Q")); + opts.ffcells[ID($_DFFE_NN_)] = make_pair(IdString(ID(D)), IdString(ID(Q))); if (en_pos || en_neg) opts.ffe = true; diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index f3da80c66..91574f3c6 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -28,82 +28,82 @@ YOSYS_NAMESPACE_BEGIN void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); - sig_a.extend_u0(GetSize(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); + sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool()); for (int i = 0; i < GetSize(sig_y); i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\A", sig_a[i]); - gate->setPort("\\Y", sig_y[i]); + RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_)); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID::A, sig_a[i]); + gate->setPort(ID::Y, sig_y[i]); } } void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); - sig_a.extend_u0(GetSize(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); + sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool()); module->connect(RTLIL::SigSig(sig_y, sig_a)); } void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); - sig_a.extend_u0(GetSize(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); - sig_b.extend_u0(GetSize(sig_y), cell->parameters.at("\\B_SIGNED").as_bool()); + sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool()); + sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID(B_SIGNED)).as_bool()); - if (cell->type == "$xnor") + if (cell->type == ID($xnor)) { RTLIL::SigSpec sig_t = module->addWire(NEW_ID, GetSize(sig_y)); for (int i = 0; i < GetSize(sig_y); i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\A", sig_t[i]); - gate->setPort("\\Y", sig_y[i]); + RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_)); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID::A, sig_t[i]); + gate->setPort(ID::Y, sig_y[i]); } sig_y = sig_t; } - std::string gate_type; - if (cell->type == "$and") gate_type = "$_AND_"; - if (cell->type == "$or") gate_type = "$_OR_"; - if (cell->type == "$xor") gate_type = "$_XOR_"; - if (cell->type == "$xnor") gate_type = "$_XOR_"; + IdString gate_type; + if (cell->type == ID($and)) gate_type = ID($_AND_); + if (cell->type == ID($or)) gate_type = ID($_OR_); + if (cell->type == ID($xor)) gate_type = ID($_XOR_); + if (cell->type == ID($xnor)) gate_type = ID($_XOR_); log_assert(!gate_type.empty()); for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\A", sig_a[i]); - gate->setPort("\\B", sig_b[i]); - gate->setPort("\\Y", sig_y[i]); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID::A, sig_a[i]); + gate->setPort(ID::B, sig_b[i]); + gate->setPort(ID::Y, sig_y[i]); } } void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); if (sig_y.size() == 0) return; if (sig_a.size() == 0) { - if (cell->type == "$reduce_and") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); - if (cell->type == "$reduce_or") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); - if (cell->type == "$reduce_xor") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); - if (cell->type == "$reduce_xnor") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); - if (cell->type == "$reduce_bool") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type == ID($reduce_and)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); + if (cell->type == ID($reduce_or)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type == ID($reduce_xor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type == ID($reduce_xnor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); + if (cell->type == ID($reduce_bool)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); return; } @@ -112,12 +112,12 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) sig_y = sig_y.extract(0, 1); } - std::string gate_type; - if (cell->type == "$reduce_and") gate_type = "$_AND_"; - if (cell->type == "$reduce_or") gate_type = "$_OR_"; - if (cell->type == "$reduce_xor") gate_type = "$_XOR_"; - if (cell->type == "$reduce_xnor") gate_type = "$_XOR_"; - if (cell->type == "$reduce_bool") gate_type = "$_OR_"; + IdString gate_type; + if (cell->type == ID($reduce_and)) gate_type = ID($_AND_); + if (cell->type == ID($reduce_or)) gate_type = ID($_OR_); + if (cell->type == ID($reduce_xor)) gate_type = ID($_XOR_); + if (cell->type == ID($reduce_xnor)) gate_type = ID($_XOR_); + if (cell->type == ID($reduce_bool)) gate_type = ID($_OR_); log_assert(!gate_type.empty()); RTLIL::Cell *last_output_cell = NULL; @@ -134,22 +134,22 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) } RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\A", sig_a[i]); - gate->setPort("\\B", sig_a[i+1]); - gate->setPort("\\Y", sig_t[i/2]); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID::A, sig_a[i]); + gate->setPort(ID::B, sig_a[i+1]); + gate->setPort(ID::Y, sig_t[i/2]); last_output_cell = gate; } sig_a = sig_t; } - if (cell->type == "$reduce_xnor") { + if (cell->type == ID($reduce_xnor)) { RTLIL::SigSpec sig_t = module->addWire(NEW_ID); - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\A", sig_a); - gate->setPort("\\Y", sig_t); + RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_)); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID::A, sig_a); + gate->setPort(ID::Y, sig_t); last_output_cell = gate; sig_a = sig_t; } @@ -157,7 +157,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) if (last_output_cell == NULL) { module->connect(RTLIL::SigSig(sig_y, sig_a)); } else { - last_output_cell->setPort("\\Y", sig_y); + last_output_cell->setPort(ID::Y, sig_y); } } @@ -174,26 +174,26 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell continue; } - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_OR_"); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\A", sig[i]); - gate->setPort("\\B", sig[i+1]); - gate->setPort("\\Y", sig_t[i/2]); + RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_OR_)); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID::A, sig[i]); + gate->setPort(ID::B, sig[i+1]); + gate->setPort(ID::Y, sig_t[i/2]); } sig = sig_t; } if (sig.size() == 0) - sig = RTLIL::SigSpec(0, 1); + sig = State::S0; } void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); logic_reduce(module, sig_a, cell); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); if (sig_y.size() == 0) return; @@ -203,21 +203,21 @@ void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) sig_y = sig_y.extract(0, 1); } - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\A", sig_a); - gate->setPort("\\Y", sig_y); + RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_)); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID::A, sig_a); + gate->setPort(ID::Y, sig_y); } void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); logic_reduce(module, sig_a, cell); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); logic_reduce(module, sig_b, cell); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); if (sig_y.size() == 0) return; @@ -227,41 +227,41 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) sig_y = sig_y.extract(0, 1); } - std::string gate_type; - if (cell->type == "$logic_and") gate_type = "$_AND_"; - if (cell->type == "$logic_or") gate_type = "$_OR_"; + IdString gate_type; + if (cell->type == ID($logic_and)) gate_type = ID($_AND_); + if (cell->type == ID($logic_or)) gate_type = ID($_OR_); log_assert(!gate_type.empty()); RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\A", sig_a); - gate->setPort("\\B", sig_b); - gate->setPort("\\Y", sig_y); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID::A, sig_a); + gate->setPort(ID::B, sig_b); + gate->setPort(ID::Y, sig_y); } void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); - bool is_signed = cell->parameters.at("\\A_SIGNED").as_bool(); - bool is_ne = cell->type == "$ne" || cell->type == "$nex"; + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); + bool is_signed = cell->parameters.at(ID(A_SIGNED)).as_bool(); + bool is_ne = cell->type.in(ID($ne), ID($nex)); RTLIL::SigSpec xor_out = module->addWire(NEW_ID, max(GetSize(sig_a), GetSize(sig_b))); RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed); - xor_cell->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); + xor_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); simplemap_bitop(module, xor_cell); module->remove(xor_cell); RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID); RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID, xor_out, reduce_out); - reduce_cell->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); + reduce_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); simplemap_reduce(module, reduce_cell); module->remove(reduce_cell); if (!is_ne) { RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID, reduce_out, sig_y); - not_cell->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); + not_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); simplemap_lognot(module, not_cell); module->remove(not_cell); } @@ -269,65 +269,65 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell) void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); for (int i = 0; i < GetSize(sig_y); i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_MUX_"); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\A", sig_a[i]); - gate->setPort("\\B", sig_b[i]); - gate->setPort("\\S", cell->getPort("\\S")); - gate->setPort("\\Y", sig_y[i]); + RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_)); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID::A, sig_a[i]); + gate->setPort(ID::B, sig_b[i]); + gate->setPort(ID(S), cell->getPort(ID(S))); + gate->setPort(ID::Y, sig_y[i]); } } void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_e = cell->getPort("\\EN"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_e = cell->getPort(ID(EN)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); for (int i = 0; i < GetSize(sig_y); i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_TBUF_"); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\A", sig_a[i]); - gate->setPort("\\E", sig_e); - gate->setPort("\\Y", sig_y[i]); + RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_TBUF_)); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID::A, sig_a[i]); + gate->setPort(ID(E), sig_e); + gate->setPort(ID::Y, sig_y[i]); } } void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell) { - SigSpec lut_ctrl = cell->getPort("\\A"); - SigSpec lut_data = cell->getParam("\\LUT"); - lut_data.extend_u0(1 << cell->getParam("\\WIDTH").as_int()); + SigSpec lut_ctrl = cell->getPort(ID::A); + SigSpec lut_data = cell->getParam(ID(LUT)); + lut_data.extend_u0(1 << cell->getParam(ID(WIDTH)).as_int()); for (int idx = 0; GetSize(lut_data) > 1; idx++) { SigSpec sig_s = lut_ctrl[idx]; SigSpec new_lut_data = module->addWire(NEW_ID, GetSize(lut_data)/2); for (int i = 0; i < GetSize(lut_data); i += 2) { - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_MUX_"); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\A", lut_data[i]); - gate->setPort("\\B", lut_data[i+1]); - gate->setPort("\\S", lut_ctrl[idx]); - gate->setPort("\\Y", new_lut_data[i/2]); + RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_)); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID::A, lut_data[i]); + gate->setPort(ID::B, lut_data[i+1]); + gate->setPort(ID(S), lut_ctrl[idx]); + gate->setPort(ID::Y, new_lut_data[i/2]); } lut_data = new_lut_data; } - module->connect(cell->getPort("\\Y"), lut_data); + module->connect(cell->getPort(ID::Y), lut_data); } void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell) { - SigSpec ctrl = cell->getPort("\\A"); - SigSpec table = cell->getParam("\\TABLE"); + SigSpec ctrl = cell->getPort(ID::A); + SigSpec table = cell->getParam(ID(TABLE)); - int width = cell->getParam("\\WIDTH").as_int(); - int depth = cell->getParam("\\DEPTH").as_int(); + int width = cell->getParam(ID(WIDTH)).as_int(); + int depth = cell->getParam(ID(DEPTH)).as_int(); table.extend_u0(2 * width * depth); SigSpec products; @@ -348,213 +348,213 @@ void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell) products.append(GetSize(in) > 0 ? module->Eq(NEW_ID, in, pat) : State::S1); } - module->connect(cell->getPort("\\Y"), module->ReduceOr(NEW_ID, products)); + module->connect(cell->getPort(ID::Y), module->ReduceOr(NEW_ID, products)); } void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell) { - int offset = cell->parameters.at("\\OFFSET").as_int(); - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + int offset = cell->parameters.at(ID(OFFSET)).as_int(); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); module->connect(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size()))); } void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_ab = cell->getPort("\\A"); - sig_ab.append(cell->getPort("\\B")); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + RTLIL::SigSpec sig_ab = cell->getPort(ID::A); + sig_ab.append(cell->getPort(ID::B)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); module->connect(RTLIL::SigSig(sig_y, sig_ab)); } void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at("\\WIDTH").as_int(); - char set_pol = cell->parameters.at("\\SET_POLARITY").as_bool() ? 'P' : 'N'; - char clr_pol = cell->parameters.at("\\CLR_POLARITY").as_bool() ? 'P' : 'N'; + int width = cell->parameters.at(ID(WIDTH)).as_int(); + 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_s = cell->getPort("\\SET"); - RTLIL::SigSpec sig_r = cell->getPort("\\CLR"); - RTLIL::SigSpec sig_q = cell->getPort("\\Q"); + RTLIL::SigSpec sig_s = cell->getPort(ID(SET)); + RTLIL::SigSpec sig_r = cell->getPort(ID(CLR)); + RTLIL::SigSpec sig_q = cell->getPort(ID(Q)); std::string gate_type = stringf("$_SR_%c%c_", set_pol, clr_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\S", sig_s[i]); - gate->setPort("\\R", sig_r[i]); - gate->setPort("\\Q", sig_q[i]); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID(S), sig_s[i]); + gate->setPort(ID(R), sig_r[i]); + gate->setPort(ID(Q), sig_q[i]); } } void simplemap_ff(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at("\\WIDTH").as_int(); + int width = cell->parameters.at(ID(WIDTH)).as_int(); - RTLIL::SigSpec sig_d = cell->getPort("\\D"); - RTLIL::SigSpec sig_q = cell->getPort("\\Q"); + RTLIL::SigSpec sig_d = cell->getPort(ID(D)); + RTLIL::SigSpec sig_q = cell->getPort(ID(Q)); - std::string gate_type = "$_FF_"; + IdString gate_type = ID($_FF_); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\D", sig_d[i]); - gate->setPort("\\Q", sig_q[i]); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID(D), sig_d[i]); + gate->setPort(ID(Q), sig_q[i]); } } void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at("\\WIDTH").as_int(); - char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N'; + int width = cell->parameters.at(ID(WIDTH)).as_int(); + char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_clk = cell->getPort("\\CLK"); - RTLIL::SigSpec sig_d = cell->getPort("\\D"); - RTLIL::SigSpec sig_q = cell->getPort("\\Q"); + RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK)); + RTLIL::SigSpec sig_d = cell->getPort(ID(D)); + RTLIL::SigSpec sig_q = cell->getPort(ID(Q)); - std::string gate_type = stringf("$_DFF_%c_", clk_pol); + IdString gate_type = stringf("$_DFF_%c_", clk_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\C", sig_clk); - gate->setPort("\\D", sig_d[i]); - gate->setPort("\\Q", sig_q[i]); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID(C), sig_clk); + gate->setPort(ID(D), sig_d[i]); + gate->setPort(ID(Q), sig_q[i]); } } void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at("\\WIDTH").as_int(); - char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N'; - char en_pol = cell->parameters.at("\\EN_POLARITY").as_bool() ? 'P' : 'N'; + int width = cell->parameters.at(ID(WIDTH)).as_int(); + char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N'; + char en_pol = cell->parameters.at(ID(EN_POLARITY)).as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_clk = cell->getPort("\\CLK"); - RTLIL::SigSpec sig_en = cell->getPort("\\EN"); - RTLIL::SigSpec sig_d = cell->getPort("\\D"); - RTLIL::SigSpec sig_q = cell->getPort("\\Q"); + RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK)); + RTLIL::SigSpec sig_en = cell->getPort(ID(EN)); + RTLIL::SigSpec sig_d = cell->getPort(ID(D)); + RTLIL::SigSpec sig_q = cell->getPort(ID(Q)); - std::string gate_type = stringf("$_DFFE_%c%c_", clk_pol, en_pol); + IdString gate_type = stringf("$_DFFE_%c%c_", clk_pol, en_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\C", sig_clk); - gate->setPort("\\E", sig_en); - gate->setPort("\\D", sig_d[i]); - gate->setPort("\\Q", sig_q[i]); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID(C), sig_clk); + gate->setPort(ID(E), sig_en); + gate->setPort(ID(D), sig_d[i]); + gate->setPort(ID(Q), sig_q[i]); } } void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at("\\WIDTH").as_int(); - char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N'; - char set_pol = cell->parameters.at("\\SET_POLARITY").as_bool() ? 'P' : 'N'; - char clr_pol = cell->parameters.at("\\CLR_POLARITY").as_bool() ? 'P' : 'N'; + int width = cell->parameters.at(ID(WIDTH)).as_int(); + char clk_pol = cell->parameters.at(ID(CLK_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_clk = cell->getPort("\\CLK"); - RTLIL::SigSpec sig_s = cell->getPort("\\SET"); - RTLIL::SigSpec sig_r = cell->getPort("\\CLR"); - RTLIL::SigSpec sig_d = cell->getPort("\\D"); - RTLIL::SigSpec sig_q = cell->getPort("\\Q"); + 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_d = cell->getPort(ID(D)); + RTLIL::SigSpec sig_q = cell->getPort(ID(Q)); - std::string gate_type = stringf("$_DFFSR_%c%c%c_", clk_pol, set_pol, clr_pol); + IdString gate_type = stringf("$_DFFSR_%c%c%c_", clk_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("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\C", sig_clk); - gate->setPort("\\S", sig_s[i]); - gate->setPort("\\R", sig_r[i]); - gate->setPort("\\D", sig_d[i]); - gate->setPort("\\Q", sig_q[i]); + 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(D), sig_d[i]); + gate->setPort(ID(Q), sig_q[i]); } } void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at("\\WIDTH").as_int(); - char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N'; - char rst_pol = cell->parameters.at("\\ARST_POLARITY").as_bool() ? 'P' : 'N'; + 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'; - std::vector rst_val = cell->parameters.at("\\ARST_VALUE").bits; + std::vector 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_clk = cell->getPort("\\CLK"); - RTLIL::SigSpec sig_rst = cell->getPort("\\ARST"); - RTLIL::SigSpec sig_d = cell->getPort("\\D"); - RTLIL::SigSpec sig_q = cell->getPort("\\Q"); + RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK)); + RTLIL::SigSpec sig_rst = cell->getPort(ID(ARST)); + RTLIL::SigSpec sig_d = cell->getPort(ID(D)); + RTLIL::SigSpec sig_q = cell->getPort(ID(Q)); - std::string gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol); - std::string gate_type_1 = stringf("$_DFF_%c%c1_", clk_pol, rst_pol); + IdString gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol); + IdString gate_type_1 = stringf("$_DFF_%c%c1_", 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("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\C", sig_clk); - gate->setPort("\\R", sig_rst); - gate->setPort("\\D", sig_d[i]); - gate->setPort("\\Q", sig_q[i]); + 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_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at("\\WIDTH").as_int(); - char en_pol = cell->parameters.at("\\EN_POLARITY").as_bool() ? 'P' : 'N'; + int width = cell->parameters.at(ID(WIDTH)).as_int(); + char en_pol = cell->parameters.at(ID(EN_POLARITY)).as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_en = cell->getPort("\\EN"); - RTLIL::SigSpec sig_d = cell->getPort("\\D"); - RTLIL::SigSpec sig_q = cell->getPort("\\Q"); + RTLIL::SigSpec sig_en = cell->getPort(ID(EN)); + RTLIL::SigSpec sig_d = cell->getPort(ID(D)); + RTLIL::SigSpec sig_q = cell->getPort(ID(Q)); - std::string gate_type = stringf("$_DLATCH_%c_", en_pol); + IdString gate_type = stringf("$_DLATCH_%c_", en_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src")); - gate->setPort("\\E", sig_en); - gate->setPort("\\D", sig_d[i]); - gate->setPort("\\Q", sig_q[i]); + gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); + gate->setPort(ID(E), sig_en); + gate->setPort(ID(D), sig_d[i]); + gate->setPort(ID(Q), sig_q[i]); } } void simplemap_get_mappers(std::map &mappers) { - mappers["$not"] = simplemap_not; - mappers["$pos"] = simplemap_pos; - mappers["$and"] = simplemap_bitop; - mappers["$or"] = simplemap_bitop; - mappers["$xor"] = simplemap_bitop; - mappers["$xnor"] = simplemap_bitop; - mappers["$reduce_and"] = simplemap_reduce; - mappers["$reduce_or"] = simplemap_reduce; - mappers["$reduce_xor"] = simplemap_reduce; - mappers["$reduce_xnor"] = simplemap_reduce; - mappers["$reduce_bool"] = simplemap_reduce; - mappers["$logic_not"] = simplemap_lognot; - mappers["$logic_and"] = simplemap_logbin; - mappers["$logic_or"] = simplemap_logbin; - mappers["$eq"] = simplemap_eqne; - mappers["$eqx"] = simplemap_eqne; - mappers["$ne"] = simplemap_eqne; - mappers["$nex"] = simplemap_eqne; - mappers["$mux"] = simplemap_mux; - mappers["$tribuf"] = simplemap_tribuf; - mappers["$lut"] = simplemap_lut; - mappers["$sop"] = simplemap_sop; - mappers["$slice"] = simplemap_slice; - mappers["$concat"] = simplemap_concat; - mappers["$sr"] = simplemap_sr; - mappers["$ff"] = simplemap_ff; - mappers["$dff"] = simplemap_dff; - mappers["$dffe"] = simplemap_dffe; - mappers["$dffsr"] = simplemap_dffsr; - mappers["$adff"] = simplemap_adff; - mappers["$dlatch"] = simplemap_dlatch; + mappers[ID($not)] = simplemap_not; + mappers[ID($pos)] = simplemap_pos; + mappers[ID($and)] = simplemap_bitop; + mappers[ID($or)] = simplemap_bitop; + mappers[ID($xor)] = simplemap_bitop; + mappers[ID($xnor)] = simplemap_bitop; + mappers[ID($reduce_and)] = simplemap_reduce; + mappers[ID($reduce_or)] = simplemap_reduce; + mappers[ID($reduce_xor)] = simplemap_reduce; + mappers[ID($reduce_xnor)] = simplemap_reduce; + mappers[ID($reduce_bool)] = simplemap_reduce; + mappers[ID($logic_not)] = simplemap_lognot; + mappers[ID($logic_and)] = simplemap_logbin; + mappers[ID($logic_or)] = simplemap_logbin; + mappers[ID($eq)] = simplemap_eqne; + mappers[ID($eqx)] = simplemap_eqne; + mappers[ID($ne)] = simplemap_eqne; + mappers[ID($nex)] = simplemap_eqne; + mappers[ID($mux)] = simplemap_mux; + mappers[ID($tribuf)] = simplemap_tribuf; + mappers[ID($lut)] = simplemap_lut; + mappers[ID($sop)] = simplemap_sop; + mappers[ID($slice)] = simplemap_slice; + mappers[ID($concat)] = simplemap_concat; + mappers[ID($sr)] = simplemap_sr; + mappers[ID($ff)] = simplemap_ff; + mappers[ID($dff)] = simplemap_dff; + mappers[ID($dffe)] = simplemap_dffe; + mappers[ID($dffsr)] = simplemap_dffsr; + mappers[ID($adff)] = simplemap_adff; + mappers[ID($dlatch)] = simplemap_dlatch; } void simplemap(RTLIL::Module *module, RTLIL::Cell *cell) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index ceb053825..b271c8781 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -39,20 +39,20 @@ YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -void apply_prefix(std::string prefix, std::string &id) +void apply_prefix(IdString prefix, IdString &id) { if (id[0] == '\\') - id = prefix + "." + id.substr(1); + id = stringf("%s.%s", prefix.c_str(), id.c_str()+1); else - id = "$techmap" + prefix + "." + id; + id = stringf("$techmap%s.%s", prefix.c_str(), id.c_str()); } -void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module *module) +void apply_prefix(IdString prefix, RTLIL::SigSpec &sig, RTLIL::Module *module) { vector chunks = sig; for (auto &chunk : chunks) if (chunk.wire != NULL) { - std::string wire_name = chunk.wire->name.str(); + IdString wire_name = chunk.wire->name; apply_prefix(prefix, wire_name); log_assert(module->wires_.count(wire_name) > 0); chunk.wire = module->wires_[wire_name]; @@ -145,8 +145,8 @@ struct TechmapWorker record.wire = it.second; record.value = it.second; result[p].push_back(record); - it.second->attributes["\\keep"] = RTLIL::Const(1); - it.second->attributes["\\_techmap_special_"] = RTLIL::Const(1); + it.second->attributes[ID::keep] = RTLIL::Const(1); + it.second->attributes[ID(_techmap_special_)] = RTLIL::Const(1); } } @@ -175,11 +175,11 @@ struct TechmapWorker } std::string orig_cell_name; - pool extra_src_attrs = cell->get_strpool_attribute("\\src"); + pool extra_src_attrs = cell->get_strpool_attribute(ID(src)); if (!flatten_mode) { for (auto &it : tpl->cells_) - if (it.first == "\\_TECHMAP_REPLACE_") { + if (it.first == ID(_TECHMAP_REPLACE_)) { orig_cell_name = cell->name.str(); module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str()); break; @@ -189,16 +189,16 @@ struct TechmapWorker dict memory_renames; for (auto &it : tpl->memories) { - std::string m_name = it.first.str(); - apply_prefix(cell->name.str(), m_name); + IdString m_name = it.first; + apply_prefix(cell->name, m_name); RTLIL::Memory *m = new RTLIL::Memory; m->name = m_name; m->width = it.second->width; m->start_offset = it.second->start_offset; m->size = it.second->size; m->attributes = it.second->attributes; - if (m->attributes.count("\\src")) - m->add_strpool_attribute("\\src", extra_src_attrs); + if (m->attributes.count(ID(src))) + m->add_strpool_attribute(ID(src), extra_src_attrs); module->memories[m->name] = m; memory_renames[it.first] = m->name; design->select(module, m); @@ -209,16 +209,16 @@ struct TechmapWorker for (auto &it : tpl->wires_) { if (it.second->port_id > 0) positional_ports[stringf("$%d", it.second->port_id)] = it.first; - std::string w_name = it.second->name.str(); - apply_prefix(cell->name.str(), w_name); + IdString w_name = it.second->name; + apply_prefix(cell->name, w_name); RTLIL::Wire *w = module->addWire(w_name, it.second); w->port_input = false; w->port_output = false; w->port_id = 0; - if (it.second->get_bool_attribute("\\_techmap_special_")) + if (it.second->get_bool_attribute(ID(_techmap_special_))) w->attributes.clear(); - if (w->attributes.count("\\src")) - w->add_strpool_attribute("\\src", extra_src_attrs); + if (w->attributes.count(ID(src))) + w->add_strpool_attribute(ID(src), extra_src_attrs); design->select(module, w); } @@ -243,7 +243,7 @@ struct TechmapWorker if (positional_ports.count(portname) > 0) portname = positional_ports.at(portname); if (tpl->wires_.count(portname) == 0 || tpl->wires_.at(portname)->port_id == 0) { - if (portname.substr(0, 1) == "$") + if (portname.begins_with("$")) log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname.c_str(), cell->name.c_str(), tpl->name.c_str()); continue; } @@ -257,18 +257,18 @@ struct TechmapWorker if (w->port_output && !w->port_input) { c.first = it.second; c.second = RTLIL::SigSpec(w); - apply_prefix(cell->name.str(), c.second, module); + apply_prefix(cell->name, c.second, module); extra_connect.first = c.second; extra_connect.second = c.first; } else if (!w->port_output && w->port_input) { c.first = RTLIL::SigSpec(w); c.second = it.second; - apply_prefix(cell->name.str(), c.first, module); + apply_prefix(cell->name, c.first, module); extra_connect.first = c.first; extra_connect.second = c.second; } else { SigSpec sig_tpl = w, sig_tpl_pf = w, sig_mod = it.second; - apply_prefix(cell->name.str(), sig_tpl_pf, module); + 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]))) { c.first.append(sig_mod[i]); @@ -320,7 +320,7 @@ struct TechmapWorker } for (auto &attr : w->attributes) { - if (attr.first == "\\src") + if (attr.first == ID(src)) continue; module->connect(extra_connect); break; @@ -330,39 +330,39 @@ struct TechmapWorker for (auto &it : tpl->cells_) { - std::string c_name = it.second->name.str(); - bool techmap_replace_cell = (!flatten_mode) && (c_name == "\\_TECHMAP_REPLACE_"); + IdString c_name = it.second->name.str(); + bool techmap_replace_cell = (!flatten_mode) && (c_name == ID(_TECHMAP_REPLACE_)); if (techmap_replace_cell) c_name = orig_cell_name; else - apply_prefix(cell->name.str(), c_name); + apply_prefix(cell->name, c_name); RTLIL::Cell *c = module->addCell(c_name, it.second); design->select(module, c); - if (!flatten_mode && c->type.substr(0, 2) == "\\$") + if (!flatten_mode && c->type.begins_with("\\$")) c->type = c->type.substr(1); for (auto &it2 : c->connections_) { - apply_prefix(cell->name.str(), it2.second, module); + apply_prefix(cell->name, it2.second, module); port_signal_map.apply(it2.second); } - if (c->type == "$memrd" || c->type == "$memwr" || c->type == "$meminit") { - IdString memid = c->getParam("\\MEMID").decode_string(); + if (c->type.in(ID($memrd), ID($memwr), ID($meminit))) { + IdString memid = c->getParam(ID(MEMID)).decode_string(); log_assert(memory_renames.count(memid) != 0); - c->setParam("\\MEMID", Const(memory_renames[memid].str())); + c->setParam(ID(MEMID), Const(memory_renames[memid].str())); } - if (c->type == "$mem") { - string memid = c->getParam("\\MEMID").decode_string(); - apply_prefix(cell->name.str(), memid); - c->setParam("\\MEMID", Const(memid)); + if (c->type == ID($mem)) { + IdString memid = c->getParam(ID(MEMID)).decode_string(); + apply_prefix(cell->name, memid); + c->setParam(ID(MEMID), Const(memid.c_str())); } - if (c->attributes.count("\\src")) - c->add_strpool_attribute("\\src", extra_src_attrs); + if (c->attributes.count(ID(src))) + c->add_strpool_attribute(ID(src), extra_src_attrs); if (techmap_replace_cell) for (auto attr : cell->attributes) @@ -406,7 +406,7 @@ struct TechmapWorker continue; std::string cell_type = cell->type.str(); - if (in_recursion && cell_type.substr(0, 2) == "\\$") + if (in_recursion && cell->type.begins_with("\\$")) cell_type = cell_type.substr(1); if (celltypeMap.count(cell_type) == 0) { @@ -416,9 +416,9 @@ struct TechmapWorker } if (flatten_mode) { - bool keepit = cell->get_bool_attribute("\\keep_hierarchy"); + bool keepit = cell->get_bool_attribute(ID(keep_hierarchy)); for (auto &tpl_name : celltypeMap.at(cell_type)) - if (map->modules_[tpl_name]->get_bool_attribute("\\keep_hierarchy")) + if (map->modules_[tpl_name]->get_bool_attribute(ID(keep_hierarchy))) keepit = true; if (keepit) { if (!flatten_keep_list[cell]) { @@ -468,7 +468,7 @@ struct TechmapWorker std::string cell_type = cell->type.str(); - if (in_recursion && cell_type.substr(0, 2) == "\\$") + if (in_recursion && cell->type.begins_with("\\$")) cell_type = cell_type.substr(1); for (auto &tpl_name : celltypeMap.at(cell_type)) @@ -484,13 +484,13 @@ struct TechmapWorker { std::string extmapper_name; - if (tpl->get_bool_attribute("\\techmap_simplemap")) + if (tpl->get_bool_attribute(ID(techmap_simplemap))) extmapper_name = "simplemap"; - if (tpl->get_bool_attribute("\\techmap_maccmap")) + if (tpl->get_bool_attribute(ID(techmap_maccmap))) extmapper_name = "maccmap"; - if (tpl->attributes.count("\\techmap_wrap")) + if (tpl->attributes.count(ID(techmap_wrap))) extmapper_name = "wrap"; if (!extmapper_name.empty()) @@ -505,7 +505,7 @@ struct TechmapWorker m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second)); if (extmapper_name == "wrap") - m_name += ":" + sha1(tpl->attributes.at("\\techmap_wrap").decode_string()); + m_name += ":" + sha1(tpl->attributes.at(ID(techmap_wrap)).decode_string()); RTLIL::Design *extmapper_design = extern_mode && !in_recursion ? design : tpl->design; RTLIL::Module *extmapper_module = extmapper_design->module(m_name); @@ -520,7 +520,7 @@ struct TechmapWorker int port_counter = 1; for (auto &c : extmapper_cell->connections_) { RTLIL::Wire *w = extmapper_module->addWire(c.first, GetSize(c.second)); - if (w->name == "\\Y" || w->name == "\\Q") + if (w->name.in(ID::Y, ID(Q))) w->port_output = true; else w->port_input = true; @@ -541,14 +541,14 @@ struct TechmapWorker if (extmapper_name == "maccmap") { log("Creating %s with maccmap.\n", log_id(extmapper_module)); - if (extmapper_cell->type != "$macc") + if (extmapper_cell->type != ID($macc)) log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(extmapper_cell->type)); maccmap(extmapper_module, extmapper_cell); extmapper_module->remove(extmapper_cell); } if (extmapper_name == "wrap") { - std::string cmd_string = tpl->attributes.at("\\techmap_wrap").decode_string(); + std::string cmd_string = tpl->attributes.at(ID(techmap_wrap)).decode_string(); log("Running \"%s\" on wrapper %s.\n", cmd_string.c_str(), log_id(extmapper_module)); mkdebug.on(); Pass::call_on_module(extmapper_design, extmapper_module, cmd_string); @@ -587,7 +587,7 @@ struct TechmapWorker } if (extmapper_name == "maccmap") { - if (cell->type != "$macc") + if (cell->type != ID($macc)) log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(cell->type)); maccmap(module, cell); } @@ -602,7 +602,7 @@ struct TechmapWorker } for (auto conn : cell->connections()) { - if (conn.first.substr(0, 1) == "$") + if (conn.first.begins_with("$")) continue; if (tpl->wires_.count(conn.first) > 0 && tpl->wires_.at(conn.first)->port_id > 0) continue; @@ -616,8 +616,8 @@ struct TechmapWorker continue; } - if (tpl->avail_parameters.count("\\_TECHMAP_CELLTYPE_") != 0) - parameters["\\_TECHMAP_CELLTYPE_"] = RTLIL::unescape_id(cell->type); + if (tpl->avail_parameters.count(ID(_TECHMAP_CELLTYPE_)) != 0) + parameters[ID(_TECHMAP_CELLTYPE_)] = RTLIL::unescape_id(cell->type); for (auto conn : cell->connections()) { if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))) != 0) { @@ -656,8 +656,8 @@ struct TechmapWorker bits = i; // Increment index by one to get number of bits bits++; - if (tpl->avail_parameters.count("\\_TECHMAP_BITS_CONNMAP_")) - parameters["\\_TECHMAP_BITS_CONNMAP_"] = bits; + if (tpl->avail_parameters.count(ID(_TECHMAP_BITS_CONNMAP_))) + parameters[ID(_TECHMAP_BITS_CONNMAP_)] = bits; for (auto conn : cell->connections()) if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) { @@ -725,7 +725,7 @@ struct TechmapWorker for (auto &it : twd) { - if (it.first.substr(0, 12) != "_TECHMAP_DO_" || it.second.empty()) + if (it.first.compare(0, 12, "_TECHMAP_DO_") != 0 || it.second.empty()) continue; auto &data = it.second.front(); @@ -874,7 +874,7 @@ struct TechmapWorker tpl->cloneInto(m); for (auto cell : m->cells()) { - if (cell->type.substr(0, 2) == "\\$") + if (cell->type.begins_with("\\$")) cell->type = cell->type.substr(1); } @@ -1113,7 +1113,7 @@ struct TechmapPass : public Pass { Frontend::frontend_call(map, &f, "", verilog_frontend); } else { for (auto &fn : map_files) - if (fn.substr(0, 1) == "%") { + if (fn.compare(0, 1, "%") == 0) { if (!saved_designs.count(fn.substr(1))) { delete map; log_cmd_error("Can't saved design `%s'.\n", fn.c_str()+1); @@ -1128,7 +1128,7 @@ struct TechmapPass : public Pass { yosys_input_files.insert(fn); if (f.fail()) log_cmd_error("Can't open map file `%s'\n", fn.c_str()); - Frontend::frontend_call(map, &f, fn, (fn.size() > 3 && fn.substr(fn.size()-3) == ".il") ? "ilang" : verilog_frontend); + Frontend::frontend_call(map, &f, fn, (fn.size() > 3 && fn.compare(fn.size()-3, std::string::npos, ".il") == 0 ? "ilang" : verilog_frontend)); } } @@ -1136,14 +1136,14 @@ struct TechmapPass : public Pass { std::map> celltypeMap; for (auto &it : map->modules_) { - if (it.second->attributes.count("\\techmap_celltype") && !it.second->attributes.at("\\techmap_celltype").bits.empty()) { - char *p = strdup(it.second->attributes.at("\\techmap_celltype").decode_string().c_str()); + if (it.second->attributes.count(ID(techmap_celltype)) && !it.second->attributes.at(ID(techmap_celltype)).bits.empty()) { + char *p = strdup(it.second->attributes.at(ID(techmap_celltype)).decode_string().c_str()); for (char *q = strtok(p, " \t\r\n"); q; q = strtok(NULL, " \t\r\n")) celltypeMap[RTLIL::escape_id(q)].insert(it.first); free(p); } else { string module_name = it.first.str(); - if (module_name.substr(0, 2) == "\\$") + if (it.first.begins_with("\\$")) module_name = module_name.substr(1); celltypeMap[module_name].insert(it.first); } @@ -1222,7 +1222,7 @@ struct FlattenPass : public Pass { RTLIL::Module *top_mod = NULL; if (design->full_selection()) for (auto mod : design->modules()) - if (mod->get_bool_attribute("\\top")) + if (mod->get_bool_attribute(ID(top))) top_mod = mod; std::set handled_cells; diff --git a/passes/techmap/tribuf.cc b/passes/techmap/tribuf.cc index 587cb9038..41fdc8f3d 100644 --- a/passes/techmap/tribuf.cc +++ b/passes/techmap/tribuf.cc @@ -63,38 +63,38 @@ struct TribufWorker { for (auto cell : module->selected_cells()) { - if (cell->type == "$tribuf") - tribuf_cells[sigmap(cell->getPort("\\Y"))].push_back(cell); + if (cell->type == ID($tribuf)) + tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); - if (cell->type == "$_TBUF_") - tribuf_cells[sigmap(cell->getPort("\\Y"))].push_back(cell); + if (cell->type == ID($_TBUF_)) + tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); - if (cell->type.in("$mux", "$_MUX_")) + if (cell->type.in(ID($mux), ID($_MUX_))) { - IdString en_port = cell->type == "$mux" ? "\\EN" : "\\E"; - IdString tri_type = cell->type == "$mux" ? "$tribuf" : "$_TBUF_"; + IdString en_port = cell->type == ID($mux) ? ID(EN) : ID(E); + IdString tri_type = cell->type == ID($mux) ? ID($tribuf) : ID($_TBUF_); - if (is_all_z(cell->getPort("\\A")) && is_all_z(cell->getPort("\\B"))) { + if (is_all_z(cell->getPort(ID::A)) && is_all_z(cell->getPort(ID::B))) { module->remove(cell); continue; } - if (is_all_z(cell->getPort("\\A"))) { - cell->setPort("\\A", cell->getPort("\\B")); - cell->setPort(en_port, cell->getPort("\\S")); - cell->unsetPort("\\B"); - cell->unsetPort("\\S"); + if (is_all_z(cell->getPort(ID::A))) { + cell->setPort(ID::A, cell->getPort(ID::B)); + cell->setPort(en_port, cell->getPort(ID(S))); + cell->unsetPort(ID::B); + cell->unsetPort(ID(S)); cell->type = tri_type; - tribuf_cells[sigmap(cell->getPort("\\Y"))].push_back(cell); + tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); continue; } - if (is_all_z(cell->getPort("\\B"))) { - cell->setPort(en_port, module->Not(NEW_ID, cell->getPort("\\S"))); - cell->unsetPort("\\B"); - cell->unsetPort("\\S"); + if (is_all_z(cell->getPort(ID::B))) { + cell->setPort(en_port, module->Not(NEW_ID, cell->getPort(ID(S)))); + cell->unsetPort(ID::B); + cell->unsetPort(ID(S)); cell->type = tri_type; - tribuf_cells[sigmap(cell->getPort("\\Y"))].push_back(cell); + tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); continue; } } @@ -118,11 +118,11 @@ struct TribufWorker { SigSpec pmux_b, pmux_s; for (auto cell : it.second) { - if (cell->type == "$tribuf") - pmux_s.append(cell->getPort("\\EN")); + if (cell->type == ID($tribuf)) + pmux_s.append(cell->getPort(ID(EN))); else - pmux_s.append(cell->getPort("\\E")); - pmux_b.append(cell->getPort("\\A")); + pmux_s.append(cell->getPort(ID(E))); + pmux_b.append(cell->getPort(ID::A)); module->remove(cell); } diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index 2aefc091d..ac3d4ed4a 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -62,12 +62,12 @@ struct ZinitPass : public Pass { for (auto wire : module->selected_wires()) { - if (wire->attributes.count("\\init") == 0) + if (wire->attributes.count(ID(init)) == 0) continue; SigSpec wirebits = sigmap(wire); - Const initval = wire->attributes.at("\\init"); - wire->attributes.erase("\\init"); + Const initval = wire->attributes.at(ID(init)); + wire->attributes.erase(ID(init)); for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) { @@ -90,12 +90,12 @@ struct ZinitPass : public Pass { } pool dff_types = { - "$ff", "$dff", "$dffe", "$dffsr", "$adff", - "$_FF_", "$_DFFE_NN_", "$_DFFE_NP_", "$_DFFE_PN_", "$_DFFE_PP_", - "$_DFFSR_NNN_", "$_DFFSR_NNP_", "$_DFFSR_NPN_", "$_DFFSR_NPP_", - "$_DFFSR_PNN_", "$_DFFSR_PNP_", "$_DFFSR_PPN_", "$_DFFSR_PPP_", - "$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", - "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1_", "$_DFF_PP0_", "$_DFF_PP1_" + ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($adff), + 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_) }; for (auto cell : module->selected_cells()) @@ -103,8 +103,8 @@ struct ZinitPass : public Pass { if (!dff_types.count(cell->type)) continue; - SigSpec sig_d = sigmap(cell->getPort("\\D")); - SigSpec sig_q = sigmap(cell->getPort("\\Q")); + SigSpec sig_d = sigmap(cell->getPort(ID(D))); + SigSpec sig_q = sigmap(cell->getPort(ID(Q))); if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1) continue; @@ -120,14 +120,14 @@ struct ZinitPass : public Pass { } Wire *initwire = module->addWire(NEW_ID, GetSize(initval)); - initwire->attributes["\\init"] = initval; + initwire->attributes[ID(init)] = initval; for (int i = 0; i < GetSize(initwire); i++) if (initval.bits.at(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["\\init"].bits.at(i) = State::S0; + initwire->attributes[ID(init)].bits.at(i) = State::S0; } else { @@ -137,8 +137,8 @@ struct ZinitPass : public Pass { 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("\\D", sig_d); - cell->setPort("\\Q", initwire); + cell->setPort(ID(D), sig_d); + cell->setPort(ID(Q), initwire); } for (auto &it : initbits) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index e360b5edb..88116eeec 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -43,7 +43,7 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, RTLIL::Cell *cell = module->addCell("\\UUT", cell_type); RTLIL::Wire *wire; - if (cell_type == "$mux" || cell_type == "$pmux") + if (cell_type.in("$mux", "$pmux")) { int width = 1 + xorshift32(8); int swidth = cell_type == "$mux" ? 1 : 1 + xorshift32(8); @@ -186,7 +186,7 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, RTLIL::SigSpec config; for (int i = 0; i < (1 << width); i++) - config.append(xorshift32(2) ? RTLIL::S1 : RTLIL::S0); + config.append(xorshift32(2) ? State::S1 : State::S0); cell->setParam("\\LUT", config.as_const()); } @@ -209,16 +209,16 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, for (int i = 0; i < width*depth; i++) switch (xorshift32(3)) { case 0: - config.append(RTLIL::S1); - config.append(RTLIL::S0); + config.append(State::S1); + config.append(State::S0); break; case 1: - config.append(RTLIL::S0); - config.append(RTLIL::S1); + config.append(State::S0); + config.append(State::S1); break; case 2: - config.append(RTLIL::S0); - config.append(RTLIL::S0); + config.append(State::S0); + config.append(State::S0); break; } @@ -264,7 +264,7 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, cell->setPort("\\Y", wire); } - if (muxdiv && (cell_type == "$div" || cell_type == "$mod")) { + if (muxdiv && cell_type.in("$div", "$mod")) { auto b_not_zero = module->ReduceBool(NEW_ID, cell->getPort("\\B")); auto div_out = module->addWire(NEW_ID, GetSize(cell->getPort("\\Y"))); module->addMux(NEW_ID, RTLIL::SigSpec(0, GetSize(div_out)), div_out, b_not_zero, cell->getPort("\\Y")); @@ -308,18 +308,18 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, case 0: n = xorshift32(GetSize(sig) + 1); for (int i = 0; i < n; i++) - sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; + sig[i] = xorshift32(2) == 1 ? State::S1 : State::S0; break; case 1: n = xorshift32(GetSize(sig) + 1); for (int i = n; i < GetSize(sig); i++) - sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; + sig[i] = xorshift32(2) == 1 ? State::S1 : State::S0; break; case 2: n = xorshift32(GetSize(sig)); m = xorshift32(GetSize(sig)); for (int i = min(n, m); i < max(n, m); i++) - sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; + sig[i] = xorshift32(2) == 1 ? State::S1 : State::S0; break; } @@ -491,7 +491,7 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: RTLIL::Const in_value; for (int i = 0; i < GetSize(gold_wire); i++) - in_value.bits.push_back(xorshift32(2) ? RTLIL::S1 : RTLIL::S0); + in_value.bits.push_back(xorshift32(2) ? State::S1 : State::S0); if (xorshift32(4) == 0) { int inv_chance = 1 + xorshift32(8); @@ -591,11 +591,11 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: } for (int i = 0; i < GetSize(out_sig); i++) { - if (out_val[i] != RTLIL::S0 && out_val[i] != RTLIL::S1) + if (out_val[i] != State::S0 && out_val[i] != State::S1) continue; - if (out_val[i] == RTLIL::S0 && sat1_model_value.at(i) == false) + if (out_val[i] == State::S0 && sat1_model_value.at(i) == false) continue; - if (out_val[i] == RTLIL::S1 && sat1_model_value.at(i) == true) + if (out_val[i] == State::S1 && sat1_model_value.at(i) == true) continue; log_error("Mismatch in sat model 1 (no undef modeling) output!\n"); } @@ -627,12 +627,12 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: for (int i = 0; i < GetSize(out_sig); i++) { if (sat2_model_value.at(GetSize(out_sig) + i)) { - if (out_val[i] != RTLIL::S0 && out_val[i] != RTLIL::S1) + if (out_val[i] != State::S0 && out_val[i] != State::S1) continue; } else { - if (out_val[i] == RTLIL::S0 && sat2_model_value.at(i) == false) + if (out_val[i] == State::S0 && sat2_model_value.at(i) == false) continue; - if (out_val[i] == RTLIL::S1 && sat2_model_value.at(i) == true) + if (out_val[i] == State::S1 && sat2_model_value.at(i) == true) continue; } log_error("Mismatch in sat model 2 (undef modeling) output!\n"); @@ -872,7 +872,7 @@ struct TestCellPass : public Pass { continue; } - if (args[argidx].substr(0, 1) == "/") { + if (args[argidx].compare(0, 1, "/") == 0) { std::vector new_selected_cell_types; for (auto it : selected_cell_types) if (it != args[argidx].substr(1)) diff --git a/techlibs/anlogic/anlogic_determine_init.cc b/techlibs/anlogic/anlogic_determine_init.cc index 34b1d4f8a..c4089dac2 100644 --- a/techlibs/anlogic/anlogic_determine_init.cc +++ b/techlibs/anlogic/anlogic_determine_init.cc @@ -50,7 +50,7 @@ struct AnlogicDetermineInitPass : public Pass { extra_args(args, args.size(), design); - size_t cnt = 0; + int cnt = 0; for (auto module : design->selected_modules()) { for (auto cell : module->selected_cells()) @@ -65,7 +65,7 @@ struct AnlogicDetermineInitPass : public Pass { } } } - log_header(design, "Updated %lu cells with determined init value.\n", cnt); + log_header(design, "Updated %d cells with determined init value.\n", cnt); } } AnlogicDetermineInitPass; diff --git a/techlibs/anlogic/anlogic_eqn.cc b/techlibs/anlogic/anlogic_eqn.cc index 741bf04cc..070d39a20 100644 --- a/techlibs/anlogic/anlogic_eqn.cc +++ b/techlibs/anlogic/anlogic_eqn.cc @@ -69,7 +69,7 @@ struct AnlogicEqnPass : public Pass { extra_args(args, args.size(), design); - size_t cnt = 0; + int cnt = 0; for (auto module : design->selected_modules()) { for (auto cell : module->selected_cells()) @@ -106,7 +106,7 @@ struct AnlogicEqnPass : public Pass { } } } - log_header(design, "Updated %lu of AL_MAP_LUT* elements with equation.\n", cnt); + log_header(design, "Updated %d of AL_MAP_LUT* elements with equation.\n", cnt); } } AnlogicEqnPass; diff --git a/techlibs/anlogic/arith_map.v b/techlibs/anlogic/arith_map.v index 11cd140ec..6d6a7ca37 100644 --- a/techlibs/anlogic/arith_map.v +++ b/techlibs/anlogic/arith_map.v @@ -42,10 +42,9 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); wire [Y_WIDTH-1:0] AA = A_buf; wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; wire [Y_WIDTH+1:0] COx; - wire [Y_WIDTH+1:0] C = {COx, CI}; + wire [Y_WIDTH+2:0] C = {COx, CI}; wire dummy; - (* keep *) AL_MAP_ADDER #( .ALUTYPE("ADD_CARRY")) adder_cin ( @@ -55,19 +54,6 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); genvar i; generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice - if(i==Y_WIDTH-1) begin - (* keep *) - AL_MAP_ADDER #( - .ALUTYPE("ADD")) - adder_cout ( - .c(C[Y_WIDTH]), - .o(COx[Y_WIDTH]) - ); - assign CO = COx[Y_WIDTH]; - end - else - begin - (* keep *) AL_MAP_ADDER #( .ALUTYPE("ADD") ) adder_i ( @@ -76,9 +62,15 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); .c(C[i+1]), .o({COx[i+1],Y[i]}) ); - end end: slice endgenerate /* End implementation */ + AL_MAP_ADDER #( + .ALUTYPE("ADD")) + adder_cout ( + .c(C[Y_WIDTH+1]), + .o(COx[Y_WIDTH+1]) + ); + assign CO = COx[Y_WIDTH+1]; assign X = AA ^ BB; endmodule \ No newline at end of file diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 289673e82..64720e598 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -228,6 +228,25 @@ output Y; assign Y = S ? B : A; endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_NMUX_ (A, B, S, Y) +//- +//- A 2-input inverting MUX gate. +//- +//- Truth table: A B S | Y +//- -------+--- +//- 0 - 0 | 1 +//- 1 - 0 | 0 +//- - 0 1 | 1 +//- - 1 1 | 0 +//- +module \$_NMUX_ (A, B, S, Y); +input A, B, S; +output Y; +assign Y = S ? !B : !A; +endmodule + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| //- //- $_MUX4_ (A, B, C, D, S, T, Y) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index a424d3089..7845a3fed 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -532,14 +532,26 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $lcu (P, G, CI, CO) +//- +//- Lookahead carry unit +//- A building block dedicated to fast computation of carry-bits used in binary +//- arithmetic operations. By replacing the ripple carry structure used in full-adder +//- blocks, the more significant bits of the sum can be expected to be computed more +//- quickly. +//- Typically created during `techmap` of $alu cells (see the "_90_alu" rule in +//- +/techmap.v). module \$lcu (P, G, CI, CO); parameter WIDTH = 1; -input [WIDTH-1:0] P, G; -input CI; +input [WIDTH-1:0] P; // Propagate +input [WIDTH-1:0] G; // Generate +input CI; // Carry-in -output reg [WIDTH-1:0] CO; +output reg [WIDTH-1:0] CO; // Carry-out integer i; always @* begin @@ -555,6 +567,17 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $alu (A, B, CI, BI, X, Y, CO) +//- +//- Arithmetic logic unit. +//- A building block supporting both binary addition/subtraction operations, and +//- indirectly, comparison operations. +//- Typically created by the `alumacc` pass, which transforms: +//- $add, $sub, $lt, $le, $ge, $gt, $eq, $eqx, $ne, $nex +//- cells into this $alu cell. +//- module \$alu (A, B, CI, BI, X, Y, CO); parameter A_SIGNED = 0; @@ -563,12 +586,16 @@ parameter A_WIDTH = 1; parameter B_WIDTH = 1; parameter Y_WIDTH = 1; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] X, Y; +input [A_WIDTH-1:0] A; // Input operand +input [B_WIDTH-1:0] B; // Input operand +output [Y_WIDTH-1:0] X; // A xor B (sign-extended, optional B inversion, + // used in combination with + // reduction-AND for $eq/$ne ops) +output [Y_WIDTH-1:0] Y; // Sum -input CI, BI; -output [Y_WIDTH-1:0] CO; +input CI; // Carry-in (set for $sub) +input BI; // Invert-B (set for $sub) +output [Y_WIDTH-1:0] CO; // Carry-out wire [Y_WIDTH-1:0] AA, BB; @@ -584,6 +611,7 @@ endgenerate wire y_co_undef = ^{A, A, B, B, CI, CI, BI, BI}; assign X = AA ^ BB; +// Full adder assign Y = (AA + BB + CI) ^ {Y_WIDTH{y_co_undef}}; function get_carry; diff --git a/techlibs/coolrunner2/coolrunner2_sop.cc b/techlibs/coolrunner2/coolrunner2_sop.cc index 48da0d8ad..de0cbb29d 100644 --- a/techlibs/coolrunner2/coolrunner2_sop.cc +++ b/techlibs/coolrunner2/coolrunner2_sop.cc @@ -60,10 +60,8 @@ struct Coolrunner2SopPass : public Pass { dict>> special_pterms_inv; for (auto cell : module->selected_cells()) { - if (cell->type == "\\FDCP" || cell->type == "\\FDCP_N" || cell->type == "\\FDDCP" || - cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP" || - cell->type == "\\FDCPE" || cell->type == "\\FDCPE_N" || cell->type == "\\FDDCPE" || - cell->type == "\\LDCP" || cell->type == "\\LDCP_N") + if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\FTCP", "\\FTCP_N", "\\FTDCP", + "\\FDCPE", "\\FDCPE_N", "\\FDDCPE", "\\LDCP", "\\LDCP_N")) { if (cell->hasPort("\\PRE")) special_pterms_no_inv[sigmap(cell->getPort("\\PRE")[0])].insert( @@ -257,10 +255,8 @@ struct Coolrunner2SopPass : public Pass { pool sig_fed_by_ff; for (auto cell : module->selected_cells()) { - if (cell->type == "\\FDCP" || cell->type == "\\FDCP_N" || cell->type == "\\FDDCP" || - cell->type == "\\LDCP" || cell->type == "\\LDCP_N" || - cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP" || - cell->type == "\\FDCPE" || cell->type == "\\FDCPE_N" || cell->type == "\\FDDCPE") + if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N", + "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE")) { auto output = sigmap(cell->getPort("\\Q")[0]); sig_fed_by_ff.insert(output); @@ -270,13 +266,11 @@ struct Coolrunner2SopPass : public Pass { // Look at all the FF inputs for (auto cell : module->selected_cells()) { - if (cell->type == "\\FDCP" || cell->type == "\\FDCP_N" || cell->type == "\\FDDCP" || - cell->type == "\\LDCP" || cell->type == "\\LDCP_N" || - cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP" || - cell->type == "\\FDCPE" || cell->type == "\\FDCPE_N" || cell->type == "\\FDDCPE") + if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N", + "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE")) { SigBit input; - if (cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP") + if (cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP")) input = sigmap(cell->getPort("\\T")[0]); else input = sigmap(cell->getPort("\\D")[0]); @@ -300,7 +294,7 @@ struct Coolrunner2SopPass : public Pass { xor_cell->setPort("\\IN_PTC", and_to_xor_wire); xor_cell->setPort("\\OUT", xor_to_ff_wire); - if (cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP") + if (cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP")) cell->setPort("\\T", xor_to_ff_wire); else cell->setPort("\\D", xor_to_ff_wire); diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index ca88d0a5b..3d343b315 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -333,6 +333,31 @@ module TRELLIS_SLICE( parameter [127:0] CCU2_INJECT1_0 = "NO"; parameter [127:0] CCU2_INJECT1_1 = "NO"; parameter WREMUX = "WRE"; + parameter WCKMUX = "WCK"; + + parameter A0MUX = "A0"; + parameter A1MUX = "A1"; + parameter B0MUX = "B0"; + parameter B1MUX = "B1"; + parameter C0MUX = "C0"; + parameter C1MUX = "C1"; + parameter D0MUX = "D0"; + parameter D1MUX = "D1"; + + wire A0m, B0m, C0m, D0m; + wire A1m, B1m, C1m, D1m; + + generate + if (A0MUX == "1") assign A0m = 1'b1; else assign A0m = A0; + if (B0MUX == "1") assign B0m = 1'b1; else assign B0m = B0; + if (C0MUX == "1") assign C0m = 1'b1; else assign C0m = C0; + if (D0MUX == "1") assign D0m = 1'b1; else assign D0m = D0; + if (A1MUX == "1") assign A1m = 1'b1; else assign A1m = A1; + if (B1MUX == "1") assign B1m = 1'b1; else assign B1m = B1; + if (C1MUX == "1") assign C1m = 1'b1; else assign C1m = C1; + if (D1MUX == "1") assign D1m = 1'b1; else assign D1m = D1; + + endgenerate function [15:0] permute_initval; input [15:0] initval; @@ -350,13 +375,13 @@ module TRELLIS_SLICE( LUT4 #( .INIT(LUT0_INITVAL) ) lut4_0 ( - .A(A0), .B(B0), .C(C0), .D(D0), + .A(A0m), .B(B0m), .C(C0m), .D(D0m), .Z(F0) ); LUT4 #( .INIT(LUT1_INITVAL) ) lut4_1 ( - .A(A1), .B(B1), .C(C1), .D(D1), + .A(A1m), .B(B1m), .C(C1m), .D(D1m), .Z(F1) ); // LUT expansion muxes @@ -370,20 +395,20 @@ module TRELLIS_SLICE( .INJECT1_1(CCU2_INJECT1_1) ) ccu2c_i ( .CIN(FCI), - .A0(A0), .B0(B0), .C0(C0), .D0(D0), - .A1(A1), .B1(B1), .C1(C1), .D1(D1), + .A0(A0m), .B0(B0m), .C0(C0m), .D0(D0m), + .A1(A1m), .B1(B1m), .C1(C1m), .D1(D1m), .S0(F0), .S1(F1), .COUT(FCO) ); end else if (MODE == "RAMW") begin - assign WDO0 = C1; - assign WDO1 = A1; - assign WDO2 = D1; - assign WDO3 = B1; - assign WADO0 = D0; - assign WADO1 = B0; - assign WADO2 = C0; - assign WADO3 = A0; + assign WDO0 = C1m; + assign WDO1 = A1m; + assign WDO2 = D1m; + assign WDO3 = B1m; + assign WADO0 = D0m; + assign WADO1 = B0m; + assign WADO2 = C0m; + assign WADO3 = A0m; end else if (MODE == "DPRAM") begin TRELLIS_RAM16X2 #( .INITVAL_0(permute_initval(LUT0_INITVAL)), @@ -393,17 +418,19 @@ module TRELLIS_SLICE( .DI0(WD0), .DI1(WD1), .WAD0(WAD0), .WAD1(WAD1), .WAD2(WAD2), .WAD3(WAD3), .WRE(WRE), .WCK(WCK), - .RAD0(D0), .RAD1(B0), .RAD2(C0), .RAD3(A0), + .RAD0(D0m), .RAD1(B0m), .RAD2(C0m), .RAD3(A0m), .DO0(F0), .DO1(F1) ); // TODO: confirm RAD and INITVAL ordering // DPRAM mode contract? +`ifdef FORMAL always @(*) begin - assert(A0==A1); - assert(B0==B1); - assert(C0==C1); - assert(D0==D1); + assert(A0m==A1m); + assert(B0m==B1m); + assert(C0m==C1m); + assert(D0m==D1m); end +`endif end else begin ERROR_UNKNOWN_SLICE_MODE error(); end @@ -455,90 +482,206 @@ module DP16KD( input CSB2, CSB1, CSB0, output DOB17, DOB16, DOB15, DOB14, DOB13, DOB12, DOB11, DOB10, DOB9, DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 ); - parameter DATA_WIDTH_A = 18; - parameter DATA_WIDTH_B = 18; + parameter DATA_WIDTH_A = 18; + parameter DATA_WIDTH_B = 18; - parameter REGMODE_A = "NOREG"; - parameter REGMODE_B = "NOREG"; + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_A = "0b000"; - parameter CSDECODE_B = "0b000"; + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; - parameter WRITEMODE_A = "NORMAL"; - parameter WRITEMODE_B = "NORMAL"; + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; - parameter CLKAMUX = "CLKA"; - parameter CLKBMUX = "CLKB"; + parameter DIA17MUX = "DIA17"; + parameter DIA16MUX = "DIA16"; + parameter DIA15MUX = "DIA15"; + parameter DIA14MUX = "DIA14"; + parameter DIA13MUX = "DIA13"; + parameter DIA12MUX = "DIA12"; + parameter DIA11MUX = "DIA11"; + parameter DIA10MUX = "DIA10"; + parameter DIA9MUX = "DIA9"; + parameter DIA8MUX = "DIA8"; + parameter DIA7MUX = "DIA7"; + parameter DIA6MUX = "DIA6"; + parameter DIA5MUX = "DIA5"; + parameter DIA4MUX = "DIA4"; + parameter DIA3MUX = "DIA3"; + parameter DIA2MUX = "DIA2"; + parameter DIA1MUX = "DIA1"; + parameter DIA0MUX = "DIA0"; + parameter ADA13MUX = "ADA13"; + parameter ADA12MUX = "ADA12"; + parameter ADA11MUX = "ADA11"; + parameter ADA10MUX = "ADA10"; + parameter ADA9MUX = "ADA9"; + parameter ADA8MUX = "ADA8"; + parameter ADA7MUX = "ADA7"; + parameter ADA6MUX = "ADA6"; + parameter ADA5MUX = "ADA5"; + parameter ADA4MUX = "ADA4"; + parameter ADA3MUX = "ADA3"; + parameter ADA2MUX = "ADA2"; + parameter ADA1MUX = "ADA1"; + parameter ADA0MUX = "ADA0"; + parameter CEAMUX = "CEA"; + parameter OCEAMUX = "OCEA"; + parameter CLKAMUX = "CLKA"; + parameter WEAMUX = "WEA"; + parameter RSTAMUX = "RSTA"; + parameter CSA2MUX = "CSA2"; + parameter CSA1MUX = "CSA1"; + parameter CSA0MUX = "CSA0"; + parameter DOA17MUX = "DOA17"; + parameter DOA16MUX = "DOA16"; + parameter DOA15MUX = "DOA15"; + parameter DOA14MUX = "DOA14"; + parameter DOA13MUX = "DOA13"; + parameter DOA12MUX = "DOA12"; + parameter DOA11MUX = "DOA11"; + parameter DOA10MUX = "DOA10"; + parameter DOA9MUX = "DOA9"; + parameter DOA8MUX = "DOA8"; + parameter DOA7MUX = "DOA7"; + parameter DOA6MUX = "DOA6"; + parameter DOA5MUX = "DOA5"; + parameter DOA4MUX = "DOA4"; + parameter DOA3MUX = "DOA3"; + parameter DOA2MUX = "DOA2"; + parameter DOA1MUX = "DOA1"; + parameter DOA0MUX = "DOA0"; + parameter DIB17MUX = "DIB17"; + parameter DIB16MUX = "DIB16"; + parameter DIB15MUX = "DIB15"; + parameter DIB14MUX = "DIB14"; + parameter DIB13MUX = "DIB13"; + parameter DIB12MUX = "DIB12"; + parameter DIB11MUX = "DIB11"; + parameter DIB10MUX = "DIB10"; + parameter DIB9MUX = "DIB9"; + parameter DIB8MUX = "DIB8"; + parameter DIB7MUX = "DIB7"; + parameter DIB6MUX = "DIB6"; + parameter DIB5MUX = "DIB5"; + parameter DIB4MUX = "DIB4"; + parameter DIB3MUX = "DIB3"; + parameter DIB2MUX = "DIB2"; + parameter DIB1MUX = "DIB1"; + parameter DIB0MUX = "DIB0"; + parameter ADB13MUX = "ADB13"; + parameter ADB12MUX = "ADB12"; + parameter ADB11MUX = "ADB11"; + parameter ADB10MUX = "ADB10"; + parameter ADB9MUX = "ADB9"; + parameter ADB8MUX = "ADB8"; + parameter ADB7MUX = "ADB7"; + parameter ADB6MUX = "ADB6"; + parameter ADB5MUX = "ADB5"; + parameter ADB4MUX = "ADB4"; + parameter ADB3MUX = "ADB3"; + parameter ADB2MUX = "ADB2"; + parameter ADB1MUX = "ADB1"; + parameter ADB0MUX = "ADB0"; + parameter CEBMUX = "CEB"; + parameter OCEBMUX = "OCEB"; + parameter CLKBMUX = "CLKB"; + parameter WEBMUX = "WEB"; + parameter RSTBMUX = "RSTB"; + parameter CSB2MUX = "CSB2"; + parameter CSB1MUX = "CSB1"; + parameter CSB0MUX = "CSB0"; + parameter DOB17MUX = "DOB17"; + parameter DOB16MUX = "DOB16"; + parameter DOB15MUX = "DOB15"; + parameter DOB14MUX = "DOB14"; + parameter DOB13MUX = "DOB13"; + parameter DOB12MUX = "DOB12"; + parameter DOB11MUX = "DOB11"; + parameter DOB10MUX = "DOB10"; + parameter DOB9MUX = "DOB9"; + parameter DOB8MUX = "DOB8"; + parameter DOB7MUX = "DOB7"; + parameter DOB6MUX = "DOB6"; + parameter DOB5MUX = "DOB5"; + parameter DOB4MUX = "DOB4"; + parameter DOB3MUX = "DOB3"; + parameter DOB2MUX = "DOB2"; + parameter DOB1MUX = "DOB1"; + parameter DOB0MUX = "DOB0"; - parameter GSR = "ENABLED"; + parameter WID = 0; - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter GSR = "ENABLED"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; endmodule // TODO: Diamond flip-flops diff --git a/techlibs/gowin/determine_init.cc b/techlibs/gowin/determine_init.cc index 991e5245a..d9a0880f6 100644 --- a/techlibs/gowin/determine_init.cc +++ b/techlibs/gowin/determine_init.cc @@ -50,7 +50,7 @@ struct DetermineInitPass : public Pass { extra_args(args, args.size(), design); - size_t cnt = 0; + int cnt = 0; for (auto module : design->selected_modules()) { for (auto cell : module->selected_cells()) @@ -65,7 +65,7 @@ struct DetermineInitPass : public Pass { } } } - log_header(design, "Updated %lu cells with determined init value.\n", cnt); + log_header(design, "Updated %d cells with determined init value.\n", cnt); } } DetermineInitPass; diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc index d258d5a5d..76a89b107 100644 --- a/techlibs/ice40/Makefile.inc +++ b/techlibs/ice40/Makefile.inc @@ -4,7 +4,6 @@ OBJS += techlibs/ice40/ice40_braminit.o OBJS += techlibs/ice40/ice40_ffssr.o OBJS += techlibs/ice40/ice40_ffinit.o OBJS += techlibs/ice40/ice40_opt.o -OBJS += techlibs/ice40/ice40_unlut.o GENFILES += techlibs/ice40/brams_init1.vh GENFILES += techlibs/ice40/brams_init2.vh diff --git a/techlibs/ice40/arith_map.v b/techlibs/ice40/arith_map.v index fe83a8e38..26b24db9e 100644 --- a/techlibs/ice40/arith_map.v +++ b/techlibs/ice40/arith_map.v @@ -44,35 +44,21 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO); genvar i; generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice -`ifdef _ABC - \$__ICE40_FULL_ADDER carry ( + \$__ICE40_CARRY_WRAPPER #( + // A[0]: 1010 1010 1010 1010 + // A[1]: 1100 1100 1100 1100 + // A[2]: 1111 0000 1111 0000 + // A[3]: 1111 1111 0000 0000 + .LUT(16'b 0110_1001_1001_0110) + ) fadd ( .A(AA[i]), .B(BB[i]), .CI(C[i]), + .I0(1'b0), + .I3(C[i]), .CO(CO[i]), .O(Y[i]) ); -`else - SB_CARRY carry ( - .I0(AA[i]), - .I1(BB[i]), - .CI(C[i]), - .CO(CO[i]) - ); - SB_LUT4 #( - // I0: 1010 1010 1010 1010 - // I1: 1100 1100 1100 1100 - // I2: 1111 0000 1111 0000 - // I3: 1111 1111 0000 0000 - .LUT_INIT(16'b 0110_1001_1001_0110) - ) adder ( - .I0(1'b0), - .I1(AA[i]), - .I2(BB[i]), - .I3(C[i]), - .O(Y[i]) - ); -`endif end endgenerate assign X = AA ^ BB; diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v index b4b831165..662423f0a 100644 --- a/techlibs/ice40/cells_map.v +++ b/techlibs/ice40/cells_map.v @@ -62,26 +62,21 @@ module \$lut (A, Y); endmodule `endif -`ifdef _ABC -module \$__ICE40_FULL_ADDER (output CO, O, input A, B, CI); +`ifndef NO_ADDER +module \$__ICE40_CARRY_WRAPPER (output CO, O, input A, B, CI, I0, I3); + parameter LUT = 0; SB_CARRY carry ( .I0(A), .I1(B), .CI(CI), .CO(CO) ); - SB_LUT4 #( - // I0: 1010 1010 1010 1010 - // I1: 1100 1100 1100 1100 - // I2: 1111 0000 1111 0000 - // I3: 1111 1111 0000 0000 - .LUT_INIT(16'b 0110_1001_1001_0110) - ) adder ( - .I0(1'b0), - .I1(A), - .I2(B), - .I3(CI), - .O(O) + \$lut #( + .WIDTH(4), + .LUT(LUT) + ) lut ( + .A({I0,A,B,I3}), + .Y(O) ); endmodule `endif diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 609facc93..2205be27d 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -1363,13 +1363,13 @@ module SB_MAC16 ( wire [15:0] p_Ah_Bh, p_Al_Bh, p_Ah_Bl, p_Al_Bl; wire [15:0] Ah, Al, Bh, Bl; assign Ah = {A_SIGNED ? {8{iA[15]}} : 8'b0, iA[15: 8]}; - assign Al = {A_SIGNED ? {8{iA[ 7]}} : 8'b0, iA[ 7: 0]}; + assign Al = {A_SIGNED && MODE_8x8 ? {8{iA[ 7]}} : 8'b0, iA[ 7: 0]}; assign Bh = {B_SIGNED ? {8{iB[15]}} : 8'b0, iB[15: 8]}; - assign Bl = {B_SIGNED ? {8{iB[ 7]}} : 8'b0, iB[ 7: 0]}; - assign p_Ah_Bh = Ah * Bh; - assign p_Al_Bh = Al * Bh; - assign p_Ah_Bl = Ah * Bl; - assign p_Al_Bl = Al * Bl; + assign Bl = {B_SIGNED && MODE_8x8 ? {8{iB[ 7]}} : 8'b0, iB[ 7: 0]}; + assign p_Ah_Bh = Ah * Bh; // F + assign p_Al_Bh = {8'b0, Al[7:0]} * Bh; // J + assign p_Ah_Bl = Ah * {8'b0, Bl[7:0]}; // K + assign p_Al_Bl = Al * Bl; // G // Regs F and J reg [15:0] rF, rJ; @@ -1400,7 +1400,9 @@ module SB_MAC16 ( assign iG = BOT_8x8_MULT_REG ? rG : p_Al_Bl; // Adder Stage - assign iL = iG + (iK << 8) + (iJ << 8) + (iF << 16); + wire [23:0] iK_e = {A_SIGNED ? {8{iK[15]}} : 8'b0, iK}; + wire [23:0] iJ_e = {B_SIGNED ? {8{iJ[15]}} : 8'b0, iJ}; + assign iL = iG + (iK_e << 8) + (iJ_e << 8) + (iF << 16); // Reg H reg [31:0] rH; diff --git a/techlibs/ice40/ice40_braminit.cc b/techlibs/ice40/ice40_braminit.cc index 4fa6b0792..1a139ffea 100644 --- a/techlibs/ice40/ice40_braminit.cc +++ b/techlibs/ice40/ice40_braminit.cc @@ -69,13 +69,13 @@ static void run_ice40_braminit(Module *module) for (int i = 0; i < GetSize(line); i++) { - if (in_comment && line.substr(i, 2) == "*/") { + if (in_comment && line.compare(i, 2, "*/") == 0) { line[i] = ' '; line[i+1] = ' '; in_comment = false; continue; } - if (!in_comment && line.substr(i, 2) == "/*") + if (!in_comment && line.compare(i, 2, "/*") == 0) in_comment = true; if (in_comment) line[i] = ' '; @@ -87,7 +87,7 @@ static void run_ice40_braminit(Module *module) long value; token = next_token(line, " \t\r\n"); - if (token.empty() || token.substr(0, 2) == "//") + if (token.empty() || token.compare(0, 2, "//") == 0) break; if (token[0] == '@') { diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index e492454fb..d5106b805 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -117,7 +117,7 @@ static void run_ice40_opts(Module *module) log("Optimized $__ICE40_FULL_ADDER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n", log_id(module), log_id(cell), log_signal(replacement_output)); cell->type = "$lut"; - cell->setPort("\\A", { RTLIL::S0, inbit[0], inbit[1], inbit[2] }); + cell->setPort("\\A", { State::S0, inbit[0], inbit[1], inbit[2] }); cell->setPort("\\Y", cell->getPort("\\O")); cell->unsetPort("\\B"); cell->unsetPort("\\CI"); diff --git a/techlibs/ice40/ice40_unlut.cc b/techlibs/ice40/ice40_unlut.cc deleted file mode 100644 index f3f70ac1f..000000000 --- a/techlibs/ice40/ice40_unlut.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * - * 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 -#include - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -static SigBit get_bit_or_zero(const SigSpec &sig) -{ - if (GetSize(sig) == 0) - return State::S0; - return sig[0]; -} - -static void run_ice40_unlut(Module *module) -{ - SigMap sigmap(module); - - for (auto cell : module->selected_cells()) - { - if (cell->type == "\\SB_LUT4") - { - SigSpec inbits; - - inbits.append(get_bit_or_zero(cell->getPort("\\I0"))); - inbits.append(get_bit_or_zero(cell->getPort("\\I1"))); - inbits.append(get_bit_or_zero(cell->getPort("\\I2"))); - inbits.append(get_bit_or_zero(cell->getPort("\\I3"))); - sigmap.apply(inbits); - - log("Mapping SB_LUT4 cell %s.%s to $lut.\n", log_id(module), log_id(cell)); - - cell->type ="$lut"; - cell->setParam("\\WIDTH", 4); - cell->setParam("\\LUT", cell->getParam("\\LUT_INIT")); - cell->unsetParam("\\LUT_INIT"); - - cell->setPort("\\A", SigSpec({ - get_bit_or_zero(cell->getPort("\\I0")), - get_bit_or_zero(cell->getPort("\\I1")), - get_bit_or_zero(cell->getPort("\\I2")), - get_bit_or_zero(cell->getPort("\\I3")) - })); - cell->setPort("\\Y", cell->getPort("\\O")[0]); - cell->unsetPort("\\I0"); - cell->unsetPort("\\I1"); - cell->unsetPort("\\I2"); - cell->unsetPort("\\I3"); - cell->unsetPort("\\O"); - - cell->check(); - } - } -} - -struct Ice40UnlutPass : public Pass { - Ice40UnlutPass() : Pass("ice40_unlut", "iCE40: transform SB_LUT4 cells to $lut cells") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" ice40_unlut [options] [selection]\n"); - log("\n"); - log("This command transforms all SB_LUT4 cells to generic $lut cells.\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing ICE40_UNLUT pass (convert SB_LUT4 to $lut).\n"); - log_push(); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) { - // if (args[argidx] == "-???") { - // continue; - // } - break; - } - extra_args(args, argidx, design); - - for (auto module : design->selected_modules()) - run_ice40_unlut(module); - } -} Ice40UnlutPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index be60a0071..c6de81bd9 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -183,7 +183,7 @@ struct SynthIce40Pass : public ScriptPass continue; } if (args[argidx] == "-dffe_min_ce_use" && argidx+1 < args.size()) { - min_ce_use = std::stoi(args[++argidx]); + min_ce_use = atoi(args[++argidx].c_str()); continue; } if (args[argidx] == "-nobram") { @@ -238,7 +238,7 @@ struct SynthIce40Pass : public ScriptPass { if (check_label("begin")) { - run("read_verilog -icells -lib -D_ABC +/ice40/cells_sim.v"); + run("read_verilog -icells -lib +/ice40/cells_sim.v"); run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); run("proc"); } @@ -293,8 +293,10 @@ struct SynthIce40Pass : public ScriptPass { if (nocarry) run("techmap"); - else - run("techmap -map +/techmap.v -map +/ice40/arith_map.v" + std::string(abc == "abc9" ? " -D _ABC" : "")); + else { + run("ice40_wrapcarry"); + run("techmap -map +/techmap.v -map +/ice40/arith_map.v"); + } if (retime || help_mode) run(abc + " -dff", "(only if -retime)"); run("ice40_opt"); @@ -309,7 +311,7 @@ struct SynthIce40Pass : public ScriptPass run("opt_merge"); run(stringf("dff2dffe -unmap-mince %d", min_ce_use)); } - run("techmap -D NO_LUT -map +/ice40/cells_map.v"); + run("techmap -D NO_LUT -D NO_ADDER -map +/ice40/cells_map.v"); run("opt_expr -mux_undef"); run("simplemap"); run("ice40_ffinit"); @@ -338,13 +340,12 @@ struct SynthIce40Pass : public ScriptPass else wire_delay = 250; run(abc + stringf(" -W %d -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)"); - run("techmap -D NO_LUT -D _ABC -map +/ice40/cells_map.v"); } else run(abc + " -dress -lut 4", "(skip if -noabc)"); } + run("techmap -D NO_LUT -map +/ice40/cells_map.v"); run("clean"); - run("ice40_unlut"); run("opt_lut -dlogic SB_CARRY:I0=2:I1=1:CI=0"); } diff --git a/techlibs/ice40/tests/test_arith.ys b/techlibs/ice40/tests/test_arith.ys index 160c767fb..ddb80b700 100644 --- a/techlibs/ice40/tests/test_arith.ys +++ b/techlibs/ice40/tests/test_arith.ys @@ -1,6 +1,5 @@ read_verilog test_arith.v synth_ice40 -techmap -map ../cells_sim.v rename test gate read_verilog test_arith.v @@ -8,3 +7,11 @@ rename test gold miter -equiv -flatten -make_outputs gold gate miter sat -verify -prove trigger 0 -show-ports miter + +synth_ice40 -top gate + +read_verilog test_arith.v +rename test gold + +miter -equiv -flatten -make_outputs gold gate miter +sat -verify -prove trigger 0 -show-ports miter diff --git a/techlibs/ice40/tests/test_dsp_model.sh b/techlibs/ice40/tests/test_dsp_model.sh index 1bc0cc688..1e564d1b2 100644 --- a/techlibs/ice40/tests/test_dsp_model.sh +++ b/techlibs/ice40/tests/test_dsp_model.sh @@ -1,10 +1,15 @@ #!/bin/bash set -ex sed 's/SB_MAC16/SB_MAC16_UUT/; /SB_MAC16_UUT/,/endmodule/ p; d;' < ../cells_sim.v > test_dsp_model_uut.v -cat /opt/lscc/iCEcube2.2017.01/verilog/sb_ice_syn.v > test_dsp_model_ref.v +if [ ! -f "test_dsp_model_ref.v" ]; then + cat /opt/lscc/iCEcube2.2017.01/verilog/sb_ice_syn.v > test_dsp_model_ref.v +fi for tb in testbench \ testbench_comb_8x8_A testbench_comb_8x8_B testbench_comb_16x16 \ - testbench_seq_16x16_A testbench_seq_16x16_B + testbench_seq_16x16_A testbench_seq_16x16_B \ + testbench_comb_8x8_A_signedA testbench_comb_8x8_A_signedB testbench_comb_8x8_A_signedAB \ + testbench_comb_8x8_B_signedA testbench_comb_8x8_B_signedB testbench_comb_8x8_B_signedAB \ + testbench_comb_16x16_signedA testbench_comb_16x16_signedB testbench_comb_16x16_signedAB do iverilog -s $tb -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v vvp -N ./test_dsp_model diff --git a/techlibs/ice40/tests/test_dsp_model.v b/techlibs/ice40/tests/test_dsp_model.v index 594bd4ad3..f4f6858f0 100644 --- a/techlibs/ice40/tests/test_dsp_model.v +++ b/techlibs/ice40/tests/test_dsp_model.v @@ -241,6 +241,81 @@ module testbench_comb_8x8_A; ) testbench (); endmodule +module testbench_comb_8x8_A_signedA; + testbench #( + .NEG_TRIGGER (0), + .C_REG (0), + .A_REG (0), + .B_REG (0), + .D_REG (0), + .TOP_8x8_MULT_REG (0), + .BOT_8x8_MULT_REG (0), + .PIPELINE_16x16_MULT_REG1 (0), + .PIPELINE_16x16_MULT_REG2 (0), + .TOPOUTPUT_SELECT (2), // 0=P, 1=Q, 2=8x8, 3=16x16 + .TOPADDSUB_LOWERINPUT (0), // 0=A, 1=8x8, 2=16x16, 3=S-EXT + .TOPADDSUB_UPPERINPUT (0), // 0=Q, 1=C + .TOPADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .BOTOUTPUT_SELECT (2), // 0=R, 1=S, 2=8x8, 3=16x16 + .BOTADDSUB_LOWERINPUT (0), // 0=B, 1=8x8, 2=16x16, 3=S-EXT + .BOTADDSUB_UPPERINPUT (0), // 0=S, 1=D + .BOTADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .MODE_8x8 (0), + .A_SIGNED (1), + .B_SIGNED (0) + ) testbench (); +endmodule + +module testbench_comb_8x8_A_signedB; + testbench #( + .NEG_TRIGGER (0), + .C_REG (0), + .A_REG (0), + .B_REG (0), + .D_REG (0), + .TOP_8x8_MULT_REG (0), + .BOT_8x8_MULT_REG (0), + .PIPELINE_16x16_MULT_REG1 (0), + .PIPELINE_16x16_MULT_REG2 (0), + .TOPOUTPUT_SELECT (2), // 0=P, 1=Q, 2=8x8, 3=16x16 + .TOPADDSUB_LOWERINPUT (0), // 0=A, 1=8x8, 2=16x16, 3=S-EXT + .TOPADDSUB_UPPERINPUT (0), // 0=Q, 1=C + .TOPADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .BOTOUTPUT_SELECT (2), // 0=R, 1=S, 2=8x8, 3=16x16 + .BOTADDSUB_LOWERINPUT (0), // 0=B, 1=8x8, 2=16x16, 3=S-EXT + .BOTADDSUB_UPPERINPUT (0), // 0=S, 1=D + .BOTADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .MODE_8x8 (0), + .A_SIGNED (0), + .B_SIGNED (1) + ) testbench (); +endmodule + +module testbench_comb_8x8_A_signedAB; + testbench #( + .NEG_TRIGGER (0), + .C_REG (0), + .A_REG (0), + .B_REG (0), + .D_REG (0), + .TOP_8x8_MULT_REG (0), + .BOT_8x8_MULT_REG (0), + .PIPELINE_16x16_MULT_REG1 (0), + .PIPELINE_16x16_MULT_REG2 (0), + .TOPOUTPUT_SELECT (2), // 0=P, 1=Q, 2=8x8, 3=16x16 + .TOPADDSUB_LOWERINPUT (0), // 0=A, 1=8x8, 2=16x16, 3=S-EXT + .TOPADDSUB_UPPERINPUT (0), // 0=Q, 1=C + .TOPADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .BOTOUTPUT_SELECT (2), // 0=R, 1=S, 2=8x8, 3=16x16 + .BOTADDSUB_LOWERINPUT (0), // 0=B, 1=8x8, 2=16x16, 3=S-EXT + .BOTADDSUB_UPPERINPUT (0), // 0=S, 1=D + .BOTADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .MODE_8x8 (0), + .A_SIGNED (1), + .B_SIGNED (1) + ) testbench (); +endmodule + module testbench_comb_8x8_B; testbench #( .NEG_TRIGGER (0), @@ -266,6 +341,81 @@ module testbench_comb_8x8_B; ) testbench (); endmodule +module testbench_comb_8x8_B_signedA; + testbench #( + .NEG_TRIGGER (0), + .C_REG (0), + .A_REG (0), + .B_REG (0), + .D_REG (0), + .TOP_8x8_MULT_REG (0), + .BOT_8x8_MULT_REG (0), + .PIPELINE_16x16_MULT_REG1 (0), + .PIPELINE_16x16_MULT_REG2 (0), + .TOPOUTPUT_SELECT (0), // 0=P, 1=Q, 2=8x8, 3=16x16 + .TOPADDSUB_LOWERINPUT (1), // 0=A, 1=8x8, 2=16x16, 3=S-EXT + .TOPADDSUB_UPPERINPUT (1), // 0=Q, 1=C + .TOPADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .BOTOUTPUT_SELECT (0), // 0=R, 1=S, 2=8x8, 3=16x16 + .BOTADDSUB_LOWERINPUT (1), // 0=B, 1=8x8, 2=16x16, 3=S-EXT + .BOTADDSUB_UPPERINPUT (1), // 0=S, 1=D + .BOTADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .MODE_8x8 (0), + .A_SIGNED (1), + .B_SIGNED (0) + ) testbench (); +endmodule + +module testbench_comb_8x8_B_signedB; + testbench #( + .NEG_TRIGGER (0), + .C_REG (0), + .A_REG (0), + .B_REG (0), + .D_REG (0), + .TOP_8x8_MULT_REG (0), + .BOT_8x8_MULT_REG (0), + .PIPELINE_16x16_MULT_REG1 (0), + .PIPELINE_16x16_MULT_REG2 (0), + .TOPOUTPUT_SELECT (0), // 0=P, 1=Q, 2=8x8, 3=16x16 + .TOPADDSUB_LOWERINPUT (1), // 0=A, 1=8x8, 2=16x16, 3=S-EXT + .TOPADDSUB_UPPERINPUT (1), // 0=Q, 1=C + .TOPADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .BOTOUTPUT_SELECT (0), // 0=R, 1=S, 2=8x8, 3=16x16 + .BOTADDSUB_LOWERINPUT (1), // 0=B, 1=8x8, 2=16x16, 3=S-EXT + .BOTADDSUB_UPPERINPUT (1), // 0=S, 1=D + .BOTADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .MODE_8x8 (0), + .A_SIGNED (0), + .B_SIGNED (1) + ) testbench (); +endmodule + +module testbench_comb_8x8_B_signedAB; + testbench #( + .NEG_TRIGGER (0), + .C_REG (0), + .A_REG (0), + .B_REG (0), + .D_REG (0), + .TOP_8x8_MULT_REG (0), + .BOT_8x8_MULT_REG (0), + .PIPELINE_16x16_MULT_REG1 (0), + .PIPELINE_16x16_MULT_REG2 (0), + .TOPOUTPUT_SELECT (0), // 0=P, 1=Q, 2=8x8, 3=16x16 + .TOPADDSUB_LOWERINPUT (1), // 0=A, 1=8x8, 2=16x16, 3=S-EXT + .TOPADDSUB_UPPERINPUT (1), // 0=Q, 1=C + .TOPADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .BOTOUTPUT_SELECT (0), // 0=R, 1=S, 2=8x8, 3=16x16 + .BOTADDSUB_LOWERINPUT (1), // 0=B, 1=8x8, 2=16x16, 3=S-EXT + .BOTADDSUB_UPPERINPUT (1), // 0=S, 1=D + .BOTADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI + .MODE_8x8 (0), + .A_SIGNED (1), + .B_SIGNED (1) + ) testbench (); +endmodule + module testbench_comb_16x16; testbench #( .NEG_TRIGGER (0), @@ -291,6 +441,81 @@ module testbench_comb_16x16; ) testbench (); endmodule +module testbench_comb_16x16_signedA; + testbench #( + .NEG_TRIGGER (0), + .C_REG (0), + .A_REG (0), + .B_REG (0), + .D_REG (0), + .TOP_8x8_MULT_REG (0), + .BOT_8x8_MULT_REG (0), + .PIPELINE_16x16_MULT_REG1 (0), + .PIPELINE_16x16_MULT_REG2 (0), + .TOPOUTPUT_SELECT (0), // 0=P, 1=Q, 2=8x8, 3=16x16 + .TOPADDSUB_LOWERINPUT (2), // 0=A, 1=8x8, 2=16x16, 3=S-EXT + .TOPADDSUB_UPPERINPUT (1), // 0=Q, 1=C + .TOPADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI + .BOTOUTPUT_SELECT (0), // 0=R, 1=S, 2=8x8, 3=16x16 + .BOTADDSUB_LOWERINPUT (2), // 0=B, 1=8x8, 2=16x16, 3=S-EXT + .BOTADDSUB_UPPERINPUT (1), // 0=S, 1=D + .BOTADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI + .MODE_8x8 (0), + .A_SIGNED (1), + .B_SIGNED (0) + ) testbench (); +endmodule + +module testbench_comb_16x16_signedB; + testbench #( + .NEG_TRIGGER (0), + .C_REG (0), + .A_REG (0), + .B_REG (0), + .D_REG (0), + .TOP_8x8_MULT_REG (0), + .BOT_8x8_MULT_REG (0), + .PIPELINE_16x16_MULT_REG1 (0), + .PIPELINE_16x16_MULT_REG2 (0), + .TOPOUTPUT_SELECT (0), // 0=P, 1=Q, 2=8x8, 3=16x16 + .TOPADDSUB_LOWERINPUT (2), // 0=A, 1=8x8, 2=16x16, 3=S-EXT + .TOPADDSUB_UPPERINPUT (1), // 0=Q, 1=C + .TOPADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI + .BOTOUTPUT_SELECT (0), // 0=R, 1=S, 2=8x8, 3=16x16 + .BOTADDSUB_LOWERINPUT (2), // 0=B, 1=8x8, 2=16x16, 3=S-EXT + .BOTADDSUB_UPPERINPUT (1), // 0=S, 1=D + .BOTADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI + .MODE_8x8 (0), + .A_SIGNED (0), + .B_SIGNED (1) + ) testbench (); +endmodule + +module testbench_comb_16x16_signedAB; + testbench #( + .NEG_TRIGGER (0), + .C_REG (0), + .A_REG (0), + .B_REG (0), + .D_REG (0), + .TOP_8x8_MULT_REG (0), + .BOT_8x8_MULT_REG (0), + .PIPELINE_16x16_MULT_REG1 (0), + .PIPELINE_16x16_MULT_REG2 (0), + .TOPOUTPUT_SELECT (0), // 0=P, 1=Q, 2=8x8, 3=16x16 + .TOPADDSUB_LOWERINPUT (2), // 0=A, 1=8x8, 2=16x16, 3=S-EXT + .TOPADDSUB_UPPERINPUT (1), // 0=Q, 1=C + .TOPADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI + .BOTOUTPUT_SELECT (0), // 0=R, 1=S, 2=8x8, 3=16x16 + .BOTADDSUB_LOWERINPUT (2), // 0=B, 1=8x8, 2=16x16, 3=S-EXT + .BOTADDSUB_UPPERINPUT (1), // 0=S, 1=D + .BOTADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI + .MODE_8x8 (0), + .A_SIGNED (1), + .B_SIGNED (1) + ) testbench (); +endmodule + module testbench_seq_16x16_A; testbench #( .NEG_TRIGGER (0), diff --git a/techlibs/intel/Makefile.inc b/techlibs/intel/Makefile.inc index ec7cea379..4e8f423c8 100644 --- a/techlibs/intel/Makefile.inc +++ b/techlibs/intel/Makefile.inc @@ -3,22 +3,12 @@ OBJS += techlibs/intel/synth_intel.o $(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.txt)) -$(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_map.v)) -$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/cells_sim.v)) -$(eval $(call add_share_file,share/intel/a10gx,techlibs/intel/a10gx/cells_sim.v)) -$(eval $(call add_share_file,share/intel/cyclonev,techlibs/intel/cyclonev/cells_sim.v)) -$(eval $(call add_share_file,share/intel/cyclone10,techlibs/intel/cyclone10/cells_sim.v)) -$(eval $(call add_share_file,share/intel/cycloneiv,techlibs/intel/cycloneiv/cells_sim.v)) -$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/cells_sim.v)) -$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/cells_map.v)) -$(eval $(call add_share_file,share/intel/a10gx,techlibs/intel/a10gx/cells_map.v)) -$(eval $(call add_share_file,share/intel/cyclonev,techlibs/intel/cyclonev/cells_map.v)) -$(eval $(call add_share_file,share/intel/cyclone10,techlibs/intel/cyclone10/cells_map.v)) -$(eval $(call add_share_file,share/intel/cycloneiv,techlibs/intel/cycloneiv/cells_map.v)) -$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/cells_map.v)) -#$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/arith_map.v)) -#$(eval $(call add_share_file,share/intel/a10gx,techlibs/intel/a10gx/arith_map.v)) -#$(eval $(call add_share_file,share/intel/cycloneiv,techlibs/intel/cycloneiv/arith_map.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)) + +# Add the cell models and mappings for the VQM backend +families := max10 a10gx cyclonev cyclone10 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/common/brams.txt b/techlibs/intel/common/brams_m9k.txt similarity index 100% rename from techlibs/intel/common/brams.txt rename to techlibs/intel/common/brams_m9k.txt diff --git a/techlibs/intel/common/brams_map.v b/techlibs/intel/common/brams_map_m9k.v similarity index 100% rename from techlibs/intel/common/brams_map.v rename to techlibs/intel/common/brams_map_m9k.v diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index d7b089503..e5dc1adc7 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -61,8 +61,8 @@ struct SynthIntelPass : public ScriptPass { 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(" -noiopads\n"); - log(" do not use IO pad cells in output netlist\n"); + log(" -iopads\n"); + log(" use IO pad cells in output netlist\n"); log("\n"); log(" -nobram\n"); log(" do not use block RAM cells in output netlist\n"); @@ -79,7 +79,7 @@ struct SynthIntelPass : public ScriptPass { } string top_opt, family_opt, vout_file, blif_file; - bool retime, flatten, nobram, noiopads; + bool retime, flatten, nobram, iopads; void clear_flags() YS_OVERRIDE { @@ -90,7 +90,7 @@ struct SynthIntelPass : public ScriptPass { retime = false; flatten = true; nobram = false; - noiopads = false; + iopads = false; } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE @@ -125,8 +125,8 @@ struct SynthIntelPass : public ScriptPass { run_to = args[argidx].substr(pos + 1); continue; } - if (args[argidx] == "-noiopads") { - noiopads = true; + if (args[argidx] == "-iopads") { + iopads = true; continue; } if (args[argidx] == "-nobram") { @@ -187,8 +187,15 @@ struct SynthIntelPass : public ScriptPass { } if (!nobram && check_label("map_bram", "(skip if -nobram)")) { - run("memory_bram -rules +/intel/common/brams.txt"); - run("techmap -map +/intel/common/brams_map.v"); + if (family_opt == "cycloneiv" || + family_opt == "cycloneive" || + family_opt == "max10" || + help_mode) { + run("memory_bram -rules +/intel/common/brams_m9k.txt", "(if applicable for family)"); + run("techmap -map +/intel/common/brams_map_m9k.v", "(if applicable for family)"); + } else { + log_warning("BRAM mapping is not currently supported for %s.\n", family_opt.c_str()); + } } if (check_label("map_ffram")) { @@ -215,10 +222,9 @@ struct SynthIntelPass : public ScriptPass { } if (check_label("map_cells")) { - if (!noiopads) - run("iopadmap -bits -outpad $__outpad I:O -inpad $__inpad O:I", "(unless -noiopads)"); + 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/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v index 2eb9fa2c1..b8e5bafc7 100644 --- a/techlibs/xilinx/cells_map.v +++ b/techlibs/xilinx/cells_map.v @@ -24,9 +24,9 @@ module _90_dff_nn0_to_np0 (input D, C, R, output Q); \$_DFF_NP0_ _TECHMAP_REPLA (* 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 +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 +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 module \$__SHREG_ (input C, input D, input E, output Q); parameter DEPTH = 0; diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index a6c1fa873..7ba67409b 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -195,7 +195,7 @@ struct SynthXilinxPass : public ScriptPass continue; } if (args[argidx] == "-widemux" && argidx+1 < args.size()) { - widemux = std::stoi(args[++argidx]); + widemux = atoi(args[++argidx].c_str()); continue; } if (args[argidx] == "-abc9") { diff --git a/techlibs/xilinx/xc6s_brams_map.v b/techlibs/xilinx/xc6s_brams_map.v index c9b33af42..16fd15e74 100644 --- a/techlibs/xilinx/xc6s_brams_map.v +++ b/techlibs/xilinx/xc6s_brams_map.v @@ -52,7 +52,7 @@ module \$__XILINX_RAMB8BWER_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DAT .CLKBRDCLK(CLK2 ^ !CLKPOL2), .ENBRDEN(A1EN), .REGCEBREGCE(|1), - .RSTB(|0) + .RSTBRST(|0) ); endmodule @@ -217,7 +217,7 @@ module \$__XILINX_RAMB8BWER_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DAT .CLKBRDCLK(CLK3 ^ !CLKPOL3), .ENBRDEN(|1), .REGCEBREGCE(|0), - .RSTB(|0), + .RSTBRST(|0), .WEBWEU(B1EN_2) ); end else begin @@ -248,7 +248,7 @@ module \$__XILINX_RAMB8BWER_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DAT .CLKBRDCLK(CLK3 ^ !CLKPOL3), .ENBRDEN(|1), .REGCEBREGCE(|0), - .RSTB(|0), + .RSTBRST(|0), .WEBWEU(B1EN_2) ); end endgenerate diff --git a/tests/fsm/run-test.sh b/tests/fsm/run-test.sh index cf506470d..fbdcbf048 100755 --- a/tests/fsm/run-test.sh +++ b/tests/fsm/run-test.sh @@ -6,7 +6,7 @@ set -e OPTIND=1 -count=100 +count=50 seed="" # default to no seed specified while getopts "c:S:" opt do diff --git a/tests/opt/opt_expr.ys b/tests/opt/opt_expr.ys new file mode 100644 index 000000000..f0306efa1 --- /dev/null +++ b/tests/opt/opt_expr.ys @@ -0,0 +1,223 @@ + +read_verilog <=', + '>']), + random.choice(['<<', '>>', '<<<', '>>>']), + random.choice(['|', '&', '^', '~^', '||', '&&']), + ]) + print(' input%s [%d:0] a;' % (random.choice(['', ' signed']), 8)) + print(' input%s [%d:0] b;' % (random.choice(['', ' signed']), 8)) + print(' input%s [%d:0] c;' % (random.choice(['', ' signed']), 8)) + print(' input s;') + print(' output [%d:0] y;' % 8) + ops1 = ['a', 'b'] + ops2 = ['a', 'c'] + random.shuffle(ops1) + random.shuffle(ops2) + cast1 = random.choice(['', '$signed', '$unsigned']) + cast2 = random.choice(['', '$signed', '$unsigned']) + print(' assign y = (s ? %s(%s %s %s) : %s(%s %s %s));' % + (cast1, ops1[0], op, ops1[1], + cast2, ops2[0], op, ops2[1])) + print('endmodule') + + with open('temp/uut_%05d.ys' % idx, 'w') as f: + with redirect_stdout(f): + print('read_verilog temp/uut_%05d.v' % idx) + print('proc;;') + print('copy uut_%05d gold' % idx) + print('rename uut_%05d gate' % idx) + print('tee -a temp/all_share_log.txt log') + print('tee -a temp/all_share_log.txt log #job# uut_%05d' % idx) + print('tee -a temp/all_share_log.txt opt gate') + print('tee -a temp/all_share_log.txt opt_share gate') + print('tee -a temp/all_share_log.txt opt_clean gate') + print( + 'miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter' + ) + print( + 'sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter' + ) diff --git a/tests/opt_share/run-test.sh b/tests/opt_share/run-test.sh new file mode 100755 index 000000000..e01552646 --- /dev/null +++ b/tests/opt_share/run-test.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# run this test many times: +# time bash -c 'for ((i=0; i<100; i++)); do echo "-- $i --"; bash run-test.sh || exit 1; done' + +set -e + +OPTIND=1 +count=100 +seed="" # default to no seed specified +while getopts "c:S:" opt +do + case "$opt" in + c) count="$OPTARG" ;; + S) seed="-S $OPTARG" ;; + esac +done +shift "$((OPTIND-1))" + +rm -rf temp +mkdir -p temp +echo "generating tests.." +python3 generate.py -c $count $seed + +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 +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 ) ) +if [ -n "$failed_share" ]; then + echo "Resource sharing failed for the following test cases: $failed_share" + false +fi + +exit 0 diff --git a/tests/simple/xfirrtl b/tests/simple/xfirrtl index ba61a4476..10063d2c2 100644 --- a/tests/simple/xfirrtl +++ b/tests/simple/xfirrtl @@ -1,10 +1,12 @@ # This file contains the names of verilog files to exclude from verilog to FIRRTL regression tests due to known failures. arraycells.v inst id[0] of +defvalue.sv Initial value not supported dff_different_styles.v dff_init.v Initial value not supported generate.v combinational loop hierdefparam.v inst id[0] of i2c_master_tests.v $adff +implicit_ports.v not fully initialized macros.v drops modules mem2reg.v drops modules mem_arst.v $adff @@ -12,7 +14,6 @@ memory.v $adff multiplier.v inst id[0] of muxtree.v drops modules omsp_dbg_uart.v $adff -operators.v $pow partsel.v drops modules process.v drops modules realexpr.v drops modules @@ -23,5 +24,6 @@ specify.v no code (empty module generates error subbytes.v $adff task_func.v drops modules values.v combinational loop +wandwor.v Invalid connect to an expression that is not a reference or a WritePort. vloghammer.v combinational loop wreduce.v original verilog issues ( -x where x isn't declared signed) diff --git a/tests/simple_abc9/.gitignore b/tests/simple_abc9/.gitignore index 598951333..2355aea29 100644 --- a/tests/simple_abc9/.gitignore +++ b/tests/simple_abc9/.gitignore @@ -1,3 +1,4 @@ *.v +*.sv *.log *.out diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh index 4935d41ad..49ae23338 100755 --- a/tests/simple_abc9/run-test.sh +++ b/tests/simple_abc9/run-test.sh @@ -18,5 +18,6 @@ if ! which iverilog > /dev/null ; then fi cp ../simple/*.v . +cp ../simple/*.sv . DOLLAR='?' -exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v EXTRA_FLAGS="-p 'hierarchy; synth -run coarse; opt -full; techmap; abc9 -lut 4 -box ../abc.box; stat; check -assert; select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%'" +exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v EXTRA_FLAGS="-n 300 -p 'hierarchy; synth -run coarse; opt -full; techmap; abc9 -lut 4 -box ../abc.box; stat; check -assert; select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%'" diff --git a/tests/various/.gitignore b/tests/various/.gitignore index 7b3e8c68e..4b286fd61 100644 --- a/tests/various/.gitignore +++ b/tests/various/.gitignore @@ -1,2 +1,5 @@ /*.log /*.out +/write_gzip.v +/write_gzip.v.gz +/run-test.mk diff --git a/tests/various/gzip_verilog.v.gz b/tests/various/gzip_verilog.v.gz new file mode 100644 index 000000000..c52a95358 Binary files /dev/null and b/tests/various/gzip_verilog.v.gz differ diff --git a/tests/various/gzip_verilog.ys b/tests/various/gzip_verilog.ys new file mode 100644 index 000000000..870317e80 --- /dev/null +++ b/tests/various/gzip_verilog.ys @@ -0,0 +1,2 @@ +read_verilog gzip_verilog.v.gz +select -assert-any top diff --git a/tests/various/muxpack.ys b/tests/various/muxpack.ys index af23fcec8..3e90419af 100644 --- a/tests/various/muxpack.ys +++ b/tests/various/muxpack.ys @@ -6,7 +6,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -21,7 +21,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -52,7 +52,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 2 t:$pmux design -stash gate @@ -67,7 +67,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -82,7 +82,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -97,7 +97,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -112,7 +112,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -127,7 +127,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -142,7 +142,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 7 t:$mux select -assert-count 0 t:$pmux design -stash gate @@ -157,7 +157,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 4 t:$mux select -assert-count 0 t:$pmux design -stash gate @@ -172,7 +172,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 3 t:$mux select -assert-count 0 t:$pmux design -stash gate @@ -204,7 +204,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 2 t:$pmux design -stash gate @@ -222,7 +222,7 @@ opt -fast -mux_undef select -assert-count 2 t:$pmux muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -240,7 +240,7 @@ opt -fast -mux_undef select -assert-count 2 t:$pmux muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 2 t:$pmux design -stash gate @@ -258,7 +258,7 @@ opt -fast -mux_undef select -assert-count 2 t:$pmux muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 2 t:$pmux design -stash gate diff --git a/tests/various/run-test.sh b/tests/various/run-test.sh index 92b905765..ea56b70f0 100755 --- a/tests/various/run-test.sh +++ b/tests/various/run-test.sh @@ -1,12 +1,20 @@ #!/usr/bin/env bash set -e +{ +echo "all::" for x in *.ys; do - echo "Running $x.." - ../../yosys -ql ${x%.ys}.log $x + 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 "Running $s.." - bash $s + 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 diff --git a/tests/various/shregmap.ys b/tests/various/shregmap.ys index d644a88aa..0e5fe882b 100644 --- a/tests/various/shregmap.ys +++ b/tests/various/shregmap.ys @@ -11,7 +11,7 @@ shregmap -init opt -stat +# stat # show -width select -assert-count 1 t:$_DFF_P_ select -assert-count 2 t:$__SHREG_DFF_P_ @@ -26,11 +26,11 @@ prep miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports -seq 5 miter -design -load gold -stat +#design -load gold +#stat -design -load gate -stat +#design -load gate +#stat ########## @@ -43,9 +43,9 @@ design -save gold simplemap t:$dff t:$dffe shregmap -tech xilinx -stat +#stat # show -width -write_verilog -noexpr -norename +# write_verilog -noexpr -norename select -assert-count 1 t:$_DFF_P_ select -assert-count 2 t:$__XILINX_SHREG_ @@ -59,8 +59,8 @@ prep miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports -seq 5 miter -design -load gold -stat +# design -load gold +# stat -design -load gate -stat +# design -load gate +# stat diff --git a/tests/various/wreduce.ys b/tests/various/wreduce.ys new file mode 100644 index 000000000..2e0812c48 --- /dev/null +++ b/tests/various/wreduce.ys @@ -0,0 +1,79 @@ +read_verilog <> 4) - i; +endmodule +EOT + +hierarchy -auto-top +proc +design -save gold + +opt_expr +wreduce + +select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i + +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +########## + +read_verilog <>> 4) - i; +endmodule +EOT + +hierarchy -auto-top +proc +design -save gold + +opt_expr +wreduce + +select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i + +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter + +########## + +# Testcase from: https://github.com/YosysHQ/yosys/commit/25680f6a078bb32f157bd580705656496717bafb +design -reset +read_verilog <