From 44b47b57e3825821438460bb7cccd3ff661e4948 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 31 Jan 2017 10:06:06 -0300 Subject: [PATCH 01/22] use Homebrew only if installed --- Makefile | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 01e1f6ad4..57e935174 100644 --- a/Makefile +++ b/Makefile @@ -62,15 +62,17 @@ SED = sed BISON = bison ifeq (Darwin,$(findstring Darwin,$(shell uname))) + BREW := $(shell command -v brew 2> /dev/null) + ifdef BREW + export PKG_CONFIG_PATH = $(shell $(BREW) list libffi | grep pkgconfig | xargs dirname) + BISON = $(shell $(BREW) list bison | grep -m1 "bin/bison") + endif # add macports/homebrew include and library path to search directories, don't use '-rdynamic' and '-lrt': CXXFLAGS += -I/opt/local/include -I/usr/local/opt/readline/include LDFLAGS += -L/opt/local/lib -L/usr/local/opt/readline/lib - # add homebrew's libffi include and library path - CXXFLAGS += $(shell PKG_CONFIG_PATH=$$(brew list libffi | grep pkgconfig | xargs dirname) pkg-config --silence-errors --cflags libffi) - LDFLAGS += $(shell PKG_CONFIG_PATH=$$(brew list libffi | grep pkgconfig | xargs dirname) pkg-config --silence-errors --libs libffi) - # use bison installed by homebrew if available - BISON = $(shell (brew list bison | grep -m1 "bin/bison") || echo bison) - SED = sed + # add macports/homebrew's libffi include and library path + CXXFLAGS += $(shell pkg-config --silence-errors --cflags libffi) + LDFLAGS += $(shell pkg-config --silence-errors --libs libffi) else LDFLAGS += -rdynamic LDLIBS += -lrt From 19f36271c2634f6829b4f7fe75b848aa74fd168d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 7 Feb 2017 11:09:15 -0300 Subject: [PATCH 02/22] Allow standard tools to be overwritten in make invocation --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 57e935174..280c9d6a1 100644 --- a/Makefile +++ b/Makefile @@ -57,9 +57,9 @@ CXXFLAGS += -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -D_YOSYS_ -fPIC -I$(PRE LDFLAGS += -L$(LIBDIR) LDLIBS = -lstdc++ -lm -PKG_CONFIG = pkg-config -SED = sed -BISON = bison +PKG_CONFIG ?= pkg-config +SED ?= sed +BISON ?= bison ifeq (Darwin,$(findstring Darwin,$(shell uname))) BREW := $(shell command -v brew 2> /dev/null) From 7e08e37961a061807cec7aa335edbbab47891ce9 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 7 Feb 2017 11:12:12 -0300 Subject: [PATCH 03/22] Fix compilation on OS X in order to support both MacPorts and Homebrew --- Makefile | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 280c9d6a1..11cef84a2 100644 --- a/Makefile +++ b/Makefile @@ -62,20 +62,32 @@ SED ?= sed BISON ?= bison ifeq (Darwin,$(findstring Darwin,$(shell uname))) - BREW := $(shell command -v brew 2> /dev/null) - ifdef BREW - export PKG_CONFIG_PATH = $(shell $(BREW) list libffi | grep pkgconfig | xargs dirname) - BISON = $(shell $(BREW) list bison | grep -m1 "bin/bison") - endif - # add macports/homebrew include and library path to search directories, don't use '-rdynamic' and '-lrt': - CXXFLAGS += -I/opt/local/include -I/usr/local/opt/readline/include - LDFLAGS += -L/opt/local/lib -L/usr/local/opt/readline/lib - # add macports/homebrew's libffi include and library path - CXXFLAGS += $(shell pkg-config --silence-errors --cflags libffi) - LDFLAGS += $(shell pkg-config --silence-errors --libs libffi) + +# homebrew search paths +ifneq ($(shell which brew),) +BREW_PREFIX := $(shell brew --prefix)/opt + +CXXFLAGS += -I$(BREW_PREFIX)/readline/include +LDFLAGS += -L$(BREW_PREFIX)/readline/lib + +export PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) +export PATH := $(BREW_PREFIX)/bison/bin:$(BREW_PREFIX)/gettext/bin:$(BREW_PREFIX)/flex/bin:$(PATH) +endif + +# macports search paths +ifneq ($(shell which port),) +PORT_PREFIX := $(patsubst %/bin/port,%,$(shell which port)) + +CXXFLAGS += -I$(PORT_PREFIX)/include +LDFLAGS += -L$(PORT_PREFIX)/lib + +export PKG_CONFIG_PATH := $(PORT_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH) +export PATH := $(PORT_PREFIX)/bin:$(PATH) +endif + else - LDFLAGS += -rdynamic - LDLIBS += -lrt +LDFLAGS += -rdynamic +LDLIBS += -lrt endif YOSYS_VER := 0.7+$(shell cd $(YOSYS_SRC) && test -e .git && { git log --author=clifford@clifford.at --oneline 61f6811.. | wc -l; }) From b8d531957d4ff77afa10f12a7909f763aa367230 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 7 Feb 2017 11:12:31 -0300 Subject: [PATCH 04/22] Added notes for compilation on OS X --- README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9b9f72cc0..f56bbf8cd 100644 --- a/README.md +++ b/README.md @@ -40,14 +40,14 @@ Web Site More information and documentation can be found on the Yosys web site: http://www.clifford.at/yosys/ - -Getting Started -=============== +Setup +====== You need a C++ compiler with C++11 support (up-to-date CLANG or GCC is recommended) and some standard tools such as GNU Flex, GNU Bison, and GNU Make. TCL, readline and libffi are optional (see ENABLE_* settings in Makefile). Xdot (graphviz) is used by the ``show`` command in yosys to display schematics. + For example on Ubuntu Linux 16.04 LTS the following commands will install all prerequisites for building yosys: @@ -55,6 +55,13 @@ prerequisites for building yosys: libreadline-dev gawk tcl-dev libffi-dev git mercurial \ graphviz xdot pkg-config python3 +Similarily, on Mac OS X MacPorts or Homebrew can be used to install dependencies: + + $ brew install bison flex gawk libffi \ + git mercurial graphviz pkg-config python3 + $ sudo port install bison flex readline gawk libffi \ + git mercurial graphviz pkg-config python3 + 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 more information: http://www.clifford.at/yosys/download.html @@ -80,6 +87,9 @@ To build Yosys simply type 'make' in this directory. Note that this also downloads, builds and installs ABC (using yosys-abc as executable name). +Getting Started +=============== + Yosys can be used with the interactive command shell, with synthesis scripts or with command line arguments. Let's perform a simple synthesis job using the interactive command shell: From 2ca8d483dde46e72f17f862ca117e2dd944e9709 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 9 Feb 2017 12:53:46 +0100 Subject: [PATCH 05/22] Add "rand" and "rand const" verific support --- frontends/verific/verific.cc | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index f3b997dc5..3f5cf3f5f 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -617,6 +617,9 @@ struct VerificImporter module->fixup_ports(); + pool anyconst_nets; + pool anyseq_nets; + FOREACH_NET_OF_NETLIST(nl, mi, net) { if (net->IsRamNet()) @@ -646,6 +649,15 @@ struct VerificImporter continue; } + const char *rand_const_attr = net->GetAttValue(" rand_const"); + const char *rand_attr = net->GetAttValue(" rand"); + + if (rand_const_attr != nullptr && !strcmp(rand_const_attr, "1")) + anyconst_nets.insert(net); + + else if (rand_attr != nullptr && !strcmp(rand_attr, "1")) + anyseq_nets.insert(net); + if (net_map.count(net)) { // log(" skipping net %s.\n", net->Name()); continue; @@ -700,8 +712,37 @@ struct VerificImporter { // log(" skipping netbus %s.\n", netbus->Name()); } + + SigSpec anyconst_sig; + SigSpec anyseq_sig; + + for (int i = netbus->RightIndex();; i += netbus->IsUp() ? -1 : +1) { + net = netbus->ElementAtIndex(i); + if (net != nullptr && anyconst_nets.count(net)) { + anyconst_sig.append(net_map.at(net)); + anyconst_nets.erase(net); + } + if (net != nullptr && anyseq_nets.count(net)) { + anyseq_sig.append(net_map.at(net)); + anyseq_nets.erase(net); + } + if (i == netbus->LeftIndex()) + break; + } + + if (GetSize(anyconst_sig)) + module->connect(anyconst_sig, module->Anyconst(NEW_ID, GetSize(anyconst_sig))); + + if (GetSize(anyseq_sig)) + module->connect(anyseq_sig, module->Anyseq(NEW_ID, GetSize(anyseq_sig))); } + for (auto net : anyconst_nets) + module->connect(net_map.at(net), module->Anyconst(NEW_ID)); + + for (auto net : anyseq_nets) + module->connect(net_map.at(net), module->Anyseq(NEW_ID)); + FOREACH_INSTANCE_OF_NETLIST(nl, mi, inst) { if (inst->Type() == PRIM_SVA_POSEDGE) { From 848062088cfc702ba2f4616e1091f63c636bbe5b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 9 Feb 2017 13:51:44 +0100 Subject: [PATCH 06/22] Add checker support to verilog front-end --- README.md | 12 +++++++++--- frontends/verilog/verilog_lexer.l | 20 +++++++++++--------- frontends/verilog/verilog_parser.y | 15 +++++++++++++-- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 396189d5f..3d3ff422e 100644 --- a/README.md +++ b/README.md @@ -379,10 +379,13 @@ Non-standard or SystemVerilog features for formal verification to 0 otherwise. - The system task ``$anyconst`` evaluates to any constant value. This is - equivalent to declaring a reg as ``const rand``. + equivalent to declaring a reg as ``rand const``, but also works outside + of checkers. (Yosys also supports ``rand const`` outside checkers.) - The system task ``$anyseq`` evaluates to any value, possibly a different - value in each cycle. This is equivalent to declaring a reg as ``rand``. + value in each cycle. This is equivalent to declaring a reg as ``rand``, + but also works outside of checkers. (Yosys also supports ``rand`` + variables outside checkers.) - The SystemVerilog tasks ``$past``, ``$stable``, ``$rose`` and ``$fell`` are supported in any clocked block. @@ -407,7 +410,10 @@ from SystemVerilog: - The keywords ``always_comb``, ``always_ff`` and ``always_latch``, ``logic`` and ``bit`` are supported. -- Declaring free variables with ``rand`` and ``const rand`` is supported. +- Declaring free variables with ``rand`` and ``rand const`` is supported. + +- Checkers without a port list that do not need to be instantiated (but instead + behave like a named block) are supported. - SystemVerilog packages are supported. Once a SystemVerilog file is read into a design with ``read_verilog``, all its packages are available to diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 97af0ae2d..ff2fa5753 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -175,15 +175,17 @@ YOSYS_NAMESPACE_END "always_ff" { SV_KEYWORD(TOK_ALWAYS); } "always_latch" { SV_KEYWORD(TOK_ALWAYS); } -"assert" { if (formal_mode) return TOK_ASSERT; SV_KEYWORD(TOK_ASSERT); } -"assume" { if (formal_mode) return TOK_ASSUME; SV_KEYWORD(TOK_ASSUME); } -"cover" { if (formal_mode) return TOK_COVER; SV_KEYWORD(TOK_COVER); } -"restrict" { if (formal_mode) return TOK_RESTRICT; SV_KEYWORD(TOK_RESTRICT); } -"property" { if (formal_mode) return TOK_PROPERTY; SV_KEYWORD(TOK_PROPERTY); } -"rand" { if (formal_mode) return TOK_RAND; SV_KEYWORD(TOK_RAND); } -"const" { if (formal_mode) return TOK_CONST; SV_KEYWORD(TOK_CONST); } -"logic" { SV_KEYWORD(TOK_REG); } -"bit" { SV_KEYWORD(TOK_REG); } +"assert" { if (formal_mode) return TOK_ASSERT; SV_KEYWORD(TOK_ASSERT); } +"assume" { if (formal_mode) return TOK_ASSUME; SV_KEYWORD(TOK_ASSUME); } +"cover" { if (formal_mode) return TOK_COVER; SV_KEYWORD(TOK_COVER); } +"restrict" { if (formal_mode) return TOK_RESTRICT; SV_KEYWORD(TOK_RESTRICT); } +"property" { if (formal_mode) return TOK_PROPERTY; SV_KEYWORD(TOK_PROPERTY); } +"rand" { if (formal_mode) return TOK_RAND; SV_KEYWORD(TOK_RAND); } +"const" { if (formal_mode) return TOK_CONST; SV_KEYWORD(TOK_CONST); } +"checker" { if (formal_mode) return TOK_CHECKER; SV_KEYWORD(TOK_CHECKER); } +"endchecker" { if (formal_mode) return TOK_ENDCHECKER; SV_KEYWORD(TOK_ENDCHECKER); } +"logic" { SV_KEYWORD(TOK_REG); } +"bit" { SV_KEYWORD(TOK_REG); } "input" { return TOK_INPUT; } "output" { return TOK_OUTPUT; } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 3eb03dfd8..1879ff441 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -116,7 +116,7 @@ static void free_attr(std::map *al) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_ASSUME %token TOK_RESTRICT TOK_COVER TOK_PROPERTY TOK_ENUM TOK_TYPEDEF -%token TOK_RAND TOK_CONST +%token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER %type range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int %type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list @@ -465,7 +465,18 @@ module_body: module_body_stmt: task_func_decl | param_decl | localparam_decl | defparam_decl | wire_decl | assign_stmt | cell_stmt | - always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property; + always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl; + +checker_decl: + TOK_CHECKER TOK_ID ';' { + AstNode *node = new AstNode(AST_GENBLOCK); + node->str = *$2; + ast_stack.back()->children.push_back(node); + ast_stack.push_back(node); + } module_body TOK_ENDCHECKER { + delete $2; + ast_stack.pop_back(); + }; task_func_decl: attr TOK_DPI_FUNCTION TOK_ID TOK_ID { From e6cc67b46f637e5fc971c79e8f115c225b807120 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 9 Feb 2017 16:06:58 +0100 Subject: [PATCH 07/22] Fix handling of init attributes with strange width --- passes/opt/opt_merge.cc | 8 ++++++-- passes/opt/opt_rmdff.cc | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index 97989d271..07e4dd39f 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -280,8 +280,12 @@ struct OptMergeWorker dff_init_map.set(module); for (auto &it : module->wires_) - if (it.second->attributes.count("\\init") != 0) - dff_init_map.add(it.second, it.second->attributes.at("\\init")); + if (it.second->attributes.count("\\init") != 0) { + Const initval = it.second->attributes.at("\\init"); + for (int i = 0; i < GetSize(initval) && i < GetSize(it.second); i++) + if (initval[i] == State::S0 || initval[i] == State::S1) + dff_init_map.add(SigBit(it.second, i), initval[i]); + } bool did_something = true; while (did_something) diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 00094738c..0eefd6a86 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -244,7 +244,9 @@ struct OptRmdffPass : public Pass { { if (wire->attributes.count("\\init") != 0) { Const initval = wire->attributes.at("\\init"); - dff_init_map.add(wire, initval); + for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) + if (initval[i] == State::S0 || initval[i] == State::S1) + dff_init_map.add(SigBit(wire, i), initval[i]); for (int i = 0; i < GetSize(wire); i++) { SigBit wire_bit(wire, i), mapped_bit = assign_map(wire_bit); if (mapped_bit.wire) { From 94c76f85da755e1d6bcba7d746deba2223016dcf Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 9 Feb 2017 18:53:37 -0300 Subject: [PATCH 08/22] Applied fixes from @joshhead (thanks for your effors!) --- Makefile | 10 ++++++---- README.md | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 11cef84a2..50dc1b865 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,8 @@ BREW_PREFIX := $(shell brew --prefix)/opt CXXFLAGS += -I$(BREW_PREFIX)/readline/include LDFLAGS += -L$(BREW_PREFIX)/readline/lib -export PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) +PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) + export PATH := $(BREW_PREFIX)/bison/bin:$(BREW_PREFIX)/gettext/bin:$(BREW_PREFIX)/flex/bin:$(PATH) endif @@ -81,7 +82,8 @@ PORT_PREFIX := $(patsubst %/bin/port,%,$(shell which port)) CXXFLAGS += -I$(PORT_PREFIX)/include LDFLAGS += -L$(PORT_PREFIX)/lib -export PKG_CONFIG_PATH := $(PORT_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH) +PKG_CONFIG_PATH := $(PORT_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH) + export PATH := $(PORT_PREFIX)/bin:$(PATH) endif @@ -224,8 +226,8 @@ endif endif ifeq ($(ENABLE_PLUGINS),1) -CXXFLAGS += -DYOSYS_ENABLE_PLUGINS $(shell $(PKG_CONFIG) --silence-errors --cflags libffi) -LDLIBS += $(shell $(PKG_CONFIG) --silence-errors --libs libffi || echo -lffi) -ldl +CXXFLAGS += -DYOSYS_ENABLE_PLUGINS $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --cflags libffi) +LDLIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs libffi || echo -lffi) -ldl endif ifeq ($(ENABLE_TCL),1) diff --git a/README.md b/README.md index f56bbf8cd..b4b3d36ee 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Similarily, on Mac OS X MacPorts or Homebrew can be used to install dependencies $ brew install bison flex gawk libffi \ git mercurial graphviz pkg-config python3 $ sudo port install bison flex readline gawk libffi \ - git mercurial graphviz pkg-config python3 + git mercurial graphviz pkgconfig python36 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 From a3f19f047c4f6fa659bfbb04524ffa42804a5d26 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 9 Feb 2017 19:08:21 -0300 Subject: [PATCH 09/22] Remove space after backslash --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b4b3d36ee..79abad629 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Similarily, on Mac OS X MacPorts or Homebrew can be used to install dependencies $ brew install bison flex gawk libffi \ git mercurial graphviz pkg-config python3 - $ sudo port install bison flex readline gawk libffi \ + $ sudo port install bison flex readline gawk libffi \ git mercurial graphviz pkgconfig python36 There are also pre-compiled Yosys binary packages for Ubuntu and Win32 as well From 9eca3671abe054e973b6c38c6670b0053954b4c2 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 10 Feb 2017 10:04:42 -0300 Subject: [PATCH 10/22] Dont mix Homebrew and MacPorts build options --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 50dc1b865..1a430277f 100644 --- a/Makefile +++ b/Makefile @@ -73,10 +73,9 @@ LDFLAGS += -L$(BREW_PREFIX)/readline/lib PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) export PATH := $(BREW_PREFIX)/bison/bin:$(BREW_PREFIX)/gettext/bin:$(BREW_PREFIX)/flex/bin:$(PATH) -endif # macports search paths -ifneq ($(shell which port),) +else ifneq ($(shell which port),) PORT_PREFIX := $(patsubst %/bin/port,%,$(shell which port)) CXXFLAGS += -I$(PORT_PREFIX)/include From 422ffd5c0699613f98cff3c45267b0af7d944a80 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 10 Feb 2017 10:06:54 -0300 Subject: [PATCH 11/22] Use pkg-config for linking tcl-tk Both MacPorts and Homebrew have a pkg-config file for TCL. So lets use it. --- Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 1a430277f..50b189081 100644 --- a/Makefile +++ b/Makefile @@ -71,6 +71,7 @@ CXXFLAGS += -I$(BREW_PREFIX)/readline/include LDFLAGS += -L$(BREW_PREFIX)/readline/lib PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) +PKG_CONFIG_PATH := $(BREW_PREFIX)/tcl-tk/lib/pkgconfig:$(PKG_CONFIG_PATH) export PATH := $(BREW_PREFIX)/bison/bin:$(BREW_PREFIX)/gettext/bin:$(BREW_PREFIX)/flex/bin:$(PATH) @@ -225,15 +226,16 @@ endif endif ifeq ($(ENABLE_PLUGINS),1) -CXXFLAGS += -DYOSYS_ENABLE_PLUGINS $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --cflags libffi) +CXXFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --cflags libffi) -DYOSYS_ENABLE_PLUGINS LDLIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs libffi || echo -lffi) -ldl endif ifeq ($(ENABLE_TCL),1) TCL_VERSION ?= tcl$(shell bash -c "tclsh <(echo 'puts [info tclversion]')") TCL_INCLUDE ?= /usr/include/$(TCL_VERSION) -CXXFLAGS += -I$(TCL_INCLUDE) -DYOSYS_ENABLE_TCL -LDLIBS += -l$(TCL_VERSION) + +CXXFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --cflags tcl || echo -I$(TCL_INCLUDE)) -DYOSYS_ENABLE_TCL +LDLIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --silence-errors --libs tcl || echo -l$(TCL_VERSION)) endif ifeq ($(ENABLE_GPROF),1) From 94b272077d33b3da3df32bf680f69e1af8130cef Mon Sep 17 00:00:00 2001 From: C-Elegans Date: Fri, 10 Feb 2017 10:28:19 -0500 Subject: [PATCH 12/22] Fix issue #306, "Bug in opt -full" Add check for whether the high bit in the constant expression is greater than the width of the variable, and optimizes that to a constant 1 or 0 --- passes/opt/opt_expr.cc | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index b3f2e87ed..7afb380a2 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -1208,6 +1208,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons //width of the variable port int width; + int const_width; bool var_signed; @@ -1216,6 +1217,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons sigVar = cell->getPort("\\A"); sigConst = cell->getPort("\\B"); width = cell->parameters["\\A_WIDTH"].as_int(); + const_width = cell->parameters["\\B_WIDTH"].as_int(); var_signed = cell->parameters["\\A_SIGNED"].as_bool(); } else if (cell->type == "$gt" || cell->type == "$le") { @@ -1223,6 +1225,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons sigVar = cell->getPort("\\B"); sigConst = cell->getPort("\\A"); width = cell->parameters["\\B_WIDTH"].as_int(); + const_width = cell->parameters["\\A_WIDTH"].as_int(); var_signed = cell->parameters["\\B_SIGNED"].as_bool(); } @@ -1265,7 +1268,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } int const_bit_set = get_onehot_bit_index(sigConst); - if (const_bit_set >= 0) { + if (const_bit_set >= 0 && const_bit_set < width) { int bit_set = const_bit_set; RTLIL::SigSpec a_prime(RTLIL::State::S0, width - bit_set); for (int i = bit_set; i < width; i++) { @@ -1284,6 +1287,21 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons did_something = true; goto next_cell; } + else if(const_bit_set >= width && const_bit_set >= 0){ + RTLIL::SigSpec a_prime(RTLIL::State::S0, 1); + if(is_lt){ + a_prime[0] = RTLIL::State::S1; + log("Replacing %s cell `%s' (implementing unsigned X[%d:0] < %s[%d:0]) with constant 0.\n", log_id(cell->type), log_id(cell), width-1, log_signal(sigConst),const_width-1); + } + else{ + log("Replacing %s cell `%s' (implementing unsigned X[%d:0]>= %s[%d:0]) with constant 1.\n", log_id(cell->type), log_id(cell), width-1, log_signal(sigConst),const_width-1); + } + module->connect(cell->getPort("\\Y"), a_prime); + module->remove(cell); + did_something = true; + goto next_cell; + + } } } From a5bfeb9e07e7d160c55c6223c203d6ec124911f0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Feb 2017 10:01:17 +0100 Subject: [PATCH 13/22] Add optimization of (a && 1'b1) and (a || 1'b0) --- passes/opt/opt_expr.cc | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 7afb380a2..9ccc230e8 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -383,7 +383,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (detect_const_and || detect_const_or) { pool input_bits = assign_map(cell->getPort("\\A")).to_sigbit_pool(); - bool found_zero = false, found_one = false, found_inv = false; + bool found_zero = false, found_one = false, found_undef = false, found_inv = false, many_conconst = false; + SigBit non_const_input = State::Sm; if (cell->hasPort("\\B")) { vector more_bits = assign_map(cell->getPort("\\B")).to_sigbit_vector(); @@ -391,12 +392,20 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } for (auto bit : input_bits) { - if (bit == State::S0) - found_zero = true; - if (bit == State::S1) - found_one = true; - if (invert_map.count(bit) && input_bits.count(invert_map.at(bit))) - found_inv = true; + if (bit.wire) { + if (invert_map.count(bit) && input_bits.count(invert_map.at(bit))) + found_inv = true; + if (non_const_input != State::Sm) + many_conconst = true; + non_const_input = many_conconst ? State::Sm : bit; + } else { + if (bit == State::S0) + found_zero = true; + else if (bit == State::S1) + found_one = true; + else + found_undef = true; + } } if (detect_const_and && (found_zero || found_inv)) { @@ -410,6 +419,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons replace_cell(assign_map, module, cell, "const_or", "\\Y", RTLIL::State::S1); goto next_cell; } + + if (non_const_input != State::Sm && !found_undef) { + cover("opt.opt_expr.and_or_buffer"); + replace_cell(assign_map, module, cell, "and_or_buffer", "\\Y", non_const_input); + goto next_cell; + } } if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool", "$reduce_xor", "$reduce_xnor", "$neg") && From a1a82d68f500604d6cb477456b89925e99171e76 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Feb 2017 10:19:21 +0100 Subject: [PATCH 14/22] Make MacOS Makefile stuff more compact --- Makefile | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Makefile b/Makefile index 58c282c3c..77651fdbf 100644 --- a/Makefile +++ b/Makefile @@ -62,31 +62,23 @@ SED ?= sed BISON ?= bison ifeq (Darwin,$(findstring Darwin,$(shell uname))) - # homebrew search paths ifneq ($(shell which brew),) BREW_PREFIX := $(shell brew --prefix)/opt - CXXFLAGS += -I$(BREW_PREFIX)/readline/include LDFLAGS += -L$(BREW_PREFIX)/readline/lib - PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) PKG_CONFIG_PATH := $(BREW_PREFIX)/tcl-tk/lib/pkgconfig:$(PKG_CONFIG_PATH) - export PATH := $(BREW_PREFIX)/bison/bin:$(BREW_PREFIX)/gettext/bin:$(BREW_PREFIX)/flex/bin:$(PATH) # macports search paths else ifneq ($(shell which port),) PORT_PREFIX := $(patsubst %/bin/port,%,$(shell which port)) - CXXFLAGS += -I$(PORT_PREFIX)/include LDFLAGS += -L$(PORT_PREFIX)/lib - PKG_CONFIG_PATH := $(PORT_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH) - export PATH := $(PORT_PREFIX)/bin:$(PATH) endif - else LDFLAGS += -rdynamic LDLIBS += -lrt From 6d4e8673cc1c73df7509b016bd7cc9e67f6384d7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Feb 2017 10:28:13 +0100 Subject: [PATCH 15/22] Evaluate all the $(shell ...) stuff for CXXFLAGS et al only once --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 77651fdbf..2773990a6 100644 --- a/Makefile +++ b/Makefile @@ -53,9 +53,9 @@ all: top-all YOSYS_SRC := $(dir $(firstword $(MAKEFILE_LIST))) VPATH := $(YOSYS_SRC) -CXXFLAGS += -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -D_YOSYS_ -fPIC -I$(PREFIX)/include -LDFLAGS += -L$(LIBDIR) -LDLIBS = -lstdc++ -lm +CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -D_YOSYS_ -fPIC -I$(PREFIX)/include +LDFLAGS := $(LDFLAGS) -L$(LIBDIR) +LDLIBS := $(LDLIBS) -lstdc++ -lm PKG_CONFIG ?= pkg-config SED ?= sed From 95dae6d416bd9e9ca08fea9ab354b6de7e433fdb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Feb 2017 10:50:48 +0100 Subject: [PATCH 16/22] Fixed some "used uninitialized" warnings in opt_expr --- passes/opt/opt_expr.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 9ccc230e8..236908060 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -1242,7 +1242,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons width = cell->parameters["\\B_WIDTH"].as_int(); const_width = cell->parameters["\\A_WIDTH"].as_int(); var_signed = cell->parameters["\\B_SIGNED"].as_bool(); - } + } else + log_abort(); // replace a(signed) < 0 with the high bit of a if (sigConst.is_fully_const() && sigConst.is_fully_zero() && var_signed == true) From 63dfdb5d7fcfb9c0ec2a5352a34cf9119e28766a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Feb 2017 11:08:12 +0100 Subject: [PATCH 17/22] Add log_wire() API --- kernel/log.cc | 7 +++++++ kernel/log.h | 1 + 2 files changed, 8 insertions(+) diff --git a/kernel/log.cc b/kernel/log.cc index cd16bb344..956d93fd1 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -488,6 +488,13 @@ void log_cell(RTLIL::Cell *cell, std::string indent) log("%s", buf.str().c_str()); } +void log_wire(RTLIL::Wire *wire, std::string indent) +{ + std::stringstream buf; + ILANG_BACKEND::dump_wire(buf, indent, wire); + log("%s", buf.str().c_str()); +} + // --------------------------------------------------- // This is the magic behind the code coverage counters // --------------------------------------------------- diff --git a/kernel/log.h b/kernel/log.h index 5b1729eb1..34b8ac3a5 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -90,6 +90,7 @@ template static inline const char *log_id(T *obj) { void log_module(RTLIL::Module *module, std::string indent = ""); void log_cell(RTLIL::Cell *cell, std::string indent = ""); +void log_wire(RTLIL::Wire *wire, std::string indent = ""); #ifndef NDEBUG static inline void log_assert_worker(bool cond, const char *expr, const char *file, int line) { From eb7b18e897ac908e960bee6c976f744043590881 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Feb 2017 11:09:07 +0100 Subject: [PATCH 18/22] Fix extremely stupid typo --- frontends/verific/verific.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 3f5cf3f5f..306bc5d82 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -774,7 +774,7 @@ struct VerificImporter SigBit outsig = net_map.at(out); log_assert(outsig.wire && GetSize(outsig.wire) == 1); - outsig.wire->attributes["\\init"] == Const(0, 1); + outsig.wire->attributes["\\init"] = Const(0, 1); module->addDff(NEW_ID, net_map.at(clk), net_map.at(in2), net_map.at(out)); continue; From 0b7aac645c482e9f8e80fb74b61b5c9c6c378857 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Feb 2017 11:39:50 +0100 Subject: [PATCH 19/22] Improve handling of Verific warnings and error messages --- frontends/verific/verific.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 306bc5d82..36e44fe01 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -57,7 +57,7 @@ PRIVATE_NAMESPACE_BEGIN void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefile, const char *msg, va_list args) { - log("VERIFIC-%s [%s] ", + string message = stringf("VERIFIC-%s [%s] ", msg_type == VERIFIC_NONE ? "NONE" : msg_type == VERIFIC_ERROR ? "ERROR" : msg_type == VERIFIC_WARNING ? "WARNING" : @@ -65,10 +65,16 @@ void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefil msg_type == VERIFIC_INFO ? "INFO" : msg_type == VERIFIC_COMMENT ? "COMMENT" : msg_type == VERIFIC_PROGRAM_ERROR ? "PROGRAM_ERROR" : "UNKNOWN", message_id); + if (linefile) - log("%s:%d: ", LineFile::GetFileName(linefile), LineFile::GetLineNo(linefile)); - logv(msg, args); - log("\n"); + message += stringf("%s:%d: ", LineFile::GetFileName(linefile), LineFile::GetLineNo(linefile)); + + message += vstringf(msg, args); + + if (msg_type == VERIFIC_ERROR || msg_type == VERIFIC_WARNING || msg_type == VERIFIC_PROGRAM_ERROR) + log_warning("%s\n", message.c_str()); + else + log("%s\n", message.c_str()); } struct VerificImporter From fa4a7efe15ccfca6c8200107284d02ee4ddabb9c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Feb 2017 11:40:18 +0100 Subject: [PATCH 20/22] Add verific support for initialized variables --- frontends/verific/verific.cc | 50 +++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 36e44fe01..9af4ce047 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -623,6 +623,7 @@ struct VerificImporter module->fixup_ports(); + dict init_nets; pool anyconst_nets; pool anyseq_nets; @@ -655,6 +656,9 @@ struct VerificImporter continue; } + if (net->GetInitialValue()) + init_nets[net] = net->GetInitialValue(); + const char *rand_const_attr = net->GetAttValue(" rand_const"); const char *rand_attr = net->GetAttValue(" rand"); @@ -701,18 +705,38 @@ struct VerificImporter wire->start_offset = min(netbus->LeftIndex(), netbus->RightIndex()); import_attributes(wire->attributes, netbus); - for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) { - if (netbus->ElementAtIndex(i)) { + RTLIL::Const initval = Const(State::Sx, GetSize(wire)); + bool initval_valid = false; + + for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) + { + if (netbus->ElementAtIndex(i)) + { + int bitidx = i - wire->start_offset; net = netbus->ElementAtIndex(i); - RTLIL::SigBit bit(wire, i - wire->start_offset); + RTLIL::SigBit bit(wire, bitidx); + + if (init_nets.count(net)) { + if (init_nets.at(net) == '0') + initval.bits.at(bitidx) = State::S0; + if (init_nets.at(net) == '1') + initval.bits.at(bitidx) = State::S1; + initval_valid = true; + init_nets.erase(net); + } + if (net_map.count(net) == 0) net_map[net] = bit; else module->connect(bit, net_map.at(net)); } + if (i == netbus->RightIndex()) break; } + + if (initval_valid) + wire->attributes["\\init"] = initval; } else { @@ -743,6 +767,26 @@ struct VerificImporter module->connect(anyseq_sig, module->Anyseq(NEW_ID, GetSize(anyseq_sig))); } + for (auto it : init_nets) + { + Const initval; + SigBit bit = net_map.at(it.first); + log_assert(bit.wire); + + if (bit.wire->attributes.count("\\init")) + initval = bit.wire->attributes.at("\\init"); + + while (GetSize(initval) < GetSize(bit.wire)) + initval.bits.push_back(State::Sx); + + if (it.second == '0') + initval.bits.at(bit.offset) = State::S0; + if (it.second == '1') + initval.bits.at(bit.offset) = State::S1; + + bit.wire->attributes["\\init"] = initval; + } + for (auto net : anyconst_nets) module->connect(net_map.at(net), module->Anyconst(NEW_ID)); From c449f4b86f66ca4ef2396454f09a73d56ff06512 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Feb 2017 11:47:51 +0100 Subject: [PATCH 21/22] Fix another stupid bug in the same line --- frontends/verific/verific.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 9af4ce047..cde72a8e3 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -824,7 +824,7 @@ struct VerificImporter SigBit outsig = net_map.at(out); log_assert(outsig.wire && GetSize(outsig.wire) == 1); - outsig.wire->attributes["\\init"] = Const(0, 1); + outsig.wire->attributes["\\init"] = Const(1, 1); module->addDff(NEW_ID, net_map.at(clk), net_map.at(in2), net_map.at(out)); continue; From cdb6ceb8c63f2c38bdba3f66be7c444def43897e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Feb 2017 15:57:36 +0100 Subject: [PATCH 22/22] Add support for verific mem initialization --- frontends/verific/verific.cc | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index cde72a8e3..bc0bd60fc 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -653,6 +653,44 @@ struct VerificImporter memory->width = bits_in_word; memory->size = number_of_bits / bits_in_word; + + const char *ascii_initdata = net->GetWideInitialValue(); + if (ascii_initdata) { + while (*ascii_initdata != 0 && *ascii_initdata != '\'') + ascii_initdata++; + if (*ascii_initdata == '\'') + ascii_initdata++; + if (*ascii_initdata != 0) { + log_assert(*ascii_initdata == 'b'); + ascii_initdata++; + } + for (int word_idx = 0; word_idx < memory->size; word_idx++) { + Const initval = Const(State::Sx, memory->width); + bool initval_valid = false; + for (int bit_idx = memory->width-1; bit_idx >= 0; bit_idx--) { + if (*ascii_initdata == 0) + break; + if (*ascii_initdata == '0' || *ascii_initdata == '1') { + initval[bit_idx] = (*ascii_initdata == '0') ? State::S0 : State::S1; + initval_valid = true; + } + ascii_initdata++; + } + if (initval_valid) { + RTLIL::Cell *cell = module->addCell(NEW_ID, "$meminit"); + cell->parameters["\\WORDS"] = 1; + if (net->GetOrigTypeRange()->LeftRangeBound() < net->GetOrigTypeRange()->RightRangeBound()) + cell->setPort("\\ADDR", word_idx); + else + cell->setPort("\\ADDR", memory->size - word_idx - 1); + cell->setPort("\\DATA", initval); + cell->parameters["\\MEMID"] = RTLIL::Const(memory->name.str()); + cell->parameters["\\ABITS"] = 32; + cell->parameters["\\WIDTH"] = memory->width; + cell->parameters["\\PRIORITY"] = RTLIL::Const(autoidx-1); + } + } + } continue; }