aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Brewfile1
-rw-r--r--CHANGELOG2
-rw-r--r--COPYING4
-rw-r--r--Makefile20
-rw-r--r--README.md41
-rw-r--r--backends/aiger/xaiger.cc92
-rw-r--r--backends/edif/edif.cc43
-rw-r--r--backends/firrtl/firrtl.cc1
-rw-r--r--backends/json/json.cc6
-rw-r--r--backends/smt2/smt2.cc20
-rw-r--r--backends/smt2/smtbmc.py14
-rw-r--r--backends/smt2/smtio.py16
-rw-r--r--backends/verilog/verilog_backend.cc13
-rw-r--r--examples/smtbmc/Makefile11
-rw-r--r--examples/smtbmc/demo9.v13
-rw-r--r--frontends/aiger/aigerparse.cc2
-rw-r--r--frontends/ast/ast.cc107
-rw-r--r--frontends/ast/ast.h18
-rw-r--r--frontends/ast/genrtlil.cc258
-rw-r--r--frontends/ast/simplify.cc497
-rw-r--r--frontends/rpc/Makefile.inc3
-rw-r--r--frontends/verilog/Makefile.inc2
-rw-r--r--frontends/verilog/verilog_frontend.cc22
-rw-r--r--frontends/verilog/verilog_frontend.h7
-rw-r--r--frontends/verilog/verilog_lexer.l131
-rw-r--r--frontends/verilog/verilog_parser.y481
-rw-r--r--kernel/driver.cc21
-rw-r--r--kernel/log.cc84
-rw-r--r--kernel/log.h41
-rw-r--r--kernel/register.cc12
-rw-r--r--kernel/register.h1
-rw-r--r--kernel/rtlil.cc10
-rw-r--r--kernel/timinginfo.h179
-rw-r--r--kernel/yosys.cc6
-rw-r--r--manual/CHAPTER_Overview.tex7
-rw-r--r--manual/command-reference-manual.tex2
-rw-r--r--misc/py_wrap_generator.py40
-rw-r--r--passes/cmds/Makefile.inc2
-rw-r--r--passes/cmds/add.cc99
-rw-r--r--passes/cmds/exec.cc203
-rw-r--r--passes/cmds/logger.cc183
-rw-r--r--passes/cmds/select.cc376
-rw-r--r--passes/cmds/show.cc19
-rw-r--r--passes/fsm/fsm_extract.cc6
-rw-r--r--passes/hierarchy/submod.cc136
-rw-r--r--passes/opt/opt_clean.cc18
-rw-r--r--passes/sat/miter.cc116
-rw-r--r--passes/techmap/abc.cc5
-rw-r--r--passes/techmap/abc9.cc57
-rw-r--r--passes/techmap/abc9_exe.cc4
-rw-r--r--passes/techmap/abc9_ops.cc550
-rw-r--r--passes/techmap/deminout.cc3
-rw-r--r--passes/techmap/extract_counter.cc451
-rw-r--r--passes/techmap/iopadmap.cc101
-rw-r--r--passes/techmap/techmap.cc2
-rw-r--r--[-rwxr-xr-x]techlibs/achronix/Makefile.inc0
-rw-r--r--[-rwxr-xr-x]techlibs/achronix/speedster22i/cells_arith.v0
-rw-r--r--[-rwxr-xr-x]techlibs/achronix/speedster22i/cells_map.v0
-rw-r--r--[-rwxr-xr-x]techlibs/achronix/speedster22i/cells_sim.v0
-rw-r--r--[-rwxr-xr-x]techlibs/achronix/synth_achronix.cc0
-rw-r--r--techlibs/common/Makefile.inc1
-rw-r--r--techlibs/common/abc9_model.v10
-rw-r--r--techlibs/common/gate2lut.v2
-rw-r--r--techlibs/common/synth.cc19
-rw-r--r--techlibs/common/techmap.v14
-rw-r--r--techlibs/coolrunner2/Makefile.inc2
-rw-r--r--techlibs/coolrunner2/cells_counter_map.v161
-rw-r--r--techlibs/coolrunner2/coolrunner2_fixup.cc520
-rw-r--r--techlibs/coolrunner2/coolrunner2_sop.cc172
-rw-r--r--techlibs/coolrunner2/synth_coolrunner2.cc5
-rw-r--r--techlibs/ecp5/Makefile.inc3
-rw-r--r--techlibs/ecp5/abc9_5g.box36
-rw-r--r--techlibs/ecp5/abc9_5g.lut25
-rw-r--r--techlibs/ecp5/abc9_5g_nowide.lut12
-rw-r--r--techlibs/ecp5/abc9_model.v9
-rw-r--r--techlibs/ecp5/brams_map.v2
-rw-r--r--techlibs/ecp5/cells_sim.v95
-rw-r--r--techlibs/ecp5/synth_ecp5.cc8
-rw-r--r--techlibs/gowin/synth_gowin.cc2
-rw-r--r--techlibs/ice40/Makefile.inc6
-rw-r--r--techlibs/ice40/abc9_hx.box17
-rw-r--r--techlibs/ice40/abc9_hx.lut6
-rw-r--r--techlibs/ice40/abc9_lp.box17
-rw-r--r--techlibs/ice40/abc9_lp.lut6
-rw-r--r--techlibs/ice40/abc9_model.v59
-rw-r--r--techlibs/ice40/abc9_u.box17
-rw-r--r--techlibs/ice40/abc9_u.lut6
-rw-r--r--techlibs/ice40/cells_sim.v1411
-rw-r--r--techlibs/ice40/synth_ice40.cc47
-rw-r--r--techlibs/xilinx/Makefile.inc10
-rw-r--r--techlibs/xilinx/abc9_map.v232
-rw-r--r--techlibs/xilinx/abc9_model.v175
-rw-r--r--techlibs/xilinx/abc9_unmap.v17
-rw-r--r--techlibs/xilinx/abc9_xc7.box384
-rw-r--r--techlibs/xilinx/abc9_xc7.lut15
-rw-r--r--techlibs/xilinx/abc9_xc7_nowide.lut10
-rw-r--r--techlibs/xilinx/arith_map.v205
-rw-r--r--techlibs/xilinx/cells_sim.v1522
-rw-r--r--techlibs/xilinx/cells_xtra.py80
-rw-r--r--techlibs/xilinx/cells_xtra.v380
-rw-r--r--techlibs/xilinx/lut4_lutrams.txt19
-rw-r--r--techlibs/xilinx/lut6_lutrams.txt (renamed from techlibs/xilinx/lutrams.txt)24
-rw-r--r--techlibs/xilinx/lut_map.v54
-rw-r--r--techlibs/xilinx/synth_xilinx.cc128
-rw-r--r--techlibs/xilinx/xc2v_brams.txt31
-rw-r--r--techlibs/xilinx/xc2v_brams_map.v266
-rw-r--r--techlibs/xilinx/xc3sa_brams.txt51
-rw-r--r--techlibs/xilinx/xc3sda_brams.txt33
-rw-r--r--techlibs/xilinx/xc6s_brams.txt1
-rw-r--r--techlibs/xilinx/xc6s_brams_map.v3
-rw-r--r--techlibs/xilinx/xc7_brams_map.v2
-rw-r--r--techlibs/xilinx/xc7_xcu_brams.txt2
-rw-r--r--techlibs/xilinx/xcu_brams_map.v2
-rw-r--r--tests/aiger/.gitignore2
-rw-r--r--tests/arch/ecp5/bug1630.ys2
-rw-r--r--tests/arch/ice40/ice40_wrapcarry.ys4
-rwxr-xr-xtests/arch/run-test.sh17
-rw-r--r--tests/arch/xilinx/add_sub.ys14
-rw-r--r--tests/arch/xilinx/bug1480.ys (renamed from tests/various/bug1480.ys)0
-rw-r--r--tests/arch/xilinx/fsm.ys19
-rw-r--r--tests/arch/xilinx/lutram.ys20
-rw-r--r--tests/arch/xilinx/mux_lut4.ys51
-rw-r--r--tests/arch/xilinx/tribuf.sh6
-rw-r--r--tests/memfile/.gitignore1
-rw-r--r--tests/memfile/content1.dat64
-rw-r--r--tests/memfile/memory.v23
-rwxr-xr-xtests/memfile/run-test.sh49
-rw-r--r--tests/rpc/frontend.py8
-rwxr-xr-xtests/rpc/run-test.sh1
-rw-r--r--tests/rpc/unix.ys6
-rw-r--r--tests/select/no_warn_assert.ys2
-rw-r--r--tests/select/no_warn_prefixed_arg_memb.ys5
-rw-r--r--tests/select/no_warn_prefixed_empty_select_arg.ys3
-rwxr-xr-xtests/select/run-test.sh6
-rw-r--r--tests/select/warn_empty_select_arg.ys3
-rw-r--r--tests/simple/partsel.v4
-rw-r--r--tests/simple_abc9/abc.box2
-rw-r--r--tests/simple_abc9/abc9.v7
-rwxr-xr-xtests/simple_abc9/run-test.sh4
-rw-r--r--tests/svtypes/enum_simple.sv48
-rw-r--r--tests/svtypes/enum_simple.ys5
-rw-r--r--tests/svtypes/typedef_memory.sv2
-rw-r--r--tests/svtypes/typedef_memory_2.sv2
-rw-r--r--tests/svtypes/typedef_package.sv5
-rw-r--r--tests/svtypes/typedef_param.sv10
-rw-r--r--tests/svtypes/typedef_scopes.sv20
-rw-r--r--tests/svtypes/typedef_simple.sv10
-rw-r--r--tests/techmap/iopadmap.ys60
-rw-r--r--tests/techmap/techmap_replace.ys18
-rw-r--r--tests/various/bug1614.ys5
-rw-r--r--tests/various/bug1710.ys30
-rw-r--r--tests/various/bug1745.ys8
-rw-r--r--tests/various/bug1781.ys33
-rw-r--r--tests/various/constcomment.ys16
-rw-r--r--tests/various/deminout_unused.ys14
-rw-r--r--tests/various/exec.ys6
-rw-r--r--tests/various/ice40_mince_abc9.ys17
-rw-r--r--tests/various/logger_error.ys6
-rw-r--r--tests/various/logger_nowarning.ys6
-rw-r--r--tests/various/logger_warn.ys6
-rw-r--r--tests/various/logger_warning.ys6
-rw-r--r--tests/various/mem2reg.ys4
-rw-r--r--tests/various/pmux2shiftx.v2
-rw-r--r--tests/various/specify.v29
-rw-r--r--tests/various/specify.ys21
-rw-r--r--tests/various/src.ys8
-rw-r--r--tests/various/submod.ys124
168 files changed, 8601 insertions, 3139 deletions
diff --git a/.gitignore b/.gitignore
index 76f53cd06..0460c7c13 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@ __pycache__
/yosys
/yosys.exe
/yosys.js
+/yosys.wasm
/yosys-abc
/yosys-abc.exe
/yosys-config
diff --git a/Brewfile b/Brewfile
index 8465d86f9..2a985f09e 100644
--- a/Brewfile
+++ b/Brewfile
@@ -8,3 +8,4 @@ brew "pkg-config"
brew "python3"
brew "tcl-tk"
brew "xdot"
+brew "bash"
diff --git a/CHANGELOG b/CHANGELOG
index ca7196091..18f82bdd1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -60,7 +60,9 @@ Yosys 0.9 .. Yosys 0.9-dev
- Added "scratchpad" pass
- Added "abc9 -dff"
- Added "synth_xilinx -dff"
+ - Improved support of $readmem[hb] Memory Content File inclusion
- Added "opt_lut_ins" pass
+ - Added "logger" pass
Yosys 0.8 .. Yosys 0.9
----------------------
diff --git a/COPYING b/COPYING
index 0839088c3..7cd2464cd 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,6 @@
-Copyright (C) 2012 - 2019 Clifford Wolf <clifford@clifford.at>
+ISC License
+
+Copyright (C) 2012 - 2020 Claire Wolf <claire@symbioticeda.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
diff --git a/Makefile b/Makefile
index 43c4d0890..3c89fed20 100644
--- a/Makefile
+++ b/Makefile
@@ -128,7 +128,7 @@ bumpversion:
# is just a symlink to your actual ABC working directory, as 'make mrproper'
# will remove the 'abc' directory and you do not want to accidentally
# delete your work on ABC..
-ABCREV = 71f2b40
+ABCREV = ed90ce2
ABCPULL = 1
ABCURL ?= https://github.com/berkeley-abc/abc
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1
@@ -237,7 +237,8 @@ ABCMKARGS += ARCHFLAGS="-DABC_USE_STDINT_H -DABC_MEMALIGN=8"
EMCCFLAGS := -Os -Wno-warn-absolute-paths
EMCCFLAGS += --memory-init-file 0 --embed-file share -s NO_EXIT_RUNTIME=1
EMCCFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg']"
-EMCCFLAGS += -s TOTAL_MEMORY=128*1024*1024
+EMCCFLAGS += -s TOTAL_MEMORY=134217728
+EMCCFLAGS += -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
# https://github.com/kripken/emscripten/blob/master/src/settings.js
CXXFLAGS += $(EMCCFLAGS)
LDFLAGS += $(EMCCFLAGS)
@@ -256,10 +257,10 @@ viz.js:
wget -O viz.js.part https://github.com/mdaines/viz.js/releases/download/0.0.3/viz.js
mv viz.js.part viz.js
-yosysjs-$(YOSYS_VER).zip: yosys.js viz.js misc/yosysjs/*
+yosysjs-$(YOSYS_VER).zip: yosys.js yosys.wasm viz.js misc/yosysjs/*
rm -rf yosysjs-$(YOSYS_VER) yosysjs-$(YOSYS_VER).zip
mkdir -p yosysjs-$(YOSYS_VER)
- cp viz.js misc/yosysjs/* yosys.js yosysjs-$(YOSYS_VER)/
+ cp viz.js misc/yosysjs/* yosys.js yosys.wasm yosysjs-$(YOSYS_VER)/
zip -r yosysjs-$(YOSYS_VER).zip yosysjs-$(YOSYS_VER)
yosys.html: misc/yosys.html
@@ -668,7 +669,8 @@ ifneq ($(ABCREV),default)
$(Q) if ( cd abc 2> /dev/null && ! git diff-index --quiet HEAD; ); then \
echo 'REEBE: NOP pbagnvaf ybpny zbqvsvpngvbaf! Frg NOPERI=qrsnhyg va Lbflf Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; false; \
fi
- $(Q) if test "`cd abc 2> /dev/null && git rev-parse --short HEAD`" != "$(ABCREV)"; then \
+# set a variable so the test fails if git fails to run - when comparing outputs directly, empty string would match empty string
+ $(Q) if ! (cd abc && rev="`git rev-parse $(ABCREV)`" && test "`git rev-parse HEAD`" == "$$rev"); then \
test $(ABCPULL) -ne 0 || { echo 'REEBE: NOP abg hc gb qngr naq NOPCHYY frg gb 0 va Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; exit 1; }; \
echo "Pulling ABC from $(ABCURL):"; set -x; \
test -d abc || git clone $(ABCURL) abc; \
@@ -714,6 +716,7 @@ test: $(TARGETS) $(EXTRA_TARGETS)
+cd tests/memories && bash run-test.sh $(ABCOPT) $(SEEDOPT)
+cd tests/bram && bash run-test.sh $(SEEDOPT)
+cd tests/various && bash run-test.sh
+ +cd tests/select && bash run-test.sh
+cd tests/sat && bash run-test.sh
+cd tests/svinterfaces && bash run-test.sh $(SEEDOPT)
+cd tests/svtypes && bash run-test.sh $(SEEDOPT)
@@ -728,6 +731,7 @@ test: $(TARGETS) $(EXTRA_TARGETS)
+cd tests/arch/anlogic && bash run-test.sh $(SEEDOPT)
+cd tests/arch/gowin && bash run-test.sh $(SEEDOPT)
+cd tests/rpc && bash run-test.sh
+ +cd tests/memfile && bash run-test.sh
@echo ""
@echo " Passed \"make test\"."
@echo ""
@@ -764,7 +768,7 @@ clean-unit-test:
install: $(TARGETS) $(EXTRA_TARGETS)
$(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR)
- $(INSTALL_SUDO) cp $(TARGETS) $(DESTDIR)$(BINDIR)
+ $(INSTALL_SUDO) cp $(filter-out libyosys.so,$(TARGETS)) $(DESTDIR)$(BINDIR)
ifneq ($(filter yosys,$(TARGETS)),)
$(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(BINDIR)/yosys
endif
@@ -894,6 +898,7 @@ config-emcc: clean
echo 'ENABLE_ABC := 0' >> Makefile.conf
echo 'ENABLE_PLUGINS := 0' >> Makefile.conf
echo 'ENABLE_READLINE := 0' >> Makefile.conf
+ echo 'ENABLE_ZLIB := 0' >> Makefile.conf
config-mxe: clean
echo 'CONFIG := mxe' > Makefile.conf
@@ -928,6 +933,9 @@ echo-yosys-ver:
echo-git-rev:
@echo "$(GIT_REV)"
+echo-abc-rev:
+ @echo "$(ABCREV)"
+
-include libs/*/*.d
-include frontends/*/*.d
-include passes/*/*.d
diff --git a/README.md b/README.md
index e4301e7bf..d1f7ddf8e 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
```
yosys -- Yosys Open SYnthesis Suite
-Copyright (C) 2012 - 2019 Clifford Wolf <clifford@clifford.at>
+Copyright (C) 2012 - 2020 Claire Wolf <claire@symbioticeda.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -69,7 +69,7 @@ prerequisites for building yosys:
graphviz xdot pkg-config python3 libboost-system-dev \
libboost-python-dev libboost-filesystem-dev zlib1g-dev
-Similarily, on Mac OS X Homebrew can be used to install dependencies:
+Similarily, on Mac OS X Homebrew can be used to install dependencies (from within cloned yosys repository):
$ brew tap Homebrew/bundle && brew bundle
@@ -364,25 +364,19 @@ Verilog Attributes and non-standard features
it as the external-facing pin of an I/O pad, and prevents ``iopadmap``
from inserting another pad cell on it.
-- The module attribute ``abc9_box_id`` specifies a positive integer linking a
- blackbox or whitebox definition to a corresponding entry in a `abc9`
- box-file.
+- The module attribute ``abc9_lut`` is an integer attribute indicating to
+ `abc9` that this module describes a LUT with an area cost of this value, and
+ propagation delays described using `specify` statements.
+
+- The module attribute ``abc9_box`` is a boolean specifying a black/white-box
+ definition, with propagation delays described using `specify` statements, for
+ use by `abc9`.
- The port attribute ``abc9_carry`` marks the carry-in (if an input port) and
carry-out (if output port) ports of a box. This information is necessary for
`abc9` to preserve the integrity of carry-chains. Specifying this attribute
onto a bus port will affect only its most significant bit.
-- The output port attribute ``abc9_arrival`` specifies an integer, or a string
- of space-separated integers to be used as the arrival time of this blackbox
- port. It can be used, for example, to specify the clk-to-Q delay of a flip-
- flop output for consideration during `abc9` techmapping.
-
-- The input port attribute ``abc9_required`` specifies an integer, or a string
- of space-separated integers to be used as the required time of this blackbox
- port. It can be used, for example, to specify the setup-time of a flip-flop
- input for consideration during `abc9` techmapping.
-
- The module attribute ``abc9_flop`` is a boolean marking the module as a
flip-flop. This allows `abc9` to analyse its contents in order to perform
sequential synthesis.
@@ -446,6 +440,17 @@ Verilog Attributes and non-standard features
...
endmodule
+- The ``wiretype`` attribute is added by the verilog parser for wires of a
+ typedef'd type to indicate the type identifier.
+
+- Various ``enum_{width}_{value}`` attributes are added to wires of an
+ enumerated type to give a map of possible enum items to their values.
+
+- The ``enum_base_type`` attribute is added to enum items to indicate which
+ enum they belong to (enums -- anonymous and otherwise -- are
+ automatically named with an auto-incrementing counter). Note that enums
+ are currently not strongly typed.
+
- A limited subset of DPI-C functions is supported. The plugin mechanism
(see ``help plugin``) can be used to load .so files with implementations
of DPI-C routines. As a non-standard extension it is possible to specify
@@ -536,6 +541,12 @@ from SystemVerilog:
SystemVerilog files being read into the same design afterwards.
- typedefs are supported (including inside packages)
+ - type identifiers must currently be enclosed in (parentheses) when declaring
+ signals of that type (this is syntactically incorrect SystemVerilog)
+ - type casts are currently not supported
+
+- enums are supported (including inside packages)
+ - but are currently not strongly typed
- SystemVerilog interfaces (SVIs) are supported. Modports for specifying whether
ports are inputs or outputs are supported.
diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc
index 76b7efbfc..cde6d066a 100644
--- a/backends/aiger/xaiger.cc
+++ b/backends/aiger/xaiger.cc
@@ -47,6 +47,7 @@ inline static uint32_t bswap32(uint32_t x)
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/utils.h"
+#include "kernel/timinginfo.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
@@ -173,20 +174,21 @@ struct XAigerWriter
undriven_bits.insert(bit);
unused_bits.insert(bit);
- bool keep = wire->get_bool_attribute(ID::keep);
- if (wire->port_input || keep)
+ bool scc = wire->attributes.count(ID(abc9_scc));
+ if (wire->port_input || scc)
input_bits.insert(bit);
- if (wire->port_output || keep) {
+ bool keep = wire->get_bool_attribute(ID::keep);
+ if (wire->port_output || keep || scc) {
if (bit != wirebit)
alias_map[wirebit] = bit;
output_bits.insert(wirebit);
}
}
- dict<IdString,dict<IdString,std::vector<int>>> arrivals_cache;
+ TimingInfo timing;
+
for (auto cell : module->cells()) {
- RTLIL::Module* inst_module = module->design->module(cell->type);
if (!cell->has_keep_attr()) {
if (cell->type == "$_NOT_")
{
@@ -222,13 +224,21 @@ struct XAigerWriter
alias_map[Q] = D;
auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell));
log_assert(r.second);
- if (input_bits.erase(Q))
- log_assert(Q.wire->attributes.count(ID::keep));
continue;
}
- if (inst_module) {
- bool abc9_flop = false;
+ if (cell->type.in("$specify2", "$specify3", "$specrule"))
+ continue;
+ }
+
+ RTLIL::Module* inst_module = module->design->module(cell->type);
+ if (inst_module) {
+ IdString derived_type = inst_module->derive(module->design, cell->parameters);
+ inst_module = module->design->module(derived_type);
+ log_assert(inst_module);
+
+ bool abc9_flop = false;
+ if (!cell->has_keep_attr()) {
auto it = cell->attributes.find("\\abc9_box_seq");
if (it != cell->attributes.end()) {
int abc9_box_seq = it->second.as_int();
@@ -241,50 +251,34 @@ struct XAigerWriter
if (!abc9_flop)
continue;
}
+ }
- auto &cell_arrivals = arrivals_cache[cell->type];
- for (const auto &conn : cell->connections()) {
- auto port_wire = inst_module->wire(conn.first);
- if (!port_wire->port_output)
- continue;
-
- auto r = cell_arrivals.insert(conn.first);
- auto &arrivals = r.first->second;
- if (r.second) {
- auto it = port_wire->attributes.find("\\abc9_arrival");
- if (it == port_wire->attributes.end())
- continue;
- if (it->second.flags == 0)
- arrivals.emplace_back(it->second.as_int());
- else
- for (const auto &tok : split_tokens(it->second.decode_string()))
- arrivals.push_back(atoi(tok.c_str()));
- }
+ if (!timing.count(derived_type))
+ timing.setup_module(inst_module);
+ auto &t = timing.at(derived_type).arrival;
+ for (const auto &conn : cell->connections()) {
+ auto port_wire = inst_module->wire(conn.first);
+ if (!port_wire->port_output)
+ continue;
- if (arrivals.empty())
+ for (int i = 0; i < GetSize(conn.second); i++) {
+ auto d = t.at(TimingInfo::NameBit(conn.first,i), 0);
+ if (d == 0)
continue;
- if (GetSize(arrivals) > 1 && GetSize(arrivals) != GetSize(port_wire))
- log_error("%s.%s is %d bits wide but abc9_arrival = %s has %d value(s)!\n", log_id(cell->type), log_id(conn.first),
- GetSize(port_wire), log_signal(it->second), GetSize(arrivals));
-
- auto jt = arrivals.begin();
#ifndef NDEBUG
if (ys_debug(1)) {
- static std::set<std::pair<IdString,IdString>> seen;
- if (seen.emplace(cell->type, conn.first).second) log("%s.%s abc9_arrival = %d\n", log_id(cell->type), log_id(conn.first), *jt);
+ static std::set<std::tuple<IdString,IdString,int>> seen;
+ if (seen.emplace(derived_type, conn.first, i).second) log("%s.%s[%d] abc9_arrival = %d\n",
+ log_id(cell->type), log_id(conn.first), i, d);
}
#endif
- for (auto bit : sigmap(conn.second)) {
- arrival_times[bit] = *jt;
- if (arrivals.size() > 1)
- jt++;
- }
+ arrival_times[conn.second[i]] = d;
}
-
- if (abc9_flop)
- continue;
}
+
+ if (abc9_flop)
+ continue;
}
bool cell_known = inst_module || cell->known();
@@ -383,11 +377,6 @@ struct XAigerWriter
alias_map[O] = b;
ci_bits.emplace_back(b);
undriven_bits.erase(O);
- // If PI and CI, then must be a (* keep *) wire
- if (input_bits.erase(O)) {
- log_assert(output_bits.count(O));
- log_assert(O.wire->get_bool_attribute(ID::keep));
- }
}
}
@@ -472,8 +461,8 @@ struct XAigerWriter
for (const auto &bit : output_bits) {
ordered_outputs[bit] = aig_o++;
int aig;
- // Unlike bit2aig() which checks aig_map first, for
- // inout/keep bits, since aig_map will point to
+ // Unlike bit2aig() which checks aig_map first for
+ // inout/scc bits, since aig_map will point to
// the PI, first attempt to find the NOT/AND driver
// before resorting to an aig_map lookup (which
// could be another PO)
@@ -650,7 +639,7 @@ struct XAigerWriter
log_assert(mergeability > 0);
write_r_buffer(mergeability);
- Const init = cell->attributes.at(ID(abc9_init));
+ Const init = cell->attributes.at(ID(abc9_init), State::Sx);
log_assert(GetSize(init) == 1);
if (init == State::S1)
write_s_buffer(1);
@@ -661,6 +650,7 @@ struct XAigerWriter
write_s_buffer(0);
}
+ // Use arrival time from output of flop box
write_i_buffer(arrival_times.at(d, 0));
//write_o_buffer(0);
}
diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc
index 616b754ce..199560ad0 100644
--- a/backends/edif/edif.cc
+++ b/backends/edif/edif.cc
@@ -246,19 +246,25 @@ struct EdifBackend : public Backend {
else if (!ct.cell_input(cell_it.first, port_it.first))
dir = "OUTPUT";
}
- if (port_it.second == 1)
+ int width = port_it.second;
+ int start = 0;
+ bool upto = false;
+ auto m = design->module(cell_it.first);
+ if (m) {
+ auto w = m->wire(port_it.first);
+ if (w) {
+ width = GetSize(w);
+ start = w->start_offset;
+ upto = w->upto;
+ }
+ }
+ if (width == 1)
*f << stringf(" (port %s (direction %s))\n", EDIF_DEF(port_it.first), dir);
else {
- int b[2] = {port_it.second-1, 0};
- auto m = design->module(cell_it.first);
- if (m) {
- auto w = m->wire(port_it.first);
- if (w) {
- b[w->upto ? 0 : 1] = w->start_offset;
- b[w->upto ? 1 : 0] = w->start_offset+GetSize(w)-1;
- }
- }
- *f << stringf(" (port (array %s %d) (direction %s))\n", EDIF_DEFR(port_it.first, port_rename, b[0], b[1]), port_it.second, dir);
+ int b[2];
+ b[upto ? 0 : 1] = start;
+ b[upto ? 1 : 0] = start+width-1;
+ *f << stringf(" (port (array %s %d) (direction %s))\n", EDIF_DEFR(port_it.first, port_rename, b[0], b[1]), width, dir);
}
}
*f << stringf(" )\n");
@@ -390,18 +396,23 @@ struct EdifBackend : public Backend {
if (sig[i].wire == NULL && sig[i] != RTLIL::State::S0 && sig[i] != RTLIL::State::S1)
log_warning("Bit %d of cell port %s.%s.%s driven by %s will be left unconnected in EDIF output.\n",
i, log_id(module), log_id(cell), log_id(p.first), log_signal(sig[i]));
- else if (sig.size() == 1)
- net_join_db[sig[i]].insert(make_pair(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name)), cell->output(p.first)));
else {
int member_idx = GetSize(sig)-i-1;
auto m = design->module(cell->type);
+ int width = sig.size();
if (m) {
auto w = m->wire(p.first);
- if (w)
+ if (w) {
member_idx = GetSize(w)-i-1;
+ width = GetSize(w);
+ }
+ }
+ if (width == 1)
+ net_join_db[sig[i]].insert(make_pair(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name)), cell->output(p.first)));
+ else {
+ net_join_db[sig[i]].insert(make_pair(stringf("(portRef (member %s %d) (instanceRef %s))",
+ EDIF_REF(p.first), member_idx, EDIF_REF(cell->name)), cell->output(p.first)));
}
- net_join_db[sig[i]].insert(make_pair(stringf("(portRef (member %s %d) (instanceRef %s))",
- EDIF_REF(p.first), member_idx, EDIF_REF(cell->name)), cell->output(p.first)));
}
}
}
diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc
index 87db0edf7..22aa686a7 100644
--- a/backends/firrtl/firrtl.cc
+++ b/backends/firrtl/firrtl.cc
@@ -25,7 +25,6 @@
#include "kernel/log.h"
#include <algorithm>
#include <string>
-#include <regex>
#include <vector>
#include <cmath>
diff --git a/backends/json/json.cc b/backends/json/json.cc
index 5c67cb857..6c924ff99 100644
--- a/backends/json/json.cc
+++ b/backends/json/json.cc
@@ -104,7 +104,7 @@ struct JsonWriter
if (state < 2)
str += " ";
f << get_string(str);
- } else if (compat_int_mode && GetSize(value) == 32 && value.is_fully_def()) {
+ } else if (compat_int_mode && GetSize(value) <= 32 && value.is_fully_def()) {
if ((value.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) != 0)
f << stringf("%d", value.as_int());
else
@@ -296,7 +296,7 @@ struct JsonBackend : public Backend {
log(" include AIG models for the different gate types\n");
log("\n");
log(" -compat-int\n");
- log(" emit 32-bit fully-defined parameter values directly\n");
+ log(" emit 32-bit or smaller fully-defined parameter values directly\n");
log(" as JSON numbers (for compatibility with old parsers)\n");
log("\n");
log("\n");
@@ -540,7 +540,7 @@ struct JsonPass : public Pass {
log(" also include AIG models for the different gate types\n");
log("\n");
log(" -compat-int\n");
- log(" emit 32-bit fully-defined parameter values directly\n");
+ log(" emit 32-bit or smaller fully-defined parameter values directly\n");
log(" as JSON numbers (for compatibility with old parsers)\n");
log("\n");
log("See 'help write_json' for a description of the JSON format used.\n");
diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc
index 081dcda99..628765831 100644
--- a/backends/smt2/smt2.cc
+++ b/backends/smt2/smt2.cc
@@ -536,6 +536,14 @@ struct Smt2Worker
if (cell->attributes.count("\\reg"))
infostr += " " + cell->attributes.at("\\reg").decode_string();
decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort("\\Y")), infostr.c_str()));
+ if (cell->getPort("\\Y").is_wire() && cell->getPort("\\Y").as_wire()->get_bool_attribute("\\maximize")){
+ decls.push_back(stringf("; yosys-smt2-maximize %s#%d\n", get_id(module), idcounter));
+ log("Wire %s is maximized\n", cell->getPort("\\Y").as_wire()->name.str().c_str());
+ }
+ else if (cell->getPort("\\Y").is_wire() && cell->getPort("\\Y").as_wire()->get_bool_attribute("\\minimize")){
+ decls.push_back(stringf("; yosys-smt2-minimize %s#%d\n", get_id(module), idcounter));
+ log("Wire %s is minimized\n", cell->getPort("\\Y").as_wire()->name.str().c_str());
+ }
makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort("\\Y")), log_signal(cell->getPort("\\Y")));
if (cell->type == "$anyseq")
ex_input_eq.push_back(stringf(" (= (|%s#%d| state) (|%s#%d| other_state))", get_id(module), idcounter, get_id(module), idcounter));
@@ -1386,7 +1394,7 @@ struct Smt2Backend : public Backend {
log("\n");
log("For this proof we create the following template (test.tpl).\n");
log("\n");
- log(" ; we need QF_UFBV for this poof\n");
+ log(" ; we need QF_UFBV for this proof\n");
log(" (set-logic QF_UFBV)\n");
log("\n");
log(" ; insert the auto-generated code here\n");
@@ -1500,11 +1508,11 @@ struct Smt2Backend : public Backend {
// extract module dependencies
std::map<RTLIL::Module*, std::set<RTLIL::Module*>> module_deps;
- for (auto &mod_it : design->modules_) {
- module_deps[mod_it.second] = std::set<RTLIL::Module*>();
- for (auto &cell_it : mod_it.second->cells_)
- if (design->modules_.count(cell_it.second->type) > 0)
- module_deps[mod_it.second].insert(design->modules_.at(cell_it.second->type));
+ for (auto mod : design->modules()) {
+ module_deps[mod] = std::set<RTLIL::Module*>();
+ for (auto cell : mod->cells())
+ if (design->has(cell->type))
+ module_deps[mod].insert(design->module(cell->type));
}
// simple good-enough topological sort
diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py
index 3d6d3e1b3..630464419 100644
--- a/backends/smt2/smtbmc.py
+++ b/backends/smt2/smtbmc.py
@@ -1158,6 +1158,8 @@ def smt_forall_assert():
global asserts_cache_dirty
asserts_cache_dirty = False
+ assert (len(smt.modinfo[topmod].maximize) + len(smt.modinfo[topmod].minimize) <= 1)
+
def make_assert_expr(asserts_cache):
expr = list()
for lst in asserts_cache:
@@ -1236,6 +1238,18 @@ def smt_forall_assert():
smt.write("".join(assert_expr))
+ if len(smt.modinfo[topmod].maximize) > 0:
+ for s in states:
+ if s in used_states_db:
+ smt.write("(maximize (|%s| %s))\n" % (smt.modinfo[topmod].maximize.copy().pop(), s))
+ break
+
+ if len(smt.modinfo[topmod].minimize) > 0:
+ for s in states:
+ if s in used_states_db:
+ smt.write("(minimize (|%s| %s))\n" % (smt.modinfo[topmod].minimize.copy().pop(), s))
+ break
+
def smt_push():
global asserts_cache_dirty
asserts_cache_dirty = True
diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py
index 34bf7ef38..69f59df79 100644
--- a/backends/smt2/smtio.py
+++ b/backends/smt2/smtio.py
@@ -101,6 +101,8 @@ class SmtModInfo:
self.cells = dict()
self.asserts = dict()
self.covers = dict()
+ self.maximize = set()
+ self.minimize = set()
self.anyconsts = dict()
self.anyseqs = dict()
self.allconsts = dict()
@@ -502,6 +504,12 @@ class SmtIo:
if fields[1] == "yosys-smt2-cover":
self.modinfo[self.curmod].covers["%s_c %s" % (self.curmod, fields[2])] = fields[3]
+ if fields[1] == "yosys-smt2-maximize":
+ self.modinfo[self.curmod].maximize.add(fields[2])
+
+ if fields[1] == "yosys-smt2-minimize":
+ self.modinfo[self.curmod].minimize.add(fields[2])
+
if fields[1] == "yosys-smt2-anyconst":
self.modinfo[self.curmod].anyconsts[fields[2]] = (fields[4], None if len(fields) <= 5 else fields[5])
self.modinfo[self.curmod].asize[fields[2]] = int(fields[3])
@@ -696,7 +704,13 @@ class SmtIo:
if msg is not None:
print("%s waiting for solver (%s)" % (self.timestamp(), msg), flush=True)
- result = self.read()
+ if self.forall:
+ result = self.read()
+ while result not in ["sat", "unsat", "unknown"]:
+ print("%s %s: %s" % (self.timestamp(), self.solver, result))
+ result = self.read()
+ else:
+ result = self.read()
if self.debug_file:
print("(set-info :status %s)" % result, file=self.debug_file)
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc
index 54d0f6148..19541f1c4 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -1066,6 +1066,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
// initial begin
// memid[0] = ...
// end
+ dump_attributes(f, indent.c_str(), cell->attributes);
f << stringf("%s" "reg [%d:%d] %s [%d:%d];\n", indent.c_str(), width-1, 0, mem_id.c_str(), size+offset-1, offset);
if (use_init)
{
@@ -1416,11 +1417,19 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
decimal = 1;
f << ", ";
- dump_const(f, cell->getParam("\\T_LIMIT"));
+ dump_const(f, cell->getParam("\\T_LIMIT_MIN"));
+ f << ": ";
+ dump_const(f, cell->getParam("\\T_LIMIT_TYP"));
+ f << ": ";
+ dump_const(f, cell->getParam("\\T_LIMIT_MAX"));
if (spec_type == "$setuphold" || spec_type == "$recrem" || spec_type == "$fullskew") {
f << ", ";
- dump_const(f, cell->getParam("\\T_LIMIT2"));
+ dump_const(f, cell->getParam("\\T_LIMIT2_MIN"));
+ f << ": ";
+ dump_const(f, cell->getParam("\\T_LIMIT2_TYP"));
+ f << ": ";
+ dump_const(f, cell->getParam("\\T_LIMIT2_MAX"));
}
f << ");\n";
diff --git a/examples/smtbmc/Makefile b/examples/smtbmc/Makefile
index 96fa058d6..61994f942 100644
--- a/examples/smtbmc/Makefile
+++ b/examples/smtbmc/Makefile
@@ -1,5 +1,5 @@
-all: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8
+all: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8 demo9
demo1: demo1.smt2
yosys-smtbmc --dump-vcd demo1.vcd demo1.smt2
@@ -28,6 +28,9 @@ demo7: demo7.smt2
demo8: demo8.smt2
yosys-smtbmc -s z3 -t 1 -g demo8.smt2
+demo9: demo9.smt2
+ yosys-smtbmc -s z3 -t 1 -g demo9.smt2
+
demo1.smt2: demo1.v
yosys -ql demo1.yslog -p 'read_verilog -formal demo1.v; prep -top demo1 -nordff; write_smt2 -wires demo1.smt2'
@@ -52,6 +55,9 @@ demo7.smt2: demo7.v
demo8.smt2: demo8.v
yosys -ql demo8.yslog -p 'read_verilog -formal demo8.v; prep -top demo8 -nordff; write_smt2 -stbv -wires demo8.smt2'
+demo9.smt2: demo9.v
+ yosys -ql demo9.yslog -p 'read_verilog -formal demo9.v; prep -top demo9 -nordff; write_smt2 -stbv -wires demo9.smt2'
+
clean:
rm -f demo1.yslog demo1.smt2 demo1.vcd
rm -f demo2.yslog demo2.smt2 demo2.vcd demo2.smtc demo2_tb.v demo2_tb demo2_tb.vcd
@@ -61,6 +67,7 @@ clean:
rm -f demo6.yslog demo6.smt2
rm -f demo7.yslog demo7.smt2
rm -f demo8.yslog demo8.smt2
+ rm -f demo9.yslog demo9.smt2
-.PHONY: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8 clean
+.PHONY: demo1 demo2 demo3 demo4 demo5 demo6 demo7 demo8 demo9 clean
diff --git a/examples/smtbmc/demo9.v b/examples/smtbmc/demo9.v
new file mode 100644
index 000000000..f0b91e2ca
--- /dev/null
+++ b/examples/smtbmc/demo9.v
@@ -0,0 +1,13 @@
+module demo9;
+ (* maximize *) wire[7:0] h = $anyconst;
+ wire [7:0] i = $allconst;
+
+ wire [7:0] t0 = ((i << 8'b00000010) + 8'b00000011);
+ wire trigger = (t0 > h) && (h < 8'b00000100);
+
+ always @* begin
+ assume(trigger == 1'b1);
+ cover(1);
+ end
+endmodule
+
diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc
index a42569301..50c2a3ce6 100644
--- a/frontends/aiger/aigerparse.cc
+++ b/frontends/aiger/aigerparse.cc
@@ -444,7 +444,7 @@ void AigerReader::parse_xaiger()
}
}
else if (c == 'r') {
- uint32_t dataSize = parse_xaiger_literal(f);
+ uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f);
flopNum = parse_xaiger_literal(f);
log_debug("flopNum = %u\n", flopNum);
log_assert(dataSize == (flopNum+1) * sizeof(uint32_t));
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 5bbea0faf..632a4d4f9 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -88,6 +88,8 @@ std::string AST::type2str(AstNodeType type)
X(AST_LIVE)
X(AST_FAIR)
X(AST_COVER)
+ X(AST_ENUM)
+ X(AST_ENUM_ITEM)
X(AST_FCALL)
X(AST_TO_BITS)
X(AST_TO_SIGNED)
@@ -180,7 +182,7 @@ bool AstNode::get_bool_attribute(RTLIL::IdString id)
AstNode *attr = attributes.at(id);
if (attr->type != AST_CONSTANT)
- log_file_error(attr->filename, attr->linenum, "Attribute `%s' with non-constant value!\n", id.c_str());
+ log_file_error(attr->filename, attr->location.first_line, "Attribute `%s' with non-constant value!\n", id.c_str());
return attr->integer != 0;
}
@@ -195,13 +197,13 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch
this->type = type;
filename = current_filename;
- linenum = get_line_num();
is_input = false;
is_output = false;
is_reg = false;
is_logic = false;
is_signed = false;
is_string = false;
+ is_enum = false;
is_wand = false;
is_wor = false;
is_unsized = false;
@@ -277,7 +279,8 @@ void AstNode::dumpAst(FILE *f, std::string indent) const
}
std::string type_name = type2str(type);
- fprintf(f, "%s%s <%s:%d>", indent.c_str(), type_name.c_str(), filename.c_str(), linenum);
+ fprintf(f, "%s%s <%s:%d.%d-%d.%d>", indent.c_str(), type_name.c_str(), filename.c_str(), location.first_line,
+ location.first_column, location.last_line, location.last_column);
if (!flag_no_dump_ptr) {
if (id2ast)
@@ -321,6 +324,9 @@ void AstNode::dumpAst(FILE *f, std::string indent) const
fprintf(f, " %d", v);
fprintf(f, " ]");
}
+ if (is_enum) {
+ fprintf(f, " type=enum");
+ }
fprintf(f, "\n");
for (auto &it : attributes) {
@@ -933,19 +939,21 @@ RTLIL::Const AstNode::realAsConst(int width)
}
// create a new AstModule from an AST_MODULE AST node
-static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL)
+static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false)
{
log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE);
if (defer)
log("Storing AST representation for module `%s'.\n", ast->str.c_str());
- else
+ else if (!quiet) {
log("Generating RTLIL representation for module `%s'.\n", ast->str.c_str());
+ }
current_module = new AstModule;
current_module->ast = NULL;
current_module->name = ast->str;
- current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum);
+ current_module->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line,
+ ast->location.first_column, ast->location.last_line, ast->location.last_column);
current_module->set_bool_attribute("\\cells_not_processed");
current_ast_mod = ast;
@@ -1022,14 +1030,14 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
if (!blackbox_module && ast->attributes.count("\\blackbox")) {
AstNode *n = ast->attributes.at("\\blackbox");
if (n->type != AST_CONSTANT)
- log_file_error(ast->filename, ast->linenum, "Got blackbox attribute with non-constant value!\n");
+ log_file_error(ast->filename, ast->location.first_line, "Got blackbox attribute with non-constant value!\n");
blackbox_module = n->asBool();
}
if (blackbox_module && ast->attributes.count("\\whitebox")) {
AstNode *n = ast->attributes.at("\\whitebox");
if (n->type != AST_CONSTANT)
- log_file_error(ast->filename, ast->linenum, "Got whitebox attribute with non-constant value!\n");
+ log_file_error(ast->filename, ast->location.first_line, "Got whitebox attribute with non-constant value!\n");
blackbox_module = !n->asBool();
}
@@ -1037,7 +1045,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
if (blackbox_module) {
AstNode *n = ast->attributes.at("\\noblackbox");
if (n->type != AST_CONSTANT)
- log_file_error(ast->filename, ast->linenum, "Got noblackbox attribute with non-constant value!\n");
+ log_file_error(ast->filename, ast->location.first_line, "Got noblackbox attribute with non-constant value!\n");
blackbox_module = !n->asBool();
}
delete ast->attributes.at("\\noblackbox");
@@ -1083,7 +1091,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
for (auto &attr : ast->attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
+ log_file_error(ast->filename, ast->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
current_module->attributes[attr.first] = attr.second->asAttrConst();
}
for (size_t i = 0; i < ast->children.size(); i++) {
@@ -1171,10 +1179,19 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
for (auto n : design->verilog_globals)
(*it)->children.push_back(n->clone());
- for (auto n : design->verilog_packages){
- for (auto o : n->children) {
+ // append nodes from previous packages using package-qualified names
+ for (auto &n : design->verilog_packages) {
+ for (auto &o : n->children) {
AstNode *cloned_node = o->clone();
- cloned_node->str = n->str + std::string("::") + cloned_node->str.substr(1);
+ // log("cloned node %s\n", type2str(cloned_node->type).c_str());
+ if (cloned_node->type == AST_ENUM) {
+ for (auto &e : cloned_node->children) {
+ log_assert(e->type == AST_ENUM_ITEM);
+ e->str = n->str + std::string("::") + e->str.substr(1);
+ }
+ } else {
+ cloned_node->str = n->str + std::string("::") + cloned_node->str.substr(1);
+ }
(*it)->children.push_back(cloned_node);
}
}
@@ -1188,25 +1205,31 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
if (design->has((*it)->str)) {
RTLIL::Module *existing_mod = design->module((*it)->str);
if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) {
- log_file_error((*it)->filename, (*it)->linenum, "Re-definition of module `%s'!\n", (*it)->str.c_str());
+ log_file_error((*it)->filename, (*it)->location.first_line, "Re-definition of module `%s'!\n", (*it)->str.c_str());
} else if (nooverwrite) {
- log("Ignoring re-definition of module `%s' at %s:%d.\n",
- (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
+ log("Ignoring re-definition of module `%s' at %s:%d.%d-%d.%d.\n",
+ (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->location.first_line, (*it)->location.first_column, (*it)->location.last_line, (*it)->location.last_column);
continue;
} else {
- log("Replacing existing%s module `%s' at %s:%d.\n",
+ log("Replacing existing%s module `%s' at %s:%d.%d-%d.%d.\n",
existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "",
- (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
+ (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->location.first_line, (*it)->location.first_column, (*it)->location.last_line, (*it)->location.last_column);
design->remove(existing_mod);
}
}
design->add(process_module(*it, defer));
}
- else if ((*it)->type == AST_PACKAGE)
+ else if ((*it)->type == AST_PACKAGE) {
+ // process enum/other declarations
+ (*it)->simplify(true, false, false, 1, -1, false, false);
design->verilog_packages.push_back((*it)->clone());
- else
+ }
+ else {
+ // must be global definition
+ (*it)->simplify(false, false, false, 1, -1, false, false); //process enum/other declarations
design->verilog_globals.push_back((*it)->clone());
+ }
}
}
@@ -1466,14 +1489,16 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
// create a new parametric module (when needed) and return the name of the generated module - without support for interfaces
RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool /*mayfail*/)
{
+ bool quiet = lib || attributes.count(ID(blackbox)) || attributes.count(ID(whitebox));
+
AstNode *new_ast = NULL;
- std::string modname = derive_common(design, parameters, &new_ast);
+ std::string modname = derive_common(design, parameters, &new_ast, quiet);
if (!design->has(modname)) {
new_ast->str = modname;
- design->add(process_module(new_ast, false));
+ design->add(process_module(new_ast, false, NULL, quiet));
design->module(modname)->check();
- } else {
+ } else if (!quiet) {
log("Found cached RTLIL representation for module `%s'.\n", modname.c_str());
}
@@ -1482,7 +1507,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
}
// create a new parametric module (when needed) and return the name of the generated module
-std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out)
+std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool quiet)
{
std::string stripped_name = name.str();
@@ -1498,13 +1523,15 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
para_counter++;
std::string para_id = child->str;
if (parameters.count(para_id) > 0) {
- log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
+ if (!quiet)
+ log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
continue;
}
para_id = stringf("$%d", para_counter);
if (parameters.count(para_id) > 0) {
- log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
+ if (!quiet)
+ log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
continue;
}
@@ -1521,7 +1548,8 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
if (design->has(modname))
return modname;
- log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str());
+ if (!quiet)
+ log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str());
loadconfig();
AstNode *new_ast = ast->clone();
@@ -1532,12 +1560,14 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
para_counter++;
std::string para_id = child->str;
if (parameters.count(para_id) > 0) {
- log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
+ if (!quiet)
+ log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
goto rewrite_parameter;
}
para_id = stringf("$%d", para_counter);
if (parameters.count(para_id) > 0) {
- log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
+ if (!quiet)
+ log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
goto rewrite_parameter;
}
continue;
@@ -1607,25 +1637,6 @@ void AstModule::loadconfig() const
flag_icells = icells;
flag_pwires = pwires;
flag_autowire = autowire;
- use_internal_line_num();
-}
-
-// internal dummy line number callbacks
-namespace {
- int internal_line_num;
- void internal_set_line_num(int n) {
- internal_line_num = n;
- }
- int internal_get_line_num() {
- return internal_line_num;
- }
-}
-
-// use internal dummy line number callbacks
-void AST::use_internal_line_num()
-{
- set_line_num = &internal_set_line_num;
- get_line_num = &internal_get_line_num;
}
YOSYS_NAMESPACE_END
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 14e1cec5e..e27ab10c2 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -68,6 +68,8 @@ namespace AST
AST_LIVE,
AST_FAIR,
AST_COVER,
+ AST_ENUM,
+ AST_ENUM_ITEM,
AST_FCALL,
AST_TO_BITS,
@@ -154,6 +156,13 @@ namespace AST
AST_TYPEDEF
};
+ struct AstSrcLocType {
+ unsigned int first_line, last_line;
+ unsigned int first_column, last_column;
+ AstSrcLocType() : first_line(0), last_line(0), first_column(0), last_column(0) {}
+ AstSrcLocType(int _first_line, int _first_column, int _last_line, int _last_column) : first_line(_first_line), last_line(_last_line), first_column(_first_column), last_column(_last_column) {}
+ };
+
// convert an node type to a string (e.g. for debug output)
std::string type2str(AstNodeType type);
@@ -181,6 +190,8 @@ namespace AST
int port_id, range_left, range_right;
uint32_t integer;
double realvalue;
+ // set for IDs typed to an enumeration, not used
+ bool is_enum;
// if this is a multirange memory then this vector contains offset and length of each dimension
std::vector<int> multirange_dimensions;
@@ -195,7 +206,7 @@ namespace AST
// it is automatically set by the constructor using AST::current_filename and
// the AST::get_line_num() callback function.
std::string filename;
- int linenum;
+ AstSrcLocType location;
// creating and deleting nodes
AstNode(AstNodeType type = AST_NONE, AstNode *child1 = NULL, AstNode *child2 = NULL, AstNode *child3 = NULL);
@@ -286,6 +297,9 @@ namespace AST
int isConst() const; // return '1' for AST_CONSTANT and '2' for AST_REALVALUE
double asReal(bool is_signed);
RTLIL::Const realAsConst(int width);
+
+ // helpers for enum
+ void allocateDefaultEnumValues();
};
// process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code
@@ -300,7 +314,7 @@ namespace AST
~AstModule() YS_OVERRIDE;
RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) YS_OVERRIDE;
RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) YS_OVERRIDE;
- std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out);
+ std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool quiet = false);
void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces) YS_OVERRIDE;
RTLIL::Module *clone() const YS_OVERRIDE;
void loadconfig() const;
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index 94f5c0a04..54d8a11fa 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -44,18 +44,18 @@ using namespace AST_INTERNAL;
static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true)
{
std::stringstream sstr;
- sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++);
+ sstr << type << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), type);
- cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum);
+ cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width);
- wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum);
+ wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
if (gen_attributes)
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
+ log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
cell->attributes[attr.first] = attr.second->asAttrConst();
}
@@ -77,18 +77,18 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
}
std::stringstream sstr;
- sstr << "$extend" << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++);
+ sstr << "$extend" << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$pos");
- cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum);
+ cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width);
- wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum);
+ wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
if (that != NULL)
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
+ log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
cell->attributes[attr.first] = attr.second->asAttrConst();
}
@@ -105,17 +105,17 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{
std::stringstream sstr;
- sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++);
+ sstr << type << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), type);
- cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum);
+ cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width);
- wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum);
+ wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
+ log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
cell->attributes[attr.first] = attr.second->asAttrConst();
}
@@ -139,17 +139,17 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const
log_assert(cond.size() == 1);
std::stringstream sstr;
- sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (autoidx++);
+ sstr << "$ternary$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$mux");
- cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum);
+ cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", left.size());
- wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum);
+ wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
+ log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
cell->attributes[attr.first] = attr.second->asAttrConst();
}
@@ -199,11 +199,11 @@ struct AST_INTERNAL::ProcessGenerator
{
// generate process and simple root case
proc = new RTLIL::Process;
- proc->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum);
- proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->linenum, autoidx++);
+ proc->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column);
+ proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->location.first_line, autoidx++);
for (auto &attr : always->attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(always->filename, always->linenum, "Attribute `%s' with non-constant value!\n",
+ log_file_error(always->filename, always->location.first_line, "Attribute `%s' with non-constant value!\n",
attr.first.c_str());
proc->attributes[attr.first] = attr.second->asAttrConst();
}
@@ -234,8 +234,8 @@ struct AST_INTERNAL::ProcessGenerator
if (found_anyedge_syncs) {
if (found_global_syncs)
- log_file_error(always->filename, always->linenum, "Found non-synthesizable event list!\n");
- log("Note: Assuming pure combinatorial block at %s:%d in\n", always->filename.c_str(), always->linenum);
+ log_file_error(always->filename, always->location.first_line, "Found non-synthesizable event list!\n");
+ log("Note: Assuming pure combinatorial block at %s:%d.%d-%d.%d in\n", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column);
log("compliance with IEC 62142(E):2005 / IEEE Std. 1364.1(E):2002. Recommending\n");
log("use of @* instead of @(...) for better match of synthesis and simulation.\n");
}
@@ -249,12 +249,12 @@ struct AST_INTERNAL::ProcessGenerator
continue;
found_clocked_sync = true;
if (found_global_syncs || found_anyedge_syncs)
- log_file_error(always->filename, always->linenum, "Found non-synthesizable event list!\n");
+ log_file_error(always->filename, always->location.first_line, "Found non-synthesizable event list!\n");
RTLIL::SyncRule *syncrule = new RTLIL::SyncRule;
syncrule->type = child->type == AST_POSEDGE ? RTLIL::STp : RTLIL::STn;
syncrule->signal = child->children[0]->genRTLIL();
if (GetSize(syncrule->signal) != 1)
- log_file_error(always->filename, always->linenum, "Found posedge/negedge event on a signal that is not 1 bit wide!\n");
+ log_file_error(always->filename, always->location.first_line, "Found posedge/negedge event on a signal that is not 1 bit wide!\n");
addChunkActions(syncrule->actions, subst_lvalue_from, subst_lvalue_to, true);
proc->syncs.push_back(syncrule);
}
@@ -335,7 +335,7 @@ struct AST_INTERNAL::ProcessGenerator
} while (current_module->wires_.count(wire_name) > 0);
RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width);
- wire->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum);
+ wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column);
chunk.wire = wire;
chunk.offset = 0;
@@ -470,13 +470,13 @@ struct AST_INTERNAL::ProcessGenerator
case AST_CASE:
{
RTLIL::SwitchRule *sw = new RTLIL::SwitchRule;
- sw->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum);
+ sw->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, ast->location.first_column, ast->location.last_line, ast->location.last_column);
sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap());
current_case->switches.push_back(sw);
for (auto &attr : ast->attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
+ log_file_error(ast->filename, ast->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
sw->attributes[attr.first] = attr.second->asAttrConst();
}
@@ -504,7 +504,7 @@ struct AST_INTERNAL::ProcessGenerator
RTLIL::CaseRule *backup_case = current_case;
current_case = new RTLIL::CaseRule;
- current_case->attributes["\\src"] = stringf("%s:%d", child->filename.c_str(), child->linenum);
+ current_case->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", child->filename.c_str(), child->location.first_line, child->location.first_column, child->location.last_line, child->location.last_column);
last_generated_case = current_case;
addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue);
for (auto node : child->children) {
@@ -554,16 +554,16 @@ struct AST_INTERNAL::ProcessGenerator
break;
case AST_WIRE:
- log_file_error(ast->filename, ast->linenum, "Found reg declaration in block without label!\n");
+ log_file_error(ast->filename, ast->location.first_line, "Found reg declaration in block without label!\n");
break;
case AST_ASSIGN:
- log_file_error(ast->filename, ast->linenum, "Found continous assignment in always/initial block!\n");
+ log_file_error(ast->filename, ast->location.first_line, "Found continous assignment in always/initial block!\n");
break;
case AST_PARAMETER:
case AST_LOCALPARAM:
- log_file_error(ast->filename, ast->linenum, "Found parameter declaration in block without label!\n");
+ log_file_error(ast->filename, ast->location.first_line, "Found parameter declaration in block without label!\n");
break;
case AST_NONE:
@@ -595,6 +595,9 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
switch (type)
{
+ case AST_NONE:
+ // unallocated enum, ignore
+ break;
case AST_CONSTANT:
width_hint = max(width_hint, int(bits.size()));
if (!is_signed)
@@ -611,8 +614,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
if (id_ast == NULL && current_scope.count(str))
id_ast = current_scope.at(str);
if (!id_ast)
- log_file_error(filename, linenum, "Failed to resolve identifier %s for width detection!\n", str.c_str());
- if (id_ast->type == AST_PARAMETER || id_ast->type == AST_LOCALPARAM) {
+ log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", str.c_str());
+ if (id_ast->type == AST_PARAMETER || id_ast->type == AST_LOCALPARAM || id_ast->type == AST_ENUM_ITEM) {
if (id_ast->children.size() > 1 && id_ast->children[1]->range_valid) {
this_width = id_ast->children[1]->range_left - id_ast->children[1]->range_right + 1;
} else
@@ -621,7 +624,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
if (id_ast->children[0]->type == AST_CONSTANT)
this_width = id_ast->children[0]->bits.size();
else
- log_file_error(filename, linenum, "Failed to detect width for parameter %s!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to detect width for parameter %s!\n", str.c_str());
if (children.size() != 0)
range = children[0];
} else if (id_ast->type == AST_WIRE || id_ast->type == AST_AUTOWIRE) {
@@ -633,7 +636,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
// log("---\n");
// id_ast->dumpAst(NULL, "decl> ");
// dumpAst(NULL, "ref> ");
- log_file_error(filename, linenum, "Failed to detect width of signal access `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to detect width of signal access `%s'!\n", str.c_str());
}
} else {
this_width = id_ast->range_left - id_ast->range_right + 1;
@@ -644,12 +647,12 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
this_width = 32;
} else if (id_ast->type == AST_MEMORY) {
if (!id_ast->children[0]->range_valid)
- log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", str.c_str());
this_width = id_ast->children[0]->range_left - id_ast->children[0]->range_right + 1;
if (children.size() > 1)
range = children[1];
} else
- log_file_error(filename, linenum, "Failed to detect width for identifier %s!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to detect width for identifier %s!\n", str.c_str());
if (range) {
if (range->children.size() == 1)
this_width = 1;
@@ -659,7 +662,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
this_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;
delete left_at_zero_ast;
delete right_at_zero_ast;
@@ -675,7 +678,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
case AST_TO_BITS:
while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { }
if (children[0]->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Left operand of tobits expression is not constant!\n");
+ log_file_error(filename, location.first_line, "Left operand of tobits expression is not constant!\n");
children[1]->detectSignWidthWorker(sub_width_hint, sign_hint);
width_hint = max(width_hint, children[0]->bitsAsConst().as_int());
break;
@@ -703,7 +706,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
case AST_REPLICATE:
while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { }
if (children[0]->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Left operand of replicate expression is not constant!\n");
+ log_file_error(filename, location.first_line, "Left operand of replicate expression is not constant!\n");
children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint);
width_hint = max(width_hint, children[0]->bitsAsConst().as_int() * sub_width_hint);
sign_hint = false;
@@ -777,7 +780,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
if (!id2ast->is_signed)
sign_hint = false;
if (!id2ast->children[0]->range_valid)
- log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", str.c_str());
this_width = id2ast->children[0]->range_left - id2ast->children[0]->range_right + 1;
width_hint = max(width_hint, this_width);
break;
@@ -787,7 +790,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
if (GetSize(children) == 1) {
while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { }
if (children[0]->type != AST_CONSTANT)
- log_file_error(filename, linenum, "System function %s called with non-const argument!\n",
+ log_file_error(filename, location.first_line, "System function %s called with non-const argument!\n",
RTLIL::unescape_id(str).c_str());
width_hint = max(width_hint, int(children[0]->asInt(true)));
}
@@ -809,7 +812,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
default:
for (auto f : log_files)
current_ast_mod->dumpAst(f, "verilog-ast> ");
- log_file_error(filename, linenum, "Don't know how to detect sign and width for %s node!\n", type2str(type).c_str());
+ log_file_error(filename, location.first_line, "Don't know how to detect sign and width for %s node!\n", type2str(type).c_str());
}
if (*found_real)
@@ -842,7 +845,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
std::string type_name;
current_filename = filename;
- set_line_num(linenum);
switch (type)
{
@@ -861,6 +863,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_GENIF:
case AST_GENCASE:
case AST_PACKAGE:
+ case AST_ENUM:
case AST_MODPORT:
case AST_MODPORTMEMBER:
case AST_TYPEDEF:
@@ -870,7 +873,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// This is used by the hierarchy pass to know when it can replace interface connection with the individual
// signals.
RTLIL::Wire *wire = current_module->addWire(str, 1);
- wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->start_offset = 0;
wire->port_id = port_id;
wire->port_input = true;
@@ -901,18 +904,18 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (flag_pwires)
{
if (GetSize(children) < 1 || children[0]->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Parameter `%s' with non-constant value!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Parameter `%s' with non-constant value!\n", str.c_str());
RTLIL::Const val = children[0]->bitsAsConst();
RTLIL::Wire *wire = current_module->addWire(str, GetSize(val));
current_module->connect(wire, val);
- wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->attributes[type == AST_PARAMETER ? "\\parameter" : "\\localparam"] = 1;
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
+ log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
wire->attributes[attr.first] = attr.second->asAttrConst();
}
}
@@ -921,15 +924,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// create an RTLIL::Wire for an AST_WIRE node
case AST_WIRE: {
if (current_module->wires_.count(str) != 0)
- log_file_error(filename, linenum, "Re-definition of signal `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Re-definition of signal `%s'!\n", str.c_str());
if (!range_valid)
- log_file_error(filename, linenum, "Signal `%s' with non-constant width!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Signal `%s' with non-constant width!\n", str.c_str());
if (!(range_left >= range_right || (range_left == -1 && range_right == 0)))
- log_file_error(filename, linenum, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1);
+ log_file_error(filename, location.first_line, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1);
RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1);
- wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->start_offset = range_right;
wire->port_id = port_id;
wire->port_input = is_input;
@@ -938,7 +941,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
+ log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
wire->attributes[attr.first] = attr.second->asAttrConst();
}
@@ -950,17 +953,17 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// create an RTLIL::Memory for an AST_MEMORY node
case AST_MEMORY: {
if (current_module->memories.count(str) != 0)
- log_file_error(filename, linenum, "Re-definition of memory `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Re-definition of memory `%s'!\n", str.c_str());
log_assert(children.size() >= 2);
log_assert(children[0]->type == AST_RANGE);
log_assert(children[1]->type == AST_RANGE);
if (!children[0]->range_valid || !children[1]->range_valid)
- log_file_error(filename, linenum, "Memory `%s' with non-constant width or size!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Memory `%s' with non-constant width or size!\n", str.c_str());
RTLIL::Memory *memory = new RTLIL::Memory;
- memory->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ memory->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
memory->name = str;
memory->width = children[0]->range_left - children[0]->range_right + 1;
if (children[1]->range_right < children[1]->range_left) {
@@ -974,7 +977,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
+ log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
memory->attributes[attr.first] = attr.second->asAttrConst();
}
}
@@ -997,7 +1000,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
RTLIL::SigSpec sig = realAsConst(width_hint);
- log_file_warning(filename, linenum, "converting real value %e to binary %s.\n", realvalue, log_signal(sig));
+ log_file_warning(filename, location.first_line, "converting real value %e to binary %s.\n", realvalue, log_signal(sig));
return sig;
}
@@ -1015,16 +1018,16 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) {
RTLIL::Wire *wire = current_module->addWire(str);
- wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->name = str;
if (flag_autowire)
- log_file_warning(filename, linenum, "Identifier `%s' is implicitly declared.\n", str.c_str());
+ log_file_warning(filename, location.first_line, "Identifier `%s' is implicitly declared.\n", str.c_str());
else
- log_file_error(filename, linenum, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str());
}
- else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM) {
+ else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM || id2ast->type == AST_ENUM_ITEM) {
if (id2ast->children[0]->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Parameter %s does not evaluate to constant value!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Parameter %s does not evaluate to constant value!\n", str.c_str());
chunk = RTLIL::Const(id2ast->children[0]->bits);
goto use_const_chunk;
}
@@ -1039,11 +1042,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
is_interface = true;
}
else {
- log_file_error(filename, linenum, "Identifier `%s' doesn't map to any signal!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Identifier `%s' doesn't map to any signal!\n", str.c_str());
}
if (id2ast->type == AST_MEMORY)
- log_file_error(filename, linenum, "Identifier `%s' does map to an unexpanded memory!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Identifier `%s' does map to an unexpanded memory!\n", str.c_str());
// If identifier is an interface, create a RTLIL::SigSpec with a dummy wire with a attribute called 'is_interface'
// This makes it possible for the hierarchy pass to see what are interface connections and then replace them
@@ -1069,7 +1072,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
use_const_chunk:
if (children.size() != 0) {
if (children[0]->type != AST_RANGE)
- log_file_error(filename, linenum, "Single range expected.\n");
+ log_file_error(filename, location.first_line, "Single range expected.\n");
int source_width = id2ast->range_left - id2ast->range_right + 1;
int source_offset = id2ast->range_right;
if (!children[0]->range_valid) {
@@ -1078,7 +1081,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;
AstNode *fake_ast = new AstNode(AST_NONE, clone(), children[0]->children.size() >= 2 ?
children[0]->children[1]->clone() : children[0]->children[0]->clone());
@@ -1106,10 +1109,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
chunk.offset = (id2ast->range_left - id2ast->range_right + 1) - (chunk.offset + chunk.width);
if (chunk.offset >= source_width || chunk.offset + chunk.width < 0) {
if (chunk.width == 1)
- log_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting result bit to undef.\n",
+ log_file_warning(filename, location.first_line, "Range select out of bounds on signal `%s': Setting result bit to undef.\n",
str.c_str());
else
- log_file_warning(filename, linenum, "Range select [%d:%d] out of bounds on signal `%s': Setting all %d result bits to undef.\n",
+ log_file_warning(filename, location.first_line, "Range select [%d:%d] out of bounds on signal `%s': Setting all %d result bits to undef.\n",
children[0]->range_left, children[0]->range_right, str.c_str(), chunk.width);
chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width);
} else {
@@ -1123,10 +1126,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
chunk.offset += add_undef_bits_lsb;
}
if (add_undef_bits_lsb)
- log_file_warning(filename, linenum, "Range [%d:%d] select out of bounds on signal `%s': Setting %d LSB bits to undef.\n",
+ log_file_warning(filename, location.first_line, "Range [%d:%d] select out of bounds on signal `%s': Setting %d LSB bits to undef.\n",
children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_lsb);
if (add_undef_bits_msb)
- log_file_warning(filename, linenum, "Range [%d:%d] select out of bounds on signal `%s': Setting %d MSB bits to undef.\n",
+ log_file_warning(filename, location.first_line, "Range [%d:%d] select out of bounds on signal `%s': Setting %d MSB bits to undef.\n",
children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_msb);
}
}
@@ -1166,7 +1169,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::SigSpec left = children[0]->genRTLIL();
RTLIL::SigSpec right = children[1]->genRTLIL();
if (!left.is_fully_const())
- log_file_error(filename, linenum, "Left operand of replicate expression is not constant!\n");
+ log_file_error(filename, location.first_line, "Left operand of replicate expression is not constant!\n");
int count = left.as_int();
RTLIL::SigSpec sig;
for (int i = 0; i < count; i++)
@@ -1334,18 +1337,31 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
detectSignWidth(width_hint, sign_hint);
RTLIL::SigSpec cond = children[0]->genRTLIL();
- RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint);
- RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint);
+ RTLIL::SigSpec sig;
+ if (cond.is_fully_const()) {
+ if (cond.as_bool()) {
+ sig = children[1]->genRTLIL(width_hint, sign_hint);
+ widthExtend(this, sig, sig.size(), children[1]->is_signed);
+ }
+ else {
+ sig = children[2]->genRTLIL(width_hint, sign_hint);
+ widthExtend(this, sig, sig.size(), children[2]->is_signed);
+ }
+ }
+ else {
+ RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint);
+ RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint);
- if (cond.size() > 1)
- cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false);
+ if (cond.size() > 1)
+ cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false);
- int width = max(val1.size(), val2.size());
- is_signed = children[1]->is_signed && children[2]->is_signed;
- widthExtend(this, val1, width, is_signed);
- widthExtend(this, val2, width, is_signed);
+ int width = max(val1.size(), val2.size());
+ is_signed = children[1]->is_signed && children[2]->is_signed;
+ widthExtend(this, val1, width, is_signed);
+ widthExtend(this, val2, width, is_signed);
- RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2);
+ sig = mux2rtlil(this, cond, val1, val2);
+ }
if (sig.size() < width_hint)
sig.extend_u0(width_hint, sign_hint);
@@ -1356,13 +1372,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_MEMRD:
{
std::stringstream sstr;
- sstr << "$memrd$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++);
+ sstr << "$memrd$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memrd");
- cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_DATA", current_module->memories[str]->width);
- wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), location.first_line);
int mem_width, mem_size, addr_bits;
is_signed = id2ast->is_signed;
@@ -1394,10 +1410,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_MEMINIT:
{
std::stringstream sstr;
- sstr << (type == AST_MEMWR ? "$memwr$" : "$meminit$") << str << "$" << filename << ":" << linenum << "$" << (autoidx++);
+ sstr << (type == AST_MEMWR ? "$memwr$" : "$meminit$") << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(sstr.str(), type == AST_MEMWR ? "$memwr" : "$meminit");
- cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
int mem_width, mem_size, addr_bits;
id2ast->meminfo(mem_width, mem_size, addr_bits);
@@ -1405,7 +1421,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
int num_words = 1;
if (type == AST_MEMINIT) {
if (children[2]->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Memory init with non-constant word count!\n");
+ log_file_error(filename, location.first_line, "Memory init with non-constant word count!\n");
num_words = int(children[2]->asInt(false));
cell->parameters["\\WORDS"] = RTLIL::Const(num_words);
}
@@ -1457,18 +1473,18 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
IdString cellname;
if (str.empty()) {
std::stringstream sstr;
- sstr << celltype << "$" << filename << ":" << linenum << "$" << (autoidx++);
+ sstr << celltype << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
cellname = sstr.str();
} else {
cellname = str;
}
RTLIL::Cell *cell = current_module->addCell(cellname, celltype);
- cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
+ log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
cell->attributes[attr.first] = attr.second->asAttrConst();
}
@@ -1489,7 +1505,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
new_left.append(left[i]);
new_right.append(right[i]);
}
- log_file_warning(filename, linenum, "Ignoring assignment to constant bits:\n"
+ log_file_warning(filename, location.first_line, "Ignoring assignment to constant bits:\n"
" old assignment: %s = %s\n new assignment: %s = %s.\n",
log_signal(left), log_signal(right),
log_signal(new_left), log_signal(new_right));
@@ -1506,10 +1522,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
int port_counter = 0, para_counter = 0;
if (current_module->count_id(str) != 0)
- log_file_error(filename, linenum, "Re-definition of cell `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Re-definition of cell `%s'!\n", str.c_str());
RTLIL::Cell *cell = current_module->addCell(str, "");
- cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
// Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass
cell->set_bool_attribute("\\module_not_derived");
@@ -1525,7 +1541,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
int extra_const_flags = 0;
IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str;
if (child->children[0]->type == AST_REALVALUE) {
- log_file_warning(filename, linenum, "Replacing floating point parameter %s.%s = %f with string.\n",
+ log_file_warning(filename, location.first_line, "Replacing floating point parameter %s.%s = %f with string.\n",
log_id(cell), log_id(paraname), child->children[0]->realvalue);
extra_const_flags = RTLIL::CONST_FLAG_REAL;
auto strnode = AstNode::mkconst_str(stringf("%f", child->children[0]->realvalue));
@@ -1533,7 +1549,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
delete strnode;
}
if (child->children[0]->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Parameter %s.%s with non-constant value!\n",
+ log_file_error(filename, location.first_line, "Parameter %s.%s with non-constant value!\n",
log_id(cell), log_id(paraname));
cell->parameters[paraname] = child->children[0]->asParaConst();
cell->parameters[paraname].flags |= extra_const_flags;
@@ -1556,24 +1572,28 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Attribute `%s' with non-constant value.\n", attr.first.c_str());
+ log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value.\n", attr.first.c_str());
cell->attributes[attr.first] = attr.second->asAttrConst();
}
- if (cell->type.in("$specify2", "$specify3")) {
+ if (cell->type == "$specify2") {
int src_width = GetSize(cell->getPort("\\SRC"));
int dst_width = GetSize(cell->getPort("\\DST"));
bool full = cell->getParam("\\FULL").as_bool();
if (!full && src_width != dst_width)
- log_file_error(filename, linenum, "Parallel specify SRC width does not match DST width.\n");
- if (cell->type == "$specify3") {
- int dat_width = GetSize(cell->getPort("\\DAT"));
- if (dat_width != dst_width)
- log_file_error(filename, linenum, "Specify DAT width does not match DST width.\n");
- }
+ log_file_error(filename, location.first_line, "Parallel specify SRC width does not match DST width.\n");
+ cell->setParam("\\SRC_WIDTH", Const(src_width));
+ cell->setParam("\\DST_WIDTH", Const(dst_width));
+ }
+ else if (cell->type == "$specify3") {
+ int dat_width = GetSize(cell->getPort("\\DAT"));
+ int dst_width = GetSize(cell->getPort("\\DST"));
+ if (dat_width != dst_width)
+ log_file_error(filename, location.first_line, "Specify DAT width does not match DST width.\n");
+ int src_width = GetSize(cell->getPort("\\SRC"));
cell->setParam("\\SRC_WIDTH", Const(src_width));
cell->setParam("\\DST_WIDTH", Const(dst_width));
}
- if (cell->type == "$specrule") {
+ else if (cell->type == "$specrule") {
int src_width = GetSize(cell->getPort("\\SRC"));
int dst_width = GetSize(cell->getPort("\\DST"));
cell->setParam("\\SRC_WIDTH", Const(src_width));
@@ -1600,30 +1620,30 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
int sz = children.size();
if (str == "$info") {
if (sz > 0)
- log_file_info(filename, linenum, "%s.\n", children[0]->str.c_str());
+ log_file_info(filename, location.first_line, "%s.\n", children[0]->str.c_str());
else
- log_file_info(filename, linenum, "\n");
+ log_file_info(filename, location.first_line, "\n");
} else if (str == "$warning") {
if (sz > 0)
- log_file_warning(filename, linenum, "%s.\n", children[0]->str.c_str());
+ log_file_warning(filename, location.first_line, "%s.\n", children[0]->str.c_str());
else
- log_file_warning(filename, linenum, "\n");
+ log_file_warning(filename, location.first_line, "\n");
} else if (str == "$error") {
if (sz > 0)
- log_file_error(filename, linenum, "%s.\n", children[0]->str.c_str());
+ log_file_error(filename, location.first_line, "%s.\n", children[0]->str.c_str());
else
- log_file_error(filename, linenum, "\n");
+ log_file_error(filename, location.first_line, "\n");
} else if (str == "$fatal") {
// TODO: 1st parameter, if exists, is 0,1 or 2, and passed to $finish()
// if no parameter is given, default value is 1
// dollar_finish(sz ? children[0] : 1);
// perhaps create & use log_file_fatal()
if (sz > 0)
- log_file_error(filename, linenum, "FATAL: %s.\n", children[0]->str.c_str());
+ log_file_error(filename, location.first_line, "FATAL: %s.\n", children[0]->str.c_str());
else
- log_file_error(filename, linenum, "FATAL.\n");
+ log_file_error(filename, location.first_line, "FATAL.\n");
} else {
- log_file_error(filename, linenum, "Unknown elabortoon system task '%s'.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Unknown elabortoon system task '%s'.\n", str.c_str());
}
} break;
@@ -1634,32 +1654,32 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
int width = width_hint;
if (GetSize(children) > 1)
- log_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 0.\n",
+ log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 0.\n",
RTLIL::unescape_id(str).c_str(), GetSize(children));
if (GetSize(children) == 1) {
if (children[0]->type != AST_CONSTANT)
- log_file_error(filename, linenum, "System function %s called with non-const argument!\n",
+ log_file_error(filename, location.first_line, "System function %s called with non-const argument!\n",
RTLIL::unescape_id(str).c_str());
width = children[0]->asInt(true);
}
if (width <= 0)
- log_file_error(filename, linenum, "Failed to detect width of %s!\n", RTLIL::unescape_id(str).c_str());
+ log_file_error(filename, location.first_line, "Failed to detect width of %s!\n", RTLIL::unescape_id(str).c_str());
Cell *cell = current_module->addCell(myid, str.substr(1));
- cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
cell->parameters["\\WIDTH"] = width;
if (attributes.count("\\reg")) {
auto &attr = attributes.at("\\reg");
if (attr->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Attribute `reg' with non-constant value!\n");
+ log_file_error(filename, location.first_line, "Attribute `reg' with non-constant value!\n");
cell->attributes["\\reg"] = attr->asAttrConst();
}
Wire *wire = current_module->addWire(myid + "_wire", width);
- wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
+ wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
cell->setPort("\\Y", wire);
is_signed = sign_hint;
@@ -1672,7 +1692,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
for (auto f : log_files)
current_ast_mod->dumpAst(f, "verilog-ast> ");
type_name = type2str(type);
- log_file_error(filename, linenum, "Don't know how to generate RTLIL code for %s node!\n", type_name.c_str());
+ log_file_error(filename, location.first_line, "Don't know how to generate RTLIL code for %s node!\n", type_name.c_str());
}
return RTLIL::SigSpec();
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 2229bb18a..10e9f2683 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -53,7 +53,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg
{
// If there's no next character, that's a problem
if (i+1 >= sformat.length())
- log_file_error(filename, linenum, "System task `%s' called with `%%' at end of string.\n", str.c_str());
+ log_file_error(filename, location.first_line, "System task `%s' called with `%%' at end of string.\n", str.c_str());
char cformat = sformat[++i];
@@ -77,13 +77,13 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg
case 'x':
case 'X':
if (next_arg >= GetSize(children))
- log_file_error(filename, linenum, "Missing argument for %%%c format specifier in system task `%s'.\n",
+ log_file_error(filename, location.first_line, "Missing argument for %%%c format specifier in system task `%s'.\n",
cformat, str.c_str());
node_arg = children[next_arg++];
while (node_arg->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
if (node_arg->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str());
break;
case 'm':
@@ -91,7 +91,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg
break;
default:
- log_file_error(filename, linenum, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str());
+ log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str());
break;
}
@@ -159,7 +159,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
#if 0
log("-------------\n");
- log("AST simplify[%d] depth %d at %s:%d on %s %p:\n", stage, recursion_counter, filename.c_str(), linenum, type2str(type).c_str(), this);
+ log("AST simplify[%d] depth %d at %s:%d on %s %p:\n", stage, recursion_counter, filename.c_str(), location.first_line, type2str(type).c_str(), this);
log("const_fold=%d, at_zero=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n",
int(const_fold), int(at_zero), int(in_lvalue), int(stage), int(width_hint), int(sign_hint), int(in_param));
// dumpAst(NULL, "> ");
@@ -251,7 +251,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (it.first != ID(mem2reg))
reg->attributes.emplace(it.first, it.second->clone());
reg->filename = node->filename;
- reg->linenum = node->linenum;
+ reg->location = node->location;
children.push_back(reg);
while (reg->simplify(true, false, false, 1, -1, false, false)) { }
}
@@ -273,7 +273,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
current_filename = filename;
- set_line_num(linenum);
// we do not look inside a task or function
// (but as soon as a task or function is instantiated we process the generated AST as usual)
@@ -286,13 +285,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
// note that $display, $finish, and $stop are used for synthesis-time DRC so they're not in this list
if ((type == AST_FCALL || type == AST_TCALL) && (str == "$strobe" || str == "$monitor" || str == "$time" ||
str == "$dumpfile" || str == "$dumpvars" || str == "$dumpon" || str == "$dumpoff" || str == "$dumpall")) {
- log_file_warning(filename, linenum, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str.c_str());
+ log_file_warning(filename, location.first_line, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str.c_str());
delete_children();
str = std::string();
}
if ((type == AST_TCALL) && (str == "$display" || str == "$write") && (!current_always || current_always->type != AST_INITIAL)) {
- log_file_warning(filename, linenum, "System task `%s' outside initial block is unsupported.\n", str.c_str());
+ log_file_warning(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str());
delete_children();
str = std::string();
}
@@ -304,14 +303,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
{
int nargs = GetSize(children);
if (nargs < 1)
- log_file_error(filename, linenum, "System task `%s' got %d arguments, expected >= 1.\n",
+ log_file_error(filename, location.first_line, "System task `%s' got %d arguments, expected >= 1.\n",
str.c_str(), int(children.size()));
// First argument is the format string
AstNode *node_string = children[0];
while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
if (node_string->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str());
std::string sformat = node_string->bitsAsConst().decode_string();
std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint);
// Finally, print the message (only include a \n for $display, not for $write)
@@ -323,9 +322,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
// activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
- if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX || type == AST_TYPEDEF)
+ if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_ENUM_ITEM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX || type == AST_TYPEDEF)
const_fold = true;
- if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM))
+ if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM || current_scope[str]->type == AST_ENUM_ITEM))
const_fold = true;
// in certain cases a function must be evaluated constant. this is what in_param controls.
@@ -405,23 +404,40 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
continue;
wires_are_incompatible:
if (stage > 1)
- log_file_error(filename, linenum, "Incompatible re-declaration of wire %s.\n", node->str.c_str());
+ log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", node->str.c_str());
continue;
}
this_wire_scope[node->str] = node;
}
+ // these nodes appear at the top level in a module and can define names
if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL ||
node->type == AST_TYPEDEF) {
backup_scope[node->str] = current_scope[node->str];
current_scope[node->str] = node;
}
+ if (node->type == AST_ENUM) {
+ current_scope[node->str] = node;
+ for (auto enode : node->children) {
+ log_assert(enode->type==AST_ENUM_ITEM);
+ if (current_scope.count(enode->str) == 0) {
+ current_scope[enode->str] = enode;
+ }
+ }
+ }
}
for (size_t i = 0; i < children.size(); i++) {
AstNode *node = children[i];
if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY || node->type == AST_TYPEDEF)
while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM))
did_something = true;
+ if (node->type == AST_ENUM) {
+ for (auto enode YS_ATTRIBUTE(unused) : node->children){
+ log_assert(enode->type==AST_ENUM_ITEM);
+ while (node->simplify(true, false, false, 1, -1, false, in_param))
+ did_something = true;
+ }
+ }
}
}
@@ -434,7 +450,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (type == AST_ALWAYS || type == AST_INITIAL)
{
if (current_always != nullptr)
- log_file_error(filename, linenum, "Invalid nesting of always blocks and/or initializations.\n");
+ log_file_error(filename, location.first_line, "Invalid nesting of always blocks and/or initializations.\n");
current_always = this;
current_always_clocked = false;
@@ -477,7 +493,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && children[0]->id2ast->is_logic)
children[0]->id2ast->is_reg = true; // if logic type is used in a block asignment
if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && !children[0]->id2ast->is_reg)
- log_warning("wire '%s' is assigned in a block at %s:%d.\n", children[0]->str.c_str(), filename.c_str(), linenum);
+ log_warning("wire '%s' is assigned in a block at %s:%d.%d-%d.%d.\n", children[0]->str.c_str(), filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
if (type == AST_ASSIGN && children[0]->id2ast->is_reg) {
bool is_rand_reg = false;
if (children[1]->type == AST_FCALL) {
@@ -491,12 +507,24 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
is_rand_reg = true;
}
if (!is_rand_reg)
- log_warning("reg '%s' is assigned in a continuous assignment at %s:%d.\n", children[0]->str.c_str(), filename.c_str(), linenum);
+ log_warning("reg '%s' is assigned in a continuous assignment at %s:%d.%d-%d.%d.\n", children[0]->str.c_str(), filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
}
children[0]->was_checked = true;
}
break;
+ case AST_ENUM:
+ //log("\nENUM %s: %d child %d\n", str.c_str(), basic_prep, children[0]->basic_prep);
+ if (!basic_prep) {
+ for (auto item_node : children) {
+ while (!item_node->basic_prep && item_node->simplify(false, false, false, stage, -1, false, in_param))
+ did_something = true;
+ }
+ // allocate values (called more than once)
+ allocateDefaultEnumValues();
+ }
+ break;
+
case AST_PARAMETER:
case AST_LOCALPARAM:
while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true)
@@ -506,7 +534,19 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true)
did_something = true;
if (!children[1]->range_valid)
- log_file_error(filename, linenum, "Non-constant width range on parameter decl.\n");
+ log_file_error(filename, location.first_line, "Non-constant width range on parameter decl.\n");
+ width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1);
+ }
+ break;
+ case AST_ENUM_ITEM:
+ while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, in_param))
+ did_something = true;
+ children[0]->detectSignWidth(width_hint, sign_hint);
+ if (children.size() > 1 && children[1]->type == AST_RANGE) {
+ while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param))
+ did_something = true;
+ if (!children[1]->range_valid)
+ log_file_error(filename, location.first_line, "Non-constant width range on enum item decl.\n");
width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1);
}
break;
@@ -745,7 +785,6 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
current_filename = filename;
- set_line_num(linenum);
if (type == AST_MODULE)
current_scope.clear();
@@ -754,7 +793,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (type == AST_DEFPARAM && !children.empty())
{
if (children[0]->type != AST_IDENTIFIER)
- log_file_error(filename, linenum, "Module name in defparam contains non-constant expressions!\n");
+ log_file_error(filename, location.first_line, "Module name in defparam contains non-constant expressions!\n");
string modname, paramname = children[0]->str;
@@ -771,12 +810,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
if (pos == std::string::npos)
- log_file_error(filename, linenum, "Can't find object for defparam `%s`!\n", RTLIL::unescape_id(paramname).c_str());
+ log_file_error(filename, location.first_line, "Can't find object for defparam `%s`!\n", RTLIL::unescape_id(paramname).c_str());
paramname = "\\" + paramname.substr(pos+1);
if (current_scope.at(modname)->type != AST_CELL)
- log_file_error(filename, linenum, "Defparam argument `%s . %s` does not match a cell!\n",
+ log_file_error(filename, location.first_line, "Defparam argument `%s . %s` does not match a cell!\n",
RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str());
AstNode *paraset = new AstNode(AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : NULL);
@@ -802,10 +841,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
log_assert(children.size() >= 1);
log_assert(children[0]->type == AST_WIRETYPE);
if (!current_scope.count(children[0]->str))
- log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str());
+ log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str());
AstNode *resolved_type = current_scope.at(children[0]->str);
if (resolved_type->type != AST_TYPEDEF)
- log_file_error(filename, linenum, "`%s' does not name a type\n", children[0]->str.c_str());
+ log_file_error(filename, location.first_line, "`%s' does not name a type\n", children[0]->str.c_str());
log_assert(resolved_type->children.size() == 1);
AstNode *templ = resolved_type->children[0];
// Remove type reference
@@ -827,6 +866,63 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
range_swapped = templ->range_swapped;
range_left = templ->range_left;
range_right = templ->range_right;
+ attributes["\\wiretype"] = mkconst_str(resolved_type->str);
+ //check if enum
+ if (templ->attributes.count("\\enum_type")){
+ //get reference to enum node:
+ std::string enum_type = templ->attributes["\\enum_type"]->str.c_str();
+ // log("enum_type=%s (count=%lu)\n", enum_type.c_str(), current_scope.count(enum_type));
+ // log("current scope:\n");
+ // for (auto &it : current_scope)
+ // log(" %s\n", it.first.c_str());
+ log_assert(current_scope.count(enum_type) == 1);
+ AstNode *enum_node = current_scope.at(enum_type);
+ log_assert(enum_node->type == AST_ENUM);
+ //get width from 1st enum item:
+ log_assert(enum_node->children.size() >= 1);
+ AstNode *enum_item0 = enum_node->children[0];
+ log_assert(enum_item0->type == AST_ENUM_ITEM);
+ int width;
+ if (!enum_item0->range_valid)
+ width = 1;
+ else if (enum_item0->range_swapped)
+ width = enum_item0->range_right - enum_item0->range_left + 1;
+ else
+ width = enum_item0->range_left - enum_item0->range_right + 1;
+ log_assert(width > 0);
+ //add declared enum items:
+ for (auto enum_item : enum_node->children){
+ log_assert(enum_item->type == AST_ENUM_ITEM);
+ //get is_signed
+ bool is_signed;
+ if (enum_item->children.size() == 1){
+ is_signed = false;
+ } else if (enum_item->children.size() == 2){
+ log_assert(enum_item->children[1]->type == AST_RANGE);
+ is_signed = enum_item->children[1]->is_signed;
+ } else {
+ log_error("enum_item children size==%lu, expected 1 or 2 for %s (%s)\n",
+ enum_item->children.size(),
+ enum_item->str.c_str(), enum_node->str.c_str()
+ );
+ }
+ //start building attribute string
+ std::string enum_item_str = "\\enum_";
+ enum_item_str.append(std::to_string(width));
+ enum_item_str.append("_");
+ //get enum item value
+ if(enum_item->children[0]->type != AST_CONSTANT){
+ log_error("expected const, got %s for %s (%s)\n",
+ type2str(enum_item->children[0]->type).c_str(),
+ enum_item->str.c_str(), enum_node->str.c_str()
+ );
+ }
+ int val = enum_item->children[0]->asInt(is_signed);
+ enum_item_str.append(std::to_string(val));
+ //set attribute for available val to enum item name mappings
+ attributes[enum_item_str.c_str()] = mkconst_str(enum_item->str);
+ }
+ }
// Insert clones children from template at beginning
for (int i = 0; i < GetSize(templ->children); i++)
@@ -851,10 +947,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
log_assert(children.size() == 2);
log_assert(children[1]->type == AST_WIRETYPE);
if (!current_scope.count(children[1]->str))
- log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str());
+ log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str());
AstNode *resolved_type = current_scope.at(children[1]->str);
if (resolved_type->type != AST_TYPEDEF)
- log_file_error(filename, linenum, "`%s' does not name a type\n", children[1]->str.c_str());
+ log_file_error(filename, location.first_line, "`%s' does not name a type\n", children[1]->str.c_str());
log_assert(resolved_type->children.size() == 1);
AstNode *templ = resolved_type->children[0];
delete children[1];
@@ -864,7 +960,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
if (templ->type == AST_MEMORY)
- log_file_error(filename, linenum, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str());
+ log_file_error(filename, location.first_line, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str());
is_signed = templ->is_signed;
is_string = templ->is_string;
is_custom_type = templ->is_custom_type;
@@ -873,6 +969,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
range_swapped = templ->range_swapped;
range_left = templ->range_left;
range_right = templ->range_right;
+ attributes["\\wiretype"] = mkconst_str(resolved_type->str);
for (auto template_child : templ->children)
children.push_back(template_child->clone());
did_something = true;
@@ -884,7 +981,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (type == AST_PREFIX) {
if (children[0]->type != AST_CONSTANT) {
// dumpAst(NULL, "> ");
- log_file_error(filename, linenum, "Index in generate block prefix syntax is not constant!\n");
+ log_file_error(filename, location.first_line, "Index in generate block prefix syntax is not constant!\n");
}
if (children[1]->type == AST_PREFIX)
children[1]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param);
@@ -900,9 +997,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
// evaluate TO_BITS nodes
if (type == AST_TO_BITS) {
if (children[0]->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Left operand of to_bits expression is not constant!\n");
+ log_file_error(filename, location.first_line, "Left operand of to_bits expression is not constant!\n");
if (children[1]->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Right operand of to_bits expression is not constant!\n");
+ log_file_error(filename, location.first_line, "Right operand of to_bits expression is not constant!\n");
RTLIL::Const new_value = children[1]->bitsAsConst(children[0]->bitsAsConst().as_int(), children[1]->is_signed);
newNode = mkconst_bits(new_value.bits, children[1]->is_signed);
goto apply_newNode;
@@ -966,7 +1063,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
multirange_dimensions.clear();
for (auto range : children[1]->children) {
if (!range->range_valid)
- log_file_error(filename, linenum, "Non-constant range on memory decl.\n");
+ log_file_error(filename, location.first_line, "Non-constant range on memory decl.\n");
multirange_dimensions.push_back(min(range->range_left, range->range_right));
multirange_dimensions.push_back(max(range->range_left, range->range_right) - min(range->range_left, range->range_right) + 1);
total_size *= multirange_dimensions.back();
@@ -984,7 +1081,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
for (int i = 0; 2*i < GetSize(id2ast->multirange_dimensions); i++)
{
if (GetSize(children[0]->children) < i)
- log_file_error(filename, linenum, "Insufficient number of array indices for %s.\n", log_id(str));
+ log_file_error(filename, location.first_line, "Insufficient number of array indices for %s.\n", log_id(str));
AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone();
@@ -1010,14 +1107,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
// trim/extend parameters
- if (type == AST_PARAMETER || type == AST_LOCALPARAM) {
+ if (type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_ENUM_ITEM) {
if (children.size() > 1 && children[1]->type == AST_RANGE) {
if (!children[1]->range_valid)
- log_file_error(filename, linenum, "Non-constant width range on parameter decl.\n");
+ log_file_error(filename, location.first_line, "Non-constant width range on parameter decl.\n");
int width = std::abs(children[1]->range_left - children[1]->range_right) + 1;
if (children[0]->type == AST_REALVALUE) {
RTLIL::Const constvalue = children[0]->realAsConst(width);
- log_file_warning(filename, linenum, "converting real value %e to binary %s.\n",
+ log_file_warning(filename, location.first_line, "converting real value %e to binary %s.\n",
children[0]->realvalue, log_signal(constvalue));
delete children[0];
children[0] = mkconst_bits(constvalue.bits, sign_hint);
@@ -1051,9 +1148,34 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (type == AST_IDENTIFIER) {
if (current_scope.count(str) == 0) {
for (auto node : current_ast_mod->children) {
- if ((node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
- node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION) && str == node->str) {
+ //log("looking at mod scope child %s\n", type2str(node->type).c_str());
+ switch (node->type) {
+ case AST_PARAMETER:
+ case AST_LOCALPARAM:
+ case AST_WIRE:
+ case AST_AUTOWIRE:
+ case AST_GENVAR:
+ case AST_MEMORY:
+ case AST_FUNCTION:
+ case AST_TASK:
+ case AST_DPI_FUNCTION:
+ //log("found child %s, %s\n", type2str(node->type).c_str(), node->str.c_str());
+ if (str == node->str) {
+ //log("add %s, type %s to scope\n", str.c_str(), type2str(node->type).c_str());
+ current_scope[node->str] = node;
+ }
+ break;
+ case AST_ENUM:
current_scope[node->str] = node;
+ for (auto enum_node : node->children) {
+ log_assert(enum_node->type==AST_ENUM_ITEM);
+ if (str == enum_node->str) {
+ //log("\nadding enum item %s to scope\n", str.c_str());
+ current_scope[str] = enum_node;
+ }
+ }
+ break;
+ default:
break;
}
}
@@ -1066,7 +1188,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
current_scope[str] = auto_wire;
did_something = true;
} else {
- log_file_error(filename, linenum, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str());
}
}
if (id2ast != current_scope[str]) {
@@ -1079,7 +1201,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue)
{
if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1)
- log_file_error(filename, linenum, "Invalid bit-select on memory access!\n");
+ log_file_error(filename, location.first_line, "Invalid bit-select on memory access!\n");
int mem_width, mem_size, addr_bits;
id2ast->meminfo(mem_width, mem_size, addr_bits);
@@ -1091,7 +1213,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
std::swap(data_range_left, data_range_right);
std::stringstream sstr;
- sstr << "$mem2bits$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++);
+ sstr << "$mem2bits$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
std::string wire_id = sstr.str();
AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(data_range_left, true), mkconst_int(data_range_right, true)));
@@ -1132,7 +1254,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
if (type == AST_WHILE)
- log_file_error(filename, linenum, "While loops are only allowed in constant functions!\n");
+ log_file_error(filename, location.first_line, "While loops are only allowed in constant functions!\n");
if (type == AST_REPEAT)
{
@@ -1143,7 +1265,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
while (count->simplify(true, false, false, stage, 32, true, false)) { }
if (count->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Repeat loops outside must have constant repeat counts!\n");
+ log_file_error(filename, location.first_line, "Repeat loops outside must have constant repeat counts!\n");
// convert to a block with the body repeated n times
type = AST_BLOCK;
@@ -1169,24 +1291,24 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
body_ast = body_ast->children.at(0);
if (init_ast->type != AST_ASSIGN_EQ)
- log_file_error(filename, linenum, "Unsupported 1st expression of generate for-loop!\n");
+ log_file_error(filename, location.first_line, "Unsupported 1st expression of generate for-loop!\n");
if (next_ast->type != AST_ASSIGN_EQ)
- log_file_error(filename, linenum, "Unsupported 3rd expression of generate for-loop!\n");
+ log_file_error(filename, location.first_line, "Unsupported 3rd expression of generate for-loop!\n");
if (type == AST_GENFOR) {
if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_GENVAR)
- log_file_error(filename, linenum, "Left hand side of 1st expression of generate for-loop is not a gen var!\n");
+ log_file_error(filename, location.first_line, "Left hand side of 1st expression of generate for-loop is not a gen var!\n");
if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_GENVAR)
- log_file_error(filename, linenum, "Left hand side of 3rd expression of generate for-loop is not a gen var!\n");
+ log_file_error(filename, location.first_line, "Left hand side of 3rd expression of generate for-loop is not a gen var!\n");
} else {
if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_WIRE)
- log_file_error(filename, linenum, "Left hand side of 1st expression of generate for-loop is not a register!\n");
+ log_file_error(filename, location.first_line, "Left hand side of 1st expression of generate for-loop is not a register!\n");
if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_WIRE)
- log_file_error(filename, linenum, "Left hand side of 3rd expression of generate for-loop is not a register!\n");
+ log_file_error(filename, location.first_line, "Left hand side of 3rd expression of generate for-loop is not a register!\n");
}
if (init_ast->children[0]->id2ast != next_ast->children[0]->id2ast)
- log_file_error(filename, linenum, "Incompatible left-hand sides in 1st and 3rd expression of generate for-loop!\n");
+ log_file_error(filename, location.first_line, "Incompatible left-hand sides in 1st and 3rd expression of generate for-loop!\n");
// eval 1st expression
AstNode *varbuf = init_ast->children[1]->clone();
@@ -1198,19 +1320,25 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
if (varbuf->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Right hand side of 1st expression of generate for-loop is not constant!\n");
-
- varbuf = new AstNode(AST_LOCALPARAM, varbuf);
- varbuf->str = init_ast->children[0]->str;
+ log_file_error(filename, location.first_line, "Right hand side of 1st expression of generate for-loop is not constant!\n");
auto resolved = current_scope.at(init_ast->children[0]->str);
if (resolved->range_valid) {
- varbuf->range_left = resolved->range_left;
- varbuf->range_right = resolved->range_right;
- varbuf->range_swapped = resolved->range_swapped;
- varbuf->range_valid = resolved->range_valid;
+ int const_size = varbuf->range_left - varbuf->range_right;
+ int resolved_size = resolved->range_left - resolved->range_right;
+ if (const_size < resolved_size) {
+ for (int i = const_size; i < resolved_size; i++)
+ varbuf->bits.push_back(resolved->is_signed ? varbuf->bits.back() : State::S0);
+ varbuf->range_left = resolved->range_left;
+ varbuf->range_right = resolved->range_right;
+ varbuf->range_swapped = resolved->range_swapped;
+ varbuf->range_valid = resolved->range_valid;
+ }
}
+ varbuf = new AstNode(AST_LOCALPARAM, varbuf);
+ varbuf->str = init_ast->children[0]->str;
+
AstNode *backup_scope_varbuf = current_scope[varbuf->str];
current_scope[varbuf->str] = varbuf;
@@ -1233,7 +1361,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
if (buf->type != AST_CONSTANT)
- log_file_error(filename, linenum, "2nd expression of generate for-loop is not constant!\n");
+ log_file_error(filename, location.first_line, "2nd expression of generate for-loop is not constant!\n");
if (buf->integer == 0) {
delete buf;
@@ -1249,7 +1377,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
buf = new AstNode(AST_GENBLOCK, body_ast->clone());
if (buf->str.empty()) {
std::stringstream sstr;
- sstr << "$genblock$" << filename << ":" << linenum << "$" << (autoidx++);
+ sstr << "$genblock$" << filename << ":" << location.first_line << "$" << (autoidx++);
buf->str = sstr.str();
}
std::map<std::string, std::string> name_map;
@@ -1279,7 +1407,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
if (buf->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Right hand side of 3rd expression of generate for-loop is not constant!\n");
+ log_file_error(filename, location.first_line, "Right hand side of 3rd expression of generate for-loop is not constant (%s)!\n", type2str(buf->type).c_str());
delete varbuf->children[0];
varbuf->children[0] = buf;
@@ -1303,7 +1431,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
{
for (size_t i = 0; i < children.size(); i++)
if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF)
- log_file_error(children[i]->filename, children[i]->linenum, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n");
+ log_file_error(children[i]->filename, children[i]->location.first_line, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n");
}
// transform block with name
@@ -1351,7 +1479,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (buf->type != AST_CONSTANT) {
// for (auto f : log_files)
// dumpAst(f, "verilog-ast> ");
- log_file_error(filename, linenum, "Condition for generate if is not constant!\n");
+ log_file_error(filename, location.first_line, "Condition for generate if is not constant!\n");
}
if (buf->asBool() != 0) {
delete buf;
@@ -1392,7 +1520,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (buf->type != AST_CONSTANT) {
// for (auto f : log_files)
// dumpAst(f, "verilog-ast> ");
- log_file_error(filename, linenum, "Condition for generate case is not constant!\n");
+ log_file_error(filename, location.first_line, "Condition for generate case is not constant!\n");
}
bool ref_signed = buf->is_signed;
@@ -1426,7 +1554,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (buf->type != AST_CONSTANT) {
// for (auto f : log_files)
// dumpAst(f, "verilog-ast> ");
- log_file_error(filename, linenum, "Expression in generate case is not constant!\n");
+ log_file_error(filename, location.first_line, "Expression in generate case is not constant!\n");
}
bool is_selected = RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool();
@@ -1467,7 +1595,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (type == AST_CELLARRAY)
{
if (!children.at(0)->range_valid)
- log_file_error(filename, linenum, "Non-constant array range on cell array.\n");
+ log_file_error(filename, location.first_line, "Non-constant array range on cell array.\n");
newNode = new AstNode(AST_GENBLOCK);
int num = max(children.at(0)->range_left, children.at(0)->range_right) - min(children.at(0)->range_left, children.at(0)->range_right) + 1;
@@ -1478,7 +1606,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
newNode->children.push_back(new_cell);
new_cell->str += stringf("[%d]", idx);
if (new_cell->type == AST_PRIMITIVE) {
- log_file_error(filename, linenum, "Cell arrays of primitives are currently not supported.\n");
+ log_file_error(filename, location.first_line, "Cell arrays of primitives are currently not supported.\n");
} else {
log_assert(new_cell->children.at(0)->type == AST_CELLTYPE);
new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str.c_str());
@@ -1492,7 +1620,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (type == AST_PRIMITIVE)
{
if (children.size() < 2)
- log_file_error(filename, linenum, "Insufficient number of arguments for primitive `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Insufficient number of arguments for primitive `%s'!\n", str.c_str());
std::vector<AstNode*> children_list;
for (auto child : children) {
@@ -1507,7 +1635,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (str == "bufif0" || str == "bufif1" || str == "notif0" || str == "notif1")
{
if (children_list.size() != 3)
- log_file_error(filename, linenum, "Invalid number of arguments for primitive `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Invalid number of arguments for primitive `%s'!\n", str.c_str());
std::vector<RTLIL::State> z_const(1, RTLIL::State::Sz);
@@ -1594,7 +1722,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
while (left_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { }
while (right_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { }
if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
result_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;
}
did_something = true;
@@ -1616,7 +1744,7 @@ skip_dynamic_range_lvalue_expansion:;
if (stage > 1 && (type == AST_ASSERT || type == AST_ASSUME || type == AST_LIVE || type == AST_FAIR || type == AST_COVER) && current_block != NULL)
{
std::stringstream sstr;
- sstr << "$formal$" << filename << ":" << linenum << "$" << (autoidx++);
+ sstr << "$formal$" << filename << ":" << location.first_line << "$" << (autoidx++);
std::string id_check = sstr.str() + "_CHECK", id_en = sstr.str() + "_EN";
AstNode *wire_check = new AstNode(AST_WIRE);
@@ -1683,6 +1811,7 @@ skip_dynamic_range_lvalue_expansion:;
newNode->children.push_back(assign_en);
AstNode *assertnode = new AstNode(type);
+ assertnode->location = location;
assertnode->str = str;
assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
@@ -1724,7 +1853,7 @@ skip_dynamic_range_lvalue_expansion:;
newNode = new AstNode(AST_BLOCK);
AstNode *wire_tmp = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(width_hint-1, true), mkconst_int(0, true)));
- wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", filename.c_str(), linenum, autoidx++);
+ wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", filename.c_str(), location.first_line, autoidx++);
current_ast_mod->children.push_back(wire_tmp);
current_scope[wire_tmp->str] = wire_tmp;
wire_tmp->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
@@ -1762,7 +1891,7 @@ skip_dynamic_range_lvalue_expansion:;
(children[0]->children.size() == 1 || children[0]->children.size() == 2) && children[0]->children[0]->type == AST_RANGE)
{
std::stringstream sstr;
- sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
+ sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN";
int mem_width, mem_size, addr_bits;
@@ -1898,7 +2027,7 @@ skip_dynamic_range_lvalue_expansion:;
while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
+ log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;
assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),
@@ -1988,11 +2117,11 @@ skip_dynamic_range_lvalue_expansion:;
int num_steps = 1;
if (GetSize(children) != 1 && GetSize(children) != 2)
- log_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 2.\n",
+ log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
if (!current_always_clocked)
- log_file_error(filename, linenum, "System function %s is only allowed in clocked blocks.\n",
+ log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n",
RTLIL::unescape_id(str).c_str());
if (GetSize(children) == 2)
@@ -2000,7 +2129,7 @@ skip_dynamic_range_lvalue_expansion:;
AstNode *buf = children[1]->clone();
while (buf->simplify(true, false, false, stage, -1, false, false)) { }
if (buf->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());
num_steps = buf->asInt(true);
delete buf;
@@ -2027,7 +2156,7 @@ skip_dynamic_range_lvalue_expansion:;
AstNode *reg = new AstNode(AST_WIRE, new AstNode(AST_RANGE,
mkconst_int(width_hint-1, true), mkconst_int(0, true)));
- reg->str = stringf("$past$%s:%d$%d$%d", filename.c_str(), linenum, myidx, i);
+ reg->str = stringf("$past$%s:%d$%d$%d", filename.c_str(), location.first_line, myidx, i);
reg->is_reg = true;
current_ast_mod->children.push_back(reg);
@@ -2062,11 +2191,11 @@ skip_dynamic_range_lvalue_expansion:;
if (str == "\\$stable" || str == "\\$rose" || str == "\\$fell" || str == "\\$changed")
{
if (GetSize(children) != 1)
- log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n",
+ log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
if (!current_always_clocked)
- log_file_error(filename, linenum, "System function %s is only allowed in clocked blocks.\n",
+ log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n",
RTLIL::unescape_id(str).c_str());
AstNode *present = children.at(0)->clone();
@@ -2104,13 +2233,13 @@ skip_dynamic_range_lvalue_expansion:;
if (str == "\\$clog2")
{
if (children.size() != 1)
- log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n",
+ log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
AstNode *buf = children[0]->clone();
while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
if (buf->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());
RTLIL::Const arg_value = buf->bitsAsConst();
if (arg_value.as_bool())
@@ -2129,11 +2258,11 @@ skip_dynamic_range_lvalue_expansion:;
if (str == "\\$size" || str == "\\$bits")
{
if (str == "\\$bits" && children.size() != 1)
- log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n",
+ log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
if (str == "\\$size" && children.size() != 1 && children.size() != 2)
- log_file_error(filename, linenum, "System function %s got %d arguments, expected 1 or 2.\n",
+ log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
int dim = 1;
@@ -2157,7 +2286,7 @@ skip_dynamic_range_lvalue_expansion:;
if (id_ast == NULL && current_scope.count(buf->str))
id_ast = current_scope.at(buf->str);
if (!id_ast)
- log_file_error(filename, linenum, "Failed to resolve identifier %s for width detection!\n", buf->str.c_str());
+ log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", buf->str.c_str());
if (id_ast->type == AST_MEMORY) {
// We got here only if the argument is a memory
// Otherwise $size() and $bits() return the expression width
@@ -2165,15 +2294,15 @@ skip_dynamic_range_lvalue_expansion:;
if (str == "\\$bits") {
if (mem_range->type == AST_RANGE) {
if (!mem_range->range_valid)
- log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", buf->str.c_str());
+ log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str());
mem_depth = mem_range->range_left - mem_range->range_right + 1;
} else
- log_file_error(filename, linenum, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str());
+ log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str());
} else {
// $size()
if (mem_range->type == AST_RANGE) {
if (!mem_range->range_valid)
- log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", buf->str.c_str());
+ log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str());
int dims;
if (id_ast->multirange_dimensions.empty())
dims = 1;
@@ -2184,9 +2313,9 @@ skip_dynamic_range_lvalue_expansion:;
else if (dim <= dims) {
width_hint = id_ast->multirange_dimensions[2*dim-1];
} else if ((dim > dims+1) || (dim < 0))
- log_file_error(filename, linenum, "Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, buf->str.c_str(), dims+1);
+ log_file_error(filename, location.first_line, "Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, buf->str.c_str(), dims+1);
} else
- log_file_error(filename, linenum, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str());
+ log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str());
}
}
}
@@ -2207,18 +2336,18 @@ skip_dynamic_range_lvalue_expansion:;
if (func_with_two_arguments) {
if (children.size() != 2)
- log_file_error(filename, linenum, "System function %s got %d arguments, expected 2.\n",
+ log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 2.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
} else {
if (children.size() != 1)
- log_file_error(filename, linenum, "System function %s got %d arguments, expected 1.\n",
+ log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
}
if (children.size() >= 1) {
while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
if (!children[0]->isConst())
- log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant argument.\n",
+ log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant argument.\n",
RTLIL::unescape_id(str).c_str());
int child_width_hint = width_hint;
bool child_sign_hint = sign_hint;
@@ -2229,7 +2358,7 @@ skip_dynamic_range_lvalue_expansion:;
if (children.size() >= 2) {
while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
if (!children[1]->isConst())
- log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant argument.\n",
+ log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant argument.\n",
RTLIL::unescape_id(str).c_str());
int child_width_hint = width_hint;
bool child_sign_hint = sign_hint;
@@ -2272,7 +2401,7 @@ skip_dynamic_range_lvalue_expansion:;
AstNode *node_string = children[0];
while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
if (node_string->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str());
std::string sformat = node_string->bitsAsConst().decode_string();
std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint);
newNode = AstNode::mkconst_str(sout);
@@ -2293,14 +2422,14 @@ skip_dynamic_range_lvalue_expansion:;
for (int i = 2; i < GetSize(dpi_decl->children); i++)
{
if (i-2 >= GetSize(children))
- log_file_error(filename, linenum, "Insufficient number of arguments in DPI function call.\n");
+ log_file_error(filename, location.first_line, "Insufficient number of arguments in DPI function call.\n");
argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str));
args.push_back(children.at(i-2)->clone());
while (args.back()->simplify(true, false, false, stage, -1, false, true)) { }
if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE)
- log_file_error(filename, linenum, "Failed to evaluate DPI function with non-constant argument.\n");
+ log_file_error(filename, location.first_line, "Failed to evaluate DPI function with non-constant argument.\n");
}
newNode = dpi_call(rtype, fname, argtypes, args);
@@ -2312,7 +2441,7 @@ skip_dynamic_range_lvalue_expansion:;
}
if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION)
- log_file_error(filename, linenum, "Can't resolve function name `%s'.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Can't resolve function name `%s'.\n", str.c_str());
}
if (type == AST_TCALL)
@@ -2320,26 +2449,26 @@ skip_dynamic_range_lvalue_expansion:;
if (str == "$finish" || str == "$stop")
{
if (!current_always || current_always->type != AST_INITIAL)
- log_file_error(filename, linenum, "System task `%s' outside initial block is unsupported.\n", str.c_str());
+ log_file_error(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str());
- log_file_error(filename, linenum, "System task `%s' executed.\n", str.c_str());
+ log_file_error(filename, location.first_line, "System task `%s' executed.\n", str.c_str());
}
if (str == "\\$readmemh" || str == "\\$readmemb")
{
if (GetSize(children) < 2 || GetSize(children) > 4)
- log_file_error(filename, linenum, "System function %s got %d arguments, expected 2-4.\n",
+ log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 2-4.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
AstNode *node_filename = children[0]->clone();
while (node_filename->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
if (node_filename->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str());
AstNode *node_memory = children[1]->clone();
while (node_memory->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
if (node_memory->type != AST_IDENTIFIER || node_memory->id2ast == nullptr || node_memory->id2ast->type != AST_MEMORY)
- log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str());
int start_addr = -1, finish_addr = -1;
@@ -2347,7 +2476,7 @@ skip_dynamic_range_lvalue_expansion:;
AstNode *node_addr = children[2]->clone();
while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
if (node_addr->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str());
start_addr = int(node_addr->asInt(false));
}
@@ -2355,7 +2484,7 @@ skip_dynamic_range_lvalue_expansion:;
AstNode *node_addr = children[3]->clone();
while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
if (node_addr->type != AST_CONSTANT)
- log_file_error(filename, linenum, "Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str());
finish_addr = int(node_addr->asInt(false));
}
@@ -2383,13 +2512,13 @@ skip_dynamic_range_lvalue_expansion:;
}
if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK)
- log_file_error(filename, linenum, "Can't resolve task name `%s'.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Can't resolve task name `%s'.\n", str.c_str());
}
AstNode *decl = current_scope[str];
std::stringstream sstr;
- sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++) << "$";
+ sstr << "$func$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++) << "$";
std::string prefix = sstr.str();
bool recommend_const_eval = false;
@@ -2411,9 +2540,9 @@ skip_dynamic_range_lvalue_expansion:;
}
if (in_param)
- log_file_error(filename, linenum, "Non-constant function call in constant expression.\n");
+ log_file_error(filename, location.first_line, "Non-constant function call in constant expression.\n");
if (require_const_eval)
- log_file_error(filename, linenum, "Function %s can only be called with constant arguments.\n", str.c_str());
+ log_file_error(filename, location.first_line, "Function %s can only be called with constant arguments.\n", str.c_str());
}
size_t arg_count = 0;
@@ -2517,7 +2646,7 @@ skip_dynamic_range_lvalue_expansion:;
}
for (auto child : decl->children)
- if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM)
+ if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM || child->type == AST_ENUM_ITEM)
{
AstNode *wire = nullptr;
@@ -2535,7 +2664,7 @@ skip_dynamic_range_lvalue_expansion:;
goto tcall_incompatible_wires;
} else {
tcall_incompatible_wires:
- log_file_error(filename, linenum, "Incompatible re-declaration of wire %s.\n", child->str.c_str());
+ log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", child->str.c_str());
}
}
}
@@ -2548,6 +2677,9 @@ skip_dynamic_range_lvalue_expansion:;
wire->is_output = false;
wire->is_reg = true;
wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
+ if (child->type == AST_ENUM_ITEM)
+ wire->attributes["\\enum_base_type"] = child->attributes["\\enum_base_type"];
+
wire_cache[child->str] = wire;
current_ast_mod->children.push_back(wire);
@@ -2623,7 +2755,7 @@ replace_fcall_later:;
switch (type)
{
case AST_IDENTIFIER:
- if (current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM)) {
+ if (current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM || current_scope[str]->type == AST_ENUM_ITEM)) {
if (current_scope[str]->children[0]->type == AST_CONSTANT) {
if (children.size() != 0 && children[0]->type == AST_RANGE && children[0]->range_valid) {
std::vector<RTLIL::State> data;
@@ -2886,7 +3018,7 @@ apply_newNode:
// newNode->dumpAst(stderr, "+ ");
log_assert(newNode != NULL);
newNode->filename = filename;
- newNode->linenum = linenum;
+ newNode->location = location;
newNode->cloneInto(this);
delete newNode;
did_something = true;
@@ -2922,10 +3054,20 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m
std::ifstream f;
f.open(mem_filename.c_str());
- yosys_input_files.insert(mem_filename);
-
- if (f.fail())
- log_file_error(filename, linenum, "Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str());
+ if (f.fail()) {
+#ifdef _WIN32
+ char slash = '\\';
+#else
+ char slash = '/';
+#endif
+ std::string path = filename.substr(0, filename.find_last_of(slash)+1);
+ f.open(path + mem_filename.c_str());
+ yosys_input_files.insert(path + mem_filename);
+ } else {
+ yosys_input_files.insert(mem_filename);
+ }
+ if (f.fail() || GetSize(mem_filename) == 0)
+ log_file_error(filename, location.first_line, "Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str());
log_assert(GetSize(memory->children) == 2 && memory->children[1]->type == AST_RANGE && memory->children[1]->range_valid);
int range_left = memory->children[1]->range_left, range_right = memory->children[1]->range_right;
@@ -2971,7 +3113,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m
char *endptr;
cursor = strtol(nptr, &endptr, 16);
if (!*nptr || *endptr)
- log_file_error(filename, linenum, "Can not parse address `%s` for %s.\n", nptr, str.c_str());
+ log_file_error(filename, location.first_line, "Can not parse address `%s` for %s.\n", nptr, str.c_str());
continue;
}
@@ -3041,14 +3183,6 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
current_ast_mod->children.push_back(p);
str = p->str;
id2ast = p;
-
- auto resolved = current_scope.at(index_var);
- if (resolved->range_valid) {
- p->range_left = resolved->range_left;
- p->range_right = resolved->range_right;
- p->range_swapped = resolved->range_swapped;
- p->range_valid = resolved->range_valid;
- }
}
}
@@ -3060,7 +3194,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
for (size_t i = 0; i < children.size(); i++) {
AstNode *child = children[i];
if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM ||
- child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL || child->type == AST_TYPEDEF) {
+ child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL || child->type == AST_TYPEDEF || child->type == AST_ENUM_ITEM) {
if (backup_name_map.size() == 0)
backup_name_map = name_map;
std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix;
@@ -3079,6 +3213,27 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
child->str = new_name;
current_scope[new_name] = child;
}
+ if (child->type == AST_ENUM){
+ current_scope[child->str] = child;
+ for (auto enode : child->children){
+ log_assert(enode->type == AST_ENUM_ITEM);
+ if (backup_name_map.size() == 0)
+ backup_name_map = name_map;
+ std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix;
+ size_t pos = enode->str.rfind('.');
+ if (pos == std::string::npos)
+ pos = enode->str[0] == '\\' && prefix[0] == '\\' ? 1 : 0;
+ else
+ pos = pos + 1;
+ new_name = enode->str.substr(0, pos) + new_name + enode->str.substr(pos);
+ if (new_name[0] != '$' && new_name[0] != '\\')
+ new_name = prefix[0] + new_name;
+ name_map[enode->str] = new_name;
+
+ enode->str = new_name;
+ current_scope[new_name] = enode;
+ }
+ }
}
for (size_t i = 0; i < children.size(); i++) {
@@ -3133,7 +3288,7 @@ static void mark_memories_assign_lhs_complex(dict<AstNode*, pool<std::string>> &
if (that->type == AST_IDENTIFIER && that->id2ast && that->id2ast->type == AST_MEMORY) {
AstNode *mem = that->id2ast;
if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_CMPLX_LHS))
- mem2reg_places[mem].insert(stringf("%s:%d", that->filename.c_str(), that->linenum));
+ mem2reg_places[mem].insert(stringf("%s:%d", that->filename.c_str(), that->location.first_line));
mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CMPLX_LHS;
}
}
@@ -3161,14 +3316,14 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg
// activate mem2reg if this is assigned in an async proc
if (flags & AstNode::MEM2REG_FL_ASYNC) {
if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ASYNC))
- mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
+ mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line));
mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ASYNC;
}
// remember if this is assigned blocking (=)
if (type == AST_ASSIGN_EQ) {
if (!(proc_flags[mem] & AstNode::MEM2REG_FL_EQ1))
- mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
+ mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line));
proc_flags[mem] |= AstNode::MEM2REG_FL_EQ1;
}
@@ -3185,11 +3340,11 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg
// remember where this is
if (flags & MEM2REG_FL_INIT) {
if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_INIT))
- mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
+ mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line));
mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_INIT;
} else {
if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ELSE))
- mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
+ mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line));
mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ELSE;
}
}
@@ -3203,7 +3358,7 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg
// flag if used after blocking assignment (in same proc)
if ((proc_flags[mem] & AstNode::MEM2REG_FL_EQ1) && !(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_EQ2)) {
- mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
+ mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line));
mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_EQ2;
}
}
@@ -3272,7 +3427,7 @@ bool AstNode::mem2reg_check(pool<AstNode*> &mem2reg_set)
return false;
if (children.empty() || children[0]->type != AST_RANGE || GetSize(children[0]->children) != 1)
- log_file_error(filename, linenum, "Invalid array access.\n");
+ log_file_error(filename, location.first_line, "Invalid array access.\n");
return true;
}
@@ -3364,7 +3519,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
children[0]->children[0]->children[0]->type != AST_CONSTANT)
{
std::stringstream sstr;
- sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
+ sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
int mem_width, mem_size, addr_bits;
@@ -3443,7 +3598,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
else
{
std::stringstream sstr;
- sstr << "$mem2reg_rd$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++);
+ sstr << "$mem2reg_rd$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
int mem_width, mem_size, addr_bits;
@@ -3587,13 +3742,13 @@ void AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &varia
int offset = variables.at(str).offset, width = variables.at(str).val.bits.size();
if (!children.empty()) {
if (children.size() != 1 || children.at(0)->type != AST_RANGE)
- log_file_error(filename, linenum, "Memory access in constant function is not supported\n%s:%d: ...called from here.\n",
- fcall->filename.c_str(), fcall->linenum);
+ log_file_error(filename, location.first_line, "Memory access in constant function is not supported\n%s:%d.%d-%d.%d: ...called from here.\n",
+ fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
children.at(0)->replace_variables(variables, fcall);
while (simplify(true, false, false, 1, -1, false, true)) { }
if (!children.at(0)->range_valid)
- log_file_error(filename, linenum, "Non-constant range\n%s:%d: ... called from here.\n",
- fcall->filename.c_str(), fcall->linenum);
+ log_file_error(filename, location.first_line, "Non-constant range\n%s:%d.%d-%d.%d: ... called from here.\n",
+ fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
offset = min(children.at(0)->range_left, children.at(0)->range_right);
width = min(std::abs(children.at(0)->range_left - children.at(0)->range_right) + 1, width);
}
@@ -3624,8 +3779,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)
{
while (child->simplify(true, false, false, 1, -1, false, true)) { }
if (!child->range_valid)
- log_file_error(child->filename, child->linenum, "Can't determine size of variable %s\n%s:%d: ... called from here.\n",
- child->str.c_str(), fcall->filename.c_str(), fcall->linenum);
+ log_file_error(child->filename, child->location.first_line, "Can't determine size of variable %s\n%s:%d.%d-%d.%d: ... called from here.\n",
+ child->str.c_str(), fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
variables[child->str].val = RTLIL::Const(RTLIL::State::Sx, abs(child->range_left - child->range_right)+1);
variables[child->str].offset = min(child->range_left, child->range_right);
variables[child->str].is_signed = child->is_signed;
@@ -3664,24 +3819,24 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)
continue;
if (stmt->children.at(1)->type != AST_CONSTANT)
- log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here. X\n",
- fcall->filename.c_str(), fcall->linenum);
+ log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here. X\n",
+ fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
if (stmt->children.at(0)->type != AST_IDENTIFIER)
- log_file_error(stmt->filename, stmt->linenum, "Unsupported composite left hand side in constant function\n%s:%d: ... called from here.\n",
- fcall->filename.c_str(), fcall->linenum);
+ log_file_error(stmt->filename, stmt->location.first_line, "Unsupported composite left hand side in constant function\n%s:%d.%d-%d.%d: ... called from here.\n",
+ fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
if (!variables.count(stmt->children.at(0)->str))
- log_file_error(stmt->filename, stmt->linenum, "Assignment to non-local variable in constant function\n%s:%d: ... called from here.\n",
- fcall->filename.c_str(), fcall->linenum);
+ log_file_error(stmt->filename, stmt->location.first_line, "Assignment to non-local variable in constant function\n%s:%d.%d-%d.%d: ... called from here.\n",
+ fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
if (stmt->children.at(0)->children.empty()) {
variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size());
} else {
AstNode *range = stmt->children.at(0)->children.at(0);
if (!range->range_valid)
- log_file_error(range->filename, range->linenum, "Non-constant range\n%s:%d: ... called from here.\n",
- fcall->filename.c_str(), fcall->linenum);
+ log_file_error(range->filename, range->location.first_line, "Non-constant range\n%s:%d.%d-%d.%d: ... called from here.\n",
+ fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
int offset = min(range->range_left, range->range_right);
int width = std::abs(range->range_left - range->range_right) + 1;
varinfo_t &v = variables[stmt->children.at(0)->str];
@@ -3712,8 +3867,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)
while (cond->simplify(true, false, false, 1, -1, false, true)) { }
if (cond->type != AST_CONSTANT)
- log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here.\n",
- fcall->filename.c_str(), fcall->linenum);
+ log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n",
+ fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
if (cond->asBool()) {
block->children.insert(block->children.begin(), stmt->children.at(1)->clone());
@@ -3733,8 +3888,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)
while (num->simplify(true, false, false, 1, -1, false, true)) { }
if (num->type != AST_CONSTANT)
- log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here.\n",
- fcall->filename.c_str(), fcall->linenum);
+ log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n",
+ fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
block->children.erase(block->children.begin());
for (int i = 0; i < num->bitsAsConst().as_int(); i++)
@@ -3771,8 +3926,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)
while (cond->simplify(true, false, false, 1, -1, false, true)) { }
if (cond->type != AST_CONSTANT)
- log_file_error(stmt->filename, stmt->linenum, "Non-constant expression in constant function\n%s:%d: ... called from here.\n",
- fcall->filename.c_str(), fcall->linenum);
+ log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s:%d.%d-%d.%d: ... called from here.\n",
+ fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
found_match = cond->asBool();
delete cond;
@@ -3801,8 +3956,8 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)
continue;
}
- log_file_error(stmt->filename, stmt->linenum, "Unsupported language construct in constant function\n%s:%d: ... called from here.\n",
- fcall->filename.c_str(), fcall->linenum);
+ log_file_error(stmt->filename, stmt->location.first_line, "Unsupported language construct in constant function\n%s:%d.%d-%d.%d: ... called from here.\n",
+ fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
log_abort();
}
@@ -3817,4 +3972,32 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)
return AstNode::mkconst_bits(variables.at(str).val.bits, variables.at(str).is_signed);
}
+void AstNode::allocateDefaultEnumValues()
+{
+ log_assert(type==AST_ENUM);
+ int last_enum_int = -1;
+ for (auto node : children) {
+ log_assert(node->type==AST_ENUM_ITEM);
+ node->attributes["\\enum_base_type"] = mkconst_str(str);
+ for (size_t i = 0; i < node->children.size(); i++) {
+ switch (node->children[i]->type) {
+ case AST_NONE:
+ // replace with auto-incremented constant
+ delete node->children[i];
+ node->children[i] = AstNode::mkconst_int(++last_enum_int, true);
+ break;
+ case AST_CONSTANT:
+ // explicit constant (or folded expression)
+ // TODO: can't extend 'x or 'z item
+ last_enum_int = node->children[i]->integer;
+ break;
+ default:
+ // ignore ranges
+ break;
+ }
+ // TODO: range check
+ }
+ }
+}
+
YOSYS_NAMESPACE_END
diff --git a/frontends/rpc/Makefile.inc b/frontends/rpc/Makefile.inc
index 9af505098..7b270b6fe 100644
--- a/frontends/rpc/Makefile.inc
+++ b/frontends/rpc/Makefile.inc
@@ -1,2 +1,3 @@
-
+ifneq ($(CONFIG),emcc)
OBJS += frontends/rpc/rpc_frontend.o
+endif
diff --git a/frontends/verilog/Makefile.inc b/frontends/verilog/Makefile.inc
index 6a8462b41..cf9b9531e 100644
--- a/frontends/verilog/Makefile.inc
+++ b/frontends/verilog/Makefile.inc
@@ -10,7 +10,7 @@ frontends/verilog/verilog_parser.tab.cc: frontends/verilog/verilog_parser.y
frontends/verilog/verilog_parser.tab.hh: frontends/verilog/verilog_parser.tab.cc
-frontends/verilog/verilog_lexer.cc: frontends/verilog/verilog_lexer.l
+frontends/verilog/verilog_lexer.cc: frontends/verilog/verilog_lexer.l frontends/verilog/verilog_parser.tab.cc
$(Q) mkdir -p $(dir $@)
$(P) flex -o frontends/verilog/verilog_lexer.cc $<
diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc
index 058d750c3..f2c1c227f 100644
--- a/frontends/verilog/verilog_frontend.cc
+++ b/frontends/verilog/verilog_frontend.cc
@@ -42,11 +42,27 @@ static std::list<std::vector<std::string>> verilog_defaults_stack;
static void error_on_dpi_function(AST::AstNode *node)
{
if (node->type == AST::AST_DPI_FUNCTION)
- log_file_error(node->filename, node->linenum, "Found DPI function %s.\n", node->str.c_str());
+ log_file_error(node->filename, node->location.first_line, "Found DPI function %s.\n", node->str.c_str());
for (auto child : node->children)
error_on_dpi_function(child);
}
+static void add_package_types(std::map<std::string, AST::AstNode *> &user_types, std::vector<AST::AstNode *> &package_list)
+{
+ // prime the parser's user type lookup table with the package qualified names
+ // of typedefed names in the packages seen so far.
+ user_types.clear();
+ for (const auto &pkg : package_list) {
+ log_assert(pkg->type==AST::AST_PACKAGE);
+ for (const auto &node: pkg->children) {
+ if (node->type == AST::AST_TYPEDEF) {
+ std::string s = pkg->str + "::" + node->str.substr(1);
+ user_types[s] = node;
+ }
+ }
+ }
+}
+
struct VerilogFrontend : public Frontend {
VerilogFrontend() : Frontend("verilog", "read modules from Verilog file") { }
void help() YS_OVERRIDE
@@ -450,6 +466,9 @@ struct VerilogFrontend : public Frontend {
lexin = new std::istringstream(code_after_preproc);
}
+ // make package typedefs available to parser
+ add_package_types(pkg_user_types, design->verilog_packages);
+
frontend_verilog_yyset_lineno(1);
frontend_verilog_yyrestart(NULL);
frontend_verilog_yyparse();
@@ -468,6 +487,7 @@ struct VerilogFrontend : public Frontend {
AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches,
flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_noblackbox, lib_mode, flag_nowb, flag_noopt, flag_icells, flag_pwires, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire);
+
if (!flag_nopp)
delete lexin;
diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h
index a7c9b2fe6..73ea51e6c 100644
--- a/frontends/verilog/verilog_frontend.h
+++ b/frontends/verilog/verilog_frontend.h
@@ -45,6 +45,12 @@ namespace VERILOG_FRONTEND
// this function converts a Verilog constant to an AST_CONSTANT node
AST::AstNode *const2ast(std::string code, char case_type = 0, bool warn_z = false);
+ // names of locally typedef'ed types
+ extern std::map<std::string, AST::AstNode*> user_types;
+
+ // names of package typedef'ed types
+ extern std::map<std::string, AST::AstNode*> pkg_user_types;
+
// state of `default_nettype
extern bool default_nettype_wire;
@@ -87,7 +93,6 @@ YOSYS_NAMESPACE_END
// the usual bison/flex stuff
extern int frontend_verilog_yydebug;
-int frontend_verilog_yylex(void);
void frontend_verilog_yyerror(char const *fmt, ...);
void frontend_verilog_yyrestart(FILE *f);
int frontend_verilog_yyparse(void);
diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l
index 9b43c250e..74e8dce7f 100644
--- a/frontends/verilog/verilog_lexer.l
+++ b/frontends/verilog/verilog_lexer.l
@@ -55,29 +55,57 @@ namespace VERILOG_FRONTEND {
}
YOSYS_NAMESPACE_END
+#define YYSTYPE FRONTEND_VERILOG_YYSTYPE
+#define YYLTYPE FRONTEND_VERILOG_YYLTYPE
+
#define SV_KEYWORD(_tok) \
if (sv_mode) return _tok; \
log("Lexer warning: The SystemVerilog keyword `%s' (at %s:%d) is not "\
"recognized unless read_verilog is called with -sv!\n", yytext, \
AST::current_filename.c_str(), frontend_verilog_yyget_lineno()); \
- frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); \
+ yylval->string = new std::string(std::string("\\") + yytext); \
return TOK_ID;
#define NON_KEYWORD() \
- frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); \
+ yylval->string = new std::string(std::string("\\") + yytext); \
return TOK_ID;
#define YY_INPUT(buf,result,max_size) \
result = readsome(*VERILOG_FRONTEND::lexin, buf, max_size)
+YYLTYPE real_location;
+YYLTYPE old_location;
+
+#define YY_USER_ACTION \
+ old_location = real_location; \
+ real_location.first_line = real_location.last_line; \
+ real_location.first_column = real_location.last_column; \
+ for(int i = 0; yytext[i] != '\0'; ++i){ \
+ if(yytext[i] == '\n') { \
+ real_location.last_line++; \
+ real_location.last_column = 1; \
+ } \
+ else { \
+ real_location.last_column++; \
+ } \
+ } \
+ (*yylloc) = real_location;
+
+#define YY_BREAK \
+ (*yylloc) = old_location; \
+ break;
+
#undef YY_BUF_SIZE
#define YY_BUF_SIZE 65536
+extern int frontend_verilog_yylex(YYSTYPE *yylval_param, YYLTYPE *yyloc_param);
%}
%option yylineno
%option noyywrap
%option nounput
+%option bison-locations
+%option bison-bridge
%option prefix="frontend_verilog_yy"
%x COMMENT
@@ -85,8 +113,10 @@ YOSYS_NAMESPACE_END
%x SYNOPSYS_TRANSLATE_OFF
%x SYNOPSYS_FLAGS
%x IMPORT_DPI
+%x BASED_CONST
%%
+ int comment_caller;
<INITIAL,SYNOPSYS_TRANSLATE_OFF>"`file_push "[^\n]* {
fn_stack.push_back(current_filename);
@@ -97,12 +127,16 @@ YOSYS_NAMESPACE_END
if (!current_filename.empty() && current_filename.back() == '"')
current_filename = current_filename.substr(0, current_filename.size()-1);
frontend_verilog_yyset_lineno(0);
+ yylloc->first_line = yylloc->last_line = 0;
+ real_location.first_line = real_location.last_line = 0;
}
<INITIAL,SYNOPSYS_TRANSLATE_OFF>"`file_pop"[^\n]*\n {
current_filename = fn_stack.back();
fn_stack.pop_back();
frontend_verilog_yyset_lineno(ln_stack.back());
+ yylloc->first_line = yylloc->last_line = ln_stack.back();
+ real_location.first_line = real_location.last_line = ln_stack.back();
ln_stack.pop_back();
}
@@ -110,6 +144,8 @@ YOSYS_NAMESPACE_END
char *p = yytext + 5;
while (*p == ' ' || *p == '\t') p++;
frontend_verilog_yyset_lineno(atoi(p));
+ yylloc->first_line = yylloc->last_line = atoi(p);
+ real_location.first_line = real_location.last_line = atoi(p);
while (*p && *p != ' ' && *p != '\t') p++;
while (*p == ' ' || *p == '\t') p++;
char *q = *p ? p + 1 : p;
@@ -198,7 +234,7 @@ YOSYS_NAMESPACE_END
[a-zA-Z_$][a-zA-Z0-9_$]*/[ \t\r\n]*:[ \t\r\n]*(assert|assume|cover|restrict)[^a-zA-Z0-9_$\.] {
if (!strcmp(yytext, "default"))
return TOK_DEFAULT;
- frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext);
+ yylval->string = new std::string(std::string("\\") + yytext);
return TOK_SVA_LABEL;
}
@@ -235,27 +271,39 @@ YOSYS_NAMESPACE_END
"typedef" { SV_KEYWORD(TOK_TYPEDEF); }
[0-9][0-9_]* {
- frontend_verilog_yylval.string = new std::string(yytext);
+ yylval->string = new std::string(yytext);
return TOK_CONSTVAL;
}
-[0-9]*[ \t]*\'[sS]?[bodhBODH]?[ \t\r\n]*[0-9a-fA-FzxZX?_]+ {
- frontend_verilog_yylval.string = new std::string(yytext);
- return TOK_CONSTVAL;
+\'[01zxZX] {
+ yylval->string = new std::string(yytext);
+ return TOK_UNBASED_UNSIZED_CONSTVAL;
+}
+
+\'[sS]?[bodhBODH] {
+ BEGIN(BASED_CONST);
+ yylval->string = new std::string(yytext);
+ return TOK_BASE;
+}
+
+<BASED_CONST>[0-9a-fA-FzxZX?][0-9a-fA-FzxZX?_]* {
+ BEGIN(0);
+ yylval->string = new std::string(yytext);
+ return TOK_BASED_CONSTVAL;
}
[0-9][0-9_]*\.[0-9][0-9_]*([eE][-+]?[0-9_]+)? {
- frontend_verilog_yylval.string = new std::string(yytext);
+ yylval->string = new std::string(yytext);
return TOK_REALVAL;
}
[0-9][0-9_]*[eE][-+]?[0-9_]+ {
- frontend_verilog_yylval.string = new std::string(yytext);
+ yylval->string = new std::string(yytext);
return TOK_REALVAL;
}
\" { BEGIN(STRING); }
-<STRING>\\. { yymore(); }
+<STRING>\\. { yymore(); real_location = old_location; }
<STRING>\" {
BEGIN(0);
char *yystr = strdup(yytext);
@@ -291,14 +339,14 @@ YOSYS_NAMESPACE_END
yystr[j++] = yystr[i++];
}
yystr[j] = 0;
- frontend_verilog_yylval.string = new std::string(yystr, j);
+ yylval->string = new std::string(yystr, j);
free(yystr);
return TOK_STRING;
}
-<STRING>. { yymore(); }
+<STRING>. { yymore(); real_location = old_location; }
and|nand|or|nor|xor|xnor|not|buf|bufif0|bufif1|notif0|notif1 {
- frontend_verilog_yylval.string = new std::string(yytext);
+ yylval->string = new std::string(yytext);
return TOK_PRIMITIVE;
}
@@ -306,31 +354,55 @@ supply0 { return TOK_SUPPLY0; }
supply1 { return TOK_SUPPLY1; }
"$"(display|write|strobe|monitor|time|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) {
- frontend_verilog_yylval.string = new std::string(yytext);
+ yylval->string = new std::string(yytext);
return TOK_ID;
}
"$"(setup|hold|setuphold|removal|recovery|recrem|skew|timeskew|fullskew|nochange) {
if (!specify_mode) REJECT;
- frontend_verilog_yylval.string = new std::string(yytext);
+ yylval->string = new std::string(yytext);
return TOK_ID;
}
"$"(info|warning|error|fatal) {
- frontend_verilog_yylval.string = new std::string(yytext);
+ yylval->string = new std::string(yytext);
return TOK_MSG_TASKS;
}
"$signed" { return TOK_TO_SIGNED; }
"$unsigned" { return TOK_TO_UNSIGNED; }
+[a-zA-Z_][a-zA-Z0-9_]*::[a-zA-Z_$][a-zA-Z0-9_$]* {
+ // package qualifier
+ auto s = std::string("\\") + yytext;
+ if (pkg_user_types.count(s) > 0) {
+ // found it
+ yylval->string = new std::string(s);
+ return TOK_USER_TYPE;
+ }
+ else {
+ // backup before :: just return first part
+ size_t len = strchr(yytext, ':') - yytext;
+ yyless(len);
+ yylval->string = new std::string(std::string("\\") + yytext);
+ return TOK_ID;
+ }
+}
+
[a-zA-Z_$][a-zA-Z0-9_$]* {
- frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext);
- return TOK_ID;
+ auto s = std::string("\\") + yytext;
+ if (user_types.count(s) > 0) {
+ yylval->string = new std::string(s);
+ return TOK_USER_TYPE;
+ }
+ else {
+ yylval->string = new std::string(std::string("\\") + yytext);
+ return TOK_ID;
+ }
}
[a-zA-Z_$][a-zA-Z0-9_$\.]* {
- frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext);
+ yylval->string = new std::string(std::string("\\") + yytext);
return TOK_ID;
}
@@ -377,7 +449,7 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ {
}
<IMPORT_DPI>[a-zA-Z_$][a-zA-Z0-9_$]* {
- frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext);
+ yylval->string = new std::string(std::string("\\") + yytext);
return TOK_ID;
}
@@ -393,7 +465,7 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ {
}
"\\"[^ \t\r\n]+ {
- frontend_verilog_yylval.string = new std::string(yytext);
+ yylval->string = new std::string(yytext);
return TOK_ID;
}
@@ -435,25 +507,26 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ {
[-+]?[=*]> {
if (!specify_mode) REJECT;
- frontend_verilog_yylval.string = new std::string(yytext);
+ yylval->string = new std::string(yytext);
return TOK_SPECIFY_OPER;
}
"&&&" {
- if (!specify_mode) REJECT;
+ if (!specify_mode) return TOK_IGNORED_SPECIFY_AND;
return TOK_SPECIFY_AND;
}
-"/*" { BEGIN(COMMENT); }
+<INITIAL,BASED_CONST>"/*" { comment_caller=YY_START; BEGIN(COMMENT); }
<COMMENT>. /* ignore comment body */
<COMMENT>\n /* ignore comment body */
-<COMMENT>"*/" { BEGIN(0); }
+<COMMENT>"*/" { BEGIN(comment_caller); }
-[ \t\r\n] /* ignore whitespaces */
-\\[\r\n] /* ignore continuation sequence */
-"//"[^\r\n]* /* ignore one-line comments */
+<INITIAL,BASED_CONST>[ \t\r\n] /* ignore whitespaces */
+<INITIAL,BASED_CONST>\\[\r\n] /* ignore continuation sequence */
+<INITIAL,BASED_CONST>"//"[^\r\n]* /* ignore one-line comments */
-. { return *yytext; }
+<INITIAL>. { return *yytext; }
+<*>. { BEGIN(0); return *yytext; }
%%
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 2c7304cc4..f7e3afd13 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -38,8 +38,11 @@
#include <stack>
#include <string.h>
#include "frontends/verilog/verilog_frontend.h"
+#include "frontends/verilog/verilog_parser.tab.hh"
#include "kernel/log.h"
+#define YYLEX_PARAM &yylval, &yylloc
+
USING_YOSYS_NAMESPACE
using namespace AST;
using namespace VERILOG_FRONTEND;
@@ -51,6 +54,8 @@ namespace VERILOG_FRONTEND {
std::map<std::string, AstNode*> *attr_list, default_attr_list;
std::stack<std::map<std::string, AstNode*> *> attr_list_stack;
std::map<std::string, AstNode*> *albuf;
+ std::map<std::string, AstNode*> user_types;
+ std::map<std::string, AstNode*> pkg_user_types;
std::vector<AstNode*> ast_stack;
struct AstNode *astbuf1, *astbuf2, *astbuf3;
struct AstNode *current_function_or_task;
@@ -68,6 +73,20 @@ namespace VERILOG_FRONTEND {
}
YOSYS_NAMESPACE_END
+#define SET_AST_NODE_LOC(WHICH, BEGIN, END) \
+ do { (WHICH)->location.first_line = (BEGIN).first_line; \
+ (WHICH)->location.first_column = (BEGIN).first_column; \
+ (WHICH)->location.last_line = (END).last_line; \
+ (WHICH)->location.last_column = (END).last_column; } while(0)
+
+#define SET_RULE_LOC(LHS, BEGIN, END) \
+ do { (LHS).first_line = (BEGIN).first_line; \
+ (LHS).first_column = (BEGIN).first_column; \
+ (LHS).last_line = (END).last_line; \
+ (LHS).last_column = (END).last_column; } while(0)
+
+int frontend_verilog_yylex(YYSTYPE *yylval_param, YYLTYPE *yyloc_param);
+
static void append_attr(AstNode *ast, std::map<std::string, AstNode*> *al)
{
for (auto &it : *al) {
@@ -108,9 +127,44 @@ struct specify_rise_fall {
specify_triple fall;
};
+static void addTypedefNode(std::string *name, AstNode *node)
+{
+ log_assert(node);
+ // seems to be support for local scoped typedefs in simplify()
+ // and tests redefine types.
+ //if (user_types.count(*name) > 0) {
+ // frontend_verilog_yyerror("Type already defined.");
+ //}
+ auto *tnode = new AstNode(AST_TYPEDEF, node);
+ tnode->str = *name;
+ user_types[*name] = tnode;
+ if (current_ast_mod && current_ast_mod->type == AST_PACKAGE) {
+ // typedef inside a package so we need the qualified name
+ auto qname = current_ast_mod->str + "::" + (*name).substr(1);
+ pkg_user_types[qname] = tnode;
+ }
+ delete name;
+ ast_stack.back()->children.push_back(tnode);
+}
+
+static AstNode *makeRange(int msb = 31, int lsb = 0, bool isSigned = true)
+{
+ auto range = new AstNode(AST_RANGE);
+ range->children.push_back(AstNode::mkconst_int(msb, true));
+ range->children.push_back(AstNode::mkconst_int(lsb, true));
+ range->is_signed = isSigned;
+ return range;
+}
+
+static void addRange(AstNode *parent, int msb = 31, int lsb = 0, bool isSigned = true)
+{
+ auto range = makeRange(msb, lsb, isSigned);
+ parent->children.push_back(range);
+}
%}
%define api.prefix {frontend_verilog_yy}
+%define api.pure
/* The union is defined in the header, so we need to provide all the
* includes it requires
@@ -134,6 +188,8 @@ struct specify_rise_fall {
%token <string> TOK_STRING TOK_ID TOK_CONSTVAL TOK_REALVAL TOK_PRIMITIVE
%token <string> TOK_SVA_LABEL TOK_SPECIFY_OPER TOK_MSG_TASKS
+%token <string> TOK_BASE TOK_BASED_CONSTVAL TOK_UNBASED_UNSIZED_CONSTVAL
+%token <string> TOK_USER_TYPE
%token TOK_ASSERT TOK_ASSUME TOK_RESTRICT TOK_COVER TOK_FINAL
%token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END
%token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM
@@ -146,7 +202,7 @@ struct specify_rise_fall {
%token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR TOK_AUTOMATIC
%token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT
%token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK TOK_SPECIFY
-%token TOK_IGNORED_SPECIFY TOK_ENDSPECIFY TOK_SPECPARAM TOK_SPECIFY_AND
+%token TOK_IGNORED_SPECIFY TOK_ENDSPECIFY TOK_SPECPARAM TOK_SPECIFY_AND TOK_IGNORED_SPECIFY_AND
%token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL
%token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE
%token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED
@@ -156,14 +212,16 @@ struct specify_rise_fall {
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
-%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id
+%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number
+%type <string> type_name
+%type <ast> opt_enum_init
%type <boolean> opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff
%type <al> attr case_attr
%type <specify_target_ptr> specify_target
-%type <specify_triple_ptr> specify_triple
+%type <specify_triple_ptr> specify_triple specify_opt_triple
%type <specify_rise_fall_ptr> specify_rise_fall
-%type <ast> specify_if specify_condition specify_opt_arg
+%type <ast> specify_if specify_condition
%type <ch> specify_edge
// operator precedence from low to high
@@ -187,6 +245,7 @@ struct specify_rise_fall {
%nonassoc TOK_ELSE
%debug
+%locations
%%
@@ -229,7 +288,9 @@ attr:
};
attr_opt:
- attr_opt ATTR_BEGIN opt_attr_list ATTR_END |
+ attr_opt ATTR_BEGIN opt_attr_list ATTR_END {
+ SET_RULE_LOC(@$, @2, @$);
+ }|
/* empty */;
defattr:
@@ -293,7 +354,9 @@ hierarchical_id:
};
hierarchical_type_id:
- '(' hierarchical_id ')' { $$ = $2; };
+ TOK_USER_TYPE
+ | '(' TOK_USER_TYPE ')' { $$ = $2; } // non-standard grammar
+ ;
module:
attr TOK_MODULE TOK_ID {
@@ -311,9 +374,11 @@ module:
if (port_stubs.size() != 0)
frontend_verilog_yyerror("Missing details for module port `%s'.",
port_stubs.begin()->first.c_str());
+ SET_AST_NODE_LOC(ast_stack.back(), @2, @$);
ast_stack.pop_back();
log_assert(ast_stack.size() == 1);
current_ast_mod = NULL;
+ user_types.clear();
};
module_para_opt:
@@ -374,6 +439,7 @@ module_arg:
node->str = *$1;
node->port_id = ++port_counter;
ast_stack.back()->children.push_back(node);
+ SET_AST_NODE_LOC(node, @1, @1);
} else {
if (port_stubs.count(*$1) != 0)
frontend_verilog_yyerror("Duplicate module port `%s'.", $1->c_str());
@@ -399,6 +465,7 @@ module_arg:
attr wire_type range TOK_ID {
AstNode *node = $2;
node->str = *$4;
+ SET_AST_NODE_LOC(node, @4, @4);
node->port_id = ++port_counter;
if ($3 != NULL)
node->children.push_back($3);
@@ -425,10 +492,13 @@ package:
} ';' package_body TOK_ENDPACKAGE {
ast_stack.pop_back();
current_ast_mod = NULL;
+ user_types.clear();
};
package_body:
- package_body package_body_stmt |;
+ package_body package_body_stmt
+ | // optional
+ ;
package_body_stmt:
typedef_decl |
@@ -452,6 +522,7 @@ interface:
ast_stack.pop_back();
log_assert(ast_stack.size() == 1);
current_ast_mod = NULL;
+ user_types.clear();
};
interface_body:
@@ -476,8 +547,9 @@ wire_type:
astbuf3 = new AstNode(AST_WIRE);
current_wire_rand = false;
current_wire_const = false;
- } wire_type_token_list delay {
+ } wire_type_token_list {
$$ = astbuf3;
+ SET_RULE_LOC(@$, @2, @$);
};
wire_type_token_list:
@@ -551,13 +623,15 @@ non_opt_range:
} |
'[' expr TOK_POS_INDEXED expr ']' {
$$ = new AstNode(AST_RANGE);
- $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, $2->clone(), $4), AstNode::mkconst_int(1, true)));
- $$->children.push_back(new AstNode(AST_ADD, $2, AstNode::mkconst_int(0, true)));
+ AstNode *expr = new AstNode(AST_CONCAT, $2);
+ $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), $4), AstNode::mkconst_int(1, true)));
+ $$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));
} |
'[' expr TOK_NEG_INDEXED expr ']' {
$$ = new AstNode(AST_RANGE);
- $$->children.push_back(new AstNode(AST_ADD, $2, AstNode::mkconst_int(0, true)));
- $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, $2->clone(), AstNode::mkconst_int(1, true)), $4));
+ AstNode *expr = new AstNode(AST_CONCAT, $2);
+ $$->children.push_back(new AstNode(AST_ADD, expr, AstNode::mkconst_int(0, true)));
+ $$->children.push_back(new AstNode(AST_SUB, new AstNode(AST_ADD, expr->clone(), AstNode::mkconst_int(1, true)), $4));
} |
'[' expr ']' {
$$ = new AstNode(AST_RANGE);
@@ -604,6 +678,7 @@ module_body:
module_body_stmt:
task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
+ enum_decl |
always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block;
checker_decl:
@@ -855,7 +930,7 @@ specify_item:
delete target;
delete timing;
} |
- TOK_ID '(' specify_edge expr specify_condition ',' specify_edge expr specify_condition ',' expr specify_opt_arg ')' ';' {
+ TOK_ID '(' specify_edge expr specify_condition ',' specify_edge expr specify_condition ',' specify_triple specify_opt_triple ')' ';' {
if (*$1 != "$setup" && *$1 != "$hold" && *$1 != "$setuphold" && *$1 != "$removal" && *$1 != "$recovery" &&
*$1 != "$recrem" && *$1 != "$skew" && *$1 != "$timeskew" && *$1 != "$fullskew" && *$1 != "$nochange")
frontend_verilog_yyerror("Unsupported specify rule type: %s\n", $1->c_str());
@@ -868,8 +943,8 @@ specify_item:
AstNode *dst_pol = AstNode::mkconst_int($7 == 'p', false, 1);
AstNode *dst_expr = $8, *dst_en = $9 ? $9 : AstNode::mkconst_int(1, false, 1);
- AstNode *limit = $11;
- AstNode *limit2 = $12;
+ specify_triple *limit = $11;
+ specify_triple *limit2 = $12;
AstNode *cell = new AstNode(AST_CELL);
ast_stack.back()->children.push_back(cell);
@@ -880,11 +955,23 @@ specify_item:
cell->children.push_back(new AstNode(AST_PARASET, AstNode::mkconst_str(*$1)));
cell->children.back()->str = "\\TYPE";
- cell->children.push_back(new AstNode(AST_PARASET, limit));
- cell->children.back()->str = "\\T_LIMIT";
+ cell->children.push_back(new AstNode(AST_PARASET, limit->t_min));
+ cell->children.back()->str = "\\T_LIMIT_MIN";
+
+ cell->children.push_back(new AstNode(AST_PARASET, limit->t_avg));
+ cell->children.back()->str = "\\T_LIMIT_TYP";
- cell->children.push_back(new AstNode(AST_PARASET, limit2 ? limit2 : AstNode::mkconst_int(0, true)));
- cell->children.back()->str = "\\T_LIMIT2";
+ cell->children.push_back(new AstNode(AST_PARASET, limit->t_max));
+ cell->children.back()->str = "\\T_LIMIT_MAX";
+
+ cell->children.push_back(new AstNode(AST_PARASET, limit2 ? limit2->t_min : AstNode::mkconst_int(0, true)));
+ cell->children.back()->str = "\\T_LIMIT2_MIN";
+
+ cell->children.push_back(new AstNode(AST_PARASET, limit2 ? limit2->t_avg : AstNode::mkconst_int(0, true)));
+ cell->children.back()->str = "\\T_LIMIT2_TYP";
+
+ cell->children.push_back(new AstNode(AST_PARASET, limit2 ? limit2->t_max : AstNode::mkconst_int(0, true)));
+ cell->children.back()->str = "\\T_LIMIT2_MAX";
cell->children.push_back(new AstNode(AST_PARASET, src_pen));
cell->children.back()->str = "\\SRC_PEN";
@@ -913,8 +1000,8 @@ specify_item:
delete $1;
};
-specify_opt_arg:
- ',' expr {
+specify_opt_triple:
+ ',' specify_triple {
$$ = $2;
} |
/* empty */ {
@@ -983,7 +1070,46 @@ specify_rise_fall:
$$->fall = *$4;
delete $2;
delete $4;
- };
+ } |
+ '(' specify_triple ',' specify_triple ',' specify_triple ')' {
+ $$ = new specify_rise_fall;
+ $$->rise = *$2;
+ $$->fall = *$4;
+ delete $2;
+ delete $4;
+ delete $6;
+ log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
+ } |
+ '(' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ')' {
+ $$ = new specify_rise_fall;
+ $$->rise = *$2;
+ $$->fall = *$4;
+ delete $2;
+ delete $4;
+ delete $6;
+ delete $8;
+ delete $10;
+ delete $12;
+ log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
+ } |
+ '(' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ',' specify_triple ')' {
+ $$ = new specify_rise_fall;
+ $$->rise = *$2;
+ $$->fall = *$4;
+ delete $2;
+ delete $4;
+ delete $6;
+ delete $8;
+ delete $10;
+ delete $12;
+ delete $14;
+ delete $16;
+ delete $18;
+ delete $20;
+ delete $22;
+ delete $24;
+ log_file_warning(current_filename, get_line_num(), "Path delay expressions beyond rise/fall not currently supported. Ignoring.\n");
+ }
specify_triple:
expr {
@@ -1031,7 +1157,7 @@ list_of_specparam_assignments:
specparam_assignment | list_of_specparam_assignments ',' specparam_assignment;
specparam_assignment:
- ignspec_id '=' constant_mintypmax_expression ;
+ ignspec_id '=' ignspec_expr ;
ignspec_opt_cond:
TOK_IF '(' ignspec_expr ')' | /* empty */;
@@ -1048,13 +1174,15 @@ simple_path_declaration :
;
path_delay_value :
- '(' path_delay_expression list_of_path_delay_extra_expressions ')'
- | path_delay_expression
- | path_delay_expression list_of_path_delay_extra_expressions
+ '(' ignspec_expr list_of_path_delay_extra_expressions ')'
+ | ignspec_expr
+ | ignspec_expr list_of_path_delay_extra_expressions
;
list_of_path_delay_extra_expressions :
- ',' path_delay_expression | ',' path_delay_expression list_of_path_delay_extra_expressions;
+ ',' ignspec_expr
+ | ',' ignspec_expr list_of_path_delay_extra_expressions
+ ;
specify_edge_identifier :
TOK_POSEDGE | TOK_NEGEDGE ;
@@ -1105,16 +1233,9 @@ system_timing_arg :
system_timing_args :
system_timing_arg |
+ system_timing_args TOK_IGNORED_SPECIFY_AND system_timing_arg |
system_timing_args ',' system_timing_arg ;
-path_delay_expression :
- ignspec_constant_expression;
-
-constant_mintypmax_expression :
- ignspec_constant_expression
- | ignspec_constant_expression ':' ignspec_constant_expression ':' ignspec_constant_expression
- ;
-
// for the time being this is OK, but we may write our own expr here.
// as I'm not sure it is legal to use a full expr here (probably not)
// On the other hand, other rules requiring constant expressions also use 'expr'
@@ -1123,10 +1244,16 @@ ignspec_constant_expression:
expr { delete $1; };
ignspec_expr:
- expr { delete $1; };
+ expr { delete $1; } |
+ expr ':' expr ':' expr {
+ delete $1;
+ delete $3;
+ delete $5;
+ };
ignspec_id:
- TOK_ID { delete $1; };
+ TOK_ID { delete $1; }
+ range_or_multirange { delete $3; };
/**********************************************************************/
@@ -1224,6 +1351,85 @@ single_defparam_decl:
ast_stack.back()->children.push_back(node);
};
+enum_type: TOK_ENUM {
+ static int enum_count;
+ // create parent node for the enum
+ astbuf2 = new AstNode(AST_ENUM);
+ ast_stack.back()->children.push_back(astbuf2);
+ astbuf2->str = std::string("$enum");
+ astbuf2->str += std::to_string(enum_count++);
+ // create the template for the names
+ astbuf1 = new AstNode(AST_ENUM_ITEM);
+ astbuf1->children.push_back(AstNode::mkconst_int(0, true));
+ } param_signed enum_base_type '{' enum_name_list '}' { // create template for the enum vars
+ auto tnode = astbuf1->clone();
+ delete astbuf1;
+ astbuf1 = tnode;
+ tnode->type = AST_WIRE;
+ tnode->attributes["\\enum_type"] = AstNode::mkconst_str(astbuf2->str);
+ // drop constant but keep any range
+ delete tnode->children[0];
+ tnode->children.erase(tnode->children.begin()); }
+ ;
+
+enum_base_type: int_vec param_range
+ | int_atom
+ | /* nothing */ {astbuf1->is_reg = true; addRange(astbuf1); }
+ ;
+
+int_atom: TOK_INTEGER {astbuf1->is_reg=true; addRange(astbuf1); } // probably should do byte, range [7:0] here
+ ;
+
+int_vec: TOK_REG {astbuf1->is_reg = true;}
+ | TOK_LOGIC {astbuf1->is_logic = true;}
+ ;
+
+enum_name_list:
+ enum_name_decl
+ | enum_name_list ',' enum_name_decl
+ ;
+
+enum_name_decl:
+ TOK_ID opt_enum_init {
+ // put in fn
+ log_assert(astbuf1);
+ log_assert(astbuf2);
+ auto node = astbuf1->clone();
+ node->str = *$1;
+ delete $1;
+ delete node->children[0];
+ node->children[0] = $2 ?: new AstNode(AST_NONE);
+ astbuf2->children.push_back(node);
+ }
+ ;
+
+opt_enum_init:
+ '=' basic_expr { $$ = $2; } // TODO: restrict this
+ | /* optional */ { $$ = NULL; }
+ ;
+
+enum_var_list:
+ enum_var
+ | enum_var_list ',' enum_var
+ ;
+
+enum_var: TOK_ID {
+ log_assert(astbuf1);
+ log_assert(astbuf2);
+ auto node = astbuf1->clone();
+ ast_stack.back()->children.push_back(node);
+ node->str = *$1;
+ delete $1;
+ node->is_enum = true;
+ }
+ ;
+
+enum_decl: enum_type enum_var_list ';' {
+ //enum_type creates astbuf1 for use by typedef only
+ delete astbuf1;
+ }
+ ;
+
wire_decl:
attr wire_type range {
albuf = $1;
@@ -1240,7 +1446,7 @@ wire_decl:
}
if (astbuf2 && astbuf2->children.size() != 2)
frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
- } wire_name_list {
+ } delay wire_name_list {
delete astbuf1;
if (astbuf2 != NULL)
delete astbuf2;
@@ -1328,11 +1534,24 @@ wire_name_and_opt_assign:
if (astbuf1->attributes.count("\\defaultvalue"))
delete astbuf1->attributes.at("\\defaultvalue");
astbuf1->attributes["\\defaultvalue"] = $3;
- } else
- if (astbuf1->is_reg || astbuf1->is_logic)
- ast_stack.back()->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, wire, $3))));
- else
- ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, $3));
+ }
+ else if (astbuf1->is_reg || astbuf1->is_logic){
+ AstNode *assign = new AstNode(AST_ASSIGN_LE, wire, $3);
+ AstNode *block = new AstNode(AST_BLOCK, assign);
+ AstNode *init = new AstNode(AST_INITIAL, block);
+
+ SET_AST_NODE_LOC(assign, @1, @3);
+ SET_AST_NODE_LOC(block, @1, @3);
+ SET_AST_NODE_LOC(init, @1, @3);
+
+ ast_stack.back()->children.push_back(init);
+ }
+ else {
+ AstNode *assign = new AstNode(AST_ASSIGN, wire, $3);
+ SET_AST_NODE_LOC(assign, @1, @3);
+ ast_stack.back()->children.push_back(assign);
+ }
+
};
wire_name:
@@ -1381,6 +1600,8 @@ wire_name:
if (node->is_input || node->is_output)
node->port_id = current_function_or_task_port_id++;
}
+ //FIXME: for some reason, TOK_ID has a location which always points to one column *after* the real last column...
+ SET_AST_NODE_LOC(node, @1, @1);
ast_stack.back()->children.push_back(node);
delete $1;
@@ -1394,11 +1615,17 @@ assign_expr_list:
assign_expr:
lvalue '=' expr {
- ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, $1, $3));
+ AstNode *node = new AstNode(AST_ASSIGN, $1, $3);
+ SET_AST_NODE_LOC(node, @$, @$);
+ ast_stack.back()->children.push_back(node);
};
+type_name: TOK_ID // first time seen
+ | TOK_USER_TYPE // redefinition
+ ;
+
typedef_decl:
- TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' {
+ TOK_TYPEDEF wire_type range type_name range_or_multirange ';' {
astbuf1 = $2;
astbuf2 = $3;
if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
@@ -1431,10 +1658,12 @@ typedef_decl:
}
astbuf1->children.push_back(rangeNode);
}
-
- ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1));
- ast_stack.back()->children.back()->str = *$4;
- };
+ addTypedefNode($4, astbuf1);
+ } |
+ TOK_TYPEDEF enum_type type_name ';' {
+ addTypedefNode($3, astbuf1);
+ }
+ ;
cell_stmt:
attr TOK_ID {
@@ -1474,14 +1703,19 @@ single_cell:
astbuf2->str = *$1;
delete $1;
ast_stack.back()->children.push_back(astbuf2);
- } '(' cell_port_list ')' |
+ } '(' cell_port_list ')' {
+ SET_AST_NODE_LOC(astbuf2, @1, @$);
+ } |
TOK_ID non_opt_range {
astbuf2 = astbuf1->clone();
if (astbuf2->type != AST_PRIMITIVE)
astbuf2->str = *$1;
delete $1;
ast_stack.back()->children.push_back(new AstNode(AST_CELLARRAY, $2, astbuf2));
- } '(' cell_port_list ')';
+ } '(' cell_port_list ')'{
+ SET_AST_NODE_LOC(astbuf2, @1, @$);
+ SET_AST_NODE_LOC(astbuf3, @1, @$);
+ };
prim_list:
single_prim |
@@ -1616,8 +1850,13 @@ always_stmt:
ast_stack.back()->children.push_back(block);
ast_stack.push_back(block);
} behavioral_stmt {
+ SET_AST_NODE_LOC(ast_stack.back(), @6, @6);
ast_stack.pop_back();
+
+ SET_AST_NODE_LOC(ast_stack.back(), @2, @$);
ast_stack.pop_back();
+
+ SET_RULE_LOC(@$, @2, @$);
} |
attr always_comb_or_latch {
AstNode *node = new AstNode(AST_ALWAYS);
@@ -1746,6 +1985,7 @@ assert:
delete $5;
} else {
AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5);
+ SET_AST_NODE_LOC(node, @1, @6);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@@ -1758,6 +1998,7 @@ assert:
delete $5;
} else {
AstNode *node = new AstNode(assert_assumes_mode ? AST_ASSERT : AST_ASSUME, $5);
+ SET_AST_NODE_LOC(node, @1, @6);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@@ -1770,6 +2011,7 @@ assert:
delete $6;
} else {
AstNode *node = new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6);
+ SET_AST_NODE_LOC(node, @1, @7);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@@ -1782,6 +2024,7 @@ assert:
delete $6;
} else {
AstNode *node = new AstNode(assert_assumes_mode ? AST_LIVE : AST_FAIR, $6);
+ SET_AST_NODE_LOC(node, @1, @7);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@@ -1791,6 +2034,7 @@ assert:
} |
opt_sva_label TOK_COVER opt_property '(' expr ')' ';' {
AstNode *node = new AstNode(AST_COVER, $5);
+ SET_AST_NODE_LOC(node, @1, @6);
if ($1 != nullptr) {
node->str = *$1;
delete $1;
@@ -1799,6 +2043,7 @@ assert:
} |
opt_sva_label TOK_COVER opt_property '(' ')' ';' {
AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
+ SET_AST_NODE_LOC(node, @1, @5);
if ($1 != nullptr) {
node->str = *$1;
delete $1;
@@ -1807,6 +2052,7 @@ assert:
} |
opt_sva_label TOK_COVER ';' {
AstNode *node = new AstNode(AST_COVER, AstNode::mkconst_int(1, false));
+ SET_AST_NODE_LOC(node, @1, @2);
if ($1 != nullptr) {
node->str = *$1;
delete $1;
@@ -1818,6 +2064,7 @@ assert:
delete $5;
} else {
AstNode *node = new AstNode(AST_ASSUME, $5);
+ SET_AST_NODE_LOC(node, @1, @6);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@@ -1832,6 +2079,7 @@ assert:
delete $6;
} else {
AstNode *node = new AstNode(AST_FAIR, $6);
+ SET_AST_NODE_LOC(node, @1, @7);
if ($1 != nullptr)
node->str = *$1;
ast_stack.back()->children.push_back(node);
@@ -1844,35 +2092,45 @@ assert:
assert_property:
opt_sva_label TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' {
- ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5));
+ AstNode *node = new AstNode(assume_asserts_mode ? AST_ASSUME : AST_ASSERT, $5);
+ SET_AST_NODE_LOC(node, @1, @6);
+ ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
}
} |
opt_sva_label TOK_ASSUME TOK_PROPERTY '(' expr ')' ';' {
- ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5));
+ AstNode *node = new AstNode(AST_ASSUME, $5);
+ SET_AST_NODE_LOC(node, @1, @6);
+ ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
}
} |
opt_sva_label TOK_ASSERT TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
- ast_stack.back()->children.push_back(new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6));
+ AstNode *node = new AstNode(assume_asserts_mode ? AST_FAIR : AST_LIVE, $6);
+ SET_AST_NODE_LOC(node, @1, @7);
+ ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
}
} |
opt_sva_label TOK_ASSUME TOK_PROPERTY '(' TOK_EVENTUALLY expr ')' ';' {
- ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6));
+ AstNode *node = new AstNode(AST_FAIR, $6);
+ SET_AST_NODE_LOC(node, @1, @7);
+ ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
}
} |
opt_sva_label TOK_COVER TOK_PROPERTY '(' expr ')' ';' {
- ast_stack.back()->children.push_back(new AstNode(AST_COVER, $5));
+ AstNode *node = new AstNode(AST_COVER, $5);
+ SET_AST_NODE_LOC(node, @1, @6);
+ ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
@@ -1882,7 +2140,9 @@ assert_property:
if (norestrict_mode) {
delete $5;
} else {
- ast_stack.back()->children.push_back(new AstNode(AST_ASSUME, $5));
+ AstNode *node = new AstNode(AST_ASSUME, $5);
+ SET_AST_NODE_LOC(node, @1, @6);
+ ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
@@ -1893,7 +2153,9 @@ assert_property:
if (norestrict_mode) {
delete $6;
} else {
- ast_stack.back()->children.push_back(new AstNode(AST_FAIR, $6));
+ AstNode *node = new AstNode(AST_FAIR, $6);
+ SET_AST_NODE_LOC(node, @1, @7);
+ ast_stack.back()->children.push_back(node);
if ($1 != nullptr) {
ast_stack.back()->children.back()->str = *$1;
delete $1;
@@ -1905,18 +2167,22 @@ simple_behavioral_stmt:
lvalue '=' delay expr {
AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, $4);
ast_stack.back()->children.push_back(node);
+ SET_AST_NODE_LOC(node, @1, @4);
} |
lvalue TOK_INCREMENT {
AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, new AstNode(AST_ADD, $1->clone(), AstNode::mkconst_int(1, true)));
ast_stack.back()->children.push_back(node);
+ SET_AST_NODE_LOC(node, @1, @2);
} |
lvalue TOK_DECREMENT {
AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, new AstNode(AST_SUB, $1->clone(), AstNode::mkconst_int(1, true)));
ast_stack.back()->children.push_back(node);
+ SET_AST_NODE_LOC(node, @1, @2);
} |
lvalue OP_LE delay expr {
AstNode *node = new AstNode(AST_ASSIGN_LE, $1, $4);
ast_stack.back()->children.push_back(node);
+ SET_AST_NODE_LOC(node, @1, @4);
};
// this production creates the obligatory if-else shift/reduce conflict
@@ -1972,7 +2238,9 @@ behavioral_stmt:
ast_stack.back()->children.push_back(block);
ast_stack.push_back(block);
} behavioral_stmt {
+ SET_AST_NODE_LOC(ast_stack.back(), @13, @13);
ast_stack.pop_back();
+ SET_AST_NODE_LOC(ast_stack.back(), @2, @13);
ast_stack.pop_back();
} |
attr TOK_WHILE '(' expr ')' {
@@ -1985,6 +2253,7 @@ behavioral_stmt:
ast_stack.back()->children.push_back(block);
ast_stack.push_back(block);
} behavioral_stmt {
+ SET_AST_NODE_LOC(ast_stack.back(), @7, @7);
ast_stack.pop_back();
ast_stack.pop_back();
} |
@@ -1998,6 +2267,7 @@ behavioral_stmt:
ast_stack.back()->children.push_back(block);
ast_stack.push_back(block);
} behavioral_stmt {
+ SET_AST_NODE_LOC(ast_stack.back(), @7, @7);
ast_stack.pop_back();
ast_stack.pop_back();
} |
@@ -2005,14 +2275,18 @@ behavioral_stmt:
AstNode *node = new AstNode(AST_CASE);
AstNode *block = new AstNode(AST_BLOCK);
AstNode *cond = new AstNode(AST_COND, AstNode::mkconst_int(1, false, 1), block);
+ SET_AST_NODE_LOC(cond, @4, @4);
ast_stack.back()->children.push_back(node);
node->children.push_back(new AstNode(AST_REDUCE_BOOL, $4));
node->children.push_back(cond);
ast_stack.push_back(node);
ast_stack.push_back(block);
append_attr(node, $1);
- } behavioral_stmt optional_else {
+ } behavioral_stmt {
+ SET_AST_NODE_LOC(ast_stack.back(), @7, @7);
+ } optional_else {
ast_stack.pop_back();
+ SET_AST_NODE_LOC(ast_stack.back(), @2, @9);
ast_stack.pop_back();
} |
case_attr case_type '(' expr ')' {
@@ -2020,7 +2294,9 @@ behavioral_stmt:
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
append_attr(node, $1);
+ SET_AST_NODE_LOC(ast_stack.back(), @4, @4);
} opt_synopsys_attr case_body TOK_ENDCASE {
+ SET_AST_NODE_LOC(ast_stack.back(), @2, @9);
case_type_stack.pop_back();
ast_stack.pop_back();
};
@@ -2072,10 +2348,14 @@ optional_else:
TOK_ELSE {
AstNode *block = new AstNode(AST_BLOCK);
AstNode *cond = new AstNode(AST_COND, new AstNode(AST_DEFAULT), block);
+ SET_AST_NODE_LOC(cond, @1, @1);
+
ast_stack.pop_back();
ast_stack.back()->children.push_back(cond);
ast_stack.push_back(block);
- } behavioral_stmt |
+ } behavioral_stmt {
+ SET_AST_NODE_LOC(ast_stack.back(), @3, @3);
+ } |
/* empty */ %prec FAKE_THEN;
case_body:
@@ -2096,6 +2376,7 @@ case_item:
case_type_stack.push_back(0);
} behavioral_stmt {
case_type_stack.pop_back();
+ SET_AST_NODE_LOC(ast_stack.back(), @4, @4);
ast_stack.pop_back();
ast_stack.pop_back();
};
@@ -2113,6 +2394,7 @@ gen_case_item:
ast_stack.push_back(node);
} case_select {
case_type_stack.push_back(0);
+ SET_AST_NODE_LOC(ast_stack.back(), @2, @2);
} gen_stmt_or_null {
case_type_stack.pop_back();
ast_stack.pop_back();
@@ -2124,10 +2406,14 @@ case_select:
case_expr_list:
TOK_DEFAULT {
- ast_stack.back()->children.push_back(new AstNode(AST_DEFAULT));
+ AstNode *node = new AstNode(AST_DEFAULT);
+ SET_AST_NODE_LOC(node, @1, @1);
+ ast_stack.back()->children.push_back(node);
} |
TOK_SVA_LABEL {
- ast_stack.back()->children.push_back(new AstNode(AST_IDENTIFIER));
+ AstNode *node = new AstNode(AST_IDENTIFIER);
+ SET_AST_NODE_LOC(node, @1, @1);
+ ast_stack.back()->children.push_back(node);
ast_stack.back()->children.back()->str = *$1;
delete $1;
} |
@@ -2147,6 +2433,7 @@ rvalue:
hierarchical_id range {
$$ = new AstNode(AST_IDENTIFIER, $2);
$$->str = *$1;
+ SET_AST_NODE_LOC($$, @1, @1);
delete $1;
if ($2 == nullptr && ($$->str == "\\$initstate" ||
$$->str == "\\$anyconst" || $$->str == "\\$anyseq" ||
@@ -2156,6 +2443,7 @@ rvalue:
hierarchical_id non_opt_multirange {
$$ = new AstNode(AST_IDENTIFIER, $2);
$$->str = *$1;
+ SET_AST_NODE_LOC($$, @1, @1);
delete $1;
};
@@ -2274,6 +2562,7 @@ expr:
$$->children.push_back($1);
$$->children.push_back($4);
$$->children.push_back($6);
+ SET_AST_NODE_LOC($$, @1, @$);
append_attr($$, $3);
};
@@ -2281,7 +2570,7 @@ basic_expr:
rvalue {
$$ = $1;
} |
- '(' expr ')' TOK_CONSTVAL {
+ '(' expr ')' integral_number {
if ($4->compare(0, 1, "'") != 0)
frontend_verilog_yyerror("Cast operation must be applied on sized constants e.g. (<expr>)<constval> , while %s is not a sized constant.", $4->c_str());
AstNode *bits = $2;
@@ -2291,11 +2580,12 @@ basic_expr:
$$ = new AstNode(AST_TO_BITS, bits, val);
delete $4;
} |
- hierarchical_id TOK_CONSTVAL {
+ hierarchical_id integral_number {
if ($2->compare(0, 1, "'") != 0)
frontend_verilog_yyerror("Cast operation must be applied on sized constants, e.g. <ID>\'d0, while %s is not a sized constant.", $2->c_str());
AstNode *bits = new AstNode(AST_IDENTIFIER);
bits->str = *$1;
+ SET_AST_NODE_LOC(bits, @1, @1);
AstNode *val = const2ast(*$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
if (val == NULL)
log_error("Value conversion failed: `%s'\n", $2->c_str());
@@ -2303,14 +2593,7 @@ basic_expr:
delete $1;
delete $2;
} |
- TOK_CONSTVAL TOK_CONSTVAL {
- $$ = const2ast(*$1 + *$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
- if ($$ == NULL || (*$2)[0] != '\'')
- log_error("Value conversion failed: `%s%s'\n", $1->c_str(), $2->c_str());
- delete $1;
- delete $2;
- } |
- TOK_CONSTVAL {
+ integral_number {
$$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
if ($$ == NULL)
log_error("Value conversion failed: `%s'\n", $1->c_str());
@@ -2323,6 +2606,7 @@ basic_expr:
if ((*$1)[j] != '_')
p[i++] = (*$1)[j], p[i] = 0;
$$->realvalue = strtod(p, &q);
+ SET_AST_NODE_LOC($$, @1, @1);
log_assert(*q == 0);
delete $1;
free(p);
@@ -2336,6 +2620,7 @@ basic_expr:
node->str = *$1;
delete $1;
ast_stack.push_back(node);
+ SET_AST_NODE_LOC(node, @1, @1);
append_attr(node, $2);
} '(' arg_list optional_comma ')' {
$$ = ast_stack.back();
@@ -2365,148 +2650,185 @@ basic_expr:
} |
'~' attr basic_expr %prec UNARY_OPS {
$$ = new AstNode(AST_BIT_NOT, $3);
+ SET_AST_NODE_LOC($$, @1, @3);
append_attr($$, $2);
} |
basic_expr '&' attr basic_expr {
$$ = new AstNode(AST_BIT_AND, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_NAND attr basic_expr {
$$ = new AstNode(AST_BIT_NOT, new AstNode(AST_BIT_AND, $1, $4));
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr '|' attr basic_expr {
$$ = new AstNode(AST_BIT_OR, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_NOR attr basic_expr {
$$ = new AstNode(AST_BIT_NOT, new AstNode(AST_BIT_OR, $1, $4));
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr '^' attr basic_expr {
$$ = new AstNode(AST_BIT_XOR, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_XNOR attr basic_expr {
$$ = new AstNode(AST_BIT_XNOR, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
'&' attr basic_expr %prec UNARY_OPS {
$$ = new AstNode(AST_REDUCE_AND, $3);
+ SET_AST_NODE_LOC($$, @1, @3);
append_attr($$, $2);
} |
OP_NAND attr basic_expr %prec UNARY_OPS {
$$ = new AstNode(AST_REDUCE_AND, $3);
+ SET_AST_NODE_LOC($$, @1, @3);
append_attr($$, $2);
$$ = new AstNode(AST_LOGIC_NOT, $$);
} |
'|' attr basic_expr %prec UNARY_OPS {
$$ = new AstNode(AST_REDUCE_OR, $3);
+ SET_AST_NODE_LOC($$, @1, @3);
append_attr($$, $2);
} |
OP_NOR attr basic_expr %prec UNARY_OPS {
$$ = new AstNode(AST_REDUCE_OR, $3);
+ SET_AST_NODE_LOC($$, @1, @3);
append_attr($$, $2);
$$ = new AstNode(AST_LOGIC_NOT, $$);
+ SET_AST_NODE_LOC($$, @1, @3);
} |
'^' attr basic_expr %prec UNARY_OPS {
$$ = new AstNode(AST_REDUCE_XOR, $3);
+ SET_AST_NODE_LOC($$, @1, @3);
append_attr($$, $2);
} |
OP_XNOR attr basic_expr %prec UNARY_OPS {
$$ = new AstNode(AST_REDUCE_XNOR, $3);
+ SET_AST_NODE_LOC($$, @1, @3);
append_attr($$, $2);
} |
basic_expr OP_SHL attr basic_expr {
$$ = new AstNode(AST_SHIFT_LEFT, $1, new AstNode(AST_TO_UNSIGNED, $4));
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_SHR attr basic_expr {
$$ = new AstNode(AST_SHIFT_RIGHT, $1, new AstNode(AST_TO_UNSIGNED, $4));
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_SSHL attr basic_expr {
$$ = new AstNode(AST_SHIFT_SLEFT, $1, new AstNode(AST_TO_UNSIGNED, $4));
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_SSHR attr basic_expr {
$$ = new AstNode(AST_SHIFT_SRIGHT, $1, new AstNode(AST_TO_UNSIGNED, $4));
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr '<' attr basic_expr {
$$ = new AstNode(AST_LT, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_LE attr basic_expr {
$$ = new AstNode(AST_LE, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_EQ attr basic_expr {
$$ = new AstNode(AST_EQ, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_NE attr basic_expr {
$$ = new AstNode(AST_NE, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_EQX attr basic_expr {
$$ = new AstNode(AST_EQX, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_NEX attr basic_expr {
$$ = new AstNode(AST_NEX, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_GE attr basic_expr {
$$ = new AstNode(AST_GE, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr '>' attr basic_expr {
$$ = new AstNode(AST_GT, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr '+' attr basic_expr {
$$ = new AstNode(AST_ADD, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr '-' attr basic_expr {
$$ = new AstNode(AST_SUB, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr '*' attr basic_expr {
$$ = new AstNode(AST_MUL, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr '/' attr basic_expr {
$$ = new AstNode(AST_DIV, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr '%' attr basic_expr {
$$ = new AstNode(AST_MOD, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_POW attr basic_expr {
$$ = new AstNode(AST_POW, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
'+' attr basic_expr %prec UNARY_OPS {
$$ = new AstNode(AST_POS, $3);
+ SET_AST_NODE_LOC($$, @1, @3);
append_attr($$, $2);
} |
'-' attr basic_expr %prec UNARY_OPS {
$$ = new AstNode(AST_NEG, $3);
+ SET_AST_NODE_LOC($$, @1, @3);
append_attr($$, $2);
} |
basic_expr OP_LAND attr basic_expr {
$$ = new AstNode(AST_LOGIC_AND, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
basic_expr OP_LOR attr basic_expr {
$$ = new AstNode(AST_LOGIC_OR, $1, $4);
+ SET_AST_NODE_LOC($$, @1, @4);
append_attr($$, $3);
} |
'!' attr basic_expr %prec UNARY_OPS {
$$ = new AstNode(AST_LOGIC_NOT, $3);
+ SET_AST_NODE_LOC($$, @1, @3);
append_attr($$, $2);
};
@@ -2518,3 +2840,18 @@ concat_list:
$$ = $3;
$$->children.push_back($1);
};
+
+integral_number:
+ TOK_CONSTVAL { $$ = $1; } |
+ TOK_UNBASED_UNSIZED_CONSTVAL { $$ = $1; } |
+ TOK_BASE TOK_BASED_CONSTVAL {
+ $1->append(*$2);
+ $$ = $1;
+ delete $2;
+ } |
+ TOK_CONSTVAL TOK_BASE TOK_BASED_CONSTVAL {
+ $1->append(*$2).append(*$3);
+ $$ = $1;
+ delete $2;
+ delete $3;
+ };
diff --git a/kernel/driver.cc b/kernel/driver.cc
index 9040408bc..5f0959776 100644
--- a/kernel/driver.cc
+++ b/kernel/driver.cc
@@ -413,22 +413,13 @@ int main(int argc, char **argv)
scriptfile_tcl = true;
break;
case 'W':
- log_warn_regexes.push_back(std::regex(optarg,
- std::regex_constants::nosubs |
- std::regex_constants::optimize |
- std::regex_constants::egrep));
+ log_warn_regexes.push_back(YS_REGEX_COMPILE(optarg));
break;
case 'w':
- log_nowarn_regexes.push_back(std::regex(optarg,
- std::regex_constants::nosubs |
- std::regex_constants::optimize |
- std::regex_constants::egrep));
+ log_nowarn_regexes.push_back(YS_REGEX_COMPILE(optarg));
break;
case 'e':
- log_werror_regexes.push_back(std::regex(optarg,
- std::regex_constants::nosubs |
- std::regex_constants::optimize |
- std::regex_constants::egrep));
+ log_werror_regexes.push_back(YS_REGEX_COMPILE(optarg));
break;
case 'D':
vlog_defines.push_back(optarg);
@@ -558,6 +549,10 @@ int main(int argc, char **argv)
fprintf(f, "\n");
}
+ if (log_expect_no_warnings && log_warnings_count_noexpect)
+ log_error("Unexpected warnings found: %d unique messages, %d total, %d expected\n", GetSize(log_warnings),
+ log_warnings_count, log_warnings_count - log_warnings_count_noexpect);
+
if (print_stats)
{
std::string hash = log_hasher->final().substr(0, 10);
@@ -664,6 +659,8 @@ int main(int argc, char **argv)
}
#endif
+ log_check_expected();
+
yosys_atexit();
memhasher_off();
diff --git a/kernel/log.cc b/kernel/log.cc
index f5d6c488e..d84a4381e 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -41,9 +41,12 @@ YOSYS_NAMESPACE_BEGIN
std::vector<FILE*> log_files;
std::vector<std::ostream*> log_streams;
std::map<std::string, std::set<std::string>> log_hdump;
-std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;
+std::vector<YS_REGEX_TYPE> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;
+std::vector<std::pair<YS_REGEX_TYPE,LogExpectedItem>> log_expect_log, log_expect_warning, log_expect_error;
std::set<std::string> log_warnings, log_experimentals, log_experimentals_ignored;
int log_warnings_count = 0;
+int log_warnings_count_noexpect = 0;
+bool log_expect_no_warnings = false;
bool log_hdump_all = false;
FILE *log_errfile = NULL;
SHA1 *log_hasher = NULL;
@@ -68,6 +71,8 @@ int string_buf_index = -1;
static struct timeval initial_tv = { 0, 0 };
static bool next_print_log = false;
static int log_newline_count = 0;
+static bool check_expected_logs = true;
+static bool display_error_log_msg = true;
static void log_id_cache_clear()
{
@@ -162,7 +167,7 @@ void logv(const char *format, va_list ap)
{
log_warn_regex_recusion_guard = true;
- if (log_warn_regexes.empty())
+ if (log_warn_regexes.empty() && log_expect_log.empty())
{
linebuffer.clear();
}
@@ -172,8 +177,13 @@ void logv(const char *format, va_list ap)
if (!linebuffer.empty() && linebuffer.back() == '\n') {
for (auto &re : log_warn_regexes)
- if (std::regex_search(linebuffer, re))
+ if (YS_REGEX_NS::regex_search(linebuffer, re))
log_warning("Found log message matching -W regex:\n%s", str.c_str());
+
+ for (auto &item : log_expect_log)
+ if (YS_REGEX_NS::regex_search(linebuffer, item.first))
+ item.second.current_count++;
+
linebuffer.clear();
}
}
@@ -228,7 +238,7 @@ static void logv_warning_with_prefix(const char *prefix,
bool suppressed = false;
for (auto &re : log_nowarn_regexes)
- if (std::regex_search(message, re))
+ if (YS_REGEX_NS::regex_search(message, re))
suppressed = true;
if (suppressed)
@@ -241,9 +251,16 @@ static void logv_warning_with_prefix(const char *prefix,
log_make_debug = 0;
for (auto &re : log_werror_regexes)
- if (std::regex_search(message, re))
+ if (YS_REGEX_NS::regex_search(message, re))
log_error("%s", message.c_str());
+ bool warning_match = false;
+ for (auto &item : log_expect_warning)
+ if (YS_REGEX_NS::regex_search(message, item.first)) {
+ item.second.current_count++;
+ warning_match = true;
+ }
+
if (log_warnings.count(message))
{
log("%s%s", prefix, message.c_str());
@@ -263,6 +280,8 @@ static void logv_warning_with_prefix(const char *prefix,
log_warnings.insert(message);
}
+ if (!warning_match)
+ log_warnings_count_noexpect++;
log_warnings_count++;
log_make_debug = bak_log_make_debug;
}
@@ -320,7 +339,8 @@ static void logv_error_with_prefix(const char *prefix,
f = stderr;
log_last_error = vstringf(format, ap);
- log("%s%s", prefix, log_last_error.c_str());
+ if (display_error_log_msg)
+ log("%s%s", prefix, log_last_error.c_str());
log_flush();
log_make_debug = bak_log_make_debug;
@@ -328,6 +348,12 @@ static void logv_error_with_prefix(const char *prefix,
if (log_error_atexit)
log_error_atexit();
+ for (auto &item : log_expect_error)
+ if (YS_REGEX_NS::regex_search(log_last_error, item.first))
+ item.second.current_count++;
+
+ if (check_expected_logs)
+ log_check_expected();
#ifdef EMSCRIPTEN
log_files = backup_log_files;
throw 0;
@@ -636,6 +662,52 @@ void log_wire(RTLIL::Wire *wire, std::string indent)
log("%s", buf.str().c_str());
}
+void log_check_expected()
+{
+ check_expected_logs = false;
+
+ for (auto &item : log_expect_warning) {
+ if (item.second.current_count == 0) {
+ log_warn_regexes.clear();
+ log_error("Expected warning pattern '%s' not found !\n", item.second.pattern.c_str());
+ }
+ if (item.second.current_count != item.second.expected_count) {
+ log_warn_regexes.clear();
+ log_error("Expected warning pattern '%s' found %d time(s), instead of %d time(s) !\n",
+ item.second.pattern.c_str(), item.second.current_count, item.second.expected_count);
+ }
+ }
+
+ for (auto &item : log_expect_log) {
+ if (item.second.current_count == 0) {
+ log_warn_regexes.clear();
+ log_error("Expected log pattern '%s' not found !\n", item.second.pattern.c_str());
+ }
+ if (item.second.current_count != item.second.expected_count) {
+ log_warn_regexes.clear();
+ log_error("Expected log pattern '%s' found %d time(s), instead of %d time(s) !\n",
+ item.second.pattern.c_str(), item.second.current_count, item.second.expected_count);
+ }
+ }
+
+ for (auto &item : log_expect_error)
+ if (item.second.current_count == item.second.expected_count) {
+ log_warn_regexes.clear();
+ log("Expected error pattern '%s' found !!!\n", item.second.pattern.c_str());
+ #ifdef EMSCRIPTEN
+ throw 0;
+ #elif defined(_MSC_VER)
+ _exit(0);
+ #else
+ _Exit(0);
+ #endif
+ } else {
+ display_error_log_msg = false;
+ log_warn_regexes.clear();
+ log_error("Expected error pattern '%s' not found !\n", item.second.pattern.c_str());
+ }
+}
+
// ---------------------------------------------------
// This is the magic behind the code coverage counters
// ---------------------------------------------------
diff --git a/kernel/log.h b/kernel/log.h
index 9db8efaa5..cd0e8185c 100644
--- a/kernel/log.h
+++ b/kernel/log.h
@@ -23,7 +23,25 @@
#define LOG_H
#include <time.h>
-#include <regex>
+
+// In GCC 4.8 std::regex is not working correctlty, in order to make features
+// using regular expressions to work replacement regex library is used
+#if defined(__GNUC__) && !defined( __clang__) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 8)
+ #include <boost/xpressive/xpressive.hpp>
+ #define YS_REGEX_TYPE boost::xpressive::sregex
+ #define YS_REGEX_NS boost::xpressive
+ #define YS_REGEX_COMPILE(param) boost::xpressive::sregex::compile(param, \
+ boost::xpressive::regex_constants::nosubs | \
+ boost::xpressive::regex_constants::optimize)
+# else
+ #include <regex>
+ #define YS_REGEX_TYPE std::regex
+ #define YS_REGEX_NS std
+ #define YS_REGEX_COMPILE(param) std::regex(param, \
+ std::regex_constants::nosubs | \
+ std::regex_constants::optimize | \
+ std::regex_constants::egrep)
+#endif
#ifndef _WIN32
# include <sys/time.h>
@@ -49,9 +67,11 @@ struct log_cmd_error_exception { };
extern std::vector<FILE*> log_files;
extern std::vector<std::ostream*> log_streams;
extern std::map<std::string, std::set<std::string>> log_hdump;
-extern std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;
+extern std::vector<YS_REGEX_TYPE> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;
extern std::set<std::string> log_warnings, log_experimentals, log_experimentals_ignored;
extern int log_warnings_count;
+extern int log_warnings_count_noexpect;
+extern bool log_expect_no_warnings;
extern bool log_hdump_all;
extern FILE *log_errfile;
extern SHA1 *log_hasher;
@@ -135,6 +155,23 @@ void log_backtrace(const char *prefix, int levels);
void log_reset_stack();
void log_flush();
+struct LogExpectedItem
+{
+ LogExpectedItem(std::string pattern, int expected) :
+ expected_count(expected),
+ current_count(0),
+ pattern(pattern)
+ {
+ }
+
+ int expected_count;
+ int current_count;
+ std::string pattern;
+};
+
+extern std::vector<std::pair<YS_REGEX_TYPE,LogExpectedItem>> log_expect_log, log_expect_warning, log_expect_error;
+void log_check_expected();
+
const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true);
const char *log_const(const RTLIL::Const &value, bool autoint = true);
const char *log_id(RTLIL::IdString id);
diff --git a/kernel/register.cc b/kernel/register.cc
index e59d59654..af8c1b8e8 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -400,6 +400,18 @@ void ScriptPass::run(std::string command, std::string info)
}
}
+void ScriptPass::run_nocheck(std::string command, std::string info)
+{
+ if (active_design == nullptr) {
+ if (info.empty())
+ log(" %s\n", command.c_str());
+ else
+ log(" %s %s\n", command.c_str(), info.c_str());
+ } else {
+ Pass::call(active_design, command);
+ }
+}
+
void ScriptPass::run_script(RTLIL::Design *design, std::string run_from, std::string run_to)
{
help_mode = false;
diff --git a/kernel/register.h b/kernel/register.h
index 4622845b6..3d89386b7 100644
--- a/kernel/register.h
+++ b/kernel/register.h
@@ -84,6 +84,7 @@ struct ScriptPass : Pass
bool check_label(std::string label, std::string info = std::string());
void run(std::string command, std::string info = std::string());
+ void run_nocheck(std::string command, std::string info = std::string());
void run_script(RTLIL::Design *design, std::string run_from = std::string(), std::string run_to = std::string());
void help_script();
};
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index f286d139f..06181b763 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -1258,8 +1258,12 @@ namespace {
param_bool(ID(SRC_POL));
param_bool(ID(DST_PEN));
param_bool(ID(DST_POL));
- param(ID(T_LIMIT));
- param(ID(T_LIMIT2));
+ param(ID(T_LIMIT_MIN));
+ param(ID(T_LIMIT_TYP));
+ param(ID(T_LIMIT_MAX));
+ param(ID(T_LIMIT2_MIN));
+ param(ID(T_LIMIT2_TYP));
+ param(ID(T_LIMIT2_MAX));
port(ID(SRC_EN), 1);
port(ID(DST_EN), 1);
port(ID(SRC), param(ID(SRC_WIDTH)));
@@ -3920,8 +3924,6 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri
cover("kernel.rtlil.sigspec.parse");
AST::current_filename = "input";
- AST::use_internal_line_num();
- AST::set_line_num(0);
std::vector<std::string> tokens;
sigspec_parse_split(tokens, str, ',');
diff --git a/kernel/timinginfo.h b/kernel/timinginfo.h
new file mode 100644
index 000000000..4b77c02e8
--- /dev/null
+++ b/kernel/timinginfo.h
@@ -0,0 +1,179 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ * (C) 2020 Eddie Hung <eddie@fpgeh.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef TIMINGINFO_H
+#define TIMINGINFO_H
+
+#include "kernel/yosys.h"
+
+YOSYS_NAMESPACE_BEGIN
+
+struct TimingInfo
+{
+ struct NameBit
+ {
+ RTLIL::IdString name;
+ int offset;
+ NameBit() : offset(0) {}
+ NameBit(const RTLIL::IdString name, int offset) : name(name), offset(offset) {}
+ explicit NameBit(const RTLIL::SigBit &b) : name(b.wire->name), offset(b.offset) {}
+ bool operator==(const NameBit& nb) const { return nb.name == name && nb.offset == offset; }
+ bool operator!=(const NameBit& nb) const { return !operator==(nb); }
+ unsigned int hash() const { return mkhash_add(name.hash(), offset); }
+ };
+ struct BitBit
+ {
+ NameBit first, second;
+ BitBit(const NameBit &first, const NameBit &second) : first(first), second(second) {}
+ BitBit(const SigBit &first, const SigBit &second) : first(first), second(second) {}
+ bool operator==(const BitBit& bb) const { return bb.first == first && bb.second == second; }
+ unsigned int hash() const { return mkhash_add(first.hash(), second.hash()); }
+ };
+
+ struct ModuleTiming
+ {
+ RTLIL::IdString type;
+ dict<BitBit, int> comb;
+ dict<NameBit, int> arrival, required;
+ };
+
+ dict<RTLIL::IdString, ModuleTiming> data;
+
+ TimingInfo()
+ {
+ }
+
+ TimingInfo(RTLIL::Design *design)
+ {
+ setup(design);
+ }
+
+ void setup(RTLIL::Design *design)
+ {
+ for (auto module : design->modules()) {
+ if (!module->get_blackbox_attribute())
+ continue;
+ setup_module(module);
+ }
+ }
+
+ const ModuleTiming& setup_module(RTLIL::Module *module)
+ {
+ auto r = data.insert(module->name);
+ log_assert(r.second);
+ auto &t = r.first->second;
+
+ for (auto cell : module->cells()) {
+ if (cell->type == ID($specify2)) {
+ auto src = cell->getPort(ID(SRC));
+ auto dst = cell->getPort(ID(DST));
+ for (const auto &c : src.chunks())
+ if (!c.wire->port_input)
+ log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src));
+ for (const auto &c : dst.chunks())
+ if (!c.wire->port_output)
+ log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", log_id(module), log_id(cell), log_signal(dst));
+ int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int();
+ int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int();
+ int max = std::max(rise_max,fall_max);
+ if (max < 0)
+ log_error("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0.\n", log_id(module), log_id(cell));
+ if (cell->getParam(ID(FULL)).as_bool()) {
+ for (const auto &s : src)
+ for (const auto &d : dst) {
+ auto r = t.comb.insert(BitBit(s,d));
+ if (!r.second)
+ log_error("Module '%s' contains multiple specify cells for SRC '%s' and DST '%s'.\n", log_id(module), log_signal(s), log_signal(d));
+ r.first->second = max;
+ }
+ }
+ else {
+ log_assert(GetSize(src) == GetSize(dst));
+ for (auto i = 0; i < GetSize(src); i++) {
+ const auto &s = src[i];
+ const auto &d = dst[i];
+ auto r = t.comb.insert(BitBit(s,d));
+ if (!r.second)
+ log_error("Module '%s' contains multiple specify cells for SRC '%s' and DST '%s'.\n", log_id(module), log_signal(s), log_signal(d));
+ r.first->second = max;
+ }
+ }
+ }
+ else if (cell->type == ID($specify3)) {
+ auto src = cell->getPort(ID(SRC));
+ auto dst = cell->getPort(ID(DST));
+ for (const auto &c : src.chunks())
+ if (!c.wire->port_input)
+ log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src));
+ for (const auto &c : dst.chunks())
+ if (!c.wire->port_output)
+ log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", log_id(module), log_id(cell), log_signal(dst));
+ int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int();
+ int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int();
+ int max = std::max(rise_max,fall_max);
+ if (max < 0)
+ log_warning("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell));
+ if (max <= 0) {
+ log_debug("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX <= 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell));
+ continue;
+ }
+ for (const auto &d : dst) {
+ auto &v = t.arrival[NameBit(d)];
+ v = std::max(v, max);
+ }
+ }
+ else if (cell->type == ID($specrule)) {
+ auto type = cell->getParam(ID(TYPE)).decode_string();
+ if (type != "$setup" && type != "$setuphold")
+ continue;
+ auto src = cell->getPort(ID(SRC));
+ auto dst = cell->getPort(ID(DST));
+ for (const auto &c : src.chunks())
+ if (!c.wire->port_input)
+ log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src));
+ for (const auto &c : dst.chunks())
+ if (!c.wire->port_input)
+ log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(dst));
+ int max = cell->getParam(ID(T_LIMIT_MAX)).as_int();
+ if (max < 0)
+ log_warning("Module '%s' contains specify cell '%s' with T_LIMIT_MAX < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell));
+ if (max <= 0) {
+ log_debug("Module '%s' contains specify cell '%s' with T_LIMIT_MAX <= 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell));
+ continue;
+ }
+ for (const auto &s : src) {
+ auto &v = t.required[NameBit(s)];
+ v = std::max(v, max);
+ }
+ }
+ }
+
+ return t;
+ }
+
+ decltype(data)::const_iterator find(RTLIL::IdString module_name) const { return data.find(module_name); }
+ decltype(data)::const_iterator end() const { return data.end(); }
+ int count(RTLIL::IdString module_name) const { return data.count(module_name); }
+ const ModuleTiming& at(RTLIL::IdString module_name) const { return data.at(module_name); }
+};
+
+YOSYS_NAMESPACE_END
+
+#endif
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 8190d8902..4cb53f05d 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -129,7 +129,7 @@ void yosys_banner()
log(" | |\n");
log(" | yosys -- Yosys Open SYnthesis Suite |\n");
log(" | |\n");
- log(" | Copyright (C) 2012 - 2019 Clifford Wolf <clifford@clifford.at> |\n");
+ log(" | Copyright (C) 2012 - 2020 Claire Wolf <claire@symbioticeda.com> |\n");
log(" | |\n");
log(" | Permission to use, copy, modify, and/or distribute this software for any |\n");
log(" | purpose with or without fee is hereby granted, provided that the above |\n");
@@ -341,7 +341,11 @@ int run_command(const std::string &command, std::function<void(const std::string
if (!process_line)
return system(command.c_str());
+#ifdef EMSCRIPTEN
+ FILE *f = nullptr;
+#else
FILE *f = popen(command.c_str(), "r");
+#endif
if (f == nullptr)
return -1;
diff --git a/manual/CHAPTER_Overview.tex b/manual/CHAPTER_Overview.tex
index 3009bf2c0..be37d8d39 100644
--- a/manual/CHAPTER_Overview.tex
+++ b/manual/CHAPTER_Overview.tex
@@ -234,6 +234,8 @@ An RTLIL::Wire object has the following properties:
\item The wire name
\item A list of attributes
\item A width (buses are just wires with a width > 1)
+\item Bus direction (MSB to LSB or vice versa)
+\item Lowest valid bit index (LSB or MSB depending on bus direction)
\item If the wire is a port: port number and direction (input/output/inout)
\end{itemize}
@@ -246,6 +248,11 @@ This makes some aspects of RTLIL more complex but enables Yosys to be used for
coarse grain synthesis where the cells of the target architecture operate on
entire signal vectors instead of single bit wires.
+In Verilog and VHDL, busses may have arbitrary bounds, and LSB can have either
+the lowest or the highest bit index. In RTLIL, bit 0 always corresponds to LSB;
+however, information from the HDL frontend is preserved so that the bus will be
+correctly indexed in error messages, backend output, constraint files, etc.
+
An RTLIL::Cell object has the following properties:
\begin{itemize}
diff --git a/manual/command-reference-manual.tex b/manual/command-reference-manual.tex
index bed6326e2..4925defe3 100644
--- a/manual/command-reference-manual.tex
+++ b/manual/command-reference-manual.tex
@@ -5350,7 +5350,7 @@ never transition from a non-zero value to a zero value.
For this proof we create the following template (test.tpl).
- ; we need QF_UFBV for this poof
+ ; we need QF_UFBV for this proof
(set-logic QF_UFBV)
; insert the auto-generated code here
diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py
index 9b4e644c0..fac5b48a4 100644
--- a/misc/py_wrap_generator.py
+++ b/misc/py_wrap_generator.py
@@ -721,6 +721,7 @@ class WClass:
name = None
namespace = None
link_type = None
+ base_class = None
id_ = None
string_id = None
hash_id = None
@@ -732,6 +733,7 @@ class WClass:
def __init__(self, name, link_type, id_, string_id = None, hash_id = None, needs_clone = False):
self.name = name
self.namespace = None
+ self.base_class = None
self.link_type = link_type
self.id_ = id_
self.string_id = string_id
@@ -804,6 +806,8 @@ class WClass:
for con in self.found_constrs:
text += con.gen_decl()
+ if self.base_class is not None:
+ text += "\n\t\tvirtual ~" + self.name + "() { };"
for var in self.found_vars:
text += var.gen_decl()
for fun in self.found_funs:
@@ -908,15 +912,19 @@ class WClass:
def gen_boost_py(self):
body = self.gen_boost_py_body()
+ base_info = ""
+ if self.base_class is not None:
+ base_info = ", bases<" + (self.base_class.name) + ">"
+
if self.link_type == link_types.derive:
- text = "\n\t\tclass_<" + self.name + ">(\"Cpp" + self.name + "\""
+ text = "\n\t\tclass_<" + self.name + base_info + ">(\"Cpp" + self.name + "\""
text += body
text += "\n\t\tclass_<" + self.name
text += "Wrap, boost::noncopyable"
text += ">(\"" + self.name + "\""
text += body
else:
- text = "\n\t\tclass_<" + self.name + ">(\"" + self.name + "\""
+ text = "\n\t\tclass_<" + self.name + base_info + ">(\"" + self.name + "\""
text += body
return text
@@ -1971,9 +1979,21 @@ def parse_header(source):
for namespace in impl_namespaces:
complete_namespace += "::" + namespace
debug("\tFound " + struct_name + " in " + complete_namespace,2)
+
+ base_class_name = None
+ if len(ugly_line.split(" : ")) > 1: # class is derived
+ deriv_str = ugly_line.split(" : ")[1]
+ if len(deriv_str.split("::")) > 1: # namespace of base class is given
+ base_class_name = deriv_str.split("::", 1)[1]
+ else:
+ base_class_name = deriv_str.split(" ")[0]
+ debug("\t " + struct_name + " is derived from " + base_class_name,2)
+ base_class = class_by_name(base_class_name)
+
class_ = (class_by_name(struct_name), ugly_line.count("{"))#calc_ident(line))
if struct_name in classnames:
class_[0].namespace = complete_namespace
+ class_[0].base_class = base_class
i += 1
continue
@@ -2142,6 +2162,21 @@ def expand_functions():
new_funs.extend(expand_function(fun))
class_.found_funs = new_funs
+def inherit_members():
+ for source in sources:
+ for class_ in source.classes:
+ if class_.base_class:
+ base_funs = copy.deepcopy(class_.base_class.found_funs)
+ for fun in base_funs:
+ fun.member_of = class_
+ fun.namespace = class_.namespace
+ base_vars = copy.deepcopy(class_.base_class.found_vars)
+ for var in base_vars:
+ var.member_of = class_
+ var.namespace = class_.namespace
+ class_.found_funs.extend(base_funs)
+ class_.found_vars.extend(base_vars)
+
def clean_duplicates():
for source in sources:
for class_ in source.classes:
@@ -2178,6 +2213,7 @@ def gen_wrappers(filename, debug_level_ = 0):
parse_header(source)
expand_functions()
+ inherit_members()
clean_duplicates()
import shutil
diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc
index 07a5d3ddc..60f20fa6d 100644
--- a/passes/cmds/Makefile.inc
+++ b/passes/cmds/Makefile.inc
@@ -1,4 +1,5 @@
+OBJS += passes/cmds/exec.o
OBJS += passes/cmds/add.o
OBJS += passes/cmds/delete.o
OBJS += passes/cmds/design.o
@@ -33,3 +34,4 @@ OBJS += passes/cmds/blackbox.o
OBJS += passes/cmds/ltp.o
OBJS += passes/cmds/bugpoint.o
OBJS += passes/cmds/scratchpad.o
+OBJS += passes/cmds/logger.o
diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc
index dd05ac81f..c49b8bf5d 100644
--- a/passes/cmds/add.cc
+++ b/passes/cmds/add.cc
@@ -22,26 +22,61 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
+static bool is_formal_celltype(const std::string &celltype)
+{
+ if(celltype == "assert" || celltype == "assume" || celltype == "live" || celltype == "fair" || celltype == "cover")
+ return true;
+ else
+ return false;
+}
+
+static void add_formal(RTLIL::Module *module, const std::string &celltype, const std::string &name, const std::string &enable_name)
+{
+ std::string escaped_name = RTLIL::escape_id(name);
+ std::string escaped_enable_name = (enable_name != "") ? RTLIL::escape_id(enable_name) : "";
+ RTLIL::Wire *wire = module->wire(escaped_name);
+ log_assert(is_formal_celltype(celltype));
+
+ if (wire == nullptr) {
+ log_error("Could not find wire with name \"%s\".\n", name.c_str());
+ }
+ else {
+ RTLIL::Cell *formal_cell = module->addCell(NEW_ID, "$" + celltype);
+ formal_cell->setPort(ID(A), wire);
+ if(enable_name == "") {
+ formal_cell->setPort(ID(EN), State::S1);
+ log("Added $%s cell for wire \"%s.%s\"\n", celltype.c_str(), module->name.str().c_str(), name.c_str());
+ }
+ else {
+ RTLIL::Wire *enable_wire = module->wire(escaped_enable_name);
+ if(enable_wire == nullptr)
+ log_error("Could not find enable wire with name \"%s\".\n", enable_name.c_str());
+
+ formal_cell->setPort(ID(EN), enable_wire);
+ log("Added $%s cell for wire \"%s.%s\" enabled by wire \"%s.%s\".\n", celltype.c_str(), module->name.str().c_str(), name.c_str(), module->name.str().c_str(), enable_name.c_str());
+ }
+ }
+}
+
static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string name, int width, bool flag_input, bool flag_output, bool flag_global)
{
- RTLIL::Wire *wire = NULL;
+ RTLIL::Wire *wire = nullptr;
name = RTLIL::escape_id(name);
if (module->count_id(name) != 0)
{
- if (module->wires_.count(name) > 0)
- wire = module->wires_.at(name);
+ wire = module->wire(name);
- if (wire != NULL && wire->width != width)
- wire = NULL;
+ if (wire != nullptr && wire->width != width)
+ wire = nullptr;
- if (wire != NULL && wire->port_input != flag_input)
- wire = NULL;
+ if (wire != nullptr && wire->port_input != flag_input)
+ wire = nullptr;
- if (wire != NULL && wire->port_output != flag_output)
- wire = NULL;
+ if (wire != nullptr && wire->port_output != flag_output)
+ wire = nullptr;
- if (wire == NULL)
+ if (wire == nullptr)
log_cmd_error("Found incompatible object with same name in module %s!\n", module->name.c_str());
log("Module %s already has such an object.\n", module->name.c_str());
@@ -53,7 +88,6 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
wire->port_output = flag_output;
if (flag_input || flag_output) {
- wire->port_id = module->wires_.size();
module->fixup_ports();
}
@@ -63,21 +97,20 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
if (!flag_global)
return;
- for (auto &it : module->cells_)
+ for (auto cell : module->cells())
{
- if (design->modules_.count(it.second->type) == 0)
+ RTLIL::Module *mod = design->module(cell->type);
+ if (mod == nullptr)
continue;
-
- RTLIL::Module *mod = design->modules_.at(it.second->type);
if (!design->selected_whole_module(mod->name))
continue;
if (mod->get_blackbox_attribute())
continue;
- if (it.second->hasPort(name))
+ if (cell->hasPort(name))
continue;
- it.second->setPort(name, wire);
- log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), it.first.c_str(), it.second->type.c_str());
+ cell->setPort(name, wire);
+ log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), cell->name.c_str(), cell->type.c_str());
}
}
@@ -106,6 +139,12 @@ struct AddPass : public Pass {
log("selected modules.\n");
log("\n");
log("\n");
+ log(" add {-assert|-assume|-live|-fair|-cover} <name1> [-if <name2>]\n");
+ log("\n");
+ log("Add an $assert, $assume, etc. cell connected to a wire named name1, with its\n");
+ log("enable signal optionally connected to a wire named name2 (default: 1'b1).\n");
+ log("\n");
+ log("\n");
log(" add -mod <name[s]>\n");
log("\n");
log("Add module[s] with the specified name[s].\n");
@@ -115,6 +154,7 @@ struct AddPass : public Pass {
{
std::string command;
std::string arg_name;
+ std::string enable_name = "";
bool arg_flag_input = false;
bool arg_flag_output = false;
bool arg_flag_global = false;
@@ -144,6 +184,17 @@ struct AddPass : public Pass {
argidx++;
break;
}
+ if (arg.length() > 0 && arg[0] == '-' && is_formal_celltype(arg.substr(1))) {
+ if (argidx + 1 >= args.size())
+ break;
+ command = arg.substr(1);
+ arg_name = args[++argidx];
+ if (argidx + 2 < args.size() && args[argidx + 1] == "-if") {
+ enable_name = args[argidx + 2];
+ argidx += 2;
+ }
+ continue;
+ }
break;
}
@@ -155,17 +206,23 @@ struct AddPass : public Pass {
extra_args(args, argidx, design);
- for (auto &mod : design->modules_)
+ bool selected_anything = false;
+ for (auto module : design->modules())
{
- RTLIL::Module *module = mod.second;
+ log_assert(module != nullptr);
if (!design->selected_whole_module(module->name))
continue;
if (module->get_bool_attribute("\\blackbox"))
continue;
- if (command == "wire")
+ selected_anything = true;
+ if (is_formal_celltype(command))
+ add_formal(module, command, arg_name, enable_name);
+ else if (command == "wire")
add_wire(design, module, arg_name, arg_width, arg_flag_input, arg_flag_output, arg_flag_global);
}
+ if (!selected_anything)
+ log_warning("No modules selected, or only blackboxes. Nothing was added.\n");
}
} AddPass;
diff --git a/passes/cmds/exec.cc b/passes/cmds/exec.cc
new file mode 100644
index 000000000..399cb0ebb
--- /dev/null
+++ b/passes/cmds/exec.cc
@@ -0,0 +1,203 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 - 2020 Claire Wolf <claire@symbioticeda.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/register.h"
+#include "kernel/log.h"
+#include <cstdio>
+
+#if defined(_WIN32)
+# define WIFEXITED(x) 1
+# define WIFSIGNALED(x) 0
+# define WIFSTOPPED(x) 0
+# define WEXITSTATUS(x) ((x) & 0xff)
+# define WTERMSIG(x) SIGTERM
+#else
+# include <sys/wait.h>
+#endif
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct ExecPass : public Pass {
+ ExecPass() : Pass("exec", "execute commands in the operating system shell") { }
+ void help() YS_OVERRIDE
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" exec [options] -- [command]\n");
+ log("\n");
+ log("Execute a command in the operating system shell. All supplied arguments are\n");
+ log("concatenated and passed as a command to popen(3). Whitespace is not guaranteed\n");
+ log("to be preserved, even if quoted. stdin and stderr are not connected, while stdout is\n");
+ log("logged unless the \"-q\" option is specified.\n");
+ log("\n");
+ log("\n");
+ log(" -q\n");
+ log(" Suppress stdout and stderr from subprocess\n");
+ log("\n");
+ log(" -expect-return <int>\n");
+ log(" Generate an error if popen() does not return specified value.\n");
+ log(" May only be specified once; the final specified value is controlling\n");
+ log(" if specified multiple times.\n");
+ log("\n");
+ log(" -expect-stdout <regex>\n");
+ log(" Generate an error if the specified regex does not match any line\n");
+ log(" in subprocess's stdout. May be specified multiple times.\n");
+ log("\n");
+ log(" -not-expect-stdout <regex>\n");
+ log(" Generate an error if the specified regex matches any line\n");
+ log(" in subprocess's stdout. May be specified multiple times.\n");
+ log("\n");
+ log("\n");
+ log(" Example: exec -q -expect-return 0 -- echo \"bananapie\" | grep \"nana\"\n");
+ log("\n");
+ log("\n");
+ }
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ std::string cmd = "";
+ char buf[1024] = {};
+ std::string linebuf = "";
+ bool flag_cmd = false;
+ bool flag_quiet = false;
+ bool flag_expect_return = false;
+ int expect_return_value = 0;
+ bool flag_expect_stdout = false;
+ struct expect_stdout_elem {
+ bool matched;
+ bool polarity; //true: this regex must match at least one line
+ //false: this regex must not match any line
+ std::string str;
+ YS_REGEX_TYPE re;
+
+ expect_stdout_elem() : matched(false), polarity(true), str(), re(){};
+ };
+ std::vector<expect_stdout_elem> expect_stdout;
+
+ if(args.size() == 0)
+ log_cmd_error("No command provided.\n");
+
+ for(size_t argidx = 1; argidx < args.size(); ++argidx) {
+ if (flag_cmd) {
+ cmd += args[argidx] + (argidx != (args.size() - 1)? " " : "");
+ } else {
+ if (args[argidx] == "--")
+ flag_cmd = true;
+ else if (args[argidx] == "-q")
+ flag_quiet = true;
+ else if (args[argidx] == "-expect-return") {
+ flag_expect_return = true;
+ ++argidx;
+ if (argidx >= args.size())
+ log_cmd_error("No expected return value specified.\n");
+
+ expect_return_value = atoi(args[argidx].c_str());
+ } else if (args[argidx] == "-expect-stdout") {
+ flag_expect_stdout = true;
+ ++argidx;
+ if (argidx >= args.size())
+ log_cmd_error("No expected regular expression specified.\n");
+
+ try{
+ expect_stdout_elem x;
+ x.str = args[argidx];
+ x.re = YS_REGEX_COMPILE(args[argidx]);
+ expect_stdout.push_back(x);
+ } catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
+ }
+ } else if (args[argidx] == "-not-expect-stdout") {
+ flag_expect_stdout = true;
+ ++argidx;
+ if (argidx >= args.size())
+ log_cmd_error("No expected regular expression specified.\n");
+
+ try{
+ expect_stdout_elem x;
+ x.str = args[argidx];
+ x.re = YS_REGEX_COMPILE(args[argidx]);
+ x.polarity = false;
+ expect_stdout.push_back(x);
+ } catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
+ }
+
+ } else
+ log_cmd_error("Unknown option \"%s\" or \"--\" doesn\'t precede command.", args[argidx].c_str());
+ }
+ }
+
+ log_header(design, "Executing command \"%s\".\n", cmd.c_str());
+ log_push();
+
+ fflush(stdout);
+ bool keep_reading = true;
+ int status = 0;
+ int retval = 0;
+
+#ifndef EMSCRIPTEN
+ FILE *f = popen(cmd.c_str(), "r");
+ if (f == nullptr)
+ log_cmd_error("errno %d after popen() returned NULL.\n", errno);
+ while (keep_reading) {
+ keep_reading = (fgets(buf, sizeof(buf), f) != nullptr);
+ linebuf += buf;
+ memset(buf, 0, sizeof(buf));
+
+ auto pos = linebuf.find('\n');
+ while (pos != std::string::npos) {
+ std::string line = linebuf.substr(0, pos);
+ linebuf.erase(0, pos + 1);
+ if (!flag_quiet)
+ log("%s\n", line.c_str());
+
+ if (flag_expect_stdout)
+ for(auto &x : expect_stdout)
+ if (YS_REGEX_NS::regex_search(line, x.re))
+ x.matched = true;
+
+ pos = linebuf.find('\n');
+ }
+ }
+ status = pclose(f);
+#endif
+
+ if(WIFEXITED(status)) {
+ retval = WEXITSTATUS(status);
+ }
+ else if(WIFSIGNALED(status)) {
+ retval = WTERMSIG(status);
+ }
+ else if(WIFSTOPPED(status)) {
+ retval = WSTOPSIG(status);
+ }
+
+ if (flag_expect_return && retval != expect_return_value)
+ log_cmd_error("Return value %d did not match expected return value %d.\n", retval, expect_return_value);
+
+ if (flag_expect_stdout)
+ for (auto &x : expect_stdout)
+ if (x.polarity ^ x.matched)
+ log_cmd_error("Command stdout did%s have a line matching given regex \"%s\".\n", (x.polarity? " not" : ""), x.str.c_str());
+
+ log_pop();
+ }
+} ExecPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/logger.cc b/passes/cmds/logger.cc
new file mode 100644
index 000000000..9a27952d4
--- /dev/null
+++ b/passes/cmds/logger.cc
@@ -0,0 +1,183 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2020 Miodrag Milanovic <clifford@clifford.at>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/register.h"
+#include "kernel/log.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct LoggerPass : public Pass {
+ LoggerPass() : Pass("logger", "set logger properties") { }
+ void help() YS_OVERRIDE
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" logger [options]\n");
+ log("\n");
+ log("This command sets global logger properties, also available using command line\n");
+ log("options.\n");
+ log("\n");
+ log(" -[no]time\n");
+ log(" enable/disable display of timestamp in log output.\n");
+ log("\n");
+ log(" -[no]stderr\n");
+ log(" enable/disable logging errors to stderr.\n");
+ log("\n");
+ log(" -warn regex\n");
+ log(" print a warning for all log messages matching the regex.\n");
+ log("\n");
+ log(" -nowarn regex\n");
+ log(" if a warning message matches the regex, it is printed as regular\n");
+ log(" message instead.\n");
+ log("\n");
+ log(" -werror regex\n");
+ log(" if a warning message matches the regex, it is printed as error\n");
+ log(" message instead and the tool terminates with a nonzero return code.\n");
+ log("\n");
+ log(" -[no]debug\n");
+ log(" globally enable/disable debug log messages.\n");
+ log("\n");
+ log(" -experimental <feature>\n");
+ log(" do not print warnings for the specified experimental feature\n");
+ log("\n");
+ log(" -expect <type> <regex> <expected_count>\n");
+ log(" expect log,warning or error to appear. In case of error return code is 0.\n");
+ log("\n");
+ log(" -expect-no-warnings\n");
+ log(" gives error in case there is at least one warning that is not expected.\n");
+ log("\n");
+ }
+
+ void execute(std::vector<std::string> args, RTLIL::Design * design) YS_OVERRIDE
+ {
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+
+ if (args[argidx] == "-time") {
+ log_time = true;
+ log("Enabled timestamp in logs.\n");
+ continue;
+ }
+ if (args[argidx] == "-notime") {
+ log_time = false;
+ log("Disabled timestamp in logs.\n");
+ continue;
+ }
+ if (args[argidx] == "-stderr") {
+ log_error_stderr = true;
+ log("Enabled loggint errors to stderr.\n");
+ continue;
+ }
+ if (args[argidx] == "-nostderr") {
+ log_error_stderr = false;
+ log("Disabled loggint errors to stderr.\n");
+ continue;
+ }
+ if (args[argidx] == "-warn" && argidx+1 < args.size()) {
+ std::string pattern = args[++argidx];
+ if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
+ try {
+ log("Added regex '%s' for warnings to warn list.\n", pattern.c_str());
+ log_warn_regexes.push_back(YS_REGEX_COMPILE(pattern));
+ }
+ catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
+ }
+ continue;
+ }
+ if (args[argidx] == "-nowarn" && argidx+1 < args.size()) {
+ std::string pattern = args[++argidx];
+ if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
+ try {
+ log("Added regex '%s' for warnings to nowarn list.\n", pattern.c_str());
+ log_nowarn_regexes.push_back(YS_REGEX_COMPILE(pattern));
+ }
+ catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
+ }
+ continue;
+ }
+ if (args[argidx] == "-werror" && argidx+1 < args.size()) {
+ std::string pattern = args[++argidx];
+ if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
+ try {
+ log("Added regex '%s' for warnings to werror list.\n", pattern.c_str());
+ log_werror_regexes.push_back(YS_REGEX_COMPILE(pattern));
+ }
+ catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
+ }
+ continue;
+ }
+ if (args[argidx] == "-debug") {
+ log_force_debug = 1;
+ log("Enabled debug log messages.\n");
+ continue;
+ }
+ if (args[argidx] == "-nodebug") {
+ log_force_debug = 0;
+ log("Disabled debug log messages.\n");
+ continue;
+ }
+ if (args[argidx] == "-experimental" && argidx+1 < args.size()) {
+ std::string value = args[++argidx];
+ log("Added '%s' experimental ignore list.\n", value.c_str());
+ log_experimentals_ignored.insert(value);
+ continue;
+ }
+ if (args[argidx] == "-expect" && argidx+3 < args.size()) {
+ std::string type = args[++argidx];
+ if (type!="error" && type!="warning" && type!="log")
+ log_cmd_error("Expect command require type to be 'log', 'warning' or 'error' !\n");
+ if (type=="error" && log_expect_error.size()>0)
+ log_cmd_error("Only single error message can be expected !\n");
+ std::string pattern = args[++argidx];
+ if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
+ int count = atoi(args[++argidx].c_str());
+ if (count<=0)
+ log_cmd_error("Number of expected messages must be higher then 0 !\n");
+ if (type=="error" && count!=1)
+ log_cmd_error("Expected error message occurrences must be 1 !\n");
+ log("Added regex '%s' for warnings to expected %s list.\n", pattern.c_str(), type.c_str());
+ try {
+ if (type=="error")
+ log_expect_error.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count)));
+ else if (type=="warning")
+ log_expect_warning.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count)));
+ else
+ log_expect_log.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count)));
+ }
+ catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
+ }
+ continue;
+ }
+ if (args[argidx] == "-expect-no-warnings") {
+ log_expect_no_warnings = true;
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design, false);
+ }
+} LoggerPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc
index 0f1f05ccb..b64b077e4 100644
--- a/passes/cmds/select.cc
+++ b/passes/cmds/select.cc
@@ -58,7 +58,7 @@ static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char
{
RTLIL::SigSpec sig_value;
- if (!RTLIL::SigSpec::parse(sig_value, NULL, pattern))
+ if (!RTLIL::SigSpec::parse(sig_value, nullptr, pattern))
return false;
RTLIL::Const pattern_value = sig_value.as_const();
@@ -152,27 +152,26 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs)
RTLIL::Selection new_sel(false);
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (lhs.selected_whole_module(mod_it.first))
+ if (lhs.selected_whole_module(mod->name))
continue;
- if (!lhs.selected_module(mod_it.first)) {
- new_sel.selected_modules.insert(mod_it.first);
+ if (!lhs.selected_module(mod->name)) {
+ new_sel.selected_modules.insert(mod->name);
continue;
}
- RTLIL::Module *mod = mod_it.second;
- for (auto &it : mod->wires_)
- if (!lhs.selected_member(mod_it.first, it.first))
- new_sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (!lhs.selected_member(mod->name, wire->name))
+ new_sel.selected_members[mod->name].insert(wire->name);
for (auto &it : mod->memories)
- if (!lhs.selected_member(mod_it.first, it.first))
- new_sel.selected_members[mod->name].insert(it.first);
- for (auto &it : mod->cells_)
- if (!lhs.selected_member(mod_it.first, it.first))
+ if (!lhs.selected_member(mod->name, it.first))
new_sel.selected_members[mod->name].insert(it.first);
+ for (auto cell : mod->cells())
+ if (!lhs.selected_member(mod->name, cell->name))
+ new_sel.selected_members[mod->name].insert(cell->name);
for (auto &it : mod->processes)
- if (!lhs.selected_member(mod_it.first, it.first))
+ if (!lhs.selected_member(mod->name, it.first))
new_sel.selected_members[mod->name].insert(it.first);
}
@@ -223,15 +222,15 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c
static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs)
{
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (lhs.selected_whole_module(mod_it.first))
+ if (lhs.selected_whole_module(mod->name))
{
- for (auto &cell_it : mod_it.second->cells_)
+ for (auto cell : mod->cells())
{
- if (design->modules_.count(cell_it.second->type) == 0)
+ if (design->module(cell->type) == nullptr)
continue;
- lhs.selected_modules.insert(cell_it.second->type);
+ lhs.selected_modules.insert(cell->type);
}
}
}
@@ -240,21 +239,21 @@ static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs)
static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection &lhs)
{
RTLIL::Selection new_sel(false);
- for (auto &mod_it : design->modules_)
- if (lhs.selected_module(mod_it.first))
- for (auto &cell_it : mod_it.second->cells_)
- if (lhs.selected_member(mod_it.first, cell_it.first) && design->modules_.count(cell_it.second->type))
- new_sel.selected_modules.insert(cell_it.second->type);
+ for (auto mod : design->modules())
+ if (lhs.selected_module(mod->name))
+ for (auto cell : mod->cells())
+ if (lhs.selected_member(mod->name, cell->name) && (design->module(cell->type) != nullptr))
+ new_sel.selected_modules.insert(cell->type);
lhs = new_sel;
}
static void select_op_module_to_cells(RTLIL::Design *design, RTLIL::Selection &lhs)
{
RTLIL::Selection new_sel(false);
- for (auto &mod_it : design->modules_)
- for (auto &cell_it : mod_it.second->cells_)
- if (design->modules_.count(cell_it.second->type) && lhs.selected_whole_module(cell_it.second->type))
- new_sel.selected_members[mod_it.first].insert(cell_it.first);
+ for (auto mod : design->modules())
+ for (auto cell : mod->cells())
+ if ((design->module(cell->type) != nullptr) && lhs.selected_whole_module(cell->type))
+ new_sel.selected_members[mod->name].insert(cell->name);
lhs = new_sel;
}
@@ -268,23 +267,23 @@ static void select_op_fullmod(RTLIL::Design *design, RTLIL::Selection &lhs)
static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs)
{
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (lhs.selected_whole_module(mod_it.first))
+ if (lhs.selected_whole_module(mod->name))
continue;
- if (!lhs.selected_module(mod_it.first))
+ if (!lhs.selected_module(mod->name))
continue;
- SigMap sigmap(mod_it.second);
+ SigMap sigmap(mod);
SigPool selected_bits;
- for (auto &it : mod_it.second->wires_)
- if (lhs.selected_member(mod_it.first, it.first))
- selected_bits.add(sigmap(it.second));
+ for (auto wire : mod->wires())
+ if (lhs.selected_member(mod->name, wire->name))
+ selected_bits.add(sigmap(wire));
- for (auto &it : mod_it.second->wires_)
- if (!lhs.selected_member(mod_it.first, it.first) && selected_bits.check_any(sigmap(it.second)))
- lhs.selected_members[mod_it.first].insert(it.first);
+ for (auto wire : mod->wires())
+ if (!lhs.selected_member(mod->name, wire->name) && selected_bits.check_any(sigmap(wire)))
+ lhs.selected_members[mod->name].insert(wire->name);
}
}
@@ -323,8 +322,8 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R
if (!rhs.full_selection && rhs.selected_modules.size() == 0 && rhs.selected_members.size() == 0)
return;
lhs.full_selection = false;
- for (auto &it : design->modules_)
- lhs.selected_modules.insert(it.first);
+ for (auto mod : design->modules())
+ lhs.selected_modules.insert(mod->name);
}
for (auto &it : rhs.selected_modules) {
@@ -334,19 +333,19 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R
for (auto &it : rhs.selected_members)
{
- if (design->modules_.count(it.first) == 0)
+ if (design->module(it.first) == nullptr)
continue;
- RTLIL::Module *mod = design->modules_[it.first];
+ RTLIL::Module *mod = design->module(it.first);
if (lhs.selected_modules.count(mod->name) > 0)
{
- for (auto &it : mod->wires_)
- lhs.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ lhs.selected_members[mod->name].insert(wire->name);
for (auto &it : mod->memories)
lhs.selected_members[mod->name].insert(it.first);
- for (auto &it : mod->cells_)
- lhs.selected_members[mod->name].insert(it.first);
+ for (auto cell : mod->cells())
+ lhs.selected_members[mod->name].insert(cell->name);
for (auto &it : mod->processes)
lhs.selected_members[mod->name].insert(it.first);
lhs.selected_modules.erase(mod->name);
@@ -367,8 +366,8 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co
if (lhs.full_selection) {
lhs.full_selection = false;
- for (auto &it : design->modules_)
- lhs.selected_modules.insert(it.first);
+ for (auto mod : design->modules())
+ lhs.selected_modules.insert(mod->name);
}
std::vector<RTLIL::IdString> del_list;
@@ -431,18 +430,17 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
{
int sel_objects = 0;
bool is_input, is_output;
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (lhs.selected_whole_module(mod_it.first) || !lhs.selected_module(mod_it.first))
+ if (lhs.selected_whole_module(mod->name) || !lhs.selected_module(mod->name))
continue;
- RTLIL::Module *mod = mod_it.second;
std::set<RTLIL::Wire*> selected_wires;
auto selected_members = lhs.selected_members[mod->name];
- for (auto &it : mod->wires_)
- if (lhs.selected_member(mod_it.first, it.first) && limits.count(it.first) == 0)
- selected_wires.insert(it.second);
+ for (auto wire : mod->wires())
+ if (lhs.selected_member(mod->name, wire->name) && limits.count(wire->name) == 0)
+ selected_wires.insert(wire);
for (auto &conn : mod->connections())
{
@@ -450,7 +448,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
std::vector<RTLIL::SigBit> conn_rhs = conn.second.to_sigbit_vector();
for (size_t i = 0; i < conn_lhs.size(); i++) {
- if (conn_lhs[i].wire == NULL || conn_rhs[i].wire == NULL)
+ if (conn_lhs[i].wire == nullptr || conn_rhs[i].wire == nullptr)
continue;
if (mode != 'i' && selected_wires.count(conn_rhs[i].wire) && selected_members.count(conn_lhs[i].wire->name) == 0)
lhs.selected_members[mod->name].insert(conn_lhs[i].wire->name), sel_objects++, max_objects--;
@@ -459,15 +457,15 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
}
}
- for (auto &cell : mod->cells_)
- for (auto &conn : cell.second->connections())
+ for (auto cell : mod->cells())
+ for (auto &conn : cell->connections())
{
char last_mode = '-';
- if (eval_only && !yosys_celltypes.cell_evaluable(cell.second->type))
+ if (eval_only && !yosys_celltypes.cell_evaluable(cell->type))
goto exclude_match;
for (auto &rule : rules) {
last_mode = rule.mode;
- if (rule.cell_types.size() > 0 && rule.cell_types.count(cell.second->type) == 0)
+ if (rule.cell_types.size() > 0 && rule.cell_types.count(cell->type) == 0)
continue;
if (rule.port_names.size() > 0 && rule.port_names.count(conn.first) == 0)
continue;
@@ -479,14 +477,14 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
if (last_mode == '+')
goto exclude_match;
include_match:
- is_input = mode == 'x' || ct.cell_input(cell.second->type, conn.first);
- is_output = mode == 'x' || ct.cell_output(cell.second->type, conn.first);
+ is_input = mode == 'x' || ct.cell_input(cell->type, conn.first);
+ is_output = mode == 'x' || ct.cell_output(cell->type, conn.first);
for (auto &chunk : conn.second.chunks())
- if (chunk.wire != NULL) {
- if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && selected_members.count(cell.first) == 0)
+ if (chunk.wire != nullptr) {
+ if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && selected_members.count(cell->name) == 0)
if (mode == 'x' || (mode == 'i' && is_output) || (mode == 'o' && is_input))
- lhs.selected_members[mod->name].insert(cell.first), sel_objects++, max_objects--;
- if (max_objects != 0 && selected_members.count(cell.first) > 0 && limits.count(cell.first) == 0 && selected_members.count(chunk.wire->name) == 0)
+ lhs.selected_members[mod->name].insert(cell->name), sel_objects++, max_objects--;
+ if (max_objects != 0 && selected_members.count(cell->name) > 0 && limits.count(cell->name) == 0 && selected_members.count(chunk.wire->name) == 0)
if (mode == 'x' || (mode == 'i' && is_input) || (mode == 'o' && is_output))
lhs.selected_members[mod->name].insert(chunk.wire->name), sel_objects++, max_objects--;
}
@@ -627,9 +625,13 @@ static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &se
}
}
-static void select_stmt(RTLIL::Design *design, std::string arg)
+static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_empty_warning = false)
{
std::string arg_mod, arg_memb;
+ std::unordered_map<std::string, bool> arg_mod_found;
+ std::unordered_map<std::string, bool> arg_memb_found;
+ auto isalpha = [](const char &x) { return ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z')); };
+ bool prefixed = GetSize(arg) >= 2 && isalpha(arg[0]) && arg[1] == ':';
if (arg.size() == 0)
return;
@@ -760,19 +762,21 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
if (!design->selected_active_module.empty()) {
arg_mod = design->selected_active_module;
arg_memb = arg;
+ if (!prefixed) arg_memb_found[arg_memb] = false;
} else
- if (GetSize(arg) >= 2 && arg[0] >= 'a' && arg[0] <= 'z' && arg[1] == ':') {
+ if (prefixed && arg[0] >= 'a' && arg[0] <= 'z') {
arg_mod = "*", arg_memb = arg;
} else {
size_t pos = arg.find('/');
if (pos == std::string::npos) {
- if (arg.find(':') == std::string::npos || arg.compare(0, 1, "A") == 0)
- arg_mod = arg;
- else
- arg_mod = "*", arg_memb = arg;
+ arg_mod = arg;
+ if (!prefixed) arg_mod_found[arg_mod] = false;
} else {
arg_mod = arg.substr(0, pos);
+ if (!prefixed) arg_mod_found[arg_mod] = false;
arg_memb = arg.substr(pos+1);
+ bool arg_memb_prefixed = GetSize(arg_memb) >= 2 && isalpha(arg_memb[0]) && arg_memb[1] == ':';
+ if (!arg_memb_prefixed) arg_memb_found[arg_memb] = false;
}
}
@@ -785,56 +789,61 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
}
sel.full_selection = false;
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->modules())
{
if (arg_mod.compare(0, 2, "A:") == 0) {
- if (!match_attr(mod_it.second->attributes, arg_mod.substr(2)))
+ if (!match_attr(mod->attributes, arg_mod.substr(2)))
+ continue;
+ } else
+ if (arg_mod.compare(0, 2, "N:") == 0) {
+ if (!match_ids(mod->name, arg_mod.substr(2)))
continue;
} else
- if (!match_ids(mod_it.first, arg_mod))
+ if (!match_ids(mod->name, arg_mod))
continue;
+ else
+ arg_mod_found[arg_mod] = true;
if (arg_memb == "") {
- sel.selected_modules.insert(mod_it.first);
+ sel.selected_modules.insert(mod->name);
continue;
}
- RTLIL::Module *mod = mod_it.second;
if (arg_memb.compare(0, 2, "w:") == 0) {
- for (auto &it : mod->wires_)
- if (match_ids(it.first, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (match_ids(wire->name, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(wire->name);
} else
if (arg_memb.compare(0, 2, "i:") == 0) {
- for (auto &it : mod->wires_)
- if (it.second->port_input && match_ids(it.first, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (wire->port_input && match_ids(wire->name, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(wire->name);
} else
if (arg_memb.compare(0, 2, "o:") == 0) {
- for (auto &it : mod->wires_)
- if (it.second->port_output && match_ids(it.first, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (wire->port_output && match_ids(wire->name, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(wire->name);
} else
if (arg_memb.compare(0, 2, "x:") == 0) {
- for (auto &it : mod->wires_)
- if ((it.second->port_input || it.second->port_output) && match_ids(it.first, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if ((wire->port_input || wire->port_output) && match_ids(wire->name, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(wire->name);
} else
if (arg_memb.compare(0, 2, "s:") == 0) {
size_t delim = arg_memb.substr(2).find(':');
if (delim == std::string::npos) {
int width = atoi(arg_memb.substr(2).c_str());
- for (auto &it : mod->wires_)
- if (it.second->width == width)
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (wire->width == width)
+ sel.selected_members[mod->name].insert(wire->name);
} else {
std::string min_str = arg_memb.substr(2, delim);
std::string max_str = arg_memb.substr(2+delim+1);
int min_width = min_str.empty() ? 0 : atoi(min_str.c_str());
int max_width = max_str.empty() ? -1 : atoi(max_str.c_str());
- for (auto &it : mod->wires_)
- if (min_width <= it.second->width && (it.second->width <= max_width || max_width == -1))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (min_width <= wire->width && (wire->width <= max_width || max_width == -1))
+ sel.selected_members[mod->name].insert(wire->name);
}
} else
if (arg_memb.compare(0, 2, "m:") == 0) {
@@ -842,15 +851,15 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
if (match_ids(it.first, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(it.first);
} else
- if (arg_memb.compare(0, 2, "c:") ==0) {
- for (auto &it : mod->cells_)
- if (match_ids(it.first, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ if (arg_memb.compare(0, 2, "c:") == 0) {
+ for (auto cell : mod->cells())
+ if (match_ids(cell->name, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(cell->name);
} else
if (arg_memb.compare(0, 2, "t:") == 0) {
- for (auto &it : mod->cells_)
- if (match_ids(it.second->type, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto cell : mod->cells())
+ if (match_ids(cell->type, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(cell->name);
} else
if (arg_memb.compare(0, 2, "p:") == 0) {
for (auto &it : mod->processes)
@@ -858,62 +867,82 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
sel.selected_members[mod->name].insert(it.first);
} else
if (arg_memb.compare(0, 2, "a:") == 0) {
- for (auto &it : mod->wires_)
- if (match_attr(it.second->attributes, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (match_attr(wire->attributes, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(wire->name);
for (auto &it : mod->memories)
if (match_attr(it.second->attributes, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(it.first);
- for (auto &it : mod->cells_)
- if (match_attr(it.second->attributes, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto cell : mod->cells())
+ if (match_attr(cell->attributes, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(cell->name);
for (auto &it : mod->processes)
if (match_attr(it.second->attributes, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(it.first);
} else
if (arg_memb.compare(0, 2, "r:") == 0) {
- for (auto &it : mod->cells_)
- if (match_attr(it.second->parameters, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto cell : mod->cells())
+ if (match_attr(cell->parameters, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(cell->name);
} else {
+ std::string orig_arg_memb = arg_memb;
if (arg_memb.compare(0, 2, "n:") == 0)
arg_memb = arg_memb.substr(2);
- for (auto &it : mod->wires_)
- if (match_ids(it.first, arg_memb))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (match_ids(wire->name, arg_memb)) {
+ sel.selected_members[mod->name].insert(wire->name);
+ arg_memb_found[orig_arg_memb] = true;
+ }
for (auto &it : mod->memories)
- if (match_ids(it.first, arg_memb))
- sel.selected_members[mod->name].insert(it.first);
- for (auto &it : mod->cells_)
- if (match_ids(it.first, arg_memb))
+ if (match_ids(it.first, arg_memb)) {
sel.selected_members[mod->name].insert(it.first);
+ arg_memb_found[orig_arg_memb] = true;
+ }
+ for (auto cell : mod->cells())
+ if (match_ids(cell->name, arg_memb)) {
+ sel.selected_members[mod->name].insert(cell->name);
+ arg_memb_found[orig_arg_memb] = true;
+ }
for (auto &it : mod->processes)
- if (match_ids(it.first, arg_memb))
+ if (match_ids(it.first, arg_memb)) {
sel.selected_members[mod->name].insert(it.first);
+ arg_memb_found[orig_arg_memb] = true;
+ }
}
}
select_filter_active_mod(design, work_stack.back());
+
+ for (auto &it : arg_mod_found) {
+ if (it.second == false && !disable_empty_warning) {
+ log_warning("Selection \"%s\" did not match any module.\n", it.first.c_str());
+ }
+ }
+ for (auto &it : arg_memb_found) {
+ if (it.second == false && !disable_empty_warning) {
+ log_warning("Selection \"%s\" did not match any object.\n", it.first.c_str());
+ }
+ }
}
static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel)
{
std::string desc = "Selection contains:\n";
- for (auto mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (sel->selected_module(mod_it.first)) {
- for (auto &it : mod_it.second->wires_)
- if (sel->selected_member(mod_it.first, it.first))
- desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
- for (auto &it : mod_it.second->memories)
- if (sel->selected_member(mod_it.first, it.first))
- desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
- for (auto &it : mod_it.second->cells_)
- if (sel->selected_member(mod_it.first, it.first))
- desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
- for (auto &it : mod_it.second->processes)
- if (sel->selected_member(mod_it.first, it.first))
- desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
+ if (sel->selected_module(mod->name)) {
+ for (auto wire : mod->wires())
+ if (sel->selected_member(mod->name, wire->name))
+ desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name));
+ for (auto &it : mod->memories)
+ if (sel->selected_member(mod->name, it.first))
+ desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first));
+ for (auto cell : mod->cells())
+ if (sel->selected_member(mod->name, cell->name))
+ desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name));
+ for (auto &it : mod->processes)
+ if (sel->selected_member(mod->name, it.first))
+ desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first));
}
}
return desc;
@@ -928,7 +957,7 @@ void handle_extra_select_args(Pass *pass, vector<string> args, size_t argidx, si
work_stack.clear();
for (; argidx < args_size; argidx++) {
if (args[argidx].compare(0, 1, "-") == 0) {
- if (pass != NULL)
+ if (pass != nullptr)
pass->cmd_error(args, argidx, "Unexpected option in selection arguments.");
else
log_cmd_error("Unexpected option in selection arguments.");
@@ -1077,6 +1106,10 @@ struct SelectPass : public Pass {
log(" all modules with an attribute matching the given pattern\n");
log(" in addition to = also <, <=, >=, and > are supported\n");
log("\n");
+ log(" N:<pattern>\n");
+ log(" all modules with a name matching the given pattern\n");
+ log(" (i.e. 'N:' is optional as it is the default matching rule)\n");
+ log("\n");
log("An <obj_pattern> can be an object name, wildcard expression, or one of\n");
log("the following:\n");
log("\n");
@@ -1267,7 +1300,7 @@ struct SelectPass : public Pass {
}
if (arg == "-module" && argidx+1 < args.size()) {
RTLIL::IdString mod_name = RTLIL::escape_id(args[++argidx]);
- if (design->modules_.count(mod_name) == 0)
+ if (design->module(mod_name) == nullptr)
log_cmd_error("No such module: %s\n", id2cstr(mod_name));
design->selected_active_module = mod_name.str();
got_module = true;
@@ -1279,7 +1312,8 @@ struct SelectPass : public Pass {
}
if (arg.size() > 0 && arg[0] == '-')
log_cmd_error("Unknown option %s.\n", arg.c_str());
- select_stmt(design, arg);
+ bool disable_empty_warning = count_mode || assert_none || assert_any || (assert_count != -1) || (assert_max != -1) || (assert_min != -1);
+ select_stmt(design, arg, disable_empty_warning);
sel_str += " " + arg;
}
@@ -1353,41 +1387,41 @@ struct SelectPass : public Pass {
if (list_mode || count_mode || !write_file.empty())
{
- #define LOG_OBJECT(...) { if (list_mode) log(__VA_ARGS__); if (f != NULL) fprintf(f, __VA_ARGS__); total_count++; }
+ #define LOG_OBJECT(...) { if (list_mode) log(__VA_ARGS__); if (f != nullptr) fprintf(f, __VA_ARGS__); total_count++; }
int total_count = 0;
- FILE *f = NULL;
+ FILE *f = nullptr;
if (!write_file.empty()) {
f = fopen(write_file.c_str(), "w");
yosys_output_files.insert(write_file);
- if (f == NULL)
+ if (f == nullptr)
log_error("Can't open '%s' for writing: %s\n", write_file.c_str(), strerror(errno));
}
RTLIL::Selection *sel = &design->selection_stack.back();
if (work_stack.size() > 0)
sel = &work_stack.back();
sel->optimize(design);
- for (auto mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (sel->selected_whole_module(mod_it.first) && list_mode)
- log("%s\n", id2cstr(mod_it.first));
- if (sel->selected_module(mod_it.first)) {
- for (auto &it : mod_it.second->wires_)
- if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
- for (auto &it : mod_it.second->memories)
- if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
- for (auto &it : mod_it.second->cells_)
- if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
- for (auto &it : mod_it.second->processes)
- if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
+ if (sel->selected_whole_module(mod->name) && list_mode)
+ log("%s\n", id2cstr(mod->name));
+ if (sel->selected_module(mod->name)) {
+ for (auto wire : mod->wires())
+ if (sel->selected_member(mod->name, wire->name))
+ LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name))
+ for (auto &it : mod->memories)
+ if (sel->selected_member(mod->name, it.first))
+ LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first))
+ for (auto cell : mod->cells())
+ if (sel->selected_member(mod->name, cell->name))
+ LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name))
+ for (auto &it : mod->processes)
+ if (sel->selected_member(mod->name, it.first))
+ LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first))
}
}
if (count_mode)
log("%d objects.\n", total_count);
- if (f != NULL)
+ if (f != nullptr)
fclose(f);
#undef LOG_OBJECT
return;
@@ -1448,19 +1482,19 @@ struct SelectPass : public Pass {
log_cmd_error("No selection to check.\n");
RTLIL::Selection *sel = &work_stack.back();
sel->optimize(design);
- for (auto mod_it : design->modules_)
- if (sel->selected_module(mod_it.first)) {
- for (auto &it : mod_it.second->wires_)
- if (sel->selected_member(mod_it.first, it.first))
+ for (auto mod : design->modules())
+ if (sel->selected_module(mod->name)) {
+ for (auto wire : mod->wires())
+ if (sel->selected_member(mod->name, wire->name))
total_count++;
- for (auto &it : mod_it.second->memories)
- if (sel->selected_member(mod_it.first, it.first))
+ for (auto &it : mod->memories)
+ if (sel->selected_member(mod->name, it.first))
total_count++;
- for (auto &it : mod_it.second->cells_)
- if (sel->selected_member(mod_it.first, it.first))
+ for (auto cell : mod->cells())
+ if (sel->selected_member(mod->name, cell->name))
total_count++;
- for (auto &it : mod_it.second->processes)
- if (sel->selected_member(mod_it.first, it.first))
+ for (auto &it : mod->processes)
+ if (sel->selected_member(mod->name, it.first))
total_count++;
}
if (assert_count >= 0 && assert_count != total_count)
@@ -1581,15 +1615,13 @@ struct CdPass : public Pass {
std::string modname = RTLIL::escape_id(args[1]);
- if (design->modules_.count(modname) == 0 && !design->selected_active_module.empty()) {
- RTLIL::Module *module = NULL;
- if (design->modules_.count(design->selected_active_module) > 0)
- module = design->modules_.at(design->selected_active_module);
- if (module != NULL && module->cells_.count(modname) > 0)
- modname = module->cells_.at(modname)->type.str();
+ if (design->module(modname) == nullptr && !design->selected_active_module.empty()) {
+ RTLIL::Module *module = design->module(design->selected_active_module);
+ if (module != nullptr && module->cell(modname) != nullptr)
+ modname = module->cell(modname)->type.str();
}
- if (design->modules_.count(modname) > 0) {
+ if (design->module(modname) != nullptr) {
design->selected_active_module = modname;
design->selection_stack.back() = RTLIL::Selection();
select_filter_active_mod(design, design->selection_stack.back());
diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc
index eeef24bde..e0d428811 100644
--- a/passes/cmds/show.cc
+++ b/passes/cmds/show.cc
@@ -668,6 +668,10 @@ struct ShowPass : public Pass {
log(" -notitle\n");
log(" do not add the module name as graph title to the dot file\n");
log("\n");
+ log(" -nobg\n");
+ log(" don't run viewer in the background, IE wait for the viewer tool to\n");
+ log(" exit before returning\n");
+ log("\n");
log("When no <format> is specified, 'dot' is used. When no <format> and <viewer> is\n");
log("specified, 'xdot' is used to display the schematic (POSIX systems only).\n");
log("\n");
@@ -706,6 +710,7 @@ struct ShowPass : public Pass {
bool flag_abbreviate = true;
bool flag_notitle = false;
bool custom_prefix = false;
+ std::string background = "&";
RTLIL::IdString colorattr;
size_t argidx;
@@ -787,6 +792,10 @@ struct ShowPass : public Pass {
flag_notitle = true;
continue;
}
+ if (arg == "-nobg") {
+ background= "";
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -859,21 +868,19 @@ struct ShowPass : public Pass {
// system()/cmd.exe does not understand single quotes nor
// background tasks on Windows. So we have to pause yosys
// until the viewer exits.
- #define VIEW_CMD "%s \"%s\""
+ std::string cmd = stringf("%s \"%s\"", viewer_exe.c_str(), out_file.c_str());
#else
- #define VIEW_CMD "%s '%s' &"
+ std::string cmd = stringf("%s '%s' %s", viewer_exe.c_str(), out_file.c_str(), background.c_str());
#endif
- std::string cmd = stringf(VIEW_CMD, viewer_exe.c_str(), out_file.c_str());
- #undef VIEW_CMD
log("Exec: %s\n", cmd.c_str());
if (run_command(cmd) != 0)
log_cmd_error("Shell command failed!\n");
} else
if (format.empty()) {
#ifdef __APPLE__
- std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' &", getuid(), dot_file.c_str(), dot_file.c_str());
+ std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' %s", getuid(), dot_file.c_str(), dot_file.c_str(), background.c_str());
#else
- std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' &", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str());
+ std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' %s", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), background.c_str());
#endif
log("Exec: %s\n", cmd.c_str());
if (run_command(cmd) != 0)
diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc
index a85c3bec0..0f7b4d106 100644
--- a/passes/fsm/fsm_extract.cc
+++ b/passes/fsm/fsm_extract.cc
@@ -422,11 +422,7 @@ struct FsmExtractPass : public Pass {
log_header(design, "Executing FSM_EXTRACT pass (extracting FSM from design).\n");
extra_args(args, 1, design);
- CellTypes ct;
- ct.setup_internals();
- ct.setup_internals_mem();
- ct.setup_stdcells();
- ct.setup_stdcells_mem();
+ CellTypes ct(design);
for (auto &mod_it : design->modules_)
{
diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc
index ec242aa1f..3b4f33a60 100644
--- a/passes/hierarchy/submod.cc
+++ b/passes/hierarchy/submod.cc
@@ -20,6 +20,7 @@
#include "kernel/register.h"
#include "kernel/celltypes.h"
#include "kernel/log.h"
+#include "kernel/sigtools.h"
#include <stdlib.h>
#include <stdio.h>
#include <set>
@@ -32,49 +33,56 @@ struct SubmodWorker
CellTypes ct;
RTLIL::Design *design;
RTLIL::Module *module;
+ SigMap sigmap;
bool copy_mode;
+ bool hidden_mode;
std::string opt_name;
struct SubModule
{
std::string name, full_name;
- std::set<RTLIL::Cell*> cells;
+ pool<RTLIL::Cell*> cells;
};
std::map<std::string, SubModule> submodules;
struct wire_flags_t {
RTLIL::Wire *new_wire;
- bool is_int_driven, is_int_used, is_ext_driven, is_ext_used;
- wire_flags_t() : new_wire(NULL), is_int_driven(false), is_int_used(false), is_ext_driven(false), is_ext_used(false) { }
+ RTLIL::Const is_int_driven;
+ bool is_int_used, is_ext_driven, is_ext_used;
+ wire_flags_t(RTLIL::Wire* wire) : new_wire(NULL), is_int_driven(State::S0, GetSize(wire)), is_int_used(false), is_ext_driven(false), is_ext_used(false) { }
};
std::map<RTLIL::Wire*, wire_flags_t> wire_flags;
bool flag_found_something;
- void flag_wire(RTLIL::Wire *wire, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used)
+ void flag_wire(RTLIL::Wire *wire, bool create, bool set_int_used, bool set_ext_driven, bool set_ext_used)
{
if (wire_flags.count(wire) == 0) {
if (!create)
return;
- wire_flags[wire] = wire_flags_t();
+ wire_flags.emplace(wire, wire);
}
- if (set_int_driven)
- wire_flags[wire].is_int_driven = true;
if (set_int_used)
- wire_flags[wire].is_int_used = true;
+ wire_flags.at(wire).is_int_used = true;
if (set_ext_driven)
- wire_flags[wire].is_ext_driven = true;
+ wire_flags.at(wire).is_ext_driven = true;
if (set_ext_used)
- wire_flags[wire].is_ext_used = true;
+ wire_flags.at(wire).is_ext_used = true;
flag_found_something = true;
}
void flag_signal(const RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used)
{
for (auto &c : sig.chunks())
- if (c.wire != NULL)
- flag_wire(c.wire, create, set_int_driven, set_int_used, set_ext_driven, set_ext_used);
+ if (c.wire != NULL) {
+ flag_wire(c.wire, create, set_int_used, set_ext_driven, set_ext_used);
+ if (set_int_driven)
+ for (int i = c.offset; i < c.offset+c.width; i++) {
+ wire_flags.at(c.wire).is_int_driven[i] = State::S1;
+ flag_found_something = true;
+ }
+ }
}
void handle_submodule(SubModule &submod)
@@ -127,27 +135,39 @@ struct SubmodWorker
flags.is_ext_driven = true;
if (wire->port_output)
flags.is_ext_used = true;
+ else {
+ auto sig = sigmap(wire);
+ for (auto c : sig.chunks())
+ if (c.wire && c.wire->port_output) {
+ flags.is_ext_used = true;
+ break;
+ }
+ }
bool new_wire_port_input = false;
bool new_wire_port_output = false;
- if (flags.is_int_driven && flags.is_ext_used)
+ if (!flags.is_int_driven.is_fully_zero() && flags.is_ext_used)
new_wire_port_output = true;
if (flags.is_ext_driven && flags.is_int_used)
new_wire_port_input = true;
- if (flags.is_int_driven && flags.is_ext_driven)
+ if (!flags.is_int_driven.is_fully_zero() && flags.is_ext_driven)
new_wire_port_input = true, new_wire_port_output = true;
std::string new_wire_name = wire->name.str();
if (new_wire_port_input || new_wire_port_output) {
- while (new_wire_name[0] == '$') {
- std::string next_wire_name = stringf("\\n%d", auto_name_counter++);
- if (all_wire_names.count(next_wire_name) == 0) {
- all_wire_names.insert(next_wire_name);
- new_wire_name = next_wire_name;
+ if (new_wire_name[0] == '$')
+ while (1) {
+ std::string next_wire_name = stringf("%s\\n%d", hidden_mode ? "$submod" : "", auto_name_counter++);
+ if (all_wire_names.count(next_wire_name) == 0) {
+ all_wire_names.insert(next_wire_name);
+ new_wire_name = next_wire_name;
+ break;
+ }
}
- }
+ else if (hidden_mode)
+ new_wire_name = stringf("$submod%s", new_wire_name.c_str());
}
RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name, wire->width);
@@ -155,6 +175,22 @@ struct SubmodWorker
new_wire->port_output = new_wire_port_output;
new_wire->start_offset = wire->start_offset;
new_wire->attributes = wire->attributes;
+ if (!flags.is_int_driven.is_fully_zero()) {
+ new_wire->attributes.erase(ID(init));
+ auto sig = sigmap(wire);
+ for (int i = 0; i < GetSize(sig); i++) {
+ if (flags.is_int_driven[i] == State::S0)
+ continue;
+ if (!sig[i].wire)
+ continue;
+ auto it = sig[i].wire->attributes.find(ID(init));
+ if (it != sig[i].wire->attributes.end()) {
+ auto jt = new_wire->attributes.insert(std::make_pair(ID(init), Const(State::Sx, GetSize(sig)))).first;
+ jt->second[i] = it->second[sig[i].offset];
+ it->second[sig[i].offset] = State::Sx;
+ }
+ }
+ }
if (new_wire->port_input && new_wire->port_output)
log(" signal %s: inout %s\n", wire->name.c_str(), new_wire->name.c_str());
@@ -177,7 +213,7 @@ struct SubmodWorker
for (auto &bit : conn.second)
if (bit.wire != NULL) {
log_assert(wire_flags.count(bit.wire) > 0);
- bit.wire = wire_flags[bit.wire].new_wire;
+ bit.wire = wire_flags.at(bit.wire).new_wire;
}
log(" cell %s (%s)\n", new_cell->name.c_str(), new_cell->type.c_str());
if (!copy_mode)
@@ -189,16 +225,27 @@ struct SubmodWorker
RTLIL::Cell *new_cell = module->addCell(submod.full_name, submod.full_name);
for (auto &it : wire_flags)
{
- RTLIL::Wire *old_wire = it.first;
+ RTLIL::SigSpec old_sig = sigmap(it.first);
RTLIL::Wire *new_wire = it.second.new_wire;
- if (new_wire->port_id > 0)
- new_cell->setPort(new_wire->name, RTLIL::SigSpec(old_wire));
+ if (new_wire->port_id > 0) {
+ if (new_wire->port_output)
+ for (int i = 0; i < GetSize(old_sig); i++) {
+ auto &b = old_sig[i];
+ // Prevents "ERROR: Mismatch in directionality ..." when flattening
+ if (!b.wire)
+ b = module->addWire(NEW_ID);
+ // Prevents "Warning: multiple conflicting drivers ..."
+ else if (!it.second.is_int_driven[i])
+ b = module->addWire(NEW_ID);
+ }
+ new_cell->setPort(new_wire->name, old_sig);
+ }
}
}
}
- SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, std::string opt_name = std::string()) :
- design(design), module(module), copy_mode(copy_mode), opt_name(opt_name)
+ SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, bool hidden_mode = false, std::string opt_name = std::string()) :
+ design(design), module(module), sigmap(module), copy_mode(copy_mode), hidden_mode(hidden_mode), opt_name(opt_name)
{
if (!design->selected_whole_module(module->name) && opt_name.empty())
return;
@@ -219,6 +266,12 @@ struct SubmodWorker
ct.setup_stdcells_mem();
ct.setup_design(design);
+ for (auto port : module->ports) {
+ auto wire = module->wire(port);
+ if (wire->port_output)
+ sigmap.add(wire);
+ }
+
if (opt_name.empty())
{
for (auto &it : module->wires_)
@@ -273,7 +326,7 @@ struct SubmodPass : public Pass {
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" submod [-copy] [selection]\n");
+ log(" submod [options] [selection]\n");
log("\n");
log("This pass identifies all cells with the 'submod' attribute and moves them to\n");
log("a newly created module. The value of the attribute is used as name for the\n");
@@ -285,16 +338,20 @@ struct SubmodPass : public Pass {
log("This pass only operates on completely selected modules with no processes\n");
log("or memories.\n");
log("\n");
+ log(" -copy\n");
+ log(" by default the cells are 'moved' from the source module and the source\n");
+ log(" module will use an instance of the new module after this command is\n");
+ log(" finished. call with -copy to not modify the source module.\n");
log("\n");
- log(" submod -name <name> [-copy] [selection]\n");
- log("\n");
- log("As above, but don't use the 'submod' attribute but instead use the selection.\n");
- log("Only objects from one module might be selected. The value of the -name option\n");
- log("is used as the value of the 'submod' attribute above.\n");
+ log(" -name <name>\n");
+ log(" don't use the 'submod' attribute but instead use the selection. only\n");
+ log(" objects from one module might be selected. the value of the -name option\n");
+ log(" is used as the value of the 'submod' attribute instead.\n");
log("\n");
- log("By default the cells are 'moved' from the source module and the source module\n");
- log("will use an instance of the new module after this command is finished. Call\n");
- log("with -copy to not modify the source module.\n");
+ log(" -hidden\n");
+ log(" instead of creating submodule ports with public names, create ports with\n");
+ log(" private names so that a subsequent 'flatten; clean' call will restore the\n");
+ log(" original module with original public names.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -304,6 +361,7 @@ struct SubmodPass : public Pass {
std::string opt_name;
bool copy_mode = false;
+ bool hidden_mode = false;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
@@ -315,6 +373,10 @@ struct SubmodPass : public Pass {
copy_mode = true;
continue;
}
+ if (args[argidx] == "-hidden") {
+ hidden_mode = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -335,7 +397,7 @@ struct SubmodPass : public Pass {
queued_modules.push_back(mod_it.first);
for (auto &modname : queued_modules)
if (design->modules_.count(modname) != 0) {
- SubmodWorker worker(design, design->modules_[modname], copy_mode);
+ SubmodWorker worker(design, design->modules_[modname], copy_mode, hidden_mode);
handled_modules.insert(modname);
did_something = true;
}
@@ -358,7 +420,7 @@ struct SubmodPass : public Pass {
else {
Pass::call_on_module(design, module, "opt_clean");
log_header(design, "Continuing SUBMOD pass.\n");
- SubmodWorker worker(design, module, copy_mode, opt_name);
+ SubmodWorker worker(design, module, copy_mode, hidden_mode, opt_name);
}
}
diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc
index 2f69b3d4c..cac265a52 100644
--- a/passes/opt/opt_clean.cc
+++ b/passes/opt/opt_clean.cc
@@ -53,18 +53,24 @@ struct keep_cache_t
cache[module] = true;
if (!module->get_bool_attribute(ID::keep)) {
- bool found_keep = false;
- for (auto cell : module->cells())
- if (query(cell)) found_keep = true;
- cache[module] = found_keep;
+ bool found_keep = false;
+ for (auto cell : module->cells())
+ if (query(cell, true /* ignore_specify */)) {
+ found_keep = true;
+ break;
+ }
+ cache[module] = found_keep;
}
return cache[module];
}
- bool query(Cell *cell)
+ bool query(Cell *cell, bool ignore_specify = false)
{
- if (cell->type.in(ID($memwr), ID($meminit), ID($assert), ID($assume), ID($live), ID($fair), ID($cover), ID($specify2), ID($specify3), ID($specrule)))
+ if (cell->type.in(ID($memwr), ID($meminit), ID($assert), ID($assume), ID($live), ID($fair), ID($cover)))
+ return true;
+
+ if (!ignore_specify && cell->type.in(ID($specify2), ID($specify3), ID($specrule)))
return true;
if (cell->has_keep_attr())
diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc
index 49ef40061..742433935 100644
--- a/passes/sat/miter.cc
+++ b/passes/sat/miter.cc
@@ -66,50 +66,48 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
RTLIL::IdString gate_name = RTLIL::escape_id(args[argidx++]);
RTLIL::IdString miter_name = RTLIL::escape_id(args[argidx++]);
- if (design->modules_.count(gold_name) == 0)
+ if (design->module(gold_name) == nullptr)
log_cmd_error("Can't find gold module %s!\n", gold_name.c_str());
- if (design->modules_.count(gate_name) == 0)
+ if (design->module(gate_name) == nullptr)
log_cmd_error("Can't find gate module %s!\n", gate_name.c_str());
- if (design->modules_.count(miter_name) != 0)
+ if (design->module(miter_name) != nullptr)
log_cmd_error("There is already a module %s!\n", miter_name.c_str());
- RTLIL::Module *gold_module = design->modules_.at(gold_name);
- RTLIL::Module *gate_module = design->modules_.at(gate_name);
+ RTLIL::Module *gold_module = design->module(gold_name);
+ RTLIL::Module *gate_module = design->module(gate_name);
- for (auto &it : gold_module->wires_) {
- RTLIL::Wire *w1 = it.second, *w2;
- if (w1->port_id == 0)
+ for (auto gold_wire : gold_module->wires()) {
+ if (gold_wire->port_id == 0)
continue;
- if (gate_module->wires_.count(it.second->name) == 0)
+ RTLIL::Wire *gate_wire = gate_module->wire(gold_wire->name);
+ if (gate_wire == nullptr)
goto match_gold_port_error;
- w2 = gate_module->wires_.at(it.second->name);
- if (w1->port_input != w2->port_input)
+ if (gold_wire->port_input != gate_wire->port_input)
goto match_gold_port_error;
- if (w1->port_output != w2->port_output)
+ if (gold_wire->port_output != gate_wire->port_output)
goto match_gold_port_error;
- if (w1->width != w2->width)
+ if (gold_wire->width != gate_wire->width)
goto match_gold_port_error;
continue;
match_gold_port_error:
- log_cmd_error("No matching port in gate module was found for %s!\n", it.second->name.c_str());
+ log_cmd_error("No matching port in gate module was found for %s!\n", gold_wire->name.c_str());
}
- for (auto &it : gate_module->wires_) {
- RTLIL::Wire *w1 = it.second, *w2;
- if (w1->port_id == 0)
+ for (auto gate_wire : gate_module->wires()) {
+ if (gate_wire->port_id == 0)
continue;
- if (gold_module->wires_.count(it.second->name) == 0)
+ RTLIL::Wire *gold_wire = gold_module->wire(gate_wire->name);
+ if (gold_wire == nullptr)
goto match_gate_port_error;
- w2 = gold_module->wires_.at(it.second->name);
- if (w1->port_input != w2->port_input)
+ if (gate_wire->port_input != gold_wire->port_input)
goto match_gate_port_error;
- if (w1->port_output != w2->port_output)
+ if (gate_wire->port_output != gold_wire->port_output)
goto match_gate_port_error;
- if (w1->width != w2->width)
+ if (gate_wire->width != gold_wire->width)
goto match_gate_port_error;
continue;
match_gate_port_error:
- log_cmd_error("No matching port in gold module was found for %s!\n", it.second->name.c_str());
+ log_cmd_error("No matching port in gold module was found for %s!\n", gate_wire->name.c_str());
}
log("Creating miter cell \"%s\" with gold cell \"%s\" and gate cell \"%s\".\n", RTLIL::id2cstr(miter_name), RTLIL::id2cstr(gold_name), RTLIL::id2cstr(gate_name));
@@ -123,73 +121,71 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
RTLIL::SigSpec all_conditions;
- for (auto &it : gold_module->wires_)
+ for (auto gold_wire : gold_module->wires())
{
- RTLIL::Wire *w1 = it.second;
-
- if (w1->port_input)
+ if (gold_wire->port_input)
{
- RTLIL::Wire *w2 = miter_module->addWire("\\in_" + RTLIL::unescape_id(w1->name), w1->width);
- w2->port_input = true;
+ RTLIL::Wire *w = miter_module->addWire("\\in_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width);
+ w->port_input = true;
- gold_cell->setPort(w1->name, w2);
- gate_cell->setPort(w1->name, w2);
+ gold_cell->setPort(gold_wire->name, w);
+ gate_cell->setPort(gold_wire->name, w);
}
- if (w1->port_output)
+ if (gold_wire->port_output)
{
- RTLIL::Wire *w2_gold = miter_module->addWire("\\gold_" + RTLIL::unescape_id(w1->name), w1->width);
- w2_gold->port_output = flag_make_outputs;
+ RTLIL::Wire *w_gold = miter_module->addWire("\\gold_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width);
+ w_gold->port_output = flag_make_outputs;
- RTLIL::Wire *w2_gate = miter_module->addWire("\\gate_" + RTLIL::unescape_id(w1->name), w1->width);
- w2_gate->port_output = flag_make_outputs;
+ RTLIL::Wire *w_gate = miter_module->addWire("\\gate_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width);
+ w_gate->port_output = flag_make_outputs;
- gold_cell->setPort(w1->name, w2_gold);
- gate_cell->setPort(w1->name, w2_gate);
+ gold_cell->setPort(gold_wire->name, w_gold);
+ gate_cell->setPort(gold_wire->name, w_gate);
RTLIL::SigSpec this_condition;
if (flag_ignore_gold_x)
{
- RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w2_gold->width);
- for (int i = 0; i < w2_gold->width; i++) {
+ RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w_gold->width);
+ for (int i = 0; i < w_gold->width; i++) {
RTLIL::Cell *eqx_cell = miter_module->addCell(NEW_ID, "$eqx");
eqx_cell->parameters["\\A_WIDTH"] = 1;
eqx_cell->parameters["\\B_WIDTH"] = 1;
eqx_cell->parameters["\\Y_WIDTH"] = 1;
eqx_cell->parameters["\\A_SIGNED"] = 0;
eqx_cell->parameters["\\B_SIGNED"] = 0;
- eqx_cell->setPort("\\A", RTLIL::SigSpec(w2_gold, i));
+ eqx_cell->setPort("\\A", RTLIL::SigSpec(w_gold, i));
eqx_cell->setPort("\\B", RTLIL::State::Sx);
eqx_cell->setPort("\\Y", gold_x.extract(i, 1));
}
- RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w2_gold->width);
- RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w2_gate->width);
+ RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w_gold->width);
+ RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w_gate->width);
RTLIL::Cell *or_gold_cell = miter_module->addCell(NEW_ID, "$or");
- or_gold_cell->parameters["\\A_WIDTH"] = w2_gold->width;
- or_gold_cell->parameters["\\B_WIDTH"] = w2_gold->width;
- or_gold_cell->parameters["\\Y_WIDTH"] = w2_gold->width;
+ or_gold_cell->parameters["\\A_WIDTH"] = w_gold->width;
+ or_gold_cell->parameters["\\B_WIDTH"] = w_gold->width;
+ or_gold_cell->parameters["\\Y_WIDTH"] = w_gold->width;
or_gold_cell->parameters["\\A_SIGNED"] = 0;
or_gold_cell->parameters["\\B_SIGNED"] = 0;
- or_gold_cell->setPort("\\A", w2_gold);
+ or_gold_cell->setPort("\\A", w_gold);
or_gold_cell->setPort("\\B", gold_x);
or_gold_cell->setPort("\\Y", gold_masked);
RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, "$or");
- or_gate_cell->parameters["\\A_WIDTH"] = w2_gate->width;
- or_gate_cell->parameters["\\B_WIDTH"] = w2_gate->width;
- or_gate_cell->parameters["\\Y_WIDTH"] = w2_gate->width;
+ or_gate_cell->parameters["\\A_WIDTH"] = w_gate->width;
+ or_gate_cell->parameters["\\B_WIDTH"] = w_gate->width;
+ or_gate_cell->parameters["\\Y_WIDTH"] = w_gate->width;
or_gate_cell->parameters["\\A_SIGNED"] = 0;
or_gate_cell->parameters["\\B_SIGNED"] = 0;
- or_gate_cell->setPort("\\A", w2_gate);
+ or_gate_cell->setPort("\\A", w_gate);
or_gate_cell->setPort("\\B", gold_x);
or_gate_cell->setPort("\\Y", gate_masked);
RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx");
- eq_cell->parameters["\\A_WIDTH"] = w2_gold->width;
- eq_cell->parameters["\\B_WIDTH"] = w2_gate->width;
+ eq_cell->parameters["\\A_WIDTH"] = w_gold->width;
+ eq_cell->parameters["\\B_WIDTH"] = w_gate->width;
eq_cell->parameters["\\Y_WIDTH"] = 1;
eq_cell->parameters["\\A_SIGNED"] = 0;
eq_cell->parameters["\\B_SIGNED"] = 0;
@@ -201,20 +197,20 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
else
{
RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx");
- eq_cell->parameters["\\A_WIDTH"] = w2_gold->width;
- eq_cell->parameters["\\B_WIDTH"] = w2_gate->width;
+ eq_cell->parameters["\\A_WIDTH"] = w_gold->width;
+ eq_cell->parameters["\\B_WIDTH"] = w_gate->width;
eq_cell->parameters["\\Y_WIDTH"] = 1;
eq_cell->parameters["\\A_SIGNED"] = 0;
eq_cell->parameters["\\B_SIGNED"] = 0;
- eq_cell->setPort("\\A", w2_gold);
- eq_cell->setPort("\\B", w2_gate);
+ eq_cell->setPort("\\A", w_gold);
+ eq_cell->setPort("\\B", w_gate);
eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID));
this_condition = eq_cell->getPort("\\Y");
}
if (flag_make_outcmp)
{
- RTLIL::Wire *w_cmp = miter_module->addWire("\\cmp_" + RTLIL::unescape_id(w1->name));
+ RTLIL::Wire *w_cmp = miter_module->addWire("\\cmp_" + RTLIL::unescape_id(gold_wire->name));
w_cmp->port_output = true;
miter_module->connect(RTLIL::SigSig(w_cmp, this_condition));
}
@@ -285,9 +281,9 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL
IdString module_name = RTLIL::escape_id(args[argidx++]);
IdString miter_name = argidx < args.size() ? RTLIL::escape_id(args[argidx++]) : "";
- if (design->modules_.count(module_name) == 0)
+ if (design->module(module_name) == nullptr)
log_cmd_error("Can't find module %s!\n", module_name.c_str());
- if (!miter_name.empty() && design->modules_.count(miter_name) != 0)
+ if (!miter_name.empty() && design->module(miter_name) != nullptr)
log_cmd_error("There is already a module %s!\n", miter_name.c_str());
Module *module = design->module(module_name);
diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc
index 581652a41..e6c189c3e 100644
--- a/passes/techmap/abc.cc
+++ b/passes/techmap/abc.cc
@@ -1553,6 +1553,11 @@ struct AbcPass : public Pass {
show_tempdir = design->scratchpad_get_bool("abc.showtmp", show_tempdir);
markgroups = design->scratchpad_get_bool("abc.markgroups", markgroups);
+ if (design->scratchpad_get_bool("abc.debug")) {
+ cleanup = false;
+ show_tempdir = true;
+ }
+
size_t argidx, g_argidx;
bool g_arg_from_cmd = false;
char pwd [PATH_MAX];
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc
index 5ae2fb22a..212e0692d 100644
--- a/passes/techmap/abc9.cc
+++ b/passes/techmap/abc9.cc
@@ -145,6 +145,11 @@ struct Abc9Pass : public ScriptPass
log(" generate netlist using luts. Use the specified costs for luts with 1,\n");
log(" 2, 3, .. inputs.\n");
log("\n");
+ log(" -maxlut <width>\n");
+ log(" when auto-generating the lut library, discard all luts equal to or\n");
+ log(" greater than this size (applicable when neither -lut nor -luts is\n");
+ log(" specified).\n");
+ log("\n");
log(" -dff\n");
log(" also pass $_ABC9_FF_ cells through to ABC. modules with many clock\n");
log(" domains are marked as such and automatically partitioned by ABC.\n");
@@ -175,6 +180,8 @@ struct Abc9Pass : public ScriptPass
std::stringstream exe_cmd;
bool dff_mode, cleanup;
+ bool lut_mode;
+ int maxlut;
std::string box_file;
void clear_flags() YS_OVERRIDE
@@ -183,7 +190,9 @@ struct Abc9Pass : public ScriptPass
exe_cmd << "abc9_exe";
dff_mode = false;
cleanup = true;
- box_file.clear();
+ lut_mode = false;
+ maxlut = 0;
+ box_file = "";
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -204,9 +213,11 @@ struct Abc9Pass : public ScriptPass
for (argidx = 1; argidx < args.size(); argidx++) {
std::string arg = args[argidx];
if ((arg == "-exe" || arg == "-script" || arg == "-D" ||
- /* arg == "-S" || */ arg == "-lut" || arg == "-luts" ||
+ /*arg == "-S" ||*/ arg == "-lut" || arg == "-luts" ||
/*arg == "-box" ||*/ arg == "-W") &&
argidx+1 < args.size()) {
+ if (arg == "-lut" || arg == "-luts")
+ lut_mode = true;
exe_cmd << " " << arg << " " << args[++argidx];
continue;
}
@@ -228,6 +239,10 @@ struct Abc9Pass : public ScriptPass
box_file = args[++argidx];
continue;
}
+ if (arg == "-maxlut" && argidx+1 < args.size()) {
+ maxlut = atoi(args[++argidx].c_str());
+ continue;
+ }
if (arg == "-run" && argidx+1 < args.size()) {
size_t pos = args[argidx+1].find(':');
if (pos == std::string::npos)
@@ -240,6 +255,9 @@ struct Abc9Pass : public ScriptPass
}
extra_args(args, argidx, design);
+ if (maxlut && lut_mode)
+ log_cmd_error("abc9 '-maxlut' option only applicable without '-lut' nor '-luts'.\n");
+
log_assert(design);
if (design->selected_modules().empty()) {
log_warning("No modules selected for ABC9 techmapping.\n");
@@ -263,6 +281,14 @@ struct Abc9Pass : public ScriptPass
run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)");
else
run("abc9_ops -mark_scc -prep_delays -prep_xaiger" + std::string(dff_mode ? " -dff" : ""), "(option for -dff)");
+ if (help_mode)
+ run("abc9_ops -prep_lut <maxlut>", "(skip if -lut or -luts)");
+ else if (!lut_mode)
+ run(stringf("abc9_ops -prep_lut %d", maxlut));
+ if (help_mode)
+ run("abc9_ops -prep_box [-dff]", "(skip if -box)");
+ else if (box_file.empty())
+ run(stringf("abc9_ops -prep_box %s", dff_mode ? "-dff" : ""));
run("select -set abc9_holes A:abc9_holes");
run("flatten -wb @abc9_holes");
run("techmap @abc9_holes");
@@ -276,9 +302,10 @@ struct Abc9Pass : public ScriptPass
if (check_label("map")) {
if (help_mode) {
run("foreach module in selection");
- run(" abc9_ops -write_box [<value from -box>|(null)] <abc-temp-dir>/input.box");
+ run(" abc9_ops -write_lut <abc-temp-dir>/input.lut", "(skip if '-lut' or '-luts')");
+ run(" abc9_ops -write_box <abc-temp-dir>/input.box");
run(" write_xaiger -map <abc-temp-dir>/input.sym <abc-temp-dir>/input.xaig");
- run(" abc9_exe [options] -cwd <abc-temp-dir> -box <abc-temp-dir>/input.box");
+ run(" abc9_exe [options] -cwd <abc-temp-dir> [-lut <abc-temp-dir>/input.lut] -box <abc-temp-dir>/input.box");
run(" read_aiger -xaiger -wideports -module_name <module-name>$abc9 -map <abc-temp-dir>/input.sym <abc-temp-dir>/output.aig");
run(" abc9_ops -reintegrate");
}
@@ -304,11 +331,10 @@ struct Abc9Pass : public ScriptPass
tempdir_name[0] = tempdir_name[4] = '_';
tempdir_name = make_temp_dir(tempdir_name);
- if (box_file.empty())
- run(stringf("abc9_ops -write_box (null) %s/input.box", tempdir_name.c_str()));
- else
- run(stringf("abc9_ops -write_box %s %s/input.box", box_file.c_str(), tempdir_name.c_str()));
- run(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()));
+ if (!lut_mode)
+ run_nocheck(stringf("abc9_ops -write_lut %s/input.lut", tempdir_name.c_str()));
+ run_nocheck(stringf("abc9_ops -write_box %s/input.box", tempdir_name.c_str()));
+ run_nocheck(stringf("write_xaiger -map %s/input.sym %s/input.xaig", tempdir_name.c_str(), tempdir_name.c_str()));
int num_outputs = active_design->scratchpad_get_int("write_xaiger.num_outputs");
@@ -319,9 +345,14 @@ struct Abc9Pass : public ScriptPass
active_design->scratchpad_get_int("write_xaiger.num_inputs"),
num_outputs);
if (num_outputs) {
- run(stringf("%s -cwd %s -box %s/input.box", exe_cmd.str().c_str(), tempdir_name.c_str(), tempdir_name.c_str()));
- run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str()));
- run("abc9_ops -reintegrate");
+ std::string abc9_exe_cmd;
+ abc9_exe_cmd += stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str());
+ if (!lut_mode)
+ abc9_exe_cmd += stringf(" -lut %s/input.lut", tempdir_name.c_str());
+ abc9_exe_cmd += stringf(" -box %s/input.box", tempdir_name.c_str());
+ run_nocheck(abc9_exe_cmd);
+ run_nocheck(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str()));
+ run_nocheck("abc9_ops -reintegrate");
}
else
log("Don't call ABC as there is nothing to map.\n");
@@ -330,7 +361,7 @@ struct Abc9Pass : public ScriptPass
log("Removing temp directory.\n");
remove_directory(tempdir_name);
}
-
+ mod->check();
active_design->selection().selected_modules.clear();
log_pop();
}
diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc
index 71221951c..898285c69 100644
--- a/passes/techmap/abc9_exe.cc
+++ b/passes/techmap/abc9_exe.cc
@@ -362,7 +362,7 @@ struct Abc9ExePass : public Pass {
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- log_header(design, "Executing ABC9_MAP pass (technology mapping using ABC9).\n");
+ log_header(design, "Executing ABC9_EXE pass (technology mapping using ABC9).\n");
#ifdef ABCEXTERNAL
std::string exe_file = ABCEXTERNAL;
@@ -471,7 +471,7 @@ struct Abc9ExePass : public Pass {
// handle -lut / -luts args
if (!lut_arg.empty()) {
string arg = lut_arg;
- if (arg.find_first_not_of("0123456789:") == std::string::npos) {
+ if (arg.find_first_not_of("0123456789:,") == std::string::npos) {
size_t pos = arg.find_first_of(':');
int lut_mode = 0, lut_mode2 = 0;
if (pos != string::npos) {
diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc
index 7071f0de4..e1baf4e3d 100644
--- a/passes/techmap/abc9_ops.cc
+++ b/passes/techmap/abc9_ops.cc
@@ -22,9 +22,7 @@
#include "kernel/sigtools.h"
#include "kernel/utils.h"
#include "kernel/celltypes.h"
-
-#define ABC9_FLOPS_BASE_ID 8000
-#define ABC9_DELAY_BASE_ID 9000
+#include "kernel/timinginfo.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
@@ -73,54 +71,6 @@ void check(RTLIL::Design *design)
carry_out = port_name;
}
}
-
- auto it = w->attributes.find("\\abc9_arrival");
- if (it != w->attributes.end()) {
- int count = 0;
- if (it->second.flags == 0) {
- if (it->second.as_int() < 0)
- log_error("%s.%s has negative arrival value %d!\n", log_id(m), log_id(port_name),
- it->second.as_int());
- count++;
- }
- else
- for (const auto &tok : split_tokens(it->second.decode_string())) {
- if (tok.find_first_not_of("0123456789") != std::string::npos)
- log_error("%s.%s has non-integer arrival value '%s'!\n", log_id(m), log_id(port_name),
- tok.c_str());
- if (atoi(tok.c_str()) < 0)
- log_error("%s.%s has negative arrival value %s!\n", log_id(m), log_id(port_name),
- tok.c_str());
- count++;
- }
- if (count > 1 && count != GetSize(w))
- log_error("%s.%s is %d bits wide but abc9_arrival = %s has %d value(s)!\n", log_id(m), log_id(port_name),
- GetSize(w), log_signal(it->second), count);
- }
-
- it = w->attributes.find("\\abc9_required");
- if (it != w->attributes.end()) {
- int count = 0;
- if (it->second.flags == 0) {
- if (it->second.as_int() < 0)
- log_error("%s.%s has negative required value %d!\n", log_id(m), log_id(port_name),
- it->second.as_int());
- count++;
- }
- else
- for (const auto &tok : split_tokens(it->second.decode_string())) {
- if (tok.find_first_not_of("0123456789") != std::string::npos)
- log_error("%s.%s has non-integer required value '%s'!\n", log_id(m), log_id(port_name),
- tok.c_str());
- if (atoi(tok.c_str()) < 0)
- log_error("%s.%s has negative required value %s!\n", log_id(m), log_id(port_name),
- tok.c_str());
- count++;
- }
- if (count > 1 && count != GetSize(w))
- log_error("%s.%s is %d bits wide but abc9_required = %s has %d value(s)!\n", log_id(m), log_id(port_name),
- GetSize(w), log_signal(it->second), count);
- }
}
if (carry_in != IdString() && carry_out == IdString())
@@ -143,9 +93,10 @@ void check(RTLIL::Design *design)
void mark_scc(RTLIL::Module *module)
{
// For every unique SCC found, (arbitrarily) find the first
- // cell in the component, and convert all wires driven by
- // its output ports into a new PO, and drive its previous
- // sinks with a new PI
+ // cell in the component, and replace its output connections
+ // with a new wire driven by the old connection but with a
+ // special (* abc9_scc *) attribute set (which is used by
+ // write_xaiger to break this wire into PI and POs)
pool<RTLIL::Const> ids_seen;
for (auto cell : module->cells()) {
auto it = cell->attributes.find(ID(abc9_scc_id));
@@ -159,15 +110,13 @@ void mark_scc(RTLIL::Module *module)
for (auto &c : cell->connections_) {
if (c.second.is_fully_const()) continue;
if (cell->output(c.first)) {
- SigBit b = c.second.as_bit();
- Wire *w = b.wire;
- w->set_bool_attribute(ID::keep);
- w->attributes[ID(abc9_scc_id)] = id.as_int();
+ Wire *w = module->addWire(NEW_ID, GetSize(c.second));
+ w->set_bool_attribute(ID(abc9_scc));
+ module->connect(w, c.second);
+ c.second = w;
}
}
}
-
- module->fixup_ports();
}
void prep_dff(RTLIL::Module *module)
@@ -192,20 +141,9 @@ void prep_dff(RTLIL::Module *module)
clkdomain_t key(abc9_clock);
auto r = clk_to_mergeability.insert(std::make_pair(abc9_clock, clk_to_mergeability.size() + 1));
- auto r2 YS_ATTRIBUTE(unused) = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second));
- log_assert(r2.second);
-
- Wire *abc9_init_wire = module->wire(stringf("%s.init", cell->name.c_str()));
- if (abc9_init_wire == NULL)
- log_error("'%s.init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
- log_assert(GetSize(abc9_init_wire) == 1);
- SigSpec abc9_init = assign_map(abc9_init_wire);
- if (!abc9_init.is_fully_const())
- log_error("'%s.init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
- if (abc9_init == State::S1)
- log_error("'%s.init' in module '%s' has value 1'b1 which is not supported by 'abc9 -dff'.\n", cell->name.c_str(), log_id(module));
- r2 = cell->attributes.insert(std::make_pair(ID(abc9_init), abc9_init.as_const()));
+ auto r2 = cell->attributes.insert(ID(abc9_mergeability));;
log_assert(r2.second);
+ r2.first->second = r.first->second;
}
RTLIL::Module *holes_module = design->module(stringf("%s$holes", module->name.c_str()));
@@ -280,7 +218,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
if (abc9_flop && !dff)
continue;
- if ((inst_module && inst_module->attributes.count("\\abc9_box_id")) || abc9_flop) {
+ if ((inst_module && inst_module->get_bool_attribute("\\abc9_box")) || abc9_flop) {
auto r = box_ports.insert(cell->type);
if (r.second) {
// Make carry in the last PI, and carry out the last PO
@@ -327,8 +265,8 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
for (auto &it : bit_users)
if (bit_drivers.count(it.first))
for (auto driver_cell : bit_drivers.at(it.first))
- for (auto user_cell : it.second)
- toposort.edge(driver_cell, user_cell);
+ for (auto user_cell : it.second)
+ toposort.edge(driver_cell, user_cell);
if (ys_debug(1))
toposort.analyze_loops = true;
@@ -354,6 +292,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
holes_module->set_bool_attribute("\\abc9_holes");
dict<IdString, Cell*> cell_cache;
+ TimingInfo timing;
int port_id = 1, box_count = 0;
for (auto cell_name : toposort.sorted) {
@@ -361,7 +300,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
log_assert(cell);
RTLIL::Module* box_module = design->module(cell->type);
- if (!box_module || (!box_module->attributes.count("\\abc9_box_id") && !box_module->get_bool_attribute("\\abc9_flop")))
+ if (!box_module || (!box_module->get_bool_attribute("\\abc9_box") && !box_module->get_bool_attribute("\\abc9_flop")))
continue;
cell->attributes["\\abc9_box_seq"] = box_count++;
@@ -440,19 +379,20 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
}
}
-void prep_delays(RTLIL::Design *design)
+void prep_delays(RTLIL::Design *design, bool dff_mode)
{
- std::set<int> delays;
+ TimingInfo timing;
+
+ // Derive all Yosys blackbox modules that are not combinatorial abc9 boxes
+ // (e.g. DSPs, RAMs, etc.) nor abc9 flops and collect all such instantiations
pool<Module*> flops;
std::vector<Cell*> cells;
- dict<IdString,dict<IdString,std::vector<int>>> requireds_cache;
for (auto module : design->selected_modules()) {
if (module->processes.size() > 0) {
log("Skipping module %s as it contains processes.\n", log_id(module));
continue;
}
- cells.clear();
for (auto cell : module->cells()) {
if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_), ID($__ABC9_DELAY)))
continue;
@@ -462,144 +402,311 @@ void prep_delays(RTLIL::Design *design)
continue;
if (!inst_module->get_blackbox_attribute())
continue;
- if (inst_module->get_bool_attribute(ID(abc9_flop))) {
- IdString derived_type = inst_module->derive(design, cell->parameters);
- inst_module = design->module(derived_type);
- log_assert(inst_module);
+ if (inst_module->attributes.count(ID(abc9_box)))
+ continue;
+ IdString derived_type = inst_module->derive(design, cell->parameters);
+ inst_module = design->module(derived_type);
+ log_assert(inst_module);
+
+ if (dff_mode && inst_module->get_bool_attribute(ID(abc9_flop))) {
flops.insert(inst_module);
- continue; // because all flop required times
- // will be captured in the flop box
+ continue; // do not add $__ABC9_DELAY boxes to flops
+ // as delays will be captured in the flop box
}
- if (inst_module->attributes.count(ID(abc9_box_id)))
- continue;
+
+ if (!timing.count(derived_type))
+ timing.setup_module(inst_module);
+
cells.emplace_back(cell);
}
+ }
- delays.clear();
- for (auto cell : cells) {
- RTLIL::Module* inst_module = module->design->module(cell->type);
- log_assert(inst_module);
- auto &cell_requireds = requireds_cache[cell->type];
- for (auto &conn : cell->connections_) {
- auto port_wire = inst_module->wire(conn.first);
- if (!port_wire->port_input)
+ // Insert $__ABC9_DELAY cells on all cells that instantiate blackboxes
+ // with required times
+ for (auto cell : cells) {
+ auto module = cell->module;
+ RTLIL::Module* inst_module = module->design->module(cell->type);
+ log_assert(inst_module);
+ IdString derived_type = inst_module->derive(design, cell->parameters);
+ inst_module = design->module(derived_type);
+ log_assert(inst_module);
+
+ auto &t = timing.at(derived_type).required;
+ for (auto &conn : cell->connections_) {
+ auto port_wire = inst_module->wire(conn.first);
+ if (!port_wire->port_input)
+ continue;
+
+ SigSpec O = module->addWire(NEW_ID, GetSize(conn.second));
+ for (int i = 0; i < GetSize(conn.second); i++) {
+ auto d = t.at(TimingInfo::NameBit(conn.first,i), 0);
+ if (d == 0)
continue;
- auto r = cell_requireds.insert(conn.first);
- auto &requireds = r.first->second;
- if (r.second) {
- auto it = port_wire->attributes.find("\\abc9_required");
- if (it == port_wire->attributes.end())
+#ifndef NDEBUG
+ if (ys_debug(1)) {
+ static std::set<std::tuple<IdString,IdString,int>> seen;
+ if (seen.emplace(derived_type, conn.first, i).second) log("%s.%s[%d] abc9_required = %d\n",
+ log_id(cell->type), log_id(conn.first), i, d);
+ }
+#endif
+ auto box = module->addCell(NEW_ID, ID($__ABC9_DELAY));
+ box->setPort(ID(I), conn.second[i]);
+ box->setPort(ID(O), O[i]);
+ box->setParam(ID(DELAY), d);
+ conn.second[i] = O[i];
+ }
+ }
+ }
+}
+
+void prep_lut(RTLIL::Design *design, int maxlut)
+{
+ TimingInfo timing;
+
+ std::vector<std::tuple<int, IdString, int, std::vector<int>>> table;
+ for (auto module : design->modules()) {
+ auto it = module->attributes.find(ID(abc9_lut));
+ if (it == module->attributes.end())
+ continue;
+
+ auto &t = timing.setup_module(module);
+
+ TimingInfo::NameBit o;
+ std::vector<int> specify;
+ for (const auto &i : t.comb) {
+ auto &d = i.first.second;
+ if (o == TimingInfo::NameBit())
+ o = d;
+ else if (o != d)
+ log_error("(* abc9_lut *) module '%s' with has more than one output.\n", log_id(module));
+ specify.push_back(i.second);
+ }
+
+ if (maxlut && GetSize(specify) > maxlut)
+ continue;
+ // ABC requires non-decreasing LUT input delays
+ std::sort(specify.begin(), specify.end());
+ table.emplace_back(GetSize(specify), module->name, it->second.as_int(), std::move(specify));
+ }
+ // ABC requires ascending size
+ std::sort(table.begin(), table.end());
+
+ std::stringstream ss;
+ const auto &first = table.front();
+ // If the first entry does not start from a 1-input LUT,
+ // (as ABC requires) crop the first entry to do so
+ for (int i = 1; i < std::get<0>(first); i++) {
+ ss << "# $__ABC9_LUT" << i << std::endl;
+ ss << i << " " << std::get<2>(first);
+ for (int j = 0; j < i; j++)
+ ss << " " << std::get<3>(first)[j];
+ ss << std::endl;
+ }
+ for (const auto &i : table) {
+ ss << "# " << log_id(std::get<1>(i)) << std::endl;
+ ss << std::get<0>(i) << " " << std::get<2>(i);
+ for (const auto &j : std::get<3>(i))
+ ss << " " << j;
+ ss << std::endl;
+ }
+ design->scratchpad_set_string("abc9_ops.lut_library", ss.str());
+}
+
+void write_lut(RTLIL::Module *module, const std::string &dst) {
+ std::ofstream ofs(dst);
+ log_assert(ofs.is_open());
+ ofs << module->design->scratchpad_get_string("abc9_ops.lut_library");
+ ofs.close();
+}
+
+void prep_box(RTLIL::Design *design, bool dff_mode)
+{
+ TimingInfo timing;
+
+ std::stringstream ss;
+ int abc9_box_id = 1;
+ for (auto module : design->modules()) {
+ auto it = module->attributes.find(ID(abc9_box_id));
+ if (it == module->attributes.end())
+ continue;
+ abc9_box_id = std::max(abc9_box_id, it->second.as_int());
+ }
+
+ dict<IdString,std::vector<IdString>> box_ports;
+ for (auto module : design->modules()) {
+ auto abc9_flop = module->get_bool_attribute(ID(abc9_flop));
+ if (abc9_flop) {
+ auto r = module->attributes.insert(ID(abc9_box_id));
+ if (!r.second)
+ continue;
+ r.first->second = abc9_box_id++;
+
+ if (dff_mode) {
+ int num_inputs = 0, num_outputs = 0;
+ for (auto port_name : module->ports) {
+ auto wire = module->wire(port_name);
+ log_assert(GetSize(wire) == 1);
+ if (wire->port_input) num_inputs++;
+ if (wire->port_output) num_outputs++;
+ }
+ log_assert(num_outputs == 1);
+
+ ss << log_id(module) << " " << r.first->second.as_int();
+ ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0");
+ ss << " " << num_inputs+1 << " " << num_outputs << std::endl;
+
+ ss << "#";
+ bool first = true;
+ for (auto port_name : module->ports) {
+ auto wire = module->wire(port_name);
+ if (!wire->port_input)
continue;
- if (it->second.flags == 0) {
- int delay = it->second.as_int();
- delays.insert(delay);
- requireds.emplace_back(delay);
- }
+ if (first)
+ first = false;
else
- for (const auto &tok : split_tokens(it->second.decode_string())) {
- int delay = atoi(tok.c_str());
- delays.insert(delay);
- requireds.push_back(delay);
- }
+ ss << " ";
+ ss << log_id(wire);
}
+ ss << " abc9_ff.Q" << std::endl;
- if (requireds.empty())
- continue;
+ auto &t = timing.setup_module(module).required;
+ first = true;
+ for (auto port_name : module->ports) {
+ auto wire = module->wire(port_name);
+ if (!wire->port_input)
+ continue;
+ if (first)
+ first = false;
+ else
+ ss << " ";
+ log_assert(GetSize(wire) == 1);
+ auto it = t.find(TimingInfo::NameBit(port_name,0));
+ if (it == t.end())
+ // Assume that no setup time means zero
+ ss << 0;
+ else {
+ ss << it->second;
- SigSpec O = module->addWire(NEW_ID, GetSize(conn.second));
- auto it = requireds.begin();
- for (int i = 0; i < GetSize(conn.second); ++i) {
#ifndef NDEBUG
- if (ys_debug(1)) {
- static std::set<std::pair<IdString,IdString>> seen;
- if (seen.emplace(cell->type, conn.first).second) log("%s.%s abc9_required = %d\n", log_id(cell->type), log_id(conn.first), requireds[i]);
- }
+ if (ys_debug(1)) {
+ static std::set<std::pair<IdString,IdString>> seen;
+ if (seen.emplace(module->name, port_name).second) log("%s.%s abc9_required = %d\n", log_id(module),
+ log_id(port_name), it->second);
+ }
#endif
- auto box = module->addCell(NEW_ID, ID($__ABC9_DELAY));
- box->setPort(ID(I), conn.second[i]);
- box->setPort(ID(O), O[i]);
- box->setParam(ID(DELAY), *it);
- if (requireds.size() > 1)
- it++;
- conn.second[i] = O[i];
+ }
+
}
+ // Last input is 'abc9_ff.Q'
+ ss << " 0" << std::endl << std::endl;
+ continue;
}
}
+ else {
+ if (!module->attributes.erase(ID(abc9_box)))
+ continue;
- std::stringstream ss;
- bool first = true;
- for (auto d : delays) {
- if (first)
- first = false;
- else
- ss << " ";
- ss << d;
+ auto r = module->attributes.insert(ID(abc9_box_id));
+ if (!r.second)
+ continue;
+ r.first->second = abc9_box_id++;
}
- module->attributes[ID(abc9_delays)] = ss.str();
- }
- int flops_id = ABC9_FLOPS_BASE_ID;
- std::stringstream ss;
- for (auto flop_module : flops) {
- int num_inputs = 0, num_outputs = 0;
- for (auto port_name : flop_module->ports) {
- auto wire = flop_module->wire(port_name);
- if (wire->port_input) num_inputs++;
- if (wire->port_output) num_outputs++;
+ auto r = box_ports.insert(module->name);
+ if (r.second) {
+ // Make carry in the last PI, and carry out the last PO
+ // since ABC requires it this way
+ IdString carry_in, carry_out;
+ for (const auto &port_name : module->ports) {
+ auto w = module->wire(port_name);
+ log_assert(w);
+ if (w->get_bool_attribute("\\abc9_carry")) {
+ log_assert(w->port_input != w->port_output);
+ if (w->port_input)
+ carry_in = port_name;
+ else if (w->port_output)
+ carry_out = port_name;
+ }
+ else
+ r.first->second.push_back(port_name);
+ }
+
+ if (carry_in != IdString()) {
+ r.first->second.push_back(carry_in);
+ r.first->second.push_back(carry_out);
+ }
+ }
+
+ std::vector<SigBit> inputs;
+ std::vector<SigBit> outputs;
+ for (auto port_name : r.first->second) {
+ auto wire = module->wire(port_name);
+ if (wire->port_input)
+ for (int i = 0; i < GetSize(wire); i++)
+ inputs.emplace_back(wire, i);
+ if (wire->port_output)
+ for (int i = 0; i < GetSize(wire); i++)
+ outputs.emplace_back(wire, i);
}
- log_assert(num_outputs == 1);
- auto r = flop_module->attributes.insert(ID(abc9_box_id));
- if (r.second)
- r.first->second = flops_id++;
+ ss << log_id(module) << " " << module->attributes.at(ID(abc9_box_id)).as_int();
+ ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0");
+ ss << " " << GetSize(inputs) << " " << GetSize(outputs) << std::endl;
- ss << log_id(flop_module) << " " << r.first->second.as_int();
- ss << " 1 " << num_inputs+1 << " " << num_outputs << std::endl;
bool first = true;
- for (auto port_name : flop_module->ports) {
- auto wire = flop_module->wire(port_name);
- if (!wire->port_input)
- continue;
+ ss << "#";
+ for (const auto &i : inputs) {
if (first)
first = false;
else
ss << " ";
- ss << wire->attributes.at("\\abc9_required", 0).as_int();
+ if (GetSize(i.wire) == 1)
+ ss << log_id(i.wire);
+ else
+ ss << log_id(i.wire) << "[" << i.offset << "]";
}
- // Last input is 'abc9_ff.Q'
- ss << " 0" << std::endl << std::endl;
- }
- design->scratchpad_set_string("abc9_ops.box.flops", ss.str());
-}
-
-void write_box(RTLIL::Module *module, const std::string &src, const std::string &dst) {
- std::ofstream ofs(dst);
- log_assert(ofs.is_open());
+ ss << std::endl;
- // Since ABC can only accept one box file, we have to copy
- // over the existing box file
- if (src != "(null)") {
- std::ifstream ifs(src);
- ofs << ifs.rdbuf() << std::endl;
- ifs.close();
- }
+ auto &t = timing.setup_module(module).comb;
+ if (!abc9_flop && t.empty())
+ log_warning("(* abc9_box *) module '%s' has no timing (and thus no connectivity) information.\n", log_id(module));
- ofs << module->design->scratchpad_get_string("abc9_ops.box.flops");
+ for (const auto &o : outputs) {
+ first = true;
+ for (const auto &i : inputs) {
+ if (first)
+ first = false;
+ else
+ ss << " ";
+ auto jt = t.find(TimingInfo::BitBit(i,o));
+ if (jt == t.end())
+ ss << "-";
+ else
+ ss << jt->second;
+ }
+ ss << " # ";
+ if (GetSize(o.wire) == 1)
+ ss << log_id(o.wire);
+ else
+ ss << log_id(o.wire) << "[" << o.offset << "]";
+ ss << std::endl;
- auto it = module->attributes.find(ID(abc9_delays));
- if (it != module->attributes.end()) {
- for (const auto &tok : split_tokens(it->second.decode_string())) {
- int d = atoi(tok.c_str());
- ofs << "$__ABC9_DELAY@" << d << " " << ABC9_DELAY_BASE_ID + d << " 0 1 1" << std::endl;
- ofs << d << std::endl;
}
- module->attributes.erase(it);
+ ss << std::endl;
}
- if (ofs.tellp() == 0)
- ofs << "(dummy) 1 0 0 0";
+ // ABC expects at least one box
+ if (ss.tellp() == 0)
+ ss << "(dummy) 1 0 0 0";
+
+ design->scratchpad_set_string("abc9_ops.box_library", ss.str());
+}
+void write_box(RTLIL::Module *module, const std::string &dst) {
+ std::ofstream ofs(dst);
+ log_assert(ofs.is_open());
+ ofs << module->design->scratchpad_get_string("abc9_ops.box_library");
ofs.close();
}
@@ -763,13 +870,11 @@ void reintegrate(RTLIL::Module *module)
continue;
}
-#ifndef NDEBUG
RTLIL::Module* box_module = design->module(existing_cell->type);
IdString derived_type = box_module->derive(design, existing_cell->parameters);
RTLIL::Module* derived_module = design->module(derived_type);
log_assert(derived_module);
log_assert(mapped_cell->type == stringf("$__boxid%d", derived_module->attributes.at("\\abc9_box_id").as_int()));
-#endif
mapped_cell->type = existing_cell->type;
RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
@@ -861,10 +966,8 @@ void reintegrate(RTLIL::Module *module)
RTLIL::Wire *mapped_wire = mapped_mod->wire(port);
RTLIL::Wire *wire = module->wire(port);
log_assert(wire);
- if (wire->attributes.erase(ID(abc9_scc_id))) {
- auto r YS_ATTRIBUTE(unused) = wire->attributes.erase(ID::keep);
- log_assert(r);
- }
+ wire->attributes.erase(ID(abc9_scc));
+
RTLIL::Wire *remap_wire = module->wire(remap_name(port));
RTLIL::SigSpec signal(wire, 0, GetSize(remap_wire));
log_assert(GetSize(signal) >= GetSize(remap_wire));
@@ -993,7 +1096,7 @@ struct Abc9OpsPass : public Pass {
log("\n");
log(" -prep_delays\n");
log(" insert `$__ABC9_DELAY' blackbox cells into the design to account for\n");
- log(" certain delays, e.g. (* abc9_required *) values.\n");
+ log(" certain required times.\n");
log("\n");
log(" -mark_scc\n");
log(" for an arbitrarily chosen cell in each unique SCC of each selected module\n");
@@ -1008,16 +1111,26 @@ struct Abc9OpsPass : public Pass {
log(" whiteboxes.\n");
log("\n");
log(" -dff\n");
- log(" consider flop cells (those instantiating modules marked with (* abc9_flop *)\n");
- log(" during -prep_xaiger.\n");
+ log(" consider flop cells (those instantiating modules marked with (* abc9_flop *))\n");
+ log(" during -prep_{delays,xaiger,box}.\n");
log("\n");
log(" -prep_dff\n");
log(" compute the clock domain and initial value of each flop in the design.\n");
log(" process the '$holes' module to support clock-enable functionality.\n");
log("\n");
- log(" -write_box (<src>|(null)) <dst>\n");
- log(" copy the existing box file from <src> (skip if '(null)') and append any\n");
- log(" new box definitions.\n");
+ log(" -prep_lut <maxlut>\n");
+ log(" pre-compute the lut library by analysing all modules marked with\n");
+ log(" (* abc9_lut=<area> *).\n");
+ log("\n");
+ log(" -write_lut <dst>\n");
+ log(" write the pre-computed lut library to <dst>.\n");
+ log("\n");
+ log(" -prep_box\n");
+ log(" pre-compute the box library by analysing all modules marked with\n");
+ log(" (* abc9_box *).\n");
+ log("\n");
+ log(" -write_box <dst>\n");
+ log(" write the pre-computed box library to <dst>.\n");
log("\n");
log(" -reintegrate\n");
log(" for each selected module, re-intergrate the module '<module-name>$abc9'\n");
@@ -1034,9 +1147,13 @@ struct Abc9OpsPass : public Pass {
bool mark_scc_mode = false;
bool prep_dff_mode = false;
bool prep_xaiger_mode = false;
+ bool prep_lut_mode = false;
+ bool prep_box_mode = false;
bool reintegrate_mode = false;
bool dff_mode = false;
- std::string write_box_src, write_box_dst;
+ std::string write_lut_dst;
+ int maxlut = 0;
+ std::string write_box_dst;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
@@ -1061,10 +1178,25 @@ struct Abc9OpsPass : public Pass {
prep_delays_mode = true;
continue;
}
- if (arg == "-write_box" && argidx+2 < args.size()) {
- write_box_src = args[++argidx];
+ if (arg == "-prep_lut" && argidx+1 < args.size()) {
+ prep_lut_mode = true;
+ maxlut = atoi(args[++argidx].c_str());
+ continue;
+ }
+ if (arg == "-maxlut" && argidx+1 < args.size()) {
+ continue;
+ }
+ if (arg == "-write_lut" && argidx+1 < args.size()) {
+ write_lut_dst = args[++argidx];
+ rewrite_filename(write_lut_dst);
+ continue;
+ }
+ if (arg == "-prep_box") {
+ prep_box_mode = true;
+ continue;
+ }
+ if (arg == "-write_box" && argidx+1 < args.size()) {
write_box_dst = args[++argidx];
- rewrite_filename(write_box_src);
rewrite_filename(write_box_dst);
continue;
}
@@ -1080,16 +1212,20 @@ struct Abc9OpsPass : public Pass {
}
extra_args(args, argidx, design);
- if (!(check_mode || mark_scc_mode || prep_delays_mode || prep_xaiger_mode || prep_dff_mode || !write_box_src.empty() || reintegrate_mode))
- log_cmd_error("At least one of -check, -mark_scc, -prep_{delays,xaiger,dff}, -write_box, -reintegrate must be specified.\n");
+ if (!(check_mode || mark_scc_mode || prep_delays_mode || prep_xaiger_mode || prep_dff_mode || prep_lut_mode || prep_box_mode || !write_lut_dst.empty() || !write_box_dst.empty() || reintegrate_mode))
+ log_cmd_error("At least one of -check, -mark_scc, -prep_{delays,xaiger,dff,lut,box}, -write_{lut,box}, -reintegrate must be specified.\n");
- if (dff_mode && !prep_xaiger_mode)
- log_cmd_error("'-dff' option is only relevant for -prep_xaiger.\n");
+ if (dff_mode && !prep_delays_mode && !prep_xaiger_mode && !prep_box_mode)
+ log_cmd_error("'-dff' option is only relevant for -prep_{delay,xaiger,box}.\n");
if (check_mode)
check(design);
if (prep_delays_mode)
- prep_delays(design);
+ prep_delays(design, dff_mode);
+ if (prep_lut_mode)
+ prep_lut(design, maxlut);
+ if (prep_box_mode)
+ prep_box(design, dff_mode);
for (auto mod : design->selected_modules()) {
if (mod->get_bool_attribute("\\abc9_holes"))
@@ -1103,8 +1239,10 @@ struct Abc9OpsPass : public Pass {
if (!design->selected_whole_module(mod))
log_error("Can't handle partially selected module %s!\n", log_id(mod));
- if (!write_box_src.empty())
- write_box(mod, write_box_src, write_box_dst);
+ if (!write_lut_dst.empty())
+ write_lut(mod, write_lut_dst);
+ if (!write_box_dst.empty())
+ write_box(mod, write_box_dst);
if (mark_scc_mode)
mark_scc(mod);
if (prep_dff_mode)
diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc
index b976b401b..35d43b106 100644
--- a/passes/techmap/deminout.cc
+++ b/passes/techmap/deminout.cc
@@ -121,8 +121,7 @@ struct DeminoutPass : public Pass {
goto tribuf_bit;
} else {
tribuf_bit:
- if (bits_used.count(bit))
- new_input = true;
+ new_input = true;
}
}
diff --git a/passes/techmap/extract_counter.cc b/passes/techmap/extract_counter.cc
index 17a99493d..639ae145b 100644
--- a/passes/techmap/extract_counter.cc
+++ b/passes/techmap/extract_counter.cc
@@ -90,22 +90,35 @@ bool is_unconnected(const RTLIL::SigSpec& port, ModIndex& index)
struct CounterExtraction
{
int width; //counter width
+ bool count_is_up; //count up (else down)
RTLIL::Wire* rwire; //the register output
bool has_reset; //true if we have a reset
bool has_ce; //true if we have a clock enable
+ bool ce_inverted; //true if clock enable is active low
RTLIL::SigSpec rst; //reset pin
bool rst_inverted; //true if reset is active low
bool rst_to_max; //true if we reset to max instead of 0
int count_value; //value we count from
RTLIL::SigSpec ce; //clock signal
RTLIL::SigSpec clk; //clock enable, if any
- RTLIL::SigSpec outsig; //counter output signal
+ RTLIL::SigSpec outsig; //counter overflow output signal
+ RTLIL::SigSpec poutsig; //counter parallel output signal
+ bool has_pout; //whether parallel output is used
RTLIL::Cell* count_mux; //counter mux
RTLIL::Cell* count_reg; //counter register
- RTLIL::Cell* underflow_inv; //inverter reduction for output-underflow detect
+ RTLIL::Cell* overflow_cell; //cell for counter overflow (either inverter reduction or $eq)
pool<ModIndex::PortInfo> pouts; //Ports that take a parallel output from us
};
+struct CounterExtractionSettings
+{
+ pool<RTLIL::IdString>& parallel_cells;
+ int maxwidth;
+ int minwidth;
+ bool allow_arst;
+ int allowed_dirs; //0 = down, 1 = up, 2 = both
+};
+
//attempt to extract a counter centered on the given adder cell
//For now we only support DOWN counters.
//TODO: up/down support
@@ -113,49 +126,132 @@ int counter_tryextract(
ModIndex& index,
Cell *cell,
CounterExtraction& extract,
- pool<RTLIL::IdString>& parallel_cells,
- int maxwidth)
+ CounterExtractionSettings settings)
{
SigMap& sigmap = index.sigmap;
- //A counter with less than 2 bits makes no sense
- //TODO: configurable min threshold
- int a_width = cell->getParam(ID(A_WIDTH)).as_int();
- extract.width = a_width;
- if( (a_width < 2) || (a_width > maxwidth) )
- return 1;
-
- //Second input must be a single bit
- int b_width = cell->getParam(ID(B_WIDTH)).as_int();
- if(b_width != 1)
- return 2;
-
//Both inputs must be unsigned, so don't extract anything with a signed input
bool a_sign = cell->getParam(ID(A_SIGNED)).as_bool();
bool b_sign = cell->getParam(ID(B_SIGNED)).as_bool();
if(a_sign || b_sign)
return 3;
- //To be a counter, one input of the ALU must be a constant 1
- //TODO: can A or B be swapped in synthesized RTL or is B always the 1?
- const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B));
- if(!b_port.is_fully_const() || (b_port.as_int() != 1) )
- return 4;
-
- //BI and CI must be constant 1 as well
- const RTLIL::SigSpec bi_port = sigmap(cell->getPort(ID(BI)));
- if(!bi_port.is_fully_const() || (bi_port.as_int() != 1) )
- return 5;
- const RTLIL::SigSpec ci_port = sigmap(cell->getPort(ID(CI)));
- if(!ci_port.is_fully_const() || (ci_port.as_int() != 1) )
- return 6;
-
//CO and X must be unconnected (exactly one connection to each port)
if(!is_unconnected(sigmap(cell->getPort(ID(CO))), index))
return 7;
if(!is_unconnected(sigmap(cell->getPort(ID(X))), index))
return 8;
+ //true if $alu is performing A - B, else A + B
+ bool alu_is_subtract;
+
+ //BI and CI must be both constant 0 or both constant 1 as well
+ const RTLIL::SigSpec bi_port = sigmap(cell->getPort(ID(BI)));
+ const RTLIL::SigSpec ci_port = sigmap(cell->getPort(ID(CI)));
+ if(bi_port.is_fully_const() && bi_port.as_int() == 1 &&
+ ci_port.is_fully_const() && ci_port.as_int() == 1)
+ {
+ alu_is_subtract = true;
+ }
+ else if(bi_port.is_fully_const() && bi_port.as_int() == 0 &&
+ ci_port.is_fully_const() && ci_port.as_int() == 0)
+ {
+ alu_is_subtract = false;
+ }
+ else
+ {
+ return 5;
+ }
+
+ //false -> port B connects to value
+ //true -> port A connects to value
+ bool alu_port_use_a = false;
+
+ if(alu_is_subtract)
+ {
+ const int a_width = cell->getParam(ID(A_WIDTH)).as_int();
+ const int b_width = cell->getParam(ID(B_WIDTH)).as_int();
+ const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B));
+
+ // down, cnt <= cnt - 1
+ if (b_width == 1 && b_port.is_fully_const() && b_port.as_int() == 1)
+ {
+ // OK
+ alu_port_use_a = true;
+ extract.count_is_up = false;
+ }
+
+ // up, cnt <= cnt - -1
+ else if (b_width == a_width && b_port.is_fully_const() && b_port.is_fully_ones())
+ {
+ // OK
+ alu_port_use_a = true;
+ extract.count_is_up = true;
+ }
+
+ // ???
+ else
+ {
+ return 2;
+ }
+ }
+ else
+ {
+ const int a_width = cell->getParam(ID(A_WIDTH)).as_int();
+ const int b_width = cell->getParam(ID(B_WIDTH)).as_int();
+ const RTLIL::SigSpec a_port = sigmap(cell->getPort(ID::A));
+ const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B));
+
+ // down, cnt <= cnt + -1
+ if (b_width == a_width && b_port.is_fully_const() && b_port.is_fully_ones())
+ {
+ // OK
+ alu_port_use_a = true;
+ extract.count_is_up = false;
+ }
+ else if (a_width == b_width && a_port.is_fully_const() && a_port.is_fully_ones())
+ {
+ // OK
+ alu_port_use_a = false;
+ extract.count_is_up = false;
+ }
+
+ // up, cnt <= cnt + 1
+ else if (b_width == 1 && b_port.is_fully_const() && b_port.as_int() == 1)
+ {
+ // OK
+ alu_port_use_a = true;
+ extract.count_is_up = true;
+ }
+ else if (a_width == 1 && a_port.is_fully_const() && a_port.as_int() == 1)
+ {
+ // OK
+ alu_port_use_a = false;
+ extract.count_is_up = true;
+ }
+
+ // ???
+ else
+ {
+ return 2;
+ }
+ }
+
+ if (extract.count_is_up && settings.allowed_dirs == 0)
+ return 26;
+ if (!extract.count_is_up && settings.allowed_dirs == 1)
+ return 26;
+
+ //Check if counter is an appropriate size
+ int count_width;
+ if (alu_port_use_a)
+ count_width = cell->getParam(ID(A_WIDTH)).as_int();
+ else
+ count_width = cell->getParam(ID(B_WIDTH)).as_int();
+ extract.width = count_width;
+ if( (count_width < settings.minwidth) || (count_width > settings.maxwidth) )
+ return 1;
+
//Y must have exactly one connection, and it has to be a $mux cell.
//We must have a direct bus connection from our Y to their A.
const RTLIL::SigSpec aluy = sigmap(cell->getPort(ID::Y));
@@ -169,30 +265,43 @@ int counter_tryextract(
if(!is_full_bus(aluy, index, cell, ID::Y, count_mux, ID::A))
return 11;
- //B connection of the mux is our underflow value
- const RTLIL::SigSpec underflow = sigmap(count_mux->getPort(ID::B));
- if(!underflow.is_fully_const())
- return 12;
- extract.count_value = underflow.as_int();
+ if (extract.count_is_up)
+ {
+ //B connection of the mux must be 0
+ const RTLIL::SigSpec underflow = sigmap(count_mux->getPort(ID::B));
+ if(!(underflow.is_fully_const() && underflow.is_fully_zero()))
+ return 12;
+ }
+ else
+ {
+ //B connection of the mux is our underflow value
+ const RTLIL::SigSpec underflow = sigmap(count_mux->getPort(ID::B));
+ if(!underflow.is_fully_const())
+ return 12;
+ extract.count_value = underflow.as_int();
+ }
- //S connection of the mux must come from an inverter (need not be the only load)
+ //S connection of the mux must come from an inverter if down, eq if up
+ //(need not be the only load)
const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort(ID(S)));
extract.outsig = muxsel;
pool<Cell*> muxsel_conns = get_other_cells(muxsel, index, count_mux);
- Cell* underflow_inv = NULL;
+ Cell* overflow_cell = NULL;
for(auto c : muxsel_conns)
{
- if(c->type != ID($logic_not))
+ if(extract.count_is_up && c->type != ID($eq))
+ continue;
+ if(!extract.count_is_up && c->type != ID($logic_not))
continue;
if(!is_full_bus(muxsel, index, c, ID::Y, count_mux, ID(S), true))
continue;
- underflow_inv = c;
+ overflow_cell = c;
break;
}
- if(underflow_inv == NULL)
+ if(overflow_cell == NULL)
return 13;
- extract.underflow_inv = underflow_inv;
+ extract.overflow_cell = overflow_cell;
//Y connection of the mux must have exactly one load, the counter's internal register, if there's no clock enable
//If we have a clock enable, Y drives the B input of a mux. A of that mux must come from our register
@@ -215,14 +324,24 @@ int counter_tryextract(
return 24;
count_reg = *cey_loads.begin();
- //Mux should have A driven by count Q, and B by muxy
- //TODO: if A and B are swapped, CE polarity is inverted
- if(sigmap(cemux->getPort(ID::B)) != muxy)
- return 24;
- if(sigmap(cemux->getPort(ID::A)) != sigmap(count_reg->getPort(ID(Q))))
- return 24;
if(sigmap(cemux->getPort(ID::Y)) != sigmap(count_reg->getPort(ID(D))))
return 24;
+ //Mux should have A driven by count Q, and B by muxy
+ //if A and B are swapped, CE polarity is inverted
+ if(sigmap(cemux->getPort(ID::B)) == muxy &&
+ sigmap(cemux->getPort(ID::A)) == sigmap(count_reg->getPort(ID(Q))))
+ {
+ extract.ce_inverted = false;
+ }
+ else if(sigmap(cemux->getPort(ID::A)) == muxy &&
+ sigmap(cemux->getPort(ID::B)) == sigmap(count_reg->getPort(ID(Q))))
+ {
+ extract.ce_inverted = true;
+ }
+ else
+ {
+ return 24;
+ }
//Select of the mux is our clock enable
extract.has_ce = true;
@@ -236,6 +355,9 @@ int counter_tryextract(
extract.has_reset = false;
else if(count_reg->type == ID($adff))
{
+ if (!settings.allow_arst)
+ return 25;
+
extract.has_reset = true;
//Check polarity of reset - we may have to add an inverter later on!
@@ -260,7 +382,9 @@ int counter_tryextract(
//Sanity check that we use the ALU output properly
if(extract.has_ce)
{
- if(!is_full_bus(muxy, index, count_mux, ID::Y, cemux, ID::B))
+ if(!extract.ce_inverted && !is_full_bus(muxy, index, count_mux, ID::Y, cemux, ID::B))
+ return 16;
+ if(extract.ce_inverted && !is_full_bus(muxy, index, count_mux, ID::Y, cemux, ID::A))
return 16;
if(!is_full_bus(cey, index, cemux, ID::Y, count_reg, ID(D)))
return 16;
@@ -274,6 +398,8 @@ int counter_tryextract(
//(unless we have a parallel output!)
//If we have a clock enable, 3 is OK
const RTLIL::SigSpec qport = count_reg->getPort(ID(Q));
+ extract.poutsig = qport;
+ extract.has_pout = false;
const RTLIL::SigSpec cnout = sigmap(qport);
pool<Cell*> cnout_loads = get_other_cells(cnout, index, count_reg);
unsigned int max_loads = 2;
@@ -283,7 +409,7 @@ int counter_tryextract(
{
for(auto c : cnout_loads)
{
- if(c == underflow_inv)
+ if(c == overflow_cell)
continue;
if(c == cell)
continue;
@@ -291,15 +417,16 @@ int counter_tryextract(
continue;
//If we specified a limited set of cells for parallel output, check that we only drive them
- if(!parallel_cells.empty())
+ if(!settings.parallel_cells.empty())
{
//Make sure we're in the whitelist
- if( parallel_cells.find(c->type) == parallel_cells.end())
+ if( settings.parallel_cells.find(c->type) == settings.parallel_cells.end())
return 17;
}
//Figure out what port(s) are driven by it
//TODO: this can probably be done more efficiently w/o multiple iterations over our whole net?
+ //TODO: For what purpose do we actually need extract.pouts?
for(auto b : qport)
{
pool<ModIndex::PortInfo> ports = index.query_ports(b);
@@ -308,25 +435,75 @@ int counter_tryextract(
if(x.cell != c)
continue;
extract.pouts.insert(ModIndex::PortInfo(c, x.port, 0));
+ extract.has_pout = true;
}
}
}
}
- if(!is_full_bus(cnout, index, count_reg, ID(Q), underflow_inv, ID::A, true))
- return 18;
- if(!is_full_bus(cnout, index, count_reg, ID(Q), cell, ID::A, true))
+ for (auto b : qport)
+ {
+ if(index.query_is_output(b))
+ {
+ // Parallel out goes out of module
+ extract.has_pout = true;
+ }
+ }
+ if(!extract.count_is_up)
+ {
+ if(!is_full_bus(cnout, index, count_reg, ID(Q), overflow_cell, ID::A, true))
+ return 18;
+ }
+ else
+ {
+ if(is_full_bus(cnout, index, count_reg, ID(Q), overflow_cell, ID::A, true))
+ {
+ // B must be the overflow value
+ const RTLIL::SigSpec overflow = sigmap(overflow_cell->getPort(ID::B));
+ if(!overflow.is_fully_const())
+ return 12;
+ extract.count_value = overflow.as_int();
+ }
+ else if(is_full_bus(cnout, index, count_reg, ID(Q), overflow_cell, ID::B, true))
+ {
+ // A must be the overflow value
+ const RTLIL::SigSpec overflow = sigmap(overflow_cell->getPort(ID::A));
+ if(!overflow.is_fully_const())
+ return 12;
+ extract.count_value = overflow.as_int();
+ }
+ else
+ {
+ return 18;
+ }
+ }
+ if(alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID(Q), cell, ID::A, true))
+ return 19;
+ if(!alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID(Q), cell, ID::B, true))
return 19;
//Look up the clock from the register
extract.clk = sigmap(count_reg->getPort(ID(CLK)));
- //Register output net must have an INIT attribute equal to the count value
- extract.rwire = cnout.as_wire();
- if(extract.rwire->attributes.find(ID(init)) == extract.rwire->attributes.end())
- return 20;
- int rinit = extract.rwire->attributes[ID(init)].as_int();
- if(rinit != extract.count_value)
- return 21;
+ if(!extract.count_is_up)
+ {
+ //Register output net must have an INIT attribute equal to the count value
+ extract.rwire = cnout.as_wire();
+ if(extract.rwire->attributes.find(ID(init)) == extract.rwire->attributes.end())
+ return 20;
+ int rinit = extract.rwire->attributes[ID(init)].as_int();
+ if(rinit != extract.count_value)
+ return 21;
+ }
+ else
+ {
+ //Register output net must not have an INIT attribute or it must be zero
+ extract.rwire = cnout.as_wire();
+ if(extract.rwire->attributes.find(ID(init)) == extract.rwire->attributes.end())
+ return 0;
+ int rinit = extract.rwire->attributes[ID(init)].as_int();
+ if(rinit != 0)
+ return 21;
+ }
return 0;
}
@@ -337,8 +514,7 @@ void counter_worker(
unsigned int& total_counters,
pool<Cell*>& cells_to_remove,
pool<pair<Cell*, string>>& cells_to_rename,
- pool<RTLIL::IdString>& parallel_cells,
- int maxwidth)
+ CounterExtractionSettings settings)
{
SigMap& sigmap = index.sigmap;
@@ -350,20 +526,24 @@ void counter_worker(
//If it's not a wire, don't even try
auto port = sigmap(cell->getPort(ID::A));
if(!port.is_wire())
- return;
- RTLIL::Wire* a_wire = port.as_wire();
+ {
+ port = sigmap(cell->getPort(ID::B));
+ if(!port.is_wire())
+ return;
+ }
+ RTLIL::Wire* port_wire = port.as_wire();
bool force_extract = false;
bool never_extract = false;
- string count_reg_src = a_wire->attributes[ID(src)].decode_string().c_str();
- if(a_wire->attributes.find(ID(COUNT_EXTRACT)) != a_wire->attributes.end())
+ string count_reg_src = port_wire->attributes[ID(src)].decode_string().c_str();
+ if(port_wire->attributes.find(ID(COUNT_EXTRACT)) != port_wire->attributes.end())
{
- pool<string> sa = a_wire->get_strpool_attribute(ID(COUNT_EXTRACT));
+ pool<string> sa = port_wire->get_strpool_attribute(ID(COUNT_EXTRACT));
string extract_value;
if(sa.size() >= 1)
{
extract_value = *sa.begin();
log(" Signal %s declared at %s has COUNT_EXTRACT = %s\n",
- log_id(a_wire),
+ log_id(port_wire),
count_reg_src.c_str(),
extract_value.c_str());
@@ -385,21 +565,21 @@ void counter_worker(
//Attempt to extract a counter
CounterExtraction extract;
- int reason = counter_tryextract(index, cell, extract, parallel_cells, maxwidth);
+ int reason = counter_tryextract(index, cell, extract, settings);
//Nonzero code - we could not find a matchable counter.
//Do nothing, unless extraction was forced in which case give an error
if(reason != 0)
{
- static const char* reasons[25]=
+ static const char* reasons[]=
{
"no problem", //0
"counter is too large/small", //1
"counter does not count by one", //2
"counter uses signed math", //3
- "counter does not count by one", //4
- "ALU is not a subtractor", //5
- "ALU is not a subtractor", //6
+ "RESERVED, not implemented", //4
+ "ALU is not an adder/subtractor", //5
+ "RESERVED, not implemented", //6
"ALU ports used outside counter", //7
"ALU ports used outside counter", //8
"ALU output used outside counter", //9
@@ -417,14 +597,16 @@ void counter_worker(
"Underflow value is not equal to init value", //21
"RESERVED, not implemented", //22, kept for compatibility but not used anymore
"Reset is not to zero or COUNT_TO", //23
- "Clock enable configuration is unsupported" //24
+ "Clock enable configuration is unsupported", //24
+ "Async reset used but not permitted", //25
+ "Count direction is not allowed" //26
};
if(force_extract)
{
log_error(
"Counter extraction is set to FORCE on register %s, but a counter could not be inferred (%s)\n",
- log_id(a_wire),
+ log_id(port_wire),
reasons[reason]);
}
return;
@@ -483,36 +665,53 @@ void counter_worker(
if(extract.has_ce)
{
cell->setParam(ID(HAS_CE), RTLIL::Const(1));
- cell->setPort(ID(CE), extract.ce);
+ if(extract.ce_inverted)
+ {
+ auto realce = cell->module->addWire(NEW_ID);
+ cell->module->addNot(NEW_ID, extract.ce, RTLIL::SigSpec(realce));
+ cell->setPort(ID(CE), realce);
+ }
+ else
+ cell->setPort(ID(CE), extract.ce);
}
else
+ {
cell->setParam(ID(HAS_CE), RTLIL::Const(0));
+ cell->setPort(ID(CE), RTLIL::Const(1));
+ }
+
+ if(extract.count_is_up)
+ {
+ cell->setParam(ID(DIRECTION), RTLIL::Const("UP"));
+ //XXX: What is this supposed to do?
+ cell->setPort(ID(UP), RTLIL::Const(1));
+ }
+ else
+ {
+ cell->setParam(ID(DIRECTION), RTLIL::Const("DOWN"));
+ cell->setPort(ID(UP), RTLIL::Const(0));
+ }
- //Hook up hard-wired ports (for now up/down are not supported), default to no parallel output
+ //Hook up hard-wired ports, default to no parallel output
cell->setParam(ID(HAS_POUT), RTLIL::Const(0));
cell->setParam(ID(RESET_TO_MAX), RTLIL::Const(0));
- cell->setParam(ID(DIRECTION), RTLIL::Const("DOWN"));
- cell->setPort(ID(CE), RTLIL::Const(1));
- cell->setPort(ID(UP), RTLIL::Const(0));
//Hook up any parallel outputs
for(auto load : extract.pouts)
{
log(" Counter has parallel output to cell %s port %s\n", log_id(load.cell->name), log_id(load.port));
-
- //Find the wire hooked to the old port
- auto sig = load.cell->getPort(load.port);
-
+ }
+ if(extract.has_pout)
+ {
//Connect it to our parallel output
- //(this is OK to do more than once b/c they all go to the same place)
- cell->setPort(ID(POUT), sig);
+ cell->setPort(ID(POUT), extract.poutsig);
cell->setParam(ID(HAS_POUT), RTLIL::Const(1));
}
//Delete the cells we've replaced (let opt_clean handle deleting the now-redundant wires)
cells_to_remove.insert(extract.count_mux);
cells_to_remove.insert(extract.count_reg);
- cells_to_remove.insert(extract.underflow_inv);
+ cells_to_remove.insert(extract.overflow_cell);
//Log it
total_counters ++;
@@ -527,17 +726,19 @@ void counter_worker(
//TODO: support other kind of reset
reset_type += " async resettable";
}
- log(" Found %d-bit (%s) down counter %s (counting from %d) for register %s, declared at %s\n",
+ log(" Found %d-bit (%s) %s counter %s (counting %s %d) for register %s, declared at %s\n",
extract.width,
reset_type.c_str(),
+ extract.count_is_up ? "up" : "down",
countname.c_str(),
+ extract.count_is_up ? "to" : "from",
extract.count_value,
log_id(extract.rwire->name),
count_reg_src.c_str());
//Optimize the counter
//If we have no parallel output, and we have redundant bits, shrink us
- if(extract.pouts.empty())
+ if(!extract.has_pout)
{
//TODO: Need to update this when we add support for counters with nonzero reset values
//to make sure the reset value fits in our bit space too
@@ -570,7 +771,16 @@ struct ExtractCounterPass : public Pass {
log("to the actual target cells.\n");
log("\n");
log(" -maxwidth N\n");
- log(" Only extract counters up to N bits wide\n");
+ log(" Only extract counters up to N bits wide (default 64)\n");
+ log("\n");
+ log(" -minwidth N\n");
+ log(" Only extract counters at least N bits wide (default 2)\n");
+ log("\n");
+ log(" -allow_arst yes|no\n");
+ log(" Allow counters to have async reset (default yes)\n");
+ log("\n");
+ log(" -dir up|down|both\n");
+ log(" Look for up-counters, down-counters, or both (default down)\n");
log("\n");
log(" -pout X,Y,...\n");
log(" Only allow parallel output from the counter to the listed cell types\n");
@@ -582,9 +792,17 @@ struct ExtractCounterPass : public Pass {
{
log_header(design, "Executing EXTRACT_COUNTER pass (find counters in netlist).\n");
- int maxwidth = 64;
+ pool<RTLIL::IdString> _parallel_cells;
+ CounterExtractionSettings settings
+ {
+ .parallel_cells = _parallel_cells,
+ .maxwidth = 64,
+ .minwidth = 2,
+ .allow_arst = true,
+ .allowed_dirs = 0,
+ };
+
size_t argidx;
- pool<RTLIL::IdString> parallel_cells;
for (argidx = 1; argidx < args.size(); argidx++)
{
if (args[argidx] == "-pout")
@@ -601,24 +819,63 @@ struct ExtractCounterPass : public Pass {
{
if(pouts[i] == ',')
{
- parallel_cells.insert(RTLIL::escape_id(tmp));
+ settings.parallel_cells.insert(RTLIL::escape_id(tmp));
tmp = "";
}
else
tmp += pouts[i];
}
- parallel_cells.insert(RTLIL::escape_id(tmp));
+ settings.parallel_cells.insert(RTLIL::escape_id(tmp));
continue;
}
if (args[argidx] == "-maxwidth" && argidx+1 < args.size())
{
- maxwidth = atoi(args[++argidx].c_str());
+ settings.maxwidth = atoi(args[++argidx].c_str());
+ continue;
+ }
+
+ if (args[argidx] == "-minwidth" && argidx+1 < args.size())
+ {
+ settings.minwidth = atoi(args[++argidx].c_str());
+ continue;
+ }
+
+ if (args[argidx] == "-allow_arst" && argidx+1 < args.size())
+ {
+ auto arg = args[++argidx];
+ if (arg == "yes")
+ settings.allow_arst = true;
+ else if (arg == "no")
+ settings.allow_arst = false;
+ else
+ log_error("Invalid -allow_arst value \"%s\"\n", arg.c_str());
+ continue;
+ }
+
+ if (args[argidx] == "-dir" && argidx+1 < args.size())
+ {
+ auto arg = args[++argidx];
+ if (arg == "up")
+ settings.allowed_dirs = 1;
+ else if (arg == "down")
+ settings.allowed_dirs = 0;
+ else if (arg == "both")
+ settings.allowed_dirs = 2;
+ else
+ log_error("Invalid -dir value \"%s\"\n", arg.c_str());
continue;
}
}
extra_args(args, argidx, design);
+ if (settings.minwidth < 2)
+ {
+ //A counter with less than 2 bits makes no sense
+ log_warning("Minimum counter width is 2 bits wide\n");
+ settings.minwidth = 2;
+ }
+
//Extract all of the counters we could find
unsigned int total_counters = 0;
for (auto module : design->selected_modules())
@@ -628,7 +885,7 @@ struct ExtractCounterPass : public Pass {
ModIndex index(module);
for (auto cell : module->selected_cells())
- counter_worker(index, cell, total_counters, cells_to_remove, cells_to_rename, parallel_cells, maxwidth);
+ counter_worker(index, cell, total_counters, cells_to_remove, cells_to_rename, settings);
for(auto cell : cells_to_remove)
{
diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc
index 531ac2b99..8b1862237 100644
--- a/passes/techmap/iopadmap.cc
+++ b/passes/techmap/iopadmap.cc
@@ -83,6 +83,20 @@ struct IopadmapPass : public Pass {
log("Tristate PADS (-toutpad, -tinoutpad) always operate in -bits mode.\n");
log("\n");
}
+
+ void module_queue(Design *design, Module *module, std::vector<Module *> &modules_sorted, pool<Module *> &modules_processed) {
+ if (modules_processed.count(module))
+ return;
+ for (auto cell : module->cells()) {
+ Module *submodule = design->module(cell->type);
+ if (!submodule)
+ continue;
+ module_queue(design, submodule, modules_sorted, modules_processed);
+ }
+ modules_sorted.push_back(module);
+ modules_processed.insert(module);
+ }
+
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing IOPADMAP pass (mapping inputs/outputs to IO-PAD cells).\n");
@@ -172,22 +186,49 @@ struct IopadmapPass : public Pass {
if (!tinoutpad_portname_pad.empty())
ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname_pad)));
- for (auto module : design->modules())
- if (module->get_blackbox_attribute())
- for (auto wire : module->wires())
- if (wire->get_bool_attribute("\\iopad_external_pin"))
- ignore.insert(make_pair(module->name, wire->name));
+ // Recursively collect list of (module, port, bit) triples that already have buffers.
+
+ pool<pair<IdString, pair<IdString, int>>> buf_ports;
+ // Process submodules before module using them.
+ std::vector<Module *> modules_sorted;
+ pool<Module *> modules_processed;
for (auto module : design->selected_modules())
+ module_queue(design, module, modules_sorted, modules_processed);
+
+ for (auto module : modules_sorted)
{
- pool<SigBit> skip_wire_bits;
- dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits;
+ pool<SigBit> buf_bits;
+ SigMap sigmap(module);
+ // Collect explicitly-marked already-buffered SigBits.
+ for (auto wire : module->wires())
+ if (wire->get_bool_attribute("\\iopad_external_pin") || ignore.count(make_pair(module->name, wire->name)))
+ for (int i = 0; i < GetSize(wire); i++)
+ buf_bits.insert(sigmap(SigBit(wire, i)));
+
+ // Collect SigBits connected to already-buffered ports.
for (auto cell : module->cells())
for (auto port : cell->connections())
- if (ignore.count(make_pair(cell->type, port.first)))
- for (auto bit : port.second)
- skip_wire_bits.insert(bit);
+ for (int i = 0; i < port.second.size(); i++)
+ if (buf_ports.count(make_pair(cell->type, make_pair(port.first, i))))
+ buf_bits.insert(sigmap(port.second[i]));
+
+ // Now fill buf_ports.
+ for (auto wire : module->wires())
+ if (wire->port_input || wire->port_output)
+ for (int i = 0; i < GetSize(wire); i++)
+ if (buf_bits.count(sigmap(SigBit(wire, i)))) {
+ buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
+ log("Marking already mapped port: %s.%s[%d].\n", log_id(module), log_id(wire), i);
+ }
+ }
+
+ // Now do the actual buffer insertion.
+
+ for (auto module : design->selected_modules())
+ {
+ dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits;
if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty())
{
@@ -234,7 +275,7 @@ struct IopadmapPass : public Pass {
SigBit wire_bit(wire, i);
Cell *tbuf_cell = nullptr;
- if (skip_wire_bits.count(wire_bit))
+ if (buf_ports.count(make_pair(module->name, make_pair(wire->name, i))))
continue;
if (tbuf_bits.count(wire_bit))
@@ -267,7 +308,9 @@ struct IopadmapPass : public Pass {
{
log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, tinoutpad_celltype.c_str());
- Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(tinoutpad_celltype));
+ Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)),
+ RTLIL::escape_id(tinoutpad_celltype));
cell->setPort(RTLIL::escape_id(tinoutpad_portname_oe), en_sig);
cell->attributes[ID::keep] = RTLIL::Const(1);
@@ -282,13 +325,14 @@ struct IopadmapPass : public Pass {
cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit);
cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig);
}
- skip_wire_bits.insert(wire_bit);
if (!tinoutpad_portname_pad.empty())
rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(tinoutpad_portname_pad));
} else {
log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, toutpad_celltype.c_str());
- Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(toutpad_celltype));
+ Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)),
+ RTLIL::escape_id(toutpad_celltype));
cell->setPort(RTLIL::escape_id(toutpad_portname_oe), en_sig);
cell->setPort(RTLIL::escape_id(toutpad_portname_i), data_sig);
@@ -298,10 +342,10 @@ struct IopadmapPass : public Pass {
module->remove(tbuf_cell);
module->connect(wire_bit, data_sig);
}
- skip_wire_bits.insert(wire_bit);
if (!toutpad_portname_pad.empty())
rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(toutpad_portname_pad));
}
+ buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
}
}
}
@@ -315,7 +359,7 @@ struct IopadmapPass : public Pass {
pool<int> skip_bit_indices;
for (int i = 0; i < GetSize(wire); i++)
- if (skip_wire_bits.count(SigBit(wire, i)))
+ if (buf_ports.count(make_pair(module->name, make_pair(wire->name, i))))
skip_bit_indices.insert(i);
if (GetSize(wire) == GetSize(skip_bit_indices))
@@ -366,7 +410,9 @@ struct IopadmapPass : public Pass {
SigBit wire_bit(wire, i);
- RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype));
+ RTLIL::Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))),
+ RTLIL::escape_id(celltype));
cell->setPort(RTLIL::escape_id(portname_int), wire_bit);
if (!portname_pad.empty())
@@ -380,12 +426,16 @@ struct IopadmapPass : public Pass {
}
else
{
- RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype));
+ RTLIL::Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))),
+ RTLIL::escape_id(celltype));
cell->setPort(RTLIL::escape_id(portname_int), RTLIL::SigSpec(wire));
if (!portname_pad.empty()) {
RTLIL::Wire *new_wire = NULL;
- new_wire = module->addWire(NEW_ID, wire);
+ new_wire = module->addWire(
+ module->uniquify(stringf("$iopadmap$%s", log_id(wire))),
+ wire);
module->swap_names(new_wire, wire);
wire->attributes.clear();
cell->setPort(RTLIL::escape_id(portname_pad), RTLIL::SigSpec(new_wire));
@@ -406,7 +456,9 @@ struct IopadmapPass : public Pass {
for (auto &it : rewrite_bits) {
RTLIL::Wire *wire = it.first;
- RTLIL::Wire *new_wire = module->addWire(NEW_ID, wire);
+ RTLIL::Wire *new_wire = module->addWire(
+ module->uniquify(stringf("$iopadmap$%s", log_id(wire))),
+ wire);
module->swap_names(new_wire, wire);
wire->attributes.clear();
for (int i = 0; i < wire->width; i++)
@@ -423,6 +475,15 @@ struct IopadmapPass : public Pass {
}
}
+ if (wire->port_output) {
+ auto jt = new_wire->attributes.find(ID(init));
+ // For output ports, move \init attributes from old wire to new wire
+ if (jt != new_wire->attributes.end()) {
+ wire->attributes[ID(init)] = std::move(jt->second);
+ new_wire->attributes.erase(jt);
+ }
+ }
+
wire->port_id = 0;
wire->port_input = false;
wire->port_output = false;
diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc
index 0c57733d4..10001baaa 100644
--- a/passes/techmap/techmap.cc
+++ b/passes/techmap/techmap.cc
@@ -177,10 +177,10 @@ struct TechmapWorker
std::string orig_cell_name;
pool<string> extra_src_attrs = cell->get_strpool_attribute(ID(src));
+ orig_cell_name = cell->name.str();
if (!flatten_mode) {
for (auto &it : tpl->cells_)
if (it.first == ID(_TECHMAP_REPLACE_)) {
- orig_cell_name = cell->name.str();
module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str());
break;
}
diff --git a/techlibs/achronix/Makefile.inc b/techlibs/achronix/Makefile.inc
index 994cf0015..994cf0015 100755..100644
--- a/techlibs/achronix/Makefile.inc
+++ b/techlibs/achronix/Makefile.inc
diff --git a/techlibs/achronix/speedster22i/cells_arith.v b/techlibs/achronix/speedster22i/cells_arith.v
index e2194cbd7..e2194cbd7 100755..100644
--- a/techlibs/achronix/speedster22i/cells_arith.v
+++ b/techlibs/achronix/speedster22i/cells_arith.v
diff --git a/techlibs/achronix/speedster22i/cells_map.v b/techlibs/achronix/speedster22i/cells_map.v
index 9f647cbef..9f647cbef 100755..100644
--- a/techlibs/achronix/speedster22i/cells_map.v
+++ b/techlibs/achronix/speedster22i/cells_map.v
diff --git a/techlibs/achronix/speedster22i/cells_sim.v b/techlibs/achronix/speedster22i/cells_sim.v
index a0c60b4be..a0c60b4be 100755..100644
--- a/techlibs/achronix/speedster22i/cells_sim.v
+++ b/techlibs/achronix/speedster22i/cells_sim.v
diff --git a/techlibs/achronix/synth_achronix.cc b/techlibs/achronix/synth_achronix.cc
index 1dc6bdb2f..1dc6bdb2f 100755..100644
--- a/techlibs/achronix/synth_achronix.cc
+++ b/techlibs/achronix/synth_achronix.cc
diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc
index 42f1068ad..d5e69a241 100644
--- a/techlibs/common/Makefile.inc
+++ b/techlibs/common/Makefile.inc
@@ -29,3 +29,4 @@ $(eval $(call add_share_file,share,techlibs/common/gate2lut.v))
$(eval $(call add_share_file,share,techlibs/common/cmp2lut.v))
$(eval $(call add_share_file,share,techlibs/common/cells.lib))
$(eval $(call add_share_file,share,techlibs/common/mul2dsp.v))
+$(eval $(call add_share_file,share,techlibs/common/abc9_model.v))
diff --git a/techlibs/common/abc9_model.v b/techlibs/common/abc9_model.v
new file mode 100644
index 000000000..c0c5dc2fd
--- /dev/null
+++ b/techlibs/common/abc9_model.v
@@ -0,0 +1,10 @@
+module \$__ABC9_FF_ (input D, output Q);
+endmodule
+
+(* abc9_box *)
+module \$__ABC9_DELAY (input I, output O);
+ parameter DELAY = 0;
+ specify
+ (I => O) = DELAY;
+ endspecify
+endmodule
diff --git a/techlibs/common/gate2lut.v b/techlibs/common/gate2lut.v
index 99c123f4a..15cea3d8d 100644
--- a/techlibs/common/gate2lut.v
+++ b/techlibs/common/gate2lut.v
@@ -79,7 +79,7 @@ module _90_lut_mux (A, B, S, Y);
// A 1010 1010
// B 1100 1100
// S 1111 0000
- .LUT(8'b_1100_1010)
+ .LUT(8'b 1100_1010)
) lut (
.A(AA),
.Y(Y)
diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc
index a176357a7..e7a192c07 100644
--- a/techlibs/common/synth.cc
+++ b/techlibs/common/synth.cc
@@ -78,6 +78,9 @@ struct SynthPass : public ScriptPass
log(" -abc9\n");
log(" use new ABC9 flow (EXPERIMENTAL)\n");
log("\n");
+ log(" -flowmap\n");
+ log(" use FlowMap LUT techmapping instead of ABC\n");
+ log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
@@ -85,7 +88,7 @@ struct SynthPass : public ScriptPass
}
string top_module, fsm_opts, memory_opts, abc;
- bool autotop, flatten, noalumacc, nofsm, noabc, noshare;
+ bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap;
int lut;
void clear_flags() YS_OVERRIDE
@@ -101,6 +104,7 @@ struct SynthPass : public ScriptPass
nofsm = false;
noabc = false;
noshare = false;
+ flowmap = false;
abc = "abc";
}
@@ -167,6 +171,10 @@ struct SynthPass : public ScriptPass
abc = "abc9";
continue;
}
+ if (args[argidx] == "-flowmap") {
+ flowmap = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -176,6 +184,8 @@ struct SynthPass : public ScriptPass
if (abc == "abc9" && !lut)
log_cmd_error("ABC9 flow only supported for FPGA synthesis (using '-lut' option)\n");
+ if (flowmap && !lut)
+ log_cmd_error("FlowMap is only supported for FPGA synthesis (using '-lut' option)\n");
log_header(design, "Executing SYNTH pass.\n");
log_push();
@@ -240,15 +250,20 @@ struct SynthPass : public ScriptPass
{
run("techmap -map +/gate2lut.v", "(if -noabc and -lut)");
run("clean; opt_lut", " (if -noabc and -lut)");
+ run("flowmap -maxlut K", " (if -flowmap and -lut)");
}
else if (noabc && lut)
{
run(stringf("techmap -map +/gate2lut.v -D LUT_WIDTH=%d", lut));
run("clean; opt_lut");
}
+ else if (flowmap)
+ {
+ run(stringf("flowmap -maxlut %d", lut));
+ }
run("opt -fast");
- if (!noabc) {
+ if (!noabc && !flowmap) {
#ifdef YOSYS_ENABLE_ABC
if (help_mode)
{
diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v
index be6530eb4..ecf4d5dc5 100644
--- a/techlibs/common/techmap.v
+++ b/techlibs/common/techmap.v
@@ -149,16 +149,14 @@ module _90_shift_shiftx (A, B, Y);
_TECHMAP_CONSTVAL_B_[CLOG2_Y_WIDTH-1:0] == {CLOG2_Y_WIDTH{1'b0}}) begin
// Halve the size of $shift/$shiftx by $mux-ing A according to
// the LSB of B, after discarding the zeroed bits
- localparam len = 2**(B_WIDTH-1);
localparam Y_WIDTH2 = 2**CLOG2_Y_WIDTH;
- wire [len-1:0] T, F, AA;
- wire [(A_WIDTH+Y_WIDTH2*2):0] Apad = {{Y_WIDTH2*2{extbit}}, A};
+ localparam entries = (A_WIDTH+Y_WIDTH-1)/Y_WIDTH2;
+ localparam len = Y_WIDTH2 * ((entries+1)/2);
+ wire [len-1:0] AA;
+ wire [(A_WIDTH+Y_WIDTH2+Y_WIDTH-1)-1:0] Apad = {{(Y_WIDTH2+Y_WIDTH-1){extbit}}, A};
genvar i;
- for (i = 0; i < A_WIDTH; i=i+Y_WIDTH2*2) begin
- assign F[i/2 +: Y_WIDTH2] = A[i +: Y_WIDTH2];
- assign T[i/2 +: Y_WIDTH2] = Apad[i+Y_WIDTH2 +: Y_WIDTH2];
- assign AA[i/2 +: Y_WIDTH2] = B[CLOG2_Y_WIDTH] ? T[i/2 +: Y_WIDTH2] : F[i/2 +: Y_WIDTH2];
- end
+ for (i = 0; i < A_WIDTH; i=i+Y_WIDTH2*2)
+ assign AA[i/2 +: Y_WIDTH2] = B[CLOG2_Y_WIDTH] ? Apad[i+Y_WIDTH2 +: Y_WIDTH2] : Apad[i +: Y_WIDTH2];
wire [B_WIDTH-2:0] BB = {B[B_WIDTH-1:CLOG2_Y_WIDTH+1], {CLOG2_Y_WIDTH{1'b0}}};
if (_TECHMAP_CELLTYPE_ == "$shift")
$shift #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(len), .B_WIDTH(B_WIDTH-1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(AA), .B(BB), .Y(Y));
diff --git a/techlibs/coolrunner2/Makefile.inc b/techlibs/coolrunner2/Makefile.inc
index d62c9960c..7a680c4fd 100644
--- a/techlibs/coolrunner2/Makefile.inc
+++ b/techlibs/coolrunner2/Makefile.inc
@@ -1,8 +1,10 @@
OBJS += techlibs/coolrunner2/synth_coolrunner2.o
OBJS += techlibs/coolrunner2/coolrunner2_sop.o
+OBJS += techlibs/coolrunner2/coolrunner2_fixup.o
$(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/cells_latch.v))
$(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/cells_sim.v))
+$(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/cells_counter_map.v))
$(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/tff_extract.v))
$(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/xc2_dff.lib))
diff --git a/techlibs/coolrunner2/cells_counter_map.v b/techlibs/coolrunner2/cells_counter_map.v
new file mode 100644
index 000000000..b474fa522
--- /dev/null
+++ b/techlibs/coolrunner2/cells_counter_map.v
@@ -0,0 +1,161 @@
+module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP);
+
+ input wire CE;
+ input wire CLK;
+ output wire OUT;
+ output wire[WIDTH-1:0] POUT;
+ input wire RST;
+ input wire UP;
+
+ parameter COUNT_TO = 1;
+ parameter RESET_MODE = "RISING";
+ parameter RESET_TO_MAX = 0;
+ parameter HAS_POUT = 0;
+ parameter HAS_CE = 0;
+ parameter WIDTH = 8;
+ parameter DIRECTION = "DOWN";
+
+ if (DIRECTION == "UP") begin
+ if (WIDTH < 2) begin
+ initial begin
+ $display("ERROR: \$__COUNT_ must be at least 2 bits wide (bug in extract_counter pass?).");
+ $finish;
+ end
+ end
+
+ // FIXME: Max width?
+
+ assign OUT = POUT == COUNT_TO;
+
+ if (HAS_CE) begin
+ genvar i;
+ for (i = 0; i < WIDTH; i++) begin: countbits
+ // each bit = (cur & !reset) ^ (all prev & !reset)
+ wire xor_to_mc_bitn;
+ FDCP #(
+ .INIT(0)
+ ) bitn_ff (
+ .C(CLK),
+ .CLR(0),
+ .D(xor_to_mc_bitn),
+ .PRE(0),
+ .Q(POUT[i])
+ );
+ wire orterm_to_xor_bitn;
+ wire pterm0_to_or_bitn;
+ wire pterm1_to_or_bitn;
+ MACROCELL_XOR #(
+ .INVERT_OUT(0)
+ ) bitn_xor (
+ .IN_ORTERM(orterm_to_xor_bitn),
+ .IN_PTC(pterm1_to_or_bitn),
+ .OUT(xor_to_mc_bitn)
+ );
+ ORTERM #(
+ .WIDTH(1)
+ ) bitn_or (
+ .IN(pterm0_to_or_bitn),
+ .OUT(orterm_to_xor_bitn)
+ );
+ ANDTERM #(
+ .COMP_INP(1),
+ .TRUE_INP(1)
+ ) bitn_pterm0 (
+ .IN(POUT[i]),
+ .IN_B(OUT),
+ .OUT(pterm0_to_or_bitn)
+ );
+ ANDTERM #(
+ .COMP_INP(1),
+ .TRUE_INP(i + 1)
+ ) bitn_pterm1 (
+ .IN({POUT[i-1:0], CE}),
+ .IN_B(OUT),
+ .OUT(pterm1_to_or_bitn)
+ );
+ end
+ end else begin
+ // Bit0 is special; toggle unless reset
+ // cur reset out
+ // 0 0 1
+ // 0 1 0
+ // 1 0 0
+ // 1 1 0
+ wire xor_to_mc_bit0;
+ FDCP #(
+ .INIT(0)
+ ) bit0_ff (
+ .C(CLK),
+ .CLR(0),
+ .D(xor_to_mc_bit0),
+ .PRE(0),
+ .Q(POUT[0])
+ );
+ wire pterm_to_xor_bit0;
+ MACROCELL_XOR #(
+ .INVERT_OUT(0)
+ ) bit0_xor (
+ .IN_PTC(pterm_to_xor_bit0),
+ .OUT(xor_to_mc_bit0)
+ );
+ ANDTERM #(
+ .COMP_INP(2),
+ .TRUE_INP(0)
+ ) bit0_pterm (
+ .IN(),
+ .IN_B({POUT[0], OUT}),
+ .OUT(pterm_to_xor_bit0)
+ );
+
+ genvar i;
+ for (i = 1; i < WIDTH; i++) begin: countbits
+ // each bit = (cur & !reset) ^ (all prev & !reset)
+ wire xor_to_mc_bitn;
+ FDCP #(
+ .INIT(0)
+ ) bitn_ff (
+ .C(CLK),
+ .CLR(0),
+ .D(xor_to_mc_bitn),
+ .PRE(0),
+ .Q(POUT[i])
+ );
+ wire orterm_to_xor_bitn;
+ wire pterm0_to_or_bitn;
+ wire pterm1_to_or_bitn;
+ MACROCELL_XOR #(
+ .INVERT_OUT(0)
+ ) bitn_xor (
+ .IN_ORTERM(orterm_to_xor_bitn),
+ .IN_PTC(pterm1_to_or_bitn),
+ .OUT(xor_to_mc_bitn)
+ );
+ ORTERM #(
+ .WIDTH(1)
+ ) bitn_or (
+ .IN(pterm0_to_or_bitn),
+ .OUT(orterm_to_xor_bitn)
+ );
+ ANDTERM #(
+ .COMP_INP(1),
+ .TRUE_INP(1)
+ ) bitn_pterm0 (
+ .IN(POUT[i]),
+ .IN_B(OUT),
+ .OUT(pterm0_to_or_bitn)
+ );
+ ANDTERM #(
+ .COMP_INP(1),
+ .TRUE_INP(i)
+ ) bitn_pterm1 (
+ .IN(POUT[i-1:0]),
+ .IN_B(OUT),
+ .OUT(pterm1_to_or_bitn)
+ );
+ end
+ end
+ end
+
+ // FIXME: down counters
+
+endmodule
diff --git a/techlibs/coolrunner2/coolrunner2_fixup.cc b/techlibs/coolrunner2/coolrunner2_fixup.cc
new file mode 100644
index 000000000..a71a1227e
--- /dev/null
+++ b/techlibs/coolrunner2/coolrunner2_fixup.cc
@@ -0,0 +1,520 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2020 R. Ou <rqou@robertou.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/yosys.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cellname)
+{
+ RTLIL::Wire *outwire = nullptr;
+
+ if (inwire == SigBit(true))
+ {
+ // Constant 1
+ outwire = module->addWire(
+ module->uniquify(stringf("$xc2fix$%s_BUF1_XOR_OUT", cellname)));
+ auto xor_cell = module->addCell(
+ module->uniquify(stringf("$xc2fix$%s_BUF1_XOR", cellname)),
+ "\\MACROCELL_XOR");
+ xor_cell->setParam("\\INVERT_OUT", true);
+ xor_cell->setPort("\\OUT", outwire);
+ }
+ else if (inwire == SigBit(false))
+ {
+ // Constant 0
+ outwire = module->addWire(
+ module->uniquify(stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname)));
+ auto xor_cell = module->addCell(
+ module->uniquify(stringf("$xc2fix$%s_BUF0_XOR", cellname)),
+ "\\MACROCELL_XOR");
+ xor_cell->setParam("\\INVERT_OUT", false);
+ xor_cell->setPort("\\OUT", outwire);
+ }
+ else if (inwire == SigBit(RTLIL::State::Sx))
+ {
+ // x; treat as 0
+ log_warning("While buffering, changing x to 0 into cell %s\n", cellname);
+ outwire = module->addWire(
+ module->uniquify(stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname)));
+ auto xor_cell = module->addCell(
+ module->uniquify(stringf("$xc2fix$%s_BUF0_XOR", cellname)),
+ "\\MACROCELL_XOR");
+ xor_cell->setParam("\\INVERT_OUT", false);
+ xor_cell->setPort("\\OUT", outwire);
+ }
+ else
+ {
+ auto inwire_name = inwire.wire->name.c_str();
+
+ outwire = module->addWire(
+ module->uniquify(stringf("$xc2fix$%s_BUF_XOR_OUT", inwire_name)));
+
+ auto and_to_xor_wire = module->addWire(
+ module->uniquify(stringf("$xc2fix$%s_BUF_AND_OUT", inwire_name)));
+
+ auto and_cell = module->addCell(
+ module->uniquify(stringf("$xc2fix$%s_BUF_AND", inwire_name)),
+ "\\ANDTERM");
+ and_cell->setParam("\\TRUE_INP", 1);
+ and_cell->setParam("\\COMP_INP", 0);
+ and_cell->setPort("\\OUT", and_to_xor_wire);
+ and_cell->setPort("\\IN", inwire);
+ and_cell->setPort("\\IN_B", SigSpec());
+
+ auto xor_cell = module->addCell(
+ module->uniquify(stringf("$xc2fix$%s_BUF_XOR", inwire_name)),
+ "\\MACROCELL_XOR");
+ xor_cell->setParam("\\INVERT_OUT", false);
+ xor_cell->setPort("\\IN_PTC", and_to_xor_wire);
+ xor_cell->setPort("\\OUT", outwire);
+ }
+
+ return outwire;
+}
+
+RTLIL::Wire *makeptermbuffer(RTLIL::Module *module, SigBit inwire)
+{
+ auto inwire_name = inwire.wire->name.c_str();
+
+ auto outwire = module->addWire(
+ module->uniquify(stringf("$xc2fix$%s_BUF_AND_OUT", inwire_name)));
+
+ auto and_cell = module->addCell(
+ module->uniquify(stringf("$xc2fix$%s_BUF_AND", inwire_name)),
+ "\\ANDTERM");
+ and_cell->setParam("\\TRUE_INP", 1);
+ and_cell->setParam("\\COMP_INP", 0);
+ and_cell->setPort("\\OUT", outwire);
+ and_cell->setPort("\\IN", inwire);
+ and_cell->setPort("\\IN_B", SigSpec());
+
+ return outwire;
+}
+
+struct Coolrunner2FixupPass : public Pass {
+ Coolrunner2FixupPass() : Pass("coolrunner2_fixup", "insert necessary buffer cells for CoolRunner-II architecture") { }
+ void help() YS_OVERRIDE
+ {
+ log("\n");
+ log(" coolrunner2_fixup [options] [selection]\n");
+ log("\n");
+ log("Insert necessary buffer cells for CoolRunner-II architecture.\n");
+ log("\n");
+ }
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ log_header(design, "Executing COOLRUNNER2_FIXUP pass (insert necessary buffer cells for CoolRunner-II architecture).\n");
+ extra_args(args, 1, design);
+
+ for (auto module : design->selected_modules())
+ {
+ SigMap sigmap(module);
+
+ // Find all the FF outputs
+ pool<SigBit> sig_fed_by_ff;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N",
+ "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
+ {
+ auto output = sigmap(cell->getPort("\\Q")[0]);
+ sig_fed_by_ff.insert(output);
+ }
+ }
+
+ // Find all the XOR outputs
+ pool<SigBit> sig_fed_by_xor;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\MACROCELL_XOR")
+ {
+ auto output = sigmap(cell->getPort("\\OUT")[0]);
+ sig_fed_by_xor.insert(output);
+ }
+ }
+
+ // Find all the input/inout outputs
+ pool<SigBit> sig_fed_by_io;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type.in("\\IBUF", "\\IOBUFE"))
+ {
+ if (cell->hasPort("\\O")) {
+ auto output = sigmap(cell->getPort("\\O")[0]);
+ sig_fed_by_io.insert(output);
+ }
+ }
+ }
+
+ // Find all the pterm outputs
+ pool<SigBit> sig_fed_by_pterm;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\ANDTERM")
+ {
+ auto output = sigmap(cell->getPort("\\OUT")[0]);
+ sig_fed_by_pterm.insert(output);
+ }
+ }
+
+ // Find all the bufg outputs
+ pool<SigBit> sig_fed_by_bufg;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\BUFG")
+ {
+ auto output = sigmap(cell->getPort("\\O")[0]);
+ sig_fed_by_bufg.insert(output);
+ }
+ }
+
+ // Find all the bufgsr outputs
+ pool<SigBit> sig_fed_by_bufgsr;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\BUFGSR")
+ {
+ auto output = sigmap(cell->getPort("\\O")[0]);
+ sig_fed_by_bufgsr.insert(output);
+ }
+ }
+
+ // Find all the bufgts outputs
+ pool<SigBit> sig_fed_by_bufgts;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\BUFGTS")
+ {
+ auto output = sigmap(cell->getPort("\\O")[0]);
+ sig_fed_by_bufgts.insert(output);
+ }
+ }
+
+ // This is used to fix the input -> FF -> output scenario
+ pool<SigBit> sig_fed_by_ibuf;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\IBUF")
+ {
+ auto output = sigmap(cell->getPort("\\O")[0]);
+ sig_fed_by_ibuf.insert(output);
+ }
+ }
+
+ // Find all of the sinks for each output from an IBUF
+ dict<SigBit, std::pair<int, RTLIL::Cell *>> ibuf_fanouts;
+ for (auto cell : module->selected_cells())
+ {
+ for (auto &conn : cell->connections())
+ {
+ if (cell->input(conn.first))
+ {
+ for (auto wire_in : sigmap(conn.second))
+ {
+ if (sig_fed_by_ibuf[wire_in])
+ {
+ auto existing_count = ibuf_fanouts[wire_in].first;
+ ibuf_fanouts[wire_in] =
+ std::pair<int, RTLIL::Cell *>(existing_count + 1, cell);
+ }
+ }
+ }
+ }
+ }
+
+ dict<SigBit, RTLIL::Cell *> ibuf_out_to_packed_reg_cell;
+ pool<SigBit> packed_reg_out;
+ for (auto x : ibuf_fanouts)
+ {
+ auto ibuf_out_wire = x.first;
+ auto fanout_count = x.second.first;
+ auto maybe_ff_cell = x.second.second;
+
+ // The register can be packed with the IBUF only if it's
+ // actually a register and it's the only fanout. Otherwise,
+ // the pad-to-zia path has to be used up and the register
+ // can't be packed with the ibuf.
+ if (fanout_count == 1 && maybe_ff_cell->type.in(
+ "\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N",
+ "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
+ {
+ SigBit input;
+ if (maybe_ff_cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP"))
+ input = sigmap(maybe_ff_cell->getPort("\\T")[0]);
+ else
+ input = sigmap(maybe_ff_cell->getPort("\\D")[0]);
+ SigBit output = sigmap(maybe_ff_cell->getPort("\\Q")[0]);
+
+ if (input == ibuf_out_wire)
+ {
+ log("Found IBUF %s that can be packed with FF %s (type %s)\n",
+ ibuf_out_wire.wire->name.c_str(),
+ maybe_ff_cell->name.c_str(),
+ maybe_ff_cell->type.c_str());
+
+ ibuf_out_to_packed_reg_cell[ibuf_out_wire] = maybe_ff_cell;
+ packed_reg_out.insert(output);
+ }
+ }
+ }
+
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N",
+ "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
+ {
+ // Buffering FF inputs. FF inputs can only come from either
+ // an IO pin or from an XOR. Otherwise AND/XOR cells need
+ // to be inserted.
+ SigBit input;
+ if (cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP"))
+ input = sigmap(cell->getPort("\\T")[0]);
+ else
+ input = sigmap(cell->getPort("\\D")[0]);
+
+ // If the input wasn't an XOR nor an IO, then a buffer
+ // definitely needs to be added.
+ // Otherwise, if it is an IO, only leave unbuffered
+ // if we're being packed with the IO.
+ if ((!sig_fed_by_xor[input] && !sig_fed_by_io[input]) ||
+ (sig_fed_by_io[input] && ibuf_out_to_packed_reg_cell[input] != cell))
+ {
+ log("Buffering input to \"%s\"\n", cell->name.c_str());
+
+ auto xor_to_ff_wire = makexorbuffer(module, input, cell->name.c_str());
+
+ if (cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP"))
+ cell->setPort("\\T", xor_to_ff_wire);
+ else
+ cell->setPort("\\D", xor_to_ff_wire);
+ }
+
+ // Buffering FF clocks. FF clocks can only come from either
+ // a pterm or a bufg. In some cases this will be handled
+ // in coolrunner2_sop (e.g. if clock is generated from
+ // AND-ing two signals) but not in all cases.
+ SigBit clock;
+ if (cell->type.in("\\LDCP", "\\LDCP_N"))
+ clock = sigmap(cell->getPort("\\G")[0]);
+ else
+ clock = sigmap(cell->getPort("\\C")[0]);
+
+ if (!sig_fed_by_pterm[clock] && !sig_fed_by_bufg[clock])
+ {
+ log("Buffering clock to \"%s\"\n", cell->name.c_str());
+
+ auto pterm_to_ff_wire = makeptermbuffer(module, clock);
+
+ if (cell->type.in("\\LDCP", "\\LDCP_N"))
+ cell->setPort("\\G", pterm_to_ff_wire);
+ else
+ cell->setPort("\\C", pterm_to_ff_wire);
+ }
+
+ // Buffering FF set/reset. This can only come from either
+ // a pterm or a bufgsr.
+ SigBit set;
+ set = sigmap(cell->getPort("\\PRE")[0]);
+ if (set != SigBit(false))
+ {
+ if (!sig_fed_by_pterm[set] && !sig_fed_by_bufgsr[set])
+ {
+ log("Buffering set to \"%s\"\n", cell->name.c_str());
+
+ auto pterm_to_ff_wire = makeptermbuffer(module, set);
+
+ cell->setPort("\\PRE", pterm_to_ff_wire);
+ }
+ }
+
+ SigBit reset;
+ reset = sigmap(cell->getPort("\\CLR")[0]);
+ if (reset != SigBit(false))
+ {
+ if (!sig_fed_by_pterm[reset] && !sig_fed_by_bufgsr[reset])
+ {
+ log("Buffering reset to \"%s\"\n", cell->name.c_str());
+
+ auto pterm_to_ff_wire = makeptermbuffer(module, reset);
+
+ cell->setPort("\\CLR", pterm_to_ff_wire);
+ }
+ }
+
+ // Buffering FF clock enable
+ // FIXME: This doesn't fully fix PTC conflicts
+ // FIXME: Need to ensure constant enables are optimized out
+ if (cell->type.in("\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
+ {
+ SigBit ce;
+ ce = sigmap(cell->getPort("\\CE")[0]);
+ if (!sig_fed_by_pterm[ce])
+ {
+ log("Buffering clock enable to \"%s\"\n", cell->name.c_str());
+
+ auto pterm_to_ff_wire = makeptermbuffer(module, ce);
+
+ cell->setPort("\\CE", pterm_to_ff_wire);
+ }
+ }
+ }
+ }
+
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\IOBUFE")
+ {
+ // Buffer IOBUFE inputs. This can only be fed from an XOR or FF.
+ SigBit input = sigmap(cell->getPort("\\I")[0]);
+
+ if ((!sig_fed_by_xor[input] && !sig_fed_by_ff[input]) ||
+ packed_reg_out[input])
+ {
+ log("Buffering input to \"%s\"\n", cell->name.c_str());
+
+ auto xor_to_io_wire = makexorbuffer(module, input, cell->name.c_str());
+
+ cell->setPort("\\I", xor_to_io_wire);
+ }
+
+ // Buffer IOBUFE enables. This can only be fed from a pterm
+ // or a bufgts.
+ if (cell->hasPort("\\E"))
+ {
+ SigBit oe;
+ oe = sigmap(cell->getPort("\\E")[0]);
+ if (!sig_fed_by_pterm[oe] && !sig_fed_by_bufgts[oe])
+ {
+ log("Buffering output enable to \"%s\"\n", cell->name.c_str());
+
+ auto pterm_to_oe_wire = makeptermbuffer(module, oe);
+
+ cell->setPort("\\E", pterm_to_oe_wire);
+ }
+ }
+ }
+ }
+
+ // Now we have to fix up some cases where shared logic can
+ // cause XORs to have multiple fanouts to something other than
+ // pterms (which is not ok)
+
+ // Find all the XOR outputs
+ dict<SigBit, RTLIL::Cell *> xor_out_to_xor_cell;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\MACROCELL_XOR")
+ {
+ auto output = sigmap(cell->getPort("\\OUT")[0]);
+ xor_out_to_xor_cell[output] = cell;
+ }
+ }
+
+ // Find all of the sinks for each output from an XOR
+ pool<SigBit> xor_fanout_once;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\ANDTERM")
+ continue;
+
+ for (auto &conn : cell->connections())
+ {
+ if (cell->input(conn.first))
+ {
+ for (auto wire_in : sigmap(conn.second))
+ {
+ auto xor_cell = xor_out_to_xor_cell[wire_in];
+ if (xor_cell)
+ {
+ if (xor_fanout_once[wire_in])
+ {
+ log("Additional fanout found for %s into %s (type %s), duplicating\n",
+ xor_cell->name.c_str(),
+ cell->name.c_str(),
+ cell->type.c_str());
+
+ auto new_xor_cell = module->addCell(
+ module->uniquify(xor_cell->name), xor_cell);
+ auto new_wire = module->addWire(
+ module->uniquify(wire_in.wire->name));
+ new_xor_cell->setPort("\\OUT", new_wire);
+ cell->setPort(conn.first, new_wire);
+ }
+ xor_fanout_once.insert(wire_in);
+ }
+ }
+ }
+ }
+ }
+
+ // Do the same fanout fixing for OR terms. By doing this
+ // after doing XORs, both pieces will be duplicated when necessary.
+
+ // Find all the OR outputs
+ dict<SigBit, RTLIL::Cell *> or_out_to_or_cell;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\ORTERM")
+ {
+ auto output = sigmap(cell->getPort("\\OUT")[0]);
+ or_out_to_or_cell[output] = cell;
+ }
+ }
+
+ // Find all of the sinks for each output from an OR
+ pool<SigBit> or_fanout_once;
+ for (auto cell : module->selected_cells())
+ {
+ for (auto &conn : cell->connections())
+ {
+ if (cell->input(conn.first))
+ {
+ for (auto wire_in : sigmap(conn.second))
+ {
+ auto or_cell = or_out_to_or_cell[wire_in];
+ if (or_cell)
+ {
+ if (or_fanout_once[wire_in])
+ {
+ log("Additional fanout found for %s into %s (type %s), duplicating\n",
+ or_cell->name.c_str(),
+ cell->name.c_str(),
+ cell->type.c_str());
+
+ auto new_or_cell = module->addCell(
+ module->uniquify(or_cell->name), or_cell);
+ auto new_wire = module->addWire(
+ module->uniquify(wire_in.wire->name));
+ new_or_cell->setPort("\\OUT", new_wire);
+ cell->setPort(conn.first, new_wire);
+ }
+ or_fanout_once.insert(wire_in);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+} Coolrunner2FixupPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/techlibs/coolrunner2/coolrunner2_sop.cc b/techlibs/coolrunner2/coolrunner2_sop.cc
index de0cbb29d..581477473 100644
--- a/techlibs/coolrunner2/coolrunner2_sop.cc
+++ b/techlibs/coolrunner2/coolrunner2_sop.cc
@@ -94,6 +94,8 @@ struct Coolrunner2SopPass : public Pass {
auto sop_width = cell->getParam("\\WIDTH").as_int();
auto sop_table = cell->getParam("\\TABLE");
+ auto sop_output_wire_name = sop_output.wire->name.c_str();
+
// Check for a $_NOT_ at the output
bool has_invert = false;
if (not_cells.count(sop_output))
@@ -108,20 +110,15 @@ struct Coolrunner2SopPass : public Pass {
}
// Check for special P-term usage
- bool is_special_pterm = false;
- bool special_pterm_can_invert = false;
- if (special_pterms_no_inv.count(sop_output) || special_pterms_inv.count(sop_output))
- {
- is_special_pterm = true;
- if (!special_pterms_no_inv[sop_output].size())
- special_pterm_can_invert = true;
- }
+ bool is_special_pterm =
+ special_pterms_no_inv.count(sop_output) || special_pterms_inv.count(sop_output);
// Construct AND cells
pool<SigBit> intermed_wires;
for (int i = 0; i < sop_depth; i++) {
// Wire for the output
- auto and_out = module->addWire(NEW_ID);
+ auto and_out = module->addWire(
+ module->uniquify(stringf("$xc2sop$%s_AND%d_OUT", sop_output_wire_name, i)));
intermed_wires.insert(and_out);
// Signals for the inputs
@@ -140,7 +137,9 @@ struct Coolrunner2SopPass : public Pass {
}
// Construct the cell
- auto and_cell = module->addCell(NEW_ID, "\\ANDTERM");
+ auto and_cell = module->addCell(
+ module->uniquify(stringf("$xc2sop$%s_AND%d", sop_output_wire_name, i)),
+ "\\ANDTERM");
and_cell->setParam("\\TRUE_INP", GetSize(and_in_true));
and_cell->setParam("\\COMP_INP", GetSize(and_in_comp));
and_cell->setPort("\\OUT", and_out);
@@ -151,7 +150,9 @@ struct Coolrunner2SopPass : public Pass {
if (sop_depth == 1)
{
// If there is only one term, don't construct an OR cell. Directly construct the XOR gate
- auto xor_cell = module->addCell(NEW_ID, "\\MACROCELL_XOR");
+ auto xor_cell = module->addCell(
+ module->uniquify(stringf("$xc2sop$%s_XOR", sop_output_wire_name)),
+ "\\MACROCELL_XOR");
xor_cell->setParam("\\INVERT_OUT", has_invert);
xor_cell->setPort("\\IN_PTC", *intermed_wires.begin());
xor_cell->setPort("\\OUT", sop_output);
@@ -159,88 +160,61 @@ struct Coolrunner2SopPass : public Pass {
// Special P-term handling
if (is_special_pterm)
{
- if (!has_invert || special_pterm_can_invert)
+ // Can always connect the P-term directly if it's going
+ // into something invert-capable
+ for (auto x : special_pterms_inv[sop_output])
{
- // Can connect the P-term directly to the special term sinks
- for (auto x : special_pterms_inv[sop_output])
- std::get<0>(x)->setPort(std::get<1>(x), *intermed_wires.begin());
- for (auto x : special_pterms_no_inv[sop_output])
- std::get<0>(x)->setPort(std::get<1>(x), *intermed_wires.begin());
- }
+ std::get<0>(x)->setPort(std::get<1>(x), *intermed_wires.begin());
- if (has_invert)
- {
- if (special_pterm_can_invert)
+ // If this signal is indeed inverted, flip the cell polarity
+ if (has_invert)
{
- log_assert(special_pterms_no_inv[sop_output].size() == 0);
-
- for (auto x : special_pterms_inv[sop_output])
- {
- auto cell = std::get<0>(x);
- // Need to invert the polarity of the cell
- if (cell->type == "\\FDCP") cell->type = "\\FDCP_N";
- else if (cell->type == "\\FDCP_N") cell->type = "\\FDCP";
- else if (cell->type == "\\FTCP") cell->type = "\\FTCP_N";
- else if (cell->type == "\\FTCP_N") cell->type = "\\FTCP";
- else if (cell->type == "\\FDCPE") cell->type = "\\FDCPE_N";
- else if (cell->type == "\\FDCPE_N") cell->type = "\\FDCPE";
- else if (cell->type == "\\LDCP") cell->type = "\\LDCP_N";
- else if (cell->type == "\\LDCP_N") cell->type = "\\LDCP";
- else log_assert(!"Internal error! Bad cell type!");
- }
+ auto cell = std::get<0>(x);
+ if (cell->type == "\\FDCP") cell->type = "\\FDCP_N";
+ else if (cell->type == "\\FDCP_N") cell->type = "\\FDCP";
+ else if (cell->type == "\\FTCP") cell->type = "\\FTCP_N";
+ else if (cell->type == "\\FTCP_N") cell->type = "\\FTCP";
+ else if (cell->type == "\\FDCPE") cell->type = "\\FDCPE_N";
+ else if (cell->type == "\\FDCPE_N") cell->type = "\\FDCPE";
+ else if (cell->type == "\\LDCP") cell->type = "\\LDCP_N";
+ else if (cell->type == "\\LDCP_N") cell->type = "\\LDCP";
+ else log_assert(!"Internal error! Bad cell type!");
}
- else
- {
- // Need to construct a feed-through term
- auto feedthrough_out = module->addWire(NEW_ID);
- auto feedthrough_cell = module->addCell(NEW_ID, "\\ANDTERM");
- feedthrough_cell->setParam("\\TRUE_INP", 1);
- feedthrough_cell->setParam("\\COMP_INP", 0);
- feedthrough_cell->setPort("\\OUT", feedthrough_out);
- feedthrough_cell->setPort("\\IN", sop_output);
- feedthrough_cell->setPort("\\IN_B", SigSpec());
+ }
- for (auto x : special_pterms_inv[sop_output])
- std::get<0>(x)->setPort(std::get<1>(x), feedthrough_out);
- for (auto x : special_pterms_no_inv[sop_output])
- std::get<0>(x)->setPort(std::get<1>(x), feedthrough_out);
- }
+ // If it's going into something that's not invert-capable,
+ // connect it directly only if this signal isn't inverted
+ if (!has_invert)
+ {
+ for (auto x : special_pterms_no_inv[sop_output])
+ std::get<0>(x)->setPort(std::get<1>(x), *intermed_wires.begin());
}
+
+ // Otherwise, a feedthrough P-term has to be created. Leave that to happen
+ // in the coolrunner2_fixup pass.
}
}
else
{
// Wire from OR to XOR
- auto or_to_xor_wire = module->addWire(NEW_ID);
+ auto or_to_xor_wire = module->addWire(
+ module->uniquify(stringf("$xc2sop$%s_OR_OUT", sop_output_wire_name)));
// Construct the OR cell
- auto or_cell = module->addCell(NEW_ID, "\\ORTERM");
+ auto or_cell = module->addCell(
+ module->uniquify(stringf("$xc2sop$%s_OR", sop_output_wire_name)),
+ "\\ORTERM");
or_cell->setParam("\\WIDTH", sop_depth);
or_cell->setPort("\\IN", intermed_wires);
or_cell->setPort("\\OUT", or_to_xor_wire);
// Construct the XOR cell
- auto xor_cell = module->addCell(NEW_ID, "\\MACROCELL_XOR");
+ auto xor_cell = module->addCell(
+ module->uniquify(stringf("$xc2sop$%s_XOR", sop_output_wire_name)),
+ "\\MACROCELL_XOR");
xor_cell->setParam("\\INVERT_OUT", has_invert);
xor_cell->setPort("\\IN_ORTERM", or_to_xor_wire);
xor_cell->setPort("\\OUT", sop_output);
-
- if (is_special_pterm)
- {
- // Need to construct a feed-through term
- auto feedthrough_out = module->addWire(NEW_ID);
- auto feedthrough_cell = module->addCell(NEW_ID, "\\ANDTERM");
- feedthrough_cell->setParam("\\TRUE_INP", 1);
- feedthrough_cell->setParam("\\COMP_INP", 0);
- feedthrough_cell->setPort("\\OUT", feedthrough_out);
- feedthrough_cell->setPort("\\IN", sop_output);
- feedthrough_cell->setPort("\\IN_B", SigSpec());
-
- for (auto x : special_pterms_inv[sop_output])
- std::get<0>(x)->setPort(std::get<1>(x), feedthrough_out);
- for (auto x : special_pterms_no_inv[sop_output])
- std::get<0>(x)->setPort(std::get<1>(x), feedthrough_out);
- }
}
// Finally, remove the $sop cell
@@ -248,60 +222,6 @@ struct Coolrunner2SopPass : public Pass {
}
}
- // In some cases we can get a FF feeding straight into an FF. This is not possible, so we need to insert
- // some AND/XOR cells in the middle to make it actually work.
-
- // Find all the FF outputs
- pool<SigBit> sig_fed_by_ff;
- for (auto cell : module->selected_cells())
- {
- if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N",
- "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
- {
- auto output = sigmap(cell->getPort("\\Q")[0]);
- sig_fed_by_ff.insert(output);
- }
- }
-
- // Look at all the FF inputs
- for (auto cell : module->selected_cells())
- {
- if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N",
- "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
- {
- SigBit input;
- if (cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP"))
- input = sigmap(cell->getPort("\\T")[0]);
- else
- input = sigmap(cell->getPort("\\D")[0]);
-
- if (sig_fed_by_ff[input])
- {
- printf("Buffering input to \"%s\"\n", cell->name.c_str());
-
- auto and_to_xor_wire = module->addWire(NEW_ID);
- auto xor_to_ff_wire = module->addWire(NEW_ID);
-
- auto and_cell = module->addCell(NEW_ID, "\\ANDTERM");
- and_cell->setParam("\\TRUE_INP", 1);
- and_cell->setParam("\\COMP_INP", 0);
- and_cell->setPort("\\OUT", and_to_xor_wire);
- and_cell->setPort("\\IN", input);
- and_cell->setPort("\\IN_B", SigSpec());
-
- auto xor_cell = module->addCell(NEW_ID, "\\MACROCELL_XOR");
- xor_cell->setParam("\\INVERT_OUT", false);
- xor_cell->setPort("\\IN_PTC", and_to_xor_wire);
- xor_cell->setPort("\\OUT", xor_to_ff_wire);
-
- if (cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP"))
- cell->setPort("\\T", xor_to_ff_wire);
- else
- cell->setPort("\\D", xor_to_ff_wire);
- }
- }
- }
-
// Actually do the removal now that we aren't iterating
for (auto cell : cells_to_remove)
{
diff --git a/techlibs/coolrunner2/synth_coolrunner2.cc b/techlibs/coolrunner2/synth_coolrunner2.cc
index 3bac8623d..d5eeaf547 100644
--- a/techlibs/coolrunner2/synth_coolrunner2.cc
+++ b/techlibs/coolrunner2/synth_coolrunner2.cc
@@ -143,6 +143,9 @@ struct SynthCoolrunner2Pass : public ScriptPass
if (check_label("fine"))
{
+ run("extract_counter -dir up -allow_arst no");
+ run("techmap -map +/coolrunner2/cells_counter_map.v");
+ run("clean");
run("opt -fast -full");
run("techmap -map +/techmap.v -map +/coolrunner2/cells_latch.v");
run("opt -fast");
@@ -175,9 +178,11 @@ struct SynthCoolrunner2Pass : public ScriptPass
run("dffinit -ff LDCP Q INIT");
run("dffinit -ff LDCP_N Q INIT");
run("coolrunner2_sop");
+ run("clean");
run("iopadmap -bits -inpad IBUF O:I -outpad IOBUFE I:IO -inoutpad IOBUFE O:IO -toutpad IOBUFE E:I:IO -tinoutpad IOBUFE E:O:I:IO");
run("attrmvcp -attr src -attr LOC t:IOBUFE n:*");
run("attrmvcp -attr src -attr LOC -driven t:IBUF n:*");
+ run("coolrunner2_fixup");
run("splitnets");
run("clean");
}
diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc
index 2c33f23b9..e4ee4991f 100644
--- a/techlibs/ecp5/Makefile.inc
+++ b/techlibs/ecp5/Makefile.inc
@@ -18,9 +18,6 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/dsp_map.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_map.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_unmap.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_model.v))
-$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_5g.box))
-$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_5g.lut))
-$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_5g_nowide.lut))
EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
.SECONDARY: techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
diff --git a/techlibs/ecp5/abc9_5g.box b/techlibs/ecp5/abc9_5g.box
deleted file mode 100644
index f153a665e..000000000
--- a/techlibs/ecp5/abc9_5g.box
+++ /dev/null
@@ -1,36 +0,0 @@
-# NB: Box inputs/outputs must each be in the same order
-# as their corresponding module definition
-# (with exceptions detailed below)
-
-# Box 1 : CCU2C (2xCARRY + 2xLUT4)
-# (Exception: carry chain input/output must be the
-# last input and output and the entire bus has been
-# moved there overriding the otherwise
-# alphabetical ordering)
-# name ID w/b ins outs
-CCU2C 1 1 9 3
-#A0 B0 C0 D0 A1 B1 C1 D1 CIN
-379 379 275 141 - - - - 257 # S0
-630 630 526 392 379 379 275 141 273 # S1
-516 516 412 278 516 516 412 278 43 # COUT
-
-# Box 2 : TRELLIS_DPR16X4_COMB (16x4 dist ram)
-# name ID w/b ins outs
-$__ABC9_DPR16X4_COMB 2 0 8 4
-#$DO0 $DO1 $DO2 $DO3 RAD0 RAD1 RAD2 RAD3
-0 0 0 0 141 379 275 379 # DO0
-0 0 0 0 141 379 275 379 # DO1
-0 0 0 0 141 379 275 379 # DO2
-0 0 0 0 141 379 275 379 # DO3
-
-# Box 3 : PFUMX (MUX2)
-# name ID w/b ins outs
-PFUMX 3 1 3 1
-#ALUT BLUT C0
-98 98 151 # Z
-
-# Box 4 : L6MUX21 (MUX2)
-# name ID w/b ins outs
-L6MUX21 4 1 3 1
-#D0 D1 SD
-140 141 148 # Z
diff --git a/techlibs/ecp5/abc9_5g.lut b/techlibs/ecp5/abc9_5g.lut
deleted file mode 100644
index e8aa9b35d..000000000
--- a/techlibs/ecp5/abc9_5g.lut
+++ /dev/null
@@ -1,25 +0,0 @@
-# ECP5-5G LUT library for ABC
-# Note that ECP5 architecture assigns difference
-# in LUT input delay to interconnect, so this is
-# considered too
-
-
-# Simple LUTs
-# area D C B A
-1 1 141
-2 1 141 275
-3 1 141 275 379
-4 1 141 275 379 379
-
-# LUT5 = 2x LUT4 + PFUMX
-# area M0 D C B A
-5 2 151 239 373 477 477
-
-# LUT6 = 2x LUT5 + MUX2
-# area M1 M0 D C B A
-6 4 148 292 380 514 618 618
-
-# LUT7 = 2x LUT6 + MUX2
-# area M2 M1 M0 D C B A
-7 8 148 289 433 521 655 759 759
-
diff --git a/techlibs/ecp5/abc9_5g_nowide.lut b/techlibs/ecp5/abc9_5g_nowide.lut
deleted file mode 100644
index 60352d892..000000000
--- a/techlibs/ecp5/abc9_5g_nowide.lut
+++ /dev/null
@@ -1,12 +0,0 @@
-# ECP5-5G LUT library for ABC
-# Note that ECP5 architecture assigns difference
-# in LUT input delay to interconnect, so this is
-# considered too
-
-
-# Simple LUTs
-# area D C B A
-1 1 141
-2 1 141 275
-3 1 141 275 379
-4 1 141 275 379 379
diff --git a/techlibs/ecp5/abc9_model.v b/techlibs/ecp5/abc9_model.v
index 81e5cd070..b7ecd7358 100644
--- a/techlibs/ecp5/abc9_model.v
+++ b/techlibs/ecp5/abc9_model.v
@@ -1,5 +1,12 @@
// ---------------------------------------
-(* abc9_box_id=2 *)
+(* abc9_box *)
module \$__ABC9_DPR16X4_COMB (input [3:0] $DO, RAD, output [3:0] DO);
+ specify
+ ($DO => DO) = 0;
+ (RAD[0] *> DO) = 141;
+ (RAD[1] *> DO) = 379;
+ (RAD[2] *> DO) = 275;
+ (RAD[3] *> DO) = 379;
+ endspecify
endmodule
diff --git a/techlibs/ecp5/brams_map.v b/techlibs/ecp5/brams_map.v
index 310aedaf2..edda17c02 100644
--- a/techlibs/ecp5/brams_map.v
+++ b/techlibs/ecp5/brams_map.v
@@ -137,8 +137,6 @@ module \$__ECP5_PDPW16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN
localparam CLKWMUX = CLKPOL2 ? "CLKA" : "INV";
localparam CLKRMUX = CLKPOL3 ? "CLKB" : "INV";
- localparam WRITEMODE_A = TRANSP2 ? "WRITETHROUGH" : "READBEFOREWRITE";
-
PDPW16KD #(
`include "bram_init_9_18_36.vh"
.DATA_WIDTH_W(36),
diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v
index 0d3ec4e5b..12b33e925 100644
--- a/techlibs/ecp5/cells_sim.v
+++ b/techlibs/ecp5/cells_sim.v
@@ -1,22 +1,78 @@
// ---------------------------------------
-(* lib_whitebox *)
+(* abc9_lut=1, lib_whitebox *)
module LUT4(input A, B, C, D, output Z);
parameter [15:0] INIT = 16'h0000;
wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0];
wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0];
wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0];
assign Z = A ? s1[1] : s1[0];
+ specify
+ (A => Z) = 141;
+ (B => Z) = 275;
+ (C => Z) = 379;
+ (D => Z) = 379;
+ endspecify
+endmodule
+
+// This is a placeholder for ABC9 to extract the area/delay
+// cost of 5-input LUTs and is not intended to be instantiated
+// LUT5 = 2x LUT4 + PFUMX
+(* abc9_lut=2 *)
+module \$__ABC9_LUT5 (input M0, D, C, B, A, output Z);
+ specify
+ (M0 => Z) = 151;
+ (D => Z) = 239;
+ (C => Z) = 373;
+ (B => Z) = 477;
+ (A => Z) = 477;
+ endspecify
+endmodule
+
+// This is a placeholder for ABC9 to extract the area/delay
+// of 6-input LUTs and is not intended to be instantiated
+// LUT6 = 2x LUT5 + MUX2
+(* abc9_lut=4 *)
+module \$__ABC9_LUT6 (input M1, M0, D, C, B, A, output Z);
+ specify
+ (M1 => Z) = 148;
+ (M0 => Z) = 292;
+ (D => Z) = 380;
+ (C => Z) = 514;
+ (B => Z) = 618;
+ (A => Z) = 618;
+ endspecify
+endmodule
+
+// This is a placeholder for ABC9 to extract the area/delay
+// of 7-input LUTs and is not intended to be instantiated
+// LUT7 = 2x LUT6 + MUX2
+(* abc9_lut=8 *)
+module \$__ABC9_LUT7 (input M2, M1, M0, D, C, B, A, output Z);
+ specify
+ (M2 => Z) = 148;
+ (M1 => Z) = 289;
+ (M0 => Z) = 433;
+ (D => Z) = 521;
+ (C => Z) = 655;
+ (B => Z) = 759;
+ (A => Z) = 759;
+ endspecify
endmodule
// ---------------------------------------
-(* abc9_box_id=4, lib_whitebox *)
+(* abc9_box, lib_whitebox *)
module L6MUX21 (input D0, D1, SD, output Z);
assign Z = SD ? D1 : D0;
+ specify
+ (D0 => Z) = 140;
+ (D1 => Z) = 141;
+ (SD => Z) = 148;
+ endspecify
endmodule
// ---------------------------------------
-(* abc9_box_id=1, lib_whitebox *)
+(* abc9_box, lib_whitebox *)
module CCU2C(
(* abc9_carry *)
input CIN,
@@ -50,6 +106,31 @@ module CCU2C(
wire gated_lut2_1 = (INJECT1_1 == "YES") ? 1'b0 : LUT2_1;
assign COUT = (~LUT4_1 & gated_lut2_1) | (LUT4_1 & cout_0);
+ specify
+ (A0 => S0) = 379;
+ (B0 => S0) = 379;
+ (C0 => S0) = 275;
+ (D0 => S0) = 141;
+ (CIN => S0) = 257;
+ (A0 => S1) = 630;
+ (B0 => S1) = 630;
+ (C0 => S1) = 526;
+ (D0 => S1) = 392;
+ (A1 => S1) = 379;
+ (B1 => S1) = 379;
+ (C1 => S1) = 275;
+ (D1 => S1) = 141;
+ (CIN => S1) = 273;
+ (A0 => COUT) = 516;
+ (B0 => COUT) = 516;
+ (C0 => COUT) = 412;
+ (D0 => COUT) = 278;
+ (A1 => COUT) = 516;
+ (B1 => COUT) = 516;
+ (C1 => COUT) = 412;
+ (D1 => COUT) = 278;
+ (CIN => COUT) = 43;
+ endspecify
endmodule
// ---------------------------------------
@@ -94,9 +175,14 @@ module TRELLIS_RAM16X2 (
endmodule
// ---------------------------------------
-(* abc9_box_id=3, lib_whitebox *)
+(* abc9_box, lib_whitebox *)
module PFUMX (input ALUT, BLUT, C0, output Z);
assign Z = C0 ? ALUT : BLUT;
+ specify
+ (ALUT => Z) = 98;
+ (BLUT => Z) = 98;
+ (C0 => Z) = 151;
+ endspecify
endmodule
// ---------------------------------------
@@ -106,7 +192,6 @@ module TRELLIS_DPR16X4 (
input WRE,
input WCK,
input [3:0] RAD,
- /* (* abc9_arrival=<TODO> *) */
output [3:0] DO
);
parameter WCKMUX = "WCK";
diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc
index d47b2bed4..9916fdafb 100644
--- a/techlibs/ecp5/synth_ecp5.cc
+++ b/techlibs/ecp5/synth_ecp5.cc
@@ -230,7 +230,7 @@ struct SynthEcp5Pass : public ScriptPass
{
if (check_label("begin"))
{
- run("read_verilog -lib +/ecp5/cells_sim.v +/ecp5/cells_bb.v");
+ run("read_verilog -lib -specify +/ecp5/cells_sim.v +/ecp5/cells_bb.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
@@ -322,11 +322,11 @@ struct SynthEcp5Pass : public ScriptPass
run("techmap " + techmap_args);
if (abc9) {
- run("read_verilog -icells -lib +/ecp5/abc9_model.v");
+ run("read_verilog -icells -lib -specify +/abc9_model.v +/ecp5/abc9_model.v");
if (nowidelut)
- run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200");
+ run("abc9 -maxlut 4 -W 200");
else
- run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200");
+ run("abc9 -W 200");
run("techmap -map +/ecp5/abc9_unmap.v");
} else {
if (nowidelut)
diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc
index d8d8397b6..86ec9cdc2 100644
--- a/techlibs/gowin/synth_gowin.cc
+++ b/techlibs/gowin/synth_gowin.cc
@@ -191,7 +191,7 @@ struct SynthGowinPass : public ScriptPass
if (!nobram && check_label("map_bram", "(skip if -nobram)"))
{
run("memory_bram -rules +/gowin/brams.txt");
- run("techmap -map +/gowin/brams_map.v -map +/gowin/cells_sim.v");
+ run("techmap -map +/gowin/brams_map.v");
}
if (!nolutram && check_label("map_lutram", "(skip if -nolutram)"))
diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc
index 31478e80e..b9e504a9d 100644
--- a/techlibs/ice40/Makefile.inc
+++ b/techlibs/ice40/Makefile.inc
@@ -29,12 +29,6 @@ $(eval $(call add_share_file,share/ice40,techlibs/ice40/brams.txt))
$(eval $(call add_share_file,share/ice40,techlibs/ice40/brams_map.v))
$(eval $(call add_share_file,share/ice40,techlibs/ice40/dsp_map.v))
$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_model.v))
-$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_hx.box))
-$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_hx.lut))
-$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_lp.box))
-$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_lp.lut))
-$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_u.box))
-$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_u.lut))
$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init1.vh))
$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init2.vh))
diff --git a/techlibs/ice40/abc9_hx.box b/techlibs/ice40/abc9_hx.box
deleted file mode 100644
index 31e743669..000000000
--- a/techlibs/ice40/abc9_hx.box
+++ /dev/null
@@ -1,17 +0,0 @@
-# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_hx8k.txt
-
-# NB: Box inputs/outputs must each be in the same order
-# as their corresponding module definition
-# (with exceptions detailed below)
-
-# Box 1 : $__ICE40_CARRY_WRAPPER (private cell used to preserve
-# SB_LUT4+SB_CARRY)
-# (Exception: carry chain input/output must be the
-# last input and output and the entire bus has been
-# moved there overriding the otherwise
-# alphabetical ordering)
-# name ID w/b ins outs
-$__ICE40_CARRY_WRAPPER 1 1 5 2
-#A B I0 I3 CI
-400 379 449 316 316 # O
-259 231 - - 126 # CO
diff --git a/techlibs/ice40/abc9_hx.lut b/techlibs/ice40/abc9_hx.lut
deleted file mode 100644
index 3b3bb11e2..000000000
--- a/techlibs/ice40/abc9_hx.lut
+++ /dev/null
@@ -1,6 +0,0 @@
-# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_hx8k.txt
-# I3 I2 I1 I0
-1 1 316
-2 1 316 379
-3 1 316 379 400
-4 1 316 379 400 449
diff --git a/techlibs/ice40/abc9_lp.box b/techlibs/ice40/abc9_lp.box
deleted file mode 100644
index 71986a67b..000000000
--- a/techlibs/ice40/abc9_lp.box
+++ /dev/null
@@ -1,17 +0,0 @@
-# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_lp8k.txt
-
-# NB: Box inputs/outputs must each be in the same order
-# as their corresponding module definition
-# (with exceptions detailed below)
-
-# Box 1 : $__ICE40_CARRY_WRAPPER (private cell used to preserve
-# SB_LUT4+SB_CARRY)
-# (Exception: carry chain input/output must be the
-# last input and output and the entire bus has been
-# moved there overriding the otherwise
-# alphabetical ordering)
-# name ID w/b ins outs
-$__ICE40_CARRY_WRAPPER 1 1 5 2
-#A B I0 I3 CI
-589 558 661 465 465 # O
-675 609 - - 186 # CO
diff --git a/techlibs/ice40/abc9_lp.lut b/techlibs/ice40/abc9_lp.lut
deleted file mode 100644
index e72f760a2..000000000
--- a/techlibs/ice40/abc9_lp.lut
+++ /dev/null
@@ -1,6 +0,0 @@
-# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_lp8k.txt
-# I3 I2 I1 I0
-1 1 465
-2 1 465 558
-3 1 465 558 589
-4 1 465 558 589 661
diff --git a/techlibs/ice40/abc9_model.v b/techlibs/ice40/abc9_model.v
index a5e5f4372..84923d381 100644
--- a/techlibs/ice40/abc9_model.v
+++ b/techlibs/ice40/abc9_model.v
@@ -1,4 +1,4 @@
-(* abc9_box_id = 1, lib_whitebox *)
+(* abc9_box, lib_whitebox *)
module \$__ICE40_CARRY_WRAPPER (
(* abc9_carry *)
output CO,
@@ -26,4 +26,61 @@ module \$__ICE40_CARRY_WRAPPER (
.I3(I3_OR_CI),
.O(O)
);
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L79
+ (CI => CO) = (126, 105);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L80
+ (I0 => O) = (449, 386);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L82
+ (A => CO) = (259, 245);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L83
+ (A => O) = (400, 379);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L85
+ (B => CO) = (231, 133);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L86
+ (B => O) = (379, 351);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L88
+ (I3 => O) = (316, 288);
+ (CI => O) = (316, 288);
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L79
+ (CI => CO) = (186, 155);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L80
+ (I0 => O) = (662, 569);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L82
+ (A => CO) = (382, 362);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L83
+ (A => O) = (589, 558);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L85
+ (B => CO) = (341, 196);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L86
+ (B => O) = (558, 517);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L88
+ (I3 => O) = (465, 423);
+ (CI => O) = (465, 423);
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L91
+ (CI => CO) = (278, 278);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L92
+ (I0 => O) = (1245, 1285);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L94
+ (A => CO) = (675, 662);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L95
+ (A => O) = (1179, 1232);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L97
+ (B => CO) = (609, 358);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L98
+ (B => O) = (1179, 1205);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L100
+ (I3 => O) = (861, 874);
+ (CI => O) = (861, 874);
+ endspecify
+`endif
endmodule
diff --git a/techlibs/ice40/abc9_u.box b/techlibs/ice40/abc9_u.box
deleted file mode 100644
index 3d4b93834..000000000
--- a/techlibs/ice40/abc9_u.box
+++ /dev/null
@@ -1,17 +0,0 @@
-# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_up5k.txt
-
-# NB: Box inputs/outputs must each be in the same order
-# as their corresponding module definition
-# (with exceptions detailed below)
-
-# Box 1 : $__ICE40_CARRY_WRAPPER (private cell used to preserve
-# SB_LUT4+SB_CARRY)
-# (Exception: carry chain input/output must be the
-# last input and output and the entire bus has been
-# moved there overriding the otherwise
-# alphabetical ordering)
-# name ID w/b ins outs
-$__ICE40_CARRY_WRAPPER 1 1 5 2
-#A B I0 I3 CI
-1231 1205 1285 874 874 # O
-675 609 - - 278 # CO
diff --git a/techlibs/ice40/abc9_u.lut b/techlibs/ice40/abc9_u.lut
deleted file mode 100644
index 1e4fcadb6..000000000
--- a/techlibs/ice40/abc9_u.lut
+++ /dev/null
@@ -1,6 +0,0 @@
-# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_up5k.txt
-# I3 I2 I1 I0
-1 1 874
-2 1 874 1205
-3 1 874 1205 1231
-4 1 874 1205 1231 1285
diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v
index 50eab5dde..6a0e3031e 100644
--- a/techlibs/ice40/cells_sim.v
+++ b/techlibs/ice40/cells_sim.v
@@ -2,10 +2,6 @@
`define SB_DFF_REG reg Q = 0
// `define SB_DFF_REG reg Q
-`define ABC9_ARRIVAL_HX(TIME) `ifdef ICE40_HX (* abc9_arrival=TIME *) `endif
-`define ABC9_ARRIVAL_LP(TIME) `ifdef ICE40_LP (* abc9_arrival=TIME *) `endif
-`define ABC9_ARRIVAL_U(TIME) `ifdef ICE40_U (* abc9_arrival=TIME *) `endif
-
// SiliconBlue IO Cells
module SB_IO (
@@ -167,53 +163,166 @@ endmodule
// SiliconBlue Logic Cells
-(* lib_whitebox *)
+(* abc9_lut=1, lib_whitebox *)
module SB_LUT4 (output O, input I0, I1, I2, I3);
parameter [15:0] LUT_INIT = 0;
wire [7:0] s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
wire [3:0] s2 = I2 ? s3[ 7:4] : s3[3:0];
wire [1:0] s1 = I1 ? s2[ 3:2] : s2[1:0];
assign O = I0 ? s1[1] : s1[0];
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L80
+ (I0 => O) = (449, 386);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L83
+ (I1 => O) = (400, 379);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L86
+ (I2 => O) = (379, 351);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L88
+ (I3 => O) = (316, 288);
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L80
+ (I0 => O) = (662, 569);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L83
+ (I1 => O) = (589, 558);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L86
+ (I2 => O) = (558, 517);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L88
+ (I3 => O) = (465, 423);
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L92
+ (I0 => O) = (1245, 1285);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L95
+ (I1 => O) = (1179, 1232);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L98
+ (I2 => O) = (1179, 1205);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L100
+ (I3 => O) = (861, 874);
+ endspecify
+`endif
endmodule
(* lib_whitebox *)
module SB_CARRY (output CO, input I0, I1, CI);
assign CO = (I0 && I1) || ((I0 || I1) && CI);
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L79
+ (CI => CO) = (126, 105);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L82
+ (I0 => CO) = (259, 245);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_hx1k.txt#L85
+ (I1 => CO) = (231, 133);
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L79
+ (CI => CO) = (186, 155);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L82
+ (I0 => CO) = (382, 362);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_lp1k.txt#L85
+ (I0 => CO) = (341, 196);
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L91
+ (CI => CO) = (278, 278);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L94
+ (I0 => CO) = (675, 662);
+ // https://github.com/cliffordwolf/icestorm/blob/be0bca0230d6fe1102e0a360b953fbb0d273a39f/icefuzz/timings_up5k.txt#L97
+ (I0 => CO) = (609, 358);
+ endspecify
+`endif
endmodule
-// Max delay from: https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
-// https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
-// https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
-
// Positive Edge SiliconBlue FF Cells
module SB_DFF (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, D
);
always @(posedge C)
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, posedge C, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ (posedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ (posedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ (posedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFE (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, D
);
always @(posedge C)
if (E)
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, posedge C &&& E, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (E) (posedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C &&& E, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (E) (posedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (E) (posedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFSR (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
@@ -222,12 +331,45 @@ module SB_DFFSR (
Q <= 0;
else
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, posedge C, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78
+ $setup(R, posedge C, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if ( R) (posedge C => (Q : 1'b0)) = 540;
+ if (!R) (posedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78
+ $setup(R, posedge C, 299);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if ( R) (posedge C => (Q : 1'b0)) = 796;
+ if (!R) (posedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90
+ $setup(R, posedge C, 530);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if ( R) (posedge C => (Q : 1'b0)) = 1391;
+ if (!R) (posedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFR (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
@@ -236,12 +378,48 @@ module SB_DFFR (
Q <= 0;
else
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, posedge C, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63
+ $setup(negedge R, posedge C, 160);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91
+ (posedge R => (Q : 1'b0)) = 599;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (!R) (posedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63
+ $setup(negedge R, posedge C, 235);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91
+ (posedge R => (Q : 1'b0)) = 883;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (!R) (posedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75
+ $setup(negedge R, posedge C, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103
+ (posedge R => (Q : 1'b0)) = 1589;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (!R) (posedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFSS (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
@@ -250,12 +428,45 @@ module SB_DFFSS (
Q <= 1;
else
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, posedge C, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78
+ $setup(S, posedge C, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if ( S) (posedge C => (Q : 1'b1)) = 540;
+ if (!S) (posedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78
+ $setup(S, posedge C, 299);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if ( S) (posedge C => (Q : 1'b1)) = 796;
+ if (!S) (posedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90
+ $setup(S, posedge C, 530);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if ( S) (posedge C => (Q : 1'b1)) = 1391;
+ if (!S) (posedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFS (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
@@ -264,12 +475,48 @@ module SB_DFFS (
Q <= 1;
else
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, posedge C, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63
+ $setup(negedge S, posedge C, 160);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91
+ (posedge S => (Q : 1'b1)) = 599;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (!S) (posedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63
+ $setup(negedge S, posedge C, 235);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91
+ (posedge S => (Q : 1'b1)) = 883;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (!S) (posedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75
+ $setup(negedge S, posedge C, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103
+ (posedge S => (Q : 1'b1)) = 1589;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (!S) (posedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFESR (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
@@ -280,12 +527,51 @@ module SB_DFFESR (
else
Q <= D;
end
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, posedge C &&& E && !R, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78
+ $setup(R, posedge C &&& E, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (E && R) (posedge C => (Q : 1'b0)) = 540;
+ if (E && !R) (posedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C &&& E && !R, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78
+ $setup(R, posedge C &&& E, 299);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (E && R) (posedge C => (Q : 1'b0)) = 796;
+ if (E && !R) (posedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90
+ $setup(R, posedge C &&& E, 530);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (E && R) (posedge C => (Q : 1'b0)) = 1391;
+ if (E && !R) (posedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFER (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
@@ -294,12 +580,54 @@ module SB_DFFER (
Q <= 0;
else if (E)
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, posedge C &&& E, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63
+ $setup(negedge R, posedge C, 160);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91
+ (posedge R => (Q : 1'b0)) = 599;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (E && !R) (posedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C &&& E, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63
+ $setup(negedge R, posedge C, 235);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91
+ (posedge R => (Q : 1'b0)) = 883;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (E && !R) (posedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75
+ $setup(negedge R, posedge C, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103
+ (posedge R => (Q : 1'b0)) = 1589;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (E && !R) (posedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFESS (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
@@ -310,12 +638,51 @@ module SB_DFFESS (
else
Q <= D;
end
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, posedge C &&& E && !S, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78
+ $setup(S, posedge C &&& E, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (E && S) (posedge C => (Q : 1'b1)) = 540;
+ if (E && !S) (posedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C &&& E && !S, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78
+ $setup(S, posedge C &&& E, 299);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (E && S) (posedge C => (Q : 1'b1)) = 796;
+ if (E && !S) (posedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90
+ $setup(S, posedge C &&& E, 530);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (E && S) (posedge C => (Q : 1'b1)) = 1391;
+ if (E && !S) (posedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFES (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
@@ -324,37 +691,133 @@ module SB_DFFES (
Q <= 1;
else if (E)
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, posedge C &&& E, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63
+ $setup(posedge S, posedge C, 160);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91
+ (posedge S => (Q : 1'b1)) = 599;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (E && !S) (posedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C &&& E, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63
+ $setup(posedge S, posedge C, 235);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91
+ (posedge S => (Q : 1'b1)) = 883;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (E && !S) (posedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, posedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86
+ $setup(E, posedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75
+ $setup(posedge S, posedge C, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103
+ (posedge S => (Q : 1'b1)) = 1589;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (E && !S) (posedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
// Negative Edge SiliconBlue FF Cells
module SB_DFFN (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, D
);
always @(negedge C)
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, negedge C, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ (negedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ (negedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ (negedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFNE (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, D
);
always @(negedge C)
if (E)
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, negedge C &&& E, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (E) (negedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C &&& E, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (E) (negedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (E) (negedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFNSR (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
@@ -363,12 +826,45 @@ module SB_DFFNSR (
Q <= 0;
else
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, negedge C, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(R, negedge C, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if ( R) (negedge C => (Q : 1'b0)) = 540;
+ if (!R) (negedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78
+ $setup(R, negedge C, 299);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if ( R) (negedge C => (Q : 1'b0)) = 796;
+ if (!R) (negedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90
+ $setup(R, negedge C, 530);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if ( R) (negedge C => (Q : 1'b0)) = 1391;
+ if (!R) (negedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFNR (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
@@ -377,12 +873,48 @@ module SB_DFFNR (
Q <= 0;
else
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, negedge C, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63
+ $setup(negedge R, negedge C, 160);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91
+ (posedge R => (Q : 1'b0)) = 599;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (!R) (negedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63
+ $setup(negedge R, negedge C, 235);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91
+ (posedge R => (Q : 1'b0)) = 883;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (!R) (negedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75
+ $setup(negedge R, negedge C, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103
+ (posedge R => (Q : 1'b0)) = 1589;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (!R) (negedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFNSS (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
@@ -391,12 +923,45 @@ module SB_DFFNSS (
Q <= 1;
else
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, negedge C, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(S, negedge C, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if ( S) (negedge C => (Q : 1'b1)) = 540;
+ if (!S) (negedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78
+ $setup(S, negedge C, 299);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if ( S) (negedge C => (Q : 1'b1)) = 796;
+ if (!S) (negedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90
+ $setup(S, negedge C, 530);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if ( S) (negedge C => (Q : 1'b1)) = 1391;
+ if (!S) (negedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFNS (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
@@ -405,12 +970,48 @@ module SB_DFFNS (
Q <= 1;
else
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, negedge C, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63
+ $setup(negedge S, negedge C, 160);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91
+ (posedge S => (Q : 1'b1)) = 599;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (!S) (negedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63
+ $setup(negedge S, negedge C, 235);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91
+ (posedge S => (Q : 1'b1)) = 883;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (!S) (negedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75
+ $setup(negedge S, negedge C, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103
+ (posedge S => (Q : 1'b1)) = 1589;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (!S) (negedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFNESR (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
@@ -421,12 +1022,51 @@ module SB_DFFNESR (
else
Q <= D;
end
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, negedge C &&& E && !R, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78
+ $setup(R, negedge C &&& E, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (E && R) (negedge C => (Q : 1'b0)) = 540;
+ if (E && !R) (negedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C &&& E && !R, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78
+ $setup(R, negedge C &&& E, 299);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (E && R) (negedge C => (Q : 1'b0)) = 796;
+ if (E && !R) (negedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90
+ $setup(R, negedge C &&& E, 530);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (E && R) (negedge C => (Q : 1'b0)) = 1391;
+ if (E && !R) (negedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFNER (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
@@ -435,12 +1075,54 @@ module SB_DFFNER (
Q <= 0;
else if (E)
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, negedge C &&& E, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63
+ $setup(R, negedge C, 2160);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91
+ (posedge R => (Q : 1'b0)) = 599;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (E && !R) (negedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C &&& E, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63
+ $setup(R, negedge C, 235);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91
+ (posedge R => (Q : 1'b0)) = 883;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (E && !R) (negedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75
+ $setup(negedge R, negedge C, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103
+ (posedge R => (Q : 1'b0)) = 1589;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (E && !R) (negedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFNESS (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
@@ -451,12 +1133,51 @@ module SB_DFFNESS (
else
Q <= D;
end
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, negedge C &&& E && !S, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78
+ $setup(S, negedge C &&& E, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (E && S) (negedge C => (Q : 1'b1)) = 540;
+ if (E && !S) (negedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C &&& E && !S, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78
+ $setup(S, negedge C &&& E, 299);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (E && S) (negedge C => (Q : 1'b1)) = 796;
+ if (E && !S) (negedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90
+ $setup(S, negedge C &&& E, 530);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (E && S) (negedge C => (Q : 1'b1)) = 1391;
+ if (E && !S) (negedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
module SB_DFFNES (
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
@@ -465,14 +1186,56 @@ module SB_DFFNES (
Q <= 1;
else if (E)
Q <= D;
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ $setup(D, negedge C &&& E, 470 - 449);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L63
+ $setup(negedge S, negedge C, 160);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91
+ (posedge S => (Q : 1'b1)) = 599;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ if (E && !S) (negedge C => (Q : D)) = 540;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C &&& E, 693 - 662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L63
+ $setup(negedge S, negedge C, 235);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91
+ (posedge S => (Q : 1'b1)) = 883;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ if (E && !S) (negedge C => (Q : D)) = 796;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ // minus https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ $setup(D, negedge C &&& E, /*1232 - 1285*/ 0); // Negative times not currently supported
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86
+ $setup(E, negedge C, 0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L75
+ $setup(negedge S, negedge C, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103
+ (posedge S => (Q : 1'b1)) = 1589;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ if (E && !S) (negedge C => (Q : D)) = 1391;
+ endspecify
+`endif
endmodule
// SiliconBlue RAM Cells
module SB_RAM40_4K (
- `ABC9_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
- `ABC9_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
- `ABC9_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
output [15:0] RDATA,
input RCLK, RCLKE, RE,
input [10:0] RADDR,
@@ -638,12 +1401,75 @@ module SB_RAM40_4K (
end
end
`endif
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358
+ $setup(MASK, posedge WCLK &&& WE && WCLKE, 274);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369
+ $setup(RADDR, posedge RCLK &&& RE && RCLKE, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370
+ $setup(RCLKE, posedge RCLK, 267);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371
+ $setup(RE, posedge RCLK, 98);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382
+ $setup(WADDR, posedge WCLK &&& WE && WCLKE, 224);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383
+ $setup(WCLKE, posedge WCLK, 267);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399
+ $setup(WDATA, posedge WCLK &&& WE && WCLKE, 161);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400
+ $setup(WE, posedge WCLK, 133);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
+ (posedge RCLK => (RDATA : 16'bx)) = 2146;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358
+ $setup(MASK, posedge WCLK &&& WE && WCLKE, 403);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369
+ $setup(RADDR, posedge RCLK &&& RE && RCLKE, 300);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370
+ $setup(RCLKE, posedge RCLK, 393);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371
+ $setup(RE, posedge RCLK, 145);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382
+ $setup(WADDR, posedge WCLK &&& WE && WCLKE, 331);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383
+ $setup(WCLKE, posedge WCLK, 393);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399
+ $setup(WDATA, posedge WCLK &&& WE && WCLKE, 238);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400
+ $setup(WE, posedge WCLK, 196);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
+ (posedge RCLK => (RDATA : 16'bx)) = 3163;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983
+ $setup(MASK, posedge WCLK &&& WE && WCLKE, 517);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994
+ $setup(RADDR, posedge RCLK &&& RE && RCLKE, 384);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995
+ $setup(RCLKE, posedge RCLK, 503);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996
+ $setup(RE, posedge RCLK, 185);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007
+ $setup(WADDR, posedge WCLK &&& WE && WCLKE, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008
+ $setup(WCLKE, posedge WCLK, 503);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024
+ $setup(WDATA, posedge WCLK &&& WE && WCLKE, 305);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025
+ $setup(WE, posedge WCLK, 252);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
+ (posedge RCLK => (RDATA : 16'bx)) = 1179;
+ endspecify
+`endif
endmodule
module SB_RAM40_4KNR (
- `ABC9_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
- `ABC9_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
- `ABC9_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
output [15:0] RDATA,
input RCLKN, RCLKE, RE,
input [10:0] RADDR,
@@ -706,12 +1532,75 @@ module SB_RAM40_4KNR (
.MASK (MASK ),
.WDATA(WDATA)
);
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358
+ $setup(MASK, posedge WCLK &&& WE && WCLKE, 274);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369
+ $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370
+ $setup(RCLKE, posedge RCLKN, 267);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371
+ $setup(RE, posedge RCLKN, 98);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382
+ $setup(WADDR, posedge WCLK &&& WE && WCLKE, 224);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383
+ $setup(WCLKE, posedge WCLK, 267);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399
+ $setup(WDATA, posedge WCLK &&& WE && WCLKE, 161);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400
+ $setup(WE, posedge WCLK, 133);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
+ (posedge RCLKN => (RDATA : 16'bx)) = 2146;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358
+ $setup(MASK, posedge WCLK &&& WE && WCLKE, 403);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369
+ $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 300);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370
+ $setup(RCLKE, posedge RCLKN, 393);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371
+ $setup(RE, posedge RCLKN, 145);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382
+ $setup(WADDR, posedge WCLK &&& WE && WCLKE, 331);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383
+ $setup(WCLKE, posedge WCLK, 393);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399
+ $setup(WDATA, posedge WCLK &&& WE && WCLKE, 238);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400
+ $setup(WE, posedge WCLK, 196);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
+ (posedge RCLKN => (RDATA : 16'bx)) = 3163;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983
+ $setup(MASK, posedge WCLK &&& WE && WCLKE, 517);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994
+ $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 384);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995
+ $setup(RCLKE, posedge RCLKN, 503);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996
+ $setup(RE, posedge RCLKN, 185);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007
+ $setup(WADDR, posedge WCLK &&& WE && WCLKE, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008
+ $setup(WCLKE, posedge WCLK, 503);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024
+ $setup(WDATA, posedge WCLK &&& WE && WCLKE, 305);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025
+ $setup(WE, posedge WCLK, 252);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
+ (posedge RCLKN => (RDATA : 16'bx)) = 1179;
+ endspecify
+`endif
endmodule
module SB_RAM40_4KNW (
- `ABC9_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
- `ABC9_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
- `ABC9_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
output [15:0] RDATA,
input RCLK, RCLKE, RE,
input [10:0] RADDR,
@@ -774,12 +1663,75 @@ module SB_RAM40_4KNW (
.MASK (MASK ),
.WDATA(WDATA)
);
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358
+ $setup(MASK, posedge WCLKN &&& WE && WCLKE, 274);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369
+ $setup(RADDR, posedge RCLK &&& RE && RCLKE, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370
+ $setup(RCLKE, posedge RCLK, 267);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371
+ $setup(RE, posedge RCLK, 98);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382
+ $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 224);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383
+ $setup(WCLKE, posedge WCLKN, 267);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399
+ $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 161);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400
+ $setup(WE, posedge WCLKN, 133);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
+ (posedge RCLK => (RDATA : 16'bx)) = 2146;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358
+ $setup(MASK, posedge WCLKN &&& WE && WCLKE, 403);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369
+ $setup(RADDR, posedge RCLK &&& RE && RCLKE, 300);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370
+ $setup(RCLKE, posedge RCLK, 393);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371
+ $setup(RE, posedge RCLK, 145);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382
+ $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 331);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383
+ $setup(WCLKE, posedge WCLKN, 393);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399
+ $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 238);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400
+ $setup(WE, posedge WCLKN, 196);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
+ (posedge RCLK => (RDATA : 16'bx)) = 3163;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983
+ $setup(MASK, posedge WCLKN &&& WE && WCLKE, 517);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994
+ $setup(RADDR, posedge RCLK &&& RE && RCLKE, 384);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995
+ $setup(RCLKE, posedge RCLK, 503);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996
+ $setup(RE, posedge RCLK, 185);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007
+ $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008
+ $setup(WCLKE, posedge WCLKN, 503);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024
+ $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 305);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025
+ $setup(WE, posedge WCLKN, 252);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
+ (posedge RCLK => (RDATA : 16'bx)) = 1179;
+ endspecify
+`endif
endmodule
module SB_RAM40_4KNRNW (
- `ABC9_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
- `ABC9_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
- `ABC9_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
output [15:0] RDATA,
input RCLKN, RCLKE, RE,
input [10:0] RADDR,
@@ -842,6 +1794,72 @@ module SB_RAM40_4KNRNW (
.MASK (MASK ),
.WDATA(WDATA)
);
+`ifdef ICE40_HX
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L343-L358
+ $setup(MASK, posedge WCLKN &&& WE && WCLKE, 274);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L359-L369
+ $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 203);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L370
+ $setup(RCLKE, posedge RCLKN, 267);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L371
+ $setup(RE, posedge RCLKN, 98);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L372-L382
+ $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 224);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L383
+ $setup(WCLKE, posedge WCLKN, 267);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L384-L399
+ $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 161);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400
+ $setup(WE, posedge WCLKN, 133);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
+ (posedge RCLKN => (RDATA : 16'bx)) = 2146;
+ endspecify
+`endif
+`ifdef ICE40_LP
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L343-L358
+ $setup(MASK, posedge WCLKN &&& WE && WCLKE, 403);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L359-L369
+ $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 300);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L370
+ $setup(RCLKE, posedge RCLKN, 393);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L371
+ $setup(RE, posedge RCLKN, 145);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L372-L382
+ $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 331);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L383
+ $setup(WCLKE, posedge WCLKN, 393);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L384-L399
+ $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 238);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400
+ $setup(WE, posedge WCLKN, 196);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
+ (posedge RCLKN => (RDATA : 16'bx)) = 3163;
+ endspecify
+`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12968-12983
+ $setup(MASK, posedge WCLKN &&& WE && WCLKE, 517);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12984-12994
+ $setup(RADDR, posedge RCLKN &&& RE && RCLKE, 384);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12995
+ $setup(RCLKE, posedge RCLKN, 503);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12996
+ $setup(RE, posedge RCLKN, 185);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L12997-13007
+ $setup(WADDR, posedge WCLKN &&& WE && WCLKE, 424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13008
+ $setup(WCLKE, posedge WCLKN, 503);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13009-13024
+ $setup(WDATA, posedge WCLKN &&& WE && WCLKE, 305);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025
+ $setup(WE, posedge WCLKN, 252);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
+ (posedge RCLKN => (RDATA : 16'bx)) = 1179;
+ endspecify
+`endif
endmodule
// Packed IceStorm Logic Cells
@@ -849,9 +1867,6 @@ endmodule
module ICESTORM_LC (
input I0, I1, I2, I3, CIN, CLK, CEN, SR,
output LO,
- `ABC9_ARRIVAL_HX(540)
- `ABC9_ARRIVAL_LP(796)
- `ABC9_ARRIVAL_U(1391)
output O,
output COUT
);
@@ -941,6 +1956,198 @@ specify
$setuphold(negedge CLK, negedge SR, 0:0:0, 0:0:0);
endspecify
`endif
+`ifdef ICE40_HX
+specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L79
+ (CIN => COUT) = (101:112:126, 85:94:105);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L80
+ (I0 => O) = (361:399:449, 310:343:386);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L81
+ (I0 => LO) = (293:324:365, 310:343:386);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L82
+ (I1 => COUT) = (209:231:259, 197:218:245);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L83
+ (I1 => O) = (321:355:400, 304:337:379);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L84
+ (I1 => LO) = (259:287:323, 304:337:379);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L85
+ (I2 => COUT) = (186:206:231, 107:118:133);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L86
+ (I2 => O) = (304:337:379, 282:312:351);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L87
+ (I2 => LO) = (254:281:316, 231:256:288);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L88
+ (I3 => O) = (254:281:316, 231:256:288);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L89
+ (I3 => LO) = (214:237:267, 220:243:274);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
+ (posedge CLK => (O : 1'bx)) = (434:480:540, 434:480:540);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L91-L92
+ (SR => O) = (482:535:599, 482:533:599);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L74
+ $setuphold(posedge CLK, posedge I0, 378:418:470, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L68
+ $setuphold(posedge CLK, negedge I0, 321:355:400, 0:0:0);
+ $setuphold(negedge CLK, posedge I0, 378:418:470, 0:0:0);
+ $setuphold(negedge CLK, negedge I0, 321:355:400, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L75
+ $setuphold(posedge CLK, posedge I1, 321:355:400, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L69
+ $setuphold(posedge CLK, negedge I1, 304:337:379, 0:0:0);
+ $setuphold(negedge CLK, posedge I1, 321:355:400, 0:0:0);
+ $setuphold(negedge CLK, negedge I1, 304:337:379, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L76
+ $setuphold(posedge CLK, posedge I2, 299:330:372, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L70
+ $setuphold(posedge CLK, negedge I2, 259:287:323, 0:0:0);
+ $setuphold(negedge CLK, posedge I2, 299:330:372, 0:0:0);
+ $setuphold(negedge CLK, negedge I2, 259:287:323, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L77
+ $setuphold(posedge CLK, posedge I3, 220:243:274, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L71
+ $setuphold(posedge CLK, negedge I3, 175:183:217, 0:0:0);
+ $setuphold(negedge CLK, posedge I3, 220:243:274, 0:0:0);
+ $setuphold(negedge CLK, negedge I3, 175:183:217, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L73
+ $setuphold(posedge CLK, negedge CEN, 0:0:0, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L67
+ $setuphold(posedge CLK, posedge CEN, 0:0:0, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L78
+ $setuphold(posedge CLK, posedge SR, 163:181:203, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L72
+ $setuphold(posedge CLK, negedge SR, 113:125:140, 0:0:0);
+ $setuphold(negedge CLK, posedge SR, 163:181:203, 0:0:0);
+ $setuphold(negedge CLK, negedge SR, 113:125:140, 0:0:0);
+endspecify
+`endif
+`ifdef ICE40_LP
+specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L79
+ (CIN => COUT) = (118:153:186, 98:128:155);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L80
+ (I0 => O) = (419:545:662, 360:468:569);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L81
+ (I0 => LO) = (340:442:538, 360:468:569);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L82
+ (I1 => COUT) = (242:315:382, 229:298:362);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L83
+ (I1 => O) = (372:485:589, 353:459:558);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L84
+ (I1 => LO) = (301:391:475, 353:459:558);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L85
+ (I2 => COUT) = (216:281:341, 124:162:196);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L86
+ (I2 => O) = (353:459:558, 327:425:517);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L87
+ (I2 => LO) = (288:374:455, 321:417:507);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L88
+ (I3 => O) = (294:383:465, 268:349:424);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L89
+ (I3 => LO) = (249:323:393, 255:332:403);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
+ (posedge CLK => (O : 1'bx)) = (504:655:796, 504:655:796);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L91-L92
+ (SR => O) = (559:726:883, 559:726:883);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L74
+ $setuphold(posedge CLK, posedge I0, 438:570:693, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L68
+ $setuphold(posedge CLK, negedge I0, 373:485:589, 0:0:0);
+ $setuphold(negedge CLK, posedge I0, 438:570:693, 0:0:0);
+ $setuphold(negedge CLK, negedge I0, 373:485:589, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L75
+ $setuphold(posedge CLK, posedge I1, 373:485:589, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L69
+ $setuphold(posedge CLK, negedge I1, 353:459:558, 0:0:0);
+ $setuphold(negedge CLK, posedge I1, 373:485:589, 0:0:0);
+ $setuphold(negedge CLK, negedge I1, 353:459:558, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L76
+ $setuphold(posedge CLK, posedge I2, 347:451:548, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L70
+ $setuphold(posedge CLK, negedge I2, 301:391:475, 0:0:0);
+ $setuphold(negedge CLK, posedge I2, 347:451:548, 0:0:0);
+ $setuphold(negedge CLK, negedge I2, 301:391:475, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L77
+ $setuphold(posedge CLK, posedge I3, 255:332:403, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L71
+ $setuphold(posedge CLK, negedge I3, 203:264:320, 0:0:0);
+ $setuphold(negedge CLK, posedge I3, 255:332:403, 0:0:0);
+ $setuphold(negedge CLK, negedge I3, 203:264:320, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L73
+ $setuphold(posedge CLK, negedge CEN, 0:0:0, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L67
+ $setuphold(posedge CLK, posedge CEN, 0:0:0, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L78
+ $setuphold(posedge CLK, posedge SR, 190:247:300, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L72
+ $setuphold(posedge CLK, negedge SR, 131:170:207, 0:0:0);
+ $setuphold(negedge CLK, posedge SR, 190:247:300, 0:0:0);
+ $setuphold(negedge CLK, negedge SR, 131:170:207, 0:0:0);
+endspecify
+`endif
+`ifdef ICE40_U
+specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L91
+ (CIN => COUT) = (103:181:278, 103:181:278);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L92
+ (I0 => O) = (462:808:1255, 477:834:1285);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L93
+ (I0 => LO) = (315:550:848, 334:585:901);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L94
+ (I1 => COUT) = (251:438:675, 246:430:662);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L95
+ (I1 => O) = (438:765:1179, 457:799:1232);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L96
+ (I1 => LO) = (275:481:742, 329:576:887);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L97
+ (I2 => COUT) = (226:395:609, 133:232:358);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L98
+ (I2 => O) = (438:765:1179, 447:782:1205);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L99
+ (I2 => LO) = (261:456:702, 290:507:781);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L100
+ (I3 => O) = (320:559:861, 226:370:874);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L101
+ (I3 => LO) = (216:378:583, 226:395:609);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
+ (posedge CLK => (O : 1'bx)) = (516:903:1391, 516:903:1391);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L103-104
+ (SR => O) = (420:734:1131, 590:1032:1589);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L86
+ $setuphold(posedge CLK, posedge I0, 457:799:1232, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L80
+ $setuphold(posedge CLK, negedge I0, 393:688:1060, 0:0:0);
+ $setuphold(negedge CLK, posedge I0, 457:799:1232, 0:0:0);
+ $setuphold(negedge CLK, negedge I0, 393:688:1060, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L87
+ $setuphold(posedge CLK, posedge I1, 393:688:1060, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L81
+ $setuphold(posedge CLK, negedge I1, 373:653:1007, 0:0:0);
+ $setuphold(negedge CLK, posedge I1, 393:688:1060, 0:0:0);
+ $setuphold(negedge CLK, negedge I1, 373:653:1007, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L88
+ $setuphold(posedge CLK, posedge I2, 364:636:980, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L82
+ $setuphold(posedge CLK, negedge I2, 320:559:861, 0:0:0);
+ $setuphold(negedge CLK, posedge I2, 364:636:980, 0:0:0);
+ $setuphold(negedge CLK, negedge I2, 320:559:861, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L89
+ $setuphold(posedge CLK, posedge I3, 279:473:728, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L83
+ $setuphold(posedge CLK, negedge I3, 216:378:583, 0:0:0);
+ $setuphold(negedge CLK, posedge I3, 279:473:728, 0:0:0);
+ $setuphold(negedge CLK, negedge I3, 216:378:583, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L85
+ $setuphold(posedge CLK, negedge CEN, 0:0:0, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L79
+ $setuphold(posedge CLK, posedge CEN, 0:0:0, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L90
+ $setuphold(posedge CLK, posedge SR, 197:344:530, 0:0:0);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L84
+ $setuphold(posedge CLK, negedge SR, 143:249:384, 0:0:0);
+ $setuphold(negedge CLK, posedge SR, 197:344:530, 0:0:0);
+ $setuphold(negedge CLK, negedge SR, 131:170:207, 0:0:0);
+endspecify
+`endif
endmodule
// SiliconBlue PLL Cells
@@ -1126,7 +2333,6 @@ module SB_SPRAM256KA (
input [15:0] DATAIN,
input [3:0] MASKWREN,
input WREN, CHIPSELECT, CLOCK, STANDBY, SLEEP, POWEROFF,
- `ABC9_ARRIVAL_U(1821) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13207
output reg [15:0] DATAOUT
);
`ifndef BLACKBOX
@@ -1144,20 +2350,45 @@ module SB_SPRAM256KA (
if (off) begin
DATAOUT <= 0;
end else
- if (CHIPSELECT && !STANDBY && !WREN) begin
- DATAOUT <= mem[ADDRESS];
- end else begin
- if (CHIPSELECT && !STANDBY && WREN) begin
+ if (STANDBY) begin
+ DATAOUT <= 'bx;
+ end else
+ if (CHIPSELECT) begin
+ if (!WREN) begin
+ DATAOUT <= mem[ADDRESS];
+ end else begin
if (MASKWREN[0]) mem[ADDRESS][ 3: 0] = DATAIN[ 3: 0];
if (MASKWREN[1]) mem[ADDRESS][ 7: 4] = DATAIN[ 7: 4];
if (MASKWREN[2]) mem[ADDRESS][11: 8] = DATAIN[11: 8];
if (MASKWREN[3]) mem[ADDRESS][15:12] = DATAIN[15:12];
+ DATAOUT <= 'bx;
end
- DATAOUT <= 'bx;
end
end
`endif
`endif
+`ifdef ICE40_U
+ specify
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13169-L13182
+ $setup(posedge ADDRESS, posedge CLOCK, 268);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13183
+ $setup(CHIPSELECT, posedge CLOCK, 404);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13184-L13199
+ $setup(DATAIN, posedge CLOCK, 143);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13200-L13203
+ $setup(MASKWREN, posedge CLOCK, 143);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13167
+ //$setup(negedge SLEEP, posedge CLOCK, 41505);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13167
+ //$setup(negedge STANDBY, posedge CLOCK, 1715);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13206
+ $setup(WREN, posedge CLOCK, 289);
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13207-L13222
+ (posedge CLOCK => (DATAOUT : 16'bx)) = 1821;
+ // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13223-L13238
+ (posedge SLEEP => (DATAOUT : 16'b0)) = 1099;
+ endspecify
+`endif
endmodule
(* blackbox *)
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index fdb203dcb..b8aedaadf 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -96,6 +96,9 @@ struct SynthIce40Pass : public ScriptPass
log(" -abc9\n");
log(" use new ABC9 flow (EXPERIMENTAL)\n");
log("\n");
+ log(" -flowmap\n");
+ log(" use FlowMap LUT techmapping instead of abc (EXPERIMENTAL)\n");
+ log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
@@ -103,7 +106,7 @@ struct SynthIce40Pass : public ScriptPass
}
string top_opt, blif_file, edif_file, json_file, device_opt;
- bool nocarry, nodffe, nobram, dsp, flatten, retime, noabc, abc2, vpr, abc9;
+ bool nocarry, nodffe, nobram, dsp, flatten, retime, noabc, abc2, vpr, abc9, flowmap;
int min_ce_use;
void clear_flags() YS_OVERRIDE
@@ -123,6 +126,7 @@ struct SynthIce40Pass : public ScriptPass
abc2 = false;
vpr = false;
abc9 = false;
+ flowmap = false;
device_opt = "hx";
}
@@ -214,6 +218,10 @@ struct SynthIce40Pass : public ScriptPass
device_opt = args[++argidx];
continue;
}
+ if (args[argidx] == "-flowmap") {
+ flowmap = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -226,6 +234,13 @@ struct SynthIce40Pass : public ScriptPass
if (abc9 && retime)
log_cmd_error("-retime option not currently compatible with -abc9!\n");
+ if (abc9 && noabc)
+ log_cmd_error("-abc9 is incompatible with -noabc!\n");
+ if (abc9 && flowmap)
+ log_cmd_error("-abc9 is incompatible with -flowmap!\n");
+ if (flowmap && noabc)
+ log_cmd_error("-flowmap is incompatible with -noabc!\n");
+
log_header(design, "Executing SYNTH_ICE40 pass.\n");
log_push();
@@ -236,16 +251,16 @@ struct SynthIce40Pass : public ScriptPass
void script() YS_OVERRIDE
{
+ std::string define;
+ if (device_opt == "lp")
+ define = "-D ICE40_LP";
+ else if (device_opt == "u")
+ define = "-D ICE40_U";
+ else
+ define = "-D ICE40_HX";
if (check_label("begin"))
{
- std::string define;
- if (device_opt == "lp")
- define = "-D ICE40_LP";
- else if (device_opt == "u")
- define = "-D ICE40_U";
- else
- define = "-D ICE40_HX";
- run("read_verilog " + define + " -lib +/ice40/cells_sim.v");
+ run("read_verilog " + define + " -lib -specify +/ice40/cells_sim.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
run("proc");
}
@@ -330,6 +345,7 @@ struct SynthIce40Pass : public ScriptPass
if (min_ce_use >= 0) {
run("opt_merge");
run(stringf("dff2dffe -unmap-mince %d", min_ce_use));
+ run("simplemap t:$dff");
}
run("techmap -D NO_LUT -D NO_ADDER -map +/ice40/cells_map.v");
run("opt_expr -mux_undef");
@@ -346,13 +362,16 @@ struct SynthIce40Pass : public ScriptPass
run("ice40_opt", "(only if -abc2)");
}
run("techmap -map +/ice40/latches_map.v");
- if (noabc || help_mode) {
- run("simplemap", " (only if -noabc)");
- run("techmap -map +/gate2lut.v -D LUT_WIDTH=4", "(only if -noabc)");
+ if (noabc || flowmap || help_mode) {
+ run("simplemap", " (if -noabc or -flowmap)");
+ if (noabc || help_mode)
+ run("techmap -map +/gate2lut.v -D LUT_WIDTH=4", "(only if -noabc)");
+ if (flowmap || help_mode)
+ run("flowmap -maxlut 4", "(only if -flowmap)");
}
if (!noabc) {
if (abc9) {
- run("read_verilog -icells -lib +/ice40/abc9_model.v");
+ run("read_verilog " + define + " -icells -lib -specify +/abc9_model.v +/ice40/abc9_model.v");
int wire_delay;
if (device_opt == "lp")
wire_delay = 400;
@@ -360,7 +379,7 @@ struct SynthIce40Pass : public ScriptPass
wire_delay = 750;
else
wire_delay = 250;
- run(stringf("abc9 -W %d -lut +/ice40/abc9_%s.lut -box +/ice40/abc9_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()));
+ run(stringf("abc9 -W %d", wire_delay));
}
else
run("abc -dress -lut 4", "(skip if -noabc)");
diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc
index 3f2fbcc85..9984290a6 100644
--- a/techlibs/xilinx/Makefile.inc
+++ b/techlibs/xilinx/Makefile.inc
@@ -27,6 +27,10 @@ techlibs/xilinx/brams_init_8.vh: techlibs/xilinx/brams_init.mk
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_sim.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_xtra.v))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc2v_brams.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc2v_brams_map.v))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3sa_brams.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3sda_brams.txt))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams.txt))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_xcu_brams.txt))
@@ -34,7 +38,8 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_brams_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams.txt))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams_map.v))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut4_lutrams.txt))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut6_lutrams.txt))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_ff_map.v))
@@ -52,9 +57,6 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_dsp_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_unmap.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_model.v))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_xc7.box))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_xc7.lut))
-$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_xc7_nowide.lut))
$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_36.vh))
$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_32.vh))
diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v
index 7dc027176..81f8a1d42 100644
--- a/techlibs/xilinx/abc9_map.v
+++ b/techlibs/xilinx/abc9_map.v
@@ -68,9 +68,10 @@
// (c) a special abc9_ff.clock wire to capture its clock domain and polarity
// (indicated to `abc9' so that it only performs sequential synthesis
// (with reachability analysis) correctly on one domain at a time)
-// (d) a special abc9_ff.init wire to encode the flop's initial state
-// NOTE: in order to perform sequential synthesis, `abc9' also requires
-// that the initial value of all flops be zero
+// (d) an (* abc9_init *) attribute on the $__ABC9_FF_ cell capturing its
+// initial state
+// NOTE: in order to perform sequential synthesis, `abc9' requires that
+// the initial value of all flops be zero
// (e) a special _TECHMAP_REPLACE_.abc9_ff.Q wire that will be used for feedback
// into the (combinatorial) FD* cell to facilitate clock-enable behaviour
@@ -103,11 +104,11 @@ module FDRE (output Q, (* techmap_autopurge *) input C, CE, D, R);
);
end
endgenerate
+ (* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
- wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
endmodule
module FDRE_1 (output Q, (* techmap_autopurge *) input C, CE, D, R);
@@ -130,11 +131,11 @@ module FDRE_1 (output Q, (* techmap_autopurge *) input C, CE, D, R);
);
end
endgenerate
+ (* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
- wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
endmodule
@@ -166,11 +167,11 @@ module FDSE (output Q, (* techmap_autopurge *) input C, CE, D, S);
.D(D), .Q($Q), .C(C), .CE(CE), .S(S)
);
end endgenerate
+ (* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
- wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
endmodule
module FDSE_1 (output Q, (* techmap_autopurge *) input C, CE, D, S);
@@ -192,11 +193,11 @@ module FDSE_1 (output Q, (* techmap_autopurge *) input C, CE, D, S);
.D(D), .Q($Q), .C(C), .CE(CE), .S(S)
);
end endgenerate
+ (* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
- wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
endmodule
@@ -215,11 +216,11 @@ module FDCE (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
.IS_PRE_INVERTED(IS_CLR_INVERTED)
) _TECHMAP_REPLACE_ (
.D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC1 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
);
// Since this is an async flop, async behaviour is dealt with here
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
@@ -233,20 +234,20 @@ module FDCE (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
.IS_CLR_INVERTED(IS_CLR_INVERTED)
) _TECHMAP_REPLACE_ (
.D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC0 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
);
// Since this is an async flop, async behaviour is dealt with here
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
end endgenerate
+ (* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
- wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
endmodule
module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
@@ -258,11 +259,11 @@ module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
.INIT(1'b0)
) _TECHMAP_REPLACE_ (
.D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC1 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
);
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR), .Y(QQ));
end
@@ -272,19 +273,19 @@ module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
.INIT(1'b0)
) _TECHMAP_REPLACE_ (
.D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC0 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
);
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR), .Y(QQ));
end endgenerate
+ (* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
- wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
endmodule
@@ -303,11 +304,11 @@ module FDPE (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
.IS_CLR_INVERTED(IS_PRE_INVERTED),
) _TECHMAP_REPLACE_ (
.D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC0 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
);
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
end
@@ -320,19 +321,19 @@ module FDPE (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
.IS_PRE_INVERTED(IS_PRE_INVERTED),
) _TECHMAP_REPLACE_ (
.D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC1 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
);
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
end endgenerate
+ (* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
- wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
endmodule
module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
@@ -344,11 +345,11 @@ module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
.INIT(1'b0)
) _TECHMAP_REPLACE_ (
.D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC0 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC0 below
);
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE), .Y(QQ));
end
@@ -358,19 +359,19 @@ module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
.INIT(1'b0)
) _TECHMAP_REPLACE_ (
.D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
- // ^^^ Note that async
- // control is not directly
- // supported by abc9 but its
- // behaviour is captured by
- // $__ABC9_ASYNC1 below
+ // ^^^ Note that async
+ // control is not directly
+ // supported by abc9 but its
+ // behaviour is captured by
+ // $__ABC9_ASYNC1 below
);
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE), .Y(QQ));
end endgenerate
+ (* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
- wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
endmodule
`endif
@@ -397,8 +398,8 @@ module RAM32X1D (
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4),
.DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4)
);
- $__ABC9_LUT6 spo (.A($SPO), .S({1'b1, A4, A3, A2, A1, A0}), .Y(SPO));
- $__ABC9_LUT6 dpo (.A($DPO), .S({1'b1, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
+ $__ABC9_RAM6 spo (.A($SPO), .S({1'b1, A4, A3, A2, A1, A0}), .Y(SPO));
+ $__ABC9_RAM6 dpo (.A($DPO), .S({1'b1, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
endmodule
module RAM64X1D (
@@ -420,8 +421,8 @@ module RAM64X1D (
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5),
.DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5)
);
- $__ABC9_LUT6 spo (.A($SPO), .S({A5, A4, A3, A2, A1, A0}), .Y(SPO));
- $__ABC9_LUT6 dpo (.A($DPO), .S({DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
+ $__ABC9_RAM6 spo (.A($SPO), .S({A5, A4, A3, A2, A1, A0}), .Y(SPO));
+ $__ABC9_RAM6 dpo (.A($DPO), .S({DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
endmodule
module RAM128X1D (
@@ -442,8 +443,8 @@ module RAM128X1D (
.A(A),
.DPRA(DPRA)
);
- $__ABC9_LUT7 spo (.A($SPO), .S(A), .Y(SPO));
- $__ABC9_LUT7 dpo (.A($DPO), .S(DPRA), .Y(DPO));
+ $__ABC9_RAM7 spo (.A($SPO), .S(A), .Y(SPO));
+ $__ABC9_RAM7 dpo (.A($DPO), .S(DPRA), .Y(DPO));
endmodule
module RAM32M (
@@ -477,14 +478,14 @@ module RAM32M (
.ADDRA(ADDRA), .ADDRB(ADDRB), .ADDRC(ADDRC), .ADDRD(ADDRD),
.DIA(DIA), .DIB(DIB), .DIC(DIC), .DID(DID)
);
- $__ABC9_LUT6 doa0 (.A($DOA[0]), .S({1'b1, ADDRA}), .Y(DOA[0]));
- $__ABC9_LUT6 doa1 (.A($DOA[1]), .S({1'b1, ADDRA}), .Y(DOA[1]));
- $__ABC9_LUT6 dob0 (.A($DOB[0]), .S({1'b1, ADDRB}), .Y(DOB[0]));
- $__ABC9_LUT6 dob1 (.A($DOB[1]), .S({1'b1, ADDRB}), .Y(DOB[1]));
- $__ABC9_LUT6 doc0 (.A($DOC[0]), .S({1'b1, ADDRC}), .Y(DOC[0]));
- $__ABC9_LUT6 doc1 (.A($DOC[1]), .S({1'b1, ADDRC}), .Y(DOC[1]));
- $__ABC9_LUT6 dod0 (.A($DOD[0]), .S({1'b1, ADDRD}), .Y(DOD[0]));
- $__ABC9_LUT6 dod1 (.A($DOD[1]), .S({1'b1, ADDRD}), .Y(DOD[1]));
+ $__ABC9_RAM6 doa0 (.A($DOA[0]), .S({1'b1, ADDRA}), .Y(DOA[0]));
+ $__ABC9_RAM6 doa1 (.A($DOA[1]), .S({1'b1, ADDRA}), .Y(DOA[1]));
+ $__ABC9_RAM6 dob0 (.A($DOB[0]), .S({1'b1, ADDRB}), .Y(DOB[0]));
+ $__ABC9_RAM6 dob1 (.A($DOB[1]), .S({1'b1, ADDRB}), .Y(DOB[1]));
+ $__ABC9_RAM6 doc0 (.A($DOC[0]), .S({1'b1, ADDRC}), .Y(DOC[0]));
+ $__ABC9_RAM6 doc1 (.A($DOC[1]), .S({1'b1, ADDRC}), .Y(DOC[1]));
+ $__ABC9_RAM6 dod0 (.A($DOD[0]), .S({1'b1, ADDRD}), .Y(DOD[0]));
+ $__ABC9_RAM6 dod1 (.A($DOD[1]), .S({1'b1, ADDRD}), .Y(DOD[1]));
endmodule
module RAM64M (
@@ -518,10 +519,25 @@ module RAM64M (
.ADDRA(ADDRA), .ADDRB(ADDRB), .ADDRC(ADDRC), .ADDRD(ADDRD),
.DIA(DIA), .DIB(DIB), .DIC(DIC), .DID(DID)
);
- $__ABC9_LUT6 doa (.A($DOA), .S(ADDRA), .Y(DOA));
- $__ABC9_LUT6 dob (.A($DOB), .S(ADDRB), .Y(DOB));
- $__ABC9_LUT6 doc (.A($DOC), .S(ADDRC), .Y(DOC));
- $__ABC9_LUT6 dod (.A($DOD), .S(ADDRD), .Y(DOD));
+ $__ABC9_RAM6 doa (.A($DOA), .S(ADDRA), .Y(DOA));
+ $__ABC9_RAM6 dob (.A($DOB), .S(ADDRB), .Y(DOB));
+ $__ABC9_RAM6 doc (.A($DOC), .S(ADDRC), .Y(DOC));
+ $__ABC9_RAM6 dod (.A($DOD), .S(ADDRD), .Y(DOD));
+endmodule
+
+module SRL16 (
+ output Q,
+ (* techmap_autopurge *) input A0, A1, A2, A3, CLK, D
+);
+ parameter [15:0] INIT = 16'h0000;
+ wire $Q;
+ SRL16 #(
+ .INIT(INIT),
+ ) _TECHMAP_REPLACE_ (
+ .Q($Q),
+ .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CLK(CLK), .D(D)
+ );
+ $__ABC9_RAM6 q (.A($Q), .S({1'b1, A3, A2, A1, A0, 1'b1}), .Y(Q));
endmodule
module SRL16E (
@@ -537,7 +553,38 @@ module SRL16E (
.Q($Q),
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
);
- $__ABC9_LUT6 q (.A($Q), .S({1'b1, A3, A2, A1, A0, 1'b1}), .Y(Q));
+ $__ABC9_RAM6 q (.A($Q), .S({1'b1, A3, A2, A1, A0, 1'b1}), .Y(Q));
+endmodule
+
+module SRLC16 (
+ output Q, Q15,
+ (* techmap_autopurge *) input A0, A1, A2, A3, CLK, D
+);
+ parameter [15:0] INIT = 16'h0000;
+ wire $Q;
+ SRLC16 #(
+ .INIT(INIT),
+ ) _TECHMAP_REPLACE_ (
+ .Q($Q), .Q(Q15),
+ .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CLK(CLK), .D(D)
+ );
+ $__ABC9_RAM6 q (.A($Q), .S({1'b1, A3, A2, A1, A0, 1'b1}), .Y(Q));
+endmodule
+
+module SRLC16E (
+ output Q, Q15,
+ (* techmap_autopurge *) input A0, A1, A2, A3, CE, CLK, D
+);
+ parameter [15:0] INIT = 16'h0000;
+ parameter [0:0] IS_CLK_INVERTED = 1'b0;
+ wire $Q;
+ SRLC16E #(
+ .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
+ ) _TECHMAP_REPLACE_ (
+ .Q($Q), .Q(Q15),
+ .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
+ );
+ $__ABC9_RAM6 q (.A($Q), .S({1'b1, A3, A2, A1, A0, 1'b1}), .Y(Q));
endmodule
module SRLC32E (
@@ -555,7 +602,7 @@ module SRLC32E (
.Q($Q), .Q31(Q31),
.A(A), .CE(CE), .CLK(CLK), .D(D)
);
- $__ABC9_LUT6 q (.A($Q), .S({1'b1, A}), .Y(Q));
+ $__ABC9_RAM6 q (.A($Q), .S({1'b1, A}), .Y(Q));
endmodule
module DSP48E1 (
@@ -724,35 +771,16 @@ module DSP48E1 (
.RSTM(RSTM),
.RSTP(RSTP)
);
-
- generate
- wire [29:0] $A;
- wire [17:0] $B;
- wire [47:0] $C;
- wire [24:0] $D;
-
- if (PREG == 0) begin
- if (MREG == 0 && AREG == 0) assign $A = A;
- else assign $A = 30'bx;
- if (MREG == 0 && BREG == 0) assign $B = B;
- else assign $B = 18'bx;
- if (MREG == 0 && DREG == 0) assign $D = D;
- else assign $D = 25'bx;
-
- if (CREG == 0) assign $C = C;
- else assign $C = 48'bx;
- end
- else begin
- assign $A = 30'bx, $B = 18'bx, $C = 48'bx, $D = 25'bx;
- end
-
- if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE")
- $__ABC9_DSP48E1_MULT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
- else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE")
- $__ABC9_DSP48E1_MULT_DPORT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
- else if (USE_MULT == "NONE" && USE_DPORT == "FALSE")
- $__ABC9_DSP48E1 dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
- else
- $error("Invalid DSP48E1 configuration");
- endgenerate
+ $__ABC9_DSP48E1 #(
+ .ADREG(ADREG),
+ .AREG(AREG),
+ .BREG(BREG),
+ .CREG(CREG),
+ .DREG(DREG),
+ .MREG(MREG),
+ .PREG(PREG),
+ .USE_DPORT(USE_DPORT),
+ .USE_MULT(USE_MULT)
+ ) dsp_comb (
+ .$A(A), .$B(B), .$C(C), .$D(D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
endmodule
diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v
index 782c53ab6..2d109ef8a 100644
--- a/techlibs/xilinx/abc9_model.v
+++ b/techlibs/xilinx/abc9_model.v
@@ -24,30 +24,40 @@
// Necessary to make these an atomic unit so that
// ABC cannot optimise just one of the MUXF7 away
// and expect to save on its delay
-(* abc9_box_id = 3, lib_whitebox *)
+(* abc9_box, lib_whitebox *)
module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1);
assign O = S1 ? (S0 ? I3 : I2)
: (S0 ? I1 : I0);
-endmodule
-
-module \$__ABC9_FF_ (input D, output Q);
-endmodule
-
-(* abc9_box_id = (9000+DELAY) *)
-module \$__ABC9_DELAY (input I, output O);
- parameter DELAY = 0;
+ specify
+ (I0 => O) = 294;
+ (I1 => O) = 297;
+ (I2 => O) = 311;
+ (I3 => O) = 317;
+ (S0 => O) = 390;
+ (S1 => O) = 273;
+ endspecify
endmodule
// Box to emulate async behaviour of FDC*
-(* abc9_box_id = 1000, lib_whitebox *)
+(* abc9_box, lib_whitebox *)
module \$__ABC9_ASYNC0 (input A, S, output Y);
assign Y = S ? 1'b0 : A;
+ specify
+ (A => Y) = 0;
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L270
+ (S => Y) = 764;
+ endspecify
endmodule
// Box to emulate async behaviour of FDP*
-(* abc9_box_id = 1001, lib_whitebox *)
+(* abc9_box, lib_whitebox *)
module \$__ABC9_ASYNC1 (input A, S, output Y);
assign Y = S ? 1'b1 : A;
+ specify
+ (A => Y) = 0;
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L270
+ (S => Y) = 764;
+ endspecify
endmodule
// Box to emulate comb/seq behaviour of RAM{32,64} and SRL{16,32}
@@ -56,18 +66,37 @@ endmodule
// is only committed on the next clock edge).
// To model the combinatorial path, such cells have to be split
// into comb and seq parts, with this box modelling only the former.
-(* abc9_box_id=2000 *)
-module \$__ABC9_LUT6 (input A, input [5:0] S, output Y);
+(* abc9_box *)
+module \$__ABC9_RAM6 (input A, input [5:0] S, output Y);
+ specify
+ (A => Y) = 0;
+ (S[0] => Y) = 642;
+ (S[1] => Y) = 631;
+ (S[2] => Y) = 472;
+ (S[3] => Y) = 407;
+ (S[4] => Y) = 238;
+ (S[5] => Y) = 127;
+ endspecify
endmodule
// Box to emulate comb/seq behaviour of RAM128
-(* abc9_box_id=2001 *)
-module \$__ABC9_LUT7 (input A, input [6:0] S, output Y);
+(* abc9_box *)
+module \$__ABC9_RAM7 (input A, input [6:0] S, output Y);
+ specify
+ (A => Y) = 0;
+ // https://github.com/SymbiFlow/prjxray-db/blob/1c85daf1b115da4d27ca83c6b89f53a94de39748/artix7/timings/slicel.sdf#L867
+ (S[0] => Y) = 642 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (S[1] => Y) = 631 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (S[2] => Y) = 472 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (S[3] => Y) = 407 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (S[4] => Y) = 238 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (S[5] => Y) = 127 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (S[6] => Y) = 0 + 296 /* to select F7BMUX */ + 174 /* CMUX */;
+ endspecify
endmodule
-// Boxes used to represent the comb behaviour of various modes
-// of DSP48E1
-`define ABC9_DSP48E1(__NAME__) """
-module __NAME__ (
+// Boxes used to represent the comb behaviour of DSP48E1
+(* abc9_box *)
+module $__ABC9_DSP48E1 (
input [29:0] $A,
input [17:0] $B,
input [47:0] $C,
@@ -76,10 +105,106 @@ module __NAME__ (
input [47:0] $PCIN,
input [47:0] $PCOUT,
output [47:0] P,
- output [47:0] PCOUT);
+ output [47:0] PCOUT
+);
+ parameter integer ADREG = 1;
+ parameter integer AREG = 1;
+ parameter integer BREG = 1;
+ parameter integer CREG = 1;
+ parameter integer DREG = 1;
+ parameter integer MREG = 1;
+ parameter integer PREG = 1;
+ parameter USE_DPORT = "FALSE";
+ parameter USE_MULT = "MULTIPLY";
+
+ function integer \A.P.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \A.P.comb = 2823;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \A.P.comb = 3806;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \A.P.comb = 1523;
+ end
+ endfunction
+ function integer \A.PCOUT.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \A.PCOUT.comb = 2970;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \A.PCOUT.comb = 3954;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \A.PCOUT.comb = 1671;
+ end
+ endfunction
+ function integer \B.P.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \B.P.comb = 2690;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \B.P.comb = 2690;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \B.P.comb = 1509;
+ end
+ endfunction
+ function integer \B.PCOUT.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \B.PCOUT.comb = 2838;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \B.PCOUT.comb = 2838;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \B.PCOUT.comb = 1658;
+ end
+ endfunction
+ function integer \C.P.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \C.P.comb = 1325;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \C.P.comb = 1325;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \C.P.comb = 1325;
+ end
+ endfunction
+ function integer \C.PCOUT.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \C.PCOUT.comb = 1474;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \C.PCOUT.comb = 1474;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \C.PCOUT.comb = 1474;
+ end
+ endfunction
+ function integer \D.P.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \D.P.comb = 3717;
+ end
+ endfunction
+ function integer \D.PCOUT.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \D.PCOUT.comb = 3700;
+ end
+ endfunction
+
+ specify
+ ($P *> P) = 0;
+ ($PCOUT *> PCOUT) = 0;
+ endspecify
+
+ // Identical comb delays to DSP48E1 in cells_sim.v
+ generate
+ if (PREG == 0 && MREG == 0 && AREG == 0 && ADREG == 0)
+ specify
+ ($A *> P) = \A.P.comb ();
+ ($A *> PCOUT) = \A.PCOUT.comb ();
+ endspecify
+
+ if (PREG == 0 && MREG == 0 && BREG == 0)
+ specify
+ ($B *> P) = \B.P.comb ();
+ ($B *> PCOUT) = \B.PCOUT.comb ();
+ endspecify
+
+ if (PREG == 0 && CREG == 0)
+ specify
+ ($C *> P) = \C.P.comb ();
+ ($C *> PCOUT) = \C.PCOUT.comb ();
+ endspecify
+
+ if (PREG == 0 && MREG == 0 && ADREG == 0 && DREG == 0)
+ specify
+ ($D *> P) = \D.P.comb ();
+ ($D *> PCOUT) = \D.PCOUT.comb ();
+ endspecify
+
+ if (PREG == 0)
+ specify
+ ($PCIN *> P) = 1107;
+ ($PCIN *> PCOUT) = 1255;
+ endspecify
+ endgenerate
endmodule
-"""
-(* abc9_box_id=3000 *) `ABC9_DSP48E1($__ABC9_DSP48E1_MULT)
-(* abc9_box_id=3001 *) `ABC9_DSP48E1($__ABC9_DSP48E1_MULT_DPORT)
-(* abc9_box_id=3002 *) `ABC9_DSP48E1($__ABC9_DSP48E1)
-`undef ABC9_DSP48E1
diff --git a/techlibs/xilinx/abc9_unmap.v b/techlibs/xilinx/abc9_unmap.v
index f2342ce62..5604ceb0a 100644
--- a/techlibs/xilinx/abc9_unmap.v
+++ b/techlibs/xilinx/abc9_unmap.v
@@ -29,15 +29,14 @@ module $__ABC9_FF_(input D, output Q);
assign Q = D;
endmodule
-module $__ABC9_LUT6(input A, input [5:0] S, output Y);
+module $__ABC9_RAM6(input A, input [5:0] S, output Y);
assign Y = A;
endmodule
-module $__ABC9_LUT7(input A, input [6:0] S, output Y);
+module $__ABC9_RAM7(input A, input [6:0] S, output Y);
assign Y = A;
endmodule
-(* techmap_celltype = "$__ABC9_DSP48E1_MULT $__ABC9_DSP48E1_MULT_DPORT $__ABC9_DSP48E1" *)
-module $ABC9_DSP48E1(
+module $__ABC9_DSP48E1(
input [29:0] $A,
input [17:0] $B,
input [47:0] $C,
@@ -48,5 +47,15 @@ module $ABC9_DSP48E1(
output [47:0] P,
output [47:0] PCOUT
);
+ parameter integer ADREG = 1;
+ parameter integer AREG = 1;
+ parameter integer BREG = 1;
+ parameter integer CREG = 1;
+ parameter integer DREG = 1;
+ parameter integer MREG = 1;
+ parameter integer PREG = 1;
+ parameter USE_DPORT = "FALSE";
+ parameter USE_MULT = "MULTIPLY";
+
assign P = $P, PCOUT = $PCOUT;
endmodule
diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box
deleted file mode 100644
index 48d492801..000000000
--- a/techlibs/xilinx/abc9_xc7.box
+++ /dev/null
@@ -1,384 +0,0 @@
-# Max delays from https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf
-# https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf
-
-# NB: Box inputs/outputs must each be in the same order
-# as their corresponding module definition
-# (with exceptions detailed below)
-
-# Box 1 : MUXF7
-# Max delays from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L451-L453
-# name ID w/b ins outs
-MUXF7 1 1 3 1
-#I0 I1 S0
-204 208 286 # O
-
-# Box 2 : MUXF8
-# Max delays from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L462-L464
-# name ID w/b ins outs
-MUXF8 2 1 3 1
-#I0 I1 S0
-104 94 273 # O
-
-# Box 3 : $__MUXF78
-# (private cell used to preserve 2xMUXF7 + 1xMUXF8
-# an atomic unit so that ABC cannot optimise just
-# one of the MUXF7 away and expect to save on its
-# delay, since MUXF8 is only reachable through an
-# MUXF7)
-# name ID w/b ins outs
-$__MUXF78 3 1 6 1
-#I0 I1 I2 I3 S0 S1
-294 297 311 317 390 273 # O
-
-# Box 4 : CARRY4 + CARRY4_[ABCD]X
-# (Exception: carry chain input/output must be the
-# last input and output and the entire bus has been
-# moved there overriding the otherwise
-# alphabetical ordering)
-# Max delays from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L11-L46
-# name ID w/b ins outs
-CARRY4 4 1 10 8
-#CYINIT DI0 DI1 DI2 DI3 S0 S1 S2 S3 CI
-482 - - - - 223 - - - 222 # O0
-598 407 - - - 400 205 - - 334 # O1
-584 556 537 - - 523 558 226 - 239 # O2
-642 615 596 438 - 582 618 330 227 313 # O3
-536 379 - - - 340 - - - 271 # CO0
-494 465 445 - - 433 469 - - 157 # CO1
-592 540 520 356 - 512 548 292 - 228 # CO2
-580 526 507 398 385 508 528 378 380 114 # CO3
-
-# Box 1000 : $__ABC9_ASYNC0
-# (private cell to emulate async behaviour of FDC*)
-# name ID w/b ins outs
-$__ABC9_ASYNC0 1000 1 2 1
-#A S
-0 764 # Y
-
-# Box 1001 : $__ABC9_ASYNC1
-# (private cell to emulate async behaviour of FDP*)
-# name ID w/b ins outs
-$__ABC9_ASYNC1 1001 1 2 1
-#A S
-0 764 # Y
-
-# Box 2000 : $__ABC9_LUT6
-# (private cell to emulate async behaviour of LUTRAMs)
-# SLICEM/A6LUT
-# name ID w/b ins outs
-$__ABC9_LUT6 2000 0 7 1
-#A S0 S1 S2 S3 S4 S5
-0 642 631 472 407 238 127 # Y
-
-# Box 2001 : $__ABC9_LUT6
-# (private cell to emulate async behaviour of LUTRAMs)
-# name ID w/b ins outs
-$__ABC9_LUT7 2001 0 8 1
-#A S0 S1 S2 S3 S4 S5 S6
-0 1047 1036 877 812 643 532 478 # Y
-
-# Box 3000 : $__ABC9_DSP48E1_MULT
-# (private cell to emulate comb behaviour of a DSP48E1 mode)
-# name ID w/b ins outs
-$__ABC9_DSP48E1_MULT 3000 0 265 96
-#A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P2
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P3
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P4
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P5
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P6
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P7
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P8
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P9
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P10
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P11
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P12
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P13
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P14
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P15
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P16
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P17
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P18
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P19
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P20
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P21
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P22
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P23
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P24
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P25
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P26
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P27
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P28
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P29
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P30
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P31
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P32
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P33
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P34
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P35
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P36
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P37
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P38
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P39
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P40
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P41
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P42
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P43
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P44
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P45
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P46
-2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2823 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P47
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT0
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT1
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT2
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT3
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT4
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT5
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT6
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT7
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT8
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT9
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT10
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT11
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT12
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT13
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT14
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT15
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT16
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT17
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT18
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT19
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT20
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT21
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT22
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT23
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT24
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT25
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT26
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT27
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT28
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT29
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT30
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT31
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT32
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT33
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT34
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT35
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT36
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT37
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT38
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT39
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT40
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT41
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT42
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT43
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT44
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT45
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT46
-2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2970 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT47
-
-# Box 3001 : $__ABC9_DSP48E1_MULT_DPORT
-# (private cell to emulate comb behaviour of a DSP48E1 mode)
-# name ID w/b ins outs
-$__ABC9_DSP48E1_MULT_DPORT 3001 0 265 96
-#A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P2
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P3
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P4
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P5
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P6
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P7
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P8
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P9
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P10
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P11
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P12
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P13
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P14
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P15
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P16
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P17
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P18
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P19
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P20
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P21
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P22
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P23
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P24
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P25
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P26
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P27
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P28
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P29
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P30
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P31
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P32
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P33
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P34
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P35
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P36
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P37
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P38
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P39
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P40
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P41
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P42
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P43
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P44
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P45
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P46
-3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 3806 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 2690 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P47
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT0
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT1
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT2
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT3
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT4
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT5
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT6
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT7
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT8
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT9
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT10
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT11
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT12
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT13
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT14
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT15
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT16
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT17
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT18
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT19
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT20
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT21
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT22
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT23
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT24
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT25
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT26
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT27
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT28
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT29
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT30
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT31
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT32
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT33
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT34
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT35
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT36
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT37
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT38
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT39
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT40
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT41
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT42
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT43
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT44
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT45
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT46
-3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 3954 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 2838 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 3700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT47
-
-# Box 3002 : $__ABC9_DSP48E1
-# (private cell to emulate comb behaviour of a DSP48E1 mode)
-# name ID w/b ins outs
-$__ABC9_DSP48E1 3002 0 265 96
-#A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 C26 C27 C28 C29 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 PCIN0 PCIN1 PCIN2 PCIN3 PCIN4 PCIN5 PCIN6 PCIN7 PCIN8 PCIN9 PCIN10 PCIN11 PCIN12 PCIN13 PCIN14 PCIN15 PCIN16 PCIN17 PCIN18 PCIN19 PCIN20 PCIN21 PCIN22 PCIN23 PCIN24 PCIN25 PCIN26 PCIN27 PCIN28 PCIN29 PCIN30 PCIN31 PCIN32 PCIN33 PCIN34 PCIN35 PCIN36 PCIN37 PCIN38 PCIN39 PCIN40 PCIN41 PCIN42 PCIN43 PCIN44 PCIN45 PCIN46 PCIN47 PCOUT0 PCOUT1 PCOUT2 PCOUT3 PCOUT4 PCOUT5 PCOUT6 PCOUT7 PCOUT8 PCOUT9 PCOUT10 PCOUT11 PCOUT12 PCOUT13 PCOUT14 PCOUT15 PCOUT16 PCOUT17 PCOUT18 PCOUT19 PCOUT20 PCOUT21 PCOUT22 PCOUT23 PCOUT24 PCOUT25 PCOUT26 PCOUT27 PCOUT28 PCOUT29 PCOUT30 PCOUT31 PCOUT32 PCOUT33 PCOUT34 PCOUT35 PCOUT36 PCOUT37 PCOUT38 PCOUT39 PCOUT40 PCOUT41 PCOUT42 PCOUT43 PCOUT44 PCOUT45 PCOUT46 PCOUT47
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P0
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P1
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P2
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P3
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P4
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P5
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P6
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P7
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P8
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P9
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P10
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P11
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P12
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P13
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P14
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P15
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P16
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P17
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P18
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P19
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P20
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P21
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P22
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P23
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P24
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P25
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P26
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P27
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P28
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P29
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P30
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P31
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P32
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P33
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P34
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P35
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P36
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P37
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P38
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P39
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P40
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P41
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P42
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P43
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P44
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P45
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P46
-1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1523 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1509 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 1325 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 1107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # P47
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT0
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT1
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT2
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT3
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT4
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT5
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT6
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT7
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT8
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT9
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT10
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT11
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT12
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT13
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT14
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT15
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT16
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT17
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT18
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT19
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT20
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT21
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT22
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT23
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT24
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT25
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT26
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT27
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT28
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT29
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT30
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT31
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT32
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT33
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT34
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT35
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT36
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT37
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT38
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT39
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT40
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT41
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT42
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT43
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT44
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT45
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT46
-1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1671 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1658 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 1474 - - - - - - - - - - - - - - - - - - - - - - - - - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 1255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # PCOUT47
diff --git a/techlibs/xilinx/abc9_xc7.lut b/techlibs/xilinx/abc9_xc7.lut
deleted file mode 100644
index bcbdec127..000000000
--- a/techlibs/xilinx/abc9_xc7.lut
+++ /dev/null
@@ -1,15 +0,0 @@
-# Max delays from https://github.com/SymbiFlow/prjxray-db/blob/82bf5f158cd8e9a11ac4d04f1aeef48ed1a528a5/artix7/timings/CLBLL_L.sdf
-# and https://github.com/SymbiFlow/prjxray-db/blob/82bf5f158cd8e9a11ac4d04f1aeef48ed1a528a5/artix7/tile_type_CLBLL_L.json
-
-# K area delay
-1 1 127
-2 2 127 238
-3 3 127 238 407
-4 3 127 238 407 472
-5 3 127 238 407 472 631
-6 5 127 238 407 472 631 642
- # (F7[AB]MUX.S + [AC]OUTMUX) / 2
-7 10 464 513 624 793 858 1017 1028
- # F8MUX.S+BOUTMUX
- # F8MUX.I0+F7MUX.S+BOUTMUX
-8 20 468 585 634 745 914 979 1138 1149
diff --git a/techlibs/xilinx/abc9_xc7_nowide.lut b/techlibs/xilinx/abc9_xc7_nowide.lut
deleted file mode 100644
index fab48c879..000000000
--- a/techlibs/xilinx/abc9_xc7_nowide.lut
+++ /dev/null
@@ -1,10 +0,0 @@
-# Max delays from https://github.com/SymbiFlow/prjxray-db/blob/82bf5f158cd8e9a11ac4d04f1aeef48ed1a528a5/artix7/timings/CLBLL_L.sdf
-# and https://github.com/SymbiFlow/prjxray-db/blob/82bf5f158cd8e9a11ac4d04f1aeef48ed1a528a5/artix7/tile_type_CLBLL_L.json
-
-# K area delay
-1 1 127
-2 2 127 238
-3 3 127 238 407
-4 3 127 238 407 472
-5 3 127 238 407 472 631
-6 5 127 238 407 472 631 642
diff --git a/techlibs/xilinx/arith_map.v b/techlibs/xilinx/arith_map.v
index 40c378d16..2b8b0dcc1 100644
--- a/techlibs/xilinx/arith_map.v
+++ b/techlibs/xilinx/arith_map.v
@@ -34,6 +34,12 @@ module _80_xilinx_lcu (P, G, CI, CO);
genvar i;
`ifdef _EXPLICIT_CARRY
+ localparam EXPLICIT_CARRY = 1'b1;
+`else
+ localparam EXPLICIT_CARRY = 1'b0;
+`endif
+
+generate if (EXPLICIT_CARRY || `LUT_SIZE == 4) begin
wire [WIDTH-1:0] C = {CO, CI};
wire [WIDTH-1:0] S = P & ~G;
@@ -47,71 +53,39 @@ module _80_xilinx_lcu (P, G, CI, CO);
);
end endgenerate
-`else
+end else begin
localparam CARRY4_COUNT = (WIDTH + 3) / 4;
localparam MAX_WIDTH = CARRY4_COUNT * 4;
localparam PAD_WIDTH = MAX_WIDTH - WIDTH;
- wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, P & ~G};
- wire [MAX_WIDTH-1:0] C = CO;
+ wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, P & ~G};
+ wire [MAX_WIDTH-1:0] GG = {{PAD_WIDTH{1'b0}}, G};
+ wire [MAX_WIDTH-1:0] C;
+ assign CO = C;
generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice
-
- // Partially occupied CARRY4
- if ((i+1)*4 > WIDTH) begin
-
- // First one
- if (i == 0) begin
- CARRY4 carry4_1st_part
- (
- .CYINIT(CI),
- .CI (1'd0),
- .DI (G [(WIDTH - 1):i*4]),
- .S (S [(WIDTH - 1):i*4]),
- .CO (CO[(WIDTH - 1):i*4]),
- );
- // Another one
- end else begin
- CARRY4 carry4_part
- (
- .CYINIT(1'd0),
- .CI (C [i*4 - 1]),
- .DI (G [(WIDTH - 1):i*4]),
- .S (S [(WIDTH - 1):i*4]),
- .CO (CO[(WIDTH - 1):i*4]),
- );
- end
-
- // Fully occupied CARRY4
+ if (i == 0) begin
+ CARRY4 carry4
+ (
+ .CYINIT(CI),
+ .CI (1'd0),
+ .DI (GG[i*4 +: 4]),
+ .S (S [i*4 +: 4]),
+ .CO (C [i*4 +: 4]),
+ );
end else begin
-
- // First one
- if (i == 0) begin
- CARRY4 carry4_1st_full
- (
- .CYINIT(CI),
- .CI (1'd0),
- .DI (G [((i+1)*4 - 1):i*4]),
- .S (S [((i+1)*4 - 1):i*4]),
- .CO (CO[((i+1)*4 - 1):i*4]),
- );
- // Another one
- end else begin
- CARRY4 carry4_full
- (
- .CYINIT(1'd0),
- .CI (C [i*4 - 1]),
- .DI (G [((i+1)*4 - 1):i*4]),
- .S (S [((i+1)*4 - 1):i*4]),
- .CO (CO[((i+1)*4 - 1):i*4]),
- );
- end
-
+ CARRY4 carry4
+ (
+ .CYINIT(1'd0),
+ .CI (C [i*4 - 1]),
+ .DI (GG[i*4 +: 4]),
+ .S (S [i*4 +: 4]),
+ .CO (C [i*4 +: 4]),
+ );
end
-
end endgenerate
-`endif
+end endgenerate
endmodule
@@ -148,9 +122,34 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO);
genvar i;
`ifdef _EXPLICIT_CARRY
+ localparam EXPLICIT_CARRY = 1'b1;
+`else
+ localparam EXPLICIT_CARRY = 1'b0;
+`endif
+
+generate if (`LUT_SIZE == 4) begin
+
+ wire [Y_WIDTH-1:0] C = {CO, CI};
+ wire [Y_WIDTH-1:0] S = {AA ^ BB};
+
+ genvar i;
+ generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
+ MUXCY muxcy (
+ .CI(C[i]),
+ .DI(AA[i]),
+ .S(S[i]),
+ .O(CO[i])
+ );
+ XORCY xorcy (
+ .CI(C[i]),
+ .LI(S[i]),
+ .O(Y[i])
+ );
+ end endgenerate
+
+end else if (EXPLICIT_CARRY) begin
wire [Y_WIDTH-1:0] S = AA ^ BB;
- wire [Y_WIDTH-1:0] DI = AA & BB;
wire CINIT;
// Carry chain.
@@ -170,7 +169,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO);
generate for (i = 0; i < 1; i = i + 1) begin:slice
CARRY0 #(.CYINIT_FABRIC(1)) carry(
.CI_INIT(CI),
- .DI(DI[0]),
+ .DI(AA[0]),
.S(S[0]),
.CO_CHAIN(CO_CHAIN[0]),
.CO_FABRIC(CO[0]),
@@ -182,7 +181,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO);
if(i % 4 == 0) begin
CARRY0 carry (
.CI(C[i]),
- .DI(DI[i]),
+ .DI(AA[i]),
.S(S[i]),
.CO_CHAIN(CO_CHAIN[i]),
.CO_FABRIC(CO[i]),
@@ -193,7 +192,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO);
begin
CARRY carry (
.CI(C[i]),
- .DI(DI[i]),
+ .DI(AA[i]),
.S(S[i]),
.CO_CHAIN(CO_CHAIN[i]),
.CO_FABRIC(CO[i]),
@@ -206,7 +205,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO);
if(i % 4 == 0) begin
CARRY0 top_of_carry (
.CI(C[i]),
- .DI(DI[i]),
+ .DI(AA[i]),
.S(S[i]),
.CO_CHAIN(CO_CHAIN[i]),
.O(Y[i])
@@ -216,7 +215,7 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO);
begin
CARRY top_of_carry (
.CI(C[i]),
- .DI(DI[i]),
+ .DI(AA[i]),
.S(S[i]),
.CO_CHAIN(CO_CHAIN[i]),
.O(Y[i])
@@ -245,79 +244,45 @@ module _80_xilinx_alu (A, B, CI, BI, X, Y, CO);
end
end endgenerate
-`else
+end else begin
localparam CARRY4_COUNT = (Y_WIDTH + 3) / 4;
localparam MAX_WIDTH = CARRY4_COUNT * 4;
localparam PAD_WIDTH = MAX_WIDTH - Y_WIDTH;
wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, AA ^ BB};
- wire [MAX_WIDTH-1:0] DI = {{PAD_WIDTH{1'b0}}, AA & BB};
+ wire [MAX_WIDTH-1:0] DI = {{PAD_WIDTH{1'b0}}, AA};
- wire [MAX_WIDTH-1:0] C = CO;
+ wire [MAX_WIDTH-1:0] O;
+ wire [MAX_WIDTH-1:0] C;
+ assign Y = O, CO = C;
genvar i;
generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice
-
- // Partially occupied CARRY4
- if ((i+1)*4 > Y_WIDTH) begin
-
- // First one
- if (i == 0) begin
- CARRY4 carry4_1st_part
- (
- .CYINIT(CI),
- .CI (1'd0),
- .DI (DI[(Y_WIDTH - 1):i*4]),
- .S (S [(Y_WIDTH - 1):i*4]),
- .O (Y [(Y_WIDTH - 1):i*4]),
- .CO (CO[(Y_WIDTH - 1):i*4])
- );
- // Another one
- end else begin
- CARRY4 carry4_part
- (
- .CYINIT(1'd0),
- .CI (C [i*4 - 1]),
- .DI (DI[(Y_WIDTH - 1):i*4]),
- .S (S [(Y_WIDTH - 1):i*4]),
- .O (Y [(Y_WIDTH - 1):i*4]),
- .CO (CO[(Y_WIDTH - 1):i*4])
- );
- end
-
- // Fully occupied CARRY4
+ if (i == 0) begin
+ CARRY4 carry4
+ (
+ .CYINIT(CI),
+ .CI (1'd0),
+ .DI (DI[i*4 +: 4]),
+ .S (S [i*4 +: 4]),
+ .O (O [i*4 +: 4]),
+ .CO (C [i*4 +: 4])
+ );
end else begin
-
- // First one
- if (i == 0) begin
- CARRY4 carry4_1st_full
- (
- .CYINIT(CI),
- .CI (1'd0),
- .DI (DI[((i+1)*4 - 1):i*4]),
- .S (S [((i+1)*4 - 1):i*4]),
- .O (Y [((i+1)*4 - 1):i*4]),
- .CO (CO[((i+1)*4 - 1):i*4])
- );
- // Another one
- end else begin
- CARRY4 carry4_full
- (
- .CYINIT(1'd0),
- .CI (C [i*4 - 1]),
- .DI (DI[((i+1)*4 - 1):i*4]),
- .S (S [((i+1)*4 - 1):i*4]),
- .O (Y [((i+1)*4 - 1):i*4]),
- .CO (CO[((i+1)*4 - 1):i*4])
- );
- end
-
+ CARRY4 carry4
+ (
+ .CYINIT(1'd0),
+ .CI (C [i*4 - 1]),
+ .DI (DI[i*4 +: 4]),
+ .S (S [i*4 +: 4]),
+ .O (O [i*4 +: 4]),
+ .CO (C [i*4 +: 4])
+ );
end
-
end endgenerate
-`endif
+end endgenerate
assign X = S;
endmodule
diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v
index 4692eba33..63223afbf 100644
--- a/techlibs/xilinx/cells_sim.v
+++ b/techlibs/xilinx/cells_sim.v
@@ -160,34 +160,60 @@ module INV(
input I
);
assign O = !I;
+ specify
+ (I => O) = 127;
+ endspecify
endmodule
+(* abc9_lut=1 *)
module LUT1(output O, input I0);
parameter [1:0] INIT = 0;
assign O = I0 ? INIT[1] : INIT[0];
+ specify
+ (I0 => O) = 127;
+ endspecify
endmodule
+(* abc9_lut=2 *)
module LUT2(output O, input I0, I1);
parameter [3:0] INIT = 0;
wire [ 1: 0] s1 = I1 ? INIT[ 3: 2] : INIT[ 1: 0];
assign O = I0 ? s1[1] : s1[0];
+ specify
+ (I0 => O) = 238;
+ (I1 => O) = 127;
+ endspecify
endmodule
+(* abc9_lut=3 *)
module LUT3(output O, input I0, I1, I2);
parameter [7:0] INIT = 0;
wire [ 3: 0] s2 = I2 ? INIT[ 7: 4] : INIT[ 3: 0];
wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
assign O = I0 ? s1[1] : s1[0];
+ specify
+ (I0 => O) = 407;
+ (I1 => O) = 238;
+ (I2 => O) = 127;
+ endspecify
endmodule
+(* abc9_lut=3 *)
module LUT4(output O, input I0, I1, I2, I3);
parameter [15:0] INIT = 0;
wire [ 7: 0] s3 = I3 ? INIT[15: 8] : INIT[ 7: 0];
wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
assign O = I0 ? s1[1] : s1[0];
+ specify
+ (I0 => O) = 472;
+ (I1 => O) = 407;
+ (I2 => O) = 238;
+ (I3 => O) = 127;
+ endspecify
endmodule
+(* abc9_lut=3 *)
module LUT5(output O, input I0, I1, I2, I3, I4);
parameter [31:0] INIT = 0;
wire [15: 0] s4 = I4 ? INIT[31:16] : INIT[15: 0];
@@ -195,8 +221,19 @@ module LUT5(output O, input I0, I1, I2, I3, I4);
wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
assign O = I0 ? s1[1] : s1[0];
+ specify
+ (I0 => O) = 631;
+ (I1 => O) = 472;
+ (I2 => O) = 407;
+ (I3 => O) = 238;
+ (I4 => O) = 127;
+ endspecify
endmodule
+// This is a placeholder for ABC9 to extract the area/delay
+// cost of 3-input LUTs and is not intended to be instantiated
+
+(* abc9_lut=5 *)
module LUT6(output O, input I0, I1, I2, I3, I4, I5);
parameter [63:0] INIT = 0;
wire [31: 0] s5 = I5 ? INIT[63:32] : INIT[31: 0];
@@ -205,6 +242,14 @@ module LUT6(output O, input I0, I1, I2, I3, I4, I5);
wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
assign O = I0 ? s1[1] : s1[0];
+ specify
+ (I0 => O) = 642;
+ (I1 => O) = 631;
+ (I2 => O) = 472;
+ (I3 => O) = 407;
+ (I4 => O) = 238;
+ (I5 => O) = 127;
+ endspecify
endmodule
module LUT6_2(output O6, output O5, input I0, I1, I2, I3, I4, I5);
@@ -223,6 +268,43 @@ module LUT6_2(output O6, output O5, input I0, I1, I2, I3, I4, I5);
assign O5 = I0 ? s5_1[1] : s5_1[0];
endmodule
+// This is a placeholder for ABC9 to extract the area/delay
+// cost of 3-input LUTs and is not intended to be instantiated
+(* abc9_lut=10 *)
+module \$__ABC9_LUT7 (output O, input I0, I1, I2, I3, I4, I5, I6);
+`ifndef __ICARUS__
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/1c85daf1b115da4d27ca83c6b89f53a94de39748/artix7/timings/slicel.sdf#L867
+ (I0 => O) = 642 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (I1 => O) = 631 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (I2 => O) = 472 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (I3 => O) = 407 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (I4 => O) = 238 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (I5 => O) = 127 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+ (I6 => O) = 0 + 296 /* to select F7BMUX */ + 174 /* CMUX */;
+ endspecify
+`endif
+endmodule
+
+// This is a placeholder for ABC9 to extract the area/delay
+// cost of 3-input LUTs and is not intended to be instantiated
+(* abc9_lut=20 *)
+module \$__ABC9_LUT8 (output O, input I0, I1, I2, I3, I4, I5, I6, I7);
+`ifndef __ICARUS__
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/1c85daf1b115da4d27ca83c6b89f53a94de39748/artix7/timings/slicel.sdf#L716
+ (I0 => O) = 642 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
+ (I1 => O) = 631 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
+ (I2 => O) = 472 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
+ (I3 => O) = 407 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
+ (I4 => O) = 238 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
+ (I5 => O) = 127 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
+ (I6 => O) = 0 + 296 /* to select F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
+ (I7 => O) = 0 + 0 + 273 /* to select F8MUX */ + 192 /* BMUX */;
+ endspecify
+`endif
+endmodule
+
module MUXCY(output O, input CI, DI, S);
assign O = S ? CI : DI;
endmodule
@@ -235,14 +317,26 @@ module MUXF6(output O, input I0, I1, S);
assign O = S ? I1 : I0;
endmodule
-(* abc9_box_id = 1, lib_whitebox *)
+(* abc9_box, lib_whitebox *)
module MUXF7(output O, input I0, I1, S);
assign O = S ? I1 : I0;
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L451-L453
+ (I0 => O) = 217;
+ (I1 => O) = 223;
+ (S => O) = 296;
+ endspecify
endmodule
-(* abc9_box_id = 2, lib_whitebox *)
+(* abc9_box, lib_whitebox *)
module MUXF8(output O, input I0, I1, S);
assign O = S ? I1 : I0;
+ specify
+ // Max delays from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L462-L464
+ (I0 => O) = 104;
+ (I1 => O) = 94;
+ (S => O) = 273;
+ endspecify
endmodule
module MUXF9(output O, input I0, I1, S);
@@ -253,7 +347,7 @@ module XORCY(output O, input CI, LI);
assign O = CI ^ LI;
endmodule
-(* abc9_box_id = 4, lib_whitebox *)
+(* abc9_box, lib_whitebox *)
module CARRY4(
(* abc9_carry *)
output [3:0] CO,
@@ -268,6 +362,61 @@ module CARRY4(
assign CO[1] = S[1] ? CO[0] : DI[1];
assign CO[2] = S[2] ? CO[1] : DI[2];
assign CO[3] = S[3] ? CO[2] : DI[3];
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L11-L46
+ (CYINIT => O[0]) = 482;
+ (S[0] => O[0]) = 223;
+ (CI => O[0]) = 222;
+ (CYINIT => O[1]) = 598;
+ (DI[0] => O[1]) = 407;
+ (S[0] => O[1]) = 400;
+ (S[1] => O[1]) = 205;
+ (CI => O[1]) = 334;
+ (CYINIT => O[2]) = 584;
+ (DI[0] => O[2]) = 556;
+ (DI[1] => O[2]) = 537;
+ (S[0] => O[2]) = 523;
+ (S[1] => O[2]) = 558;
+ (S[2] => O[2]) = 226;
+ (CI => O[2]) = 239;
+ (CYINIT => O[3]) = 642;
+ (DI[0] => O[3]) = 615;
+ (DI[1] => O[3]) = 596;
+ (DI[2] => O[3]) = 438;
+ (S[0] => O[3]) = 582;
+ (S[1] => O[3]) = 618;
+ (S[2] => O[3]) = 330;
+ (S[3] => O[3]) = 227;
+ (CI => O[3]) = 313;
+ (CYINIT => CO[0]) = 536;
+ (DI[0] => CO[0]) = 379;
+ (S[0] => CO[0]) = 340;
+ (CI => CO[0]) = 271;
+ (CYINIT => CO[1]) = 494;
+ (DI[0] => CO[1]) = 465;
+ (DI[1] => CO[1]) = 445;
+ (S[0] => CO[1]) = 433;
+ (S[1] => CO[1]) = 469;
+ (CI => CO[1]) = 157;
+ (CYINIT => CO[2]) = 592;
+ (DI[0] => CO[2]) = 540;
+ (DI[1] => CO[2]) = 520;
+ (DI[2] => CO[2]) = 356;
+ (S[0] => CO[2]) = 512;
+ (S[1] => CO[2]) = 548;
+ (S[2] => CO[2]) = 292;
+ (CI => CO[2]) = 228;
+ (CYINIT => CO[3]) = 580;
+ (DI[0] => CO[3]) = 526;
+ (DI[1] => CO[3]) = 507;
+ (DI[2] => CO[3]) = 398;
+ (DI[3] => CO[3]) = 385;
+ (S[0] => CO[3]) = 508;
+ (S[1] => CO[3]) = 528;
+ (S[2] => CO[3]) = 378;
+ (S[3] => CO[3]) = 380;
+ (CI => CO[3]) = 114;
+ endspecify
endmodule
module CARRY8(
@@ -327,18 +476,14 @@ endmodule
(* abc9_flop, lib_whitebox *)
module FDRE (
- (* abc9_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C,
- (* abc9_required=109 *)
input CE,
(* invertible_pin = "IS_D_INVERTED" *)
- //(* abc9_required=-46 *) // Negative required times not currently supported
input D,
(* invertible_pin = "IS_R_INVERTED" *)
- (* abc9_required=404 *)
input R
);
parameter [0:0] INIT = 1'b0;
@@ -346,44 +491,64 @@ module FDRE (
parameter [0:0] IS_D_INVERTED = 1'b0;
parameter [0:0] IS_R_INVERTED = 1'b0;
initial Q <= INIT;
- generate case (|IS_C_INVERTED)
+ generate
+ case (|IS_C_INVERTED)
1'b0: always @(posedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
1'b1: always @(negedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
- endcase endgenerate
+ endcase
+ endgenerate
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
+ //$setup(D , posedge C &&& CE && !IS_C_INVERTED , -46); // Negative times not currently supported
+ //$setup(D , negedge C &&& CE && IS_C_INVERTED , -46); // Negative times not currently supported
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
+ $setup(CE, posedge C &&& !IS_C_INVERTED, 109);
+ $setup(CE, negedge C &&& IS_C_INVERTED, 109);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
+ $setup(R , posedge C &&& !IS_C_INVERTED, 404);
+ $setup(R , negedge C &&& IS_C_INVERTED, 404);
+ // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L243
+ if (!IS_C_INVERTED && R ^ IS_R_INVERTED) (posedge C => (Q : 1'b0)) = 303;
+ if ( IS_C_INVERTED && R ^ IS_R_INVERTED) (negedge C => (Q : 1'b0)) = 303;
+ if (!IS_C_INVERTED && R ~^ IS_R_INVERTED && CE) (posedge C => (Q : D ^ IS_D_INVERTED)) = 303;
+ if ( IS_C_INVERTED && R ~^ IS_R_INVERTED && CE) (negedge C => (Q : D ^ IS_D_INVERTED)) = 303;
+ endspecify
endmodule
(* abc9_flop, lib_whitebox *)
module FDRE_1 (
- (* abc9_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
input C,
- (* abc9_required=109 *)
input CE,
- //(* abc9_required=-46 *) // Negative required times not currently supported
input D,
- (* abc9_required=404 *)
input R
);
parameter [0:0] INIT = 1'b0;
initial Q <= INIT;
always @(negedge C) if (R) Q <= 1'b0; else if (CE) Q <= D;
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
+ //$setup(D , negedge C &&& CE, -46); // Negative times not currently supported
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
+ $setup(CE, negedge C, 109);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
+ $setup(R , negedge C, 404); // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L243
+ if (R) (negedge C => (Q : 1'b0)) = 303;
+ if (!R && CE) (negedge C => (Q : D)) = 303;
+ endspecify
endmodule
(* abc9_flop, lib_whitebox *)
module FDSE (
- (* abc9_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C,
- (* abc9_required=109 *)
input CE,
(* invertible_pin = "IS_D_INVERTED" *)
- //(* abc9_required=-46 *) // Negative required times not currently supported
input D,
(* invertible_pin = "IS_S_INVERTED" *)
- (* abc9_required=404 *)
input S
);
parameter [0:0] INIT = 1'b1;
@@ -391,28 +556,53 @@ module FDSE (
parameter [0:0] IS_D_INVERTED = 1'b0;
parameter [0:0] IS_S_INVERTED = 1'b0;
initial Q <= INIT;
- generate case (|IS_C_INVERTED)
+ generate
+ case (|IS_C_INVERTED)
1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
- endcase endgenerate
+ endcase
+ endgenerate
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
+ //$setup(D , posedge C &&& !IS_C_INVERTED && CE, -46); // Negative times not currently supported
+ //$setup(D , negedge C &&& IS_C_INVERTED && CE, -46); // Negative times not currently supported
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
+ $setup(CE, posedge C &&& !IS_C_INVERTED, 109);
+ $setup(CE, negedge C &&& IS_C_INVERTED, 109);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
+ $setup(S , posedge C &&& !IS_C_INVERTED, 404);
+ $setup(S , negedge C &&& IS_C_INVERTED, 404);
+ // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L243
+ if (!IS_C_INVERTED && S ^ IS_S_INVERTED) (posedge C => (Q : 1'b1)) = 303;
+ if ( IS_C_INVERTED && S ^ IS_S_INVERTED) (negedge C => (Q : 1'b1)) = 303;
+ if (!IS_C_INVERTED && S ~^ IS_S_INVERTED && CE) (posedge C => (Q : D ^ IS_D_INVERTED)) = 303;
+ if ( IS_C_INVERTED && S ~^ IS_S_INVERTED && CE) (negedge C => (Q : D ^ IS_D_INVERTED)) = 303;
+ endspecify
endmodule
(* abc9_flop, lib_whitebox *)
module FDSE_1 (
- (* abc9_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
input C,
- (* abc9_required=109 *)
input CE,
- //(* abc9_required=-46 *) // Negative required times not currently supported
input D,
- (* abc9_required=404 *)
input S
);
parameter [0:0] INIT = 1'b1;
initial Q <= INIT;
always @(negedge C) if (S) Q <= 1'b1; else if (CE) Q <= D;
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
+ //$setup(D , negedge C &&& CE, -46); // Negative times not currently supported
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
+ $setup(CE, negedge C, 109);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
+ $setup(S , negedge C, 404);
+ // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L243
+ if (S) (negedge C => (Q : 1'b1)) = 303;
+ if (!S && CE) (negedge C => (Q : D)) = 303;
+ endspecify
endmodule
module FDRSE (
@@ -421,7 +611,6 @@ module FDRSE (
(* invertible_pin = "IS_C_INVERTED" *)
input C,
(* invertible_pin = "IS_CE_INVERTED" *)
- (* abc9_required=109 *)
input CE,
(* invertible_pin = "IS_D_INVERTED" *)
input D,
@@ -453,18 +642,14 @@ endmodule
(* abc9_flop, lib_whitebox *)
module FDCE (
- (* abc9_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C,
- (* abc9_required=109 *)
input CE,
(* invertible_pin = "IS_CLR_INVERTED" *)
- (* abc9_required=764 *)
input CLR,
(* invertible_pin = "IS_D_INVERTED" *)
- //(* abc9_required=-46 *) // Negative required times not currently supported
input D
);
parameter [0:0] INIT = 1'b0;
@@ -472,46 +657,67 @@ module FDCE (
parameter [0:0] IS_D_INVERTED = 1'b0;
parameter [0:0] IS_CLR_INVERTED = 1'b0;
initial Q <= INIT;
- generate case ({|IS_C_INVERTED, |IS_CLR_INVERTED})
+ generate
+ case ({|IS_C_INVERTED, |IS_CLR_INVERTED})
2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
- endcase endgenerate
+ endcase
+ endgenerate
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
+ //$setup(D , posedge C &&& !IS_C_INVERTED && CE, -46); // Negative times not currently supported
+ //$setup(D , negedge C &&& IS_C_INVERTED && CE, -46); // Negative times not currently supported
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
+ $setup(CE , posedge C &&& !IS_C_INVERTED, 109);
+ $setup(CE , negedge C &&& IS_C_INVERTED, 109);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
+ $setup(CLR, posedge C &&& !IS_C_INVERTED, 404);
+ $setup(CLR, negedge C &&& IS_C_INVERTED, 404);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L270
+ //if (!IS_CLR_INVERTED) (posedge CLR => (Q : 1'b0)) = 764; // Captured by $__ABC9_ASYNC0
+ //if ( IS_CLR_INVERTED) (negedge CLR => (Q : 1'b0)) = 764; // Captured by $__ABC9_ASYNC0
+ if (!IS_C_INVERTED && CLR ~^ IS_CLR_INVERTED && CE) (posedge C => (Q : D ^ IS_D_INVERTED)) = 303;
+ if ( IS_C_INVERTED && CLR ~^ IS_CLR_INVERTED && CE) (negedge C => (Q : D ^ IS_D_INVERTED)) = 303;
+ endspecify
endmodule
(* abc9_flop, lib_whitebox *)
module FDCE_1 (
- (* abc9_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
input C,
- (* abc9_required=109 *)
input CE,
- (* abc9_required=764 *)
input CLR,
- //(* abc9_required=-46 *) // Negative required times not currently supported
input D
);
parameter [0:0] INIT = 1'b0;
initial Q <= INIT;
always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D;
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
+ //$setup(D , negedge C &&& CE, -46); // Negative times not currently supported
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
+ $setup(CE , negedge C, 109);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
+ $setup(CLR, negedge C, 404);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L270
+ //(posedge CLR => (Q : 1'b0)) = 764; // Captured by $__ABC9_ASYNC0
+ if (!CLR && CE) (negedge C => (Q : D)) = 303;
+ endspecify
endmodule
(* abc9_flop, lib_whitebox *)
module FDPE (
- (* abc9_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C,
- (* abc9_required=109 *)
input CE,
(* invertible_pin = "IS_D_INVERTED" *)
- //(* abc9_required=-46 *) // Negative required times not currently supported
input D,
(* invertible_pin = "IS_PRE_INVERTED" *)
- (* abc9_required=764 *)
input PRE
);
parameter [0:0] INIT = 1'b1;
@@ -524,25 +730,50 @@ module FDPE (
2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
- endcase endgenerate
+ endcase
+ endgenerate
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
+ //$setup(D , posedge C &&& !IS_C_INVERTED && CE, -46); // Negative times not currently supported
+ //$setup(D , negedge C &&& IS_C_INVERTED && CE, -46); // Negative times not currently supported
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
+ $setup(CE , posedge C &&& !IS_C_INVERTED, 109);
+ $setup(CE , negedge C &&& IS_C_INVERTED, 109);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
+ $setup(PRE, posedge C &&& !IS_C_INVERTED, 404);
+ $setup(PRE, negedge C &&& IS_C_INVERTED, 404);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L270
+ //if (!IS_PRE_INVERTED) (posedge PRE => (Q : 1'b1)) = 764; // Captured by $__ABC9_ASYNC1
+ //if ( IS_PRE_INVERTED) (negedge PRE => (Q : 1'b1)) = 764; // Captured by $__ABC9_ASYNC1
+ if (!IS_C_INVERTED && PRE ~^ IS_PRE_INVERTED && CE) (posedge C => (Q : D ^ IS_D_INVERTED)) = 303;
+ if ( IS_C_INVERTED && PRE ~^ IS_PRE_INVERTED && CE) (negedge C => (Q : D ^ IS_D_INVERTED)) = 303;
+ endspecify
endmodule
(* abc9_flop, lib_whitebox *)
module FDPE_1 (
- (* abc9_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
input C,
- (* abc9_required=109 *)
input CE,
- //(* abc9_required=-46 *) // Negative required times not currently supported
input D,
- (* abc9_required=764 *)
input PRE
);
parameter [0:0] INIT = 1'b1;
initial Q <= INIT;
always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
+ //$setup(D , negedge C &&& CE, -46); // Negative times not currently supported
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
+ $setup(CE , negedge C, 109);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
+ $setup(PRE, negedge C, 404);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L270
+ //if (!IS_PRE_INVERTED) (posedge PRE => (Q : 1'b1)) = 764; // Captured by $__ABC9_ASYNC1
+ //if (IS_PRE_INVERTED) (negedge PRE => (Q : 1'b1)) = 764; // Captured by $__ABC9_ASYNC1
+ if (!PRE && CE) (negedge C => (Q : D)) = 303;
+ endspecify
endmodule
module FDCPE (
@@ -1153,33 +1384,13 @@ module RAM16X1D_1 (
endmodule
module RAM32X1D (
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
- (* abc9_arrival=1153 *)
output DPO, SPO,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
- (* abc9_required=453 *)
input D,
(* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
- (* abc9_required=654 *)
input WE,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800
- (* abc9_required=245 *)
- input A0,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/clBLM_R.sdf#L798
- (* abc9_required=208 *)
- input A1,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796
- (* abc9_required=147 *)
- input A2,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794
- (* abc9_required=68 *)
- input A3,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792
- (* abc9_required=66 *)
- input A4,
+ input A0, A1, A2, A3, A4,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
);
parameter INIT = 32'h0;
@@ -1191,35 +1402,53 @@ module RAM32X1D (
assign DPO = mem[dpra];
wire clk = WCLK ^ IS_WCLK_INVERTED;
always @(posedge clk) if (WE) mem[a] <= D;
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
+ $setup(D , posedge WCLK &&& !IS_WCLK_INVERTED && WE, 453);
+ $setup(D , negedge WCLK &&& IS_WCLK_INVERTED && WE, 453);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
+ $setup(WE, posedge WCLK &&& !IS_WCLK_INVERTED, 654);
+ $setup(WE, negedge WCLK &&& IS_WCLK_INVERTED, 654);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800
+ $setup(A0, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 245);
+ $setup(A0, negedge WCLK &&& IS_WCLK_INVERTED && WE, 245);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L798
+ $setup(A1, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 208);
+ $setup(A1, negedge WCLK &&& IS_WCLK_INVERTED && WE, 208);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796
+ $setup(A2, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 147);
+ $setup(A2, negedge WCLK &&& IS_WCLK_INVERTED && WE, 147);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794
+ $setup(A3, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 68);
+ $setup(A3, negedge WCLK &&& IS_WCLK_INVERTED && WE, 68);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792
+ $setup(A4, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 66);
+ $setup(A4, posedge WCLK &&& IS_WCLK_INVERTED && WE, 66);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
+ if (!IS_WCLK_INVERTED) (posedge WCLK => (SPO : D)) = 1153;
+ if (!IS_WCLK_INVERTED) (posedge WCLK => (DPO : 1'bx)) = 1153;
+ if ( IS_WCLK_INVERTED) (posedge WCLK => (SPO : D)) = 1153;
+ if ( IS_WCLK_INVERTED) (negedge WCLK => (DPO : 1'bx)) = 1153;
+ // Captured by $__ABC9_RAM6
+ //({A0,DPRA0} => {SPO,DPO}) = 642;
+ //({A1,DPRA1} => {SPO,DPO}) = 631;
+ //({A2,DPRA2} => {SPO,DPO}) = 472;
+ //({A3,DPRA3} => {SPO,DPO}) = 407;
+ //({A4,DPRA4} => {SPO,DPO}) = 238;
+ endspecify
endmodule
module RAM32X1D_1 (
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
- (* abc9_arrival=1153 *)
output DPO, SPO,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
- (* abc9_required=453 *)
input D,
(* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
- (* abc9_required=654 *)
input WE,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800
- (* abc9_required=245 *)
input A0,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/clBLM_R.sdf#L798
- (* abc9_required=208 *)
input A1,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796
- (* abc9_required=147 *)
input A2,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794
- (* abc9_required=68 *)
input A3,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792
- (* abc9_required=66 *)
input A4,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
);
@@ -1232,39 +1461,41 @@ module RAM32X1D_1 (
assign DPO = mem[dpra];
wire clk = WCLK ^ IS_WCLK_INVERTED;
always @(negedge clk) if (WE) mem[a] <= D;
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
+ $setup(D , negedge WCLK &&& WE, 453);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
+ $setup(WE, negedge WCLK, 654);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800
+ $setup(A0, negedge WCLK &&& WE, 245);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L798
+ $setup(A1, negedge WCLK &&& WE, 208);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796
+ $setup(A2, negedge WCLK &&& WE, 147);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794
+ $setup(A3, negedge WCLK &&& WE, 68);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792
+ $setup(A4, negedge WCLK &&& WE, 66);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
+ if (WE) (negedge WCLK => (SPO : D)) = 1153;
+ if (WE) (negedge WCLK => (DPO : 1'bx)) = 1153;
+ // Captured by $__ABC9_RAM6
+ //({A0,DPRA0} => {SPO,DPO}) = 642;
+ //({A1,DPRA1} => {SPO,DPO}) = 631;
+ //({A2,DPRA2} => {SPO,DPO}) = 472;
+ //({A3,DPRA3} => {SPO,DPO}) = 407;
+ //({A4,DPRA4} => {SPO,DPO}) = 238;
+ endspecify
endmodule
module RAM64X1D (
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
- (* abc9_arrival=1153 *)
output DPO, SPO,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
- (* abc9_required=453 *)
input D,
(* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
- (* abc9_required=654 *)
input WE,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828
- (* abc9_required=362 *)
- input A0,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826
- (* abc9_required=245 *)
- input A1,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824
- (* abc9_required=208 *)
- input A2,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822
- (* abc9_required=147 *)
- input A3,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820
- (* abc9_required=68 *)
- input A4,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818
- (* abc9_required=66 *)
- input A5,
+ input A0, A1, A2, A3, A4, A5,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
);
parameter INIT = 64'h0;
@@ -1276,39 +1507,54 @@ module RAM64X1D (
assign DPO = mem[dpra];
wire clk = WCLK ^ IS_WCLK_INVERTED;
always @(posedge clk) if (WE) mem[a] <= D;
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
+ $setup(D , posedge WCLK &&& !IS_WCLK_INVERTED && WE, 453);
+ $setup(D , negedge WCLK &&& IS_WCLK_INVERTED && WE, 453);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
+ $setup(WE, posedge WCLK &&& !IS_WCLK_INVERTED, 654);
+ $setup(WE, negedge WCLK &&& IS_WCLK_INVERTED, 654);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828
+ $setup(A0, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 362);
+ $setup(A0, negedge WCLK &&& IS_WCLK_INVERTED && WE, 362);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826
+ $setup(A1, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 245);
+ $setup(A1, negedge WCLK &&& IS_WCLK_INVERTED && WE, 245);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824
+ $setup(A2, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 208);
+ $setup(A2, negedge WCLK &&& IS_WCLK_INVERTED && WE, 208);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822
+ $setup(A3, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 147);
+ $setup(A3, negedge WCLK &&& IS_WCLK_INVERTED && WE, 147);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820
+ $setup(A4, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 68);
+ $setup(A4, negedge WCLK &&& IS_WCLK_INVERTED && WE, 68);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818
+ $setup(A5, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 66);
+ $setup(A5, negedge WCLK &&& IS_WCLK_INVERTED && WE, 66);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (SPO : D)) = 1153;
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DPO : 1'bx)) = 1153;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (SPO : D)) = 1153;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DPO : 1'bx)) = 1153;
+ // Captured by $__ABC9_RAM6
+ //({A0,DPRA0} => {SPO,DPO}) = 642;
+ //({A1,DPRA1} => {SPO,DPO}) = 631;
+ //({A2,DPRA2} => {SPO,DPO}) = 472;
+ //({A3,DPRA3} => {SPO,DPO}) = 407;
+ //({A4,DPRA4} => {SPO,DPO}) = 238;
+ //({A5,DPRA5} => {SPO,DPO}) = 127;
+ endspecify
endmodule
module RAM64X1D_1 (
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
- (* abc9_arrival=1153 *)
output DPO, SPO,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
- (* abc9_required=453 *)
input D,
(* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
- (* abc9_required=654 *)
input WE,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828
- (* abc9_required=362 *)
- input A0,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826
- (* abc9_required=245 *)
- input A1,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824
- (* abc9_required=208 *)
- input A2,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822
- (* abc9_required=147 *)
- input A3,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820
- (* abc9_required=68 *)
- input A4,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818
- (* abc9_required=66 *)
- input A5,
+ input A0, A1, A2, A3, A4, A5,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
);
parameter INIT = 64'h0;
@@ -1320,24 +1566,36 @@ module RAM64X1D_1 (
assign DPO = mem[dpra];
wire clk = WCLK ^ IS_WCLK_INVERTED;
always @(negedge clk) if (WE) mem[a] <= D;
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
+ $setup(D , negedge WCLK &&& WE, 453);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
+ $setup(WE, negedge WCLK, 654);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828
+ $setup(A0, negedge WCLK &&& WE, 362);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826
+ $setup(A1, negedge WCLK &&& WE, 245);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824
+ $setup(A2, negedge WCLK &&& WE, 208);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822
+ $setup(A3, negedge WCLK &&& WE, 147);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820
+ $setup(A4, negedge WCLK &&& WE, 68);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818
+ $setup(A5, negedge WCLK &&& WE, 66);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
+ if (WE) (negedge WCLK => (SPO : D)) = 1153;
+ if (WE) (negedge WCLK => (DPO : 1'bx)) = 1153;
+ endspecify
endmodule
module RAM128X1D (
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
- // plus 208ps to cross MUXF7
- (* abc9_arrival=1359 *)
output DPO, SPO,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
- (* abc9_required=453 *)
input D,
(* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
- (* abc9_required=654 *)
input WE,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-830
- (* abc9_required="616 362 245 208 147 68 66" *)
input [6:0] A,
input [6:0] DPRA
);
@@ -1348,6 +1606,49 @@ module RAM128X1D (
assign DPO = mem[DPRA];
wire clk = WCLK ^ IS_WCLK_INVERTED;
always @(posedge clk) if (WE) mem[A] <= D;
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
+ $setup(D , posedge WCLK &&& !IS_WCLK_INVERTED && WE, 453);
+ $setup(D , negedge WCLK &&& IS_WCLK_INVERTED && WE, 453);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
+ $setup(WE, posedge WCLK &&& !IS_WCLK_INVERTED, 654);
+ $setup(WE, negedge WCLK &&& IS_WCLK_INVERTED, 654);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-830
+ $setup(A[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 616);
+ $setup(A[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 616);
+ $setup(A[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 362);
+ $setup(A[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 362);
+ $setup(A[2], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 245);
+ $setup(A[2], negedge WCLK &&& IS_WCLK_INVERTED && WE, 245);
+ $setup(A[3], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 208);
+ $setup(A[3], negedge WCLK &&& IS_WCLK_INVERTED && WE, 208);
+ $setup(A[4], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 147);
+ $setup(A[4], negedge WCLK &&& IS_WCLK_INVERTED && WE, 147);
+ $setup(A[5], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 68);
+ $setup(A[5], negedge WCLK &&& IS_WCLK_INVERTED && WE, 68);
+ $setup(A[6], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 66);
+ $setup(A[6], negedge WCLK &&& IS_WCLK_INVERTED && WE, 66);
+`ifndef __ICARUS__
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (SPO : D)) = 1153 + 217 /* to cross F7AMUX */ + 175 /* AMUX */;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DPO : 1'bx)) = 1153 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
+`endif
+ // Captured by $__ABC9_RAM7
+ //(A[0] => SPO) = 642 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
+ //(A[1] => SPO) = 631 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
+ //(A[2] => SPO) = 472 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
+ //(A[3] => SPO) = 407 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
+ //(A[4] => SPO) = 238 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
+ //(A[5] => SPO) = 127 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
+ //(A[6] => SPO) = 0 + 276 /* to select F7AMUX */ + 175 /* AMUX */;
+ //(DPRA[0] => DPO) = 642 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
+ //(DPRA[1] => DPO) = 631 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
+ //(DPRA[2] => DPO) = 472 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
+ //(DPRA[3] => DPO) = 407 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
+ //(DPRA[4] => DPO) = 238 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
+ //(DPRA[5] => DPO) = 127 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
+ //(DPRA[6] => DPO) = 0 + 296 /* to select MUXF7 */ + 174 /* CMUX */;
+ endspecify
endmodule
module RAM256X1D (
@@ -1371,43 +1672,19 @@ endmodule
// Multi port.
module RAM32M (
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857
- (* abc9_arrival="1153 1188" *)
output [1:0] DOA,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L925
- (* abc9_arrival="1161 1187" *)
output [1:0] DOB,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L993
- (* abc9_arrival="1158 1180" *)
output [1:0] DOC,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1061
- (* abc9_arrival="1163 1190" *)
output [1:0] DOD,
input [4:0] ADDRA, ADDRB, ADDRC,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792-L802
- (* abc9_required="245 208 147 68 66" *)
input [4:0] ADDRD,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
- (* abc9_required="453 384" *)
input [1:0] DIA,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
- (* abc9_required="461 354" *)
input [1:0] DIB,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
- (* abc9_required="457 375" *)
input [1:0] DIC,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
- (* abc9_required="310 334" *)
input [1:0] DID,
(* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
- (* abc9_required=654 *)
input WE
);
parameter [63:0] INIT_A = 64'h0000000000000000;
@@ -1431,6 +1708,72 @@ module RAM32M (
mem_c[2*ADDRD+:2] <= DIC;
mem_d[2*ADDRD+:2] <= DID;
end
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
+ $setup(ADDRD[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 245);
+ $setup(ADDRD[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 245);
+ $setup(ADDRD[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 208);
+ $setup(ADDRD[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 208);
+ $setup(ADDRD[2], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 147);
+ $setup(ADDRD[2], negedge WCLK &&& IS_WCLK_INVERTED && WE, 147);
+ $setup(ADDRD[3], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 68);
+ $setup(ADDRD[3], negedge WCLK &&& IS_WCLK_INVERTED && WE, 68);
+ $setup(ADDRD[4], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 66);
+ $setup(ADDRD[4], negedge WCLK &&& IS_WCLK_INVERTED && WE, 66);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
+ $setup(DIA[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 453);
+ $setup(DIA[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 453);
+ $setup(DIA[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 384);
+ $setup(DIA[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 384);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
+ $setup(DIB[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 461);
+ $setup(DIB[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 461);
+ $setup(DIB[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 354);
+ $setup(DIB[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 354);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
+ $setup(DIC[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 457);
+ $setup(DIC[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 457);
+ $setup(DIC[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 375);
+ $setup(DIC[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 375);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
+ $setup(DID[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 310);
+ $setup(DID[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 310);
+ $setup(DID[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 334);
+ $setup(DID[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 334);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
+ $setup(WE, posedge WCLK &&& !IS_WCLK_INVERTED, 654);
+ $setup(WE, negedge WCLK &&& IS_WCLK_INVERTED, 654);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOA[0] : DIA[0])) = 1153;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOA[0] : DIA[0])) = 1153;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOA[1] : DIA[1])) = 1188;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOA[1] : DIA[1])) = 1188;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOB[0] : DIB[0])) = 1161;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOB[0] : DIB[0])) = 1161;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L925
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOB[1] : DIB[1])) = 1187;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOB[1] : DIB[1])) = 1187;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L993
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOC[0] : DIC[0])) = 1158;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOC[0] : DIC[0])) = 1158;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOC[1] : DIC[1])) = 1180;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOC[1] : DIC[1])) = 1180;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOD[0] : DID[0])) = 1163;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOD[0] : DID[0])) = 1163;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1061
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOD[1] : DID[1])) = 1190;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOD[1] : DID[1])) = 1190;
+ // Captured by $__ABC9_RAM6
+ //({{2{ADDRA[0]}},{2{ADDRB[0]}},{2{ADDRC[0]}},{2{ADDRD[0]}}} => {DOA,DOB,DOC,DOD}) = 642;
+ //({{2{ADDRA[1]}},{2{ADDRB[1]}},{2{ADDRC[1]}},{2{ADDRD[1]}}} => {DOA,DOB,DOC,DOD}) = 631;
+ //({{2{ADDRA[2]}},{2{ADDRB[2]}},{2{ADDRC[2]}},{2{ADDRD[2]}}} => {DOA,DOB,DOC,DOD}) = 472;
+ //({{2{ADDRA[3]}},{2{ADDRB[3]}},{2{ADDRC[3]}},{2{ADDRD[3]}}} => {DOA,DOB,DOC,DOD}) = 407;
+ //({{2{ADDRA[4]}},{2{ADDRB[4]}},{2{ADDRC[4]}},{2{ADDRD[4]}}} => {DOA,DOB,DOC,DOD}) = 238;
+ endspecify
endmodule
module RAM32M16 (
@@ -1503,39 +1846,19 @@ module RAM32M16 (
endmodule
module RAM64M (
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
- (* abc9_arrival=1153 *)
output DOA,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
- (* abc9_arrival=1161 *)
output DOB,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
- (* abc9_arrival=1158 *)
output DOC,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
- (* abc9_arrival=1163 *)
output DOD,
input [5:0] ADDRA, ADDRB, ADDRC,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-L830
- (* abc9_required="362 245 208 147 68 66" *)
input [5:0] ADDRD,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
- (* abc9_required=384 *)
input DIA,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
- (* abc9_required=354 *)
input DIB,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
- (* abc9_required=375 *)
input DIC,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
- (* abc9_required=310 *)
input DID,
(* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
- (* abc9_required=654 *)
input WE
);
parameter [63:0] INIT_A = 64'h0000000000000000;
@@ -1559,6 +1882,54 @@ module RAM64M (
mem_c[ADDRD] <= DIC;
mem_d[ADDRD] <= DID;
end
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-L830
+ $setup(ADDRD[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 362);
+ $setup(ADDRD[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 362);
+ $setup(ADDRD[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 245);
+ $setup(ADDRD[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 245);
+ $setup(ADDRD[2], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 208);
+ $setup(ADDRD[2], negedge WCLK &&& IS_WCLK_INVERTED && WE, 208);
+ $setup(ADDRD[3], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 147);
+ $setup(ADDRD[3], negedge WCLK &&& IS_WCLK_INVERTED && WE, 147);
+ $setup(ADDRD[4], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 68);
+ $setup(ADDRD[4], negedge WCLK &&& IS_WCLK_INVERTED && WE, 68);
+ $setup(ADDRD[5], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 66);
+ $setup(ADDRD[5], negedge WCLK &&& IS_WCLK_INVERTED && WE, 66);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
+ $setup(DIA, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 384);
+ $setup(DIA, negedge WCLK &&& IS_WCLK_INVERTED && WE, 384);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
+ $setup(DIB, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 354);
+ $setup(DIB, negedge WCLK &&& IS_WCLK_INVERTED && WE, 354);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
+ $setup(DIC, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 375);
+ $setup(DIC, negedge WCLK &&& IS_WCLK_INVERTED && WE, 375);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
+ $setup(DID, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 310);
+ $setup(DID, negedge WCLK &&& IS_WCLK_INVERTED && WE, 310);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
+ $setup(WE, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 654);
+ $setup(WE, negedge WCLK &&& IS_WCLK_INVERTED && WE, 654);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOA : DIA)) = 1153;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOA : DIA)) = 1153;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOB : DIB)) = 1161;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOB : DIB)) = 1161;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOC : DIC)) = 1158;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOC : DIC)) = 1158;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
+ if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOD : DID)) = 1163;
+ if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOD : DID)) = 1163;
+ // Captured by $__ABC9_RAM6
+ //({ADDRA[0],ADDRB[0],ADDRC[0],ADDRD[0]} => {DOA,DOB,DOC,DOD}) = 642;
+ //({ADDRA[1],ADDRB[1],ADDRC[1],ADDRD[1]} => {DOA,DOB,DOC,DOD}) = 631;
+ //({ADDRA[2],ADDRB[2],ADDRC[2],ADDRD[2]} => {DOA,DOB,DOC,DOD}) = 472;
+ //({ADDRA[3],ADDRB[3],ADDRC[3],ADDRD[3]} => {DOA,DOB,DOC,DOD}) = 407;
+ //({ADDRA[4],ADDRB[4],ADDRC[4],ADDRD[4]} => {DOA,DOB,DOC,DOD}) = 238;
+ endspecify
endmodule
module RAM64M8 (
@@ -1686,11 +2057,21 @@ module SRL16 (
reg [15:0] r = INIT;
assign Q = r[{A3,A2,A1,A0}];
always @(posedge CLK) r <= { r[14:0], D };
+
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
+ (posedge CLK => (Q : 1'bx)) = 1472;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L912
+ $setup(D , posedge CLK, 173);
+ // Captured by $__ABC9_RAM6
+ //(A0 => Q) = 631;
+ //(A1 => Q) = 472;
+ //(A2 => Q) = 407;
+ //(A3 => Q) = 238;
+ endspecify
endmodule
module SRL16E (
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
- (* abc9_arrival=1472 *)
output Q,
input A0, A1, A2, A3, CE,
(* clkbuf_sink *)
@@ -1710,6 +2091,19 @@ module SRL16E (
else
always @(posedge CLK) if (CE) r <= { r[14:0], D };
endgenerate
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L912
+ $setup(D , posedge CLK &&& !IS_CLK_INVERTED, 173);
+ $setup(D , negedge CLK &&& IS_CLK_INVERTED, 173);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
+ if (!IS_CLK_INVERTED && CE) (posedge CLK => (Q : 1'bx)) = 1472;
+ if ( IS_CLK_INVERTED && CE) (negedge CLK => (Q : 1'bx)) = 1472;
+ // Captured by $__ABC9_RAM6
+ //(A0 => Q) = 631;
+ //(A1 => Q) = 472;
+ //(A2 => Q) = 407;
+ //(A3 => Q) = 238;
+ endspecify
endmodule
module SRLC16 (
@@ -1726,6 +2120,18 @@ module SRLC16 (
assign Q15 = r[15];
assign Q = r[{A3,A2,A1,A0}];
always @(posedge CLK) r <= { r[14:0], D };
+
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
+ (posedge CLK => (Q : 1'bx)) = 1472;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L912
+ $setup(D , posedge CLK, 173);
+ // Captured by $__ABC9_RAM6
+ //(A0 => Q) = 631;
+ //(A1 => Q) = 472;
+ //(A2 => Q) = 407;
+ //(A3 => Q) = 238;
+ endspecify
endmodule
module SRLC16E (
@@ -1750,14 +2156,24 @@ module SRLC16E (
else
always @(posedge CLK) if (CE) r <= { r[14:0], D };
endgenerate
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L912
+ $setup(D , posedge CLK &&& !IS_CLK_INVERTED, 173);
+ $setup(D , negedge CLK &&& IS_CLK_INVERTED, 173);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
+ if (!IS_CLK_INVERTED && CE) (posedge CLK => (Q : D)) = 1472;
+ if ( IS_CLK_INVERTED && CE) (negedge CLK => (Q : D)) = 1472;
+ // Captured by $__ABC9_RAM6
+ //(A0 => Q) = 642;
+ //(A1 => Q) = 631;
+ //(A2 => Q) = 472;
+ //(A3 => Q) = 407;
+ //(A4 => Q) = 238;
+ endspecify
endmodule
module SRLC32E (
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
- (* abc9_arrival=1472 *)
output Q,
- // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904
- (* abc9_arrival=1114 *)
output Q31,
input [4:0] A,
input CE,
@@ -1779,6 +2195,23 @@ module SRLC32E (
else
always @(posedge CLK) if (CE) r <= { r[30:0], D };
endgenerate
+ specify
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L912
+ $setup(D , posedge CLK &&& !IS_CLK_INVERTED, 173);
+ $setup(D , negedge CLK &&& IS_CLK_INVERTED, 173);
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
+ if (!IS_CLK_INVERTED && CE) (posedge CLK => (Q : 1'bx)) = 1472;
+ if ( IS_CLK_INVERTED && CE) (negedge CLK => (Q : 1'bx)) = 1472;
+ // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904
+ if (!IS_CLK_INVERTED && CE) (posedge CLK => (Q : 1'bx)) = 1114;
+ if ( IS_CLK_INVERTED && CE) (negedge CLK => (Q : 1'bx)) = 1114;
+ // Captured by $__ABC9_RAM6
+ //(A0 => Q) = 642;
+ //(A1 => Q) = 631;
+ //(A2 => Q) = 472;
+ //(A3 => Q) = 407;
+ //(A4 => Q) = 238;
+ endspecify
endmodule
module CFGLUT5 (
@@ -1962,6 +2395,7 @@ parameter RSTTYPE = "SYNC";
// This is a strict subset of Spartan 6 -- reuse its model.
+/* verilator lint_off PINMISSING */
DSP48A1 #(
.A0REG(A0REG),
.A1REG(A1REG),
@@ -2008,6 +2442,7 @@ DSP48A1 #(
.RSTOPMODE(RSTOPMODE),
.RSTP(RSTP)
);
+/* verilator lint_on PINMISSING */
endmodule
@@ -2550,31 +2985,16 @@ module DSP48E1 (
output reg [3:0] CARRYOUT,
output reg MULTSIGNOUT,
output OVERFLOW,
-`ifdef YOSYS
- (* abc9_arrival = \P.abc9_arrival () *)
-`endif
output reg signed [47:0] P,
output reg PATTERNBDETECT,
output reg PATTERNDETECT,
-`ifdef YOSYS
- (* abc9_arrival = \PCOUT.abc9_arrival () *)
-`endif
output [47:0] PCOUT,
output UNDERFLOW,
-`ifdef YOSYS
- (* abc9_required = \A.abc9_required () *)
-`endif
input signed [29:0] A,
input [29:0] ACIN,
input [3:0] ALUMODE,
-`ifdef YOSYS
- (* abc9_required = \B.abc9_required () *)
-`endif
input signed [17:0] B,
input [17:0] BCIN,
-`ifdef YOSYS
- (* abc9_required = \C.abc9_required () *)
-`endif
input [47:0] C,
input CARRYCASCIN,
input CARRYIN,
@@ -2593,16 +3013,10 @@ module DSP48E1 (
input CEM,
input CEP,
(* clkbuf_sink *) input CLK,
-`ifdef YOSYS
- (* abc9_required = \D.abc9_required () *)
-`endif
input [24:0] D,
input [4:0] INMODE,
input MULTSIGNIN,
input [6:0] OPMODE,
-`ifdef YOSYS
- (* abc9_required = \PCIN.abc9_required () *)
-`endif
input [47:0] PCIN,
input RSTA,
input RSTALLCARRYIN,
@@ -2647,138 +3061,239 @@ module DSP48E1 (
parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
`ifdef YOSYS
- function integer \A.abc9_required ;
+ function integer \A.required ;
begin
- \A.abc9_required = 0;
- if (AREG != 0) \A.abc9_required = 254;
+ if (AREG != 0) \A.required = 254;
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
- if (MREG != 0) \A.abc9_required = 1416;
- else if (PREG != 0) \A.abc9_required = (USE_PATTERN_DETECT != "NO_PATDET" ? 3030 : 2739) ;
+ if (MREG != 0) \A.required = 1416;
+ else if (PREG != 0) \A.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 3030 : 2739) ;
end
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
// Worst-case from ADREG and MREG
- if (MREG != 0) \A.abc9_required = 2400;
- else if (ADREG != 0) \A.abc9_required = 1283;
- else if (PREG != 0) \A.abc9_required = 3723;
- else if (PREG != 0) \A.abc9_required = (USE_PATTERN_DETECT != "NO_PATDET" ? 4014 : 3723) ;
+ if (MREG != 0) \A.required = 2400;
+ else if (ADREG != 0) \A.required = 1283;
+ else if (PREG != 0) \A.required = 3723;
+ else if (PREG != 0) \A.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 4014 : 3723) ;
end
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
- if (PREG != 0) \A.abc9_required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1730 : 1441) ;
+ if (PREG != 0) \A.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1730 : 1441) ;
end
end
endfunction
- function integer \B.abc9_required ;
+ function integer \B.required ;
begin
- \B.abc9_required = 0;
- if (BREG != 0) \B.abc9_required = 324;
- else if (MREG != 0) \B.abc9_required = 1285;
+ if (BREG != 0) \B.required = 324;
+ else if (MREG != 0) \B.required = 1285;
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
- if (PREG != 0) \B.abc9_required = (USE_PATTERN_DETECT != "NO_PATDET" ? 2898 : 2608) ;
+ if (PREG != 0) \B.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 2898 : 2608) ;
end
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
- if (PREG != 0) \B.abc9_required = (USE_PATTERN_DETECT != "NO_PATDET" ? 2898 : 2608) ;
+ if (PREG != 0) \B.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 2898 : 2608) ;
end
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
- if (PREG != 0) \B.abc9_required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1718 : 1428) ;
+ if (PREG != 0) \B.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1718 : 1428) ;
end
end
endfunction
- function integer \C.abc9_required ;
+ function integer \C.required ;
begin
- \C.abc9_required = 0;
- if (CREG != 0) \C.abc9_required = 168;
- else if (PREG != 0) \C.abc9_required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1534 : 1244) ;
+ if (CREG != 0) \C.required = 168;
+ else if (PREG != 0) \C.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1534 : 1244) ;
end
endfunction
- function integer \D.abc9_required ;
+ function integer \D.required ;
begin
- \D.abc9_required = 0;
if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
end
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
- if (DREG != 0) \D.abc9_required = 248;
- else if (ADREG != 0) \D.abc9_required = 1195;
- else if (MREG != 0) \D.abc9_required = 2310;
- else if (PREG != 0) \D.abc9_required = (USE_PATTERN_DETECT != "NO_PATDET" ? 3925 : 3635) ;
+ if (DREG != 0) \D.required = 248;
+ else if (ADREG != 0) \D.required = 1195;
+ else if (MREG != 0) \D.required = 2310;
+ else if (PREG != 0) \D.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 3925 : 3635) ;
end
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
end
end
endfunction
- function integer \PCIN.abc9_required ;
- begin
- \PCIN.abc9_required = 0;
- if (PREG != 0) \PCIN.abc9_required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1315 : 1025) ;
- end
- endfunction
- function integer \P.abc9_arrival ;
+ function integer \P.arrival ;
begin
- \P.abc9_arrival = 0;
if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
- if (PREG != 0) \P.abc9_arrival = 329;
+ if (PREG != 0) \P.arrival = 329;
// Worst-case from CREG and MREG
- else if (CREG != 0) \P.abc9_arrival = 1687;
- else if (MREG != 0) \P.abc9_arrival = 1671;
+ else if (CREG != 0) \P.arrival = 1687;
+ else if (MREG != 0) \P.arrival = 1671;
// Worst-case from AREG and BREG
- else if (AREG != 0) \P.abc9_arrival = 2952;
- else if (BREG != 0) \P.abc9_arrival = 2813;
+ else if (AREG != 0) \P.arrival = 2952;
+ else if (BREG != 0) \P.arrival = 2813;
end
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
- if (PREG != 0) \P.abc9_arrival = 329;
+ if (PREG != 0) \P.arrival = 329;
// Worst-case from CREG and MREG
- else if (CREG != 0) \P.abc9_arrival = 1687;
- else if (MREG != 0) \P.abc9_arrival = 1671;
+ else if (CREG != 0) \P.arrival = 1687;
+ else if (MREG != 0) \P.arrival = 1671;
// Worst-case from AREG, ADREG, BREG, DREG
- else if (AREG != 0) \P.abc9_arrival = 3935;
- else if (DREG != 0) \P.abc9_arrival = 3908;
- else if (ADREG != 0) \P.abc9_arrival = 2958;
- else if (BREG != 0) \P.abc9_arrival = 2813;
+ else if (AREG != 0) \P.arrival = 3935;
+ else if (DREG != 0) \P.arrival = 3908;
+ else if (ADREG != 0) \P.arrival = 2958;
+ else if (BREG != 0) \P.arrival = 2813;
end
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
- if (PREG != 0) \P.abc9_arrival = 329;
+ if (PREG != 0) \P.arrival = 329;
// Worst-case from AREG, BREG, CREG
- else if (CREG != 0) \P.abc9_arrival = 1687;
- else if (AREG != 0) \P.abc9_arrival = 1632;
- else if (BREG != 0) \P.abc9_arrival = 1616;
+ else if (CREG != 0) \P.arrival = 1687;
+ else if (AREG != 0) \P.arrival = 1632;
+ else if (BREG != 0) \P.arrival = 1616;
end
- //else
- // $error("Invalid DSP48E1 configuration");
end
endfunction
- function integer \PCOUT.abc9_arrival ;
+ function integer \PCOUT.arrival ;
begin
- \PCOUT.abc9_arrival = 0;
if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
- if (PREG != 0) \PCOUT.abc9_arrival = 435;
+ if (PREG != 0) \PCOUT.arrival = 435;
// Worst-case from CREG and MREG
- else if (CREG != 0) \PCOUT.abc9_arrival = 1835;
- else if (MREG != 0) \PCOUT.abc9_arrival = 1819;
+ else if (CREG != 0) \PCOUT.arrival = 1835;
+ else if (MREG != 0) \PCOUT.arrival = 1819;
// Worst-case from AREG and BREG
- else if (AREG != 0) \PCOUT.abc9_arrival = 3098;
- else if (BREG != 0) \PCOUT.abc9_arrival = 2960;
+ else if (AREG != 0) \PCOUT.arrival = 3098;
+ else if (BREG != 0) \PCOUT.arrival = 2960;
end
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
- if (PREG != 0) \PCOUT.abc9_arrival = 435;
+ if (PREG != 0) \PCOUT.arrival = 435;
// Worst-case from CREG and MREG
- else if (CREG != 0) \PCOUT.abc9_arrival = 1835;
- else if (MREG != 0) \PCOUT.abc9_arrival = 1819;
+ else if (CREG != 0) \PCOUT.arrival = 1835;
+ else if (MREG != 0) \PCOUT.arrival = 1819;
// Worst-case from AREG, ADREG, BREG, DREG
- else if (AREG != 0) \PCOUT.abc9_arrival = 4083;
- else if (DREG != 0) \PCOUT.abc9_arrival = 4056;
- else if (BREG != 0) \PCOUT.abc9_arrival = 2960;
- else if (ADREG != 0) \PCOUT.abc9_arrival = 2859;
+ else if (AREG != 0) \PCOUT.arrival = 4083;
+ else if (DREG != 0) \PCOUT.arrival = 4056;
+ else if (BREG != 0) \PCOUT.arrival = 2960;
+ else if (ADREG != 0) \PCOUT.arrival = 2859;
end
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
- if (PREG != 0) \PCOUT.abc9_arrival = 435;
+ if (PREG != 0) \PCOUT.arrival = 435;
// Worst-case from AREG, BREG, CREG
- else if (CREG != 0) \PCOUT.abc9_arrival = 1835;
- else if (AREG != 0) \PCOUT.abc9_arrival = 1780;
- else if (BREG != 0) \PCOUT.abc9_arrival = 1765;
+ else if (CREG != 0) \PCOUT.arrival = 1835;
+ else if (AREG != 0) \PCOUT.arrival = 1780;
+ else if (BREG != 0) \PCOUT.arrival = 1765;
end
- //else
- // $error("Invalid DSP48E1 configuration");
end
endfunction
+ function integer \A.P.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \A.P.comb = 2823;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \A.P.comb = 3806;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \A.P.comb = 1523;
+ end
+ endfunction
+ function integer \A.PCOUT.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \A.PCOUT.comb = 2970;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \A.PCOUT.comb = 3954;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \A.PCOUT.comb = 1671;
+ end
+ endfunction
+ function integer \B.P.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \B.P.comb = 2690;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \B.P.comb = 2690;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \B.P.comb = 1509;
+ end
+ endfunction
+ function integer \B.PCOUT.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \B.PCOUT.comb = 2838;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \B.PCOUT.comb = 2838;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \B.PCOUT.comb = 1658;
+ end
+ endfunction
+ function integer \C.P.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \C.P.comb = 1325;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \C.P.comb = 1325;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \C.P.comb = 1325;
+ end
+ endfunction
+ function integer \C.PCOUT.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \C.PCOUT.comb = 1474;
+ else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \C.PCOUT.comb = 1474;
+ else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \C.PCOUT.comb = 1474;
+ end
+ endfunction
+ function integer \D.P.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \D.P.comb = 3717;
+ end
+ endfunction
+ function integer \D.PCOUT.comb ;
+ begin
+ if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \D.PCOUT.comb = 3700;
+ end
+ endfunction
+
+ generate
+ if (PREG == 0 && MREG == 0 && AREG == 0 && ADREG == 0)
+ specify
+ (A *> P) = \A.P.comb ();
+ (A *> PCOUT) = \A.PCOUT.comb ();
+ endspecify
+ else
+ specify
+ $setup(A, posedge CLK &&& !IS_CLK_INVERTED, \A.required () );
+ $setup(A, negedge CLK &&& IS_CLK_INVERTED, \A.required () );
+ endspecify
+
+ if (PREG == 0 && MREG == 0 && BREG == 0)
+ specify
+ (B *> P) = \B.P.comb ();
+ (B *> PCOUT) = \B.PCOUT.comb ();
+ endspecify
+ else
+ specify
+ $setup(B, posedge CLK &&& !IS_CLK_INVERTED, \B.required () );
+ $setup(B, negedge CLK &&& IS_CLK_INVERTED, \B.required () );
+ endspecify
+
+ if (PREG == 0 && CREG == 0)
+ specify
+ (C *> P) = \C.P.comb ();
+ (C *> PCOUT) = \C.PCOUT.comb ();
+ endspecify
+ else
+ specify
+ $setup(C, posedge CLK &&& !IS_CLK_INVERTED, \C.required () );
+ $setup(C, negedge CLK &&& IS_CLK_INVERTED, \C.required () );
+ endspecify
+
+ if (PREG == 0 && MREG == 0 && ADREG == 0 && DREG == 0)
+ specify
+ (D *> P) = \D.P.comb ();
+ (D *> PCOUT) = \D.PCOUT.comb ();
+ endspecify
+ else
+ specify
+ $setup(D, posedge CLK &&& !IS_CLK_INVERTED, \D.required () );
+ $setup(D, negedge CLK &&& IS_CLK_INVERTED, \D.required () );
+ endspecify
+
+ if (PREG == 0)
+ specify
+ (PCIN *> P) = 1107;
+ (PCIN *> PCOUT) = 1255;
+ endspecify
+ else
+ specify
+ $setup(PCIN, posedge CLK &&& !IS_CLK_INVERTED, USE_PATTERN_DETECT != "NO_PATDET" ? 1315 : 1025);
+ $setup(PCIN, negedge CLK &&& IS_CLK_INVERTED, USE_PATTERN_DETECT != "NO_PATDET" ? 1315 : 1025);
+ endspecify
+
+ if (PREG || AREG || ADREG || BREG || CREG || DREG || MREG)
+ specify
+ if (!IS_CLK_INVERTED && CEP) (posedge CLK => (P : 48'bx)) = \P.arrival () ;
+ if ( IS_CLK_INVERTED && CEP) (negedge CLK => (P : 48'bx)) = \P.arrival () ;
+ if (!IS_CLK_INVERTED && CEP) (posedge CLK => (PCOUT : 48'bx)) = \PCOUT.arrival () ;
+ if ( IS_CLK_INVERTED && CEP) (negedge CLK => (PCOUT : 48'bx)) = \PCOUT.arrival () ;
+ endspecify
+ endgenerate
`endif
initial begin
@@ -3163,3 +3678,448 @@ module DSP48E1 (
endmodule
// TODO: DSP48E2 (Ultrascale).
+
+// Block RAM
+
+module RAMB18E1 (
+ (* clkbuf_sink *)
+ (* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
+ input CLKARDCLK,
+ (* clkbuf_sink *)
+ (* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
+ input CLKBWRCLK,
+ (* invertible_pin = "IS_ENARDEN_INVERTED" *)
+ input ENARDEN,
+ (* invertible_pin = "IS_ENBWREN_INVERTED" *)
+ input ENBWREN,
+ input REGCEAREGCE,
+ input REGCEB,
+ (* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
+ input RSTRAMARSTRAM,
+ (* invertible_pin = "IS_RSTRAMB_INVERTED" *)
+ input RSTRAMB,
+ (* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
+ input RSTREGARSTREG,
+ (* invertible_pin = "IS_RSTREGB_INVERTED" *)
+ input RSTREGB,
+ input [13:0] ADDRARDADDR,
+ input [13:0] ADDRBWRADDR,
+ input [15:0] DIADI,
+ input [15:0] DIBDI,
+ input [1:0] DIPADIP,
+ input [1:0] DIPBDIP,
+ input [1:0] WEA,
+ input [3:0] WEBWE,
+ output [15:0] DOADO,
+ output [15:0] DOBDO,
+ output [1:0] DOPADOP,
+ output [1:0] DOPBDOP
+);
+ parameter integer DOA_REG = 0;
+ parameter integer DOB_REG = 0;
+ parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_A = 18'h0;
+ parameter INIT_B = 18'h0;
+ parameter INIT_FILE = "NONE";
+ parameter RAM_MODE = "TDP";
+ parameter RDADDR_COLLISION_HWCONFIG = "DELAYED_WRITE";
+ parameter integer READ_WIDTH_A = 0;
+ parameter integer READ_WIDTH_B = 0;
+ parameter RSTREG_PRIORITY_A = "RSTREG";
+ parameter RSTREG_PRIORITY_B = "RSTREG";
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter SIM_DEVICE = "VIRTEX6";
+ parameter SRVAL_A = 18'h0;
+ parameter SRVAL_B = 18'h0;
+ parameter WRITE_MODE_A = "WRITE_FIRST";
+ parameter WRITE_MODE_B = "WRITE_FIRST";
+ parameter integer WRITE_WIDTH_A = 0;
+ parameter integer WRITE_WIDTH_B = 0;
+ parameter IS_CLKARDCLK_INVERTED = 1'b0;
+ parameter IS_CLKBWRCLK_INVERTED = 1'b0;
+ parameter IS_ENARDEN_INVERTED = 1'b0;
+ parameter IS_ENBWREN_INVERTED = 1'b0;
+ parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0;
+ parameter IS_RSTRAMB_INVERTED = 1'b0;
+ parameter IS_RSTREGARSTREG_INVERTED = 1'b0;
+ parameter IS_RSTREGB_INVERTED = 1'b0;
+
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L13
+ $setup(ADDRARDADDR, posedge CLKARDCLK, 566);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L17
+ $setup(ADDRBWRADDR, posedge CLKBWRCLK, 566);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L19
+ $setup(WEA, posedge CLKARDCLK, 532);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L21
+ $setup(WEBWE, posedge CLKBWRCLK, 532);
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L29
+ $setup(REGCEAREGCE, posedge CLKARDCLK, 360);
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L31
+ $setup(RSTREGARSTREG, posedge CLKARDCLK, 342);
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L49
+ $setup(REGCEB, posedge CLKBWRCLK, 360);
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L59
+ $setup(RSTREGB, posedge CLKBWRCLK, 342);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L123
+ $setup(DIADI, posedge CLKARDCLK, 737);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L133
+ $setup(DIBDI, posedge CLKBWRCLK, 737);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L125
+ $setup(DIPADIP, posedge CLKARDCLK, 737);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L135
+ $setup(DIPBDIP, posedge CLKBWRCLK, 737);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L143
+ if (&DOA_REG) (posedge CLKARDCLK => (DOADO : 16'bx)) = 2454;
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L144
+ if (&DOA_REG) (posedge CLKARDCLK => (DOPADOP : 2'bx)) = 2454;
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L153
+ if (|DOA_REG) (posedge CLKARDCLK => (DOADO : 16'bx)) = 882;
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L154
+ if (|DOA_REG) (posedge CLKARDCLK => (DOPADOP : 2'bx)) = 882;
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L163
+ if (&DOB_REG) (posedge CLKBWRCLK => (DOBDO : 16'bx)) = 2454;
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L164
+ if (&DOB_REG) (posedge CLKBWRCLK => (DOPBDOP : 2'bx)) = 2454;
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L173
+ if (|DOB_REG) (posedge CLKBWRCLK => (DOBDO : 16'bx)) = 882;
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L174
+ if (|DOB_REG) (posedge CLKBWRCLK => (DOPBDOP : 2'bx)) = 882;
+ endspecify
+endmodule
+
+module RAMB36E1 (
+ output CASCADEOUTA,
+ output CASCADEOUTB,
+ output [31:0] DOADO,
+ output [31:0] DOBDO,
+ output [3:0] DOPADOP,
+ output [3:0] DOPBDOP,
+ output [7:0] ECCPARITY,
+ output [8:0] RDADDRECC,
+ output SBITERR,
+ output DBITERR,
+ (* invertible_pin = "IS_ENARDEN_INVERTED" *)
+ input ENARDEN,
+ (* clkbuf_sink *)
+ (* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
+ input CLKARDCLK,
+ (* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
+ input RSTRAMARSTRAM,
+ (* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
+ input RSTREGARSTREG,
+ input CASCADEINA,
+ input REGCEAREGCE,
+ (* invertible_pin = "IS_ENBWREN_INVERTED" *)
+ input ENBWREN,
+ (* clkbuf_sink *)
+ (* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
+ input CLKBWRCLK,
+ (* invertible_pin = "IS_RSTRAMB_INVERTED" *)
+ input RSTRAMB,
+ (* invertible_pin = "IS_RSTREGB_INVERTED" *)
+ input RSTREGB,
+ input CASCADEINB,
+ input REGCEB,
+ input INJECTDBITERR,
+ input INJECTSBITERR,
+ input [15:0] ADDRARDADDR,
+ input [15:0] ADDRBWRADDR,
+ input [31:0] DIADI,
+ input [31:0] DIBDI,
+ input [3:0] DIPADIP,
+ input [3:0] DIPBDIP,
+ input [3:0] WEA,
+ input [7:0] WEBWE
+);
+ parameter integer DOA_REG = 0;
+ parameter integer DOB_REG = 0;
+ parameter EN_ECC_READ = "FALSE";
+ parameter EN_ECC_WRITE = "FALSE";
+ parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INITP_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_40 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_41 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_42 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_43 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_44 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_45 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_46 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_47 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_48 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_49 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_4F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_50 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_51 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_52 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_53 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_54 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_55 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_56 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_57 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_58 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_59 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_5F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_60 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_61 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_62 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_63 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_64 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_65 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_66 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_67 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_68 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_69 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_6F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_70 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_71 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_72 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_73 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_74 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_75 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_76 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_77 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_78 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_79 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_7F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
+ parameter INIT_A = 36'h0;
+ parameter INIT_B = 36'h0;
+ parameter INIT_FILE = "NONE";
+ parameter RAM_EXTENSION_A = "NONE";
+ parameter RAM_EXTENSION_B = "NONE";
+ parameter RAM_MODE = "TDP";
+ parameter RDADDR_COLLISION_HWCONFIG = "DELAYED_WRITE";
+ parameter integer READ_WIDTH_A = 0;
+ parameter integer READ_WIDTH_B = 0;
+ parameter RSTREG_PRIORITY_A = "RSTREG";
+ parameter RSTREG_PRIORITY_B = "RSTREG";
+ parameter SIM_COLLISION_CHECK = "ALL";
+ parameter SIM_DEVICE = "VIRTEX6";
+ parameter SRVAL_A = 36'h0;
+ parameter SRVAL_B = 36'h0;
+ parameter WRITE_MODE_A = "WRITE_FIRST";
+ parameter WRITE_MODE_B = "WRITE_FIRST";
+ parameter integer WRITE_WIDTH_A = 0;
+ parameter integer WRITE_WIDTH_B = 0;
+ parameter IS_CLKARDCLK_INVERTED = 1'b0;
+ parameter IS_CLKBWRCLK_INVERTED = 1'b0;
+ parameter IS_ENARDEN_INVERTED = 1'b0;
+ parameter IS_ENBWREN_INVERTED = 1'b0;
+ parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0;
+ parameter IS_RSTRAMB_INVERTED = 1'b0;
+ parameter IS_RSTREGARSTREG_INVERTED = 1'b0;
+ parameter IS_RSTREGB_INVERTED = 1'b0;
+
+ specify
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L13
+ $setup(ADDRARDADDR, posedge CLKARDCLK, 566);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L17
+ $setup(ADDRBWRADDR, posedge CLKBWRCLK, 566);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L19
+ $setup(WEA, posedge CLKARDCLK, 532);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L21
+ $setup(WEBWE, posedge CLKBWRCLK, 532);
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L29
+ $setup(REGCEAREGCE, posedge CLKARDCLK, 360);
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L31
+ $setup(RSTREGARSTREG, posedge CLKARDCLK, 342);
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L49
+ $setup(REGCEB, posedge CLKBWRCLK, 360);
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L59
+ $setup(RSTREGB, posedge CLKBWRCLK, 342);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L123
+ $setup(DIADI, posedge CLKARDCLK, 737);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L133
+ $setup(DIBDI, posedge CLKBWRCLK, 737);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L125
+ $setup(DIPADIP, posedge CLKARDCLK, 737);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L135
+ $setup(DIPBDIP, posedge CLKBWRCLK, 737);
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L143
+ if (&DOA_REG) (posedge CLKARDCLK => (DOADO : 32'bx)) = 2454;
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L144
+ if (&DOA_REG) (posedge CLKARDCLK => (DOPADOP : 4'bx)) = 2454;
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L153
+ if (|DOA_REG) (posedge CLKARDCLK => (DOADO : 32'bx)) = 882;
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L154
+ if (|DOA_REG) (posedge CLKARDCLK => (DOPADOP : 4'bx)) = 882;
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L163
+ if (&DOB_REG) (posedge CLKBWRCLK => (DOBDO : 32'bx)) = 2454;
+ // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L164
+ if (&DOB_REG) (posedge CLKBWRCLK => (DOPBDOP : 4'bx)) = 2454;
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L173
+ if (|DOB_REG) (posedge CLKBWRCLK => (DOBDO : 32'bx)) = 882;
+ // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L174
+ if (|DOB_REG) (posedge CLKBWRCLK => (DOPBDOP : 4'bx)) = 882;
+ endspecify
+endmodule
+
diff --git a/techlibs/xilinx/cells_xtra.py b/techlibs/xilinx/cells_xtra.py
index 75646f594..f086291ab 100644
--- a/techlibs/xilinx/cells_xtra.py
+++ b/techlibs/xilinx/cells_xtra.py
@@ -144,23 +144,9 @@ CELLS = [
Cell('RAMB16BWE_S36_S18', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
Cell('RAMB16BWE_S36_S36', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
# Spartan 3A DSP.
- Cell('RAMB16BWER', port_attrs={
- 'CLKA': ['clkbuf_sink'],
- 'CLKB': ['clkbuf_sink'],
- #'DOA': ['abc9_arrival=<TODO>'],
- #'DOB': ['abc9_arrival=<TODO>'],
- #'DOPA': ['abc9_arrival=<TODO>'],
- #'DOPB': ['abc9_arrival=<TODO>'],
- }),
+ Cell('RAMB16BWER', port_attrs={ 'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
# Spartan 6 (in addition to above).
- Cell('RAMB8BWER', port_attrs={
- 'CLKAWRCLK': ['clkbuf_sink'],
- 'CLKBRDCLK': ['clkbuf_sink'],
- #'DOADO': ['abc9_arrival=<TODO>'],
- #'DOBDO': ['abc9_arrival=<TODO>'],
- #'DOPADOP': ['abc9_arrival=<TODO>'],
- #'DOPBDOP': ['abc9_arrival=<TODO>'],
- }),
+ Cell('RAMB8BWER', port_attrs={ 'CLKAWRCLK': ['clkbuf_sink'], 'CLKBRDCLK': ['clkbuf_sink']}),
# Virtex 4.
Cell('FIFO16', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
Cell('RAMB16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
@@ -177,62 +163,8 @@ CELLS = [
# Virtex 6 / Series 7.
Cell('FIFO18E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
Cell('FIFO36E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
- Cell('RAMB18E1', port_attrs={
- 'CLKARDCLK': ['clkbuf_sink'],
- 'CLKBWRCLK': ['clkbuf_sink'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L143
- 'DOADO': ['abc9_arrival=2454'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L163
- 'DOBDO': ['abc9_arrival=2454'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L144
- 'DOPADOP': ['abc9_arrival=2454'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L164
- 'DOPBDOP': ['abc9_arrival=2454'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L13
- 'ADDRARDADDR': ['abc9_required=566'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L17
- 'ADDRBWRADDR': ['abc9_required=566'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L19
- 'WEA': ['abc9_required=532'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L21
- 'WEBWE': ['abc9_required=532'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L123
- 'DIADI': ['abc9_required=737'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L133
- 'DIBDI': ['abc9_required=737'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L125
- 'DIPADIP': ['abc9_required=737'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L135
- 'DIPBDIP': ['abc9_required=737'],
- }),
- Cell('RAMB36E1', port_attrs={
- 'CLKARDCLK': ['clkbuf_sink'],
- 'CLKBWRCLK': ['clkbuf_sink'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L143
- 'DOADO': ['abc9_arrival=2454'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L163
- 'DOBDO': ['abc9_arrival=2454'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L144
- 'DOPADOP': ['abc9_arrival=2454'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L164
- 'DOPBDOP': ['abc9_arrival=2454'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L13
- 'ADDRARDADDR': ['abc9_required=566'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L17
- 'ADDRBWRADDR': ['abc9_required=566'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L19
- 'WEA': ['abc9_required=532'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L21
- 'WEBWE': ['abc9_required=532'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L123
- 'DIADI': ['abc9_required=737'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L133
- 'DIBDI': ['abc9_required=737'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L125
- 'DIPADIP': ['abc9_required=737'],
- # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L135
- 'DIPBDIP': ['abc9_required=737'],
- }),
+ #Cell('RAMB18E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']]}),
+ #Cell('RAMB36E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']]}),
# Ultrascale.
Cell('FIFO18E2', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
Cell('FIFO36E2', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
@@ -370,13 +302,13 @@ CELLS = [
Cell('IOBUF_DCIEN', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUF_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUFE3', port_attrs={'IO': ['iopad_external_pin']}),
- Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
+ Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_DIFF_OUT', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_DIFF_OUT_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
- Cell('IOBUFDSE3', port_attrs={'IO': ['iopad_external_pin']}),
+ Cell('IOBUFDSE3', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
# Output.
# Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v
index e87f4ec76..3021f6b5a 100644
--- a/techlibs/xilinx/cells_xtra.v
+++ b/techlibs/xilinx/cells_xtra.v
@@ -4390,384 +4390,6 @@ module FIFO36E1 (...);
input WREN;
endmodule
-module RAMB18E1 (...);
- parameter integer DOA_REG = 0;
- parameter integer DOB_REG = 0;
- parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_A = 18'h0;
- parameter INIT_B = 18'h0;
- parameter INIT_FILE = "NONE";
- parameter RAM_MODE = "TDP";
- parameter RDADDR_COLLISION_HWCONFIG = "DELAYED_WRITE";
- parameter integer READ_WIDTH_A = 0;
- parameter integer READ_WIDTH_B = 0;
- parameter RSTREG_PRIORITY_A = "RSTREG";
- parameter RSTREG_PRIORITY_B = "RSTREG";
- parameter SIM_COLLISION_CHECK = "ALL";
- parameter SIM_DEVICE = "VIRTEX6";
- parameter SRVAL_A = 18'h0;
- parameter SRVAL_B = 18'h0;
- parameter WRITE_MODE_A = "WRITE_FIRST";
- parameter WRITE_MODE_B = "WRITE_FIRST";
- parameter integer WRITE_WIDTH_A = 0;
- parameter integer WRITE_WIDTH_B = 0;
- parameter IS_CLKARDCLK_INVERTED = 1'b0;
- parameter IS_CLKBWRCLK_INVERTED = 1'b0;
- parameter IS_ENARDEN_INVERTED = 1'b0;
- parameter IS_ENBWREN_INVERTED = 1'b0;
- parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0;
- parameter IS_RSTRAMB_INVERTED = 1'b0;
- parameter IS_RSTREGARSTREG_INVERTED = 1'b0;
- parameter IS_RSTREGB_INVERTED = 1'b0;
- (* abc9_arrival=2454 *)
- output [15:0] DOADO;
- (* abc9_arrival=2454 *)
- output [15:0] DOBDO;
- (* abc9_arrival=2454 *)
- output [1:0] DOPADOP;
- (* abc9_arrival=2454 *)
- output [1:0] DOPBDOP;
- (* clkbuf_sink *)
- (* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
- input CLKARDCLK;
- (* clkbuf_sink *)
- (* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
- input CLKBWRCLK;
- (* invertible_pin = "IS_ENARDEN_INVERTED" *)
- input ENARDEN;
- (* invertible_pin = "IS_ENBWREN_INVERTED" *)
- input ENBWREN;
- input REGCEAREGCE;
- input REGCEB;
- (* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
- input RSTRAMARSTRAM;
- (* invertible_pin = "IS_RSTRAMB_INVERTED" *)
- input RSTRAMB;
- (* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
- input RSTREGARSTREG;
- (* invertible_pin = "IS_RSTREGB_INVERTED" *)
- input RSTREGB;
- (* abc9_required=566 *)
- input [13:0] ADDRARDADDR;
- (* abc9_required=566 *)
- input [13:0] ADDRBWRADDR;
- (* abc9_required=737 *)
- input [15:0] DIADI;
- (* abc9_required=737 *)
- input [15:0] DIBDI;
- (* abc9_required=737 *)
- input [1:0] DIPADIP;
- (* abc9_required=737 *)
- input [1:0] DIPBDIP;
- (* abc9_required=532 *)
- input [1:0] WEA;
- (* abc9_required=532 *)
- input [3:0] WEBWE;
-endmodule
-
-module RAMB36E1 (...);
- parameter integer DOA_REG = 0;
- parameter integer DOB_REG = 0;
- parameter EN_ECC_READ = "FALSE";
- parameter EN_ECC_WRITE = "FALSE";
- parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INITP_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_40 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_41 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_42 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_43 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_44 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_45 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_46 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_47 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_48 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_49 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_4A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_4B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_4C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_4D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_4E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_4F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_50 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_51 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_52 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_53 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_54 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_55 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_56 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_57 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_58 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_59 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_5A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_5B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_5C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_5D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_5E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_5F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_60 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_61 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_62 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_63 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_64 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_65 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_66 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_67 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_68 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_69 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_6A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_6B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_6C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_6D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_6E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_6F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_70 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_71 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_72 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_73 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_74 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_75 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_76 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_77 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_78 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_79 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_7A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_7B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_7C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_7D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_7E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_7F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
- parameter INIT_A = 36'h0;
- parameter INIT_B = 36'h0;
- parameter INIT_FILE = "NONE";
- parameter RAM_EXTENSION_A = "NONE";
- parameter RAM_EXTENSION_B = "NONE";
- parameter RAM_MODE = "TDP";
- parameter RDADDR_COLLISION_HWCONFIG = "DELAYED_WRITE";
- parameter integer READ_WIDTH_A = 0;
- parameter integer READ_WIDTH_B = 0;
- parameter RSTREG_PRIORITY_A = "RSTREG";
- parameter RSTREG_PRIORITY_B = "RSTREG";
- parameter SIM_COLLISION_CHECK = "ALL";
- parameter SIM_DEVICE = "VIRTEX6";
- parameter SRVAL_A = 36'h0;
- parameter SRVAL_B = 36'h0;
- parameter WRITE_MODE_A = "WRITE_FIRST";
- parameter WRITE_MODE_B = "WRITE_FIRST";
- parameter integer WRITE_WIDTH_A = 0;
- parameter integer WRITE_WIDTH_B = 0;
- parameter IS_CLKARDCLK_INVERTED = 1'b0;
- parameter IS_CLKBWRCLK_INVERTED = 1'b0;
- parameter IS_ENARDEN_INVERTED = 1'b0;
- parameter IS_ENBWREN_INVERTED = 1'b0;
- parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0;
- parameter IS_RSTRAMB_INVERTED = 1'b0;
- parameter IS_RSTREGARSTREG_INVERTED = 1'b0;
- parameter IS_RSTREGB_INVERTED = 1'b0;
- output CASCADEOUTA;
- output CASCADEOUTB;
- (* abc9_arrival=2454 *)
- output [31:0] DOADO;
- (* abc9_arrival=2454 *)
- output [31:0] DOBDO;
- (* abc9_arrival=2454 *)
- output [3:0] DOPADOP;
- (* abc9_arrival=2454 *)
- output [3:0] DOPBDOP;
- output [7:0] ECCPARITY;
- output [8:0] RDADDRECC;
- output SBITERR;
- output DBITERR;
- (* invertible_pin = "IS_ENARDEN_INVERTED" *)
- input ENARDEN;
- (* clkbuf_sink *)
- (* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
- input CLKARDCLK;
- (* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
- input RSTRAMARSTRAM;
- (* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
- input RSTREGARSTREG;
- input CASCADEINA;
- input REGCEAREGCE;
- (* invertible_pin = "IS_ENBWREN_INVERTED" *)
- input ENBWREN;
- (* clkbuf_sink *)
- (* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
- input CLKBWRCLK;
- (* invertible_pin = "IS_RSTRAMB_INVERTED" *)
- input RSTRAMB;
- (* invertible_pin = "IS_RSTREGB_INVERTED" *)
- input RSTREGB;
- input CASCADEINB;
- input REGCEB;
- input INJECTDBITERR;
- input INJECTSBITERR;
- (* abc9_required=566 *)
- input [15:0] ADDRARDADDR;
- (* abc9_required=566 *)
- input [15:0] ADDRBWRADDR;
- (* abc9_required=737 *)
- input [31:0] DIADI;
- (* abc9_required=737 *)
- input [31:0] DIBDI;
- (* abc9_required=737 *)
- input [3:0] DIPADIP;
- (* abc9_required=737 *)
- input [3:0] DIPBDIP;
- (* abc9_required=532 *)
- input [3:0] WEA;
- (* abc9_required=532 *)
- input [7:0] WEBWE;
-endmodule
-
module FIFO18E2 (...);
parameter CASCADE_ORDER = "NONE";
parameter CLOCK_DOMAINS = "INDEPENDENT";
@@ -7450,6 +7072,7 @@ module IOBUFDS (...);
output O;
(* iopad_external_pin *)
inout IO;
+ (* iopad_external_pin *)
inout IOB;
input I;
input T;
@@ -7559,6 +7182,7 @@ module IOBUFDSE3 (...);
output O;
(* iopad_external_pin *)
inout IO;
+ (* iopad_external_pin *)
inout IOB;
input DCITERMDISABLE;
input I;
diff --git a/techlibs/xilinx/lut4_lutrams.txt b/techlibs/xilinx/lut4_lutrams.txt
new file mode 100644
index 000000000..2b344a9ee
--- /dev/null
+++ b/techlibs/xilinx/lut4_lutrams.txt
@@ -0,0 +1,19 @@
+bram $__XILINX_RAM16X1D
+ init 1
+ abits 4
+ dbits 1
+ groups 2
+ ports 1 1
+ wrmode 0 1
+ enable 0 1
+ transp 0 0
+ clocks 0 1
+ clkpol 0 2
+endbram
+
+
+match $__XILINX_RAM16X1D
+ min bits 2
+ min wports 1
+ make_outreg
+endmatch
diff --git a/techlibs/xilinx/lutrams.txt b/techlibs/xilinx/lut6_lutrams.txt
index faf66bc18..3b3cb81e1 100644
--- a/techlibs/xilinx/lutrams.txt
+++ b/techlibs/xilinx/lut6_lutrams.txt
@@ -1,17 +1,3 @@
-
-bram $__XILINX_RAM16X1D
- init 1
- abits 4
- dbits 1
- groups 2
- ports 1 1
- wrmode 0 1
- enable 0 1
- transp 0 0
- clocks 0 1
- clkpol 0 2
-endbram
-
bram $__XILINX_RAM32X1D
init 1
abits 5
@@ -105,16 +91,6 @@ bram $__XILINX_RAM64X1Q
endbram
-# Disabled for now, pending support for LUT4 arches
-# since on LUT6 arches this occupies same area as
-# a RAM32X1D
-#match $__XILINX_RAM16X1D
-# min bits 2
-# min wports 1
-# make_outreg
-# or_next_if_better
-#endmatch
-
match $__XILINX_RAM32X1D
min bits 3
min wports 1
diff --git a/techlibs/xilinx/lut_map.v b/techlibs/xilinx/lut_map.v
index 718ec42f1..ec2e3b234 100644
--- a/techlibs/xilinx/lut_map.v
+++ b/techlibs/xilinx/lut_map.v
@@ -51,43 +51,45 @@ module \$lut (A, Y);
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]));
end else
- if (WIDTH == 5) begin
+ if (WIDTH == 5 && WIDTH <= `LUT_WIDTH) begin
LUT5 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]), .I4(A[4]));
end else
- if (WIDTH == 6) begin
+ if (WIDTH == 6 && WIDTH <= `LUT_WIDTH) begin
LUT6 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]), .I4(A[4]), .I5(A[5]));
end else
+ if (WIDTH == 5 && WIDTH > `LUT_WIDTH) begin
+ wire f0, f1;
+ \$lut #(.LUT(LUT[15: 0]), .WIDTH(4)) lut0 (.A(A[3:0]), .Y(f0));
+ \$lut #(.LUT(LUT[31:16]), .WIDTH(4)) lut1 (.A(A[3:0]), .Y(f1));
+ MUXF5 mux5(.I0(f0), .I1(f1), .S(A[4]), .O(Y));
+ end else
+ if (WIDTH == 6 && WIDTH > `LUT_WIDTH) begin
+ wire f0, f1;
+ \$lut #(.LUT(LUT[31: 0]), .WIDTH(5)) lut0 (.A(A[4:0]), .Y(f0));
+ \$lut #(.LUT(LUT[63:32]), .WIDTH(5)) lut1 (.A(A[4:0]), .Y(f1));
+ MUXF6 mux6(.I0(f0), .I1(f1), .S(A[5]), .O(Y));
+ end else
if (WIDTH == 7) begin
- wire T0, T1;
- LUT6 #(.INIT(LUT[63:0])) fpga_lut_0 (.O(T0),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- LUT6 #(.INIT(LUT[127:64])) fpga_lut_1 (.O(T1),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- MUXF7 fpga_mux_0 (.O(Y), .I0(T0), .I1(T1), .S(A[6]));
+ wire f0, f1;
+ \$lut #(.LUT(LUT[ 63: 0]), .WIDTH(6)) lut0 (.A(A[5:0]), .Y(f0));
+ \$lut #(.LUT(LUT[127:64]), .WIDTH(6)) lut1 (.A(A[5:0]), .Y(f1));
+ MUXF7 mux7(.I0(f0), .I1(f1), .S(A[6]), .O(Y));
end else
if (WIDTH == 8) begin
- wire T0, T1, T2, T3, T4, T5;
- LUT6 #(.INIT(LUT[63:0])) fpga_lut_0 (.O(T0),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- LUT6 #(.INIT(LUT[127:64])) fpga_lut_1 (.O(T1),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- LUT6 #(.INIT(LUT[191:128])) fpga_lut_2 (.O(T2),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- LUT6 #(.INIT(LUT[255:192])) fpga_lut_3 (.O(T3),
- .I0(A[0]), .I1(A[1]), .I2(A[2]),
- .I3(A[3]), .I4(A[4]), .I5(A[5]));
- MUXF7 fpga_mux_0 (.O(T4), .I0(T0), .I1(T1), .S(A[6]));
- MUXF7 fpga_mux_1 (.O(T5), .I0(T2), .I1(T3), .S(A[6]));
- MUXF8 fpga_mux_2 (.O(Y), .I0(T4), .I1(T5), .S(A[7]));
+ wire f0, f1;
+ \$lut #(.LUT(LUT[127: 0]), .WIDTH(7)) lut0 (.A(A[6:0]), .Y(f0));
+ \$lut #(.LUT(LUT[255:128]), .WIDTH(7)) lut1 (.A(A[6:0]), .Y(f1));
+ MUXF8 mux8(.I0(f0), .I1(f1), .S(A[7]), .O(Y));
+ end else
+ if (WIDTH == 9) begin
+ wire f0, f1;
+ \$lut #(.LUT(LUT[255: 0]), .WIDTH(8)) lut0 (.A(A[7:0]), .Y(f0));
+ \$lut #(.LUT(LUT[511:256]), .WIDTH(8)) lut1 (.A(A[7:0]), .Y(f1));
+ MUXF9 mux9(.I0(f0), .I1(f1), .S(A[8]), .O(Y));
end else begin
wire _TECHMAP_FAIL_ = 1;
end
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index 5a28bb139..8553efd6b 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -49,10 +49,25 @@ struct SynthXilinxPass : public ScriptPass
log(" -top <module>\n");
log(" use the specified module as top module\n");
log("\n");
- log(" -family {xcup|xcu|xc7|xc6v|xc5v|xc6s}\n");
+ log(" -family <family>\n");
log(" run synthesis for the specified Xilinx architecture\n");
log(" generate the synthesis netlist for the specified family.\n");
- log(" default: xc7\n");
+ log(" supported values:\n");
+ log(" - xcup: Ultrascale Plus\n");
+ log(" - xcu: Ultrascale\n");
+ log(" - xc7: Series 7 (default)\n");
+ log(" - xc6s: Spartan 6\n");
+ log(" - xc6v: Virtex 6\n");
+ log(" - xc5v: Virtex 5 (EXPERIMENTAL)\n");
+ log(" - xc4v: Virtex 4 (EXPERIMENTAL)\n");
+ log(" - xc3sda: Spartan 3A DSP (EXPERIMENTAL)\n");
+ log(" - xc3sa: Spartan 3A (EXPERIMENTAL)\n");
+ log(" - xc3se: Spartan 3E (EXPERIMENTAL)\n");
+ log(" - xc3s: Spartan 3 (EXPERIMENTAL)\n");
+ log(" - xc2vp: Virtex 2 Pro (EXPERIMENTAL)\n");
+ log(" - xc2v: Virtex 2 (EXPERIMENTAL)\n");
+ log(" - xcve: Virtex E, Spartan 2E (EXPERIMENTAL)\n");
+ log(" - xcv: Virtex, Spartan 2 (EXPERIMENTAL)\n");
log("\n");
log(" -edif <file>\n");
log(" write the design to the specified edif file. writing of an output file\n");
@@ -82,10 +97,10 @@ struct SynthXilinxPass : public ScriptPass
log(" do not use XORCY/MUXCY/CARRY4 cells in output netlist\n");
log("\n");
log(" -nowidelut\n");
- log(" do not use MUXF[78] resources to implement LUTs larger than LUT6s\n");
+ log(" do not use MUXF[5-9] resources to implement LUTs larger than native for the target\n");
log("\n");
log(" -nodsp\n");
- log(" do not use DSP48E1s to implement multipliers and associated logic\n");
+ log(" do not use DSP48*s to implement multipliers and associated logic\n");
log("\n");
log(" -noiopad\n");
log(" disable I/O buffer insertion (useful for hierarchical or \n");
@@ -131,6 +146,8 @@ struct SynthXilinxPass : public ScriptPass
bool abc9, dff_mode;
bool flatten_before_abc;
int widemux;
+ int lut_size;
+ int widelut_size;
void clear_flags() YS_OVERRIDE
{
@@ -156,6 +173,7 @@ struct SynthXilinxPass : public ScriptPass
dff_mode = false;
flatten_before_abc = false;
widemux = 0;
+ lut_size = 6;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -270,9 +288,38 @@ struct SynthXilinxPass : public ScriptPass
}
extra_args(args, argidx, design);
- if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6v" && family != "xc5v" && family != "xc6s")
+ if (family == "xcup" || family == "xcu") {
+ lut_size = 6;
+ widelut_size = 9;
+ } else if (family == "xc7" ||
+ family == "xc6v" ||
+ family == "xc5v" ||
+ family == "xc6s") {
+ lut_size = 6;
+ widelut_size = 8;
+ } else if (family == "xc4v" ||
+ family == "xc3sda" ||
+ family == "xc3sa" ||
+ family == "xc3se" ||
+ family == "xc3s" ||
+ family == "xc2vp" ||
+ family == "xc2v") {
+ lut_size = 4;
+ widelut_size = 8;
+ } else if (family == "xcve" || family == "xcv") {
+ lut_size = 4;
+ widelut_size = 6;
+ } else
log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family.c_str());
+ if (widemux != 0 && lut_size != 6)
+ log_cmd_error("-widemux is not currently supported for LUT4-based architectures.\n");
+
+ if (lut_size != 6) {
+ log_warning("Shift register inference not yet supported for family %s.\n", family.c_str());
+ nosrl = true;
+ }
+
if (widemux != 0 && widemux < 2)
log_cmd_error("-widemux value must be 0 or >= 2.\n");
@@ -292,6 +339,9 @@ struct SynthXilinxPass : public ScriptPass
void script() YS_OVERRIDE
{
+ std::string lut_size_s = std::to_string(lut_size);
+ if (help_mode)
+ lut_size_s = "[46]";
std::string ff_map_file;
if (help_mode)
ff_map_file = "+/xilinx/{family}_ff_map.v";
@@ -304,7 +354,7 @@ struct SynthXilinxPass : public ScriptPass
std::string read_args;
if (vpr)
read_args += " -D_EXPLICIT_CARRY";
- read_args += " -lib +/xilinx/cells_sim.v";
+ read_args += " -lib -specify +/xilinx/cells_sim.v";
run("read_verilog" + read_args);
run("read_verilog -lib +/xilinx/cells_xtra.v");
@@ -344,7 +394,7 @@ struct SynthXilinxPass : public ScriptPass
run("clean", " (skip if '-nosrl' and '-widemux=0')");
}
- run("techmap -map +/cmp2lut.v -D LUT_WIDTH=6");
+ run("techmap -map +/cmp2lut.v -D LUT_WIDTH=" + lut_size_s);
}
if (check_label("map_dsp", "(skip if '-nodsp')")) {
@@ -353,7 +403,7 @@ struct SynthXilinxPass : public ScriptPass
// NB: Xilinx multipliers are signed only
if (help_mode)
run("techmap -map +/mul2dsp.v -map +/xilinx/{family}_dsp_map.v {options}");
- else if (family == "xc2v" || family == "xc3s" || family == "xc3se" || family == "xc3sa")
+ else if (family == "xc2v" || family == "xc2vp" || family == "xc3s" || family == "xc3se" || family == "xc3sa")
run("techmap -map +/mul2dsp.v -map +/xilinx/xc3s_mult_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
@@ -438,7 +488,19 @@ struct SynthXilinxPass : public ScriptPass
run("memory_bram -rules +/xilinx/{family}_brams.txt");
run("techmap -map +/xilinx/{family}_brams_map.v");
} else if (!nobram) {
- if (family == "xc6s") {
+ if (family == "xc2v" || family == "xc2vp" || family == "xc3s" || family == "xc3se") {
+ run("memory_bram -rules +/xilinx/xc2v_brams.txt");
+ run("techmap -map +/xilinx/xc2v_brams_map.v");
+ } else if (family == "xc3sa") {
+ // Superset of Virtex 2 primitives — uses common map file.
+ run("memory_bram -rules +/xilinx/xc3sa_brams.txt");
+ run("techmap -map +/xilinx/xc2v_brams_map.v");
+ } else if (family == "xc3sda") {
+ // Supported block RAMs for Spartan 3A DSP are
+ // a subset of Spartan 6's ones.
+ run("memory_bram -rules +/xilinx/xc3sda_brams.txt");
+ run("techmap -map +/xilinx/xc6s_brams_map.v");
+ } else if (family == "xc6s") {
run("memory_bram -rules +/xilinx/xc6s_brams.txt");
run("techmap -map +/xilinx/xc6s_brams_map.v");
} else if (family == "xc6v" || family == "xc7") {
@@ -455,7 +517,7 @@ struct SynthXilinxPass : public ScriptPass
if (check_label("map_lutram", "(skip if '-nolutram')")) {
if (!nolutram || help_mode) {
- run("memory_bram -rules +/xilinx/lutrams.txt");
+ run("memory_bram -rules +/xilinx/lut" + lut_size_s + "_lutrams.txt");
run("techmap -map +/xilinx/lutrams_map.v");
}
}
@@ -481,9 +543,8 @@ struct SynthXilinxPass : public ScriptPass
if (check_label("fine")) {
run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
- if (help_mode) {
- run("muxcover <internal options>, ('-widemux' only)");
- }
+ if (help_mode)
+ run("muxcover <internal options> ('-widemux' only)");
else if (widemux > 0) {
constexpr int cost_mux2 = 100;
std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2);
@@ -511,14 +572,12 @@ struct SynthXilinxPass : public ScriptPass
if (!nosrl || help_mode)
run("xilinx_srl -variable -minlen 3", "(skip if '-nosrl')");
- std::string techmap_args = " -map +/techmap.v";
+ std::string techmap_args = " -map +/techmap.v -D LUT_SIZE=" + lut_size_s;
if (help_mode)
techmap_args += " [-map +/xilinx/mux_map.v]";
else if (widemux > 0)
techmap_args += stringf(" -D MIN_MUX_INPUTS=%d -map +/xilinx/mux_map.v", widemux);
- if (help_mode)
- techmap_args += " [-map +/xilinx/arith_map.v]";
- else if (!nocarry) {
+ if (!nocarry) {
techmap_args += " -map +/xilinx/arith_map.v";
if (vpr)
techmap_args += " -D _EXPLICIT_CARRY";
@@ -551,6 +610,8 @@ struct SynthXilinxPass : public ScriptPass
if (help_mode)
run("abc -luts 2:2,3,6:5[,10,20] [-dff] [-D 1]", "(option for 'nowidelut', '-dff', '-retime')");
else if (abc9) {
+ if (lut_size != 6)
+ log_error("'synth_xilinx -abc9' not currently supported for LUT4-based devices.\n");
if (family != "xc7")
log_warning("'synth_xilinx -abc9' not currently supported for the '%s' family, "
"will use timing for 'xc7' instead.\n", family.c_str());
@@ -558,17 +619,15 @@ struct SynthXilinxPass : public ScriptPass
if (dff_mode)
techmap_args += " -D DFF_MODE";
run("techmap " + techmap_args);
- run("read_verilog -icells -lib +/xilinx/abc9_model.v");
- std::string abc9_opts = " -box +/xilinx/abc9_xc7.box";
+ run("read_verilog -icells -lib -specify +/abc9_model.v +/xilinx/abc9_model.v");
+ std::string abc9_opts;
auto k = stringf("synth_xilinx.abc9.%s.W", family.c_str());
if (active_design->scratchpad.count(k))
abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str());
else
abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k, RTLIL::constpad.at("synth_xilinx.abc9.xc7.W")).c_str());
if (nowidelut)
- abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut";
- else
- abc9_opts += " -lut +/xilinx/abc9_xc7.lut";
+ abc9_opts += stringf(" -maxlut %d", lut_size);
if (dff_mode)
abc9_opts += " -dff";
run("abc9" + abc9_opts);
@@ -576,10 +635,19 @@ struct SynthXilinxPass : public ScriptPass
}
else {
std::string abc_opts;
- if (nowidelut)
- abc_opts += " -luts 2:2,3,6:5";
- else
- abc_opts += " -luts 2:2,3,6:5,10,20";
+ if (lut_size != 6) {
+ if (nowidelut)
+ abc_opts += " -lut " + lut_size_s;
+ else
+ abc_opts += " -lut " + lut_size_s + ":" + std::to_string(widelut_size);
+ } else {
+ if (nowidelut)
+ abc_opts += " -luts 2:2,3,6:5";
+ else if (widelut_size == 8)
+ abc_opts += " -luts 2:2,3,6:5,10,20";
+ else
+ abc_opts += " -luts 2:2,3,6:5,10,20,40";
+ }
if (dff_mode)
abc_opts += " -dff";
if (retime)
@@ -595,8 +663,14 @@ struct SynthXilinxPass : public ScriptPass
std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/cells_map.v";
if (help_mode || !abc9)
techmap_args += stringf(" -map %s", ff_map_file.c_str());
+ techmap_args += " -D LUT_WIDTH=" + lut_size_s;
run("techmap " + techmap_args);
- run("xilinx_dffopt");
+ if (help_mode)
+ run("xilinx_dffopt [-lut4]");
+ else if (lut_size == 4)
+ run("xilinx_dffopt -lut4");
+ else
+ run("xilinx_dffopt");
run("opt_lut_ins -tech xilinx");
}
diff --git a/techlibs/xilinx/xc2v_brams.txt b/techlibs/xilinx/xc2v_brams.txt
new file mode 100644
index 000000000..ac8cfb552
--- /dev/null
+++ b/techlibs/xilinx/xc2v_brams.txt
@@ -0,0 +1,31 @@
+# Virtex 2, Virtex 2 Pro, Spartan 3, Spartan 3E block RAM rules.
+
+bram $__XILINX_RAMB16
+ init 1
+ abits 9 @a9d36
+ dbits 36 @a9d36
+ abits 10 @a10d18
+ dbits 18 @a10d18
+ abits 11 @a11d9
+ dbits 9 @a11d9
+ abits 12 @a12d4
+ dbits 4 @a12d4
+ abits 13 @a13d2
+ dbits 2 @a13d2
+ abits 14 @a14d1
+ dbits 1 @a14d1
+ groups 2
+ ports 1 1
+ wrmode 0 1
+ enable 1 1
+ transp 0 0
+ clocks 2 3
+ clkpol 2 3
+endbram
+
+match $__XILINX_RAMB16
+ min bits 4096
+ min efficiency 5
+ shuffle_enable B
+ make_transp
+endmatch
diff --git a/techlibs/xilinx/xc2v_brams_map.v b/techlibs/xilinx/xc2v_brams_map.v
new file mode 100644
index 000000000..dc698f956
--- /dev/null
+++ b/techlibs/xilinx/xc2v_brams_map.v
@@ -0,0 +1,266 @@
+// Virtex 2, Virtex 2 Pro, Spartan 3, Spartan 3E, Spartan 3A block RAM
+// mapping (Spartan 3A is a superset of the other four).
+
+// ------------------------------------------------------------------------
+
+module \$__XILINX_RAMB16 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+ parameter CFG_ABITS = 9;
+ parameter CFG_DBITS = 36;
+ parameter CFG_ENABLE_B = 1;
+
+ parameter CLKPOL2 = 1;
+ parameter CLKPOL3 = 1;
+ parameter [18431:0] INIT = 18432'bx;
+
+ input CLK2;
+ input CLK3;
+
+ input [CFG_ABITS-1:0] A1ADDR;
+ output [CFG_DBITS-1:0] A1DATA;
+ input A1EN;
+
+ input [CFG_ABITS-1:0] B1ADDR;
+ input [CFG_DBITS-1:0] B1DATA;
+ input [CFG_ENABLE_B-1:0] B1EN;
+
+ generate if (CFG_DBITS == 1) begin
+ wire DOB;
+ RAMB16_S1_S1 #(
+ `include "brams_init_16.vh"
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ ) _TECHMAP_REPLACE_ (
+ .DIA(1'd0),
+ .DOA(A1DATA),
+ .ADDRA(A1ADDR),
+ .CLKA(CLK2 ^ !CLKPOL2),
+ .ENA(A1EN),
+ .SSRA(|0),
+ .WEA(1'b0),
+
+ .DIB(B1DATA),
+ .DOB(DOB),
+ .ADDRB(B1ADDR),
+ .CLKB(CLK3 ^ !CLKPOL3),
+ .ENB(|1),
+ .SSRB(|0),
+ .WEB(B1EN)
+ );
+ end else if (CFG_DBITS == 2) begin
+ wire [1:0] DOB;
+ RAMB16_S2_S2 #(
+ `include "brams_init_16.vh"
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ ) _TECHMAP_REPLACE_ (
+ .DIA(2'd0),
+ .DOA(A1DATA),
+ .ADDRA(A1ADDR),
+ .CLKA(CLK2 ^ !CLKPOL2),
+ .ENA(A1EN),
+ .SSRA(|0),
+ .WEA(1'b0),
+
+ .DIB(B1DATA),
+ .DOB(DOB),
+ .ADDRB(B1ADDR),
+ .CLKB(CLK3 ^ !CLKPOL3),
+ .ENB(|1),
+ .SSRB(|0),
+ .WEB(B1EN)
+ );
+ end else if (CFG_DBITS == 4) begin
+ wire [3:0] DOB;
+ RAMB16_S4_S4 #(
+ `include "brams_init_16.vh"
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ ) _TECHMAP_REPLACE_ (
+ .DIA(4'd0),
+ .DOA(A1DATA),
+ .ADDRA(A1ADDR),
+ .CLKA(CLK2 ^ !CLKPOL2),
+ .ENA(A1EN),
+ .SSRA(|0),
+ .WEA(1'b0),
+
+ .DIB(B1DATA),
+ .DOB(DOB),
+ .ADDRB(B1ADDR),
+ .CLKB(CLK3 ^ !CLKPOL3),
+ .ENB(|1),
+ .SSRB(|0),
+ .WEB(B1EN)
+ );
+ end else if (CFG_DBITS == 9) begin
+ wire [7:0] DOB;
+ wire DOPB;
+ RAMB16_S9_S9 #(
+ `include "brams_init_18.vh"
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ ) _TECHMAP_REPLACE_ (
+ .DIA(8'd0),
+ .DIPA(1'd0),
+ .DOA(A1DATA[7:0]),
+ .DOPA(A1DATA[8]),
+ .ADDRA(A1ADDR),
+ .CLKA(CLK2 ^ !CLKPOL2),
+ .ENA(A1EN),
+ .SSRA(|0),
+ .WEA(1'b0),
+
+ .DIB(B1DATA[7:0]),
+ .DIPB(B1DATA[8]),
+ .DOB(DOB),
+ .DOPB(DOPB),
+ .ADDRB(B1ADDR),
+ .CLKB(CLK3 ^ !CLKPOL3),
+ .ENB(|1),
+ .SSRB(|0),
+ .WEB(B1EN)
+ );
+ end else if (CFG_DBITS == 18) begin
+ wire [15:0] DOB;
+ wire [1:0] DOPB;
+ RAMB16_S18_S18 #(
+ `include "brams_init_18.vh"
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ ) _TECHMAP_REPLACE_ (
+ .DIA(16'd0),
+ .DIPA(2'd0),
+ .DOA({A1DATA[16:9], A1DATA[7:0]}),
+ .DOPA({A1DATA[17], A1DATA[8]}),
+ .ADDRA(A1ADDR),
+ .CLKA(CLK2 ^ !CLKPOL2),
+ .ENA(A1EN),
+ .SSRA(|0),
+ .WEA(1'b0),
+
+ .DIB({B1DATA[16:9], B1DATA[7:0]}),
+ .DIPB({B1DATA[17], B1DATA[8]}),
+ .DOB(DOB),
+ .DOPB(DOPB),
+ .ADDRB(B1ADDR),
+ .CLKB(CLK3 ^ !CLKPOL3),
+ .ENB(|1),
+ .SSRB(|0),
+ .WEB(B1EN)
+ );
+ end else if (CFG_DBITS == 36) begin
+ wire [31:0] DOB;
+ wire [3:0] DOPB;
+ RAMB16_S36_S36 #(
+ `include "brams_init_18.vh"
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ ) _TECHMAP_REPLACE_ (
+ .DIA(32'd0),
+ .DIPA(4'd0),
+ .DOA({A1DATA[34:27], A1DATA[25:18], A1DATA[16:9], A1DATA[7:0]}),
+ .DOPA({A1DATA[35], A1DATA[26], A1DATA[17], A1DATA[8]}),
+ .ADDRA(A1ADDR),
+ .CLKA(CLK2 ^ !CLKPOL2),
+ .ENA(A1EN),
+ .SSRA(|0),
+ .WEA(1'b0),
+
+ .DIB({B1DATA[34:27], B1DATA[25:18], B1DATA[16:9], B1DATA[7:0]}),
+ .DIPB({B1DATA[35], B1DATA[26], B1DATA[17], B1DATA[8]}),
+ .DOB(DOB),
+ .DOPB(DOPB),
+ .ADDRB(B1ADDR),
+ .CLKB(CLK3 ^ !CLKPOL3),
+ .ENB(|1),
+ .SSRB(|0),
+ .WEB(B1EN)
+ );
+ end else begin
+ $error("Strange block RAM data width.");
+ end endgenerate
+endmodule
+
+
+// Version with separate byte enables, only available on Spartan 3A.
+
+module \$__XILINX_RAMB16BWE (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+ parameter CFG_ABITS = 9;
+ parameter CFG_DBITS = 36;
+ parameter CFG_ENABLE_B = 4;
+
+ parameter CLKPOL2 = 1;
+ parameter CLKPOL3 = 1;
+ parameter [18431:0] INIT = 18432'bx;
+
+ input CLK2;
+ input CLK3;
+
+ input [CFG_ABITS-1:0] A1ADDR;
+ output [CFG_DBITS-1:0] A1DATA;
+ input A1EN;
+
+ input [CFG_ABITS-1:0] B1ADDR;
+ input [CFG_DBITS-1:0] B1DATA;
+ input [CFG_ENABLE_B-1:0] B1EN;
+
+ generate if (CFG_DBITS == 18) begin
+ wire [15:0] DOB;
+ wire [1:0] DOPB;
+ RAMB16BWE_S18_S18 #(
+ `include "brams_init_18.vh"
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ ) _TECHMAP_REPLACE_ (
+ .DIA(16'd0),
+ .DIPA(2'd0),
+ .DOA({A1DATA[16:9], A1DATA[7:0]}),
+ .DOPA({A1DATA[17], A1DATA[8]}),
+ .ADDRA(A1ADDR),
+ .CLKA(CLK2 ^ !CLKPOL2),
+ .ENA(A1EN),
+ .SSRA(|0),
+ .WEA(2'b00),
+
+ .DIB({B1DATA[16:9], B1DATA[7:0]}),
+ .DIPB({B1DATA[17], B1DATA[8]}),
+ .DOB(DOB),
+ .DOPB(DOPB),
+ .ADDRB(B1ADDR),
+ .CLKB(CLK3 ^ !CLKPOL3),
+ .ENB(|1),
+ .SSRB(|0),
+ .WEB(B1EN)
+ );
+ end else if (CFG_DBITS == 36) begin
+ wire [31:0] DOB;
+ wire [3:0] DOPB;
+ RAMB16BWE_S36_S36 #(
+ `include "brams_init_18.vh"
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ ) _TECHMAP_REPLACE_ (
+ .DIA(32'd0),
+ .DIPA(4'd0),
+ .DOA({A1DATA[34:27], A1DATA[25:18], A1DATA[16:9], A1DATA[7:0]}),
+ .DOPA({A1DATA[35], A1DATA[26], A1DATA[17], A1DATA[8]}),
+ .ADDRA(A1ADDR),
+ .CLKA(CLK2 ^ !CLKPOL2),
+ .ENA(A1EN),
+ .SSRA(|0),
+ .WEA(4'b0000),
+
+ .DIB({B1DATA[34:27], B1DATA[25:18], B1DATA[16:9], B1DATA[7:0]}),
+ .DIPB({B1DATA[35], B1DATA[26], B1DATA[17], B1DATA[8]}),
+ .DOB(DOB),
+ .DOPB(DOPB),
+ .ADDRB(B1ADDR),
+ .CLKB(CLK3 ^ !CLKPOL3),
+ .ENB(|1),
+ .SSRB(|0),
+ .WEB(B1EN)
+ );
+ end else begin
+ $error("Strange block RAM data width.");
+ end endgenerate
+endmodule
diff --git a/techlibs/xilinx/xc3sa_brams.txt b/techlibs/xilinx/xc3sa_brams.txt
new file mode 100644
index 000000000..22a62bd2c
--- /dev/null
+++ b/techlibs/xilinx/xc3sa_brams.txt
@@ -0,0 +1,51 @@
+# Spartan 3A block RAM rules.
+
+bram $__XILINX_RAMB16
+ init 1
+ abits 11 @a11d9
+ dbits 9 @a11d9
+ abits 12 @a12d4
+ dbits 4 @a12d4
+ abits 13 @a13d2
+ dbits 2 @a13d2
+ abits 14 @a14d1
+ dbits 1 @a14d1
+ groups 2
+ ports 1 1
+ wrmode 0 1
+ enable 1 1
+ transp 0 0
+ clocks 2 3
+ clkpol 2 3
+endbram
+
+bram $__XILINX_RAMB16BWE
+ init 1
+ abits 9 @a9d36
+ dbits 36 @a9d36
+ abits 10 @a10d18
+ dbits 18 @a10d18
+ groups 2
+ ports 1 1
+ wrmode 0 1
+ enable 1 4 @a9d36
+ enable 1 2 @a10d18
+ transp 0 0
+ clocks 2 3
+ clkpol 2 3
+endbram
+
+match $__XILINX_RAMB16
+ min bits 4096
+ min efficiency 5
+ shuffle_enable B
+ make_transp
+ or_next_if_better
+endmatch
+
+match $__XILINX_RAMB16BWE
+ min bits 4096
+ min efficiency 5
+ shuffle_enable B
+ make_transp
+endmatch
diff --git a/techlibs/xilinx/xc3sda_brams.txt b/techlibs/xilinx/xc3sda_brams.txt
new file mode 100644
index 000000000..12c68ffd5
--- /dev/null
+++ b/techlibs/xilinx/xc3sda_brams.txt
@@ -0,0 +1,33 @@
+# Spartan 3A DSP block RAM rules.
+
+bram $__XILINX_RAMB16BWER_TDP
+ init 1
+ abits 9 @a9d36
+ dbits 36 @a9d36
+ abits 10 @a10d18
+ dbits 18 @a10d18
+ abits 11 @a11d9
+ dbits 9 @a11d9
+ abits 12 @a12d4
+ dbits 4 @a12d4
+ abits 13 @a13d2
+ dbits 2 @a13d2
+ abits 14 @a14d1
+ dbits 1 @a14d1
+ groups 2
+ ports 1 1
+ wrmode 0 1
+ enable 1 4 @a9d36
+ enable 1 2 @a10d18
+ enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
+ transp 0 0
+ clocks 2 3
+ clkpol 2 3
+endbram
+
+match $__XILINX_RAMB16BWER_TDP
+ min bits 4096
+ min efficiency 5
+ shuffle_enable B
+ make_transp
+endmatch
diff --git a/techlibs/xilinx/xc6s_brams.txt b/techlibs/xilinx/xc6s_brams.txt
index 17cd8e355..6457097db 100644
--- a/techlibs/xilinx/xc6s_brams.txt
+++ b/techlibs/xilinx/xc6s_brams.txt
@@ -1,3 +1,4 @@
+# Spartan 6 block RAM rules.
bram $__XILINX_RAMB8BWER_SDP
init 1
diff --git a/techlibs/xilinx/xc6s_brams_map.v b/techlibs/xilinx/xc6s_brams_map.v
index 16fd15e74..9577eebe4 100644
--- a/techlibs/xilinx/xc6s_brams_map.v
+++ b/techlibs/xilinx/xc6s_brams_map.v
@@ -1,3 +1,6 @@
+// Spartan 3A DSP and Spartan 6 block RAM mapping (Spartan 6 is a superset of
+// Spartan 3A DSP).
+
module \$__XILINX_RAMB8BWER_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter CLKPOL2 = 1;
parameter CLKPOL3 = 1;
diff --git a/techlibs/xilinx/xc7_brams_map.v b/techlibs/xilinx/xc7_brams_map.v
index 7ea49158d..2b6ad0da6 100644
--- a/techlibs/xilinx/xc7_brams_map.v
+++ b/techlibs/xilinx/xc7_brams_map.v
@@ -1,3 +1,5 @@
+// Virtex 6 and Series 7 block RAM mapping.
+
module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter CLKPOL2 = 1;
parameter CLKPOL3 = 1;
diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt
index c63218ae1..650367abf 100644
--- a/techlibs/xilinx/xc7_xcu_brams.txt
+++ b/techlibs/xilinx/xc7_xcu_brams.txt
@@ -1,3 +1,5 @@
+# Virtex 6, Series 7, Ultrascale, Ultrascale Plus block RAM rules.
+
bram $__XILINX_RAMB36_SDP
init 1
abits 9
diff --git a/techlibs/xilinx/xcu_brams_map.v b/techlibs/xilinx/xcu_brams_map.v
index 6e7925b57..b6719b2dd 100644
--- a/techlibs/xilinx/xcu_brams_map.v
+++ b/techlibs/xilinx/xcu_brams_map.v
@@ -1,3 +1,5 @@
+// Ultrascale and Ultrascale Plus block RAM mapping.
+
module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter CLKPOL2 = 1;
parameter CLKPOL3 = 1;
diff --git a/tests/aiger/.gitignore b/tests/aiger/.gitignore
index 9a26bb8f4..b76bdb653 100644
--- a/tests/aiger/.gitignore
+++ b/tests/aiger/.gitignore
@@ -1 +1,3 @@
/*_ref.v
+/*.aag.log
+/*.aig.log
diff --git a/tests/arch/ecp5/bug1630.ys b/tests/arch/ecp5/bug1630.ys
index b419fb9bb..63df1ad5b 100644
--- a/tests/arch/ecp5/bug1630.ys
+++ b/tests/arch/ecp5/bug1630.ys
@@ -1,2 +1,2 @@
read_ilang bug1630.il.gz
-abc9 -lut +/ecp5/abc9_5g.lut
+abc9 -lut 4
diff --git a/tests/arch/ice40/ice40_wrapcarry.ys b/tests/arch/ice40/ice40_wrapcarry.ys
index fb9fccc3a..74319c480 100644
--- a/tests/arch/ice40/ice40_wrapcarry.ys
+++ b/tests/arch/ice40/ice40_wrapcarry.ys
@@ -50,5 +50,5 @@ select -assert-count 0 t:* t:$__ICE40_CARRY_WRAPPER %d
select -assert-count 1 a:keep=1 a:SB_CARRY.\foo=bar %i a:SB_CARRY.\answer=42 %i a:SB_LUT4.\blah=blah %i a:SB_LUT4.\answer=43 %i
ice40_wrapcarry -unwrap
-select -assert-count 1 c:carry a:src=<<EOT:3 %i a:keep=0 %i a:foo=bar %i a:answer=42 %i
-select -assert-count 1 c:adder a:src=<<EOT:10 %i a:keep=1 %i a:blah=blah %i a:answer=43 %i
+select -assert-count 1 c:carry a:src=<<EOT:3.11-8.3 %i a:keep=0 %i a:foo=bar %i a:answer=42 %i
+select -assert-count 1 c:adder a:src=<<EOT:12.4-18.3 %i a:keep=1 %i a:blah=blah %i a:answer=43 %i
diff --git a/tests/arch/run-test.sh b/tests/arch/run-test.sh
index 5292d1615..170078a7f 100755
--- a/tests/arch/run-test.sh
+++ b/tests/arch/run-test.sh
@@ -2,12 +2,23 @@
set -e
+declare -A defines=( ["ice40"]="ICE40_HX ICE40_LP ICE40_U" )
+
echo "Running syntax check on arch sim models"
for arch in ../../techlibs/*; do
find $arch -name cells_sim.v | while read path; do
- echo -n "Test $path ->"
- iverilog -t null -I$arch $path
- echo " ok"
+ arch_name=$(basename -- $arch)
+ if [ "${defines[$arch_name]}" ]; then
+ for def in ${defines[$arch_name]}; do
+ echo -n "Test $path -D$def ->"
+ iverilog -t null -I$arch -D$def $path
+ echo " ok"
+ done
+ else
+ echo -n "Test $path ->"
+ iverilog -t null -I$arch $path
+ echo " ok"
+ fi
done
done
diff --git a/tests/arch/xilinx/add_sub.ys b/tests/arch/xilinx/add_sub.ys
index 70cfe81a3..6be9a73a3 100644
--- a/tests/arch/xilinx/add_sub.ys
+++ b/tests/arch/xilinx/add_sub.ys
@@ -1,11 +1,23 @@
read_verilog ../common/add_sub.v
hierarchy -top top
proc
+design -save orig
+
equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
stat
-select -assert-count 16 t:LUT2
+select -assert-count 8 t:LUT2
select -assert-count 2 t:CARRY4
select -assert-none t:LUT2 t:CARRY4 %% t:* %D
+design -load orig
+
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc3s -noiopad # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd top # Constrain all select calls below inside the top module
+stat
+select -assert-count 8 t:LUT2
+select -assert-count 6 t:MUXCY
+select -assert-count 8 t:XORCY
+select -assert-none t:LUT2 t:MUXCY t:XORCY %% t:* %D
diff --git a/tests/various/bug1480.ys b/tests/arch/xilinx/bug1480.ys
index 84faea08a..84faea08a 100644
--- a/tests/various/bug1480.ys
+++ b/tests/arch/xilinx/bug1480.ys
diff --git a/tests/arch/xilinx/fsm.ys b/tests/arch/xilinx/fsm.ys
index a464fcfdb..fec4c6082 100644
--- a/tests/arch/xilinx/fsm.ys
+++ b/tests/arch/xilinx/fsm.ys
@@ -3,6 +3,8 @@ hierarchy -top fsm
proc
flatten
+design -save orig
+
equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -noiopad
miter -equiv -make_assert -flatten gold gate miter
sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
@@ -17,3 +19,20 @@ select -assert-count 1 t:LUT2
select -assert-count 3 t:LUT5
select -assert-count 1 t:LUT6
select -assert-none t:BUFG t:FDRE t:FDSE t:LUT2 t:LUT5 t:LUT6 %% t:* %D
+
+design -load orig
+
+equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -family xc3se -noiopad
+miter -equiv -make_assert -flatten gold gate miter
+sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
+
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd fsm # Constrain all select calls below inside the top module
+stat
+select -assert-count 1 t:BUFG
+select -assert-count 6 t:FDRE
+select -assert-count 1 t:LUT1
+select -assert-count 3 t:LUT3
+select -assert-count 6 t:LUT4
+select -assert-count 6 t:MUXF5
+select -assert-none t:BUFG t:FDRE t:LUT1 t:LUT3 t:LUT4 t:MUXF5 %% t:* %D
diff --git a/tests/arch/xilinx/lutram.ys b/tests/arch/xilinx/lutram.ys
index 3f127a77e..cc7354501 100644
--- a/tests/arch/xilinx/lutram.ys
+++ b/tests/arch/xilinx/lutram.ys
@@ -135,3 +135,23 @@ select -assert-count 1 t:BUFG
select -assert-count 6 t:FDRE
select -assert-count 2 t:RAM64M
select -assert-none t:BUFG t:FDRE t:RAM64M %% t:* %D
+
+
+design -reset
+read_verilog ../common/lutram.v
+hierarchy -top lutram_1w1r -chparam A_WIDTH 4
+proc
+memory -nomap
+equiv_opt -run :prove -map +/xilinx/cells_sim.v synth_xilinx -family xc3s -noiopad
+memory
+opt -full
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
+
+design -load postopt
+cd lutram_1w1r
+select -assert-count 1 t:BUFG
+select -assert-count 8 t:FDRE
+select -assert-count 8 t:RAM16X1D
+select -assert-none t:BUFG t:FDRE t:RAM16X1D %% t:* %D
diff --git a/tests/arch/xilinx/mux_lut4.ys b/tests/arch/xilinx/mux_lut4.ys
new file mode 100644
index 000000000..3e3256993
--- /dev/null
+++ b/tests/arch/xilinx/mux_lut4.ys
@@ -0,0 +1,51 @@
+read_verilog ../common/mux.v
+design -save read
+
+hierarchy -top mux2
+proc
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc3se -noiopad # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux2 # Constrain all select calls below inside the top module
+select -assert-count 1 t:LUT3
+
+select -assert-none t:LUT3 %% t:* %D
+
+
+design -load read
+hierarchy -top mux4
+proc
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc3se -noiopad # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux4 # Constrain all select calls below inside the top module
+select -assert-count 4 t:LUT1
+select -assert-count 2 t:MUXF5
+select -assert-count 1 t:MUXF6
+
+select -assert-none t:LUT1 t:MUXF5 t:MUXF6 %% t:* %D
+
+
+design -load read
+hierarchy -top mux8
+proc
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc3se -noiopad # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux8 # Constrain all select calls below inside the top module
+select -assert-count 4 t:LUT1
+select -assert-count 3 t:LUT4
+select -assert-count 2 t:MUXF5
+select -assert-count 1 t:MUXF6
+
+select -assert-none t:LUT1 t:LUT4 t:MUXF5 t:MUXF6 %% t:* %D
+
+
+design -load read
+hierarchy -top mux16
+proc
+equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc3se -noiopad # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux16 # Constrain all select calls below inside the top module
+select -assert-max 32 t:LUT*
+select -assert-max 8 t:MUXF6
+select -assert-max 4 t:MUXF7
+
+select -assert-none t:LUT* t:MUXF5 t:MUXF6 t:MUXF7 %% t:* %D
diff --git a/tests/arch/xilinx/tribuf.sh b/tests/arch/xilinx/tribuf.sh
index 636aed12a..bd44395cb 100644
--- a/tests/arch/xilinx/tribuf.sh
+++ b/tests/arch/xilinx/tribuf.sh
@@ -1,5 +1,5 @@
-! ../../../yosys ../common/tribuf.v -qp "synth_xilinx"
-../../../yosys ../common/tribuf.v -qp "synth_xilinx -iopad; \
+! ../../../yosys -qp "synth_xilinx" ../common/tribuf.v
+../../../yosys -qp "synth_xilinx -iopad; \
select -assert-count 2 t:IBUF; \
select -assert-count 1 t:INV; \
-select -assert-count 1 t:OBUFT"
+select -assert-count 1 t:OBUFT" ../common/tribuf.v
diff --git a/tests/memfile/.gitignore b/tests/memfile/.gitignore
new file mode 100644
index 000000000..61b0d4264
--- /dev/null
+++ b/tests/memfile/.gitignore
@@ -0,0 +1 @@
+temp*
diff --git a/tests/memfile/content1.dat b/tests/memfile/content1.dat
new file mode 100644
index 000000000..4d1c67c26
--- /dev/null
+++ b/tests/memfile/content1.dat
@@ -0,0 +1,64 @@
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
+00001111000000001111111100000000
diff --git a/tests/memfile/memory.v b/tests/memfile/memory.v
new file mode 100644
index 000000000..57106eae8
--- /dev/null
+++ b/tests/memfile/memory.v
@@ -0,0 +1,23 @@
+// A memory initialized with an external file
+
+module memory (
+ input clk_i,
+ input we_i,
+ input [5:0] addr_i,
+ input [31:0] data_i,
+ output reg [31:0] data_o
+);
+
+parameter MEMFILE = "";
+
+reg [31:0] mem [0:63];
+
+initial $readmemb(MEMFILE,mem);
+
+always @(posedge clk_i) begin
+ if (we_i)
+ mem[addr_i] <= data_i;
+ data_o <= mem[addr_i];
+end
+
+endmodule
diff --git a/tests/memfile/run-test.sh b/tests/memfile/run-test.sh
new file mode 100755
index 000000000..e43ddd093
--- /dev/null
+++ b/tests/memfile/run-test.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+set -e
+
+mkdir -p temp
+cp content1.dat temp/content2.dat
+
+cd ..
+
+echo "Running from the parent directory with content1.dat"
+../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"content1.dat\" memory"
+echo "Running from the parent directory with temp/content2.dat"
+../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory"
+echo "Running from the parent directory with memfile/temp/content2.dat"
+../yosys -qp "read_verilog -defer memfile/memory.v; chparam -set MEMFILE \"memfile/temp/content2.dat\" memory"
+
+cd memfile
+
+echo "Running from the same directory with content1.dat"
+../../yosys -qp "read_verilog -defer memory.v; chparam -set MEMFILE \"content1.dat\" memory"
+echo "Running from the same directory with temp/content2.dat"
+../../yosys -qp "read_verilog -defer memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory"
+
+cd temp
+
+echo "Running from a child directory with content1.dat"
+../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"content1.dat\" memory"
+echo "Running from a child directory with temp/content2.dat"
+../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory"
+echo "Running from a child directory with content2.dat"
+../../../yosys -qp "read_verilog -defer ../memory.v; chparam -set MEMFILE \"temp/content2.dat\" memory"
+
+cd ..
+
+echo "Checking a failure when zero length filename is provided"
+if ../../yosys -qp "read_verilog memory.v"; then
+ echo "The execution should fail but it didn't happen, which is WRONG."
+ exit 1
+else
+ echo "Execution failed, which is OK."
+fi
+
+echo "Checking a failure when not existing filename is provided"
+if ../../yosys -qp "read_verilog -defer memory.v; chparam -set MEMFILE \"content3.dat\" memory"; then
+ echo "The execution should fail but it didn't happen, which is WRONG."
+ exit 1
+else
+ echo "Execution failed, which is OK."
+fi
diff --git a/tests/rpc/frontend.py b/tests/rpc/frontend.py
index eff41738a..8cbec5682 100644
--- a/tests/rpc/frontend.py
+++ b/tests/rpc/frontend.py
@@ -31,7 +31,7 @@ end
import json
import argparse
-import sys, socket, os
+import sys, socket, os, subprocess
try:
import msvcrt, win32pipe, win32file
except ImportError:
@@ -83,9 +83,11 @@ def main():
if args.mode == "unix-socket":
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ sock.settimeout(30)
sock.bind(args.path)
try:
sock.listen(1)
+ ys_proc = subprocess.Popen(["../../yosys", "-ql", "unix.log", "-p", "connect_rpc -path {}; read_verilog design.v; hierarchy -top top; flatten; select -assert-count 1 t:$neg".format(args.path)])
conn, addr = sock.accept()
file = conn.makefile("rw")
while True:
@@ -93,7 +95,11 @@ def main():
if not input: break
file.write(call(input) + "\n")
file.flush()
+ ys_proc.wait(timeout=10)
+ if ys_proc.returncode:
+ raise subprocess.CalledProcessError(ys_proc.returncode, ys_proc.args)
finally:
+ ys_proc.kill()
sock.close()
os.unlink(args.path)
diff --git a/tests/rpc/run-test.sh b/tests/rpc/run-test.sh
index 44ce7e674..eeb309347 100755
--- a/tests/rpc/run-test.sh
+++ b/tests/rpc/run-test.sh
@@ -4,3 +4,4 @@ for x in *.ys; do
echo "Running $x.."
../../yosys -ql ${x%.ys}.log $x
done
+python3 frontend.py unix-socket frontend.sock
diff --git a/tests/rpc/unix.ys b/tests/rpc/unix.ys
deleted file mode 100644
index cc7ec14ab..000000000
--- a/tests/rpc/unix.ys
+++ /dev/null
@@ -1,6 +0,0 @@
-!python3 frontend.py unix-socket frontend.sock & sleep 0.1
-connect_rpc -path frontend.sock
-read_verilog design.v
-hierarchy -top top
-flatten
-select -assert-count 1 t:$neg
diff --git a/tests/select/no_warn_assert.ys b/tests/select/no_warn_assert.ys
new file mode 100644
index 000000000..889315826
--- /dev/null
+++ b/tests/select/no_warn_assert.ys
@@ -0,0 +1,2 @@
+logger -expect-no-warnings
+select -assert-count 0 top/t:ff4 top/w:d0 %co:+[d] %i
diff --git a/tests/select/no_warn_prefixed_arg_memb.ys b/tests/select/no_warn_prefixed_arg_memb.ys
new file mode 100644
index 000000000..596a6ed70
--- /dev/null
+++ b/tests/select/no_warn_prefixed_arg_memb.ys
@@ -0,0 +1,5 @@
+logger -expect-no-warnings
+read_verilog ../../examples/igloo2/example.v
+hierarchy
+proc
+select example/t:$add
diff --git a/tests/select/no_warn_prefixed_empty_select_arg.ys b/tests/select/no_warn_prefixed_empty_select_arg.ys
new file mode 100644
index 000000000..617e0d63e
--- /dev/null
+++ b/tests/select/no_warn_prefixed_empty_select_arg.ys
@@ -0,0 +1,3 @@
+logger -expect-no-warnings
+select n:foo/bar*
+select t:$assert
diff --git a/tests/select/run-test.sh b/tests/select/run-test.sh
new file mode 100755
index 000000000..44ce7e674
--- /dev/null
+++ b/tests/select/run-test.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -e
+for x in *.ys; do
+ echo "Running $x.."
+ ../../yosys -ql ${x%.ys}.log $x
+done
diff --git a/tests/select/warn_empty_select_arg.ys b/tests/select/warn_empty_select_arg.ys
new file mode 100644
index 000000000..55aca8eb6
--- /dev/null
+++ b/tests/select/warn_empty_select_arg.ys
@@ -0,0 +1,3 @@
+logger -expect warning "did not match any module." 1
+logger -expect warning "did not match any object." 1
+select foo/bar
diff --git a/tests/simple/partsel.v b/tests/simple/partsel.v
index 7461358ad..83493fcb0 100644
--- a/tests/simple/partsel.v
+++ b/tests/simple/partsel.v
@@ -60,3 +60,7 @@ always @(posedge clk) begin
end
endmodule
+
+module partsel_test003(input [2:0] a, b, input [31:0] din, output [3:0] dout);
+assign dout = din[a*b +: 2];
+endmodule
diff --git a/tests/simple_abc9/abc.box b/tests/simple_abc9/abc.box
deleted file mode 100644
index a8801d807..000000000
--- a/tests/simple_abc9/abc.box
+++ /dev/null
@@ -1,2 +0,0 @@
-MUXF8 1 0 3 1
-1 1 1
diff --git a/tests/simple_abc9/abc9.v b/tests/simple_abc9/abc9.v
index e5837d480..688b47586 100644
--- a/tests/simple_abc9/abc9.v
+++ b/tests/simple_abc9/abc9.v
@@ -213,8 +213,13 @@ module arbiter (clk, rst, request, acknowledge, grant, grant_valid, grant_encode
input rst;
endmodule
-(* abc9_box_id=1, whitebox *)
+(* abc9_box, blackbox *)
module MUXF8(input I0, I1, S, output O);
+specify
+ (I0 => O) = 0;
+ (I1 => O) = 0;
+ (S => O) = 0;
+endspecify
endmodule
// Citation: https://github.com/alexforencich/verilog-ethernet
diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh
index 32d7a80ca..424d8f417 100755
--- a/tests/simple_abc9/run-test.sh
+++ b/tests/simple_abc9/run-test.sh
@@ -25,8 +25,8 @@ exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v *.sv EXTRA_FLAGS="-n 300 -p
synth -run coarse; \
opt -full; \
techmap; \
- abc9 -lut 4 -box ../abc.box; \
+ abc9 -lut 4; \
clean; \
check -assert; \
select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%; \
- setattr -mod -unset whitebox'"
+ setattr -mod -unset blackbox'"
diff --git a/tests/svtypes/enum_simple.sv b/tests/svtypes/enum_simple.sv
new file mode 100644
index 000000000..4e4d5871c
--- /dev/null
+++ b/tests/svtypes/enum_simple.sv
@@ -0,0 +1,48 @@
+
+module enum_simple(input clk, input rst);
+
+ enum {s0, s1, s2, s3} test_enum;
+ typedef enum logic [1:0] {
+ ts0, ts1, ts2, ts3
+ } states_t;
+ states_t state;
+ (states_t) state1;
+ states_t enum_const = ts1;
+
+ always @(posedge clk) begin
+ if (rst) begin
+ test_enum <= s3;
+ state <= ts0;
+ end else begin
+ //test_enum
+ if (test_enum == s0)
+ test_enum <= s1;
+ else if (test_enum == s1)
+ test_enum <= s2;
+ else if (test_enum == s2)
+ test_enum <= s3;
+ else if (test_enum == s3)
+ test_enum <= s0;
+ else
+ assert(1'b0); //should be unreachable
+
+ //state
+ if (state == ts0)
+ state <= ts1;
+ else if (state == ts1)
+ state <= ts2;
+ else if (state == ts2)
+ state <= ts0;
+ else
+ assert(1'b0); //should be unreachable
+ end
+ end
+
+ always @(*) begin
+ assert(state != 2'h3);
+ assert(s0 == '0);
+ assert(ts0 == '0);
+ assert(enum_const == ts1);
+ end
+
+endmodule
diff --git a/tests/svtypes/enum_simple.ys b/tests/svtypes/enum_simple.ys
new file mode 100644
index 000000000..79981657b
--- /dev/null
+++ b/tests/svtypes/enum_simple.ys
@@ -0,0 +1,5 @@
+
+read_verilog -sv enum_simple.sv
+hierarchy; proc; opt
+sat -verify -seq 1 -set-at 1 rst 1 -tempinduct -prove-asserts -show-all
+
diff --git a/tests/svtypes/typedef_memory.sv b/tests/svtypes/typedef_memory.sv
index 577e484ad..37e63c1d0 100644
--- a/tests/svtypes/typedef_memory.sv
+++ b/tests/svtypes/typedef_memory.sv
@@ -1,7 +1,7 @@
module top(input [3:0] addr, wdata, input clk, wen, output reg [3:0] rdata);
typedef logic [3:0] ram16x4_t[0:15];
- (ram16x4_t) mem;
+ ram16x4_t mem;
always @(posedge clk) begin
if (wen) mem[addr] <= wdata;
diff --git a/tests/svtypes/typedef_memory_2.sv b/tests/svtypes/typedef_memory_2.sv
index f3089bf55..6d65131db 100644
--- a/tests/svtypes/typedef_memory_2.sv
+++ b/tests/svtypes/typedef_memory_2.sv
@@ -1,7 +1,7 @@
module top(input [3:0] addr, wdata, input clk, wen, output reg [3:0] rdata);
typedef logic [3:0] nibble;
- (nibble) mem[0:15];
+ nibble mem[0:15];
always @(posedge clk) begin
if (wen) mem[addr] <= wdata;
diff --git a/tests/svtypes/typedef_package.sv b/tests/svtypes/typedef_package.sv
index a1e16d4b1..57a78c53a 100644
--- a/tests/svtypes/typedef_package.sv
+++ b/tests/svtypes/typedef_package.sv
@@ -1,11 +1,14 @@
package pkg;
typedef logic [7:0] uint8_t;
+ typedef enum logic [7:0] {bb=8'hBB} enum8_t;
endpackage
module top;
- (* keep *) (pkg::uint8_t) a = 8'hAA;
+ (* keep *) pkg::uint8_t a = 8'hAA;
+ (* keep *) pkg::enum8_t b_enum = pkg::bb;
always @* assert(a == 8'hAA);
+ always @* assert(b_enum == 8'hBB);
endmodule
diff --git a/tests/svtypes/typedef_param.sv b/tests/svtypes/typedef_param.sv
index ddbd471e0..d838dd828 100644
--- a/tests/svtypes/typedef_param.sv
+++ b/tests/svtypes/typedef_param.sv
@@ -6,12 +6,12 @@ module top;
typedef logic [1:0] uint2_t;
typedef logic signed [3:0] int4_t;
typedef logic signed [7:0] int8_t;
- typedef (int8_t) char_t;
+ typedef int8_t char_t;
- parameter (uint2_t) int2 = 2'b10;
- localparam (int4_t) int4 = -1;
- localparam (int8_t) int8 = int4;
- localparam (char_t) ch = int8;
+ parameter uint2_t int2 = 2'b10;
+ localparam int4_t int4 = -1;
+ localparam int8_t int8 = int4;
+ localparam char_t ch = int8;
`STATIC_ASSERT(int2 == 2'b10);
diff --git a/tests/svtypes/typedef_scopes.sv b/tests/svtypes/typedef_scopes.sv
index faa385bd6..d41a58147 100644
--- a/tests/svtypes/typedef_scopes.sv
+++ b/tests/svtypes/typedef_scopes.sv
@@ -1,23 +1,35 @@
typedef logic [3:0] outer_uint4_t;
+typedef enum logic {s0, s1} outer_enum_t;
module top;
- (outer_uint4_t) u4_i = 8'hA5;
+ outer_uint4_t u4_i = 8'hA5;
+ outer_enum_t enum4_i = s0;
always @(*) assert(u4_i == 4'h5);
+ always @(*) assert(enum4_i == 1'b0);
typedef logic [3:0] inner_type;
- (inner_type) inner_i1 = 8'h5A;
+ typedef enum logic [2:0] {s2=2, s3, s4} inner_enum_t;
+ inner_type inner_i1 = 8'h5A;
+ inner_enum_t inner_enum1 = s3;
always @(*) assert(inner_i1 == 4'hA);
+ always @(*) assert(inner_enum1 == 3'h3);
if (1) begin: genblock
typedef logic [7:0] inner_type;
- (inner_type) inner_gb_i = 8'hA5;
+ parameter inner_type inner_const = 8'hA5;
+ typedef enum logic [2:0] {s5=5, s6, s7} inner_enum_t;
+ inner_type inner_gb_i = inner_const; //8'hA5;
+ inner_enum_t inner_gb_enum1 = s7;
always @(*) assert(inner_gb_i == 8'hA5);
+ always @(*) assert(inner_gb_enum1 == 3'h7);
end
- (inner_type) inner_i2 = 8'h42;
+ inner_type inner_i2 = 8'h42;
+ inner_enum_t inner_enum2 = s4;
always @(*) assert(inner_i2 == 4'h2);
+ always @(*) assert(inner_enum2 == 3'h4);
endmodule
diff --git a/tests/svtypes/typedef_simple.sv b/tests/svtypes/typedef_simple.sv
index 7e760dee4..8f89910e5 100644
--- a/tests/svtypes/typedef_simple.sv
+++ b/tests/svtypes/typedef_simple.sv
@@ -3,12 +3,12 @@ module top;
typedef logic [1:0] uint2_t;
typedef logic signed [3:0] int4_t;
typedef logic signed [7:0] int8_t;
- typedef (int8_t) char_t;
+ typedef int8_t char_t;
- (* keep *) (uint2_t) int2 = 2'b10;
- (* keep *) (int4_t) int4 = -1;
- (* keep *) (int8_t) int8 = int4;
- (* keep *) (char_t) ch = int8;
+ (* keep *) uint2_t int2 = 2'b10;
+ (* keep *) int4_t int4 = -1;
+ (* keep *) int8_t int8 = int4;
+ (* keep *) char_t ch = int8;
always @* assert(int2 == 2'b10);
diff --git a/tests/techmap/iopadmap.ys b/tests/techmap/iopadmap.ys
index c058d1607..25ea94dfc 100644
--- a/tests/techmap/iopadmap.ys
+++ b/tests/techmap/iopadmap.ys
@@ -4,12 +4,15 @@ module obuf (input i, (* iopad_external_pin *) output o); endmodule
module obuft (input i, input oe, (* iopad_external_pin *) output o); endmodule
module iobuf (input i, input oe, output o, (* iopad_external_pin *) inout io); endmodule
+module buf_inside (input i, output o);
+obuf b (.i(i), .o(o));
+endmodule
+
module a(input i, output o);
assign o = i;
endmodule
module b(input i, output o);
-assign o = i;
ibuf b (.i(i), .o(o));
endmodule
@@ -42,12 +45,22 @@ assign io = i;
assign o = io;
endmodule
+module i(input i, output o);
+buf_inside b (.i(i), .o(o));
+endmodule
+
+module j(input i, output o);
+wire tmp;
+obuf b (.i(i), .o(tmp));
+assign o = tmp;
+endmodule
+
EOT
opt_clean
tribuf
simplemap
-iopadmap -bits -inpad ibuf o:i -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io
+iopadmap -bits -inpad ibuf o:i -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io a b c d e f g h i j
opt_clean
select -assert-count 1 a/t:ibuf
@@ -120,3 +133,46 @@ select -assert-count 1 g/t:iobuf
select -assert-count 1 h/t:ibuf
select -assert-count 1 h/t:iobuf
select -assert-count 1 h/t:obuf
+
+select -assert-count 1 i/t:ibuf
+select -assert-count 0 i/t:obuf
+
+select -assert-count 1 j/t:ibuf
+select -assert-count 1 j/t:obuf
+
+
+# Check that \init attributes get moved from output buffer
+# to buffer input
+design -reset
+read_verilog << EOT
+module obuf (input i, (* iopad_external_pin *) output o); endmodule
+module obuft (input i, input oe, (* iopad_external_pin *) output o); endmodule
+module iobuf (input i, input oe, output o, (* iopad_external_pin *) inout io); endmodule
+module sub(input i, output o); endmodule
+
+module a(input i, (* init=1'b1 *) output o);
+sub s(.i(i), .o(o));
+endmodule
+
+module b(input [1:0] i, oe, (* init=2'b1x *) output [1:0] o);
+wire [1:0] w;
+sub s1(.i(i[0]), .o(w[0]));
+sub s2(.i(i[1]), .o(w[1]));
+assign o = oe ? w : 2'bz;
+endmodule
+
+module c(input i, oe, (* init=2'b00 *) inout io, output o1, o2);
+assign io = oe ? i : 1'bz;
+assign {o1,o2} = {io,io};
+endmodule
+EOT
+opt_clean
+tribuf
+simplemap
+iopadmap -bits -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io
+select -assert-count 1 a/c:s %co a/a:init=1'b1 %i
+select -assert-count 1 a/a:init
+select -assert-count 1 b/c:s* %co %a b/a:init=2'b1x %i
+select -assert-count 1 b/a:init
+select -assert-count 1 c/t:iobuf %co c/a:init=2'b00 %i
+select -assert-count 1 c/a:init
diff --git a/tests/techmap/techmap_replace.ys b/tests/techmap/techmap_replace.ys
index c2f42d50b..8403586bd 100644
--- a/tests/techmap/techmap_replace.ys
+++ b/tests/techmap/techmap_replace.ys
@@ -16,3 +16,21 @@ EOT
techmap -map %techmap
select -assert-any w:s0.asdf
select -assert-any c:s0.blah
+
+read_verilog <<EOT
+module sub(input i, output o, input j);
+wire _TECHMAP_REPLACE_.asdf = i ;
+barfoo _TECHMAP_REPLACE_.blah (i, o, j);
+endmodule
+EOT
+design -stash techmap
+
+read_verilog <<EOT
+module top(input i, output o);
+sub s0(i, o);
+endmodule
+EOT
+
+techmap -map %techmap
+select -assert-any w:s0.asdf
+select -assert-any c:s0.blah
diff --git a/tests/various/bug1614.ys b/tests/various/bug1614.ys
new file mode 100644
index 000000000..6fbe84a4c
--- /dev/null
+++ b/tests/various/bug1614.ys
@@ -0,0 +1,5 @@
+read_verilog <<EOT
+module testcase;
+ wire [3:0] #1 a = 4'b0000;
+endmodule
+EOT
diff --git a/tests/various/bug1710.ys b/tests/various/bug1710.ys
new file mode 100644
index 000000000..c2ecf3c90
--- /dev/null
+++ b/tests/various/bug1710.ys
@@ -0,0 +1,30 @@
+logger -werror "out of bounds"
+read_verilog <<EOT
+module Example;
+
+ parameter FLAG = 1;
+ wire [3:0] inp;
+
+ reg out1;
+ initial out1 = FLAG ? &inp[2:0] : &inp[4:0];
+
+ reg out2;
+ initial
+ if (FLAG)
+ out2 = &inp[2:0];
+ else
+ out2 = &inp[4:0];
+
+ wire out3;
+ assign out3 = FLAG ? &inp[2:0] : &inp[4:0];
+
+ wire out4;
+ generate
+ if (FLAG)
+ assign out4 = &inp[2:0];
+ else
+ assign out4 = &inp[4:0];
+ endgenerate
+
+endmodule
+EOT
diff --git a/tests/various/bug1745.ys b/tests/various/bug1745.ys
new file mode 100644
index 000000000..2e5b8c2d4
--- /dev/null
+++ b/tests/various/bug1745.ys
@@ -0,0 +1,8 @@
+logger -expect error "syntax error, unexpected TOK_CONSTVAL" 1
+read_verilog <<EOT
+module inverter(input a, output y);
+
+ assign y = (a == 1'b0? 1'b1 : 1'b0);
+
+endmodule // inverter
+EOT
diff --git a/tests/various/bug1781.ys b/tests/various/bug1781.ys
new file mode 100644
index 000000000..60dcc0830
--- /dev/null
+++ b/tests/various/bug1781.ys
@@ -0,0 +1,33 @@
+read_verilog <<EOT
+
+module top(input clk, input rst);
+
+reg [1:0] state;
+
+always @(posedge clk, posedge rst) begin
+ if (rst)
+ state <= 0;
+ else
+ case (state)
+ 2'b00: state <= 2'b01;
+ 2'b01: state <= 2'b10;
+ 2'b10: state <= 2'b00;
+ endcase
+end
+
+sub sub_i(.i(state == 0));
+
+endmodule
+
+
+(* blackbox, keep *)
+module sub(input i);
+endmodule
+
+EOT
+
+proc
+fsm
+
+# Make sure there is a driver
+select -assert-any t:sub %ci %a w:* %i %ci c:* %i
diff --git a/tests/various/constcomment.ys b/tests/various/constcomment.ys
new file mode 100644
index 000000000..f4f2e75d8
--- /dev/null
+++ b/tests/various/constcomment.ys
@@ -0,0 +1,16 @@
+read_verilog <<EOT
+module top1;
+ localparam a = 8 /*foo*/ 'h ab;
+ localparam b = 8 'h /*foo*/ cd;
+ generate
+ if (a != 8'b10101011) $error("a incorrect!");
+ if (b != 8'b11001101) $error("b incorrect!");
+ endgenerate
+endmodule
+EOT
+logger -expect error "syntax error, unexpected TOK_BASE" 1
+read_verilog <<EOT
+module top2;
+ localparam a = 12'h4 /*foo*/'b0;
+endmodule
+EOT
diff --git a/tests/various/deminout_unused.ys b/tests/various/deminout_unused.ys
new file mode 100644
index 000000000..5ed00509d
--- /dev/null
+++ b/tests/various/deminout_unused.ys
@@ -0,0 +1,14 @@
+read_verilog <<EOT
+module top(input clk, inout [7:0] x);
+
+reg [3:0] ctr;
+always @(posedge clk) ctr <= ctr + 1'b1;
+
+assign x[7:4] = ctr;
+endmodule
+EOT
+proc
+tribuf
+deminout
+select -assert-count 1 i:x o:x %i
+
diff --git a/tests/various/exec.ys b/tests/various/exec.ys
new file mode 100644
index 000000000..0eec00719
--- /dev/null
+++ b/tests/various/exec.ys
@@ -0,0 +1,6 @@
+exec -expect-return 0 -- exit 0
+exec -expect-return 27 -- exit 27
+exec -expect-stdout nana -expect-stdout api -not-expect-stdout giraffe -- echo "bananapie"
+
+logger -expect error "stdout did have a line" 1
+exec -not-expect-stdout giraffe -- echo "giraffe"
diff --git a/tests/various/ice40_mince_abc9.ys b/tests/various/ice40_mince_abc9.ys
new file mode 100644
index 000000000..408e16f05
--- /dev/null
+++ b/tests/various/ice40_mince_abc9.ys
@@ -0,0 +1,17 @@
+read_verilog <<EOT
+
+module top(input clk, ce, input [2:0] a, b, output reg [2:0] q);
+
+ reg [2:0] aa, bb;
+
+ always @(posedge clk) begin
+ if (ce) begin
+ aa <= a;
+ end
+ bb <= b;
+ q <= aa + bb;
+ end
+endmodule
+EOT
+
+synth_ice40 -abc9 -dffe_min_ce_use 4
diff --git a/tests/various/logger_error.ys b/tests/various/logger_error.ys
new file mode 100644
index 000000000..46fe7f506
--- /dev/null
+++ b/tests/various/logger_error.ys
@@ -0,0 +1,6 @@
+logger -werror "is implicitly declared." -expect error "is implicitly declared." 1
+read_verilog << EOF
+module top(...);
+ assign b = w;
+endmodule
+EOF
diff --git a/tests/various/logger_nowarning.ys b/tests/various/logger_nowarning.ys
new file mode 100644
index 000000000..87cbbc644
--- /dev/null
+++ b/tests/various/logger_nowarning.ys
@@ -0,0 +1,6 @@
+logger -expect-no-warnings -nowarn "is implicitly declared."
+read_verilog << EOF
+module top(...);
+ assign b = w;
+endmodule
+EOF
diff --git a/tests/various/logger_warn.ys b/tests/various/logger_warn.ys
new file mode 100644
index 000000000..2316ae4c6
--- /dev/null
+++ b/tests/various/logger_warn.ys
@@ -0,0 +1,6 @@
+logger -warn "Successfully finished Verilog frontend." -expect warning "Successfully finished Verilog frontend." 1
+read_verilog << EOF
+module top(...);
+ assign b = w;
+endmodule
+EOF
diff --git a/tests/various/logger_warning.ys b/tests/various/logger_warning.ys
new file mode 100644
index 000000000..642b1b97b
--- /dev/null
+++ b/tests/various/logger_warning.ys
@@ -0,0 +1,6 @@
+logger -expect warning "is implicitly declared." 2
+read_verilog << EOF
+module top(...);
+ assign b = w;
+endmodule
+EOF
diff --git a/tests/various/mem2reg.ys b/tests/various/mem2reg.ys
index 85d6267c5..ba94787bc 100644
--- a/tests/various/mem2reg.ys
+++ b/tests/various/mem2reg.ys
@@ -9,6 +9,6 @@ EOT
proc
cd top
-select -assert-count 1 m:data1 a:src=<<EOT:4 %i
-select -assert-count 2 w:data2[*] a:src=<<EOT:5 %i
+select -assert-count 1 m:data1 a:src=<<EOT:4.43-4.48 %i
+select -assert-count 2 w:data2[*] a:src=<<EOT:5.41-5.46 %i
select -assert-none a:mem2reg
diff --git a/tests/various/pmux2shiftx.v b/tests/various/pmux2shiftx.v
index 563394080..c1994e92c 100644
--- a/tests/various/pmux2shiftx.v
+++ b/tests/various/pmux2shiftx.v
@@ -33,7 +33,7 @@ module pmux2shiftx_test (
end
endmodule
-module issue01135(input [7:0] i, output o);
+module issue01135(input [7:0] i, output reg o);
always @*
case (i[6:3])
4: o <= i[0];
diff --git a/tests/various/specify.v b/tests/various/specify.v
index 5d44d78f7..c160d2ec4 100644
--- a/tests/various/specify.v
+++ b/tests/various/specify.v
@@ -7,11 +7,9 @@ module test (
if (EN) Q <= D;
specify
-`ifndef SKIP_UNSUPPORTED_IGN_PARSER_CONSTRUCTS
if (EN) (posedge CLK *> (Q : D)) = (1, 2:3:4);
$setup(D, posedge CLK &&& EN, 5);
$hold(posedge CLK, D &&& EN, 6);
-`endif
endspecify
endmodule
@@ -37,3 +35,30 @@ specify
(posedge clk *> (q +: d)) = (3,1);
endspecify
endmodule
+
+module test3(input clk, input [1:0] d, output [1:0] q);
+specify
+ (posedge clk => (q +: d)) = (3,1);
+ (posedge clk *> (q +: d)) = (3,1);
+endspecify
+endmodule
+
+module test4(input clk, d, output q);
+specify
+ $setup(d, posedge clk, 1:2:3);
+ $setuphold(d, posedge clk, 1:2:3, 4:5:6);
+endspecify
+endmodule
+
+module test5(input clk, d, e, output q);
+specify
+ $setup(d, posedge clk &&& e, 1:2:3);
+endspecify
+endmodule
+
+module test6(input clk, d, e, output q);
+specify
+ (d[0] *> q[0]) = (3,1);
+ (posedge clk[0] => (q[0] +: d[0])) = (3,1);
+endspecify
+endmodule
diff --git a/tests/various/specify.ys b/tests/various/specify.ys
index 00597e1e2..9d55b8eb5 100644
--- a/tests/various/specify.ys
+++ b/tests/various/specify.ys
@@ -55,4 +55,23 @@ equiv_induct -seq 5
equiv_status -assert
design -reset
-read_verilog -DSKIP_UNSUPPORTED_IGN_PARSER_CONSTRUCTS specify.v
+read_verilog -specify <<EOT
+(* blackbox *)
+module test7_sub(input i, output o);
+specify
+ (i => o) = 1;
+endspecify
+assign o = ~i;
+endmodule
+
+module test7(input i, output o);
+ wire w;
+ test7_sub unused(i, w);
+ test7_sub used(i, o);
+endmodule
+EOT
+hierarchy
+cd test7
+clean
+select -assert-count 1 c:used
+select -assert-none c:* c:used %d
diff --git a/tests/various/src.ys b/tests/various/src.ys
new file mode 100644
index 000000000..89d6700ca
--- /dev/null
+++ b/tests/various/src.ys
@@ -0,0 +1,8 @@
+logger -expect warning "wire '\\o' is assigned in a block at <<EOT:2.11-2.17" 1
+logger -expect warning "wire '\\p' is assigned in a block at <<EOT:3.11-3.16" 1
+read_verilog <<EOT
+module top(input i, output o, p);
+always @* o <= i;
+always @* p = i;
+endmodule
+EOT
diff --git a/tests/various/submod.ys b/tests/various/submod.ys
new file mode 100644
index 000000000..4fb45043b
--- /dev/null
+++ b/tests/various/submod.ys
@@ -0,0 +1,124 @@
+read_verilog <<EOT
+module top(input a, output b);
+wire c;
+(* submod="bar" *) sub s1(a, c);
+assign b = c;
+endmodule
+
+module sub(input a, output c);
+assign c = a;
+endmodule
+EOT
+
+hierarchy -top top
+proc
+design -save gold
+
+submod
+check -assert
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
+
+
+design -reset
+read_verilog <<EOT
+module top(input a, output [1:0] b);
+(* submod="bar" *) sub s1(a, b[1]);
+assign b[0] = 1'b0;
+endmodule
+
+module sub(input a, output c);
+assign c = a;
+endmodule
+EOT
+
+hierarchy -top top
+proc
+design -save gold
+
+submod
+check -assert top
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
+
+
+design -reset
+read_verilog <<EOT
+module top(input a, output [1:0] b, c);
+(* submod="bar" *) sub s1(a, b[0]);
+(* submod="bar" *) sub s2(a, c[1]);
+assign c = b;
+endmodule
+
+module sub(input a, output c);
+assign c = a;
+endmodule
+EOT
+
+hierarchy -top top
+proc
+design -save gold
+
+submod
+check -assert top
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
+
+
+design -reset
+read_verilog <<EOT
+module top(input d, c, (* init = 3'b011 *) output reg [2:0] q);
+(* submod="bar" *) DFF s1(.D(d), .C(c), .Q(q[1]));
+DFF s2(.D(d), .C(c), .Q(q[0]));
+DFF s3(.D(d), .C(c), .Q(q[2]));
+endmodule
+
+module DFF(input D, C, output Q);
+parameter INIT = 1'b0;
+endmodule
+EOT
+
+hierarchy -top top
+proc
+
+submod
+dffinit -ff DFF Q INIT
+check -noinit -assert
+
+
+design -reset
+read_verilog <<EOT
+module top(input d, c, output reg [2:0] q);
+(* submod="bar" *) DFF s1(.D(d), .C(c), .Q(q[1]));
+DFF s2(.D(d), .C(c), .Q(q[0]));
+DFF s3(.D(d), .C(c), .Q(q[2]));
+endmodule
+EOT
+
+hierarchy -top top
+proc
+
+submod
+flatten
+
+read_verilog <<EOT
+module DFF(input D, C, output Q);
+endmodule
+EOT
+
+check -assert