Add message that a UDP with a range is not currently supported.

For now Icarus doesn't support a UDP instantiation with a range.
Instead of generating a warning about the port count being wrong
this patch adds code to calculate the range and print a message
if a range greater than one is found.
This commit is contained in:
Cary R 2011-04-04 10:43:58 -07:00 committed by Stephen Williams
parent c81645ff46
commit 0bc746dab0
2 changed files with 79 additions and 7 deletions

View File

@ -1,7 +1,7 @@
#ifndef __PGate_H #ifndef __PGate_H
#define __PGate_H #define __PGate_H
/* /*
* Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2011 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -238,6 +238,9 @@ class PGModule : public PGate {
friend class delayed_elaborate_scope_mod_instances; friend class delayed_elaborate_scope_mod_instances;
void elaborate_mod_(Design*, Module*mod, NetScope*scope) const; void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
void elaborate_udp_(Design*, PUdp *udp, 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_(Design*des, Module*mod, NetScope*sc) const;
void elaborate_scope_mod_instances_(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; bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;

View File

@ -263,8 +263,8 @@ unsigned PGBuiltin::calculate_array_count_(Design*des, NetScope*scope,
if (debug_elaborate) { if (debug_elaborate) {
cerr << get_fileline() << ": debug: PGBuiltin: Make array " cerr << get_fileline() << ": debug: PGBuiltin: Make array "
<< "[" << high << ":" << low << "]" << "[" << high << ":" << low << "]" << " of "
<< " of " << count << " gates for " << get_name() << endl; << count << " gates for " << get_name() << endl;
} }
} }
@ -684,8 +684,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
unsigned instance_width = 1; unsigned instance_width = 1;
perm_string name = get_name(); perm_string name = get_name();
if (name == "") if (name == "") name = scope->local_symbol();
name = scope->local_symbol();
/* Calculate the array bounds and instance count for the gate, /* Calculate the array bounds and instance count for the gate,
as described in the Verilog source. If there is none, then as described in the Verilog source. If there is none, then
@ -693,8 +692,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
long low=0, high=0; long low=0, high=0;
unsigned array_count = calculate_array_count_(des, scope, high, low); unsigned array_count = calculate_array_count_(des, scope, high, low);
if (array_count == 0) if (array_count == 0) return;
return;
unsigned output_count = calculate_output_count_(); unsigned output_count = calculate_output_count_();
@ -1771,6 +1769,64 @@ 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_) {
need_constant_expr = true;
NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1);
NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1);
need_constant_expr = false;
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 * From a UDP definition in the source, make a NetUDP
* object. Elaborate the pin expressions as netlists, then connect * object. Elaborate the pin expressions as netlists, then connect
@ -1801,6 +1857,19 @@ 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);
if (inst_count == 0) return;
if (inst_count != 1) {
cerr << get_fileline() << ": sorry: UDPs with a range ("
<< my_name << " [" << high << ":" << low << "]) are "
<< "not supported." << endl;
des->errors += 1;
return;
}
assert(udp); assert(udp);
NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp); NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp);
net->set_line(*this); net->set_line(*this);