mirror of https://github.com/YosysHQ/yosys.git
Merge remote-tracking branch 'origin/master' into eddie/wreduce_add
This commit is contained in:
commit
26cb3e7afc
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
--------------------------
|
||||
|
|
16
Makefile
16
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
|
||||
|
|
73
README.md
73
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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")));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) +
|
||||
|
|
|
@ -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)))");
|
||||
|
|
|
@ -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")),
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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
|
|
@ -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 ;
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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> ¶meters = 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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 = "");
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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! */
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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")));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
/*.log
|
||||
/*.out
|
||||
/write_gzip.v
|
||||
/write_gzip.v.gz
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
read_verilog gzip_verilog.v.gz
|
||||
select -assert-any top
|
|
@ -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
|
Loading…
Reference in New Issue