From b232e027bf18bd37206c15209e23d2f8f7b2a17d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 22 Apr 2019 02:33:12 +0200 Subject: Checking and fixing specify cells in genRTLIL Signed-off-by: Clifford Wolf --- frontends/ast/genrtlil.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'frontends/ast') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b3a2a84be..b2a22b49a 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1521,9 +1521,23 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(filename, linenum, "Attribute `%s' with non-constant value.\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } + if (cell->type.in("$specify2", "$specify3")) { + int src_width = GetSize(cell->getPort("\\SRC")); + int dst_width = GetSize(cell->getPort("\\DST")); + bool full = cell->getParam("\\FULL").as_bool(); + if (!full && src_width != dst_width) + log_file_error(filename, linenum, "Parallel specify SRC width does not match DST width.\n"); + if (cell->type == "$specify3") { + int dat_width = GetSize(cell->getPort("\\DAT")); + if (dat_width != dst_width) + log_file_error(filename, linenum, "Specify DAT width does not match DST width.\n"); + } + cell->setParam("\\SRC_WIDTH", Const(src_width)); + cell->setParam("\\DST_WIDTH", Const(dst_width)); + } } break; -- cgit v1.2.3 From 012c6af088a22c035ce1244954b6625188478480 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 22 Apr 2019 09:59:49 +0200 Subject: Allow $specify[23] cells in blackbox modules Signed-off-by: Clifford Wolf --- frontends/ast/ast.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'frontends/ast') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 9f88b08c1..6b3604ee5 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -951,6 +951,9 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast continue; if (child->type == AST_PARAMETER || child->type == AST_LOCALPARAM) continue; + if (child->type == AST_CELL && child->children.size() > 0 && child->children[0]->type == AST_CELLTYPE && + (child->children[0]->str == "$specify2" || child->children[0]->str == "$specify3")) + continue; blackbox_module = false; break; } @@ -1035,6 +1038,9 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast child->delete_children(); child->children.push_back(AstNode::mkconst_int(0, false, 0)); new_children.push_back(child); + } else if (child->type == AST_CELL && child->children.size() > 0 && child->children[0]->type == AST_CELLTYPE && + (child->children[0]->str == "$specify2" || child->children[0]->str == "$specify3")) { + new_children.push_back(child); } else { delete child; } -- cgit v1.2.3 From 71c38d9de527e1a8b55ba295df459fbcf2a0fe47 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 23 Apr 2019 15:46:40 +0200 Subject: Add $specrule cells for $setup/$hold/$skew specify rules Signed-off-by: Clifford Wolf --- frontends/ast/ast.cc | 4 ++-- frontends/ast/genrtlil.cc | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'frontends/ast') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 6b3604ee5..5623541b2 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -952,7 +952,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast if (child->type == AST_PARAMETER || child->type == AST_LOCALPARAM) continue; if (child->type == AST_CELL && child->children.size() > 0 && child->children[0]->type == AST_CELLTYPE && - (child->children[0]->str == "$specify2" || child->children[0]->str == "$specify3")) + (child->children[0]->str == "$specify2" || child->children[0]->str == "$specify3" || child->children[0]->str == "$specrule")) continue; blackbox_module = false; break; @@ -1039,7 +1039,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast child->children.push_back(AstNode::mkconst_int(0, false, 0)); new_children.push_back(child); } else if (child->type == AST_CELL && child->children.size() > 0 && child->children[0]->type == AST_CELLTYPE && - (child->children[0]->str == "$specify2" || child->children[0]->str == "$specify3")) { + (child->children[0]->str == "$specify2" || child->children[0]->str == "$specify3" || child->children[0]->str == "$specrule")) { new_children.push_back(child); } else { delete child; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b2a22b49a..48bd466e6 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1538,6 +1538,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->setParam("\\SRC_WIDTH", Const(src_width)); cell->setParam("\\DST_WIDTH", Const(dst_width)); } + if (cell->type == "$specrule") { + int src_width = GetSize(cell->getPort("\\SRC")); + int dst_width = GetSize(cell->getPort("\\DST")); + cell->setParam("\\SRC_WIDTH", Const(src_width)); + cell->setParam("\\DST_WIDTH", Const(dst_width)); + } } break; -- cgit v1.2.3 From 9af825e31e493bec6f0d86b8f30aeee436ed50df Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 30 Apr 2019 15:03:32 +0200 Subject: Add final loop variable assignment when unrolling for-loops, fixes #968 Signed-off-by: Clifford Wolf --- frontends/ast/simplify.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'frontends/ast') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 3e453bd7f..a342bf5d9 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1172,6 +1172,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, varbuf->children[0] = buf; } + if (type == AST_FOR) { + AstNode *buf = next_ast->clone(); + delete buf->children[1]; + buf->children[1] = varbuf->children[0]->clone(); + current_block->children.insert(current_block->children.begin() + current_block_idx++, buf); + } + current_scope[varbuf->str] = backup_scope_varbuf; delete varbuf; delete_children(); -- cgit v1.2.3 From e35fe1344dd4c8f11632ed2a7f5b0463352a1ee4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 30 Apr 2019 20:22:50 +0200 Subject: Disabled "final loop assignment" feature Signed-off-by: Clifford Wolf --- frontends/ast/simplify.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'frontends/ast') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index a342bf5d9..4d4b9dfe1 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1172,12 +1172,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, varbuf->children[0] = buf; } +#if 0 if (type == AST_FOR) { AstNode *buf = next_ast->clone(); delete buf->children[1]; buf->children[1] = varbuf->children[0]->clone(); current_block->children.insert(current_block->children.begin() + current_block_idx++, buf); } +#endif current_scope[varbuf->str] = backup_scope_varbuf; delete varbuf; -- cgit v1.2.3 From 59d74a334889a17817bbf0c5d3bdef4c59df0c5b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 1 May 2019 09:01:47 +0200 Subject: Re-enable "final loop assignment" feature Signed-off-by: Clifford Wolf --- frontends/ast/simplify.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'frontends/ast') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 4d4b9dfe1..a342bf5d9 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1172,14 +1172,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, varbuf->children[0] = buf; } -#if 0 if (type == AST_FOR) { AstNode *buf = next_ast->clone(); delete buf->children[1]; buf->children[1] = varbuf->children[0]->clone(); current_block->children.insert(current_block->children.begin() + current_block_idx++, buf); } -#endif current_scope[varbuf->str] = backup_scope_varbuf; delete varbuf; -- cgit v1.2.3 From 3b6a02d3a74dc0113d595c6d26a4436160e28a6f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 1 May 2019 09:57:26 +0200 Subject: Fix width detection of memory access with bit slice, fixes #974 Signed-off-by: Clifford Wolf --- frontends/ast/genrtlil.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'frontends/ast') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b3a2a84be..d4515babf 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -645,6 +645,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun if (!id_ast->children[0]->range_valid) log_file_error(filename, linenum, "Failed to detect width of memory access `%s'!\n", str.c_str()); this_width = id_ast->children[0]->range_left - id_ast->children[0]->range_right + 1; + if (children.size() > 1) + range = children[1]; } else log_file_error(filename, linenum, "Failed to detect width for identifier %s!\n", str.c_str()); if (range) { -- cgit v1.2.3 From 6bbe2fdbf32e6335cdbecc21547e54992c3a606d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 1 May 2019 10:01:54 +0200 Subject: Add splitcmplxassign test case and silence splitcmplxassign warning Signed-off-by: Clifford Wolf --- frontends/ast/simplify.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'frontends/ast') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 4d4b9dfe1..d6561682a 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1607,6 +1607,7 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_tmp->str] = wire_tmp; wire_tmp->attributes["\\nosync"] = AstNode::mkconst_int(1, false); while (wire_tmp->simplify(true, false, false, 1, -1, false, false)) { } + wire_tmp->is_logic = true; AstNode *wire_tmp_id = new AstNode(AST_IDENTIFIER); wire_tmp_id->str = wire_tmp->str; -- cgit v1.2.3 From ac10e7d96da4965751fd60a8dd42a8998c011c39 Mon Sep 17 00:00:00 2001 From: Udi Finkelstein Date: Fri, 3 May 2019 03:10:43 +0300 Subject: Initial implementation of elaboration system tasks (IEEE1800-2017 section 20.11) This PR allows us to use $info/$warning/$error/$fatal **at elaboration time** within a generate block. This is very useful to stop a synthesis of a parametrized block when an illegal combination of parameters is chosen. --- frontends/ast/ast.cc | 1 + frontends/ast/ast.h | 4 +++- frontends/ast/genrtlil.cc | 1 + frontends/ast/simplify.cc | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 49 insertions(+), 4 deletions(-) (limited to 'frontends/ast') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 9f88b08c1..d28345503 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -154,6 +154,7 @@ std::string AST::type2str(AstNodeType type) X(AST_GENIF) X(AST_GENCASE) X(AST_GENBLOCK) + X(AST_TECALL) X(AST_POSEDGE) X(AST_NEGEDGE) X(AST_EDGE) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 281cbe086..b3e6fbaa0 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -137,7 +137,8 @@ namespace AST AST_GENIF, AST_GENCASE, AST_GENBLOCK, - + AST_TECALL, + AST_POSEDGE, AST_NEGEDGE, AST_EDGE, @@ -233,6 +234,7 @@ namespace AST bool mem2reg_check(pool &mem2reg_set); void mem2reg_remove(pool &mem2reg_set, vector &delnodes); void meminfo(int &mem_width, int &mem_size, int &addr_bits); + bool check_elab_tasks(void); // additional functionality for evaluating constant functions struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b3a2a84be..d5e7d94ab 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -856,6 +856,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_GENVAR: case AST_GENFOR: case AST_GENBLOCK: + case AST_TECALL: case AST_GENIF: case AST_GENCASE: case AST_PACKAGE: diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 4d4b9dfe1..e6132995d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1146,7 +1146,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENFOR) { for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false, false); + if (!buf->children[i]->check_elab_tasks()) + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } } else { @@ -1261,7 +1262,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false, false); + if (!buf->children[i]->check_elab_tasks()) + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -1340,7 +1342,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false, false); + if (!buf->children[i]->check_elab_tasks()) + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -2969,6 +2972,44 @@ static void mark_memories_assign_lhs_complex(dict> & } } +// handle $info(), $warning(), $error(), $fatal() +// we don't do that in simplify() because we don't know +bool AstNode::check_elab_tasks(void) +{ + if (type == AST_TECALL) { + int sz = children.size(); + if (str == "$info") { + if (sz > 0) + log_file_info(filename, linenum, "%s.\n", children[0]->str.c_str()); + else + log_file_info(filename, linenum, "\n"); + } else if (str == "$warning") { + if (sz > 0) + log_file_warning(filename, linenum, "%s.\n", children[0]->str.c_str()); + else + log_file_warning(filename, linenum, "\n"); + } else if (str == "$error") { + if (sz > 0) + log_file_error(filename, linenum, "%s.\n", children[0]->str.c_str()); + else + log_file_error(filename, linenum, "\n"); + } else if (str == "$fatal") { + // TODO: 1st parameter, if exists, is 0,1 or 2, and passed to $finish() + // if no parameter is given, default value is 1 + // dollar_finish(sz ? children[0] : 1); + // perhaps create & use log_file_fatal() + if (sz > 0) + log_file_error(filename, linenum, "FATAL: %s.\n", children[0]->str.c_str()); + else + log_file_error(filename, linenum, "FATAL.\n"); + } else { + log_file_error(filename, linenum, "Unknown elabortoon system task '%s'.\n", str.c_str()); + } + return true; + } + return false; + +} // find memories that should be replaced by registers void AstNode::mem2reg_as_needed_pass1(dict> &mem2reg_places, dict &mem2reg_candidates, dict &proc_flags, uint32_t &flags) -- cgit v1.2.3 From 87426f5a06b0cf9d1fe44efda65e3c048d89d322 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 4 May 2019 08:46:24 +0200 Subject: Improve write_verilog specify support Signed-off-by: Clifford Wolf --- frontends/ast/genrtlil.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'frontends/ast') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 92205b7ae..379fed641 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1492,10 +1492,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) continue; } if (child->type == AST_PARASET) { + int extra_const_flags = 0; IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str; if (child->children[0]->type == AST_REALVALUE) { log_file_warning(filename, linenum, "Replacing floating point parameter %s.%s = %f with string.\n", log_id(cell), log_id(paraname), child->children[0]->realvalue); + extra_const_flags = RTLIL::CONST_FLAG_REAL; auto strnode = AstNode::mkconst_str(stringf("%f", child->children[0]->realvalue)); strnode->cloneInto(child->children[0]); delete strnode; @@ -1504,6 +1506,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_file_error(filename, linenum, "Parameter %s.%s with non-constant value!\n", log_id(cell), log_id(paraname)); cell->parameters[paraname] = child->children[0]->asParaConst(); + cell->parameters[paraname].flags |= extra_const_flags; continue; } if (child->type == AST_ARGUMENT) { -- cgit v1.2.3 From 9df04d7e7520884bfc40004bb131cfdb474061c7 Mon Sep 17 00:00:00 2001 From: Stefan Biereigel Date: Wed, 22 May 2019 14:22:42 +0200 Subject: make lexer/parser aware of wand/wor net types --- frontends/ast/ast.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends/ast') diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 281cbe086..6c19dc7e6 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -173,7 +173,7 @@ namespace AST // node content - most of it is unused in most node types std::string str; std::vector bits; - bool is_input, is_output, is_reg, is_logic, is_signed, is_string, range_valid, range_swapped, was_checked; + bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked; int port_id, range_left, range_right; uint32_t integer; double realvalue; -- cgit v1.2.3 From 075a48d3fa69324d5b2700779a686fa46a69adb2 Mon Sep 17 00:00:00 2001 From: Stefan Biereigel Date: Thu, 23 May 2019 10:16:41 +0200 Subject: implementation for assignments working --- frontends/ast/ast.cc | 3 ++ frontends/ast/ast.h | 1 + frontends/ast/genrtlil.cc | 93 ++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 83 insertions(+), 14 deletions(-) (limited to 'frontends/ast') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5623541b2..9c360efb6 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -51,6 +51,7 @@ namespace AST_INTERNAL { std::map current_scope; const dict *genRTLIL_subst_ptr = NULL; RTLIL::SigSpec ignoreThisSignalsInInitial; + std::map wire_logic_map; AstNode *current_always, *current_top_block, *current_block, *current_block_child; AstModule *current_module; bool current_always_clocked; @@ -940,6 +941,8 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast log("--- END OF AST DUMP ---\n"); } + wire_logic_map = std::map(); + if (!defer) { bool blackbox_module = flag_lib; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6c19dc7e6..7b1744b2e 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -327,6 +327,7 @@ namespace AST_INTERNAL extern std::map current_scope; extern const dict *genRTLIL_subst_ptr; extern RTLIL::SigSpec ignoreThisSignalsInInitial; + extern std::map wire_logic_map; extern AST::AstNode *current_always, *current_top_block, *current_block, *current_block_child; extern AST::AstModule *current_module; extern bool current_always_clocked; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 379fed641..c60f8f5cc 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -163,6 +163,42 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const return wire; } +// helper function for creating RTLIL code for wand/wor declarations +static void wandwor2rtlil(AstNode *that, RTLIL::Wire *output_wire, bool gen_attributes = true) +{ + std::string type; + + if (that->is_wand) { + type = "$reduce_and"; + } else if (that->is_wor) { + type = "$reduce_or"; + } else { + log_file_error(that->filename, that->linenum, "Unrecognized wired logic type.\n"); + } + + std::stringstream sstr; + sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); + + RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); + cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); + + if (gen_attributes) + for (auto &attr : that->attributes) { + if (attr.second->type != AST_CONSTANT) + log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + cell->attributes[attr.first] = attr.second->asAttrConst(); + } + + cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(0); + cell->setPort("\\A", RTLIL::SigSpec()); + + cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); + cell->setPort("\\Y", output_wire); + + wire_logic_map[output_wire] = cell; +} + // helper class for converting AST always nodes to RTLIL processes struct AST_INTERNAL::ProcessGenerator { @@ -919,6 +955,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); wire->attributes[attr.first] = attr.second->asAttrConst(); } + + if (is_wand || is_wor) { + if (wire->width > 1) + log_file_error(filename, linenum, "Multi-bit wand/wor not supported.\n"); + wandwor2rtlil(this, wire); + } + } break; @@ -1450,23 +1493,45 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // add entries to current_module->connections for assignments (outside of always blocks) case AST_ASSIGN: { + bool left_had_const = false; RTLIL::SigSpec left = children[0]->genRTLIL(); RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.size()); - if (left.has_const()) { - RTLIL::SigSpec new_left, new_right; - for (int i = 0; i < GetSize(left); i++) - if (left[i].wire) { - new_left.append(left[i]); - new_right.append(right[i]); - } - log_file_warning(filename, linenum, "Ignoring assignment to constant bits:\n" - " old assignment: %s = %s\n new assignment: %s = %s.\n", - log_signal(left), log_signal(right), - log_signal(new_left), log_signal(new_right)); - left = new_left; - right = new_right; - } + + RTLIL::SigSpec new_left, new_right; + for (int i = 0; i < GetSize(left); i++) + if (left[i].wire) { + std::map::iterator iter = wire_logic_map.find(left[i].wire); + if (iter == wire_logic_map.end()) + { + new_left.append(left[i]); + } else { + RTLIL::Cell *reduce_cell = iter->second; + RTLIL::SigSpec reduce_cell_in = reduce_cell->getPort("\\A"); + int reduce_width = reduce_cell->getParam("\\A_WIDTH").as_int(); + log_warning("%d\n", reduce_cell_in.size()); + + RTLIL::Wire *new_reduce_input = current_module->addWire( + stringf("%s_in%d", reduce_cell->name.c_str(), reduce_width)); + new_reduce_input->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + reduce_cell_in.append(new_reduce_input); + reduce_cell->setPort("\\A", reduce_cell_in); + reduce_cell->fixup_parameters(); + new_left.append(new_reduce_input); + } + new_right.append(right[i]); + } else { + left_had_const = true; + } + + left = new_left; + right = new_right; current_module->connect(RTLIL::SigSig(left, right)); + + if (left_had_const) + log_file_warning(filename, linenum, "Ignoring assignment to constant bits:\n" + " old assignment: %s = %s\n new assignment: %s = %s.\n", + log_signal(left), log_signal(right), + log_signal(new_left), log_signal(new_right)); } break; -- cgit v1.2.3 From fd003e0e975be3c7f357fb151fd1c83a8ea9b0ae Mon Sep 17 00:00:00 2001 From: Stefan Biereigel Date: Thu, 23 May 2019 13:42:30 +0200 Subject: fix indentation across files --- frontends/ast/ast.cc | 6 ++- frontends/ast/ast.h | 2 +- frontends/ast/genrtlil.cc | 134 ++++++++++++++++++++++++++-------------------- 3 files changed, 81 insertions(+), 61 deletions(-) (limited to 'frontends/ast') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 9c360efb6..963152588 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -51,7 +51,7 @@ namespace AST_INTERNAL { std::map current_scope; const dict *genRTLIL_subst_ptr = NULL; RTLIL::SigSpec ignoreThisSignalsInInitial; - std::map wire_logic_map; + std::map wire_logic_map; AstNode *current_always, *current_top_block, *current_block, *current_block_child; AstModule *current_module; bool current_always_clocked; @@ -195,6 +195,8 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch is_logic = false; is_signed = false; is_string = false; + is_wand = false; + is_wor = false; was_checked = false; range_valid = false; range_swapped = false; @@ -941,7 +943,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast log("--- END OF AST DUMP ---\n"); } - wire_logic_map = std::map(); + wire_logic_map = std::map(); if (!defer) { diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 7b1744b2e..c2a7744c4 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -327,7 +327,7 @@ namespace AST_INTERNAL extern std::map current_scope; extern const dict *genRTLIL_subst_ptr; extern RTLIL::SigSpec ignoreThisSignalsInInitial; - extern std::map wire_logic_map; + extern std::map wire_logic_map; extern AST::AstNode *current_always, *current_top_block, *current_block, *current_block_child; extern AST::AstModule *current_module; extern bool current_always_clocked; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index c60f8f5cc..7a6a2be6b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -166,37 +166,37 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const // helper function for creating RTLIL code for wand/wor declarations static void wandwor2rtlil(AstNode *that, RTLIL::Wire *output_wire, bool gen_attributes = true) { - std::string type; - - if (that->is_wand) { - type = "$reduce_and"; - } else if (that->is_wor) { - type = "$reduce_or"; - } else { - log_file_error(that->filename, that->linenum, "Unrecognized wired logic type.\n"); - } + std::string type; + + if (that->is_wand) { + type = "$reduce_and"; + } else if (that->is_wor) { + type = "$reduce_or"; + } else { + log_file_error(that->filename, that->linenum, "Unrecognized wired logic type.\n"); + } std::stringstream sstr; sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - + if (gen_attributes) for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } - + cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(0); cell->setPort("\\A", RTLIL::SigSpec()); - + cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->setPort("\\Y", output_wire); - - wire_logic_map[output_wire] = cell; + + wire_logic_map[output_wire] = cell; } // helper class for converting AST always nodes to RTLIL processes @@ -956,12 +956,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) wire->attributes[attr.first] = attr.second->asAttrConst(); } - if (is_wand || is_wor) { - if (wire->width > 1) - log_file_error(filename, linenum, "Multi-bit wand/wor not supported.\n"); - wandwor2rtlil(this, wire); - } - + if (is_wand || is_wor) { + if (wire->width > 1) + log_file_error(filename, linenum, "Multi-bit wand/wor not supported.\n"); + wandwor2rtlil(this, wire); + } } break; @@ -1493,45 +1492,44 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // add entries to current_module->connections for assignments (outside of always blocks) case AST_ASSIGN: { - bool left_had_const = false; + bool left_had_const = false; RTLIL::SigSpec left = children[0]->genRTLIL(); RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.size()); - RTLIL::SigSpec new_left, new_right; - for (int i = 0; i < GetSize(left); i++) - if (left[i].wire) { - std::map::iterator iter = wire_logic_map.find(left[i].wire); - if (iter == wire_logic_map.end()) - { - new_left.append(left[i]); - } else { - RTLIL::Cell *reduce_cell = iter->second; - RTLIL::SigSpec reduce_cell_in = reduce_cell->getPort("\\A"); - int reduce_width = reduce_cell->getParam("\\A_WIDTH").as_int(); - log_warning("%d\n", reduce_cell_in.size()); - - RTLIL::Wire *new_reduce_input = current_module->addWire( - stringf("%s_in%d", reduce_cell->name.c_str(), reduce_width)); - new_reduce_input->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - reduce_cell_in.append(new_reduce_input); - reduce_cell->setPort("\\A", reduce_cell_in); - reduce_cell->fixup_parameters(); - new_left.append(new_reduce_input); - } - new_right.append(right[i]); - } else { - left_had_const = true; - } - - left = new_left; - right = new_right; + RTLIL::SigSpec new_left, new_right; + for (int i = 0; i < GetSize(left); i++) + if (left[i].wire) { + std::map::iterator iter = wire_logic_map.find(left[i].wire); + if (iter == wire_logic_map.end()) + { + new_left.append(left[i]); + } else { + RTLIL::Cell *reduce_cell = iter->second; + RTLIL::SigSpec reduce_cell_in = reduce_cell->getPort("\\A"); + int reduce_width = reduce_cell->getParam("\\A_WIDTH").as_int(); + + RTLIL::Wire *new_reduce_input = current_module->addWire( + stringf("%s_in%d", reduce_cell->name.c_str(), reduce_width)); + new_reduce_input->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + reduce_cell_in.append(new_reduce_input); + reduce_cell->setPort("\\A", reduce_cell_in); + reduce_cell->fixup_parameters(); + new_left.append(new_reduce_input); + } + new_right.append(right[i]); + } else { + left_had_const = true; + } + + left = new_left; + right = new_right; current_module->connect(RTLIL::SigSig(left, right)); - - if (left_had_const) - log_file_warning(filename, linenum, "Ignoring assignment to constant bits:\n" - " old assignment: %s = %s\n new assignment: %s = %s.\n", - log_signal(left), log_signal(right), - log_signal(new_left), log_signal(new_right)); + + if (left_had_const) + log_file_warning(filename, linenum, "Ignoring assignment to constant bits:\n" + " old assignment: %s = %s\n new assignment: %s = %s.\n", + log_signal(left), log_signal(right), + log_signal(new_left), log_signal(new_right)); } break; @@ -1576,14 +1574,34 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } if (child->type == AST_ARGUMENT) { RTLIL::SigSpec sig; - if (child->children.size() > 0) + RTLIL::SigSpec new_sig; + if (child->children.size() > 0) { sig = child->children[0]->genRTLIL(); + for (int i = 0; i < GetSize(sig); i++) { + std::map::iterator iter = wire_logic_map.find(sig[i].wire); + if (iter == wire_logic_map.end()) { + new_sig.append(sig[i]); + } else { + RTLIL::Cell *reduce_cell = iter->second; + RTLIL::SigSpec reduce_cell_in = reduce_cell->getPort("\\A"); + int reduce_width = reduce_cell->getParam("\\A_WIDTH").as_int(); + + RTLIL::Wire *new_reduce_input = current_module->addWire( + stringf("%s_in%d", reduce_cell->name.c_str(), reduce_width)); + new_reduce_input->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + reduce_cell_in.append(new_reduce_input); + reduce_cell->setPort("\\A", reduce_cell_in); + reduce_cell->fixup_parameters(); + new_sig.append(new_reduce_input); + } + } + } if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++port_counter); - cell->setPort(buf, sig); + cell->setPort(buf, new_sig); } else { - cell->setPort(child->str, sig); + cell->setPort(child->str, new_sig); } continue; } -- cgit v1.2.3 From 85de9d26c1118a83b01f62c450acecf3fd9077d6 Mon Sep 17 00:00:00 2001 From: Stefan Biereigel Date: Thu, 23 May 2019 17:55:56 +0200 Subject: fix assignment of non-wires --- frontends/ast/genrtlil.cc | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'frontends/ast') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 7a6a2be6b..047b0a81b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1500,8 +1500,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) for (int i = 0; i < GetSize(left); i++) if (left[i].wire) { std::map::iterator iter = wire_logic_map.find(left[i].wire); - if (iter == wire_logic_map.end()) - { + if (iter == wire_logic_map.end()) { new_left.append(left[i]); } else { RTLIL::Cell *reduce_cell = iter->second; @@ -1578,21 +1577,25 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (child->children.size() > 0) { sig = child->children[0]->genRTLIL(); for (int i = 0; i < GetSize(sig); i++) { - std::map::iterator iter = wire_logic_map.find(sig[i].wire); - if (iter == wire_logic_map.end()) { - new_sig.append(sig[i]); + if (sig[i].wire) { + std::map::iterator iter = wire_logic_map.find(sig[i].wire); + if (iter == wire_logic_map.end()) { + new_sig.append(sig[i]); + } else { + RTLIL::Cell *reduce_cell = iter->second; + RTLIL::SigSpec reduce_cell_in = reduce_cell->getPort("\\A"); + int reduce_width = reduce_cell->getParam("\\A_WIDTH").as_int(); + + RTLIL::Wire *new_reduce_input = current_module->addWire( + stringf("%s_in%d", reduce_cell->name.c_str(), reduce_width)); + new_reduce_input->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); + reduce_cell_in.append(new_reduce_input); + reduce_cell->setPort("\\A", reduce_cell_in); + reduce_cell->fixup_parameters(); + new_sig.append(new_reduce_input); + } } else { - RTLIL::Cell *reduce_cell = iter->second; - RTLIL::SigSpec reduce_cell_in = reduce_cell->getPort("\\A"); - int reduce_width = reduce_cell->getParam("\\A_WIDTH").as_int(); - - RTLIL::Wire *new_reduce_input = current_module->addWire( - stringf("%s_in%d", reduce_cell->name.c_str(), reduce_width)); - new_reduce_input->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - reduce_cell_in.append(new_reduce_input); - reduce_cell->setPort("\\A", reduce_cell_in); - reduce_cell->fixup_parameters(); - new_sig.append(new_reduce_input); + new_sig.append(sig[i]); } } } -- cgit v1.2.3 From 34417ce55f1b1d71ac11dfdfecfffc7a3340b6cb Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 27 May 2019 11:42:10 +0200 Subject: Added support for unsized constants, fixes #1022 Includes work from @sumit0190 and @AaronKel --- frontends/ast/ast.cc | 17 ++++++++++++++++- frontends/ast/ast.h | 4 +++- frontends/ast/genrtlil.cc | 9 +++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) (limited to 'frontends/ast') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5623541b2..29e175c15 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -194,6 +194,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch is_logic = false; is_signed = false; is_string = false; + is_unsized = false; was_checked = false; range_valid = false; range_swapped = false; @@ -722,7 +723,7 @@ AstNode *AstNode::mkconst_int(uint32_t v, bool is_signed, int width) } // create an AST node for a constant (using a bit vector as value) -AstNode *AstNode::mkconst_bits(const std::vector &v, bool is_signed) +AstNode *AstNode::mkconst_bits(const std::vector &v, bool is_signed, bool is_unsized) { AstNode *node = new AstNode(AST_CONSTANT); node->is_signed = is_signed; @@ -736,9 +737,15 @@ AstNode *AstNode::mkconst_bits(const std::vector &v, bool is_signe node->range_valid = true; node->range_left = node->bits.size()-1; node->range_right = 0; + node->is_unsized = is_unsized; return node; } +AstNode *AstNode::mkconst_bits(const std::vector &v, bool is_signed) +{ + return mkconst_bits(v, is_signed, false); +} + // create an AST node for a constant (using a string in bit vector form as value) AstNode *AstNode::mkconst_str(const std::vector &v) { @@ -775,6 +782,14 @@ bool AstNode::bits_only_01() const return true; } +RTLIL::Const AstNode::bitsAsUnsizedConst(int width) +{ + RTLIL::State extbit = bits.back(); + while (width > int(bits.size())) + bits.push_back(extbit); + return RTLIL::Const(bits); +} + RTLIL::Const AstNode::bitsAsConst(int width, bool is_signed) { std::vector bits = this->bits; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 281cbe086..f90e683ad 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -173,7 +173,7 @@ namespace AST // node content - most of it is unused in most node types std::string str; std::vector bits; - bool is_input, is_output, is_reg, is_logic, is_signed, is_string, range_valid, range_swapped, was_checked; + bool is_input, is_output, is_reg, is_logic, is_signed, is_string, range_valid, range_swapped, was_checked, is_unsized; int port_id, range_left, range_right; uint32_t integer; double realvalue; @@ -262,6 +262,7 @@ namespace AST // helper functions for creating AST nodes for constants static AstNode *mkconst_int(uint32_t v, bool is_signed, int width = 32); + static AstNode *mkconst_bits(const std::vector &v, bool is_signed, bool is_unsized); static AstNode *mkconst_bits(const std::vector &v, bool is_signed); static AstNode *mkconst_str(const std::vector &v); static AstNode *mkconst_str(const std::string &str); @@ -269,6 +270,7 @@ namespace AST // helper function for creating sign-extended const objects RTLIL::Const bitsAsConst(int width, bool is_signed); RTLIL::Const bitsAsConst(int width = -1); + RTLIL::Const bitsAsUnsizedConst(int width); RTLIL::Const asAttrConst(); RTLIL::Const asParaConst(); uint64_t asInt(bool is_signed); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 379fed641..d9dfc17cc 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -963,8 +963,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); is_signed = sign_hint; - if (type == AST_CONSTANT) - return RTLIL::SigSpec(bitsAsConst()); + if (type == AST_CONSTANT) { + if (is_unsized) { + return RTLIL::SigSpec(bitsAsUnsizedConst(width_hint)); + } else { + return RTLIL::SigSpec(bitsAsConst()); + } + } RTLIL::SigSpec sig = realAsConst(width_hint); log_file_warning(filename, linenum, "converting real value %e to binary %s.\n", realvalue, log_signal(sig)); -- cgit v1.2.3 From 84ffb217081fed7ddf1f683f65f2a2fdf813cd6b Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 27 May 2019 12:25:18 +0200 Subject: Give error instead of asserting for invalid range, fixes #947 --- frontends/ast/genrtlil.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'frontends/ast') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 379fed641..1b19ba4e5 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -904,7 +904,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (!range_valid) log_file_error(filename, linenum, "Signal `%s' with non-constant width!\n", str.c_str()); - log_assert(range_left >= range_right || (range_left == -1 && range_right == 0)); + if (!(range_left >= range_right || (range_left == -1 && range_right == 0))) + log_file_error(filename, linenum, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1); RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); -- cgit v1.2.3 From ed625a3102233bf9c9af17e56575dc4a0ed8946c Mon Sep 17 00:00:00 2001 From: Stefan Biereigel Date: Mon, 27 May 2019 18:00:22 +0200 Subject: move wand/wor resolution into hierarchy pass --- frontends/ast/genrtlil.cc | 111 ++++++---------------------------------------- 1 file changed, 14 insertions(+), 97 deletions(-) (limited to 'frontends/ast') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 047b0a81b..8094304e5 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -163,42 +163,6 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const return wire; } -// helper function for creating RTLIL code for wand/wor declarations -static void wandwor2rtlil(AstNode *that, RTLIL::Wire *output_wire, bool gen_attributes = true) -{ - std::string type; - - if (that->is_wand) { - type = "$reduce_and"; - } else if (that->is_wor) { - type = "$reduce_or"; - } else { - log_file_error(that->filename, that->linenum, "Unrecognized wired logic type.\n"); - } - - std::stringstream sstr; - sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); - - RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); - cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - - if (gen_attributes) - for (auto &attr : that->attributes) { - if (attr.second->type != AST_CONSTANT) - log_file_error(that->filename, that->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); - cell->attributes[attr.first] = attr.second->asAttrConst(); - } - - cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(0); - cell->setPort("\\A", RTLIL::SigSpec()); - - cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->setPort("\\Y", output_wire); - - wire_logic_map[output_wire] = cell; -} - // helper class for converting AST always nodes to RTLIL processes struct AST_INTERNAL::ProcessGenerator { @@ -956,11 +920,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) wire->attributes[attr.first] = attr.second->asAttrConst(); } - if (is_wand || is_wor) { - if (wire->width > 1) - log_file_error(filename, linenum, "Multi-bit wand/wor not supported.\n"); - wandwor2rtlil(this, wire); - } + if (is_wand) wire->set_bool_attribute("\\wand"); + if (is_wor) wire->set_bool_attribute("\\wor"); } break; @@ -1492,43 +1453,23 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // add entries to current_module->connections for assignments (outside of always blocks) case AST_ASSIGN: { - bool left_had_const = false; RTLIL::SigSpec left = children[0]->genRTLIL(); RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.size()); - - RTLIL::SigSpec new_left, new_right; - for (int i = 0; i < GetSize(left); i++) - if (left[i].wire) { - std::map::iterator iter = wire_logic_map.find(left[i].wire); - if (iter == wire_logic_map.end()) { + if (left.has_const()) { + RTLIL::SigSpec new_left, new_right; + for (int i = 0; i < GetSize(left); i++) + if (left[i].wire) { new_left.append(left[i]); - } else { - RTLIL::Cell *reduce_cell = iter->second; - RTLIL::SigSpec reduce_cell_in = reduce_cell->getPort("\\A"); - int reduce_width = reduce_cell->getParam("\\A_WIDTH").as_int(); - - RTLIL::Wire *new_reduce_input = current_module->addWire( - stringf("%s_in%d", reduce_cell->name.c_str(), reduce_width)); - new_reduce_input->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - reduce_cell_in.append(new_reduce_input); - reduce_cell->setPort("\\A", reduce_cell_in); - reduce_cell->fixup_parameters(); - new_left.append(new_reduce_input); + new_right.append(right[i]); } - new_right.append(right[i]); - } else { - left_had_const = true; - } - - left = new_left; - right = new_right; - current_module->connect(RTLIL::SigSig(left, right)); - - if (left_had_const) log_file_warning(filename, linenum, "Ignoring assignment to constant bits:\n" " old assignment: %s = %s\n new assignment: %s = %s.\n", log_signal(left), log_signal(right), log_signal(new_left), log_signal(new_right)); + left = new_left; + right = new_right; + } + current_module->connect(RTLIL::SigSig(left, right)); } break; @@ -1573,38 +1514,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } if (child->type == AST_ARGUMENT) { RTLIL::SigSpec sig; - RTLIL::SigSpec new_sig; - if (child->children.size() > 0) { + if (child->children.size() > 0) sig = child->children[0]->genRTLIL(); - for (int i = 0; i < GetSize(sig); i++) { - if (sig[i].wire) { - std::map::iterator iter = wire_logic_map.find(sig[i].wire); - if (iter == wire_logic_map.end()) { - new_sig.append(sig[i]); - } else { - RTLIL::Cell *reduce_cell = iter->second; - RTLIL::SigSpec reduce_cell_in = reduce_cell->getPort("\\A"); - int reduce_width = reduce_cell->getParam("\\A_WIDTH").as_int(); - - RTLIL::Wire *new_reduce_input = current_module->addWire( - stringf("%s_in%d", reduce_cell->name.c_str(), reduce_width)); - new_reduce_input->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - reduce_cell_in.append(new_reduce_input); - reduce_cell->setPort("\\A", reduce_cell_in); - reduce_cell->fixup_parameters(); - new_sig.append(new_reduce_input); - } - } else { - new_sig.append(sig[i]); - } - } - } if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++port_counter); - cell->setPort(buf, new_sig); + cell->setPort(buf, sig); } else { - cell->setPort(child->str, new_sig); + cell->setPort(child->str, sig); } continue; } -- cgit v1.2.3 From cd12f2ddcfbdbfbf147afc2c90ddc54ec1f74485 Mon Sep 17 00:00:00 2001 From: Stefan Biereigel Date: Mon, 27 May 2019 18:01:44 +0200 Subject: remove leftovers from ast data structures --- frontends/ast/ast.cc | 3 --- frontends/ast/ast.h | 1 - 2 files changed, 4 deletions(-) (limited to 'frontends/ast') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 963152588..44b8863f9 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -51,7 +51,6 @@ namespace AST_INTERNAL { std::map current_scope; const dict *genRTLIL_subst_ptr = NULL; RTLIL::SigSpec ignoreThisSignalsInInitial; - std::map wire_logic_map; AstNode *current_always, *current_top_block, *current_block, *current_block_child; AstModule *current_module; bool current_always_clocked; @@ -943,8 +942,6 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast log("--- END OF AST DUMP ---\n"); } - wire_logic_map = std::map(); - if (!defer) { bool blackbox_module = flag_lib; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index c2a7744c4..6c19dc7e6 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -327,7 +327,6 @@ namespace AST_INTERNAL extern std::map current_scope; extern const dict *genRTLIL_subst_ptr; extern RTLIL::SigSpec ignoreThisSignalsInInitial; - extern std::map wire_logic_map; extern AST::AstNode *current_always, *current_top_block, *current_block, *current_block_child; extern AST::AstModule *current_module; extern bool current_always_clocked; -- cgit v1.2.3 From 211d85cfcc1ae701bb9392347bcbb9750e3045b0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Jun 2019 12:41:09 +0200 Subject: Fixes and cleanups in AST_TECALL handling Signed-off-by: Clifford Wolf --- frontends/ast/ast.h | 1 - frontends/ast/genrtlil.cc | 32 +++++++++++++++++++++++++++++++- frontends/ast/simplify.cc | 47 +++-------------------------------------------- 3 files changed, 34 insertions(+), 46 deletions(-) (limited to 'frontends/ast') diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 93997ab86..b8cde060e 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -234,7 +234,6 @@ namespace AST bool mem2reg_check(pool &mem2reg_set); void mem2reg_remove(pool &mem2reg_set, vector &delnodes); void meminfo(int &mem_width, int &mem_size, int &addr_bits); - bool check_elab_tasks(void); // additional functionality for evaluating constant functions struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 60a087282..32ed401eb 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -858,7 +858,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_GENVAR: case AST_GENFOR: case AST_GENBLOCK: - case AST_TECALL: case AST_GENIF: case AST_GENCASE: case AST_PACKAGE: @@ -1576,6 +1575,37 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) delete always; } break; + case AST_TECALL: { + int sz = children.size(); + if (str == "$info") { + if (sz > 0) + log_file_info(filename, linenum, "%s.\n", children[0]->str.c_str()); + else + log_file_info(filename, linenum, "\n"); + } else if (str == "$warning") { + if (sz > 0) + log_file_warning(filename, linenum, "%s.\n", children[0]->str.c_str()); + else + log_file_warning(filename, linenum, "\n"); + } else if (str == "$error") { + if (sz > 0) + log_file_error(filename, linenum, "%s.\n", children[0]->str.c_str()); + else + log_file_error(filename, linenum, "\n"); + } else if (str == "$fatal") { + // TODO: 1st parameter, if exists, is 0,1 or 2, and passed to $finish() + // if no parameter is given, default value is 1 + // dollar_finish(sz ? children[0] : 1); + // perhaps create & use log_file_fatal() + if (sz > 0) + log_file_error(filename, linenum, "FATAL: %s.\n", children[0]->str.c_str()); + else + log_file_error(filename, linenum, "FATAL.\n"); + } else { + log_file_error(filename, linenum, "Unknown elabortoon system task '%s'.\n", str.c_str()); + } + } break; + case AST_FCALL: { if (str == "\\$anyconst" || str == "\\$anyseq" || str == "\\$allconst" || str == "\\$allseq") { diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 66fd243d3..e947125bf 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1146,8 +1146,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENFOR) { for (size_t i = 0; i < buf->children.size(); i++) { - if (!buf->children[i]->check_elab_tasks()) - buf->children[i]->simplify(false, false, false, stage, -1, false, false); + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } } else { @@ -1260,8 +1259,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - if (!buf->children[i]->check_elab_tasks()) - buf->children[i]->simplify(false, false, false, stage, -1, false, false); + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -1340,8 +1338,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - if (!buf->children[i]->check_elab_tasks()) - buf->children[i]->simplify(false, false, false, stage, -1, false, false); + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -2971,44 +2968,6 @@ static void mark_memories_assign_lhs_complex(dict> & } } -// handle $info(), $warning(), $error(), $fatal() -// we don't do that in simplify() because we don't know -bool AstNode::check_elab_tasks(void) -{ - if (type == AST_TECALL) { - int sz = children.size(); - if (str == "$info") { - if (sz > 0) - log_file_info(filename, linenum, "%s.\n", children[0]->str.c_str()); - else - log_file_info(filename, linenum, "\n"); - } else if (str == "$warning") { - if (sz > 0) - log_file_warning(filename, linenum, "%s.\n", children[0]->str.c_str()); - else - log_file_warning(filename, linenum, "\n"); - } else if (str == "$error") { - if (sz > 0) - log_file_error(filename, linenum, "%s.\n", children[0]->str.c_str()); - else - log_file_error(filename, linenum, "\n"); - } else if (str == "$fatal") { - // TODO: 1st parameter, if exists, is 0,1 or 2, and passed to $finish() - // if no parameter is given, default value is 1 - // dollar_finish(sz ? children[0] : 1); - // perhaps create & use log_file_fatal() - if (sz > 0) - log_file_error(filename, linenum, "FATAL: %s.\n", children[0]->str.c_str()); - else - log_file_error(filename, linenum, "FATAL.\n"); - } else { - log_file_error(filename, linenum, "Unknown elabortoon system task '%s'.\n", str.c_str()); - } - return true; - } - return false; - -} // find memories that should be replaced by registers void AstNode::mem2reg_as_needed_pass1(dict> &mem2reg_places, dict &mem2reg_candidates, dict &proc_flags, uint32_t &flags) -- cgit v1.2.3