diff --git a/PTask.h b/PTask.h index b06375dfc..4cd6a9a22 100644 --- a/PTask.h +++ b/PTask.h @@ -1,7 +1,7 @@ #ifndef __PTask_H #define __PTask_H /* - * Copyright (c) 1999-2008,2010 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2008,2010,2012 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -46,7 +46,7 @@ enum PTaskFuncEnum { struct PTaskFuncArg { PTaskFuncEnum type; - vector*range; + std::list*range; }; /* diff --git a/elab_scope.cc b/elab_scope.cc index a93c9a08c..efce812c6 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -133,9 +133,10 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope, enum_type_t*enum_type) { bool rc_flag; - assert(enum_type->range->size() == 2); - NetExpr*msb_ex = elab_and_eval(des, scope, enum_type->range->front(), -1); - NetExpr*lsb_ex = elab_and_eval(des, scope, enum_type->range->back(), -1); + 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); long msb = 0; rc_flag = eval_as_long(msb, msb_ex); diff --git a/elab_sig.cc b/elab_sig.cc index 42ed8c355..1a00cb786 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -476,15 +476,12 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const case PTF_REG: case PTF_REG_S: if (return_type_.range) { - ivl_assert(*this, return_type_.range->size() == 2); + ivl_assert(*this, return_type_.range->size() == 1); + index_component_t index = return_type_.range->front(); - NetExpr*me = elab_and_eval(des, scope, - return_type_.range->at(0), -1, - true); + NetExpr*me = elab_and_eval(des, scope, index.msb, -1, true); assert(me); - NetExpr*le = elab_and_eval(des, scope, - return_type_.range->at(1), -1, - true); + NetExpr*le = elab_and_eval(des, scope, index.lsb, -1, true); assert(le); long mnum = 0, lnum = 0; @@ -550,17 +547,14 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const case PTF_ATOM2: case PTF_ATOM2_S: - ivl_assert(*this, return_type_.range != 0); long use_wid; { - NetExpr*me = elab_and_eval(des, scope, - (*return_type_.range)[0], -1, - true); - assert(me); - NetExpr*le = elab_and_eval(des, scope, - (*return_type_.range)[1], -1, - true); - assert(le); + 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); + ivl_assert(*this, me); + NetExpr*le = elab_and_eval(des, scope, index.lsb, -1, true); + ivl_assert(*this, le); long mnum = 0, lnum = 0; if ( ! get_const_argument(me, mnum) ) { @@ -805,9 +799,10 @@ static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope, long use_msb = 0; long use_lsb = 0; if (curp->range.get() && ! curp->range->empty()) { - ivl_assert(*curp, curp->range->size() == 2); - PExpr*msb_pex = curp->range->front(); - PExpr*lsb_pex = curp->range->back(); + ivl_assert(*curp, curp->range->size() == 1); + index_component_t index = curp->range->front(); + PExpr*msb_pex = index.msb; + PExpr*lsb_pex = index.lsb; NetExpr*tmp = elab_and_eval(des, scope, msb_pex, -2, true); ivl_assert(*curp, tmp); diff --git a/parse.y b/parse.y index 02a458b28..411875217 100644 --- a/parse.y +++ b/parse.y @@ -38,7 +38,7 @@ extern void lex_end_table(); bool have_timeunit_decl = false; bool have_timeprec_decl = false; -static list* param_active_range = 0; +static list* param_active_range = 0; static bool param_active_signed = false; static ivl_variable_type_t param_active_type = IVL_VT_LOGIC; @@ -48,7 +48,7 @@ static struct { NetNet::PortType port_type; ivl_variable_type_t var_type; bool sign_flag; - list* range; + list* range; data_type_t* data_type; } port_declaration_context = {NetNet::NONE, NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, false, 0, 0}; @@ -98,8 +98,7 @@ static list >* make_port_list(char*id, PExpr*expr) delete[]id; return tmp; } -static list >* make_port_list(list >*tmp, +static list >* make_port_list(list >*tmp, char*id, PExpr*expr) { tmp->push_back(make_pair(lex_strings.make(id), expr)); @@ -107,16 +106,19 @@ static list >* make_port_list(list* make_range_from_width(uint64_t wid) +list* make_range_from_width(uint64_t wid) { - list*range = new list; + list*range = new list; - range->push_back(new PENumber(new verinum(wid-1, integer_width))); - range->push_back(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); return range; } +#if 0 /* * Make a range vector from an existing pair of expressions. */ @@ -129,7 +131,8 @@ static vector* make_range_vector(list*that) delete that; return tmp; } - +#endif +#if 0 /* * Make a range vector from a width. Generate the msb and lsb * expressions to get the canonical range for the given width. @@ -141,7 +144,7 @@ static vector* make_range_vector(uint64_t wid) tmp->at(1) = new PENumber(new verinum((uint64_t)0, integer_width)); return tmp; } - +#endif static list* list_from_identifier(char*id) { list*tmp = new list; @@ -157,12 +160,12 @@ static list* list_from_identifier(list*tmp, char*id) return tmp; } -list* copy_range(list* orig) +list* copy_range(list* orig) { - list*copy = 0; + list*copy = 0; if (orig) - copy = new list (*orig); + copy = new list (*orig); return copy; } @@ -512,8 +515,8 @@ static void current_task_set_statement(vector*s) %type struct_union_member_list %type struct_data_type -%type range range_opt variable_dimension -%type dimensions_opt dimensions +%type range range_opt +%type dimensions_opt dimensions variable_dimension %type net_type var_type net_type_opt %type gatetype switchtype %type port_direction port_direction_opt @@ -1015,13 +1018,6 @@ variable_decl_assignment /* IEEE1800-2005 A.2.3 */ delete[]$1; $$ = tmp; } - | IDENTIFIER '[' ']' - { decl_assignment_t*tmp = new decl_assignment_t; - tmp->name = lex_strings.make($1); - yyerror("sorry: Dynamic arrays not yet supported here."); - delete[]$1; - $$ = tmp; - } | IDENTIFIER '[' '$' ']' { decl_assignment_t*tmp = new decl_assignment_t; tmp->name = lex_strings.make($1); @@ -1272,7 +1268,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*range_stub = make_range_from_width(integer_width); + { list*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; @@ -1297,7 +1293,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*range_stub = make_range_from_width(64); + { list*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; @@ -1414,18 +1410,39 @@ tf_port_list /* IEEE1800-2005: A.2.7 */ variable_dimension /* IEEE1800-2005: A.2.5 */ : '[' expression ':' expression ']' - { list*tmp = new list; - tmp->push_back($2); - tmp->push_back($4); + { list *tmp = new list; + index_component_t index; + index.sel = index_component_t::SEL_PART; + index.msb = $2; + index.lsb = $4; + tmp->push_back(index); + $$ = tmp; + } + | '[' expression ']' + { // SystemVerilog canonical range + if (generation_flag < GN_VER2005_SV) { + warn_count += 1; + cerr << @2 << ": warning: Use of SystemVerilog [size] dimension. " + << "Use at least -g2005-sv to remove this warning." << endl; + } + list *tmp = new list; + 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))); + tmp->push_back(index); $$ = tmp; } | '[' ']' - { list*tmp = new list; - tmp->push_back(0); - tmp->push_back(0); + { list *tmp = new list; + index_component_t index; + index.msb = 0; + index.lsb = 0; + yyerror("sorry: Dynamic array ranges not supported."); + tmp->push_back(index); $$ = tmp; } -; + ; /* Verilog-2001 supports attribute lists, which can be attached to a variety of different objects. The syntax inside the (* *) is a @@ -2822,20 +2839,21 @@ gate_instance $$ = tmp; } - | IDENTIFIER range '(' expression_list_with_nuls ')' - { lgate*tmp = new lgate; - list*rng = $2; - tmp->name = $1; - tmp->parms = $4; - tmp->range[0] = rng->front(); rng->pop_front(); - tmp->range[1] = rng->front(); rng->pop_front(); - assert(rng->empty()); - tmp->file = @1.text; - tmp->lineno = @1.first_line; - delete[]$1; - delete rng; - $$ = tmp; - } + | IDENTIFIER range '(' expression_list_with_nuls ')' + { lgate*tmp = new lgate; + list*rng = $2; + tmp->name = $1; + tmp->parms = $4; + tmp->range = rng->front(); + rng->pop_front(); + assert(rng->empty()); + tmp->file = @1.text; + tmp->lineno = @1.first_line; + delete[]$1; + delete rng; + $$ = tmp; + } + | '(' expression_list_with_nuls ')' { lgate*tmp = new lgate; tmp->name = ""; @@ -2847,50 +2865,50 @@ gate_instance /* Degenerate modules can have no ports. */ - | IDENTIFIER range - { lgate*tmp = new lgate; - list*rng = $2; - tmp->name = $1; - tmp->parms = 0; - tmp->parms_by_name = 0; - tmp->range[0] = rng->front(); rng->pop_front(); - tmp->range[1] = rng->front(); rng->pop_front(); - assert(rng->empty()); - tmp->file = @1.text; - tmp->lineno = @1.first_line; - delete[]$1; - delete rng; - $$ = tmp; - } + | IDENTIFIER range + { lgate*tmp = new lgate; + list*rng = $2; + tmp->name = $1; + tmp->parms = 0; + tmp->parms_by_name = 0; + tmp->range = rng->front(); + rng->pop_front(); + assert(rng->empty()); + tmp->file = @1.text; + tmp->lineno = @1.first_line; + delete[]$1; + delete rng; + $$ = tmp; + } /* Modules can also take ports by port-name expressions. */ - | IDENTIFIER '(' port_name_list ')' - { lgate*tmp = new lgate; - tmp->name = $1; - tmp->parms = 0; - tmp->parms_by_name = $3; - tmp->file = @1.text; - tmp->lineno = @1.first_line; - delete[]$1; - $$ = tmp; - } + | IDENTIFIER '(' port_name_list ')' + { lgate*tmp = new lgate; + tmp->name = $1; + tmp->parms = 0; + tmp->parms_by_name = $3; + tmp->file = @1.text; + tmp->lineno = @1.first_line; + delete[]$1; + $$ = tmp; + } - | IDENTIFIER range '(' port_name_list ')' - { lgate*tmp = new lgate; - list*rng = $2; - tmp->name = $1; - tmp->parms = 0; - tmp->parms_by_name = $4; - tmp->range[0] = rng->front(); rng->pop_front(); - tmp->range[1] = rng->front(); rng->pop_front(); - assert(rng->empty()); - tmp->file = @1.text; - tmp->lineno = @1.first_line; - delete[]$1; - delete rng; - $$ = tmp; - } + | IDENTIFIER range '(' port_name_list ')' + { lgate*tmp = new lgate; + list*rng = $2; + tmp->name = $1; + tmp->parms = 0; + tmp->parms_by_name = $4; + tmp->range = rng->front(); + rng->pop_front(); + assert(rng->empty()); + tmp->file = @1.text; + tmp->lineno = @1.first_line; + delete[]$1; + delete rng; + $$ = tmp; + } | IDENTIFIER '(' error ')' { lgate*tmp = new lgate; @@ -3143,7 +3161,7 @@ port_declaration K_input atom2_type signed_unsigned_opt IDENTIFIER { Module::port_t*ptmp; perm_string name = lex_strings.make($5); - list*use_range = make_range_from_width($3); + list*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, @@ -3289,7 +3307,7 @@ port_declaration K_output atom2_type signed_unsigned_opt IDENTIFIER { Module::port_t*ptmp; perm_string name = lex_strings.make($5); - list*use_range = make_range_from_width($3); + list*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, @@ -3308,7 +3326,7 @@ port_declaration K_output atom2_type signed_unsigned_opt IDENTIFIER '=' expression { Module::port_t*ptmp; perm_string name = lex_strings.make($5); - list*use_range = make_range_from_width($3); + list*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, @@ -4606,9 +4624,13 @@ port_reference_list /* The range is a list of variable dimensions. */ range : variable_dimension + { $$ = $1; } | range variable_dimension - { list*tmp = $1; - if ($2) tmp->splice(tmp->end(), *$2); + { list*tmp = $1; + if ($2) { + tmp->splice(tmp->end(), *$2); + delete $2; + } $$ = tmp; } ; @@ -4623,88 +4645,54 @@ dimensions_opt | dimensions { $$ = $1; } dimensions - : '[' expression ':' expression ']' - { list *tmp = new list; - index_component_t index; - index.msb = $2; - index.lsb = $4; - tmp->push_back(index); - $$ = tmp; - } - | '[' expression ']' - { if (generation_flag < GN_VER2005_SV) { - warn_count += 1; - cerr << @2 << ": warning: Use of SystemVerilog [size] dimension. " - << "Use at least -g2005-sv to remove this warning." << endl; - } - list *tmp = new list; - index_component_t index; - index.msb = new PENumber(new verinum((uint64_t)0, integer_width)); - index.lsb = new PEBinary('-', $2, new PENumber(new verinum((uint64_t)1, integer_width))); - tmp->push_back(index); - $$ = tmp; - } - | dimensions '[' expression ':' expression ']' - { list *tmp = $1; - index_component_t index; - index.msb = $3; - index.lsb = $5; - tmp->push_back(index); - $$ = tmp; - } - | dimensions '[' expression ']' - { if (generation_flag < GN_VER2005_SV) { - warn_count += 1; - cerr << @2 << ": warning: Use of SystemVerilog [size] dimension. " - << "Use at least -g2005-sv to remove this warning." << endl; - } - list *tmp = $1; - index_component_t index; - index.msb = new PENumber(new verinum((uint64_t)0, integer_width)); - index.lsb = new PEBinary('-', $3, new PENumber(new verinum((uint64_t)1, integer_width))); - tmp->push_back(index); - $$ = tmp; - } + : variable_dimension + { $$ = $1; } + | dimensions variable_dimension + { list *tmp = $1; + if ($2) { + tmp->splice(tmp->end(), *$2); + delete $2; + } + $$ = tmp; + } + ; /* This is used to express the return type of a function. */ function_range_or_type_opt : unsigned_signed_opt range_opt - { - /* the default type is reg unsigned and no range */ - $$.type = PTF_REG; - $$.range = 0; - if ($1) - $$.type = PTF_REG_S; - if ($2) - $$.range = make_range_vector($2); - } + { /* the default type is reg unsigned and no range */ + $$.type = PTF_REG; + $$.range = 0; + 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; - if ($2) - $$.type = PTF_REG_S; - if ($3) - $$.range = make_range_vector($3); - } + { /* the default type is reg unsigned and no range */ + $$.type = PTF_REG; + $$.range = 0; + 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; - if ($2) - $$.type = PTF_REG_S; - if ($3) - $$.range = make_range_vector($3); - } + { /* the default type is bit/logic unsigned and no range */ + $$.type = PTF_REG; + $$.range = 0; + if ($2) + $$.type = PTF_REG_S; + if ($3) + $$.range = $3; + } | K_integer { $$.range = 0; $$.type = PTF_INTEGER; } | K_real { $$.range = 0; $$.type = PTF_REAL; } | K_realtime { $$.range = 0; $$.type = PTF_REALTIME; } | K_time { $$.range = 0; $$.type = PTF_TIME; } - | atom2_type { $$.range = make_range_vector($1); $$.type = PTF_ATOM2_S; } - | atom2_type K_signed { $$.range = make_range_vector($1); $$.type = PTF_ATOM2_S; } - | atom2_type K_unsigned { $$.range = make_range_vector($1); $$.type = PTF_ATOM2; } + | atom2_type { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2_S; } + | atom2_type K_signed { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2_S; } + | atom2_type K_unsigned { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2; } ; /* The register_variable rule is matched only when I am parsing @@ -5577,7 +5565,7 @@ task_port_item shape. Generate a range ([31:0]) to make it work. */ | port_direction K_integer list_of_identifiers ';' - { list*range_stub = make_range_from_width(integer_width); + { list*range_stub = make_range_from_width(integer_width); svector*tmp = pform_make_task_ports(@1, $1, IVL_VT_LOGIC, true, range_stub, $3, true); $$ = tmp; @@ -5586,7 +5574,7 @@ task_port_item /* Ports can be time with a width of [63:0] (unsigned). */ | port_direction K_time list_of_identifiers ';' - { list*range_stub = make_range_from_width(64); + { list*range_stub = make_range_from_width(64); svector*tmp = pform_make_task_ports(@1, $1, IVL_VT_LOGIC, false, range_stub, $3); $$ = tmp; diff --git a/pform.cc b/pform.cc index 2a8653c60..d500bf7ff 100644 --- a/pform.cc +++ b/pform.cc @@ -1480,16 +1480,15 @@ void pform_make_udp(perm_string name, bool synchronous_flag, delete init_expr; } -static void ranges_from_list(list&rlist, const list*range) +static void ranges_from_list(list&rlist, + const list*range) { - // There must be an even number of expressions in the - // range. The parser will assure that for us. - assert(range->size()%2 == 0); - list::const_iterator rcur = range->begin(); - while (rcur != range->end()) { + // Convert a list of index_component_t to PWire::range_t. + for (list::const_iterator rcur = range->begin() + ; rcur != range->end() ; ++rcur) { PWire::range_t rng; - rng.msb = *rcur; ++rcur; - rng.lsb = *rcur; ++rcur; + rng.msb = rcur->msb; + rng.lsb = rcur->lsb; rlist.push_back(rng); } } @@ -1500,7 +1499,7 @@ static void ranges_from_list(list&rlist, const list*rang * and the name that I receive only has the tail component. */ static void pform_set_net_range(perm_string name, - const list*range, + const list*range, bool signed_flag, ivl_variable_type_t dt, PWSRType rt) @@ -1528,12 +1527,10 @@ static void pform_set_net_range(perm_string name, } static void pform_set_net_range(list*names, - list*range, + list*range, bool signed_flag, ivl_variable_type_t dt) { - assert((range == 0) || (range->size()%2 == 0)); - for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur ) { perm_string txt = *cur; @@ -1601,8 +1598,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[0]) - cur->set_range(info.range[0], info.range[1]); + if (info.range.msb) + cur->set_range(info.range.msb, info.range.lsb); // The pform_makegates() that calls me will take care of // deleting the attr pointer, so tell the @@ -1741,7 +1738,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[0], cur.range[1], + cur.range.msb, cur.range.lsb, cur.file, cur.lineno); } else if (cur.parms) { @@ -1755,14 +1752,14 @@ void pform_make_modgates(perm_string type, } pform_make_modgate(type, cur_name, overrides, cur.parms, - cur.range[0], cur.range[1], + cur.range.msb, cur.range.lsb, cur.file, cur.lineno); } else { list*wires = new list; pform_make_modgate(type, cur_name, overrides, wires, - cur.range[0], cur.range[1], + cur.range.msb, cur.range.lsb, cur.file, cur.lineno); } } @@ -1875,7 +1872,7 @@ void pform_module_define_port(const struct vlltype&li, NetNet::Type type, ivl_variable_type_t data_type, bool signed_flag, - list*range, + list*range, list*attr) { PWire*cur = pform_get_wire_in_scope(name); @@ -2011,7 +2008,7 @@ void pform_makewire(const vlltype&li, perm_string name, * pform_makewire above. */ void pform_makewire(const vlltype&li, - list*range, + list*range, bool signed_flag, list*names, NetNet::Type type, @@ -2038,7 +2035,7 @@ void pform_makewire(const vlltype&li, * This form makes nets with delays and continuous assignments. */ void pform_makewire(const vlltype&li, - list*range, + list*range, bool signed_flag, list*delay, str_pair_t str, @@ -2149,7 +2146,7 @@ svector*pform_make_task_ports(const struct vlltype&loc, NetNet::PortType pt, ivl_variable_type_t vtype, bool signed_flag, - list*range, + list*range, list*names, bool isint) { @@ -2198,7 +2195,7 @@ svector*pform_make_task_ports(const struct vlltype&loc, list*names) { if (atom2_type_t*atype = dynamic_cast (vtype)) { - list*range_tmp = make_range_from_width(atype->type_code); + list*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); @@ -2211,7 +2208,7 @@ svector*pform_make_task_ports(const struct vlltype&loc, names); } - if (real_type_t*real_type = dynamic_cast (vtype)) { + if (/*real_type_t*real_type = */ dynamic_cast (vtype)) { return pform_make_task_ports(loc, pt, IVL_VT_REAL, true, 0, names); } @@ -2325,7 +2322,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*range, PExpr*expr, + bool signed_flag, list*range, PExpr*expr, LexicalScope::range_t*value_range) { LexicalScope*scope = lexical_scope; @@ -2360,11 +2357,12 @@ void pform_set_parameter(const struct vlltype&loc, parm.type = type; if (range) { - assert(range->size() == 2); - assert(range->front()); - assert(range->back()); - parm.msb = range->front(); - parm.lsb = range->back(); + assert(range->size() == 1); + index_component_t index = range->front(); + assert(index.msb); + assert(index.lsb); + parm.msb = index.msb; + parm.lsb = index.lsb; } else { parm.msb = 0; parm.lsb = 0; @@ -2378,7 +2376,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*range, PExpr*expr) + bool signed_flag, list*range, PExpr*expr) { LexicalScope*scope = lexical_scope; @@ -2408,11 +2406,12 @@ void pform_set_localparam(const struct vlltype&loc, parm.type = type; if (range) { - assert(range->size() == 2); - assert(range->front()); - assert(range->back()); - parm.msb = range->front(); - parm.lsb = range->back(); + assert(range->size() == 1); + index_component_t index = range->front(); + assert(index.msb); + assert(index.lsb); + parm.msb = index.msb; + parm.lsb = index.lsb; } else { parm.msb = 0; parm.lsb = 0; @@ -2511,7 +2510,7 @@ extern void pform_module_specify_path(PSpecPath*obj) void pform_set_port_type(const struct vlltype&li, list*names, - list*range, + list*range, bool signed_flag, NetNet::PortType pt) { @@ -2627,7 +2626,7 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list (data_type)) { + if (/*real_type_t*real_type =*/ dynamic_cast (data_type)) { pform_set_net_range(names, 0, true, IVL_VT_REAL); return; } @@ -2645,7 +2644,7 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, cur->set_signed(enum_type->signed_flag); assert(enum_type->range.get() != 0); - assert(enum_type->range->size() == 2); + assert(enum_type->range->size() == 1); listrlist; ranges_from_list(rlist, enum_type->range.get()); cur->set_range(rlist, SR_NET); @@ -2659,7 +2658,7 @@ void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, listbase_type==IVL_VT_LOGIC || enum_type->base_type==IVL_VT_BOOL); assert(enum_type->range.get() != 0); - assert(enum_type->range->size() == 2); + assert(enum_type->range->size() == 1); // Add the file and line information to the enumeration type. FILE_NAME(&(enum_type->li), li); diff --git a/pform.h b/pform.h index 0e2613715..85039e7df 100644 --- a/pform.h +++ b/pform.h @@ -101,24 +101,22 @@ struct net_decl_assign_t { /* The lgate is gate instantiation information. */ struct lgate { - lgate(int =0) + inline lgate(int =0) : parms(0), parms_by_name(0), file(NULL), lineno(0) - { range[0] = 0; - range[1] = 0; - } + { } string name; list*parms; list*parms_by_name; - PExpr*range[2]; + index_component_t range; const char* file; unsigned lineno; }; -extern std::list* make_range_from_width(uint64_t wid); -extern list* copy_range(list* orig); +extern std::list* make_range_from_width(uint64_t wid); +extern std::list* copy_range(std::list* orig); /* Use this function to transform the parted form of the attribute list to the attribute map that is used later. */ @@ -161,7 +159,7 @@ extern void pform_module_define_port(const struct vlltype&li, NetNet::Type type, ivl_variable_type_t data_type, bool signed_flag, - list*range, + list*range, list*attr); extern Module::port_t* pform_module_port_reference(perm_string name, @@ -241,7 +239,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*range, + list*range, bool signed_flag, list*names, NetNet::Type type, @@ -258,7 +256,7 @@ extern void pform_makewire(const struct vlltype&li, /* This form handles assignment declarations. */ extern void pform_makewire(const struct vlltype&li, - list*range, + list*range, bool signed_flag, list*delay, str_pair_t str, @@ -281,7 +279,7 @@ 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*names, - list*range, + list*range, bool signed_flag, NetNet::PortType); extern void pform_set_port_type(perm_string nm, NetNet::PortType pt, @@ -316,13 +314,13 @@ extern void pform_set_parameter(const struct vlltype&loc, perm_string name, ivl_variable_type_t type, bool signed_flag, - list*range, + list*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*range, + list*range, PExpr*expr); extern void pform_set_defparam(const pform_name_t&name, PExpr*expr); @@ -386,7 +384,7 @@ extern svector*pform_make_task_ports(const struct vlltype&loc, NetNet::PortType pt, ivl_variable_type_t vtype, bool signed_flag, - list*range, + list*range, list*names, bool isint = false); diff --git a/pform_types.h b/pform_types.h index 8ec228eaa..ab700cadc 100644 --- a/pform_types.h +++ b/pform_types.h @@ -1,7 +1,7 @@ #ifndef __pform_types_H #define __pform_types_H /* - * Copyright (c) 2007-2011 Stephen Williams (steve@icarus.com) + * Copyright (c) 2007-2012 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -84,14 +84,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 > range; + std::auto_ptr< list > range; std::auto_ptr< list > names; LineInfo li; }; struct struct_member_t : public LineInfo { ivl_variable_type_t type; - std::auto_ptr< list > range; + std::auto_ptr< list > range; std::auto_ptr< list > names; }; @@ -108,11 +108,12 @@ 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, list*pd) + inline explicit vector_type_t(ivl_variable_type_t bt, bool sf, + std::list*pd) : base_type(bt), signed_flag(sf), pdims(pd) { } ivl_variable_type_t base_type; bool signed_flag; - std::auto_ptr< list > pdims; + std::auto_ptr< list > pdims; }; struct real_type_t : public data_type_t {