Implemented correct handling of signed module parameters
authorClifford Wolf <clifford@clifford.at>
Sun, 24 Nov 2013 16:17:21 +0000 (17:17 +0100)
committerClifford Wolf <clifford@clifford.at>
Sun, 24 Nov 2013 16:17:21 +0000 (17:17 +0100)
frontends/ast/ast.cc
frontends/ast/ast.h
frontends/ast/genrtlil.cc
kernel/rtlil.cc
kernel/rtlil.h
passes/hierarchy/hierarchy.cc
passes/techmap/techmap.cc
tests/simple/hierarchy.v

index 29093b83070d7cab87e82f0d740da2db46e07a0d..6423cae22e8ff03a46a477820bb72f5831afcaef 100644 (file)
@@ -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<RTLIL::IdString, RTLIL::Const> parameters)
+RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters, std::set<RTLIL::IdString> 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::map<RTLIL::IdStrin
        rewrite_parameter:
                        para_info += stringf("%s=%s", child->str.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());
index de32a2bb9d6e4fd4aefcb30fd50c001fa4b40acc..f9f47f6a4a9a6de545fbf212c29f20a03201f697 100644 (file)
@@ -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<RTLIL::IdString, RTLIL::Const> parameters);
+               virtual RTLIL::IdString derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters, std::set<RTLIL::IdString> signed_parameters);
                virtual void update_auto_wires(std::map<RTLIL::IdString, int> auto_sizes);
                virtual RTLIL::Module *clone() const;
        };
index e634a27a9928558b0247550b270ccc9d975b6c74..177c1ec59f621d224daad114f8b42a788d417784 100644 (file)
@@ -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;
                                        }
index bd73fe5388ffbbef95cc653d6caae7c09589b4fd..afd7ca2f14ac9c315af5a698f9616e2c4329b576 100644 (file)
@@ -260,7 +260,7 @@ RTLIL::Module::~Module()
                delete it->second;
 }
 
-RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, std::map<RTLIL::IdString, RTLIL::Const>)
+RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, std::map<RTLIL::IdString, RTLIL::Const>, std::set<RTLIL::IdString>)
 {
        log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
 }
index c7f9cf1227e3bb9f8fa28f643d2344fd6f0a85d0..a4c3008bc8833342f7c9696435f1b262511c96bb 100644 (file)
@@ -264,7 +264,7 @@ struct RTLIL::Module {
        std::vector<RTLIL::SigSig> connections;
        RTLIL_ATTRIBUTE_MEMBERS
        virtual ~Module();
-       virtual RTLIL::IdString derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters);
+       virtual RTLIL::IdString derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters, std::set<RTLIL::IdString> signed_parameters);
        virtual void update_auto_wires(std::map<RTLIL::IdString, int> 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<RTLIL::IdString, RTLIL::SigSpec> connections;
        std::map<RTLIL::IdString, RTLIL::Const> parameters;
+       std::set<RTLIL::IdString> signed_parameters;
        RTLIL_ATTRIBUTE_MEMBERS
        void optimize();
 
index d9b52c6d00f8ad924a0f21cf825b78133c294529..291df184f14ac790ceb0b2930b6a28643702ab8f 100644 (file)
@@ -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;
        }
index 4f9d9c4e4862ed665b89290dce320a420ec0aa96..c3af697be136e8fe5a6ed839fbe63113202bcf60 100644 (file)
@@ -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;
                                }
index 97612c74a3ae648bde861d291a7b2f2dc901d59f..17888009f59e9a5038489b21f45ea1ea270a2b52 100644 (file)
@@ -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;