Module output ports use data_type_or_implicit
This cleans up the parsing of module output ports, allows for more complex types on the ports, and fixes some bugs.
This commit is contained in:
parent
b7b633b613
commit
67af96fee7
144
parse.y
144
parse.y
|
|
@ -903,11 +903,13 @@ data_type_or_implicit /* IEEE1800-2005: A.2.2.1 */
|
|||
{ $$ = $1; }
|
||||
| signing range_opt
|
||||
{ vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $1, $2);
|
||||
tmp->implicit_flag = true;
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| range
|
||||
{ vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, false, $1);
|
||||
tmp->implicit_flag = true;
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
|
@ -3549,62 +3551,32 @@ port_declaration
|
|||
delete[]$4;
|
||||
$$ = ptmp;
|
||||
}
|
||||
| attribute_list_opt
|
||||
K_output net_type_opt primitive_type_opt unsigned_signed_opt range_opt IDENTIFIER
|
||||
{ Module::port_t*ptmp;
|
||||
perm_string name = lex_strings.make($7);
|
||||
ptmp = pform_module_port_reference(name, @2.text,
|
||||
@2.first_line);
|
||||
vector_type_t*tmp = new vector_type_t($4, $5, $6);
|
||||
pform_module_define_port(@2, name, NetNet::POUTPUT, $3, IVL_VT_NO_TYPE,
|
||||
false, tmp, 0, $1);
|
||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||
port_declaration_context.port_net_type = $3;
|
||||
port_declaration_context.var_type = IVL_VT_NO_TYPE;
|
||||
port_declaration_context.sign_flag = false;
|
||||
delete port_declaration_context.range;
|
||||
port_declaration_context.range = 0;
|
||||
port_declaration_context.data_type = tmp;
|
||||
delete[]$7;
|
||||
$$ = ptmp;
|
||||
}
|
||||
| attribute_list_opt
|
||||
K_output K_reg primitive_type_opt unsigned_signed_opt range_opt IDENTIFIER
|
||||
{ Module::port_t*ptmp;
|
||||
perm_string name = lex_strings.make($7);
|
||||
ptmp = pform_module_port_reference(name, @2.text,
|
||||
@2.first_line);
|
||||
vector_type_t*tmp = new vector_type_t($4, $5, $6);
|
||||
tmp->reg_flag = true;
|
||||
pform_module_define_port(@2, name, NetNet::POUTPUT, NetNet::REG, IVL_VT_NO_TYPE,
|
||||
false, tmp, 0, $1);
|
||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||
port_declaration_context.port_net_type = NetNet::REG;
|
||||
port_declaration_context.var_type = IVL_VT_NO_TYPE;
|
||||
port_declaration_context.sign_flag = false;
|
||||
delete port_declaration_context.range;
|
||||
port_declaration_context.range = 0;
|
||||
port_declaration_context.data_type = tmp;
|
||||
delete[]$7;
|
||||
$$ = ptmp;
|
||||
}
|
||||
| attribute_list_opt
|
||||
K_output atom2_type signed_unsigned_opt IDENTIFIER
|
||||
| attribute_list_opt K_output net_type_opt data_type_or_implicit IDENTIFIER
|
||||
{ Module::port_t*ptmp;
|
||||
perm_string name = lex_strings.make($5);
|
||||
ptmp = pform_module_port_reference(name, @2.text,
|
||||
@2.first_line);
|
||||
atom2_type_t*tmp = new atom2_type_t($3, $4);
|
||||
pform_module_define_port(@2, name, NetNet::POUTPUT,
|
||||
NetNet::IMPLICIT_REG, IVL_VT_NO_TYPE,
|
||||
false, tmp, 0, $1);
|
||||
NetNet::Type use_type = $3;
|
||||
if (use_type == NetNet::IMPLICIT) {
|
||||
if (vector_type_t*dtype = dynamic_cast<vector_type_t*> ($4)) {
|
||||
if (dtype->reg_flag)
|
||||
use_type = NetNet::REG;
|
||||
else if (dtype->implicit_flag)
|
||||
use_type = NetNet::IMPLICIT;
|
||||
else
|
||||
use_type = NetNet::IMPLICIT_REG;
|
||||
} else if (dynamic_cast<atom2_type_t*> ($4)) {
|
||||
use_type = NetNet::IMPLICIT_REG;
|
||||
}
|
||||
}
|
||||
ptmp = pform_module_port_reference(name, @2.text, @2.first_line);
|
||||
pform_module_define_port(@2, name, NetNet::POUTPUT, use_type, IVL_VT_NO_TYPE,
|
||||
false, $4, 0, $1);
|
||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||
port_declaration_context.port_net_type = NetNet::IMPLICIT_REG;
|
||||
port_declaration_context.port_net_type = use_type;
|
||||
port_declaration_context.var_type = IVL_VT_NO_TYPE;
|
||||
port_declaration_context.sign_flag = false;
|
||||
delete port_declaration_context.range;
|
||||
port_declaration_context.range = 0;
|
||||
port_declaration_context.data_type = tmp;
|
||||
port_declaration_context.data_type = $4;
|
||||
delete[]$5;
|
||||
$$ = ptmp;
|
||||
}
|
||||
|
|
@ -3626,68 +3598,30 @@ port_declaration
|
|||
delete[]$4;
|
||||
$$ = ptmp;
|
||||
}
|
||||
| attribute_list_opt
|
||||
K_output K_reg primitive_type_opt unsigned_signed_opt range_opt IDENTIFIER '=' expression
|
||||
{ Module::port_t*ptmp;
|
||||
perm_string name = lex_strings.make($7);
|
||||
ptmp = pform_module_port_reference(name, @2.text,
|
||||
@2.first_line);
|
||||
vector_type_t*tmp = new vector_type_t($4, $5, $6);
|
||||
pform_module_define_port(@2, name, NetNet::POUTPUT, NetNet::REG, IVL_VT_NO_TYPE,
|
||||
false, tmp, 0, $1);
|
||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||
port_declaration_context.port_net_type = NetNet::REG;
|
||||
port_declaration_context.var_type = IVL_VT_NO_TYPE;
|
||||
port_declaration_context.sign_flag = false;
|
||||
delete port_declaration_context.range;
|
||||
port_declaration_context.range = 0;
|
||||
port_declaration_context.data_type = tmp;
|
||||
|
||||
pform_make_reginit(@7, name, $9);
|
||||
|
||||
delete[]$7;
|
||||
$$ = ptmp;
|
||||
}
|
||||
| attribute_list_opt
|
||||
K_output net_type_opt primitive_type_opt unsigned_signed_opt range_opt IDENTIFIER '=' expression
|
||||
{ Module::port_t*ptmp;
|
||||
perm_string name = lex_strings.make($7);
|
||||
NetNet::Type t = ($3 == NetNet::IMPLICIT) ? NetNet::IMPLICIT_REG : $3;
|
||||
ptmp = pform_module_port_reference(name, @2.text,
|
||||
@2.first_line);
|
||||
vector_type_t*tmp = new vector_type_t($4, $5, $6);
|
||||
pform_module_define_port(@2, name, NetNet::POUTPUT, t, IVL_VT_NO_TYPE,
|
||||
false, tmp, 0, $1);
|
||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||
port_declaration_context.port_net_type = t;
|
||||
port_declaration_context.var_type = IVL_VT_NO_TYPE;
|
||||
port_declaration_context.sign_flag = false;
|
||||
delete port_declaration_context.range;
|
||||
port_declaration_context.range = 0;
|
||||
port_declaration_context.data_type = tmp;
|
||||
|
||||
pform_make_reginit(@7, name, $9);
|
||||
|
||||
delete[]$7;
|
||||
$$ = ptmp;
|
||||
}
|
||||
| attribute_list_opt
|
||||
K_output atom2_type signed_unsigned_opt IDENTIFIER '=' expression
|
||||
| attribute_list_opt K_output net_type_opt data_type_or_implicit IDENTIFIER '=' expression
|
||||
{ Module::port_t*ptmp;
|
||||
perm_string name = lex_strings.make($5);
|
||||
ptmp = pform_module_port_reference(name, @2.text,
|
||||
@2.first_line);
|
||||
atom2_type_t*tmp = new atom2_type_t($3, $4);
|
||||
pform_module_define_port(@2, name, NetNet::POUTPUT,
|
||||
NetNet::IMPLICIT_REG, IVL_VT_NO_TYPE,
|
||||
false, tmp, 0, $1);
|
||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||
port_declaration_context.port_net_type = NetNet::IMPLICIT_REG;
|
||||
NetNet::Type use_type = $3;
|
||||
if (use_type == NetNet::IMPLICIT) {
|
||||
if (vector_type_t*dtype = dynamic_cast<vector_type_t*> ($4)) {
|
||||
if (dtype->reg_flag)
|
||||
use_type = NetNet::REG;
|
||||
else
|
||||
use_type = NetNet::IMPLICIT_REG;
|
||||
} else {
|
||||
use_type = NetNet::IMPLICIT_REG;
|
||||
}
|
||||
}
|
||||
ptmp = pform_module_port_reference(name, @2.text, @2.first_line);
|
||||
pform_module_define_port(@2, name, NetNet::POUTPUT, use_type, IVL_VT_NO_TYPE,
|
||||
false, $4, 0, $1);
|
||||
port_declaration_context.port_type = NetNet::PINOUT;
|
||||
port_declaration_context.port_net_type = use_type;
|
||||
port_declaration_context.var_type = IVL_VT_NO_TYPE;
|
||||
port_declaration_context.sign_flag = false;
|
||||
delete port_declaration_context.range;
|
||||
port_declaration_context.range = 0;
|
||||
port_declaration_context.data_type = tmp;
|
||||
port_declaration_context.data_type = $4;
|
||||
|
||||
pform_make_reginit(@5, name, $7);
|
||||
|
||||
|
|
|
|||
|
|
@ -108,13 +108,33 @@ struct atom2_type_t : public data_type_t {
|
|||
bool signed_flag;
|
||||
};
|
||||
|
||||
/*
|
||||
* The vector_type_t class represents types in the old Verilog
|
||||
* way. Some typical examples:
|
||||
*
|
||||
* logic signed [7:0] foo
|
||||
* bit unsigned foo
|
||||
* reg foo
|
||||
*
|
||||
* There are a few special cases:
|
||||
*
|
||||
* For the most part, Verilog treats "logic" and "reg" as synonyms,
|
||||
* but there are a few cases where the parser needs to know the
|
||||
* difference. So "reg_flag" is set to true if the IVL_VT_LOGIC type
|
||||
* is due to the "reg" keyword.
|
||||
*
|
||||
* If there are no reg/logic/bit/bool keywords, then Verilog will
|
||||
* assume the type is logic, but the context may need to know about
|
||||
* this case, so the implicit_flag member is set to true in that case.
|
||||
*/
|
||||
struct vector_type_t : public data_type_t {
|
||||
inline explicit vector_type_t(ivl_variable_type_t bt, bool sf,
|
||||
std::list<pform_range_t>*pd)
|
||||
: base_type(bt), signed_flag(sf), reg_flag(false), pdims(pd) { }
|
||||
: base_type(bt), signed_flag(sf), reg_flag(false), implicit_flag(false), pdims(pd) { }
|
||||
ivl_variable_type_t base_type;
|
||||
bool signed_flag;
|
||||
bool reg_flag;
|
||||
bool reg_flag; // True if "reg" was used
|
||||
bool implicit_flag; // True if this type is implicitly logic/reg
|
||||
std::auto_ptr< list<pform_range_t> > pdims;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -72,9 +72,7 @@ int VTypeArray::emit_decl(ostream&out, perm_string name, bool reg_flag) const
|
|||
int errors = 0;
|
||||
assert(dimensions() == 1);
|
||||
|
||||
if (reg_flag)
|
||||
out << "reg ";
|
||||
else
|
||||
if (!reg_flag)
|
||||
out << "wire ";
|
||||
|
||||
errors += emit_def(out, name);
|
||||
|
|
@ -135,9 +133,7 @@ int VTypePrimitive::emit_def(ostream&out, perm_string name) const
|
|||
int VTypePrimitive::emit_decl(ostream&out, perm_string name, bool reg_flag) const
|
||||
{
|
||||
int errors = 0;
|
||||
if (reg_flag)
|
||||
out << "reg ";
|
||||
else
|
||||
if (!reg_flag)
|
||||
out << "wire ";
|
||||
|
||||
errors += emit_def(out, name);
|
||||
|
|
|
|||
Loading…
Reference in New Issue