Merge branch 'master' of git://icarus.com/~steve-icarus/verilog into vhdl

This commit is contained in:
Nick Gasson 2008-08-07 09:19:13 +01:00
commit a17924f819
5 changed files with 101 additions and 18 deletions

View File

@ -944,6 +944,17 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
return tmp; return tmp;
} }
static bool need_bufz_for_input_port(const svector<NetNet*>&prts)
{
if (prts[0]->port_type() != NetNet::PINPUT)
return false;
if (prts[0]->pin(0).nexus()->drivers_present())
return true;
return false;
}
/* /*
* Instantiate a module by recursively elaborating it. Set the path of * Instantiate a module by recursively elaborating it. Set the path of
* the recursive elaboration so that signal names get properly * the recursive elaboration so that signal names get properly
@ -1162,7 +1173,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
width. We use that, then, to decide how to hook width. We use that, then, to decide how to hook
it up. it up.
NOTE that this also handles the case that the v NOTE that this also handles the case that the
port is actually empty on the inside. We assume port is actually empty on the inside. We assume
in that case that the port is input. */ in that case that the port is input. */
@ -1176,6 +1187,21 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
continue; continue;
} }
if (need_bufz_for_input_port(prts)) {
NetBUFZ*tmp = new NetBUFZ(scope, scope->local_symbol(),
sig->vector_width());
des->add_node(tmp);
connect(tmp->pin(1), sig->pin(0));
NetNet*tmp2 = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, sig->vector_width());
tmp2->local_flag(true);
tmp2->set_line(*this);
tmp2->data_type(sig->data_type());
connect(tmp->pin(0), tmp2->pin(0));
sig = tmp2;
}
} else if (prts[0]->port_type() == NetNet::PINOUT) { } else if (prts[0]->port_type() == NetNet::PINOUT) {
/* Inout to/from module. This is a more /* Inout to/from module. This is a more

View File

@ -247,6 +247,41 @@ verinum::V Nexus::get_init() const
return verinum::Vz; return verinum::Vz;
} }
bool Nexus::drivers_present() const
{
assert(list_);
for (Link*cur = list_ ; cur ; cur = cur->next_) {
if (cur->get_dir() == Link::OUTPUT)
return true;
if (cur->get_dir() == Link::INPUT)
continue;
// Must be PASSIVE, so if it is some kind of net, see if
// it is the sort that might drive the nexus.
const NetObj*obj;
unsigned pin;
cur->cur_link(obj, pin);
if (const NetNet*net = dynamic_cast<const NetNet*>(obj))
switch (net->type()) {
case NetNet::SUPPLY0:
case NetNet::SUPPLY1:
case NetNet::TRI0:
case NetNet::TRI1:
case NetNet::WAND:
case NetNet::WOR:
case NetNet::TRIAND:
case NetNet::TRIOR:
case NetNet::REG:
return true;
default:
break;
}
}
return false;
}
void Nexus::drivers_delays(NetExpr*rise, NetExpr*fall, NetExpr*decay) void Nexus::drivers_delays(NetExpr*rise, NetExpr*fall, NetExpr*decay)
{ {
for (Link*cur = list_ ; cur ; cur = cur->next_) { for (Link*cur = list_ ; cur ; cur = cur->next_) {

View File

@ -290,6 +290,10 @@ class Nexus {
NetNet* pick_any_net(); NetNet* pick_any_net();
/* This method returns true if there are any drivers
(including variables) attached to this nexus. */
bool drivers_present() const;
/* This method returns true if all the possible drivers of /* This method returns true if all the possible drivers of
this nexus are constant. It will also return true if there this nexus are constant. It will also return true if there
are no drivers at all. */ are no drivers at all. */

View File

@ -281,7 +281,6 @@ static int scan_format(vpiHandle sys, struct byte_source*src, vpiHandle argv)
int suppress_flag = 0; int suppress_flag = 0;
int length_field = -1; int length_field = -1;
int code = 0; int code = 0;
int sign_flag = 1;
PLI_INT32 value; PLI_INT32 value;
char*tmp; char*tmp;
@ -373,30 +372,38 @@ static int scan_format(vpiHandle sys, struct byte_source*src, vpiHandle argv)
break; break;
case 'd': case 'd':
match_fail = 1; /* decimal integer */
/* Decimal integer */ tmp = malloc(2);
ch = byte_getc(src);
if (ch == '-') {
sign_flag = -1;
ch = byte_getc(src);
}
value = 0; value = 0;
while ( isdigit(ch) ) { tmp[0] = 0;
match_fail = 1;
ch = byte_getc(src);
while (isdigit(ch) || ch == '_' || (value == 0 && ch == '-')) {
match_fail = 0; match_fail = 0;
value *= 10; if (ch != '_') {
value += ch - '0'; tmp[value++] = ch;
tmp = realloc(tmp, value+1);
tmp[value] = 0;
ch = byte_getc(src); ch = byte_getc(src);
} }
}
byte_ungetc(src, ch);
if (match_fail) if (match_fail) {
free(tmp);
break; break;
}
/* Matched a decimal value, put it to an argument. */
item = vpi_scan(argv); item = vpi_scan(argv);
assert(item); assert(item);
val.format = vpiIntVal; val.format = vpiDecStrVal;
val.value.integer = value * sign_flag; val.value.str = tmp;
vpi_put_value(item, &val, 0, vpiNoDelay); vpi_put_value(item, &val, 0, vpiNoDelay);
free(tmp);
rc += 1; rc += 1;
break; break;

View File

@ -229,7 +229,13 @@ void vpip_dec_str_to_vec4(vvp_vector4_t&vec,
input is "1234", str gets "4321". */ input is "1234", str gets "4321". */
unsigned slen = strlen(buf); unsigned slen = strlen(buf);
char*str = new char[slen + 1]; char*str = new char[slen + 1];
int is_negative = 0;
for (unsigned idx = 0 ; idx < slen ; idx += 1) { for (unsigned idx = 0 ; idx < slen ; idx += 1) {
if (idx == slen-1 && buf[slen-idx-1] == '-') {
is_negative = 1;
slen--;
continue;
}
if (isdigit(buf[slen-idx-1])) if (isdigit(buf[slen-idx-1]))
str[idx] = buf[slen-idx-1]; str[idx] = buf[slen-idx-1];
else else
@ -266,5 +272,10 @@ void vpip_dec_str_to_vec4(vvp_vector4_t&vec,
} }
if (is_negative) {
vec.invert();
vec += 1;
}
delete[]str; delete[]str;
} }