From 1fdb3fc98cdbd7126f07778397e3c334f45945df Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 19:58:58 -0700 Subject: [PATCH 01/18] Add failing test --- tests/various/hierarchy_defer.ys | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/various/hierarchy_defer.ys diff --git a/tests/various/hierarchy_defer.ys b/tests/various/hierarchy_defer.ys new file mode 100644 index 000000000..170bb8c5f --- /dev/null +++ b/tests/various/hierarchy_defer.ys @@ -0,0 +1,18 @@ +read -vlog2k < Date: Wed, 28 Aug 2019 19:59:09 -0700 Subject: [PATCH 02/18] read_verilog -defer should still populate module attributes --- frontends/ast/ast.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 82283fb5b..6a91c418b 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1073,11 +1073,6 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast ignoreThisSignalsInInitial = RTLIL::SigSpec(); - for (auto &attr : ast->attributes) { - if (attr.second->type != AST_CONSTANT) - log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); - current_module->attributes[attr.first] = attr.second->asAttrConst(); - } for (size_t i = 0; i < ast->children.size(); i++) { AstNode *node = ast->children[i]; if (node->type == AST_WIRE || node->type == AST_MEMORY) @@ -1100,6 +1095,12 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast ignoreThisSignalsInInitial = RTLIL::SigSpec(); } + for (auto &attr : ast->attributes) { + if (attr.second->type != AST_CONSTANT) + log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + current_module->attributes[attr.first] = attr.second->asAttrConst(); + } + if (ast->type == AST_INTERFACE) current_module->set_bool_attribute("\\is_interface"); current_module->ast = ast_before_simplify; From 116c2496011aeeac9847d69af597a0db58209793 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 19:59:25 -0700 Subject: [PATCH 03/18] -auto-top should check $abstract (deferred) modules with (* top *) --- passes/hierarchy/hierarchy.cc | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index fd95b94b2..ad795c69f 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -808,6 +808,37 @@ struct HierarchyPass : public Pass { if (mod_it.second->get_bool_attribute("\\top")) top_mod = mod_it.second; + if (top_mod != nullptr && auto_top_mode) { + IdString abstract_id = top_mod->name; + IdString top_name = abstract_id; + if (top_name.begins_with("$abstract")) + top_name = top_name.substr(strlen("$abstract")); + top_mod = design->module(top_name); + + dict top_parameters; + for (auto ¶ : parameters) { + SigSpec sig_value; + if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second)) + log_cmd_error("Can't decode value '%s'!\n", para.second.c_str()); + top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const(); + } + + if (top_mod == nullptr && design->module(abstract_id)) + top_mod = design->module(design->module(abstract_id)->derive(design, top_parameters)); + else if (top_mod != nullptr && !top_parameters.empty()) + top_mod = design->module(top_mod->derive(design, top_parameters)); + + if (top_mod != nullptr && top_mod->name != top_name) { + Module *m = top_mod->clone(); + m->name = top_name; + Module *old_mod = design->module(top_name); + if (old_mod) + design->remove(old_mod); + design->add(m); + top_mod = m; + } + } + if (top_mod == nullptr && auto_top_mode) { log_header(design, "Finding top of design hierarchy..\n"); dict db; From 6510297712729f9742d00f6a4cd4fc3a0e530758 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 29 Aug 2019 09:02:10 -0700 Subject: [PATCH 04/18] Restore non-deferred code, deferred case to ignore non constant attr --- frontends/ast/ast.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 6a91c418b..01e865557 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1073,6 +1073,12 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast ignoreThisSignalsInInitial = RTLIL::SigSpec(); + for (auto &attr : ast->attributes) { + if (attr.second->type != AST_CONSTANT) + log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + current_module->attributes[attr.first] = attr.second->asAttrConst(); + } + for (size_t i = 0; i < ast->children.size(); i++) { AstNode *node = ast->children[i]; if (node->type == AST_WIRE || node->type == AST_MEMORY) @@ -1094,11 +1100,12 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast ignoreThisSignalsInInitial = RTLIL::SigSpec(); } - - for (auto &attr : ast->attributes) { - if (attr.second->type != AST_CONSTANT) - log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); - current_module->attributes[attr.first] = attr.second->asAttrConst(); + else { + for (auto &attr : ast->attributes) { + if (attr.second->type != AST_CONSTANT) + continue; + current_module->attributes[attr.first] = attr.second->asAttrConst(); + } } if (ast->type == AST_INTERFACE) From 83ffec26cbda434b31a2bbd004213a538bf3e6e6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 29 Aug 2019 09:08:58 -0700 Subject: [PATCH 05/18] Remove newline --- frontends/ast/ast.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 01e865557..a3a78e414 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1078,7 +1078,6 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); current_module->attributes[attr.first] = attr.second->asAttrConst(); } - for (size_t i = 0; i < ast->children.size(); i++) { AstNode *node = ast->children[i]; if (node->type == AST_WIRE || node->type == AST_MEMORY) From 67587bad7fb1adf14ca9598bb1a01d0ffda6a018 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 29 Aug 2019 09:10:20 -0700 Subject: [PATCH 06/18] Add constant expression attribute to test --- tests/various/hierarchy_defer.ys | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/various/hierarchy_defer.ys b/tests/various/hierarchy_defer.ys index 170bb8c5f..0bf4de44e 100644 --- a/tests/various/hierarchy_defer.ys +++ b/tests/various/hierarchy_defer.ys @@ -7,6 +7,7 @@ module top(input i, output o); sub s0(i, o); endmodule +(* constant_expression=1+1?2*2:3/3 *) module sub(input i, output o); assign o = ~i; endmodule From c1459bc748d0d2c47dcb2366e5a0893736d6d463 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 30 Aug 2019 12:22:14 -0700 Subject: [PATCH 07/18] Do not restrict multiplier to unsigned --- passes/pmgen/ice40_dsp.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc index 39d033a04..16bfe537f 100644 --- a/passes/pmgen/ice40_dsp.cc +++ b/passes/pmgen/ice40_dsp.cc @@ -64,11 +64,6 @@ void create_ice40_dsp(ice40_dsp_pm &pm) bool mul_signed = st.mul->getParam("\\A_SIGNED").as_bool(); - if (mul_signed) { - log(" inference of signed iCE40 DSP arithmetic is currently not supported.\n"); - return; - } - log(" replacing $mul with SB_MAC16 cell.\n"); Cell *cell = pm.module->addCell(NEW_ID, "\\SB_MAC16"); From 76a52712dac4f28fbc3c5611911310d252cd91a6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 30 Aug 2019 12:22:59 -0700 Subject: [PATCH 08/18] Improve tests/ice40/macc.ys for SB_MAC16 --- tests/ice40/macc.v | 4 ++-- tests/ice40/macc.ys | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/ice40/macc.v b/tests/ice40/macc.v index 63a3d3a74..6c3676c83 100644 --- a/tests/ice40/macc.v +++ b/tests/ice40/macc.v @@ -2,8 +2,8 @@ Example from: https://www.latticesemi.com/-/media/LatticeSemi/Documents/UserManuals/EI/iCEcube201701UserGuide.ashx?document_id=52071 [p. 77]. */ module top(clk,a,b,c,set); -parameter A_WIDTH = 4; -parameter B_WIDTH = 3; +parameter A_WIDTH = 6 /*4*/; +parameter B_WIDTH = 6 /*3*/; input set; input clk; input signed [(A_WIDTH - 1):0] a; diff --git a/tests/ice40/macc.ys b/tests/ice40/macc.ys index fe5b5f662..0f4c19be5 100644 --- a/tests/ice40/macc.ys +++ b/tests/ice40/macc.ys @@ -1,10 +1,13 @@ read_verilog macc.v proc hierarchy -top top -equiv_opt -assert -map +/ice40/cells_sim.v synth_ice40 -dsp # equivalency check +#equiv_opt -assert -map +/ice40/cells_sim.v synth_ice40 -dsp # equivalency check + +equiv_opt -run :prove -map +/ice40/cells_sim.v synth_ice40 -dsp +async2sync +equiv_opt -run prove: -assert null + design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module -select -assert-count 38 t:SB_LUT4 -select -assert-count 3 t:SB_CARRY -select -assert-count 7 t:SB_DFFSR -select -assert-none t:SB_LUT4 t:SB_CARRY t:SB_DFFSR %% t:* %D +select -assert-count 1 t:SB_MAC16 +select -assert-none t:SB_MAC16 %% t:* %D From 17b77fd41197b64f79bbbb59088e9de623d84716 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 30 Aug 2019 14:00:40 -0700 Subject: [PATCH 09/18] Missing dep for test_pmgen --- passes/pmgen/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index e73a7b1c9..4989c582a 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -4,7 +4,7 @@ # -------------------------------------- OBJS += passes/pmgen/test_pmgen.o -passes/pmgen/test_pmgen.o: passes/pmgen/test_pmgen_pm.h passes/pmgen/ice40_dsp_pm.h passes/pmgen/peepopt_pm.h +passes/pmgen/test_pmgen.o: passes/pmgen/test_pmgen_pm.h passes/pmgen/ice40_dsp_pm.h passes/pmgen/peepopt_pm.h passes/pmgen/xilinx_srl_pm.h $(eval $(call add_extra_objs,passes/pmgen/test_pmgen_pm.h)) # -------------------------------------- From 90b44113d89cd1f028e7805e0990dae43e2efa6f Mon Sep 17 00:00:00 2001 From: David Shah Date: Sat, 31 Aug 2019 09:58:46 +0100 Subject: [PATCH 10/18] ecp5_gsr: Fix typo Signed-off-by: David Shah --- techlibs/ecp5/ecp5_gsr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ecp5/ecp5_gsr.cc b/techlibs/ecp5/ecp5_gsr.cc index 8b8927d31..2bc714b6f 100644 --- a/techlibs/ecp5/ecp5_gsr.cc +++ b/techlibs/ecp5/ecp5_gsr.cc @@ -124,7 +124,7 @@ struct Ecp5GsrPass : public Pass { SigBit lsr = sigmap(sig_lsr[0]); if (!inverted_gsr.count(lsr)) continue; - cell->setParam(ID(SRMODE), Const("SYNC")); + cell->setParam(ID(SRMODE), Const("LSR_OVER_CE")); cell->unsetPort(ID(LSR)); } From a3c16a05657e639a04d647a15af56b6fbce25e17 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 31 Aug 2019 11:12:06 +0200 Subject: [PATCH 11/18] Fix TRELLIS_FF simulation model --- techlibs/ecp5/cells_sim.v | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 75a1aad1f..5bdb8395e 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -229,14 +229,15 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); parameter REGSET = "RESET"; parameter [127:0] LSRMODE = "LSR"; - reg muxce; - always @(*) + wire muxce; + generate case (CEMUX) - "1": muxce = 1'b1; - "0": muxce = 1'b0; - "INV": muxce = ~CE; - default: muxce = CE; + "1": assign muxce = 1'b1; + "0": assign muxce = 1'b0; + "INV": assign muxce = ~CE; + default: assign muxce = CE; endcase + endgenerate wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; From fa5065e9b5ed58d774bfe4fc23de681314b50270 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 1 Sep 2019 11:00:09 +0200 Subject: [PATCH 12/18] Fix select command error msg, fixes issue #1081 --- passes/cmds/select.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 59d10a1b8..0f1f05ccb 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -664,7 +664,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) } else if (arg == "%D") { if (work_stack.size() < 2) - log_cmd_error("Must have at least two elements on the stack for operator %%d.\n"); + log_cmd_error("Must have at least two elements on the stack for operator %%D.\n"); select_op_diff(design, work_stack[work_stack.size()-1], work_stack[work_stack.size()-2]); work_stack[work_stack.size()-2] = work_stack[work_stack.size()-1]; work_stack.pop_back(); @@ -693,7 +693,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) } else if (arg == "%C") { if (work_stack.size() < 1) - log_cmd_error("Must have at least one element on the stack for operator %%M.\n"); + log_cmd_error("Must have at least one element on the stack for operator %%C.\n"); select_op_module_to_cells(design, work_stack[work_stack.size()-1]); } else if (arg == "%c") { From f76cb584940fa3217de28febdb103443b8a8cf37 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 30 Aug 2019 20:15:09 -0700 Subject: [PATCH 13/18] Recognise built-in types (e.g. $_DFF_*) --- backends/aiger/xaiger.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 77d0e94c2..e1b84236d 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -261,11 +261,12 @@ struct XAigerWriter } } else { - bool cell_known = cell->known(); + bool cell_known = inst_module || cell->known(); for (const auto &c : cell->connections()) { if (c.second.is_fully_const()) continue; - auto is_input = !cell_known || cell->input(c.first); - auto is_output = !cell_known || cell->output(c.first); + auto port_wire = inst_module ? inst_module->wire(c.first) : nullptr; + auto is_input = (port_wire && port_wire->port_input) || !cell_known || cell->input(c.first); + auto is_output = (port_wire && port_wire->port_output) || !cell_known || cell->output(c.first); if (!is_input && !is_output) log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); From 69a5dea89ef8cbf8bcc1b761518738623e028e38 Mon Sep 17 00:00:00 2001 From: Emily Date: Tue, 3 Sep 2019 00:57:32 +0100 Subject: [PATCH 14/18] Use `command -v` rather than `which` --- tests/simple/run-test.sh | 2 +- tests/simple_abc9/run-test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/simple/run-test.sh b/tests/simple/run-test.sh index 967ac49f2..f20fd0d30 100755 --- a/tests/simple/run-test.sh +++ b/tests/simple/run-test.sh @@ -12,7 +12,7 @@ done shift "$((OPTIND-1))" # check for Icarus Verilog -if ! which iverilog > /dev/null ; then +if ! command -v iverilog > /dev/null ; then echo "$0: Error: Icarus Verilog 'iverilog' not found." exit 1 fi diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh index 8df6994e3..0d4262005 100755 --- a/tests/simple_abc9/run-test.sh +++ b/tests/simple_abc9/run-test.sh @@ -12,7 +12,7 @@ done shift "$((OPTIND-1))" # check for Icarus Verilog -if ! which iverilog > /dev/null ; then +if ! command -v iverilog > /dev/null ; then echo "$0: Error: Icarus Verilog 'iverilog' not found." exit 1 fi From 81247168302a578add43e3e856eb74868dc5a1ba Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 3 Sep 2019 10:52:34 -0700 Subject: [PATCH 15/18] Add `read -noverific` before read --- tests/various/hierarchy_defer.ys | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/various/hierarchy_defer.ys b/tests/various/hierarchy_defer.ys index 0bf4de44e..baec52c9d 100644 --- a/tests/various/hierarchy_defer.ys +++ b/tests/various/hierarchy_defer.ys @@ -1,3 +1,4 @@ +read -noverific read -vlog2k < Date: Tue, 3 Sep 2019 12:17:26 -0700 Subject: [PATCH 16/18] Expand test with `hierarchy' without -auto-top --- tests/various/hierarchy_defer.ys | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/various/hierarchy_defer.ys b/tests/various/hierarchy_defer.ys index baec52c9d..70f5b70a3 100644 --- a/tests/various/hierarchy_defer.ys +++ b/tests/various/hierarchy_defer.ys @@ -13,8 +13,15 @@ module sub(input i, output o); assign o = ~i; endmodule EOT +design -save read hierarchy -auto-top select -assert-any top select -assert-any sub select -assert-none foo + +design -load read +hierarchy +select -assert-any top +select -assert-any sub +select -assert-none foo From d2306d7b1d9725fef2d1db4e205c1b0cb6c84715 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 3 Sep 2019 12:18:50 -0700 Subject: [PATCH 17/18] Adopt @cliffordwolf's suggestion --- passes/hierarchy/hierarchy.cc | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index ad795c69f..d8a628448 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -808,12 +808,8 @@ struct HierarchyPass : public Pass { if (mod_it.second->get_bool_attribute("\\top")) top_mod = mod_it.second; - if (top_mod != nullptr && auto_top_mode) { - IdString abstract_id = top_mod->name; - IdString top_name = abstract_id; - if (top_name.begins_with("$abstract")) - top_name = top_name.substr(strlen("$abstract")); - top_mod = design->module(top_name); + if (top_mod != nullptr && top_mod->name.begins_with("$abstract")) { + IdString top_name = top_mod->name.substr(strlen("$abstract")); dict top_parameters; for (auto ¶ : parameters) { @@ -823,10 +819,7 @@ struct HierarchyPass : public Pass { top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const(); } - if (top_mod == nullptr && design->module(abstract_id)) - top_mod = design->module(design->module(abstract_id)->derive(design, top_parameters)); - else if (top_mod != nullptr && !top_parameters.empty()) - top_mod = design->module(top_mod->derive(design, top_parameters)); + top_mod = design->module(top_mod->derive(design, top_parameters)); if (top_mod != nullptr && top_mod->name != top_name) { Module *m = top_mod->clone(); From a7ea6a6fcf964f3c368b634e1fcc2c29d3bfdce4 Mon Sep 17 00:00:00 2001 From: Emily Date: Wed, 4 Sep 2019 19:01:00 +0100 Subject: [PATCH 18/18] Replace `which` with `command -v` in Makefile too --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 2cac80f0f..bb26eabed 100644 --- a/Makefile +++ b/Makefile @@ -88,7 +88,7 @@ ifeq ($(OS), Darwin) PLUGIN_LDFLAGS += -undefined dynamic_lookup # homebrew search paths -ifneq ($(shell which brew),) +ifneq ($(shell command -v brew),) BREW_PREFIX := $(shell brew --prefix)/opt $(info $$BREW_PREFIX is [${BREW_PREFIX}]) ifeq ($(ENABLE_PYOSYS),1) @@ -102,8 +102,8 @@ 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)) +else ifneq ($(shell command -v port),) +PORT_PREFIX := $(patsubst %/bin/port,%,$(shell command -v port)) CXXFLAGS += -I$(PORT_PREFIX)/include LDFLAGS += -L$(PORT_PREFIX)/lib PKG_CONFIG_PATH := $(PORT_PREFIX)/lib/pkgconfig:$(PKG_CONFIG_PATH)