aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEddie Hung <eddie@fpgeh.com>2019-08-06 14:50:00 -0700
committerEddie Hung <eddie@fpgeh.com>2019-08-06 14:50:00 -0700
commit26cb3e7afc603b5aa703434c2cdfad444a4d4db0 (patch)
treecb346623885c4bc1e98affc623084f58b0a87ce2
parent09beeee38a5af767f70d24e86c976e43b1b27547 (diff)
parent8110fb9266e685aaea48359a5aebc4e5ac865240 (diff)
downloadyosys-26cb3e7afc603b5aa703434c2cdfad444a4d4db0.tar.gz
yosys-26cb3e7afc603b5aa703434c2cdfad444a4d4db0.tar.bz2
yosys-26cb3e7afc603b5aa703434c2cdfad444a4d4db0.zip
Merge remote-tracking branch 'origin/master' into eddie/wreduce_add
-rw-r--r--.travis.yml5
-rw-r--r--CHANGELOG4
-rw-r--r--Makefile16
-rw-r--r--README.md73
-rw-r--r--backends/aiger/xaiger.cc14
-rw-r--r--backends/blif/blif.cc7
-rw-r--r--backends/btor/btor.cc8
-rw-r--r--backends/simplec/simplec.cc6
-rw-r--r--backends/smt2/smt2.cc1
-rw-r--r--backends/smv/smv.cc7
-rw-r--r--backends/verilog/verilog_backend.cc14
-rw-r--r--examples/mimas2/README8
-rw-r--r--examples/mimas2/example.ucf13
-rw-r--r--examples/mimas2/example.v14
-rw-r--r--examples/mimas2/run.sh8
-rw-r--r--examples/mimas2/run_yosys.ys4
-rw-r--r--frontends/aiger/aigerparse.cc4
-rw-r--r--frontends/ast/ast.cc2
-rw-r--r--frontends/verific/verific.cc3
-rw-r--r--frontends/verilog/verilog_lexer.l3
-rw-r--r--kernel/cellaigs.cc2
-rw-r--r--kernel/celltypes.h1
-rw-r--r--kernel/consteval.h7
-rw-r--r--kernel/cost.h34
-rw-r--r--kernel/register.cc109
-rw-r--r--kernel/rtlil.cc2
-rw-r--r--kernel/rtlil.h24
-rw-r--r--kernel/satgen.h7
-rw-r--r--kernel/yosys.cc21
-rw-r--r--kernel/yosys.h5
-rw-r--r--manual/CHAPTER_CellLib.tex2
-rw-r--r--misc/launcher.c3
-rw-r--r--passes/cmds/stat.cc35
-rw-r--r--passes/opt/opt_lut.cc8
-rw-r--r--passes/opt/rmports.cc2
-rw-r--r--passes/proc/proc_prune.cc13
-rw-r--r--passes/techmap/abc.cc91
-rw-r--r--passes/techmap/extract_fa.cc2
-rw-r--r--passes/techmap/flowmap.cc10
-rw-r--r--techlibs/anlogic/anlogic_determine_init.cc4
-rw-r--r--techlibs/anlogic/anlogic_eqn.cc4
-rw-r--r--techlibs/common/simcells.v19
-rw-r--r--techlibs/gowin/determine_init.cc4
-rw-r--r--techlibs/ice40/cells_sim.v16
-rw-r--r--techlibs/ice40/tests/test_dsp_model.sh9
-rw-r--r--techlibs/ice40/tests/test_dsp_model.v225
-rw-r--r--techlibs/intel/Makefile.inc4
-rw-r--r--techlibs/intel/common/brams_m9k.txt (renamed from techlibs/intel/common/brams.txt)0
-rw-r--r--techlibs/intel/common/brams_map_m9k.v (renamed from techlibs/intel/common/brams_map.v)0
-rw-r--r--techlibs/intel/synth_intel.cc28
-rw-r--r--techlibs/xilinx/cells_map.v4
-rw-r--r--techlibs/xilinx/xc6s_brams_map.v6
-rw-r--r--tests/various/.gitignore2
-rw-r--r--tests/various/gzip_verilog.v.gzbin0 -> 82 bytes
-rw-r--r--tests/various/gzip_verilog.ys2
-rw-r--r--tests/various/write_gzip.ys16
56 files changed, 763 insertions, 172 deletions
diff --git a/.travis.yml b/.travis.yml
index 957735f1d..4102f05fe 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -36,6 +36,7 @@ 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"
@@ -64,6 +65,7 @@ matrix:
- libboost-system-dev
- libboost-python-dev
- libboost-filesystem-dev
+ - zlib1g-dev
env:
- MATRIX_EVAL="CONFIG=gcc && CC=gcc-6 && CXX=g++-6"
@@ -92,6 +94,7 @@ matrix:
- libboost-system-dev
- libboost-python-dev
- libboost-filesystem-dev
+ - zlib1g-dev
env:
- MATRIX_EVAL="CONFIG=gcc && CC=gcc-7 && CXX=g++-7"
@@ -121,6 +124,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"
@@ -149,6 +153,7 @@ 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"
diff --git a/CHANGELOG b/CHANGELOG
index 44d83c1bf..661581433 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -14,7 +14,9 @@ Yosys 0.9 .. Yosys 0.9-dev
- Added "synth -abc9" (experimental)
- Added "script -scriptwire
- "synth_xilinx" to now infer wide multiplexers (-widemux <min> to enable)
-
+ - Added automatic gzip decompression for frontends
+ - Added $_NMUX_ cell type
+ - Added automatic gzip compression (based on filename extension) for backends
Yosys 0.8 .. Yosys 0.8-dev
--------------------------
diff --git a/Makefile b/Makefile
index d33f27b63..a697e9844 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
@@ -122,7 +123,7 @@ OBJS = kernel/version_$(GIT_REV).o
# is just a symlink to your actual ABC working directory, as 'make mrproper'
# will remove the 'abc' directory and you do not want to accidentally
# delete your work on ABC..
-ABCREV = 62487de
+ABCREV = 5776ad0
ABCPULL = 1
ABCURL ?= https://github.com/berkeley-abc/abc
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1
@@ -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)
@@ -862,9 +870,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 <command>`` 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..a3a753912 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
@@ -610,15 +610,15 @@ 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;
@@ -772,7 +772,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..f32b0f533 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")));
diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc
index a507b120b..7bacce2af 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;
}
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..ddd680782 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)))");
diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc
index d75456c1b..e9586fae0 100644
--- a/backends/smv/smv.cc
+++ b/backends/smv/smv.cc
@@ -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..776f4eacb 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -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"));
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..bb97c5703 100644
--- a/frontends/aiger/aigerparse.cc
+++ b/frontends/aiger/aigerparse.cc
@@ -301,7 +301,11 @@ static uint32_t parse_xaiger_literal(std::istream &f)
uint32_t l;
f.read(reinterpret_cast<char*>(&l), sizeof(l));
if (f.gcount() != sizeof(l))
+#if defined(_WIN32) && defined(__MINGW32__)
+ log_error("Offset %I64d: unable to read literal!\n", static_cast<int64_t>(f.tellg()));
+#else
log_error("Offset %" PRId64 ": unable to read literal!\n", static_cast<int64_t>(f.tellg()));
+#endif
return from_big_endian(l);
}
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 3d066af53..943466ee3 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -1551,7 +1551,9 @@ RTLIL::Module *AstModule::clone() const
new_mod->nomeminit = 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/verific/verific.cc b/frontends/verific/verific.cc
index 2bf99e58e..06d58a44a 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -2484,7 +2484,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 +2498,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/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/kernel/cellaigs.cc b/kernel/cellaigs.cc
index 26c625f89..fbc6d045e 100644
--- a/kernel/cellaigs.cc
+++ b/kernel/cellaigs.cc
@@ -325,6 +325,8 @@ Aig::Aig(Cell *cell)
int A = mk.inport("\\A", i);
int B = mk.inport("\\B", i);
int Y = mk.mux_gate(A, B, S);
+ if (cell->type == "$_NMUX_")
+ Y = mk.not_gate(Y);
mk.outport(Y, "\\Y", i);
}
goto optimize;
diff --git a/kernel/celltypes.h b/kernel/celltypes.h
index 758661c02..d2594bc46 100644
--- a/kernel/celltypes.h
+++ b/kernel/celltypes.h
@@ -193,6 +193,7 @@ struct CellTypes
setup_type("$_ANDNOT_", {A, B}, {Y}, true);
setup_type("$_ORNOT_", {A, B}, {Y}, true);
setup_type("$_MUX_", {A, B, S}, {Y}, true);
+ setup_type("$_NMUX_", {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);
diff --git a/kernel/consteval.h b/kernel/consteval.h
index 154373a8d..f70dfa0fb 100644
--- a/kernel/consteval.h
+++ b/kernel/consteval.h
@@ -145,7 +145,7 @@ struct ConstEval
if (cell->hasPort("\\B"))
sig_b = cell->getPort("\\B");
- if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_")
+ if (cell->type.in("$mux", "$pmux", "$_MUX_", "$_NMUX_"))
{
std::vector<RTLIL::SigSpec> 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 == "$_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)
diff --git a/kernel/cost.h b/kernel/cost.h
index 41a09eb63..e8e077ff5 100644
--- a/kernel/cost.h
+++ b/kernel/cost.h
@@ -24,10 +24,10 @@
YOSYS_NAMESPACE_BEGIN
-int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr);
+int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr, bool cmos_cost = false);
inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> &parameters = dict<RTLIL::IdString, RTLIL::Const>(),
- RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr)
+ RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr, bool cmos_cost = false)
{
static dict<RTLIL::IdString, int> gate_cost = {
{ "$_BUF_", 1 },
@@ -44,9 +44,33 @@ inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL
{ "$_OAI3_", 6 },
{ "$_AOI4_", 8 },
{ "$_OAI4_", 8 },
- { "$_MUX_", 4 }
+ { "$_MUX_", 4 },
+ { "$_NMUX_", 4 }
};
+ // match costs in "stat -tech cmos"
+ static dict<RTLIL::IdString, int> cmos_gate_cost = {
+ { "$_BUF_", 1 },
+ { "$_NOT_", 2 },
+ { "$_AND_", 6 },
+ { "$_NAND_", 4 },
+ { "$_OR_", 6 },
+ { "$_NOR_", 4 },
+ { "$_ANDNOT_", 6 },
+ { "$_ORNOT_", 6 },
+ { "$_XOR_", 12 },
+ { "$_XNOR_", 12 },
+ { "$_AOI3_", 6 },
+ { "$_OAI3_", 6 },
+ { "$_AOI4_", 8 },
+ { "$_OAI4_", 8 },
+ { "$_MUX_", 12 },
+ { "$_NMUX_", 10 }
+ };
+
+ if (cmos_cost && cmos_gate_cost.count(type))
+ return cmos_gate_cost.at(type);
+
if (gate_cost.count(type))
return gate_cost.at(type);
@@ -76,9 +100,9 @@ inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL
return 1;
}
-inline int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache)
+inline int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache, bool cmos_cost)
{
- return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache);
+ return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache, cmos_cost);
}
YOSYS_NAMESPACE_END
diff --git a/kernel/register.cc b/kernel/register.cc
index 26da96b95..4f60338e9 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -25,6 +25,65 @@
#include <stdio.h>
#include <errno.h>
+#ifdef YOSYS_ENABLE_ZLIB
+#include <zlib.h>
+
+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<void *>(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<const void *>(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
@@ -436,6 +495,28 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
delete ff;
else
f = ff;
+ if (f != NULL) {
+ // Check for gzip magic
+ unsigned char magic[3];
+ int n = readsome(*ff, reinterpret_cast<char*>(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));
@@ -546,14 +627,28 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st
filename = arg;
rewrite_filename(filename);
- 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));
+ if (filename.size() > 3 && filename.substr(filename.size()-3) == ".gz") {
+#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)
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 85b013bdc..f2c81db72 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -1249,6 +1249,7 @@ namespace {
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 == "$_NMUX_") { 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; }
@@ -1976,6 +1977,7 @@ 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(NmuxGate, "$_NMUX_", 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)
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index f9412e776..633cb51d6 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -420,8 +420,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<typename T>
- 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<RTLIL::IdString, T>::iterator it;
dict<RTLIL::IdString, T> *list_p;
int *refcount_p;
@@ -474,13 +478,25 @@ namespace RTLIL
return it != other.it;
}
- inline void operator++() {
+
+ inline bool operator==(const RTLIL::ObjIterator<T> &other) const {
+ return !(*this != other);
+ }
+
+ inline ObjIterator<T>& operator++() {
log_assert(list_p != nullptr);
if (++it == list_p->end()) {
(*refcount_p)--;
list_p = nullptr;
refcount_p = nullptr;
}
+ return *this;
+ }
+
+ inline const ObjIterator<T> operator++(int) {
+ ObjIterator<T> result(*this);
+ ++(*this);
+ return result;
}
};
@@ -1139,6 +1155,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 = "");
@@ -1214,6 +1231,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 = "");
diff --git a/kernel/satgen.h b/kernel/satgen.h
index 210cca3f3..e9f3ecd44 100644
--- a/kernel/satgen.h
+++ b/kernel/satgen.h
@@ -475,7 +475,7 @@ struct SatGen
return true;
}
- if (cell->type == "$_MUX_" || cell->type == "$mux")
+ if (cell->type == "$_MUX_" || cell->type == "$mux" || cell->type == "$_NMUX_")
{
std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
@@ -483,7 +483,10 @@ struct SatGen
std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
std::vector<int> 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 == "$_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)
{
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index a42a7c0b8..191b6d5c7 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -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.substr(filename_trim.size()-3) == ".gz")
+ filename_trim.erase(filename_trim.size()-3);
+ if (filename_trim.size() > 2 && filename_trim.substr(filename_trim.size()-2) == ".v")
command = "verilog";
- else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv")
+ else if (filename_trim.size() > 2 && filename_trim.substr(filename_trim.size()-3) == ".sv")
command = "verilog -sv";
- else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".vhd")
+ else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-4) == ".vhd")
command = "vhdl";
- else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".blif")
+ else if (filename_trim.size() > 4 && filename_trim.substr(filename_trim.size()-5) == ".blif")
command = "blif";
- else if (filename.size() > 5 && filename.substr(filename.size()-6) == ".eblif")
+ else if (filename_trim.size() > 5 && filename_trim.substr(filename_trim.size()-6) == ".eblif")
command = "blif";
- else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".json")
+ else if (filename_trim.size() > 4 && filename_trim.substr(filename_trim.size()-5) == ".json")
command = "json";
- else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il")
+ else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-3) == ".il")
command = "ilang";
- else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys")
+ else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-3) == ".ys")
command = "script";
- else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".tcl")
+ else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-4) == ".tcl")
command = "tcl";
else if (filename == "-")
command = "script";
diff --git a/kernel/yosys.h b/kernel/yosys.h
index c7b671724..09e8139bb 100644
--- a/kernel/yosys.h
+++ b/kernel/yosys.h
@@ -52,6 +52,7 @@
#include <stdexcept>
#include <memory>
#include <cmath>
+#include <cstddef>
#include <sstream>
#include <fstream>
@@ -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
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 <windows.h>
#include <tchar.h>
#include <fcntl.h>
+#include <unistd.h>
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/stat.cc b/passes/cmds/stat.cc
index 27c5fb60c..89920ed55 100644
--- a/passes/cmds/stat.cc
+++ b/passes/cmds/stat.cc
@@ -223,6 +223,37 @@ 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;
+
+ for (auto it : num_cells_by_type) {
+ auto ctype = it.first;
+ auto cnum = it.second;
+
+ if (ctype == "$_NOT_")
+ tran_cnt += 2*cnum;
+ else if (ctype.in("$_NAND_", "$_NOR_"))
+ tran_cnt += 4*cnum;
+ else if (ctype.in("$_AOI3_", "$_OAI3_"))
+ tran_cnt += 6*cnum;
+ else if (ctype.in("$_AOI4_", "$_OAI4_"))
+ tran_cnt += 8*cnum;
+ else if (ctype.in("$_NMUX_"))
+ tran_cnt += 10*cnum;
+ else if (ctype.in("$_MUX_", "$_XOR_", "$_XNOR_"))
+ tran_cnt += 12*cnum;
+ else if (ctype.in("$_DFF_P_", "$_DFF_N_"))
+ tran_cnt += 16*cnum;
+ else
+ tran_cnt_exact = false;
+ }
+
+ log("\n");
+ log(" Estimated number of transistors: %10d%s\n", tran_cnt, tran_cnt_exact ? "" : "+");
+ }
}
};
@@ -286,7 +317,7 @@ struct StatPass : public Pass {
log("\n");
log(" -tech <technology>\n");
log(" print area estemate for the specified technology. Currently supported\n");
- log(" values for <technology>: xilinx\n");
+ log(" values for <technology>: xilinx, cmos\n");
log("\n");
log(" -width\n");
log(" annotate internal cell types with their word width.\n");
@@ -330,7 +361,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/opt/opt_lut.cc b/passes/opt/opt_lut.cc
index 182f63d99..587ef878a 100644
--- a/passes/opt/opt_lut.cc
+++ b/passes/opt/opt_lut.cc
@@ -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])
@@ -351,14 +351,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;
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; i<module->ports.size(); i++)
diff --git a/passes/proc/proc_prune.cc b/passes/proc/proc_prune.cc
index 9e00b0a8a..b47ee79c2 100644
--- a/passes/proc/proc_prune.cc
+++ b/passes/proc/proc_prune.cc
@@ -82,14 +82,23 @@ struct PruneWorker
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);
+ module->connect(conn);
remove.insert(*it);
}
}
diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc
index 65c7d1bb8..41a05c619 100644
--- a/passes/techmap/abc.cc
+++ b/passes/techmap/abc.cc
@@ -49,6 +49,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <cctype>
#include <cerrno>
#include <sstream>
#include <climits>
@@ -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<gate_t> signal_list;
std::map<RTLIL::SigBit, int> signal_map;
std::map<RTLIL::SigBit, RTLIL::State> signal_init;
pool<std::string> enabled_gates;
-bool recover_init;
+bool recover_init, cmos_cost;
bool clk_polarity, en_polarity;
RTLIL::SigSpec clk_sig, en_sig;
@@ -257,7 +259,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
return;
}
- if (cell->type == "$_MUX_")
+ if (cell->type.in("$_MUX_", "$_NMUX_"))
{
RTLIL::SigSpec sig_a = cell->getPort("\\A");
RTLIL::SigSpec sig_b = cell->getPort("\\B");
@@ -273,7 +275,7 @@ 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 == "$_MUX_" ? G(MUX) : G(NMUX), mapped_a, mapped_b, mapped_s);
module->remove(cell);
return;
@@ -885,6 +887,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 +931,52 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
{
log_header(design, "Executing ABC.\n");
+ auto cell_cost = [](IdString cell_type) {
+ return get_cell_cost(cell_type, dict<RTLIL::IdString, RTLIL::Const>(), nullptr, nullptr, cmos_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_"));
+ fprintf(f, "GATE BUF %d Y=A; PIN * NONINV 1 999 1 0 1 0\n", cell_cost("$_BUF_"));
+ fprintf(f, "GATE NOT %d Y=!A; PIN * INV 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE AND %d Y=A*B; PIN * NONINV 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE NAND %d Y=!(A*B); PIN * INV 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE OR %d Y=A+B; PIN * NONINV 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE NOR %d Y=!(A+B); PIN * INV 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE XOR %d Y=(A*!B)+(!A*B); PIN * UNKNOWN 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE XNOR %d Y=(A*B)+(!A*!B); PIN * UNKNOWN 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE ANDNOT %d Y=A*!B; PIN * UNKNOWN 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE ORNOT %d Y=A+!B; PIN * UNKNOWN 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE AOI3 %d Y=!((A*B)+C); PIN * INV 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE OAI3 %d Y=!((A+B)*C); PIN * INV 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE AOI4 %d Y=!((A*B)+(C*D)); PIN * INV 1 999 1 0 1 0\n", 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_"));
+ fprintf(f, "GATE OAI4 %d Y=!((A+B)*(C+D)); PIN * INV 1 999 1 0 1 0\n", 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 MUX %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost("$_MUX_"));
+ if (enabled_gates.empty() || 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("$_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("$_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("$_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("$_MUX_"));
fclose(f);
if (!lut_costs.empty()) {
@@ -1065,8 +1077,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
design->select(module, cell);
continue;
}
- if (c->type == "\\MUX") {
- RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX_");
+ if (c->type == "\\MUX" || c->type == "\\NMUX") {
+ 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)]));
@@ -1406,11 +1418,12 @@ struct AbcPass : public Pass {
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(" 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");
@@ -1488,6 +1501,7 @@ struct AbcPass : public Pass {
map_mux8 = false;
map_mux16 = false;
enabled_gates.clear();
+ cmos_cost = false;
#ifdef _WIN32
#ifndef ABCEXTERNAL
@@ -1628,11 +1642,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 +1658,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 +1668,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");
diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc
index 591bc43dd..b541ceb6b 100644
--- a/passes/techmap/extract_fa.cc
+++ b/passes/techmap/extract_fa.cc
@@ -86,7 +86,7 @@ struct ExtractFaWorker
for (auto cell : module->selected_cells())
{
if (cell->type.in( "$_BUF_", "$_NOT_", "$_AND_", "$_NAND_", "$_OR_", "$_NOR_",
- "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_", "$_MUX_",
+ "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_", "$_MUX_", "$_NMUX_",
"$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_"))
{
SigBit y = sigmap(SigBit(cell->getPort("\\Y")));
diff --git a/passes/techmap/flowmap.cc b/passes/techmap/flowmap.cc
index f5892a60e..96d0df5f8 100644
--- a/passes/techmap/flowmap.cc
+++ b/passes/techmap/flowmap.cc
@@ -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<RTLIL::SigBit, pool<RTLIL::SigBit>> &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");
@@ -1419,9 +1419,9 @@ struct FlowmapWorker
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)
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/common/simcells.v b/techlibs/common/simcells.v
index 289673e82..64720e598 100644
--- a/techlibs/common/simcells.v
+++ b/techlibs/common/simcells.v
@@ -230,6 +230,25 @@ 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)
//-
//- A 4-input MUX gate.
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/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/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..7a3d2c71a 100644
--- a/techlibs/intel/Makefile.inc
+++ b/techlibs/intel/Makefile.inc
@@ -3,8 +3,8 @@ 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/common,techlibs/intel/common/brams_m9k.txt))
+$(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_map_m9k.v))
$(eval $(call add_share_file,share/intel/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))
diff --git a/techlibs/intel/common/brams.txt b/techlibs/intel/common/brams_m9k.txt
index 3bf21afc9..3bf21afc9 100644
--- a/techlibs/intel/common/brams.txt
+++ b/techlibs/intel/common/brams_m9k.txt
diff --git a/techlibs/intel/common/brams_map.v b/techlibs/intel/common/brams_map_m9k.v
index d0f07c1de..d0f07c1de 100644
--- a/techlibs/intel/common/brams_map.v
+++ b/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<std::string> 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/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/various/.gitignore b/tests/various/.gitignore
index 7b3e8c68e..31078b298 100644
--- a/tests/various/.gitignore
+++ b/tests/various/.gitignore
@@ -1,2 +1,4 @@
/*.log
/*.out
+/write_gzip.v
+/write_gzip.v.gz
diff --git a/tests/various/gzip_verilog.v.gz b/tests/various/gzip_verilog.v.gz
new file mode 100644
index 000000000..c52a95358
--- /dev/null
+++ b/tests/various/gzip_verilog.v.gz
Binary files 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/write_gzip.ys b/tests/various/write_gzip.ys
new file mode 100644
index 000000000..030ec318e
--- /dev/null
+++ b/tests/various/write_gzip.ys
@@ -0,0 +1,16 @@
+read -vlog2k <<EOT
+module top(input a, output y);
+assign y = !a;
+endmodule
+EOT
+
+prep -top top
+write_verilog write_gzip.v.gz
+design -reset
+
+! rm -f write_gzip.v
+! gunzip write_gzip.v.gz
+read -vlog2k write_gzip.v
+! rm -f write_gzip.v
+hierarchy -top top
+select -assert-any top