Merge branch 'master' of git://icarus.com/~steve-icarus/verilog into vhdl
This commit is contained in:
commit
a17924f819
28
elaborate.cc
28
elaborate.cc
|
|
@ -944,6 +944,17 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
|
|||
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
|
||||
* 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
|
||||
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
|
||||
in that case that the port is input. */
|
||||
|
||||
|
|
@ -1176,6 +1187,21 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
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) {
|
||||
|
||||
/* Inout to/from module. This is a more
|
||||
|
|
|
|||
35
net_link.cc
35
net_link.cc
|
|
@ -247,6 +247,41 @@ verinum::V Nexus::get_init() const
|
|||
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)
|
||||
{
|
||||
for (Link*cur = list_ ; cur ; cur = cur->next_) {
|
||||
|
|
|
|||
|
|
@ -290,6 +290,10 @@ class Nexus {
|
|||
|
||||
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 nexus are constant. It will also return true if there
|
||||
are no drivers at all. */
|
||||
|
|
|
|||
|
|
@ -281,7 +281,6 @@ static int scan_format(vpiHandle sys, struct byte_source*src, vpiHandle argv)
|
|||
int suppress_flag = 0;
|
||||
int length_field = -1;
|
||||
int code = 0;
|
||||
int sign_flag = 1;
|
||||
PLI_INT32 value;
|
||||
|
||||
char*tmp;
|
||||
|
|
@ -373,30 +372,38 @@ static int scan_format(vpiHandle sys, struct byte_source*src, vpiHandle argv)
|
|||
break;
|
||||
|
||||
case 'd':
|
||||
match_fail = 1;
|
||||
/* Decimal integer */
|
||||
ch = byte_getc(src);
|
||||
if (ch == '-') {
|
||||
sign_flag = -1;
|
||||
ch = byte_getc(src);
|
||||
}
|
||||
/* decimal integer */
|
||||
tmp = malloc(2);
|
||||
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;
|
||||
value *= 10;
|
||||
value += ch - '0';
|
||||
if (ch != '_') {
|
||||
tmp[value++] = ch;
|
||||
tmp = realloc(tmp, value+1);
|
||||
tmp[value] = 0;
|
||||
ch = byte_getc(src);
|
||||
}
|
||||
}
|
||||
byte_ungetc(src, ch);
|
||||
|
||||
if (match_fail)
|
||||
if (match_fail) {
|
||||
free(tmp);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Matched a decimal value, put it to an argument. */
|
||||
item = vpi_scan(argv);
|
||||
assert(item);
|
||||
|
||||
val.format = vpiIntVal;
|
||||
val.value.integer = value * sign_flag;
|
||||
val.format = vpiDecStrVal;
|
||||
val.value.str = tmp;
|
||||
vpi_put_value(item, &val, 0, vpiNoDelay);
|
||||
|
||||
free(tmp);
|
||||
rc += 1;
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -229,7 +229,13 @@ void vpip_dec_str_to_vec4(vvp_vector4_t&vec,
|
|||
input is "1234", str gets "4321". */
|
||||
unsigned slen = strlen(buf);
|
||||
char*str = new char[slen + 1];
|
||||
int is_negative = 0;
|
||||
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]))
|
||||
str[idx] = buf[slen-idx-1];
|
||||
else
|
||||
|
|
@ -266,5 +272,10 @@ void vpip_dec_str_to_vec4(vvp_vector4_t&vec,
|
|||
|
||||
}
|
||||
|
||||
if (is_negative) {
|
||||
vec.invert();
|
||||
vec += 1;
|
||||
}
|
||||
|
||||
delete[]str;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue