mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 12:28:44 +00:00
Implemented correct handling of signed module parameters
This commit is contained in:
parent
1e6836933d
commit
609caa23b5
|
@ -792,7 +792,7 @@ AstModule::~AstModule()
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new parametric module (when needed) and return the name of the generated module
|
// 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());
|
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:
|
rewrite_parameter:
|
||||||
para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
|
para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
|
||||||
delete child->children.at(0);
|
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.insert(hash_data.end(), child->str.begin(), child->str.end());
|
||||||
hash_data.push_back(0);
|
hash_data.push_back(0);
|
||||||
hash_data.insert(hash_data.end(), parameters[para_id].bits.begin(), parameters[para_id].bits.end());
|
hash_data.insert(hash_data.end(), parameters[para_id].bits.begin(), parameters[para_id].bits.end());
|
||||||
|
|
|
@ -227,7 +227,7 @@ namespace AST
|
||||||
AstNode *ast;
|
AstNode *ast;
|
||||||
bool nolatches, nomem2reg, mem2reg, lib, noopt;
|
bool nolatches, nomem2reg, mem2reg, lib, noopt;
|
||||||
virtual ~AstModule();
|
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 void update_auto_wires(std::map<RTLIL::IdString, int> auto_sizes);
|
||||||
virtual RTLIL::Module *clone() const;
|
virtual RTLIL::Module *clone() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1309,9 +1309,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
if (child->str.size() == 0) {
|
if (child->str.size() == 0) {
|
||||||
char buf[100];
|
char buf[100];
|
||||||
snprintf(buf, 100, "$%d", ++para_counter);
|
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].str = child->children[0]->str;
|
||||||
cell->parameters[buf].bits = child->children[0]->bits;
|
cell->parameters[buf].bits = child->children[0]->bits;
|
||||||
} else {
|
} 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].str = child->children[0]->str;
|
||||||
cell->parameters[child->str].bits = child->children[0]->bits;
|
cell->parameters[child->str].bits = child->children[0]->bits;
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,7 +260,7 @@ RTLIL::Module::~Module()
|
||||||
delete it->second;
|
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));
|
log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,7 +264,7 @@ struct RTLIL::Module {
|
||||||
std::vector<RTLIL::SigSig> connections;
|
std::vector<RTLIL::SigSig> connections;
|
||||||
RTLIL_ATTRIBUTE_MEMBERS
|
RTLIL_ATTRIBUTE_MEMBERS
|
||||||
virtual ~Module();
|
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 void update_auto_wires(std::map<RTLIL::IdString, int> auto_sizes);
|
||||||
virtual size_t count_id(RTLIL::IdString id);
|
virtual size_t count_id(RTLIL::IdString id);
|
||||||
virtual void check();
|
virtual void check();
|
||||||
|
@ -300,6 +300,7 @@ struct RTLIL::Cell {
|
||||||
RTLIL::IdString type;
|
RTLIL::IdString type;
|
||||||
std::map<RTLIL::IdString, RTLIL::SigSpec> connections;
|
std::map<RTLIL::IdString, RTLIL::SigSpec> connections;
|
||||||
std::map<RTLIL::IdString, RTLIL::Const> parameters;
|
std::map<RTLIL::IdString, RTLIL::Const> parameters;
|
||||||
|
std::set<RTLIL::IdString> signed_parameters;
|
||||||
RTLIL_ATTRIBUTE_MEMBERS
|
RTLIL_ATTRIBUTE_MEMBERS
|
||||||
void optimize();
|
void optimize();
|
||||||
|
|
||||||
|
|
|
@ -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"))
|
if (design->modules.at(cell->type)->get_bool_attribute("\\blackbox"))
|
||||||
continue;
|
continue;
|
||||||
RTLIL::Module *mod = design->modules[cell->type];
|
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();
|
cell->parameters.clear();
|
||||||
did_something = true;
|
did_something = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,7 +239,7 @@ static bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::
|
||||||
tpl = techmap_cache[key];
|
tpl = techmap_cache[key];
|
||||||
} else {
|
} else {
|
||||||
if (cell->parameters.size() != 0) {
|
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];
|
tpl = map->modules[derived_name];
|
||||||
log_continue = true;
|
log_continue = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,20 @@ module top(a, b, y1, y2, y3, y4);
|
||||||
input [3:0] a;
|
input [3:0] a;
|
||||||
input signed [3:0] b;
|
input signed [3:0] b;
|
||||||
output [7:0] y1, y2, y3, y4;
|
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);
|
submod #(-3'sd1, -3'sd1) foo (a, b, y1, y2, y3, y4);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* gentb_skip *)
|
(* gentb_skip *)
|
||||||
module submod(a, b, y1, y2, y3, y4);
|
module submod(a, b, y1, y2, y3, y4);
|
||||||
parameter c = 0;
|
parameter c = 0;
|
||||||
parameter [7:0] d = 0;
|
parameter [7:0] d = 0;
|
||||||
input [7:0] a, b;
|
input [3:0] a, b;
|
||||||
output [7:0] y1, y2, y3, y4;
|
output [7:0] y1, y2, y3, y4;
|
||||||
assign y1 = a;
|
assign y1 = a;
|
||||||
assign y2 = b;
|
assign y2 = b;
|
||||||
|
|
Loading…
Reference in a new issue