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;
|
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
|
||||||
|
|
|
||||||
35
net_link.cc
35
net_link.cc
|
|
@ -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_) {
|
||||||
|
|
|
||||||
|
|
@ -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. */
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue