From 609caa23b5e12547c043dc4a1827d1a531af1992 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 24 Nov 2013 17:17:21 +0100 Subject: [PATCH] Implemented correct handling of signed module parameters --- frontends/ast/ast.cc | 4 ++-- frontends/ast/ast.h | 2 +- frontends/ast/genrtlil.cc | 4 ++++ kernel/rtlil.cc | 2 +- kernel/rtlil.h | 3 ++- passes/hierarchy/hierarchy.cc | 2 +- passes/techmap/techmap.cc | 2 +- tests/simple/hierarchy.v | 8 +++++++- 8 files changed, 19 insertions(+), 8 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 29093b830..6423cae22 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -792,7 +792,7 @@ AstModule::~AstModule() } // create a new parametric module (when needed) and return the name of the generated module -RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map parameters) +RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map parameters, std::set signed_parameters) { log_header("Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", name.c_str()); @@ -826,7 +826,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::mapstr.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); delete child->children.at(0); - child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, child->is_signed); + child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, signed_parameters.count(para_id) > 0); hash_data.insert(hash_data.end(), child->str.begin(), child->str.end()); hash_data.push_back(0); hash_data.insert(hash_data.end(), parameters[para_id].bits.begin(), parameters[para_id].bits.end()); diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index de32a2bb9..f9f47f6a4 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -227,7 +227,7 @@ namespace AST AstNode *ast; bool nolatches, nomem2reg, mem2reg, lib, noopt; virtual ~AstModule(); - virtual RTLIL::IdString derive(RTLIL::Design *design, std::map parameters); + virtual RTLIL::IdString derive(RTLIL::Design *design, std::map parameters, std::set signed_parameters); virtual void update_auto_wires(std::map auto_sizes); virtual RTLIL::Module *clone() const; }; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index e634a27a9..177c1ec59 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1309,9 +1309,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++para_counter); + if (child->children[0]->is_signed) + cell->signed_parameters.insert(buf); cell->parameters[buf].str = child->children[0]->str; cell->parameters[buf].bits = child->children[0]->bits; } else { + if (child->children[0]->is_signed) + cell->signed_parameters.insert(child->str); cell->parameters[child->str].str = child->children[0]->str; cell->parameters[child->str].bits = child->children[0]->bits; } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index bd73fe538..afd7ca2f1 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -260,7 +260,7 @@ RTLIL::Module::~Module() delete it->second; } -RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, std::map) +RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, std::map, std::set) { log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name)); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index c7f9cf122..a4c3008bc 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -264,7 +264,7 @@ struct RTLIL::Module { std::vector connections; RTLIL_ATTRIBUTE_MEMBERS virtual ~Module(); - virtual RTLIL::IdString derive(RTLIL::Design *design, std::map parameters); + virtual RTLIL::IdString derive(RTLIL::Design *design, std::map parameters, std::set signed_parameters); virtual void update_auto_wires(std::map auto_sizes); virtual size_t count_id(RTLIL::IdString id); virtual void check(); @@ -300,6 +300,7 @@ struct RTLIL::Cell { RTLIL::IdString type; std::map connections; std::map parameters; + std::set signed_parameters; RTLIL_ATTRIBUTE_MEMBERS void optimize(); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index d9b52c6d0..291df184f 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -150,7 +150,7 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla if (design->modules.at(cell->type)->get_bool_attribute("\\blackbox")) continue; RTLIL::Module *mod = design->modules[cell->type]; - cell->type = mod->derive(design, cell->parameters); + cell->type = mod->derive(design, cell->parameters, cell->signed_parameters); cell->parameters.clear(); did_something = true; } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 4f9d9c4e4..c3af697be 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -239,7 +239,7 @@ static bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL:: tpl = techmap_cache[key]; } else { if (cell->parameters.size() != 0) { - derived_name = tpl->derive(map, parameters); + derived_name = tpl->derive(map, parameters, cell->signed_parameters); tpl = map->modules[derived_name]; log_continue = true; } diff --git a/tests/simple/hierarchy.v b/tests/simple/hierarchy.v index 97612c74a..17888009f 100644 --- a/tests/simple/hierarchy.v +++ b/tests/simple/hierarchy.v @@ -4,14 +4,20 @@ module top(a, b, y1, y2, y3, y4); input [3:0] a; input signed [3:0] b; output [7:0] y1, y2, y3, y4; + +// this version triggers a bug in icarus verilog +// submod #(-3'sd1, 3'b111 + 3'b001) foo (a, b, y1, y2, y3, y4); + +// this version is handled correctly by icarus verilog submod #(-3'sd1, -3'sd1) foo (a, b, y1, y2, y3, y4); + endmodule (* gentb_skip *) module submod(a, b, y1, y2, y3, y4); parameter c = 0; parameter [7:0] d = 0; -input [7:0] a, b; +input [3:0] a, b; output [7:0] y1, y2, y3, y4; assign y1 = a; assign y2 = b; -- 2.30.2