Merge remote-tracking branch 'origin/master' into xc7srl

This commit is contained in:
Eddie Hung 2019-04-22 10:36:27 -07:00
commit e300b1922c
39 changed files with 3148 additions and 73 deletions

View File

@ -32,6 +32,10 @@ matrix:
- xdot
- pkg-config
- python
- python3
- libboost-system-dev
- libboost-python-dev
- libboost-filesystem-dev
env:
- MATRIX_EVAL="CONFIG=gcc && CC=gcc-4.8 && CXX=g++-4.8"
@ -56,6 +60,10 @@ matrix:
- xdot
- pkg-config
- python
- python3
- libboost-system-dev
- libboost-python-dev
- libboost-filesystem-dev
env:
- MATRIX_EVAL="CONFIG=gcc && CC=gcc-6 && CXX=g++-6"
@ -80,6 +88,10 @@ matrix:
- xdot
- pkg-config
- python
- python3
- libboost-system-dev
- libboost-python-dev
- libboost-filesystem-dev
env:
- MATRIX_EVAL="CONFIG=gcc && CC=gcc-7 && CXX=g++-7"
@ -105,6 +117,10 @@ matrix:
- xdot
- pkg-config
- python
- python3
- libboost-system-dev
- libboost-python-dev
- libboost-filesystem-dev
env:
- MATRIX_EVAL="CONFIG=clang && CC=clang-3.8 && CXX=clang++-3.8"
@ -129,6 +145,10 @@ matrix:
- xdot
- pkg-config
- python
- python3
- libboost-system-dev
- libboost-python-dev
- libboost-filesystem-dev
env:
- MATRIX_EVAL="CONFIG=clang && CC=clang-5.0 && CXX=clang++-5.0"

View File

@ -19,6 +19,14 @@ ENABLE_COVER := 1
ENABLE_LIBYOSYS := 0
ENABLE_PROTOBUF := 0
# python wrappers
ENABLE_PYOSYS := 0
PYTHON_VERSION_TESTCODE := "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));print(t)"
PYTHON_EXECUTABLE := $(shell if python3 -c ""; then echo "python3"; else echo "python"; fi)
PYTHON_VERSION := $(shell $(PYTHON_EXECUTABLE) -c ""$(PYTHON_VERSION_TESTCODE)"")
PYTHON_MAJOR_VERSION := $(shell echo $(PYTHON_VERSION) | cut -f1 -d.)
PYTHON_DESTDIR := `$(PYTHON_EXECUTABLE)-config --prefix`/lib/python$(PYTHON_VERSION)/dist-packages
# other configuration flags
ENABLE_GCOV := 0
ENABLE_GPROF := 0
@ -261,6 +269,34 @@ ifeq ($(ENABLE_LIBYOSYS),1)
TARGETS += libyosys.so
endif
ifeq ($(ENABLE_PYOSYS),1)
#Detect name of boost_python library. Some distros usbe boost_python-py<version>, other boost_python<version>, some only use the major version number, some a concatenation of major and minor version numbers
BOOST_PYTHON_LIB ?= $(shell \
if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python-py$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_VERSION))"; else \
if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python-py$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \
if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python$(subst .,,$(PYTHON_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_VERSION))"; else \
if echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null `$(PYTHON_EXECUTABLE)-config --libs` -lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION)) - > /dev/null 2>&1; then echo "-lboost_python$(subst .,,$(PYTHON_MAJOR_VERSION))"; else \
echo ""; fi; fi; fi; fi;)
ifeq ($(BOOST_PYTHON_LIB),)
$(error BOOST_PYTHON_LIB could not be detected. Please define manualy)
endif
ifeq ($(PYTHON_MAJOR_VERSION),3)
LDLIBS += `$(PYTHON_EXECUTABLE)-config --libs` $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem
CXXFLAGS += `$(PYTHON_EXECUTABLE)-config --includes` -D WITH_PYTHON
else
LDLIBS += `$(PYTHON_EXECUTABLE)-config --libs` $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem
CXXFLAGS += `$(PYTHON_EXECUTABLE)-config --includes` -D WITH_PYTHON
endif
PY_WRAPPER_FILE = kernel/python_wrappers
OBJS += $(PY_WRAPPER_FILE).o
PY_GEN_SCRIPT= py_wrap_generator
PY_WRAP_INCLUDES := $(shell python$(PYTHON_VERSION) -c "import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).print_includes()")
endif
ifeq ($(ENABLE_READLINE),1)
CXXFLAGS += -DYOSYS_ENABLE_READLINE
ifeq ($(OS), FreeBSD)
@ -510,6 +546,14 @@ libyosys.so: $(filter-out kernel/driver.o,$(OBJS))
$(Q) mkdir -p $(dir $@)
$(P) $(CXX) -o $@ -c $(CPPFLAGS) $(CXXFLAGS) $<
%.pyh: %.h
$(Q) mkdir -p $(dir $@)
$(P) cat $< | grep -E -v "#[ ]*(include|error)" | $(LD) -x c++ -o $@ -E -P -
$(PY_WRAPPER_FILE).cc: $(PY_GEN_SCRIPT).py $(PY_WRAP_INCLUDES)
$(Q) mkdir -p $(dir $@)
$(P) python$(PYTHON_VERSION) -c "import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).gen_wrappers(\"$(PY_WRAPPER_FILE).cc\")"
%.o: %.cpp
$(Q) mkdir -p $(dir $@)
$(P) $(CXX) -o $@ -c $(CPPFLAGS) $(CXXFLAGS) $<
@ -638,6 +682,11 @@ ifeq ($(ENABLE_LIBYOSYS),1)
$(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(LIBDIR)
$(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(LIBDIR)/libyosys.so
$(INSTALL_SUDO) ldconfig
ifeq ($(ENABLE_PYOSYS),1)
$(INSTALL_SUDO) mkdir -p $(PYTHON_DESTDIR)/pyosys
$(INSTALL_SUDO) cp libyosys.so $(PYTHON_DESTDIR)/pyosys
$(INSTALL_SUDO) cp __init__.py $(PYTHON_DESTDIR)/pyosys
endif
endif
uninstall:
@ -645,6 +694,11 @@ uninstall:
$(INSTALL_SUDO) rm -rvf $(DESTDIR)$(DATDIR)
ifeq ($(ENABLE_LIBYOSYS),1)
$(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.so
ifeq ($(ENABLE_PYOSYS),1)
$(INSTALL_SUDO) rm -vf $(PYTHON_DESTDIR)/pyosys/libyosys.so
$(INSTALL_SUDO) rm -vf $(PYTHON_DESTDIR)/pyosys/__init__.py
$(INSTALL_SUDO) rmdir $(PYTHON_DESTDIR)/pyosys
endif
endif
update-manual: $(TARGETS) $(EXTRA_TARGETS)
@ -657,8 +711,9 @@ manual: $(TARGETS) $(EXTRA_TARGETS)
clean:
rm -rf share
rm -rf kernel/*.pyh
if test -d manual; then cd manual && sh clean.sh; fi
rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS)
rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) $(PY_WRAP_INCLUDES) $(PY_WRAPPER_FILE).cc
rm -f kernel/version_*.o kernel/version_*.cc abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a
rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d
rm -rf tests/asicworld/*.out tests/asicworld/*.log

View File

@ -66,25 +66,26 @@ prerequisites for building yosys:
$ sudo apt-get install build-essential clang bison flex \
libreadline-dev gawk tcl-dev libffi-dev git \
graphviz xdot pkg-config python3
graphviz xdot pkg-config python3 libboost-system-dev \
libboost-python-dev libboost-filesystem-dev
Similarily, on Mac OS X MacPorts or Homebrew can be used to install dependencies:
$ brew tap Homebrew/bundle && brew bundle
$ sudo port install bison flex readline gawk libffi \
git graphviz pkgconfig python36
git graphviz pkgconfig python36 boost
On FreeBSD use the following command to install all prerequisites:
# pkg install bison flex readline gawk libffi\
git graphviz pkgconfig python3 python36 tcl-wrapper
git graphviz pkgconfig python3 python36 tcl-wrapper boost-libs
On FreeBSD system use gmake instead of make. To run tests use:
% MAKE=gmake CC=cc gmake test
For Cygwin use the following command to install all prerequisites, or select these additional packages:
setup-x86_64.exe -q --packages=bison,flex,gcc-core,gcc-g++,git,libffi-devel,libreadline-devel,make,pkg-config,python3,tcl-devel
setup-x86_64.exe -q --packages=bison,flex,gcc-core,gcc-g++,git,libffi-devel,libreadline-devel,make,pkg-config,python3,tcl-devel,boost-build
There are also pre-compiled Yosys binary packages for Ubuntu and Win32 as well
as a source distribution for Visual Studio. Visit the Yosys download page for
@ -310,12 +311,20 @@ Verilog Attributes and non-standard features
that have the same ports as the real thing but do not contain information
on the internal configuration. This modules are only used by the synthesis
passes to identify input and output ports of cells. The Verilog backend
also does not output blackbox modules on default.
also does not output blackbox modules on default. ``read_verilog``, unless
called with ``-noblackbox`` will automatically set the blackbox attribute
on any empty module it reads.
- The ``noblackbox`` attribute set on an empty module prevents ``read_verilog``
from automatically setting the blackbox attribute on the module.
- The ``whitebox`` attribute on modules triggers the same behavior as
``blackbox``, but is for whitebox modules, i.e. library modules that
contain a behavioral model of the cell type.
- The ``lib_whitebox`` attribute overwrites ``whitebox`` when ``read_verilog``
is run in `-lib` mode. Otherwise it's automatically removed.
- The ``dynports`` attribute is used by the Verilog front-end to mark modules
that have ports with a width that depends on a parameter.

5
__init__.py Normal file
View File

@ -0,0 +1,5 @@
import os
import sys
sys.setdlopenflags(os.RTLD_NOW | os.RTLD_GLOBAL)
__all__ = ["libyosys"]

1
examples/python-api/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
out/**

32
examples/python-api/pass.py Executable file
View File

@ -0,0 +1,32 @@
#!/usr/bin/python3
from pyosys import libyosys as ys
import matplotlib.pyplot as plt
import numpy as np
class CellStatsPass(ys.Pass):
def __init__(self):
super().__init__("cell_stats", "Shows cell stats as plot")
def py_help(self):
ys.log("This pass uses the matplotlib library to display cell stats\n")
def py_execute(self, args, design):
ys.log_header(design, "Plotting cell stats\n")
cell_stats = {}
for module in design.selected_whole_modules_warn():
for cell in module.selected_cells():
if cell.type.str() in cell_stats:
cell_stats[cell.type.str()] += 1
else:
cell_stats[cell.type.str()] = 1
plt.bar(range(len(cell_stats)), height = list(cell_stats.values()),align='center')
plt.xticks(range(len(cell_stats)), list(cell_stats.keys()))
plt.show()
def py_clear_flags(self):
ys.log("Clear Flags - CellStatsPass\n")
p = CellStatsPass()

22
examples/python-api/script.py Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
from pyosys import libyosys as ys
import matplotlib.pyplot as plt
import numpy as np
design = ys.Design()
ys.run_pass("read_verilog ../../tests/simple/fiedler-cooley.v", design);
ys.run_pass("prep", design)
ys.run_pass("opt -full", design)
cell_stats = {}
for module in design.selected_whole_modules_warn():
for cell in module.selected_cells():
if cell.type.str() in cell_stats:
cell_stats[cell.type.str()] += 1
else:
cell_stats[cell.type.str()] = 1
plt.bar(range(len(cell_stats)), height = list(cell_stats.values()),align='center')
plt.xticks(range(len(cell_stats)), list(cell_stats.keys()))
plt.show()

View File

@ -46,7 +46,7 @@ namespace AST {
// instantiate global variables (private API)
namespace AST_INTERNAL {
bool flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches, flag_nomeminit;
bool flag_nomem2reg, flag_mem2reg, flag_lib, flag_wb, flag_noopt, flag_icells, flag_autowire;
bool flag_nomem2reg, flag_mem2reg, flag_noblackbox, flag_lib, flag_nowb, flag_noopt, flag_icells, flag_autowire;
AstNode *current_ast, *current_ast_mod;
std::map<std::string, AstNode*> current_scope;
const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr = NULL;
@ -942,6 +942,20 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
if (!defer)
{
bool blackbox_module = flag_lib;
if (!blackbox_module && !flag_noblackbox) {
blackbox_module = true;
for (auto child : ast->children) {
if (child->type == AST_WIRE && (child->is_input || child->is_output))
continue;
if (child->type == AST_PARAMETER || child->type == AST_LOCALPARAM)
continue;
blackbox_module = false;
break;
}
}
while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { }
if (flag_dump_ast2) {
@ -956,18 +970,63 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
log("--- END OF AST DUMP ---\n");
}
if (flag_wb) {
if (!ast->attributes.count("\\whitebox"))
goto blackbox_module;
AstNode *n = ast->attributes.at("\\whitebox");
if (n->type != AST_CONSTANT)
log_file_error(ast->filename, ast->linenum, "Whitebox attribute with non-constant value!\n");
if (!n->asBool())
goto blackbox_module;
if (flag_nowb && ast->attributes.count("\\whitebox")) {
delete ast->attributes.at("\\whitebox");
ast->attributes.erase("\\whitebox");
}
if (flag_lib) {
blackbox_module:
if (ast->attributes.count("\\lib_whitebox")) {
if (!flag_lib || flag_nowb) {
delete ast->attributes.at("\\lib_whitebox");
ast->attributes.erase("\\lib_whitebox");
} else {
if (ast->attributes.count("\\whitebox")) {
delete ast->attributes.at("\\whitebox");
ast->attributes.erase("\\whitebox");
}
AstNode *n = ast->attributes.at("\\lib_whitebox");
ast->attributes["\\whitebox"] = n;
ast->attributes.erase("\\lib_whitebox");
}
}
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");
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");
blackbox_module = !n->asBool();
}
if (ast->attributes.count("\\noblackbox")) {
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");
blackbox_module = !n->asBool();
}
delete ast->attributes.at("\\noblackbox");
ast->attributes.erase("\\noblackbox");
}
if (blackbox_module)
{
if (ast->attributes.count("\\whitebox")) {
delete ast->attributes.at("\\whitebox");
ast->attributes.erase("\\whitebox");
}
if (ast->attributes.count("\\lib_whitebox")) {
delete ast->attributes.at("\\lib_whitebox");
ast->attributes.erase("\\lib_whitebox");
}
std::vector<AstNode*> new_children;
for (auto child : ast->children) {
if (child->type == AST_WIRE && (child->is_input || child->is_output)) {
@ -980,12 +1039,12 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
delete child;
}
}
ast->children.swap(new_children);
if (ast->attributes.count("\\whitebox")) {
delete ast->attributes.at("\\whitebox");
ast->attributes.erase("\\whitebox");
if (ast->attributes.count("\\blackbox") == 0) {
ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false);
}
ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false);
}
ignoreThisSignalsInInitial = RTLIL::SigSpec();
@ -1024,8 +1083,9 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
current_module->nomeminit = flag_nomeminit;
current_module->nomem2reg = flag_nomem2reg;
current_module->mem2reg = flag_mem2reg;
current_module->noblackbox = flag_noblackbox;
current_module->lib = flag_lib;
current_module->wb = flag_wb;
current_module->nowb = flag_nowb;
current_module->noopt = flag_noopt;
current_module->icells = flag_icells;
current_module->autowire = flag_autowire;
@ -1042,7 +1102,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
// create AstModule instances for all modules in the AST tree and add them to 'design'
void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool no_dump_ptr, bool dump_vlog1, bool dump_vlog2, bool dump_rtlil,
bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool lib, bool wb, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire)
bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire)
{
current_ast = ast;
flag_dump_ast1 = dump_ast1;
@ -1055,8 +1115,9 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
flag_nomeminit = nomeminit;
flag_nomem2reg = nomem2reg;
flag_mem2reg = mem2reg;
flag_noblackbox = noblackbox;
flag_lib = lib;
flag_wb = wb;
flag_nowb = nowb;
flag_noopt = noopt;
flag_icells = icells;
flag_autowire = autowire;
@ -1390,8 +1451,9 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
flag_nomeminit = nomeminit;
flag_nomem2reg = nomem2reg;
flag_mem2reg = mem2reg;
flag_noblackbox = noblackbox;
flag_lib = lib;
flag_wb = wb;
flag_nowb = nowb;
flag_noopt = noopt;
flag_icells = icells;
flag_autowire = autowire;

View File

@ -283,13 +283,13 @@ namespace AST
// process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code
void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool no_dump_ptr, bool dump_vlog1, bool dump_vlog2, bool dump_rtlil, bool nolatches, bool nomeminit,
bool nomem2reg, bool mem2reg, bool lib, bool wb, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire);
bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire);
// parametric modules are supported directly by the AST library
// therefore we need our own derivate of RTLIL::Module with overloaded virtual functions
struct AstModule : RTLIL::Module {
AstNode *ast;
bool nolatches, nomeminit, nomem2reg, mem2reg, lib, wb, noopt, icells, autowire;
bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, autowire;
~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;

View File

@ -1030,7 +1030,26 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
log_file_error(filename, linenum, "While loops are only allowed in constant functions!\n");
if (type == AST_REPEAT)
log_file_error(filename, linenum, "Repeat loops are only allowed in constant functions!\n");
{
AstNode *count = children[0];
AstNode *body = children[1];
// eval count expression
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");
// convert to a block with the body repeated n times
type = AST_BLOCK;
children.clear();
for (int i = 0; i < count->bitsAsConst().as_int(); i++)
children.insert(children.begin(), body->clone());
delete count;
delete body;
did_something = true;
}
// unroll for loops and generate-for blocks
if ((type == AST_GENFOR || type == AST_FOR) && children.size() != 0)

View File

@ -145,12 +145,18 @@ struct VerilogFrontend : public Frontend {
log(" -nodpi\n");
log(" disable DPI-C support\n");
log("\n");
log(" -noblackbox\n");
log(" do not automatically add a (* blackbox *) attribute to an\n");
log(" empty module.\n");
log("\n");
log(" -lib\n");
log(" only create empty blackbox modules. This implies -DBLACKBOX.\n");
log(" modules with the (* whitebox *) attribute will be preserved.\n");
log(" (* lib_whitebox *) will be treated like (* whitebox *).\n");
log("\n");
log(" -wb\n");
log(" like -lib, except do not touch modules with the whitebox\n");
log(" attribute set. This also implies -DBLACKBOX.\n");
log(" -nowb\n");
log(" delete (* whitebox *) and (* lib_whitebox *) attributes from\n");
log(" all modules.\n");
log("\n");
log(" -noopt\n");
log(" don't perform basic optimizations (such as const folding) in the\n");
@ -231,8 +237,9 @@ struct VerilogFrontend : public Frontend {
formal_mode = false;
norestrict_mode = false;
assume_asserts_mode = false;
noblackbox_mode = false;
lib_mode = false;
wb_mode = false;
nowb_mode = false;
default_nettype_wire = true;
log_header(design, "Executing Verilog-2005 frontend.\n");
@ -334,14 +341,17 @@ struct VerilogFrontend : public Frontend {
flag_nodpi = true;
continue;
}
if (arg == "-lib" && !wb_mode) {
if (arg == "-noblackbox") {
noblackbox_mode = true;
continue;
}
if (arg == "-lib") {
lib_mode = true;
defines_map["BLACKBOX"] = string();
continue;
}
if (arg == "-wb" && !lib_mode) {
wb_mode = true;
defines_map["BLACKBOX"] = string();
if (arg == "-nowb") {
nowb_mode = true;
continue;
}
if (arg == "-noopt") {
@ -439,7 +449,8 @@ struct VerilogFrontend : public Frontend {
if (flag_nodpi)
error_on_dpi_function(current_ast);
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, lib_mode, wb_mode, flag_noopt, flag_icells, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire);
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, noblackbox_mode, lib_mode, nowb_mode, flag_noopt, flag_icells, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire);
if (!flag_nopp)
delete lexin;

View File

@ -69,11 +69,14 @@ namespace VERILOG_FRONTEND
// running in -assert-assumes mode
extern bool assert_assumes_mode;
// running in -noblackbox mode
extern bool noblackbox_mode;
// running in -lib mode
extern bool lib_mode;
// running in -wb mode
extern bool wb_mode;
// running in -nowb mode
extern bool nowb_mode;
// lexer input stream
extern std::istream *lexin;

View File

@ -59,7 +59,7 @@ namespace VERILOG_FRONTEND {
std::vector<char> case_type_stack;
bool do_not_require_port_stubs;
bool default_nettype_wire;
bool sv_mode, formal_mode, lib_mode, wb_mode;
bool sv_mode, formal_mode, noblackbox_mode, lib_mode, nowb_mode;
bool noassert_mode, noassume_mode, norestrict_mode;
bool assume_asserts_mode, assert_assumes_mode;
bool current_wire_rand, current_wire_const;
@ -1906,7 +1906,7 @@ basic_expr:
if ($4->substr(0, 1) != "'")
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;
AstNode *val = const2ast(*$4, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode && !wb_mode);
AstNode *val = const2ast(*$4, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
if (val == NULL)
log_error("Value conversion failed: `%s'\n", $4->c_str());
$$ = new AstNode(AST_TO_BITS, bits, val);
@ -1917,7 +1917,7 @@ basic_expr:
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;
AstNode *val = const2ast(*$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode && !wb_mode);
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());
$$ = new AstNode(AST_TO_BITS, bits, val);
@ -1925,14 +1925,14 @@ basic_expr:
delete $2;
} |
TOK_CONSTVAL TOK_CONSTVAL {
$$ = const2ast(*$1 + *$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode && !wb_mode);
$$ = 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 {
$$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode && !wb_mode);
$$ = 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());
delete $1;

View File

@ -26,7 +26,7 @@ YOSYS_NAMESPACE_BEGIN
int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr);
int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> &parameters = dict<RTLIL::IdString, RTLIL::Const>(),
inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> &parameters = dict<RTLIL::IdString, RTLIL::Const>(),
RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr)
{
static dict<RTLIL::IdString, int> gate_cost = {
@ -76,7 +76,7 @@ int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const
return 1;
}
int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache)
inline int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache)
{
return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache);
}

View File

@ -110,6 +110,10 @@ int main(int argc, char **argv)
log_error_stderr = true;
yosys_banner();
yosys_setup();
#ifdef WITH_PYTHON
PyRun_SimpleString(("sys.path.append(\""+proc_self_dirname()+"\")").c_str());
PyRun_SimpleString(("sys.path.append(\""+proc_share_dirname()+"plugins\")").c_str());
#endif
if (argc == 2)
{
@ -469,6 +473,10 @@ int main(int argc, char **argv)
#endif
yosys_setup();
#ifdef WITH_PYTHON
PyRun_SimpleString(("sys.path.append(\""+proc_self_dirname()+"\")").c_str());
PyRun_SimpleString(("sys.path.append(\""+proc_share_dirname()+"plugins\")").c_str());
#endif
log_error_atexit = yosys_atexit;
for (auto &fn : plugin_filenames)

View File

@ -76,6 +76,13 @@ RTLIL::Const::Const(const std::vector<bool> &bits)
this->bits.push_back(b ? RTLIL::S1 : RTLIL::S0);
}
RTLIL::Const::Const(const RTLIL::Const &c)
{
flags = c.flags;
for (auto b : c.bits)
this->bits.push_back(b);
}
bool RTLIL::Const::operator <(const RTLIL::Const &other) const
{
if (bits.size() != other.bits.size())
@ -363,6 +370,10 @@ RTLIL::Design::Design()
refcount_modules_ = 0;
selection_stack.push_back(RTLIL::Selection());
#ifdef WITH_PYTHON
RTLIL::Design::get_all_designs()->insert(std::pair<unsigned int, RTLIL::Design*>(hashidx_, this));
#endif
}
RTLIL::Design::~Design()
@ -373,8 +384,19 @@ RTLIL::Design::~Design()
delete n;
for (auto n : verilog_globals)
delete n;
#ifdef WITH_PYTHON
RTLIL::Design::get_all_designs()->erase(hashidx_);
#endif
}
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Design*> all_designs;
std::map<unsigned int, RTLIL::Design*> *RTLIL::Design::get_all_designs(void)
{
return &all_designs;
}
#endif
RTLIL::ObjRange<RTLIL::Module*> RTLIL::Design::modules()
{
return RTLIL::ObjRange<RTLIL::Module*>(&modules_, &refcount_modules_);
@ -630,6 +652,10 @@ RTLIL::Module::Module()
design = nullptr;
refcount_wires_ = 0;
refcount_cells_ = 0;
#ifdef WITH_PYTHON
RTLIL::Module::get_all_modules()->insert(std::pair<unsigned int, RTLIL::Module*>(hashidx_, this));
#endif
}
RTLIL::Module::~Module()
@ -642,8 +668,19 @@ RTLIL::Module::~Module()
delete it->second;
for (auto it = processes.begin(); it != processes.end(); ++it)
delete it->second;
#ifdef WITH_PYTHON
RTLIL::Module::get_all_modules()->erase(hashidx_);
#endif
}
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Module*> all_modules;
std::map<unsigned int, RTLIL::Module*> *RTLIL::Module::get_all_modules(void)
{
return &all_modules;
}
#endif
void RTLIL::Module::makeblackbox()
{
pool<RTLIL::Wire*> delwires;
@ -2229,8 +2266,27 @@ RTLIL::Wire::Wire()
port_input = false;
port_output = false;
upto = false;
#ifdef WITH_PYTHON
RTLIL::Wire::get_all_wires()->insert(std::pair<unsigned int, RTLIL::Wire*>(hashidx_, this));
#endif
}
RTLIL::Wire::~Wire()
{
#ifdef WITH_PYTHON
RTLIL::Wire::get_all_wires()->erase(hashidx_);
#endif
}
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Wire*> all_wires;
std::map<unsigned int, RTLIL::Wire*> *RTLIL::Wire::get_all_wires(void)
{
return &all_wires;
}
#endif
RTLIL::Memory::Memory()
{
static unsigned int hashidx_count = 123456789;
@ -2240,6 +2296,9 @@ RTLIL::Memory::Memory()
width = 1;
start_offset = 0;
size = 0;
#ifdef WITH_PYTHON
RTLIL::Memory::get_all_memorys()->insert(std::pair<unsigned int, RTLIL::Memory*>(hashidx_, this));
#endif
}
RTLIL::Cell::Cell() : module(nullptr)
@ -2250,8 +2309,27 @@ RTLIL::Cell::Cell() : module(nullptr)
// log("#memtrace# %p\n", this);
memhasher();
#ifdef WITH_PYTHON
RTLIL::Cell::get_all_cells()->insert(std::pair<unsigned int, RTLIL::Cell*>(hashidx_, this));
#endif
}
RTLIL::Cell::~Cell()
{
#ifdef WITH_PYTHON
RTLIL::Cell::get_all_cells()->erase(hashidx_);
#endif
}
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Cell*> all_cells;
std::map<unsigned int, RTLIL::Cell*> *RTLIL::Cell::get_all_cells(void)
{
return &all_cells;
}
#endif
bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const
{
return connections_.count(portname) != 0;
@ -2511,6 +2589,14 @@ RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit)
width = 1;
}
RTLIL::SigChunk::SigChunk(const RTLIL::SigChunk &sigchunk) : data(sigchunk.data)
{
wire = sigchunk.wire;
data = sigchunk.data;
width = sigchunk.width;
offset = sigchunk.offset;
}
RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
{
RTLIL::SigChunk ret;
@ -3895,5 +3981,15 @@ RTLIL::Process *RTLIL::Process::clone() const
return new_proc;
}
#ifdef WITH_PYTHON
RTLIL::Memory::~Memory()
{
RTLIL::Memory::get_all_memorys()->erase(hashidx_);
}
static std::map<unsigned int, RTLIL::Memory*> all_memorys;
std::map<unsigned int, RTLIL::Memory*> *RTLIL::Memory::get_all_memorys(void)
{
return &all_memorys;
}
#endif
YOSYS_NAMESPACE_END

View File

@ -517,6 +517,7 @@ struct RTLIL::Const
Const(RTLIL::State bit, int width = 1);
Const(const std::vector<RTLIL::State> &bits) : bits(bits) { flags = CONST_FLAG_NONE; }
Const(const std::vector<bool> &bits);
Const(const RTLIL::Const &c);
bool operator <(const RTLIL::Const &other) const;
bool operator ==(const RTLIL::Const &other) const;
@ -595,6 +596,7 @@ struct RTLIL::SigChunk
SigChunk(int val, int width = 32);
SigChunk(RTLIL::State bit, int width = 1);
SigChunk(RTLIL::SigBit bit);
SigChunk(const RTLIL::SigChunk &sigchunk);
RTLIL::SigChunk extract(int offset, int length) const;
@ -619,6 +621,7 @@ struct RTLIL::SigBit
SigBit(const RTLIL::SigChunk &chunk);
SigBit(const RTLIL::SigChunk &chunk, int index);
SigBit(const RTLIL::SigSpec &sig);
SigBit(const RTLIL::SigBit &sigbit);
bool operator <(const RTLIL::SigBit &other) const;
bool operator ==(const RTLIL::SigBit &other) const;
@ -940,9 +943,13 @@ struct RTLIL::Design
}
}
std::vector<RTLIL::Module*> selected_modules() const;
std::vector<RTLIL::Module*> selected_whole_modules() const;
std::vector<RTLIL::Module*> selected_whole_modules_warn() const;
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Design*> *get_all_designs(void);
#endif
};
struct RTLIL::Module : public RTLIL::AttrObject
@ -1199,6 +1206,10 @@ public:
RTLIL::SigSpec Allconst (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Allseq (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Initstate (RTLIL::IdString name, const std::string &src = "");
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Module*> *get_all_modules(void);
#endif
};
struct RTLIL::Wire : public RTLIL::AttrObject
@ -1210,7 +1221,7 @@ protected:
// use module->addWire() and module->remove() to create or destroy wires
friend struct RTLIL::Module;
Wire();
~Wire() { };
~Wire();
public:
// do not simply copy wires
@ -1221,6 +1232,10 @@ public:
RTLIL::IdString name;
int width, start_offset, port_id;
bool port_input, port_output, upto;
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Wire*> *get_all_wires(void);
#endif
};
struct RTLIL::Memory : public RTLIL::AttrObject
@ -1232,6 +1247,10 @@ struct RTLIL::Memory : public RTLIL::AttrObject
RTLIL::IdString name;
int width, start_offset, size;
#ifdef WITH_PYTHON
~Memory();
static std::map<unsigned int, RTLIL::Memory*> *get_all_memorys(void);
#endif
};
struct RTLIL::Cell : public RTLIL::AttrObject
@ -1243,6 +1262,7 @@ protected:
// use module->addCell() and module->remove() to create or destroy cells
friend struct RTLIL::Module;
Cell();
~Cell();
public:
// do not simply copy cells
@ -1283,6 +1303,10 @@ public:
}
template<typename T> void rewrite_sigspecs(T &functor);
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Cell*> *get_all_cells(void);
#endif
};
struct RTLIL::CaseRule
@ -1343,6 +1367,7 @@ inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_as
inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); }
inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; }
inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; }
inline RTLIL::SigBit::SigBit(const RTLIL::SigBit &sigbit) : wire(sigbit.wire), data(sigbit.data){if(wire) offset = sigbit.offset;}
inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const {
if (wire == other.wire)

View File

@ -57,6 +57,16 @@
# include <sys/sysctl.h>
#endif
#ifdef WITH_PYTHON
#if PY_MAJOR_VERSION >= 3
# define INIT_MODULE PyInit_libyosys
extern "C" PyObject* INIT_MODULE();
#else
# define INIT_MODULE initlibyosys
extern "C" void INIT_MODULE();
#endif
#endif
#include <limits.h>
#include <errno.h>
@ -477,21 +487,42 @@ int GetSize(RTLIL::Wire *wire)
return wire->width;
}
bool already_setup = false;
void yosys_setup()
{
if(already_setup)
return;
already_setup = true;
// if there are already IdString objects then we have a global initialization order bug
IdString empty_id;
log_assert(empty_id.index_ == 0);
IdString::get_reference(empty_id.index_);
#ifdef WITH_PYTHON
PyImport_AppendInittab((char*)"libyosys", INIT_MODULE);
Py_Initialize();
PyRun_SimpleString("import sys");
#endif
Pass::init_register();
yosys_design = new RTLIL::Design;
yosys_celltypes.setup();
log_push();
}
bool yosys_already_setup()
{
return already_setup;
}
bool already_shutdown = false;
void yosys_shutdown()
{
if(already_shutdown)
return;
already_shutdown = true;
log_pop();
delete yosys_design;
@ -519,9 +550,16 @@ void yosys_shutdown()
dlclose(it.second);
loaded_plugins.clear();
#ifdef WITH_PYTHON
loaded_python_plugins.clear();
#endif
loaded_plugin_aliases.clear();
#endif
#ifdef WITH_PYTHON
Py_Finalize();
#endif
IdString empty_id;
IdString::put_reference(empty_id.index_);
}

View File

@ -66,6 +66,10 @@
#include <stdio.h>
#include <limits.h>
#ifdef WITH_PYTHON
#include <Python.h>
#endif
#ifndef _YOSYS_
# error It looks like you are trying to build Yosys without the config defines set. \
When building Yosys with a custom make system, make sure you set all the \
@ -115,6 +119,7 @@ extern const char *Tcl_GetStringResult(Tcl_Interp *interp);
# define PATH_MAX 4096
#endif
#define YOSYS_NAMESPACE Yosys
#define PRIVATE_NAMESPACE_BEGIN namespace {
#define PRIVATE_NAMESPACE_END }
#define YOSYS_NAMESPACE_BEGIN namespace Yosys {
@ -276,6 +281,11 @@ namespace hashlib {
}
void yosys_setup();
#ifdef WITH_PYTHON
bool yosys_already_setup();
#endif
void yosys_shutdown();
#ifdef YOSYS_ENABLE_TCL
@ -317,6 +327,9 @@ extern std::vector<RTLIL::Design*> pushed_designs;
// from passes/cmds/pluginc.cc
extern std::map<std::string, void*> loaded_plugins;
#ifdef WITH_PYTHON
extern std::map<std::string, void*> loaded_python_plugins;
#endif
extern std::map<std::string, std::string> loaded_plugin_aliases;
void load_plugin(std::string filename, std::vector<std::string> aliases);

View File

@ -23,9 +23,18 @@
# include <dlfcn.h>
#endif
#ifdef WITH_PYTHON
# include <boost/algorithm/string/predicate.hpp>
# include <Python.h>
# include <boost/filesystem.hpp>
#endif
YOSYS_NAMESPACE_BEGIN
std::map<std::string, void*> loaded_plugins;
#ifdef WITH_PYTHON
std::map<std::string, void*> loaded_python_plugins;
#endif
std::map<std::string, std::string> loaded_plugin_aliases;
#ifdef YOSYS_ENABLE_PLUGINS
@ -36,7 +45,35 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)
if (filename.find('/') == std::string::npos)
filename = "./" + filename;
#ifdef WITH_PYTHON
if (!loaded_plugins.count(filename) && !loaded_python_plugins.count(filename)) {
#else
if (!loaded_plugins.count(filename)) {
#endif
#ifdef WITH_PYTHON
boost::filesystem::path full_path(filename);
if(strcmp(full_path.extension().c_str(), ".py") == 0)
{
std::string path(full_path.parent_path().c_str());
filename = full_path.filename().c_str();
filename = filename.substr(0,filename.size()-3);
PyRun_SimpleString(("sys.path.insert(0,\""+path+"\")").c_str());
PyErr_Print();
PyObject *module_p = PyImport_ImportModule(filename.c_str());
if(module_p == NULL)
{
PyErr_Print();
log_cmd_error("Can't load python module `%s'\n", full_path.filename().c_str());
return;
}
loaded_python_plugins[orig_filename] = module_p;
Pass::init_register();
} else {
#endif
void *hdl = dlopen(filename.c_str(), RTLD_LAZY|RTLD_LOCAL);
if (hdl == NULL && orig_filename.find('/') == std::string::npos)
hdl = dlopen((proc_share_dirname() + "plugins/" + orig_filename + ".so").c_str(), RTLD_LAZY|RTLD_LOCAL);
@ -44,6 +81,10 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)
log_cmd_error("Can't load module `%s': %s\n", filename.c_str(), dlerror());
loaded_plugins[orig_filename] = hdl;
Pass::init_register();
#ifdef WITH_PYTHON
}
#endif
}
for (auto &alias : aliases)
@ -107,7 +148,11 @@ struct PluginPass : public Pass {
if (list_mode)
{
log("\n");
#ifdef WITH_PYTHON
if (loaded_plugins.empty() and loaded_python_plugins.empty())
#else
if (loaded_plugins.empty())
#endif
log("No plugins loaded.\n");
else
log("Loaded plugins:\n");
@ -115,6 +160,11 @@ struct PluginPass : public Pass {
for (auto &it : loaded_plugins)
log(" %s\n", it.first.c_str());
#ifdef WITH_PYTHON
for (auto &it : loaded_python_plugins)
log(" %s\n", it.first.c_str());
#endif
if (!loaded_plugin_aliases.empty()) {
log("\n");
int max_alias_len = 1;

View File

@ -111,9 +111,10 @@ struct AttrmapMap : AttrmapAction {
};
struct AttrmapRemove : AttrmapAction {
bool has_value;
string name, value;
bool apply(IdString &id, Const &val) YS_OVERRIDE {
return !(match_name(name, id) && match_value(value, val));
return !(match_name(name, id) && (!has_value || match_value(value, val)));
}
};
@ -235,6 +236,7 @@ struct AttrmapPass : public Pass {
}
auto action = new AttrmapRemove;
action->name = arg1;
action->has_value = (p != string::npos);
action->value = val1;
actions.push_back(std::unique_ptr<AttrmapAction>(action));
continue;

View File

@ -1036,7 +1036,7 @@ struct TechmapPass : public Pass {
simplemap_get_mappers(worker.simplemap_mappers);
std::vector<std::string> map_files;
std::string verilog_frontend = "verilog -nooverwrite";
std::string verilog_frontend = "verilog -nooverwrite -noblackbox";
int max_iter = -1;
size_t argidx;

2096
py_wrap_generator.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,17 @@
OBJS += techlibs/gowin/synth_gowin.o
OBJS += techlibs/gowin/determine_init.o
$(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_sim.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/arith_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/bram.txt))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/drams_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/dram.txt))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_init3.vh))

29
techlibs/gowin/bram.txt Normal file
View File

@ -0,0 +1,29 @@
bram $__GW1NR_SDP
# uncomment when done
# init 1
abits 10 @a10d18
dbits 16 @a10d18
abits 11 @a11d9
dbits 8 @a11d9
abits 12 @a12d4
dbits 4 @a12d4
abits 13 @a13d2
dbits 2 @a13d2
abits 14 @a14d1
dbits 1 @a14d1
groups 2
ports 1 1
wrmode 1 0
enable 1 1 @a10d18
enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
transp 0 0
clocks 2 3
clkpol 2 3
endbram
match $__GW1NR_SDP
min bits 2048
min efficiency 5
shuffle_enable B
make_transp
endmatch

View File

@ -0,0 +1,12 @@
localparam [15:0] INIT_0 = {
INIT[ 60], INIT[ 56], INIT[ 52], INIT[ 48], INIT[ 44], INIT[ 40], INIT[ 36], INIT[ 32], INIT[ 28], INIT[ 24], INIT[ 20], INIT[ 16], INIT[ 12], INIT[ 8], INIT[ 4], INIT[ 0]
};
localparam [15:0] INIT_1 = {
INIT[ 61], INIT[ 57], INIT[ 53], INIT[ 49], INIT[ 45], INIT[ 41], INIT[ 37], INIT[ 33], INIT[ 29], INIT[ 25], INIT[ 21], INIT[ 17], INIT[ 13], INIT[ 9], INIT[ 5], INIT[ 1]
};
localparam [15:0] INIT_2 = {
INIT[ 62], INIT[ 58], INIT[ 54], INIT[ 50], INIT[ 46], INIT[ 42], INIT[ 38], INIT[ 34], INIT[ 30], INIT[ 26], INIT[ 22], INIT[ 18], INIT[ 14], INIT[ 10], INIT[ 6], INIT[ 2]
};
localparam [15:0] INIT_3 = {
INIT[ 63], INIT[ 59], INIT[ 55], INIT[ 51], INIT[ 47], INIT[ 43], INIT[ 39], INIT[ 35], INIT[ 31], INIT[ 27], INIT[ 23], INIT[ 19], INIT[ 15], INIT[ 11], INIT[ 7], INIT[ 3]
};

103
techlibs/gowin/brams_map.v Normal file
View File

@ -0,0 +1,103 @@
/* Semi Dual Port (SDP) memory have the following configurations:
* Memory Config RAM(BIT) Port Mode Memory Depth Data Depth
* ----------------|---------| ----------|--------------|------------|
* B-SRAM_16K_SD1 16K 16Kx1 16,384 1
* B-SRAM_8K_SD2 16K 8Kx2 8,192 2
* B-SRAM_4K_SD4 16K 4Kx2 4,096 4
*/
module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter CFG_ABITS = 10;
parameter CFG_DBITS = 16;
parameter CFG_ENABLE_A = 3;
parameter [16383:0] INIT = 16384'hx;
parameter CLKPOL2 = 1;
parameter CLKPOL3 = 1;
input CLK2;
input CLK3;
input [CFG_ABITS-1:0] A1ADDR;
input [CFG_DBITS-1:0] A1DATA;
input [CFG_ENABLE_A-1:0] A1EN;
input [CFG_ABITS-1:0] B1ADDR;
output [CFG_DBITS-1:0] B1DATA;
input B1EN;
generate if (CFG_DBITS == 1) begin
SDP #(
.READ_MODE(0),
.BIT_WIDTH_0(1),
.BIT_WIDTH_1(1),
.BLK_SEL(3'b000),
.RESET_MODE("SYNC")
) _TECHMAP_REPLACE_ (
.CLKA(CLK2), .CLKB(CLK3),
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
.WREB(1'b0), .CEB(B1EN),
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
);
end else if (CFG_DBITS == 2) begin
SDP #(
.READ_MODE(0),
.BIT_WIDTH_0(2),
.BIT_WIDTH_1(2),
.BLK_SEL(3'b000),
.RESET_MODE("SYNC")
) _TECHMAP_REPLACE_ (
.CLKA(CLK2), .CLKB(CLK3),
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
.WREB(1'b0), .CEB(B1EN),
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
);
end else if (CFG_DBITS <= 4) begin
SDP #(
.READ_MODE(0),
.BIT_WIDTH_0(4),
.BIT_WIDTH_1(4),
.BLK_SEL(3'b000),
.RESET_MODE("SYNC")
) _TECHMAP_REPLACE_ (
.CLKA(CLK2), .CLKB(CLK3),
.WREA(A1EN), .OCE(1'b0),
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
);
end else if (CFG_DBITS <= 8) begin
SDP #(
.READ_MODE(0),
.BIT_WIDTH_0(8),
.BIT_WIDTH_1(8),
.BLK_SEL(3'b000),
.RESET_MODE("SYNC")
) _TECHMAP_REPLACE_ (
.CLKA(CLK2), .CLKB(CLK3),
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
.WREB(1'b0), .CEB(B1EN),
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
);
end else if (CFG_DBITS <= 16) begin
SDP #(
.READ_MODE(0),
.BIT_WIDTH_0(16),
.BIT_WIDTH_1(16),
.BLK_SEL(3'b000),
.RESET_MODE("SYNC")
) _TECHMAP_REPLACE_ (
.CLKA(CLK2), .CLKB(CLK3),
.WREA(A1EN), .OCE(1'b0),
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
);
end else begin
wire TECHMAP_FAIL = 1'b1;
end endgenerate
endmodule

View File

@ -1,5 +1,9 @@
module \$_DFF_N_ (input D, C, output Q); DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
module \$_DFF_P_ (input D, C, output Q); DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
module \$_DFF_P_ #(parameter INIT = 1'b0) (input D, C, output Q); DFF #(.INIT(INIT)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
module \$__DFFS_PN0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule
module \$__DFFS_PP0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
module \$__DFFS_PP1_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
module \$lut (A, Y);
parameter WIDTH = 0;

View File

@ -38,6 +38,17 @@ module DFFN (output reg Q, input CLK, D);
Q <= D;
endmodule
module DFFR (output reg Q, input D, CLK, RESET);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;
always @(posedge CLK) begin
if (RESET)
Q <= 1'b0;
else
Q <= D;
end
endmodule // DFFR (positive clock edge; synchronous reset)
module VCC(output V);
assign V = 1;
endmodule
@ -63,3 +74,126 @@ module ALU (input I0, input I1, input I3, input CIN, output COUT, output SUM);
assign {COUT, SUM} = CIN + I1 + I0;
endmodule // alu
module RAM16S4 (DO, DI, AD, WRE, CLK);
parameter WIDTH = 4;
parameter INIT_0 = 16'h0000;
parameter INIT_1 = 16'h0000;
parameter INIT_2 = 16'h0000;
parameter INIT_3 = 16'h0000;
input [WIDTH-1:0] AD;
input [WIDTH-1:0] DI;
output [WIDTH-1:0] DO;
input CLK;
input WRE;
reg [15:0] mem0, mem1, mem2, mem3;
initial begin
mem0 = INIT_0;
mem1 = INIT_1;
mem2 = INIT_2;
mem3 = INIT_3;
end
assign DO[0] = mem0[AD];
assign DO[1] = mem1[AD];
assign DO[2] = mem2[AD];
assign DO[3] = mem3[AD];
always @(posedge CLK) begin
if (WRE) begin
mem0[AD] <= DI[0];
mem1[AD] <= DI[1];
mem2[AD] <= DI[2];
mem3[AD] <= DI[3];
end
end
endmodule // RAM16S4
(* blackbox *)
module SDP (DO, DI, BLKSEL, ADA, ADB, WREA, WREB, CLKA, CLKB, CEA, CEB, OCE, RESETA, RESETB);
//1'b0: Bypass mode; 1'b1 Pipeline mode
parameter READ_MODE = 1'b0;
parameter BIT_WIDTH_0 = 32; // 1, 2, 4, 8, 16, 32
parameter BIT_WIDTH_1 = 32; // 1, 2, 4, 8, 16, 32
parameter BLK_SEL = 3'b000;
parameter RESET_MODE = "SYNC";
parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
input CLKA, CEA, CLKB, CEB;
input OCE; // clock enable of memory output register
input RESETA, RESETB; // resets output registers, not memory contents
input WREA, WREB; // 1'b0: read enabled; 1'b1: write enabled
input [13:0] ADA, ADB;
input [31:0] DI;
input [2:0] BLKSEL;
output [31:0] DO;
endmodule

View File

@ -0,0 +1,72 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct DetermineInitPass : public Pass {
DetermineInitPass() : Pass("determine_init", "Determine the init value of cells") { }
void help() YS_OVERRIDE
{
log("\n");
log(" determine_init [selection]\n");
log("\n");
log("Determine the init value of cells that doesn't allow unknown init value.\n");
log("\n");
}
Const determine_init(Const init)
{
for (int i = 0; i < GetSize(init); i++) {
if (init[i] != State::S0 && init[i] != State::S1)
init[i] = State::S0;
}
return init;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing DETERMINE_INIT pass (determine init value for cells).\n");
extra_args(args, args.size(), design);
size_t cnt = 0;
for (auto module : design->selected_modules())
{
for (auto cell : module->selected_cells())
{
if (cell->type == "\\RAM16S4")
{
cell->setParam("\\INIT_0", determine_init(cell->getParam("\\INIT_0")));
cell->setParam("\\INIT_1", determine_init(cell->getParam("\\INIT_1")));
cell->setParam("\\INIT_2", determine_init(cell->getParam("\\INIT_2")));
cell->setParam("\\INIT_3", determine_init(cell->getParam("\\INIT_3")));
cnt++;
}
}
}
log_header(design, "Updated %lu cells with determined init value.\n", cnt);
}
} DetermineInitPass;
PRIVATE_NAMESPACE_END

17
techlibs/gowin/dram.txt Normal file
View File

@ -0,0 +1,17 @@
bram $__GW1NR_RAM16S4
init 1
abits 4
dbits 4
groups 2
ports 1 1
wrmode 0 1
enable 0 1
transp 0 1
clocks 0 1
clkpol 0 1
endbram
match $__GW1NR_RAM16S4
make_outreg
min wports 1
endmatch

View File

@ -0,0 +1,31 @@
module \$__GW1NR_RAM16S4 (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter CFG_ABITS = 4;
parameter CFG_DBITS = 4;
parameter [63:0] INIT = 64'bx;
input CLK1;
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 B1EN;
`include "brams_init3.vh"
RAM16S4
#(.INIT_0(INIT_0),
.INIT_1(INIT_1),
.INIT_2(INIT_2),
.INIT_3(INIT_3))
_TECHMAP_REPLACE_
(.AD(B1ADDR),
.DI(B1DATA),
.DO(A1DATA),
.CLK(CLK1),
.WRE(B1EN));
endmodule

View File

@ -49,9 +49,15 @@ struct SynthGowinPass : public ScriptPass
log(" from label is synonymous to 'begin', and empty to label is\n");
log(" synonymous to the end of the command list.\n");
log("\n");
log(" -nodffe\n");
log(" do not use flipflops with CE in output netlist\n");
log("\n");
log(" -nobram\n");
log(" do not use BRAM cells in output netlist\n");
log("\n");
log(" -nodram\n");
log(" do not use distributed RAM cells in output netlist\n");
log("\n");
log(" -noflatten\n");
log(" do not flatten design before synthesis\n");
log("\n");
@ -65,7 +71,7 @@ struct SynthGowinPass : public ScriptPass
}
string top_opt, vout_file;
bool retime, flatten, nobram;
bool retime, nobram, nodram, flatten, nodffe;
void clear_flags() YS_OVERRIDE
{
@ -73,7 +79,9 @@ struct SynthGowinPass : public ScriptPass
vout_file = "";
retime = false;
flatten = true;
nobram = true;
nobram = false;
nodffe = false;
nodram = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@ -108,6 +116,14 @@ struct SynthGowinPass : public ScriptPass
nobram = true;
continue;
}
if (args[argidx] == "-nodram") {
nodram = true;
continue;
}
if (args[argidx] == "-nodffe") {
nodffe = true;
continue;
}
if (args[argidx] == "-noflatten") {
flatten = false;
continue;
@ -147,25 +163,43 @@ struct SynthGowinPass : public ScriptPass
{
run("synth -run coarse");
}
if (!nobram && check_label("bram", "(skip if -nobram)"))
if (!nobram && check_label("bram", "(skip if -nobram)"))
{
run("memory_bram -rules +/gowin/bram.txt");
run("techmap -map +/gowin/brams_map.v");
run("techmap -map +/gowin/brams_map.v -map +/gowin/cells_sim.v");
}
if (!nodram && check_label("dram", "(skip if -nodram)"))
{
run("memory_bram -rules +/gowin/dram.txt");
run("techmap -map +/gowin/drams_map.v");
run("determine_init");
}
if (check_label("fine"))
{
run("opt -fast -mux_undef -undriven -fine");
run("memory_map");
run("opt -undriven -fine");
run("techmap -map +/techmap.v -map +/gowin/arith_map.v");
run("opt -fine");
run("clean -purge");
run("splitnets -ports");
run("setundef -undriven -zero");
run("techmap -map +/techmap.v");
if (retime || help_mode)
run("abc -dff", "(only if -retime)");
}
if (check_label("map_ffs"))
{
run("dffsr2dff");
run("dff2dffs");
run("opt_clean");
if (!nodffe)
run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
run("techmap -map +/gowin/cells_map.v");
run("opt_expr -mux_undef");
run("simplemap");
}
if (check_label("map_luts"))
{
run("abc -lut 4");
@ -176,8 +210,10 @@ struct SynthGowinPass : public ScriptPass
{
run("techmap -map +/gowin/cells_map.v");
run("hilomap -hicell VCC V -locell GND G");
run("iopadmap -inpad IBUF O:I -outpad OBUF I:O");
run("clean -purge");
run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O", "(unless -noiopads)");
run("dffinit -ff DFF Q INIT");
run("clean");
}
if (check_label("check"))

View File

@ -27,18 +27,27 @@ module SB_IO (
reg dout_q_0, dout_q_1;
reg outena_q;
// IO tile generates a constant 1'b1 internally if global_cen is not connected
wire clken_pulled = CLOCK_ENABLE || CLOCK_ENABLE === 1'bz;
reg clken_pulled_ri;
reg clken_pulled_ro;
generate if (!NEG_TRIGGER) begin
always @(posedge INPUT_CLK) if (CLOCK_ENABLE) din_q_0 <= PACKAGE_PIN;
always @(negedge INPUT_CLK) if (CLOCK_ENABLE) din_q_1 <= PACKAGE_PIN;
always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_0 <= D_OUT_0;
always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_1 <= D_OUT_1;
always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) outena_q <= OUTPUT_ENABLE;
always @(posedge INPUT_CLK) clken_pulled_ri <= clken_pulled;
always @(posedge INPUT_CLK) if (clken_pulled) din_q_0 <= PACKAGE_PIN;
always @(negedge INPUT_CLK) if (clken_pulled_ri) din_q_1 <= PACKAGE_PIN;
always @(posedge OUTPUT_CLK) clken_pulled_ro <= clken_pulled;
always @(posedge OUTPUT_CLK) if (clken_pulled) dout_q_0 <= D_OUT_0;
always @(negedge OUTPUT_CLK) if (clken_pulled_ro) dout_q_1 <= D_OUT_1;
always @(posedge OUTPUT_CLK) if (clken_pulled) outena_q <= OUTPUT_ENABLE;
end else begin
always @(negedge INPUT_CLK) if (CLOCK_ENABLE) din_q_0 <= PACKAGE_PIN;
always @(posedge INPUT_CLK) if (CLOCK_ENABLE) din_q_1 <= PACKAGE_PIN;
always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_0 <= D_OUT_0;
always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_1 <= D_OUT_1;
always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) outena_q <= OUTPUT_ENABLE;
always @(negedge INPUT_CLK) clken_pulled_ri <= clken_pulled;
always @(negedge INPUT_CLK) if (clken_pulled) din_q_0 <= PACKAGE_PIN;
always @(posedge INPUT_CLK) if (clken_pulled_ri) din_q_1 <= PACKAGE_PIN;
always @(negedge OUTPUT_CLK) clken_pulled_ro <= clken_pulled;
always @(negedge OUTPUT_CLK) if (clken_pulled) dout_q_0 <= D_OUT_0;
always @(posedge OUTPUT_CLK) if (clken_pulled_ro) dout_q_1 <= D_OUT_1;
always @(negedge OUTPUT_CLK) if (clken_pulled) outena_q <= OUTPUT_ENABLE;
end endgenerate
always @* begin

View File

@ -132,6 +132,7 @@ struct SynthXilinxPass : public Pass
log(" techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v");
log(" dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT \\\n");
log(" -ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT\n");
log(" clean\n");
log("\n");
log(" check:\n");
log(" hierarchy -check\n");
@ -309,6 +310,7 @@ struct SynthXilinxPass : public Pass
Pass::call(design, "techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v");
Pass::call(design, "dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT "
"-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT");
Pass::call(design, "clean");
}
if (check_label(active, run_from, run_to, "check"))

View File

@ -0,0 +1,38 @@
// coverage for repeat loops outside of constant functions
module counter1(clk, rst, ping);
input clk, rst;
output ping;
reg [31:0] count;
always @(posedge clk) begin
if (rst)
count <= 0;
else
count <= count + 1;
end
assign ping = &count;
endmodule
module counter2(clk, rst, ping);
input clk, rst;
output ping;
reg [31:0] count;
integer i;
reg carry;
always @(posedge clk) begin
carry = 1;
i = 0;
repeat (32) begin
count[i] <= !rst & (count[i] ^ carry);
carry = count[i] & carry;
i = i+1;
end
end
assign ping = &count;
endmodule

View File

@ -0,0 +1,10 @@
read_verilog counters-repeat.v
proc; opt
expose -shared counter1 counter2
miter -equiv -make_assert -make_outputs counter1 counter2 miter
cd miter; flatten; opt
sat -verify -prove-asserts -tempinduct -set-at 1 in_rst 1 -seq 1 -show-inputs -show-outputs

View File

@ -7,7 +7,7 @@ use_modelsim=false
verbose=false
keeprunning=false
makejmode=false
frontend="verilog"
frontend="verilog -noblackbox"
backend_opts="-noattr -noexpr -siminit"
autotb_opts=""
include_opts=""
@ -137,7 +137,7 @@ do
egrep -v '^\s*`timescale' ../$fn > ${bn}_ref.${ext}
else
"$toolsdir"/../../yosys -f "$frontend $include_opts" -b "verilog" -o ${bn}_ref.v ../${fn}
frontend="verilog"
frontend="verilog -noblackbox"
fi
if [ ! -f ../${bn}_tb.v ]; then

View File

@ -53,6 +53,7 @@ echo -n " no explicit top - "
module noTop(a, y);
input a;
output [31:0] y;
assign y = a;
endmodule
EOV
hierarchy -auto-top