Fix for br974 - support SV types in non-ansi port declarations.
This commit is contained in:
parent
9f88b26a67
commit
6ba2bee977
165
parse.y
165
parse.y
|
|
@ -135,17 +135,17 @@ static list<named_pexpr_t>*attributes_in_context = 0;
|
||||||
static const struct str_pair_t pull_strength = { IVL_DR_PULL, IVL_DR_PULL };
|
static const struct str_pair_t pull_strength = { IVL_DR_PULL, IVL_DR_PULL };
|
||||||
static const struct str_pair_t str_strength = { IVL_DR_STRONG, IVL_DR_STRONG };
|
static const struct str_pair_t str_strength = { IVL_DR_STRONG, IVL_DR_STRONG };
|
||||||
|
|
||||||
static list<pair<perm_string,PExpr*> >* make_port_list(char*id, PExpr*expr)
|
static list<pform_port_t>* make_port_list(char*id, list<pform_range_t>*udims, PExpr*expr)
|
||||||
{
|
{
|
||||||
list<pair<perm_string,PExpr*> >*tmp = new list<pair<perm_string,PExpr*> >;
|
list<pform_port_t>*tmp = new list<pform_port_t>;
|
||||||
tmp->push_back(make_pair(lex_strings.make(id), expr));
|
tmp->push_back(pform_port_t(lex_strings.make(id), udims, expr));
|
||||||
delete[]id;
|
delete[]id;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
static list<pair<perm_string,PExpr*> >* make_port_list(list<pair<perm_string, PExpr*> >*tmp,
|
static list<pform_port_t>* make_port_list(list<pform_port_t>*tmp,
|
||||||
char*id, PExpr*expr)
|
char*id, list<pform_range_t>*udims, PExpr*expr)
|
||||||
{
|
{
|
||||||
tmp->push_back(make_pair(lex_strings.make(id), expr));
|
tmp->push_back(pform_port_t(lex_strings.make(id), udims, expr));
|
||||||
delete[]id;
|
delete[]id;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -374,7 +374,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
char*text;
|
char*text;
|
||||||
list<perm_string>*perm_strings;
|
list<perm_string>*perm_strings;
|
||||||
|
|
||||||
list<pair<perm_string,PExpr*> >*port_list;
|
list<pform_port_t>*port_list;
|
||||||
|
|
||||||
vector<pform_tf_port_t>* tf_ports;
|
vector<pform_tf_port_t>* tf_ports;
|
||||||
|
|
||||||
|
|
@ -582,7 +582,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
%type <text> register_variable net_variable event_variable endlabel_opt class_declaration_endlabel_opt
|
%type <text> register_variable net_variable event_variable endlabel_opt class_declaration_endlabel_opt
|
||||||
%type <perm_strings> register_variable_list net_variable_list event_variable_list
|
%type <perm_strings> register_variable_list net_variable_list event_variable_list
|
||||||
%type <perm_strings> list_of_identifiers loop_variables
|
%type <perm_strings> list_of_identifiers loop_variables
|
||||||
%type <port_list> list_of_port_identifiers
|
%type <port_list> list_of_port_identifiers list_of_variable_port_identifiers
|
||||||
|
|
||||||
%type <net_decl_assign> net_decl_assign net_decl_assigns
|
%type <net_decl_assign> net_decl_assign net_decl_assigns
|
||||||
|
|
||||||
|
|
@ -642,7 +642,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
%type <ranges> variable_dimension
|
%type <ranges> variable_dimension
|
||||||
%type <ranges> dimensions_opt dimensions
|
%type <ranges> dimensions_opt dimensions
|
||||||
|
|
||||||
%type <nettype> net_type var_type net_type_opt
|
%type <nettype> net_type net_type_opt
|
||||||
%type <gatetype> gatetype switchtype
|
%type <gatetype> gatetype switchtype
|
||||||
%type <porttype> port_direction port_direction_opt
|
%type <porttype> port_direction port_direction_opt
|
||||||
%type <vartype> bit_logic bit_logic_opt
|
%type <vartype> bit_logic bit_logic_opt
|
||||||
|
|
@ -4057,14 +4057,21 @@ list_of_identifiers
|
||||||
;
|
;
|
||||||
|
|
||||||
list_of_port_identifiers
|
list_of_port_identifiers
|
||||||
: IDENTIFIER
|
: IDENTIFIER dimensions_opt
|
||||||
{ $$ = make_port_list($1, 0); }
|
{ $$ = make_port_list($1, $2, 0); }
|
||||||
| IDENTIFIER '=' expression
|
| list_of_port_identifiers ',' IDENTIFIER dimensions_opt
|
||||||
{ $$ = make_port_list($1, $3); }
|
{ $$ = make_port_list($1, $3, $4, 0); }
|
||||||
| list_of_port_identifiers ',' IDENTIFIER
|
;
|
||||||
{ $$ = make_port_list($1, $3, 0); }
|
|
||||||
| list_of_port_identifiers ',' IDENTIFIER '=' expression
|
list_of_variable_port_identifiers
|
||||||
{ $$ = make_port_list($1, $3, $5); }
|
: IDENTIFIER dimensions_opt
|
||||||
|
{ $$ = make_port_list($1, $2, 0); }
|
||||||
|
| IDENTIFIER dimensions_opt '=' expression
|
||||||
|
{ $$ = make_port_list($1, $2, $4); }
|
||||||
|
| list_of_variable_port_identifiers ',' IDENTIFIER dimensions_opt
|
||||||
|
{ $$ = make_port_list($1, $3, $4, 0); }
|
||||||
|
| list_of_variable_port_identifiers ',' IDENTIFIER dimensions_opt '=' expression
|
||||||
|
{ $$ = make_port_list($1, $3, $4, $6); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -4652,58 +4659,102 @@ module_item
|
||||||
delete $4;
|
delete $4;
|
||||||
}
|
}
|
||||||
|
|
||||||
| attribute_list_opt port_direction unsigned_signed_opt dimensions_opt delay3_opt list_of_identifiers ';'
|
|
||||||
{ pform_set_port_type(@2, $6, $4, $3, $2, $1); }
|
|
||||||
|
|
||||||
/* The next two rules handle Verilog 2001 statements of the form:
|
/* The next two rules handle port declarations that include a net type, e.g.
|
||||||
input wire signed [h:l] <list>;
|
input wire signed [h:l] <list>;
|
||||||
This creates the wire and sets the port type all at once. */
|
This creates the wire and sets the port type all at once. */
|
||||||
|
|
||||||
| attribute_list_opt port_direction net_type unsigned_signed_opt dimensions_opt list_of_identifiers ';'
|
| attribute_list_opt port_direction net_type data_type_or_implicit list_of_port_identifiers ';'
|
||||||
{ pform_makewire(@2, $5, $4, $6, $3, $2, IVL_VT_NO_TYPE, $1, SR_BOTH); }
|
{ pform_module_define_port(@2, $5, $2, $3, $4, $1); }
|
||||||
|
|
||||||
| attribute_list_opt K_output var_type unsigned_signed_opt dimensions_opt list_of_port_identifiers ';'
|
| attribute_list_opt port_direction K_wreal list_of_port_identifiers ';'
|
||||||
{ list<pair<perm_string,PExpr*> >::const_iterator pp;
|
{ real_type_t*real_type = new real_type_t(real_type_t::REAL);
|
||||||
list<perm_string>*tmp = new list<perm_string>;
|
pform_module_define_port(@2, $4, $2, NetNet::WIRE, real_type, $1);
|
||||||
for (pp = $6->begin(); pp != $6->end(); ++ pp ) {
|
}
|
||||||
tmp->push_back((*pp).first);
|
|
||||||
|
/* The next three rules handle port declarations that include a variable
|
||||||
|
type, e.g.
|
||||||
|
output reg signed [h:l] <list>;
|
||||||
|
and also handle incomplete port declarations, e.g.
|
||||||
|
input signed [h:l] <list>;
|
||||||
|
*/
|
||||||
|
| attribute_list_opt K_inout data_type_or_implicit list_of_port_identifiers ';'
|
||||||
|
{ NetNet::Type use_type = $3 ? NetNet::IMPLICIT : NetNet::NONE;
|
||||||
|
if (vector_type_t*dtype = dynamic_cast<vector_type_t*> ($3)) {
|
||||||
|
if (dtype->implicit_flag)
|
||||||
|
use_type = NetNet::NONE;
|
||||||
}
|
}
|
||||||
pform_makewire(@2, $5, $4, tmp, $3, NetNet::POUTPUT,
|
if (use_type == NetNet::NONE)
|
||||||
IVL_VT_NO_TYPE, $1, SR_BOTH);
|
pform_set_port_type(@2, $4, NetNet::PINOUT, $3, $1);
|
||||||
for (pp = $6->begin(); pp != $6->end(); ++ pp ) {
|
else
|
||||||
if ((*pp).second) {
|
pform_module_define_port(@2, $4, NetNet::PINOUT, use_type, $3, $1);
|
||||||
pform_make_var_init(@2, (*pp).first, (*pp).second);
|
}
|
||||||
}
|
|
||||||
|
| attribute_list_opt K_input data_type_or_implicit list_of_port_identifiers ';'
|
||||||
|
{ NetNet::Type use_type = $3 ? NetNet::IMPLICIT : NetNet::NONE;
|
||||||
|
if (vector_type_t*dtype = dynamic_cast<vector_type_t*> ($3)) {
|
||||||
|
if (dtype->implicit_flag)
|
||||||
|
use_type = NetNet::NONE;
|
||||||
}
|
}
|
||||||
delete $6;
|
if (use_type == NetNet::NONE)
|
||||||
|
pform_set_port_type(@2, $4, NetNet::PINPUT, $3, $1);
|
||||||
|
else
|
||||||
|
pform_module_define_port(@2, $4, NetNet::PINPUT, use_type, $3, $1);
|
||||||
}
|
}
|
||||||
|
|
||||||
| attribute_list_opt port_direction K_wreal list_of_identifiers ';'
|
| attribute_list_opt K_output data_type_or_implicit list_of_variable_port_identifiers ';'
|
||||||
{ pform_makewire(@2, 0, true, $4, NetNet::WIRE, $2,
|
{ NetNet::Type use_type = $3 ? NetNet::IMPLICIT : NetNet::NONE;
|
||||||
IVL_VT_REAL, $1, SR_BOTH);
|
if (vector_type_t*dtype = dynamic_cast<vector_type_t*> ($3)) {
|
||||||
|
if (dtype->implicit_flag)
|
||||||
|
use_type = NetNet::NONE;
|
||||||
|
else if (dtype->reg_flag)
|
||||||
|
use_type = NetNet::REG;
|
||||||
|
else
|
||||||
|
use_type = NetNet::IMPLICIT_REG;
|
||||||
|
|
||||||
|
// The SystemVerilog types that can show up as
|
||||||
|
// output ports are implicitly (on the inside)
|
||||||
|
// variables because "reg" is not valid syntax
|
||||||
|
// here.
|
||||||
|
} else if (dynamic_cast<atom2_type_t*> ($3)) {
|
||||||
|
use_type = NetNet::IMPLICIT_REG;
|
||||||
|
} else if (dynamic_cast<struct_type_t*> ($3)) {
|
||||||
|
use_type = NetNet::IMPLICIT_REG;
|
||||||
|
} else if (enum_type_t*etype = dynamic_cast<enum_type_t*> ($3)) {
|
||||||
|
if(etype->base_type == IVL_VT_LOGIC)
|
||||||
|
use_type = NetNet::IMPLICIT_REG;
|
||||||
|
}
|
||||||
|
if (use_type == NetNet::NONE)
|
||||||
|
pform_set_port_type(@2, $4, NetNet::POUTPUT, $3, $1);
|
||||||
|
else
|
||||||
|
pform_module_define_port(@2, $4, NetNet::POUTPUT, use_type, $3, $1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* var_type declaration (reg variables) cannot be input or output,
|
| attribute_list_opt port_direction net_type data_type_or_implicit error ';'
|
||||||
because the port declaration implies an external driver, which
|
|
||||||
cannot be attached to a reg. These rules catch that error early. */
|
|
||||||
|
|
||||||
| attribute_list_opt K_input var_type unsigned_signed_opt dimensions_opt list_of_identifiers ';'
|
|
||||||
{ pform_makewire(@2, $5, $4, $6, $3, NetNet::PINPUT,
|
|
||||||
IVL_VT_NO_TYPE, $1);
|
|
||||||
yyerror(@3, "error: reg variables cannot be inputs.");
|
|
||||||
}
|
|
||||||
|
|
||||||
| attribute_list_opt K_inout var_type unsigned_signed_opt dimensions_opt list_of_identifiers ';'
|
|
||||||
{ pform_makewire(@2, $5, $4, $6, $3, NetNet::PINOUT,
|
|
||||||
IVL_VT_NO_TYPE, $1);
|
|
||||||
yyerror(@3, "error: reg variables cannot be inouts.");
|
|
||||||
}
|
|
||||||
|
|
||||||
| attribute_list_opt port_direction unsigned_signed_opt dimensions_opt delay3_opt error ';'
|
|
||||||
{ yyerror(@2, "error: Invalid variable list in port declaration.");
|
{ yyerror(@2, "error: Invalid variable list in port declaration.");
|
||||||
if ($1) delete $1;
|
if ($1) delete $1;
|
||||||
if ($4) delete $4;
|
if ($4) delete $4;
|
||||||
if ($5) delete $5;
|
yyerrok;
|
||||||
|
}
|
||||||
|
|
||||||
|
| attribute_list_opt K_inout data_type_or_implicit error ';'
|
||||||
|
{ yyerror(@2, "error: Invalid variable list in port declaration.");
|
||||||
|
if ($1) delete $1;
|
||||||
|
if ($3) delete $3;
|
||||||
|
yyerrok;
|
||||||
|
}
|
||||||
|
|
||||||
|
| attribute_list_opt K_input data_type_or_implicit error ';'
|
||||||
|
{ yyerror(@2, "error: Invalid variable list in port declaration.");
|
||||||
|
if ($1) delete $1;
|
||||||
|
if ($3) delete $3;
|
||||||
|
yyerrok;
|
||||||
|
}
|
||||||
|
|
||||||
|
| attribute_list_opt K_output data_type_or_implicit error ';'
|
||||||
|
{ yyerror(@2, "error: Invalid variable list in port declaration.");
|
||||||
|
if ($1) delete $1;
|
||||||
|
if ($3) delete $3;
|
||||||
yyerrok;
|
yyerrok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5103,10 +5154,6 @@ net_type
|
||||||
| K_uwire { $$ = NetNet::UNRESOLVED_WIRE; }
|
| K_uwire { $$ = NetNet::UNRESOLVED_WIRE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
var_type
|
|
||||||
: K_reg { $$ = NetNet::REG; }
|
|
||||||
;
|
|
||||||
|
|
||||||
param_type
|
param_type
|
||||||
: bit_logic_opt unsigned_signed_opt dimensions_opt
|
: bit_logic_opt unsigned_signed_opt dimensions_opt
|
||||||
{ param_active_range = $3;
|
{ param_active_range = $3;
|
||||||
|
|
|
||||||
84
pform.cc
84
pform.cc
|
|
@ -1944,6 +1944,7 @@ static void pform_set_net_range(perm_string name,
|
||||||
VLerror("error: name is not a valid net.");
|
VLerror("error: name is not a valid net.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is not implicit ("implicit" meaning we don't
|
// If this is not implicit ("implicit" meaning we don't
|
||||||
// know what the type is yet) then set the type now.
|
// know what the type is yet) then set the type now.
|
||||||
if (net_type != NetNet::IMPLICIT && net_type != NetNet::NONE) {
|
if (net_type != NetNet::IMPLICIT && net_type != NetNet::NONE) {
|
||||||
|
|
@ -2349,7 +2350,8 @@ void pform_module_define_port(const struct vlltype&li,
|
||||||
NetNet::PortType port_kind,
|
NetNet::PortType port_kind,
|
||||||
NetNet::Type type,
|
NetNet::Type type,
|
||||||
data_type_t*vtype,
|
data_type_t*vtype,
|
||||||
list<named_pexpr_t>*attr)
|
list<named_pexpr_t>*attr,
|
||||||
|
bool keep_attr)
|
||||||
{
|
{
|
||||||
struct_type_t*struct_type = 0;
|
struct_type_t*struct_type = 0;
|
||||||
ivl_variable_type_t data_type = IVL_VT_NO_TYPE;
|
ivl_variable_type_t data_type = IVL_VT_NO_TYPE;
|
||||||
|
|
@ -2438,10 +2440,37 @@ void pform_module_define_port(const struct vlltype&li,
|
||||||
cur->set_unpacked_idx(*urange);
|
cur->set_unpacked_idx(*urange);
|
||||||
}
|
}
|
||||||
|
|
||||||
pform_bind_attributes(cur->attributes, attr);
|
pform_bind_attributes(cur->attributes, attr, keep_attr);
|
||||||
pform_put_wire_in_scope(name, cur);
|
pform_put_wire_in_scope(name, cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pform_module_define_port(const struct vlltype&li,
|
||||||
|
list<pform_port_t>*ports,
|
||||||
|
NetNet::PortType port_kind,
|
||||||
|
NetNet::Type type,
|
||||||
|
data_type_t*vtype,
|
||||||
|
list<named_pexpr_t>*attr)
|
||||||
|
{
|
||||||
|
for (list<pform_port_t>::iterator cur = ports->begin()
|
||||||
|
; cur != ports->end() ; ++ cur ) {
|
||||||
|
|
||||||
|
data_type_t*use_type = vtype;
|
||||||
|
if (cur->udims)
|
||||||
|
use_type = new uarray_type_t(vtype, cur->udims);
|
||||||
|
|
||||||
|
pform_module_define_port(li, cur->name, port_kind, type, use_type,
|
||||||
|
attr, true);
|
||||||
|
if (cur->udims)
|
||||||
|
delete use_type;
|
||||||
|
|
||||||
|
if (cur->expr)
|
||||||
|
pform_make_var_init(li, cur->name, cur->expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete ports;
|
||||||
|
delete attr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function makes a single signal (a wire, a reg, etc) as
|
* This function makes a single signal (a wire, a reg, etc) as
|
||||||
* requested by the parser. The name is unscoped, so I attach the
|
* requested by the parser. The name is unscoped, so I attach the
|
||||||
|
|
@ -3246,24 +3275,53 @@ static void pform_set_port_type(perm_string name, NetNet::PortType pt,
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_port_type(const struct vlltype&li,
|
void pform_set_port_type(const struct vlltype&li,
|
||||||
list<perm_string>*names,
|
list<pform_port_t>*ports,
|
||||||
list<pform_range_t>*range,
|
|
||||||
bool signed_flag,
|
|
||||||
NetNet::PortType pt,
|
NetNet::PortType pt,
|
||||||
|
data_type_t*dt,
|
||||||
list<named_pexpr_t>*attr)
|
list<named_pexpr_t>*attr)
|
||||||
{
|
{
|
||||||
assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT);
|
assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT);
|
||||||
|
|
||||||
for (list<perm_string>::iterator cur = names->begin()
|
list<pform_range_t>*range = 0;
|
||||||
; cur != names->end() ; ++ cur ) {
|
bool signed_flag = false;
|
||||||
perm_string txt = *cur;
|
if (vector_type_t*vt = dynamic_cast<vector_type_t*> (dt)) {
|
||||||
pform_set_port_type(txt, pt, li.text, li.first_line);
|
assert(vt->implicit_flag);
|
||||||
pform_set_net_range(txt, NetNet::NONE, range, signed_flag, IVL_VT_NO_TYPE,
|
range = vt->pdims.get();
|
||||||
SR_PORT, attr);
|
signed_flag = vt->signed_flag;
|
||||||
|
} else {
|
||||||
|
assert(dt == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete names;
|
bool have_init_expr = false;
|
||||||
delete range;
|
for (list<pform_port_t>::iterator cur = ports->begin()
|
||||||
|
; cur != ports->end() ; ++ cur ) {
|
||||||
|
|
||||||
|
pform_set_port_type(cur->name, pt, li.text, li.first_line);
|
||||||
|
pform_set_net_range(cur->name, NetNet::NONE, range, signed_flag,
|
||||||
|
IVL_VT_NO_TYPE, SR_PORT, attr);
|
||||||
|
if (cur->udims) {
|
||||||
|
cerr << li.text << ":" << li.first_line << ": warning: "
|
||||||
|
<< "Array dimensions in incomplete port declarations "
|
||||||
|
<< "are currently ignored." << endl;
|
||||||
|
cerr << li.text << ":" << li.first_line << ": : "
|
||||||
|
<< "The dimensions specified in the net or variable "
|
||||||
|
<< "declaration will be used." << endl;
|
||||||
|
delete cur->udims;
|
||||||
|
}
|
||||||
|
if (cur->expr) {
|
||||||
|
have_init_expr = true;
|
||||||
|
delete cur->expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (have_init_expr) {
|
||||||
|
cerr << li.text << ":" << li.first_line << ": error: "
|
||||||
|
<< "Incomplete port declarations cannot be initialized."
|
||||||
|
<< endl;
|
||||||
|
error_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete ports;
|
||||||
|
delete dt;
|
||||||
delete attr;
|
delete attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
25
pform.h
25
pform.h
|
|
@ -168,14 +168,21 @@ extern void pform_startmodule(const struct vlltype&loc, const char*name,
|
||||||
extern void pform_check_timeunit_prec();
|
extern void pform_check_timeunit_prec();
|
||||||
extern void pform_module_set_ports(vector<Module::port_t*>*);
|
extern void pform_module_set_ports(vector<Module::port_t*>*);
|
||||||
|
|
||||||
/* This function is used to support the port definition in a
|
/* These functions are used when we have a complete port definition, either
|
||||||
port_definition_list. In this case, we have everything needed to
|
in an ansi style or non-ansi style declaration. In this case, we have
|
||||||
define the port, all in one place. */
|
everything needed to define the port, all in one place. */
|
||||||
extern void pform_module_define_port(const struct vlltype&li,
|
extern void pform_module_define_port(const struct vlltype&li,
|
||||||
perm_string name,
|
perm_string name,
|
||||||
NetNet::PortType,
|
NetNet::PortType,
|
||||||
NetNet::Type type,
|
NetNet::Type type,
|
||||||
data_type_t*vtype,
|
data_type_t*vtype,
|
||||||
|
list<named_pexpr_t>*attr,
|
||||||
|
bool keep_attr =false);
|
||||||
|
extern void pform_module_define_port(const struct vlltype&li,
|
||||||
|
list<pform_port_t>*ports,
|
||||||
|
NetNet::PortType,
|
||||||
|
NetNet::Type type,
|
||||||
|
data_type_t*vtype,
|
||||||
list<named_pexpr_t>*attr);
|
list<named_pexpr_t>*attr);
|
||||||
|
|
||||||
extern Module::port_t* pform_module_port_reference(perm_string name,
|
extern Module::port_t* pform_module_port_reference(perm_string name,
|
||||||
|
|
@ -364,14 +371,14 @@ extern void pform_makewire(const struct vlltype&li,
|
||||||
extern void pform_make_var_init(const struct vlltype&li,
|
extern void pform_make_var_init(const struct vlltype&li,
|
||||||
perm_string name, PExpr*expr);
|
perm_string name, PExpr*expr);
|
||||||
|
|
||||||
/* Look up the names of the wires, and set the port type,
|
/* This function is used when we have an incomplete port definition in
|
||||||
i.e. input, output or inout. If the wire does not exist, create
|
a non-ansi style declaration. Look up the names of the wires, and set
|
||||||
it. The second form takes a single name. */
|
the port type, i.e. input, output or inout, and, if specified, the
|
||||||
|
range and signedness. If the wire does not exist, create it. */
|
||||||
extern void pform_set_port_type(const struct vlltype&li,
|
extern void pform_set_port_type(const struct vlltype&li,
|
||||||
list<perm_string>*names,
|
list<pform_port_t>*ports,
|
||||||
list<pform_range_t>*range,
|
|
||||||
bool signed_flag,
|
|
||||||
NetNet::PortType,
|
NetNet::PortType,
|
||||||
|
data_type_t*dt,
|
||||||
list<named_pexpr_t>*attr);
|
list<named_pexpr_t>*attr);
|
||||||
|
|
||||||
extern void pform_set_reg_idx(perm_string name,
|
extern void pform_set_reg_idx(perm_string name,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_pform_types_H
|
#ifndef IVL_pform_types_H
|
||||||
#define IVL_pform_types_H
|
#define IVL_pform_types_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2014 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2007-2016 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -72,6 +72,21 @@ typedef named<PExpr*> named_pexpr_t;
|
||||||
*/
|
*/
|
||||||
typedef std::pair<PExpr*,PExpr*> pform_range_t;
|
typedef std::pair<PExpr*,PExpr*> pform_range_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The pform_port_t holds the name and optional unpacked dimensions
|
||||||
|
* and initialization expression for a single port in a list of port
|
||||||
|
* declarations.
|
||||||
|
*/
|
||||||
|
struct pform_port_t {
|
||||||
|
pform_port_t(perm_string n, list<pform_range_t>*ud, PExpr*e)
|
||||||
|
: name(n), udims(ud), expr(e) { }
|
||||||
|
~pform_port_t() { }
|
||||||
|
|
||||||
|
perm_string name;
|
||||||
|
list<pform_range_t>*udims;
|
||||||
|
PExpr*expr;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Semantic NOTES:
|
* Semantic NOTES:
|
||||||
* - The SEL_BIT is a single expression. This might me a bit select
|
* - The SEL_BIT is a single expression. This might me a bit select
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue