Support SV [size] dimension for module and gate instances (issue #553).
Also output a proper error message if multiple dimensions are supplied instead of failing an assertion.
This commit is contained in:
parent
dbf55da0f5
commit
dcc9b59f6d
40
PGate.cc
40
PGate.cc
|
|
@ -41,7 +41,7 @@ void PGate::set_pins_(list<PExpr*>*pins)
|
|||
}
|
||||
|
||||
PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
|
||||
: name_(name), pins_(pins? pins->size() : 0)
|
||||
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
|
||||
{
|
||||
if (pins) set_pins_(pins);
|
||||
if (del) delay_.set_delays(del);
|
||||
|
|
@ -50,7 +50,7 @@ PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
|
|||
}
|
||||
|
||||
PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del)
|
||||
: name_(name), pins_(pins? pins->size() : 0)
|
||||
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
|
||||
{
|
||||
if (pins) set_pins_(pins);
|
||||
if (del) delay_.set_delay(del);
|
||||
|
|
@ -59,7 +59,7 @@ PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del)
|
|||
}
|
||||
|
||||
PGate::PGate(perm_string name, list<PExpr*>*pins)
|
||||
: name_(name), pins_(pins? pins->size() : 0)
|
||||
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
|
||||
{
|
||||
if (pins) set_pins_(pins);
|
||||
str0_ = IVL_DR_STRONG;
|
||||
|
|
@ -70,6 +70,12 @@ PGate::~PGate()
|
|||
{
|
||||
}
|
||||
|
||||
void PGate::set_ranges(list<pform_range_t>*ranges)
|
||||
{
|
||||
assert(ranges_ == 0);
|
||||
ranges_ = ranges;
|
||||
}
|
||||
|
||||
ivl_drive_t PGate::strength0() const
|
||||
{
|
||||
return str0_;
|
||||
|
|
@ -143,14 +149,14 @@ PGAssign::~PGAssign()
|
|||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
list<PExpr*>*pins,
|
||||
list<PExpr*>*del)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
: PGate(name, pins, del), type_(t)
|
||||
{
|
||||
}
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
list<PExpr*>*pins,
|
||||
PExpr*del)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
: PGate(name, pins, del), type_(t)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -159,15 +165,6 @@ PGBuiltin::~PGBuiltin()
|
|||
{
|
||||
}
|
||||
|
||||
void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
|
||||
{
|
||||
assert(msb_ == 0);
|
||||
assert(lsb_ == 0);
|
||||
|
||||
msb_ = msb;
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
const char* PGBuiltin::gate_name() const
|
||||
{
|
||||
switch(type_) {
|
||||
|
|
@ -268,20 +265,20 @@ const char* PGBuiltin::gate_name() const
|
|||
|
||||
PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
|
||||
: PGate(name, pins), bound_type_(0), type_(type), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
npins_(0), parms_(0), nparms_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PGModule::PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins)
|
||||
: PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins),
|
||||
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
npins_(npins), parms_(0), nparms_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PGModule::PGModule(Module*type, perm_string name)
|
||||
: PGate(name, 0), bound_type_(type), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
npins_(0), parms_(0), nparms_(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -303,15 +300,6 @@ void PGModule::set_parameters(named<PExpr*>*pa, unsigned npa)
|
|||
nparms_ = npa;
|
||||
}
|
||||
|
||||
void PGModule::set_range(PExpr*msb, PExpr*lsb)
|
||||
{
|
||||
assert(msb_ == 0);
|
||||
assert(lsb_ == 0);
|
||||
|
||||
msb_ = msb;
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
perm_string PGModule::get_type() const
|
||||
{
|
||||
return type_;
|
||||
|
|
|
|||
26
PGate.h
26
PGate.h
|
|
@ -60,6 +60,9 @@ class PGate : public PNamedItem {
|
|||
|
||||
virtual ~PGate();
|
||||
|
||||
void set_ranges(std::list<pform_range_t>*ranges);
|
||||
bool is_array() const { return ranges_ != 0; }
|
||||
|
||||
perm_string get_name() const { return name_; }
|
||||
|
||||
// This evaluates the delays as far as possible, but returns
|
||||
|
|
@ -93,14 +96,20 @@ class PGate : public PNamedItem {
|
|||
protected:
|
||||
const std::vector<PExpr*>& get_pins() const { return pins_; }
|
||||
|
||||
unsigned calculate_array_size_(Design*, NetScope*,
|
||||
long&high, long&low) const;
|
||||
|
||||
void dump_pins(std::ostream&out) const;
|
||||
void dump_delays(std::ostream&out) const;
|
||||
void dump_ranges(std::ostream&out) const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
PDelays delay_;
|
||||
std::vector<PExpr*>pins_;
|
||||
|
||||
std::list<pform_range_t>*ranges_;
|
||||
|
||||
ivl_drive_t str0_, str1_;
|
||||
|
||||
void set_pins_(std::list<PExpr*>*pins);
|
||||
|
|
@ -159,16 +168,12 @@ class PGBuiltin : public PGate {
|
|||
|
||||
Type type() const { return type_; }
|
||||
const char * gate_name() const;
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
unsigned calculate_array_count_(Design*, NetScope*,
|
||||
long&high, long&low) const;
|
||||
|
||||
void calculate_gate_and_lval_count_(unsigned&gate_count,
|
||||
unsigned&lval_count) const;
|
||||
|
||||
|
|
@ -179,8 +184,6 @@ class PGBuiltin : public PGate {
|
|||
bool check_delay_count(Design*des) const;
|
||||
|
||||
Type type_;
|
||||
PExpr*msb_;
|
||||
PExpr*lsb_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -215,10 +218,6 @@ class PGModule : public PGate {
|
|||
void set_parameters(std::list<PExpr*>*o);
|
||||
void set_parameters(named<PExpr*>*pa, unsigned npa);
|
||||
|
||||
// Modules can be instantiated in ranges. The parser uses this
|
||||
// method to pass the range to the pform.
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
std::map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind =4) const;
|
||||
|
|
@ -241,16 +240,9 @@ class PGModule : public PGate {
|
|||
named<PExpr*>*parms_;
|
||||
unsigned nparms_;
|
||||
|
||||
// Arrays of modules are give if these are set.
|
||||
PExpr*msb_;
|
||||
PExpr*lsb_;
|
||||
|
||||
friend class delayed_elaborate_scope_mod_instances;
|
||||
void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
|
||||
void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const;
|
||||
unsigned calculate_instance_count_(Design*, NetScope*,
|
||||
long&high, long&low,
|
||||
perm_string name) const;
|
||||
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
|
||||
void elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const;
|
||||
bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
|
||||
|
|
|
|||
|
|
@ -1413,7 +1413,7 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
|||
return;
|
||||
}
|
||||
|
||||
if (msb_ || lsb_) {
|
||||
if (is_array()) {
|
||||
// If there are expressions to evaluate in order to know
|
||||
// the actual number of instances that will be
|
||||
// instantiated, then we have to delay further scope
|
||||
|
|
@ -1443,41 +1443,17 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
|||
*/
|
||||
void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const
|
||||
{
|
||||
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1, true) : 0;
|
||||
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1, true) : 0;
|
||||
NetEConst*msb = dynamic_cast<NetEConst*> (mse);
|
||||
NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
|
||||
|
||||
assert( (msb == 0) || (lsb != 0) );
|
||||
|
||||
long instance_low = 0;
|
||||
long instance_high = 0;
|
||||
long instance_count = 1;
|
||||
bool instance_array = false;
|
||||
|
||||
if (msb) {
|
||||
instance_array = true;
|
||||
instance_high = msb->value().as_long();
|
||||
instance_low = lsb->value().as_long();
|
||||
if (instance_high > instance_low)
|
||||
instance_count = instance_high - instance_low + 1;
|
||||
else
|
||||
instance_count = instance_low - instance_high + 1;
|
||||
|
||||
delete mse;
|
||||
delete lse;
|
||||
}
|
||||
long instance_count = calculate_array_size_(des, sc, instance_high, instance_low);
|
||||
if (instance_count == 0)
|
||||
return;
|
||||
|
||||
NetScope::scope_vec_t instances (instance_count);
|
||||
if (debug_scopes) {
|
||||
cerr << get_fileline() << ": debug: Create " << instance_count
|
||||
<< " instances of " << get_name()
|
||||
<< "." << endl;
|
||||
}
|
||||
|
||||
struct attrib_list_t*attrib_list;
|
||||
unsigned attrib_list_n = 0;
|
||||
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, sc);
|
||||
struct attrib_list_t*attrib_list;
|
||||
unsigned attrib_list_n = 0;
|
||||
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, sc);
|
||||
|
||||
// Run through the module instances, and make scopes out of
|
||||
// them. Also do parameter overrides that are done on the
|
||||
|
|
@ -1486,7 +1462,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
|
||||
hname_t use_name (get_name());
|
||||
|
||||
if (instance_array) {
|
||||
if (is_array()) {
|
||||
int instance_idx;
|
||||
if (instance_low < instance_high)
|
||||
instance_idx = instance_low + idx;
|
||||
|
|
|
|||
158
elaborate.cc
158
elaborate.cc
|
|
@ -63,6 +63,44 @@ void PGate::elaborate(Design*, NetScope*) const
|
|||
typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
unsigned PGate::calculate_array_size_(Design*des, NetScope*scope,
|
||||
long&high, long&low) const
|
||||
{
|
||||
if (ranges_ && ranges_->size() > 1) {
|
||||
if (gn_system_verilog()) {
|
||||
cerr << get_fileline() << ": sorry: Multi-dimensional"
|
||||
<< " arrays of instances are not yet supported." << endl;
|
||||
} else {
|
||||
cerr << get_fileline() << ": error: Multi-dimensional"
|
||||
<< " arrays of instances require SystemVerilog." << endl;
|
||||
}
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned size = 1;
|
||||
high = 0;
|
||||
low = 0;
|
||||
|
||||
if (ranges_) {
|
||||
if (!evaluate_range(des, scope, this, ranges_->front(), high, low))
|
||||
return 0;
|
||||
|
||||
if (high > low)
|
||||
size = high - low + 1;
|
||||
else
|
||||
size = low - high + 1;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: PGate: Make array "
|
||||
<< "[" << high << ":" << low << "]" << " of "
|
||||
<< size << " instances for " << get_name() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate the continuous assign. (This is *not* the procedural
|
||||
* assign.) Elaborate the lvalue and rvalue, and do the assignment.
|
||||
|
|
@ -234,61 +272,6 @@ void PGAssign::elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval
|
|||
assign_unpacked_with_bufz(des, scope, this, lval, rval_net);
|
||||
}
|
||||
|
||||
unsigned PGBuiltin::calculate_array_count_(Design*des, NetScope*scope,
|
||||
long&high, long&low) const
|
||||
{
|
||||
unsigned count = 1;
|
||||
high = 0;
|
||||
low = 0;
|
||||
|
||||
/* If the Verilog source has a range specification for the
|
||||
gates, then I am expected to make more than one
|
||||
gate. Figure out how many are desired. */
|
||||
if (msb_) {
|
||||
NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1, true);
|
||||
NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1, true);
|
||||
|
||||
NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
|
||||
NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp);
|
||||
|
||||
if (msb_con == 0) {
|
||||
cerr << get_fileline() << ": error: Unable to evaluate "
|
||||
"expression " << *msb_ << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lsb_con == 0) {
|
||||
cerr << get_fileline() << ": error: Unable to evaluate "
|
||||
"expression " << *lsb_ << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum msb = msb_con->value();
|
||||
verinum lsb = lsb_con->value();
|
||||
|
||||
delete msb_exp;
|
||||
delete lsb_exp;
|
||||
|
||||
if (msb.as_long() > lsb.as_long())
|
||||
count = msb.as_long() - lsb.as_long() + 1;
|
||||
else
|
||||
count = lsb.as_long() - msb.as_long() + 1;
|
||||
|
||||
low = lsb.as_long();
|
||||
high = msb.as_long();
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: PGBuiltin: Make array "
|
||||
<< "[" << high << ":" << low << "]" << " of "
|
||||
<< count << " gates for " << get_name() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void PGBuiltin::calculate_gate_and_lval_count_(unsigned&gate_count,
|
||||
unsigned&lval_count) const
|
||||
{
|
||||
|
|
@ -724,7 +707,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
the count is 1, and high==low==0. */
|
||||
|
||||
long low=0, high=0;
|
||||
unsigned array_count = calculate_array_count_(des, scope, high, low);
|
||||
unsigned array_count = calculate_array_size_(des, scope, high, low);
|
||||
if (array_count == 0) return;
|
||||
|
||||
unsigned gate_count = 0, lval_count = 0;
|
||||
|
|
@ -855,10 +838,10 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
// to be the exact width required (this will be checked
|
||||
// later). But if this is a single instance, consensus
|
||||
// is that we just take the LSB of the port expression.
|
||||
NetExpr*tmp = elab_and_eval(des, scope, ex, msb_ ? -1 : 1);
|
||||
NetExpr*tmp = elab_and_eval(des, scope, ex, is_array() ? -1 : 1);
|
||||
if (tmp == 0)
|
||||
continue;
|
||||
if (msb_ == 0 && tmp->expr_width() != 1)
|
||||
if (!is_array() && tmp->expr_width() != 1)
|
||||
tmp = new NetESelect(tmp, make_const_0(1), 1,
|
||||
IVL_SEL_IDX_UP);
|
||||
sig = tmp->synthesize(des, scope, tmp);
|
||||
|
|
@ -1989,62 +1972,6 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
|
||||
}
|
||||
|
||||
unsigned PGModule::calculate_instance_count_(Design*des, NetScope*scope,
|
||||
long&high, long&low,
|
||||
perm_string name) const
|
||||
{
|
||||
unsigned count = 1;
|
||||
high = 0;
|
||||
low = 0;
|
||||
|
||||
/* If the Verilog source has a range specification for the UDP, then
|
||||
* I am expected to make more than one gate. Figure out how many are
|
||||
* desired. */
|
||||
if (msb_) {
|
||||
NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1, true);
|
||||
NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1, true);
|
||||
|
||||
NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
|
||||
NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp);
|
||||
|
||||
if (msb_con == 0) {
|
||||
cerr << get_fileline() << ": error: Unable to evaluate "
|
||||
"expression " << *msb_ << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lsb_con == 0) {
|
||||
cerr << get_fileline() << ": error: Unable to evaluate "
|
||||
"expression " << *lsb_ << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum msb = msb_con->value();
|
||||
verinum lsb = lsb_con->value();
|
||||
|
||||
delete msb_exp;
|
||||
delete lsb_exp;
|
||||
|
||||
if (msb.as_long() > lsb.as_long())
|
||||
count = msb.as_long() - lsb.as_long() + 1;
|
||||
else
|
||||
count = lsb.as_long() - msb.as_long() + 1;
|
||||
|
||||
low = lsb.as_long();
|
||||
high = msb.as_long();
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: PGModule: Make range "
|
||||
<< "[" << high << ":" << low << "]" << " of "
|
||||
<< count << " UDPs for " << name << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* From a UDP definition in the source, make a NetUDP
|
||||
* object. Elaborate the pin expressions as netlists, then connect
|
||||
|
|
@ -2076,8 +2003,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
|
|||
}
|
||||
|
||||
long low = 0, high = 0;
|
||||
unsigned inst_count = calculate_instance_count_(des, scope, high, low,
|
||||
my_name);
|
||||
unsigned inst_count = calculate_array_size_(des, scope, high, low);
|
||||
if (inst_count == 0) return;
|
||||
|
||||
if (inst_count != 1) {
|
||||
|
|
|
|||
19
parse.y
19
parse.y
|
|
@ -4290,16 +4290,12 @@ gate_instance
|
|||
|
||||
| IDENTIFIER dimensions '(' port_conn_expression_list_with_nuls ')'
|
||||
{ lgate*tmp = new lgate;
|
||||
list<pform_range_t>*rng = $2;
|
||||
tmp->name = $1;
|
||||
tmp->parms = $4;
|
||||
tmp->range = rng->front();
|
||||
rng->pop_front();
|
||||
assert(rng->empty());
|
||||
tmp->ranges = $2;
|
||||
tmp->file = @1.text;
|
||||
tmp->lineno = @1.first_line;
|
||||
delete[]$1;
|
||||
delete rng;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
|
|
@ -4316,17 +4312,13 @@ gate_instance
|
|||
|
||||
| IDENTIFIER dimensions
|
||||
{ lgate*tmp = new lgate;
|
||||
list<pform_range_t>*rng = $2;
|
||||
tmp->name = $1;
|
||||
tmp->parms = 0;
|
||||
tmp->parms_by_name = 0;
|
||||
tmp->range = rng->front();
|
||||
rng->pop_front();
|
||||
assert(rng->empty());
|
||||
tmp->ranges = $2;
|
||||
tmp->file = @1.text;
|
||||
tmp->lineno = @1.first_line;
|
||||
delete[]$1;
|
||||
delete rng;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
|
|
@ -4345,17 +4337,13 @@ gate_instance
|
|||
|
||||
| IDENTIFIER dimensions '(' port_name_list ')'
|
||||
{ lgate*tmp = new lgate;
|
||||
list<pform_range_t>*rng = $2;
|
||||
tmp->name = $1;
|
||||
tmp->parms = 0;
|
||||
tmp->parms_by_name = $4;
|
||||
tmp->range = rng->front();
|
||||
rng->pop_front();
|
||||
assert(rng->empty());
|
||||
tmp->ranges = $2;
|
||||
tmp->file = @1.text;
|
||||
tmp->lineno = @1.first_line;
|
||||
delete[]$1;
|
||||
delete rng;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
|
|
@ -4377,6 +4365,7 @@ gate_instance
|
|||
tmp->name = $1;
|
||||
tmp->parms = 0;
|
||||
tmp->parms_by_name = 0;
|
||||
tmp->ranges = $2;
|
||||
tmp->file = @1.text;
|
||||
tmp->lineno = @1.first_line;
|
||||
yyerror(@3, "error: Syntax error in instance port "
|
||||
|
|
|
|||
20
pform.cc
20
pform.cc
|
|
@ -2260,8 +2260,7 @@ static void pform_makegate(PGBuiltin::Type type,
|
|||
|
||||
perm_string dev_name = lex_strings.make(info.name);
|
||||
PGBuiltin*cur = new PGBuiltin(type, dev_name, info.parms, delay);
|
||||
if (info.range.first)
|
||||
cur->set_range(info.range.first, info.range.second);
|
||||
cur->set_ranges(info.ranges);
|
||||
|
||||
// The pform_makegates() that calls me will take care of
|
||||
// deleting the attr pointer, so tell the
|
||||
|
|
@ -2326,7 +2325,7 @@ static void pform_make_modgate(perm_string type,
|
|||
perm_string name,
|
||||
struct parmvalue_t*overrides,
|
||||
list<PExpr*>*wires,
|
||||
PExpr*msb, PExpr*lsb,
|
||||
list<pform_range_t>*ranges,
|
||||
const char*fn, unsigned ln,
|
||||
std::list<named_pexpr_t>*attr)
|
||||
{
|
||||
|
|
@ -2337,7 +2336,7 @@ static void pform_make_modgate(perm_string type,
|
|||
|
||||
PGModule*cur = new PGModule(type, name, wires);
|
||||
FILE_NAME(cur, fn, ln);
|
||||
cur->set_range(msb,lsb);
|
||||
cur->set_ranges(ranges);
|
||||
|
||||
if (overrides && overrides->by_name) {
|
||||
unsigned cnt = overrides->by_name->size();
|
||||
|
|
@ -2369,7 +2368,7 @@ static void pform_make_modgate(perm_string type,
|
|||
perm_string name,
|
||||
struct parmvalue_t*overrides,
|
||||
list<named_pexpr_t>*bind,
|
||||
PExpr*msb, PExpr*lsb,
|
||||
list<pform_range_t>*ranges,
|
||||
const char*fn, unsigned ln,
|
||||
std::list<named_pexpr_t>*attr)
|
||||
{
|
||||
|
|
@ -2384,7 +2383,7 @@ static void pform_make_modgate(perm_string type,
|
|||
|
||||
PGModule*cur = new PGModule(type, name, pins, npins);
|
||||
FILE_NAME(cur, fn, ln);
|
||||
cur->set_range(msb,lsb);
|
||||
cur->set_ranges(ranges);
|
||||
|
||||
if (overrides && overrides->by_name) {
|
||||
unsigned cnt = overrides->by_name->size();
|
||||
|
|
@ -2452,8 +2451,7 @@ void pform_make_modgates(const struct vlltype&loc,
|
|||
|
||||
if (cur.parms_by_name) {
|
||||
pform_make_modgate(type, cur_name, overrides,
|
||||
cur.parms_by_name,
|
||||
cur.range.first, cur.range.second,
|
||||
cur.parms_by_name, cur.ranges,
|
||||
cur.file, cur.lineno, attr);
|
||||
|
||||
} else if (cur.parms) {
|
||||
|
|
@ -2466,15 +2464,13 @@ void pform_make_modgates(const struct vlltype&loc,
|
|||
cur.parms = new list<PExpr*>;
|
||||
}
|
||||
pform_make_modgate(type, cur_name, overrides,
|
||||
cur.parms,
|
||||
cur.range.first, cur.range.second,
|
||||
cur.parms, cur.ranges,
|
||||
cur.file, cur.lineno, attr);
|
||||
|
||||
} else {
|
||||
list<PExpr*>*wires = new list<PExpr*>;
|
||||
pform_make_modgate(type, cur_name, overrides,
|
||||
wires,
|
||||
cur.range.first, cur.range.second,
|
||||
wires, cur.ranges,
|
||||
cur.file, cur.lineno, attr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
4
pform.h
4
pform.h
|
|
@ -105,14 +105,14 @@ struct net_decl_assign_t {
|
|||
/* The lgate is gate instantiation information. */
|
||||
struct lgate {
|
||||
explicit inline lgate(int =0)
|
||||
: parms(0), parms_by_name(0), file(NULL), lineno(0)
|
||||
: parms(0), parms_by_name(0), ranges(0), file(NULL), lineno(0)
|
||||
{ }
|
||||
|
||||
std::string name;
|
||||
std::list<PExpr*>*parms;
|
||||
std::list<named_pexpr_t>*parms_by_name;
|
||||
|
||||
pform_range_t range;
|
||||
std::list<pform_range_t>*ranges;
|
||||
|
||||
const char* file;
|
||||
unsigned lineno;
|
||||
|
|
|
|||
|
|
@ -677,6 +677,17 @@ void PGate::dump_delays(ostream&out) const
|
|||
delay_.dump_delays(out);
|
||||
}
|
||||
|
||||
void PGate::dump_ranges(ostream&out) const
|
||||
{
|
||||
for (list<pform_range_t>::iterator cur = ranges_->begin()
|
||||
; cur != ranges_->end() ; ++cur) {
|
||||
out << "[";
|
||||
if (cur->first) out << *(cur->first);
|
||||
if (cur->second) out << ":" << *(cur->second);
|
||||
out << "]";
|
||||
}
|
||||
}
|
||||
|
||||
void PGate::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << typeid(*this).name() << " ";
|
||||
|
|
@ -739,11 +750,7 @@ void PGBuiltin::dump(ostream&out, unsigned ind) const
|
|||
out << "(" << strength0() << "0 " << strength1() << "1) ";
|
||||
dump_delays(out);
|
||||
out << " " << get_name();
|
||||
|
||||
if (msb_) {
|
||||
out << " [" << *msb_ << ":" << *lsb_ << "]";
|
||||
}
|
||||
|
||||
dump_ranges(out);
|
||||
out << "(";
|
||||
dump_pins(out);
|
||||
out << ");" << endl;
|
||||
|
|
@ -784,16 +791,7 @@ void PGModule::dump(ostream&out, unsigned ind) const
|
|||
}
|
||||
|
||||
out << get_name();
|
||||
|
||||
// If the module is arrayed, print the index expressions.
|
||||
if (msb_ || lsb_) {
|
||||
out << "[";
|
||||
if (msb_) out << *msb_;
|
||||
out << ":";
|
||||
if (lsb_) out << *lsb_;
|
||||
out << "]";
|
||||
}
|
||||
|
||||
dump_ranges(out);
|
||||
out << "(";
|
||||
if (pins_) {
|
||||
out << "." << pins_[0].name << "(";
|
||||
|
|
|
|||
Loading…
Reference in New Issue