Ranges are ranges, not expression lists.

This is a cleanup in preparation for better support of range lists.
(cherry picked from commit 8f7cf3255acad55841f8b3725e3786ef49daad68)

Conflicts:

	PTask.h
	elab_scope.cc
	elab_sig.cc
	parse.y
	pform.cc
	pform.h
	pform_types.h

Signed-off-by: Stephen Williams <steve@icarus.com>
This commit is contained in:
Stephen Williams 2012-04-10 14:29:28 -07:00
parent cf0b45702f
commit 13348ba7ac
10 changed files with 170 additions and 184 deletions

View File

@ -48,7 +48,7 @@ enum PTaskFuncEnum {
struct PTaskFuncArg {
PTaskFuncEnum type;
std::list<index_component_t>*range;
std::list<pform_range_t>*range;
};
/*

View File

@ -192,7 +192,7 @@ void PWire::set_range_scalar(PWSRType type)
}
}
void PWire::set_range(const list<PWire::range_t>&rlist, PWSRType type)
void PWire::set_range(const list<pform_range_t>&rlist, PWSRType type)
{
switch (type) {
case SR_PORT:

11
PWire.h
View File

@ -51,11 +51,6 @@ enum PWSRType {SR_PORT, SR_NET, SR_BOTH};
* the wire name.
*/
class PWire : public LineInfo {
public:
struct range_t {
PExpr*msb;
PExpr*lsb;
};
public:
PWire(perm_string name,
@ -81,7 +76,7 @@ class PWire : public LineInfo {
ivl_variable_type_t get_data_type() const;
void set_range_scalar(PWSRType type);
void set_range(const std::list<range_t>&ranges, PWSRType type);
void set_range(const std::list<pform_range_t>&ranges, PWSRType type);
void set_memory_idx(PExpr*ldx, PExpr*rdx);
@ -112,9 +107,9 @@ class PWire : public LineInfo {
// bit. The first item in the list is the first range, and so
// on. For example "reg [3:0][7:0] ..." will contains the
// range_t object for [3:0] first and [7:0] last.
std::list<range_t>port_;
std::list<pform_range_t>port_;
bool port_set_;
std::list<range_t>net_;
std::list<pform_range_t>net_;
bool net_set_;
bool is_scalar_;
unsigned error_cnt_;

View File

@ -134,9 +134,9 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
{
bool rc_flag;
assert(enum_type->range->size() == 1);
index_component_t index = enum_type->range->front();
NetExpr*msb_ex = elab_and_eval(des, scope, index.msb, -1);
NetExpr*lsb_ex = elab_and_eval(des, scope, index.lsb, -1);
pform_range_t&range = enum_type->range->front();
NetExpr*msb_ex = elab_and_eval(des, scope, range.first, -1);
NetExpr*lsb_ex = elab_and_eval(des, scope, range.second, -1);
long msb = 0;
rc_flag = eval_as_long(msb, msb_ex);

View File

@ -477,11 +477,15 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
case PTF_REG_S:
if (return_type_.range) {
ivl_assert(*this, return_type_.range->size() == 1);
index_component_t index = return_type_.range->front();
pform_range_t&return_range = return_type_.range->front();
NetExpr*me = elab_and_eval(des, scope, index.msb, -1, true);
NetExpr*me = elab_and_eval(des, scope,
return_range.first, -1,
true);
assert(me);
NetExpr*le = elab_and_eval(des, scope, index.lsb, -1, true);
NetExpr*le = elab_and_eval(des, scope,
return_range.second, -1,
true);
assert(le);
long mnum = 0, lnum = 0;
@ -550,10 +554,14 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
long use_wid;
{
ivl_assert(*this, return_type_.range->size() == 1);
index_component_t index = return_type_.range->front();
NetExpr*me = elab_and_eval(des, scope, index.msb, -1, true);
pform_range_t&return_range = return_type_.range->front();
NetExpr*me = elab_and_eval(des, scope,
return_range.first, -1,
true);
ivl_assert(*this, me);
NetExpr*le = elab_and_eval(des, scope, index.lsb, -1, true);
NetExpr*le = elab_and_eval(des, scope,
return_range.second, -1,
true);
ivl_assert(*this, le);
long mnum = 0, lnum = 0;
@ -809,9 +817,9 @@ static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
long use_lsb = 0;
if (curp->range.get() && ! curp->range->empty()) {
ivl_assert(*curp, curp->range->size() == 1);
index_component_t index = curp->range->front();
PExpr*msb_pex = index.msb;
PExpr*lsb_pex = index.lsb;
pform_range_t&rangep = curp->range->front();
PExpr*msb_pex = rangep.first;
PExpr*lsb_pex = rangep.second;
NetExpr*tmp = elab_and_eval(des, scope, msb_pex, -2, true);
ivl_assert(*curp, tmp);
@ -842,34 +850,34 @@ static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
static bool evaluate_ranges(Design*des, NetScope*scope,
list<NetNet::range_t>&llist,
const list<PWire::range_t>&rlist)
const list<pform_range_t>&rlist)
{
bool bad_msb = false, bad_lsb = false;
for (list<PWire::range_t>::const_iterator cur = rlist.begin()
for (list<pform_range_t>::const_iterator cur = rlist.begin()
; cur != rlist.end() ; ++cur) {
NetNet::range_t lrng;
NetExpr*texpr = elab_and_eval(des, scope, cur->msb, -1, true);
NetExpr*texpr = elab_and_eval(des, scope, cur->first, -1, true);
if (! eval_as_long(lrng.msb, texpr)) {
cerr << cur->msb->get_fileline() << ": error: "
cerr << cur->first->get_fileline() << ": error: "
"Range expressions must be constant." << endl;
cerr << cur->msb->get_fileline() << " : "
cerr << cur->first->get_fileline() << " : "
"This MSB expression violates the rule: "
<< *cur->msb << endl;
<< *cur->first << endl;
des->errors += 1;
bad_msb = true;
}
delete texpr;
texpr = elab_and_eval(des, scope, cur->lsb, -1, true);
texpr = elab_and_eval(des, scope, cur->second, -1, true);
if (! eval_as_long(lrng.lsb, texpr)) {
cerr << cur->lsb->get_fileline() << ": error: "
cerr << cur->second->get_fileline() << ": error: "
"Range expressions must be constant." << endl;
cerr << cur->lsb->get_fileline() << " : "
cerr << cur->second->get_fileline() << " : "
"This LSB expression violates the rule: "
<< *cur->lsb << endl;
<< *cur->second << endl;
des->errors += 1;
bad_lsb = true;
}
@ -1007,7 +1015,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
/* Vectored port with a scalar net/etc. definition */
if (net_.empty()) {
cerr << port_.front().msb->get_fileline()
cerr << port_.front().first->get_fileline()
<< ": error: Vectored port ``"
<< name_ << "'' " << plist
<< " has a scalar net declaration at "
@ -1018,11 +1026,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
/* Both vectored, but they have different ranges. */
if (!port_.empty() && !net_.empty()) {
cerr << port_.front().msb->get_fileline()
cerr << port_.front().first->get_fileline()
<< ": error: Vectored port ``"
<< name_ << "'' " << plist
<< " has a net declaration " << nlist
<< " at " << net_.front().msb->get_fileline()
<< " at " << net_.front().first->get_fileline()
<< " that does not match." << endl;
des->errors += 1;
return 0;

128
parse.y
View File

@ -38,7 +38,7 @@ extern void lex_end_table();
bool have_timeunit_decl = false;
bool have_timeprec_decl = false;
static list<index_component_t>* param_active_range = 0;
static list<pform_range_t>* param_active_range = 0;
static bool param_active_signed = false;
static ivl_variable_type_t param_active_type = IVL_VT_LOGIC;
@ -48,8 +48,8 @@ static struct {
NetNet::PortType port_type;
ivl_variable_type_t var_type;
bool sign_flag;
list<index_component_t>* range;
data_type_t* data_type;
list<pform_range_t>* range;
} port_declaration_context = {NetNet::NONE, NetNet::NOT_A_PORT,
IVL_VT_NO_TYPE, false, 0, 0};
@ -106,16 +106,28 @@ static list<pair<perm_string,PExpr*> >* make_port_list(list<pair<perm_string, PE
return tmp;
}
list<index_component_t>* make_range_from_width(uint64_t wid)
list<pform_range_t>* make_range_from_width(uint64_t wid)
{
list<index_component_t>*range = new list<index_component_t>;
pform_range_t range;
range.first = new PENumber(new verinum(wid-1, integer_width));
range.second = new PENumber(new verinum((uint64_t)0, integer_width));
index_component_t tmp;
tmp.msb = new PENumber(new verinum(wid-1, integer_width));
tmp.lsb = new PENumber(new verinum((uint64_t)0, integer_width));
range->push_back(tmp);
list<pform_range_t>*rlist = new list<pform_range_t>;
rlist->push_back(range);
return rlist;
}
return range;
static list<pform_range_t>* make_range_from_pair(list<PExpr*>*rpair)
{
pform_range_t range;
assert(rpair && rpair->size() == 2);
range.first = rpair->front();
range.second = rpair->back();
delete rpair;
list<pform_range_t>*rlist = new list<pform_range_t>;
rlist->push_back(range);
return rlist;
}
static list<perm_string>* list_from_identifier(char*id)
@ -133,12 +145,12 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
return tmp;
}
list<index_component_t>* copy_range(list<index_component_t>* orig)
list<pform_range_t>* copy_range(list<pform_range_t>* orig)
{
list<index_component_t>*copy = 0;
list<pform_range_t>*copy = 0;
if (orig)
copy = new list<index_component_t> (*orig);
copy = new list<pform_range_t> (*orig);
return copy;
}
@ -341,6 +353,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
named_pexpr_t*named_pexpr;
list<named_pexpr_t>*named_pexprs;
struct parmvalue_t*parmvalue;
list<pform_range_t>*ranges;
PExpr*expr;
list<PExpr*>*exprs;
@ -547,8 +560,9 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%type <struct_members> struct_union_member_list
%type <struct_type> struct_data_type
%type <dimensions> range range_opt
%type <dimensions> dimensions_opt dimensions variable_dimension
%type <ranges> range range_opt variable_dimension
%type <ranges> dimensions_opt dimensions
%type <nettype> net_type var_type net_type_opt
%type <gatetype> gatetype switchtype
%type <porttype> port_direction port_direction_opt
@ -1472,7 +1486,7 @@ tf_port_declaration /* IEEE1800-2005: A.2.7 */
shape. Generate a range ([31:0]) to make it work. */
| port_direction K_integer list_of_identifiers ';'
{ list<index_component_t>*range_stub = make_range_from_width(integer_width);
{ list<pform_range_t>*range_stub = make_range_from_width(integer_width);
svector<PWire*>*tmp = pform_make_task_ports(@1, $1, IVL_VT_LOGIC, true,
range_stub, $3, true);
$$ = tmp;
@ -1481,7 +1495,7 @@ tf_port_declaration /* IEEE1800-2005: A.2.7 */
/* Ports can be time with a width of [63:0] (unsigned). */
| port_direction K_time list_of_identifiers ';'
{ list<index_component_t>*range_stub = make_range_from_width(64);
{ list<pform_range_t>*range_stub = make_range_from_width(64);
svector<PWire*>*tmp = pform_make_task_ports(@1, $1, IVL_VT_LOGIC, false,
range_stub, $3);
$$ = tmp;
@ -1511,7 +1525,7 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
/* Ports can be integer with a width of [31:0]. */
: port_direction_opt K_integer IDENTIFIER range_opt tf_port_item_expr_opt
{ list<index_component_t>*range_stub = make_range_from_width(integer_width);
{ list<pform_range_t>*range_stub = make_range_from_width(integer_width);
NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1;
port_declaration_context.port_type = use_port_type;
@ -1537,7 +1551,7 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
/* Ports can be time with a width of [63:0] (unsigned). */
| port_direction_opt K_time IDENTIFIER range_opt tf_port_item_expr_opt
{ list<index_component_t>*range_stub = make_range_from_width(64);
{ list<pform_range_t>*range_stub = make_range_from_width(64);
NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1;
port_declaration_context.port_type = use_port_type;
@ -1668,11 +1682,8 @@ value_range /* IEEE1800-2005: A.8.3 */
variable_dimension /* IEEE1800-2005: A.2.5 */
: '[' expression ':' expression ']'
{ list<index_component_t> *tmp = new list<index_component_t>;
index_component_t index;
index.sel = index_component_t::SEL_PART;
index.msb = $2;
index.lsb = $4;
{ list<pform_range_t> *tmp = new list<pform_range_t>;
pform_range_t index ($2,$4);
tmp->push_back(index);
$$ = tmp;
}
@ -1683,29 +1694,24 @@ variable_dimension /* IEEE1800-2005: A.2.5 */
cerr << @2 << ": warning: Use of SystemVerilog [size] dimension. "
<< "Use at least -g2005-sv to remove this warning." << endl;
}
list<index_component_t> *tmp = new list<index_component_t>;
index_component_t index;
index.sel = index_component_t::SEL_PART;
index.lsb = new PENumber(new verinum((uint64_t)0, integer_width));
index.msb = new PEBinary('-', $2, new PENumber(new verinum((uint64_t)1, integer_width)));
list<pform_range_t> *tmp = new list<pform_range_t>;
pform_range_t index;
index.first = new PENumber(new verinum((uint64_t)0, integer_width));
index.second = new PEBinary('-', $2, new PENumber(new verinum((uint64_t)1, integer_width)));
tmp->push_back(index);
$$ = tmp;
}
| '[' ']'
{ list<index_component_t> *tmp = new list<index_component_t>;
index_component_t index;
index.msb = 0;
index.lsb = 0;
{ list<pform_range_t> *tmp = new list<pform_range_t>;
pform_range_t index (0,0);
yyerror("sorry: Dynamic array ranges not supported.");
tmp->push_back(index);
$$ = tmp;
}
| '[' '$' ']'
{ // SystemVerilog queue
list<index_component_t> *tmp = new list<index_component_t>;
index_component_t index;
index.msb = 0;
index.lsb = 0;
list<pform_range_t> *tmp = new list<pform_range_t>;
pform_range_t index (0,0);
if (gn_system_verilog()) {
yyerror("sorry: Dynamic array ranges not supported.");
} else {
@ -1898,7 +1904,7 @@ enum_data_type
enum_type->names .reset($3);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = true;
enum_type->range.reset( make_range_from_width(32) );
enum_type->range.reset(make_range_from_width(32));
$$ = enum_type;
}
| K_enum atom2_type signed_unsigned_opt '{' enum_name_list '}'
@ -1907,7 +1913,7 @@ enum_data_type
enum_type->names .reset($5);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = $3;
enum_type->range.reset( make_range_from_width($2) );
enum_type->range.reset(make_range_from_width($2));
$$ = enum_type;
}
| K_enum K_integer signed_unsigned_opt '{' enum_name_list '}'
@ -1916,7 +1922,7 @@ enum_data_type
enum_type->names .reset($5);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
enum_type->range.reset( make_range_from_width(integer_width) );
enum_type->range.reset(make_range_from_width(integer_width));
$$ = enum_type;
}
| K_enum K_logic unsigned_signed_opt range '{' enum_name_list '}'
@ -1925,7 +1931,7 @@ enum_data_type
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
enum_type->range.reset( $4 );
enum_type->range.reset($4);
$$ = enum_type;
}
| K_enum K_reg unsigned_signed_opt range '{' enum_name_list '}'
@ -1934,7 +1940,7 @@ enum_data_type
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
enum_type->range.reset( $4 );
enum_type->range.reset($4);
$$ = enum_type;
}
| K_enum K_bit unsigned_signed_opt range '{' enum_name_list '}'
@ -1943,7 +1949,7 @@ enum_data_type
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = $3;
enum_type->range.reset( $4 );
enum_type->range.reset($4);
$$ = enum_type;
}
;
@ -2066,7 +2072,7 @@ struct_union_member
{ struct_member_t*tmp = new struct_member_t;
FILE_NAME(tmp, @2);
tmp->type = IVL_VT_BOOL;
tmp->range .reset( make_range_from_width($2) );
tmp->range .reset(make_range_from_width($2));
tmp->names .reset($3);
$$ = tmp;
}
@ -3163,7 +3169,7 @@ gate_instance
| IDENTIFIER range '(' expression_list_with_nuls ')'
{ lgate*tmp = new lgate;
list<index_component_t>*rng = $2;
list<pform_range_t>*rng = $2;
tmp->name = $1;
tmp->parms = $4;
tmp->range = rng->front();
@ -3189,7 +3195,7 @@ gate_instance
| IDENTIFIER range
{ lgate*tmp = new lgate;
list<index_component_t>*rng = $2;
list<pform_range_t>*rng = $2;
tmp->name = $1;
tmp->parms = 0;
tmp->parms_by_name = 0;
@ -3218,7 +3224,7 @@ gate_instance
| IDENTIFIER range '(' port_name_list ')'
{ lgate*tmp = new lgate;
list<index_component_t>*rng = $2;
list<pform_range_t>*rng = $2;
tmp->name = $1;
tmp->parms = 0;
tmp->parms_by_name = $4;
@ -3483,7 +3489,7 @@ port_declaration
K_input atom2_type signed_unsigned_opt IDENTIFIER
{ Module::port_t*ptmp;
perm_string name = lex_strings.make($5);
list<index_component_t>*use_range = make_range_from_width($3);
list<pform_range_t>* use_range = make_range_from_width($3);
ptmp = pform_module_port_reference(name, @2.text,
@2.first_line);
pform_module_define_port(@2, name, NetNet::PINPUT,
@ -3629,7 +3635,7 @@ port_declaration
K_output atom2_type signed_unsigned_opt IDENTIFIER
{ Module::port_t*ptmp;
perm_string name = lex_strings.make($5);
list<index_component_t>*use_range = make_range_from_width($3);
list<pform_range_t>*use_range = make_range_from_width($3);
ptmp = pform_module_port_reference(name, @2.text,
@2.first_line);
pform_module_define_port(@2, name, NetNet::POUTPUT,
@ -3648,7 +3654,7 @@ port_declaration
K_output atom2_type signed_unsigned_opt IDENTIFIER '=' expression
{ Module::port_t*ptmp;
perm_string name = lex_strings.make($5);
list<index_component_t>*use_range = make_range_from_width($3);
list<pform_range_t>*use_range = make_range_from_width($3);
ptmp = pform_module_port_reference(name, @2.text,
@2.first_line);
pform_module_define_port(@2, name, NetNet::POUTPUT,
@ -4953,7 +4959,7 @@ range
: variable_dimension
{ $$ = $1; }
| range variable_dimension
{ list<index_component_t>*tmp = $1;
{ list<pform_range_t>*tmp = $1;
if ($2) {
tmp->splice(tmp->end(), *$2);
delete $2;
@ -4975,7 +4981,7 @@ dimensions
: variable_dimension
{ $$ = $1; }
| dimensions variable_dimension
{ list<index_component_t> *tmp = $1;
{ list<pform_range_t> *tmp = $1;
if ($2) {
tmp->splice(tmp->end(), *$2);
delete $2;
@ -4991,29 +4997,23 @@ function_range_or_type_opt
: unsigned_signed_opt range_opt
{ /* the default type is reg unsigned and no range */
$$.type = PTF_REG;
$$.range = 0;
$$.range = $2;
if ($1)
$$.type = PTF_REG_S;
if ($2)
$$.range = $2;
}
| K_reg unsigned_signed_opt range_opt
{ /* the default type is reg unsigned and no range */
$$.type = PTF_REG;
$$.range = 0;
$$.range = $3;
if ($2)
$$.type = PTF_REG_S;
if ($3)
$$.range = $3;
}
| bit_logic unsigned_signed_opt range_opt
{ /* the default type is bit/logic unsigned and no range */
$$.type = PTF_REG;
$$.range = 0;
$$.range = $3;
if ($2)
$$.type = PTF_REG_S;
if ($3)
$$.range = $3;
}
| K_integer { $$.range = 0; $$.type = PTF_INTEGER; }
| K_real { $$.range = 0; $$.type = PTF_REAL; }
@ -5037,13 +5037,13 @@ register_variable
pform_makewire(@1, ident_name, NetNet::REG,
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
if ($2 != 0) {
index_component_t index;
pform_range_t index;
if ($2->size() > 1) {
yyerror(@2, "sorry: only 1 dimensional arrays "
"are currently supported.");
}
index = $2->front();
pform_set_reg_idx(ident_name, index.msb, index.lsb);
pform_set_reg_idx(ident_name, index.first, index.second);
delete $2;
}
$$ = $1;
@ -5078,13 +5078,13 @@ net_variable
pform_makewire(@1, name, NetNet::IMPLICIT,
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
if ($2 != 0) {
index_component_t index;
pform_range_t index;
if ($2->size() > 1) {
yyerror(@2, "sorry: only 1 dimensional arrays "
"are currently supported.");
}
index = $2->front();
pform_set_reg_idx(name, index.msb, index.lsb);
pform_set_reg_idx(name, index.first, index.second);
delete $2;
}
$$ = $1;

109
pform.cc
View File

@ -1512,26 +1512,13 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
delete init_expr;
}
static void ranges_from_list(list<PWire::range_t>&rlist,
const list<index_component_t>*range)
{
// Convert a list of index_component_t to PWire::range_t.
for (list<index_component_t>::const_iterator rcur = range->begin()
; rcur != range->end() ; ++rcur) {
PWire::range_t rng;
rng.msb = rcur->msb;
rng.lsb = rcur->lsb;
rlist.push_back(rng);
}
}
/*
* This function attaches a range to a given name. The function is
* only called by the parser within the scope of the net declaration,
* and the name that I receive only has the tail component.
*/
static void pform_set_net_range(perm_string name,
const list<index_component_t>*range,
const list<pform_range_t>*range,
bool signed_flag,
ivl_variable_type_t dt,
PWSRType rt)
@ -1548,9 +1535,7 @@ static void pform_set_net_range(perm_string name,
cur->set_range_scalar(rt);
} else {
list<PWire::range_t> rlist;
ranges_from_list(rlist, range);
cur->set_range(rlist, rt);
cur->set_range(*range, rt);
}
cur->set_signed(signed_flag);
@ -1558,10 +1543,10 @@ static void pform_set_net_range(perm_string name,
cur->set_data_type(dt);
}
static void pform_set_net_range(list<perm_string>*names,
list<index_component_t>*range,
bool signed_flag,
ivl_variable_type_t dt)
void pform_set_net_range(list<perm_string>*names,
list<pform_range_t>*range,
bool signed_flag,
ivl_variable_type_t dt)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur ) {
@ -1630,8 +1615,8 @@ static void pform_makegate(PGBuiltin::Type type,
perm_string dev_name = lex_strings.make(info.name);
PGBuiltin*cur = new PGBuiltin(type, dev_name, info.parms, delay);
if (info.range.msb)
cur->set_range(info.range.msb, info.range.lsb);
if (info.range.first)
cur->set_range(info.range.first, info.range.second);
// The pform_makegates() that calls me will take care of
// deleting the attr pointer, so tell the
@ -1770,7 +1755,7 @@ void pform_make_modgates(perm_string type,
if (cur.parms_by_name) {
pform_make_modgate(type, cur_name, overrides,
cur.parms_by_name,
cur.range.msb, cur.range.lsb,
cur.range.first, cur.range.second,
cur.file, cur.lineno);
} else if (cur.parms) {
@ -1784,14 +1769,14 @@ void pform_make_modgates(perm_string type,
}
pform_make_modgate(type, cur_name, overrides,
cur.parms,
cur.range.msb, cur.range.lsb,
cur.range.first, cur.range.second,
cur.file, cur.lineno);
} else {
list<PExpr*>*wires = new list<PExpr*>;
pform_make_modgate(type, cur_name, overrides,
wires,
cur.range.msb, cur.range.lsb,
cur.range.first, cur.range.second,
cur.file, cur.lineno);
}
}
@ -1904,7 +1889,7 @@ void pform_module_define_port(const struct vlltype&li,
NetNet::Type type,
ivl_variable_type_t data_type,
bool signed_flag,
list<index_component_t>*range,
list<pform_range_t>*range,
list<named_pexpr_t>*attr)
{
PWire*cur = pform_get_wire_in_scope(name);
@ -1930,9 +1915,7 @@ void pform_module_define_port(const struct vlltype&li,
cur->set_range_scalar((type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
} else {
list<PWire::range_t> rlist;
ranges_from_list(rlist, range);
cur->set_range(rlist, (type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
cur->set_range(*range, (type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH);
}
pform_bind_attributes(cur->attributes, attr);
@ -2038,7 +2021,7 @@ void pform_makewire(const vlltype&li, perm_string name,
* pform_makewire above.
*/
void pform_makewire(const vlltype&li,
list<index_component_t>*range,
list<pform_range_t>*range,
bool signed_flag,
list<perm_string>*names,
NetNet::Type type,
@ -2065,7 +2048,7 @@ void pform_makewire(const vlltype&li,
* This form makes nets with delays and continuous assignments.
*/
void pform_makewire(const vlltype&li,
list<index_component_t>*range,
list<pform_range_t>*range,
bool signed_flag,
list<PExpr*>*delay,
str_pair_t str,
@ -2143,7 +2126,7 @@ svector<PWire*>*pform_make_task_ports(const struct vlltype&loc,
NetNet::PortType pt,
ivl_variable_type_t vtype,
bool signed_flag,
list<index_component_t>*range,
list<pform_range_t>*range,
list<perm_string>*names,
bool isint)
{
@ -2171,9 +2154,7 @@ svector<PWire*>*pform_make_task_ports(const struct vlltype&loc,
/* If there is a range involved, it needs to be set. */
if (range) {
list<PWire::range_t> rlist;
ranges_from_list(rlist, range);
curw->set_range(rlist, SR_PORT);
curw->set_range(*range, SR_PORT);
}
svector<PWire*>*tmp = new svector<PWire*>(*res, curw);
@ -2193,7 +2174,7 @@ svector<PWire*>*pform_make_task_ports(const struct vlltype&loc,
list<perm_string>*names)
{
if (atom2_type_t*atype = dynamic_cast<atom2_type_t*> (vtype)) {
list<index_component_t>*range_tmp = make_range_from_width(atype->type_code);
list<pform_range_t>*range_tmp = make_range_from_width(atype->type_code);
return pform_make_task_ports(loc, pt, IVL_VT_BOOL,
atype->signed_flag,
range_tmp, names);
@ -2320,7 +2301,7 @@ LexicalScope::range_t* pform_parameter_value_range(bool exclude_flag,
void pform_set_parameter(const struct vlltype&loc,
perm_string name, ivl_variable_type_t type,
bool signed_flag, list<index_component_t>*range, PExpr*expr,
bool signed_flag, list<pform_range_t>*range, PExpr*expr,
LexicalScope::range_t*value_range)
{
LexicalScope*scope = lexical_scope;
@ -2356,11 +2337,11 @@ void pform_set_parameter(const struct vlltype&loc,
parm.type = type;
if (range) {
assert(range->size() == 1);
index_component_t index = range->front();
assert(index.msb);
assert(index.lsb);
parm.msb = index.msb;
parm.lsb = index.lsb;
pform_range_t&rng = range->front();
assert(rng.first);
assert(rng.second);
parm.msb = rng.first;
parm.lsb = rng.second;
} else {
parm.msb = 0;
parm.lsb = 0;
@ -2374,7 +2355,7 @@ void pform_set_parameter(const struct vlltype&loc,
void pform_set_localparam(const struct vlltype&loc,
perm_string name, ivl_variable_type_t type,
bool signed_flag, list<index_component_t>*range, PExpr*expr)
bool signed_flag, list<pform_range_t>*range, PExpr*expr)
{
LexicalScope*scope = lexical_scope;
@ -2405,11 +2386,11 @@ void pform_set_localparam(const struct vlltype&loc,
parm.type = type;
if (range) {
assert(range->size() == 1);
index_component_t index = range->front();
assert(index.msb);
assert(index.lsb);
parm.msb = index.msb;
parm.lsb = index.lsb;
pform_range_t&rng = range->front();
assert(rng.first);
assert(rng.second);
parm.msb = rng.first;
parm.lsb = rng.second;
} else {
parm.msb = 0;
parm.lsb = 0;
@ -2542,7 +2523,7 @@ static void pform_set_port_type(perm_string name, NetNet::PortType pt,
void pform_set_port_type(const struct vlltype&li,
list<perm_string>*names,
list<index_component_t>*range,
list<pform_range_t>*range,
bool signed_flag,
NetNet::PortType pt)
{
@ -2565,10 +2546,10 @@ static void pform_set_reg_integer(perm_string name)
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::INTEGER, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
assert(cur);
PWire::range_t rng;
rng.msb = new PENumber(new verinum(integer_width-1, integer_width));
rng.lsb = new PENumber(new verinum((uint64_t)0, integer_width));
list<PWire::range_t>rlist;
pform_range_t rng;
rng.first = new PENumber(new verinum(integer_width-1, integer_width));
rng.second = new PENumber(new verinum((uint64_t)0, integer_width));
list<pform_range_t>rlist;
rlist.push_back(rng);
cur->set_range(rlist, SR_NET);
cur->set_signed(true);
@ -2589,10 +2570,10 @@ static void pform_set_reg_time(perm_string name)
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
assert(cur);
PWire::range_t rng;
rng.msb = new PENumber(new verinum(TIME_WIDTH-1, integer_width));
rng.lsb = new PENumber(new verinum((uint64_t)0, integer_width));
list<PWire::range_t>rlist;
pform_range_t rng;
rng.first = new PENumber(new verinum(TIME_WIDTH-1, integer_width));
rng.second = new PENumber(new verinum((uint64_t)0, integer_width));
list<pform_range_t>rlist;
rlist.push_back(rng);
cur->set_range(rlist, SR_NET);
}
@ -2614,10 +2595,10 @@ static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_strin
cur->set_signed(signed_flag);
PWire::range_t rng;
rng.msb = new PENumber(new verinum(width-1, integer_width));
rng.lsb = new PENumber(new verinum((uint64_t)0, integer_width));
list<PWire::range_t>rlist;
pform_range_t rng;
rng.first = new PENumber(new verinum(width-1, integer_width));
rng.second = new PENumber(new verinum((uint64_t)0, integer_width));
list<pform_range_t>rlist;
rlist.push_back(rng);
cur->set_range(rlist, SR_NET);
}
@ -2684,9 +2665,7 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
assert(enum_type->range.get() != 0);
assert(enum_type->range->size() == 1);
list<PWire::range_t>rlist;
ranges_from_list(rlist, enum_type->range.get());
cur->set_range(rlist, SR_NET);
cur->set_range(*enum_type->range, SR_NET);
cur->set_enumeration(enum_type);
}

25
pform.h
View File

@ -110,14 +110,14 @@ struct lgate {
list<PExpr*>*parms;
list<named_pexpr_t>*parms_by_name;
index_component_t range;
pform_range_t range;
const char* file;
unsigned lineno;
};
extern std::list<index_component_t>* make_range_from_width(uint64_t wid);
extern std::list<index_component_t>* copy_range(std::list<index_component_t>* orig);
extern std::list<pform_range_t>* make_range_from_width(uint64_t wid);
extern std::list<pform_range_t>* copy_range(std::list<pform_range_t>* orig);
/* Use this function to transform the parted form of the attribute
list to the attribute map that is used later. */
@ -160,7 +160,7 @@ extern void pform_module_define_port(const struct vlltype&li,
NetNet::Type type,
ivl_variable_type_t data_type,
bool signed_flag,
list<index_component_t>*range,
list<pform_range_t>*range,
list<named_pexpr_t>*attr);
extern Module::port_t* pform_module_port_reference(perm_string name,
@ -245,7 +245,7 @@ extern void pform_makewire(const struct vlltype&li, perm_string name,
/* This form handles simple declarations */
extern void pform_makewire(const struct vlltype&li,
list<index_component_t>*range,
list<pform_range_t>*range,
bool signed_flag,
list<perm_string>*names,
NetNet::Type type,
@ -262,7 +262,7 @@ extern void pform_makewire(const struct vlltype&li,
/* This form handles assignment declarations. */
extern void pform_makewire(const struct vlltype&li,
list<index_component_t>*range,
list<pform_range_t>*range,
bool signed_flag,
list<PExpr*>*delay,
str_pair_t str,
@ -285,11 +285,14 @@ extern void pform_make_reginit(const struct vlltype&li,
it. The second form takes a single name. */
extern void pform_set_port_type(const struct vlltype&li,
list<perm_string>*names,
list<index_component_t>*range,
list<pform_range_t>*range,
bool signed_flag,
NetNet::PortType);
extern void pform_set_net_range(list<perm_string>*names,
list<pform_range_t>*,
bool signed_flag,
ivl_variable_type_t);
extern void pform_set_reg_idx(perm_string 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);
@ -319,13 +322,13 @@ extern void pform_set_parameter(const struct vlltype&loc,
perm_string name,
ivl_variable_type_t type,
bool signed_flag,
list<index_component_t>*range,
list<pform_range_t>*range,
PExpr*expr, LexicalScope::range_t*value_range);
extern void pform_set_localparam(const struct vlltype&loc,
perm_string name,
ivl_variable_type_t type,
bool signed_flag,
list<index_component_t>*range,
list<pform_range_t>*range,
PExpr*expr);
extern void pform_set_defparam(const pform_name_t&name, PExpr*expr);
@ -389,7 +392,7 @@ extern svector<PWire*>*pform_make_task_ports(const struct vlltype&loc,
NetNet::PortType pt,
ivl_variable_type_t vtype,
bool signed_flag,
list<index_component_t>*range,
list<pform_range_t>*range,
list<perm_string>*names,
bool isint = false);

View File

@ -358,9 +358,9 @@ void PWire::dump(ostream&out, unsigned ind) const
out << " port<scalar>";
} else {
out << " port";
for (list<PWire::range_t>::const_iterator cur = port_.begin()
for (list<pform_range_t>::const_iterator cur = port_.begin()
; cur != port_.end() ; ++cur)
out << "[" << *cur->msb << ":" << *cur->lsb << "]";
out << "[" << *cur->first << ":" << *cur->second << "]";
}
}
if (net_set_) {
@ -368,9 +368,9 @@ void PWire::dump(ostream&out, unsigned ind) const
out << " net<scalar>";
} else {
out << " net";
for (list<PWire::range_t>::const_iterator cur = net_.begin()
for (list<pform_range_t>::const_iterator cur = net_.begin()
; cur != net_.end() ; ++cur)
out << "[" << *cur->msb << ":" << *cur->lsb << "]";
out << "[" << *cur->first << ":" << *cur->second << "]";
}
}

View File

@ -37,6 +37,7 @@
class PExpr;
typedef named<verinum> named_number_t;
typedef named<PExpr*> named_pexpr_t;
typedef std::pair<PExpr*,PExpr*> pform_range_t;
struct index_component_t {
enum ctype_t { SEL_NONE, SEL_BIT, SEL_PART, SEL_IDX_UP, SEL_IDX_DO };
@ -59,7 +60,7 @@ struct name_component_t {
struct decl_assignment_t {
perm_string name;
std::list<index_component_t>index;
std::list<pform_range_t>index;
std::auto_ptr<PExpr> expr;
};
@ -84,14 +85,14 @@ struct data_type_t : public LineInfo {
struct enum_type_t : public data_type_t {
ivl_variable_type_t base_type;
bool signed_flag;
std::auto_ptr< list<index_component_t> > range;
std::auto_ptr< list<pform_range_t> > range;
std::auto_ptr< list<named_pexpr_t> > names;
LineInfo li;
};
struct struct_member_t : public LineInfo {
ivl_variable_type_t type;
std::auto_ptr< list<index_component_t> > range;
std::auto_ptr< list<pform_range_t> > range;
std::auto_ptr< list<decl_assignment_t*> > names;
};
@ -109,11 +110,11 @@ struct atom2_type_t : public data_type_t {
struct vector_type_t : public data_type_t {
inline explicit vector_type_t(ivl_variable_type_t bt, bool sf,
std::list<index_component_t>*pd)
std::list<pform_range_t>*pd)
: base_type(bt), signed_flag(sf), pdims(pd) { }
ivl_variable_type_t base_type;
bool signed_flag;
std::auto_ptr< list<index_component_t> > pdims;
std::auto_ptr< list<pform_range_t> > pdims;
};
struct real_type_t : public data_type_t {