Fix range handling/checking and add a flag to allow deprecated port syntax.

This patch is rather large and fixes a couple of problems. The major
change is that instead of keeping all the range specifications in
a list that is later processed the information is now kept as
individual entries for the port and net definitions. This allows
easier checking for multiple definitions (pr1660028), more
detailed error messages and the ability to pass the now deprecated
style of a scalar I/O definition used with a vectored net definition.
These changes did require extra code to prevent a single definition
from setting the range values in more than on place.

When using the new ANSI-C style of port declarations (1364-2001 12.3.4
list_of_port_declarations) the compiler ensures that you do not
redeclare the port in the body (it is already completely defined).
This caught a few errors in the test suite (pr859 and sqrt32*).

The flag to disable the normal port checking and allow the deprecated
port syntax is -gno-io-range-error. This will print a warning for the
case of a scalar port with a vectored definition in the body. All
other cases are still considered an error.
This commit is contained in:
Cary R 2007-08-21 19:52:42 -07:00 committed by Stephen Williams
parent d08817aec1
commit b69c4c9a2c
11 changed files with 262 additions and 200 deletions

117
PWire.cc
View File

@ -22,6 +22,7 @@
# include "config.h"
# include "PWire.h"
# include "PExpr.h"
# include <assert.h>
PWire::PWire(const pform_name_t&n,
@ -29,8 +30,8 @@ PWire::PWire(const pform_name_t&n,
NetNet::PortType pt,
ivl_variable_type_t dt)
: hname_(n), type_(t), port_type_(pt), data_type_(dt),
signed_(false), isint_(false),
lidx_(0), ridx_(0)
signed_(false), isint_(false), port_set_(false), net_set_(false),
error_cnt_(0), lidx_(0), ridx_(0)
{
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
@ -129,10 +130,62 @@ bool PWire::get_isint() const
return isint_;
}
void PWire::set_range(PExpr*m, PExpr*l)
void PWire::set_net_range()
{
msb_ = svector<PExpr*>(msb_,m);
lsb_ = svector<PExpr*>(lsb_,l);
net_msb_ = port_msb_;
net_lsb_ = port_lsb_;
net_set_ = true;
}
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
{
switch (type) {
case SR_PORT:
if (port_set_) {
cerr << get_line() << ": error: Port ``" << hname_
<< "'' has already been declared a port." << endl;
error_cnt_ += 1;
} else {
port_msb_ = m;
port_lsb_ = l;
port_set_ = true;
}
return;
case SR_NET:
if (net_set_) {
cerr << get_line() << ": error: Net ``" << hname_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
} else {
net_msb_ = m;
net_lsb_ = l;
net_set_ = true;
}
return;
case SR_BOTH:
if (port_set_ || net_set_) {
if (port_set_) {
cerr << get_line() << ": error: Port ``" << hname_
<< "'' has already been declared a port." << endl;
error_cnt_ += 1;
}
if (net_set_) {
cerr << get_line() << ": error: Net ``" << hname_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
}
} else {
port_msb_ = m;
port_lsb_ = l;
port_set_ = true;
net_msb_ = m;
net_lsb_ = l;
net_set_ = true;
}
return;
}
}
void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
@ -143,57 +196,3 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
ridx_ = rdx;
}
/*
* $Log: PWire.cc,v $
* Revision 1.14 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.13 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.12 2007/01/16 05:44:14 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.11 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.10 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.9 2002/06/21 04:59:35 steve
* Carry integerness throughout the compilation.
*
* Revision 1.8 2002/01/26 05:28:28 steve
* Detect scalar/vector declarion mismatch.
*
* Revision 1.7 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.6 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.5 2001/01/06 02:29:35 steve
* Support arrays of integers.
*
* Revision 1.4 2000/12/11 00:31:43 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.
*
* Revision 1.3 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/09/10 05:02:09 steve
* Handle integers at task parameters.
*
* Revision 1.1 1999/06/17 05:34:42 steve
* Clean up interface of the PWire class,
* Properly match wire ranges.
*
*/

63
PWire.h
View File

@ -37,6 +37,11 @@ class ostream;
class PExpr;
class Design;
/*
* The different type of PWire::set_range() calls.
*/
enum PWSRType {SR_PORT, SR_NET, SR_BOTH};
/*
* Wires include nets, registers and ports. A net or register becomes
* a port by declaration, so ports are not separate. The module
@ -72,7 +77,8 @@ class PWire : public LineInfo {
bool set_data_type(ivl_variable_type_t dt);
ivl_variable_type_t get_data_type() const;
void set_range(PExpr*msb, PExpr*lsb);
void set_range(PExpr*msb, PExpr*lsb, PWSRType type);
void set_net_range();
void set_memory_idx(PExpr*ldx, PExpr*rdx);
@ -93,8 +99,13 @@ class PWire : public LineInfo {
// These members hold expressions for the bit width of the
// wire. If they do not exist, the wire is 1 bit wide.
svector<PExpr*>msb_;
svector<PExpr*>lsb_;
PExpr*port_msb_;
PExpr*port_lsb_;
bool port_set_;
PExpr*net_msb_;
PExpr*net_lsb_;
bool net_set_;
unsigned error_cnt_;
// If this wire is actually a memory, these indices will give
// me the size and address range of the memory.
@ -106,50 +117,4 @@ class PWire : public LineInfo {
PWire& operator= (const PWire&);
};
/*
* $Log: PWire.h,v $
* Revision 1.21 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.20 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.19 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.18 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.17 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.16 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.15 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.14 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.13 2002/06/21 04:59:35 steve
* Carry integerness throughout the compilation.
*
* Revision 1.12 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.11 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.10 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*/
#endif

View File

@ -112,6 +112,10 @@ inline bool gn_cadence_types_enabled()
is false, then skip elaboration of specify behavior. */
extern bool gn_specify_blocks_flag;
/* If this flag is false a warning is printed when the port declaration
is scalar and the net/register definition is vectored. */
extern bool gn_io_range_error_flag;
/* This is the string to use to invoke the preprocessor. */
extern char*ivlpp_string;

View File

@ -4,7 +4,8 @@ iverilog - Icarus Verilog compiler
.SH SYNOPSIS
.B iverilog
[-ESVv] [-Bpath] [-ccmdfile] [-g1|-g2|-g2x|-gspecify-gxtypes] [-Dmacro[=defn]] [-pflag=value]
[-ESVv] [-Bpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value]
[-g1|-g2|-g2x|-gspecify|-gxtypes|-gio-range-error]
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
@ -72,6 +73,15 @@ Verilog as extensions beyond the baseline Verilog. It may be necessary
to disable extended types if compiling code that clashes with the few
new keywords used to implement the type system.
.TP 8
.B -gio-range-error\fI|\fP-gno-io-range-error
The standards requires that a vectored port have matching ranges for its
port declaration as well as any net/register declaration. It was common
practice in the past to only specify the range for the net/register
declaration and some tools still allow this. By default any mismatch is
reported as a error. Using \fI-gno-io-range-error\fP will produce a
warning instead of a fatal error for the case of a vectored net/register
and a scalar port declaration.
.TP 8
.B -I\fIincludedir\fP
Append directory \fIincludedir\fP to list of directories searched
for Verilog include files. The \fB-I\fP switch may be used many times

View File

@ -110,6 +110,7 @@ const char*depfile = 0;
const char*generation = "2x";
const char*gen_specify = "specify";
const char*gen_xtypes = "xtypes";
const char*gen_io_range_error = "io-range-error";
char warning_flags[16] = "";
@ -439,6 +440,12 @@ int process_generation(const char*name)
else if (strcmp(name,"no-specify") == 0)
gen_specify = "no-specify";
else if (strcmp(name,"io-range-error") == 0)
gen_io_range_error = "io-range-error";
else if (strcmp(name,"no-io-range-error") == 0)
gen_io_range_error = "no-io-range-error";
else {
fprintf(stderr, "Unknown/Unsupported Language generation "
"%s\n", name);
@ -448,7 +455,8 @@ int process_generation(const char*name)
" 2x -- Verilog with extensions\n"
"Other generation flags:\n"
" specify | no-specify\n"
" xtypes | no-xtypes\n");
" xtypes | no-xtypes\n"
" io-range-error | no-io-range-error\n");
return 1;
}
@ -694,6 +702,7 @@ int main(int argc, char **argv)
fprintf(iconfig_file, "generation:%s\n", generation);
fprintf(iconfig_file, "generation:%s\n", gen_specify);
fprintf(iconfig_file, "generation:%s\n", gen_xtypes);
fprintf(iconfig_file, "generation:%s\n", gen_io_range_error);
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
fprintf(iconfig_file, "out:%s\n", opath);
if (depfile) fprintf(iconfig_file, "depfile:%s\n", depfile);

View File

@ -560,86 +560,118 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
unsigned wid = 1;
long lsb = 0, msb = 0;
assert(msb_.count() == lsb_.count());
if (msb_.count()) {
svector<long>mnum (msb_.count());
svector<long>lnum (msb_.count());
/* There may be places where the signal is declared as a
scalar. Count those here, for consistency check
later. */
unsigned count_scalars = 0;
des->errors += error_cnt_;
/* There may be multiple declarations of ranges, because
the symbol may have its range declared in e.g., input
and reg declarations. Calculate *all* the numbers
here. I will resolve the values later. */
if (port_set_ || net_set_) {
long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
/* If they exist get the port definition MSB and LSB */
if (port_set_ && port_msb_ != 0) {
NetExpr*texpr = elab_and_eval(des, scope, port_msb_, -1);
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
if (msb_[idx] == 0) {
count_scalars += 1;
assert(lsb_[idx] == 0);
mnum[idx] = 0;
lnum[idx] = 0;
continue;
}
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx], -1);
if (! eval_as_long(mnum[idx], texpr)) {
cerr << msb_[idx]->get_line() << ": error: "
"Unable to evaluate constant expression ``" <<
*msb_[idx] << "''." << endl;
if (! eval_as_long(pmsb, texpr)) {
cerr << port_msb_->get_line() << ": error: "
"Unable to evaluate MSB constant expression ``"
<< *port_msb_ << "''." << endl;
des->errors += 1;
return 0;
}
delete texpr;
texpr = elab_and_eval(des, scope, lsb_[idx], -1);
texpr = elab_and_eval(des, scope, port_lsb_, -1);
if (! eval_as_long(lnum[idx], texpr) ) {
cerr << msb_[idx]->get_line() << ": error: "
"Unable to evaluate constant expression ``" <<
*lsb_[idx] << "''." << endl;
if (! eval_as_long(plsb, texpr)) {
cerr << port_lsb_->get_line() << ": error: "
"Unable to evaluate LSB constant expression ``"
<< *port_lsb_ << "''." << endl;
des->errors += 1;
return 0;
}
delete texpr;
nmsb = pmsb;
nlsb = plsb;
}
if (port_msb_ == 0) assert(port_lsb_ == 0);
/* If they exist get the net/etc. definition MSB and LSB */
if (net_set_ && net_msb_ != 0) {
NetExpr*texpr = elab_and_eval(des, scope, net_msb_, -1);
if (! eval_as_long(nmsb, texpr)) {
cerr << net_msb_->get_line() << ": error: "
"Unable to evaluate MSB constant expression ``"
<< *net_msb_ << "''." << endl;
des->errors += 1;
return 0;
}
delete texpr;
texpr = elab_and_eval(des, scope, net_lsb_, -1);
if (! eval_as_long(nlsb, texpr)) {
cerr << net_lsb_->get_line() << ": error: "
"Unable to evaluate LSB constant expression ``"
<< *net_lsb_ << "''." << endl;
des->errors += 1;
return 0;
}
delete texpr;
}
if (net_msb_ == 0) assert(net_lsb_ == 0);
/* Check that the declarations were all scalar or all
vector. It is an error to mix them. Use the
count_scalars to know. */
if ((count_scalars > 0) && (count_scalars != msb_.count())) {
cerr << get_line() << ": error: Signal ``" << hname_
<< "'' declared both as a vector and a scalar."
<< endl;
des->errors += 1;
return 0;
}
/* We have a port size error */
if (port_set_ && net_set_ && (pmsb != nmsb || plsb != nlsb)) {
/* Scalar port with a vector net/etc. definition */
if (port_msb_ == 0) {
if (!gn_io_range_error_flag) {
cerr << get_line()
<< ": warning: Scalar port ``" << hname_
<< "'' has a vectored net declaration ["
<< nmsb << ":" << nlsb << "]." << endl;
} else {
cerr << get_line()
<< ": error: Scalar port ``" << hname_
<< "'' has a vectored net declaration ["
<< nmsb << ":" << nlsb << "]." << endl;
des->errors += 1;
return 0;
}
}
/* Make sure all the values for msb and lsb match by
value. If not, report an error. */
for (unsigned idx = 1 ; idx < msb_.count() ; idx += 1) {
if ((mnum[idx] != mnum[0]) || (lnum[idx] != lnum[0])) {
cerr << get_line() << ": error: Inconsistent width, "
"[" << mnum[idx] << ":" << lnum[idx] << "]"
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
" for signal ``" << hname_ << "''" << endl;
/* Vectored port with a scalar net/etc. definition */
if (net_msb_ == 0) {
cerr << port_msb_->get_line()
<< ": error: Vectored port ``"
<< hname_ << "'' [" << pmsb << ":" << plsb
<< "] has a scalar net declaration at "
<< get_line() << "." << endl;
des->errors += 1;
return 0;
}
}
lsb = lnum[0];
msb = mnum[0];
if (mnum[0] > lnum[0])
wid = mnum[0] - lnum[0] + 1;
/* Both vectored, but they have different ranges. */
if (port_msb_ != 0 && net_msb_ != 0) {
cerr << port_msb_->get_line()
<< ": error: Vectored port ``"
<< hname_ << "'' [" << pmsb << ":" << plsb
<< "] has a net declaration [" << nmsb << ":"
<< nlsb << "] at " << net_msb_->get_line()
<< " that does not match." << endl;
des->errors += 1;
return 0;
}
}
lsb = nlsb;
msb = nmsb;
if (nmsb > nlsb)
wid = nmsb - nlsb + 1;
else
wid = lnum[0] - mnum[0] + 1;
wid = nlsb - nmsb + 1;
}

View File

@ -89,6 +89,7 @@ const char*target = "null";
generation_t generation_flag = GN_DEFAULT;
bool gn_cadence_types_flag = true;
bool gn_specify_blocks_flag = true;
bool gn_io_range_error_flag = true;
map<string,const char*> flags;
char*vpi_module_list = 0;
@ -211,6 +212,12 @@ static void process_generation_flag(const char*gen)
} else if (strcmp(gen,"no-specify") == 0) {
gn_specify_blocks_flag = false;
} else if (strcmp(gen,"io-range-error") == 0) {
gn_io_range_error_flag = true;
} else if (strcmp(gen,"no-io-range-error") == 0) {
gn_io_range_error_flag = false;
} else {
}
}

11
parse.y
View File

@ -1411,12 +1411,14 @@ list_of_port_declarations
{ svector<Module::port_t*>*tmp
= new svector<Module::port_t*>(1);
(*tmp)[0] = $1;
pform_set_net_range($1[0].name);
$$ = tmp;
}
| list_of_port_declarations ',' port_declaration
{ svector<Module::port_t*>*tmp
= new svector<Module::port_t*>(*$1, $3);
delete $1;
pform_set_net_range($3[0].name);
$$ = tmp;
}
| list_of_port_declarations ',' IDENTIFIER
@ -1435,6 +1437,7 @@ list_of_port_declarations
port_declaration_context.sign_flag,
port_declaration_context.range, 0);
delete $1;
pform_set_net_range($3);
$$ = tmp;
}
;
@ -1694,13 +1697,13 @@ module_item
This creates the wire and sets the port type all at once. */
| port_type net_type signed_opt range_opt list_of_identifiers ';'
{ pform_makewire(@1, $4, $3, $5, $2, $1, IVL_VT_NO_TYPE, 0);
{ pform_makewire(@1, $4, $3, $5, $2, $1, IVL_VT_NO_TYPE, 0,
SR_BOTH);
}
| K_output var_type signed_opt range_opt list_of_identifiers ';'
{ pform_makewire(@1, $4, $3, $5, $2,
NetNet::POUTPUT,
IVL_VT_NO_TYPE, 0);
{ pform_makewire(@1, $4, $3, $5, $2, NetNet::POUTPUT,
IVL_VT_NO_TYPE, 0, SR_BOTH);
}
/* var_type declaration (reg variables) cannot be input or output,

View File

@ -828,6 +828,21 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
delete init_expr;
}
/*
* This function is used to set the net range for a port that uses
* the new (1364-2001) list_of_port_declarations, but omitted a
* register/wire/etc. that would have triggered it to be set elsewhere.
*/
void pform_set_net_range(const char* name)
{
PWire*cur = get_wire_in_module(hier_name(name));
if (cur == 0) {
VLerror("error: name is not a valid net.");
return;
}
cur->set_net_range();
}
/*
* This function attaches a range to a given name. The function is
* only called by the parser within the scope of the net declaration,
@ -836,7 +851,8 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
static void pform_set_net_range(const char* name,
const svector<PExpr*>*range,
bool signed_flag,
ivl_variable_type_t dt)
ivl_variable_type_t dt,
PWSRType rt)
{
PWire*cur = get_wire_in_module(hier_name(name));
if (cur == 0) {
@ -847,13 +863,13 @@ static void pform_set_net_range(const char* name,
if (range == 0) {
/* This is the special case that we really mean a
scalar. Set a fake range. */
cur->set_range(0, 0);
cur->set_range(0, 0, rt);
} else {
assert(range->count() == 2);
assert((*range)[0]);
assert((*range)[1]);
cur->set_range((*range)[0], (*range)[1]);
cur->set_range((*range)[0], (*range)[1], rt);
}
cur->set_signed(signed_flag);
@ -864,7 +880,8 @@ static void pform_set_net_range(const char* name,
void pform_set_net_range(list<perm_string>*names,
svector<PExpr*>*range,
bool signed_flag,
ivl_variable_type_t dt)
ivl_variable_type_t dt,
PWSRType rt)
{
assert((range == 0) || (range->count() == 2));
@ -872,7 +889,7 @@ void pform_set_net_range(list<perm_string>*names,
; cur != names->end()
; cur ++ ) {
perm_string txt = *cur;
pform_set_net_range(txt, range, signed_flag, dt);
pform_set_net_range(txt, range, signed_flag, dt, rt);
}
delete names;
@ -1217,13 +1234,15 @@ void pform_module_define_port(const struct vlltype&li,
cur->set_signed(signed_flag);
if (range == 0) {
cur->set_range(0, 0);
cur->set_range(0, 0, (type == NetNet::IMPLICIT) ? SR_PORT :
SR_BOTH);
} else {
assert(range->count() == 2);
assert((*range)[0]);
assert((*range)[1]);
cur->set_range((*range)[0], (*range)[1]);
cur->set_range((*range)[0], (*range)[1],
(type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
}
if (attr) {
@ -1296,7 +1315,7 @@ void pform_makewire(const vlltype&li, const char*nm,
switch (dt) {
case IVL_VT_REAL:
cur->set_data_type(dt);
cur->set_range(0, 0);
cur->set_range(0, 0, SR_NET);
cur->set_signed(true);
break;
default:
@ -1320,7 +1339,7 @@ void pform_makewire(const vlltype&li, const char*nm,
/*
* This form takes a list of names and some type information, and
* generates a bunch of variables/nets. We hse the basic
* generates a bunch of variables/nets. We use the basic
* pform_makewire above.
*/
void pform_makewire(const vlltype&li,
@ -1330,14 +1349,18 @@ void pform_makewire(const vlltype&li,
NetNet::Type type,
NetNet::PortType pt,
ivl_variable_type_t dt,
svector<named_pexpr_t*>*attr)
svector<named_pexpr_t*>*attr,
PWSRType rt)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end()
; cur ++ ) {
perm_string txt = *cur;
pform_makewire(li, txt, type, pt, dt, attr);
pform_set_net_range(txt, range, signed_flag, dt);
/* This has already been done for real variables. */
if (dt != IVL_VT_REAL) {
pform_set_net_range(txt, range, signed_flag, dt, rt);
}
}
delete names;
@ -1364,7 +1387,11 @@ void pform_makewire(const vlltype&li,
net_decl_assign_t*next = first->next;
pform_makewire(li, first->name, type, NetNet::NOT_A_PORT, dt, 0);
pform_set_net_range(first->name, range, signed_flag, dt);
/* This has already been done for real variables. */
if (dt != IVL_VT_REAL) {
pform_set_net_range(first->name, range, signed_flag, dt,
SR_NET);
}
perm_string first_name = lex_strings.make(first->name);
pform_name_t name = hier_name(first_name);
@ -1491,7 +1518,7 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
/* If there is a range involved, it needs to be set. */
if (range)
curw->set_range((*range)[0], (*range)[1]);
curw->set_range((*range)[0], (*range)[1], SR_PORT);
svector<PWire*>*tmp = new svector<PWire*>(*res, curw);
@ -1694,7 +1721,8 @@ void pform_set_port_type(const struct vlltype&li,
; cur ++ ) {
perm_string txt = *cur;
pform_set_port_type(txt, pt, li.text, li.first_line);
pform_set_net_range(txt, range, signed_flag, IVL_VT_NO_TYPE);
pform_set_net_range(txt, range, signed_flag, IVL_VT_NO_TYPE,
SR_PORT);
}
delete names;
@ -1721,7 +1749,8 @@ static void pform_set_reg_integer(const char*nm)
assert(cur);
cur->set_range(new PENumber(new verinum(integer_width-1, integer_width)),
new PENumber(new verinum((uint64_t)0, integer_width)));
new PENumber(new verinum((uint64_t)0, integer_width)),
SR_NET);
cur->set_signed(true);
}
@ -1752,7 +1781,8 @@ static void pform_set_reg_time(const char*nm)
assert(cur);
cur->set_range(new PENumber(new verinum(TIME_WIDTH-1, integer_width)),
new PENumber(new verinum((uint64_t)0, integer_width)));
new PENumber(new verinum((uint64_t)0, integer_width)),
SR_NET);
}
void pform_set_reg_time(list<perm_string>*names)

View File

@ -210,7 +210,8 @@ extern void pform_makewire(const struct vlltype&li,
NetNet::Type type,
NetNet::PortType,
ivl_variable_type_t,
svector<named_pexpr_t*>*attr);
svector<named_pexpr_t*>*attr,
PWSRType rt = SR_NET);
/* This form handles assignment declarations. */
extern void pform_makewire(const struct vlltype&li,
@ -236,10 +237,12 @@ extern void pform_set_port_type(const struct vlltype&li,
extern void pform_set_port_type(perm_string nm, NetNet::PortType pt,
const char*file, unsigned lineno);
extern void pform_set_net_range(const char* name);
extern void pform_set_net_range(list<perm_string>*names,
svector<PExpr*>*,
bool signed_flag,
ivl_variable_type_t);
ivl_variable_type_t,
PWSRType rt = SR_NET);
extern void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r);
extern void pform_set_reg_integer(list<perm_string>*names);
extern void pform_set_reg_time(list<perm_string>*names);

View File

@ -281,18 +281,18 @@ void PWire::dump(ostream&out, unsigned ind) const
out << " signed";
}
assert(msb_.count() == lsb_.count());
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
if (msb_[idx] == 0) {
assert(lsb_[idx] == 0);
out << " <scalar>";
if (port_set_) {
if (port_msb_ == 0) {
out << " port<scalar>";
} else {
if (lsb_[idx])
out << " [" << *msb_[idx] << ":" << *lsb_[idx] << "]";
else
out << " [" << *msb_[idx] << "]";
out << " port[" << *port_msb_ << ":" << *port_lsb_ << "]";
}
}
if (net_set_) {
if (net_msb_ == 0) {
out << " net<scalar>";
} else {
out << " net[" << *net_msb_ << ":" << *net_lsb_ << "]";
}
}