Don't make input `integer` ports variables

In Verilog module input ports can only have a packed dimensions and a
signed flag, but no explicit data type.

In SystemVerilog an explicit data type can be specified for module input
ports. Such a port is a net, regardless of the data type, unless
explicitly made a variable using the `var` keyword.

This works for the most part in the current implementation, but for some
data types such as `reg` and `integer` the input port is turned into a
variable. And since input port's can't be variables in the current
implementation this results in an error.

Fix this by completely removing the `reg_flag` that is used to indicate
that a certain data type is always a variable. There is no such restriction
on data types for SystemVerilog and for Verilog there are already checks in
place that a input port can only have an implicit (or real) data type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-03-02 09:44:44 +01:00
parent 472598dd74
commit f67cdddecf
3 changed files with 9 additions and 51 deletions

47
parse.y
View File

@ -1221,14 +1221,7 @@ packed_array_data_type /* IEEE1800-2005: A.2.2.1 */
data_type /* IEEE1800-2005: A.2.2.1 */
: integer_vector_type unsigned_signed_opt dimensions_opt
{ ivl_variable_type_t use_vtype = $1;
bool reg_flag = false;
if (use_vtype == IVL_VT_NO_TYPE) {
use_vtype = IVL_VT_LOGIC;
reg_flag = true;
}
vector_type_t*tmp = new vector_type_t(use_vtype, $2, $3);
tmp->reg_flag = reg_flag;
{ vector_type_t*tmp = new vector_type_t($1, $2, $3);
FILE_NAME(tmp, @1);
$$ = tmp;
}
@ -1245,14 +1238,12 @@ data_type /* IEEE1800-2005: A.2.2.1 */
| K_integer signed_unsigned_opt
{ std::list<pform_range_t>*pd = make_range_from_width(integer_width);
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $2, pd);
tmp->reg_flag = true;
tmp->integer_flag = true;
$$ = tmp;
}
| K_time unsigned_signed_opt
{ std::list<pform_range_t>*pd = make_range_from_width(64);
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $2, pd);
tmp->reg_flag = !gn_system_verilog();
$$ = tmp;
}
| packed_array_data_type dimensions_opt
@ -1595,7 +1586,7 @@ inside_expression /* IEEE1800-2005 A.8.3 */
;
integer_vector_type /* IEEE1800-2005: A.2.2.1 */
: K_reg { $$ = IVL_VT_NO_TYPE; } /* Usually a synonym for logic. */
: K_reg { $$ = IVL_VT_LOGIC; } /* A synonym for logic. */
| K_bit { $$ = IVL_VT_BOOL; }
| K_logic { $$ = IVL_VT_LOGIC; }
| K_bool { $$ = IVL_VT_BOOL; } /* Icarus Verilog xtypes extension */
@ -2179,14 +2170,7 @@ simple_immediate_assertion_statement /* IEEE1800-2012 A.6.10 */
simple_type_or_string /* IEEE1800-2005: A.2.2.1 */
: integer_vector_type
{ ivl_variable_type_t use_vtype = $1;
bool reg_flag = false;
if (use_vtype == IVL_VT_NO_TYPE) {
use_vtype = IVL_VT_LOGIC;
reg_flag = true;
}
vector_type_t*tmp = new vector_type_t(use_vtype, false, 0);
tmp->reg_flag = reg_flag;
{ vector_type_t*tmp = new vector_type_t($1, false, 0);
FILE_NAME(tmp, @1);
$$ = tmp;
}
@ -2203,14 +2187,12 @@ simple_type_or_string /* IEEE1800-2005: A.2.2.1 */
| K_integer
{ std::list<pform_range_t>*pd = make_range_from_width(integer_width);
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, true, pd);
tmp->reg_flag = true;
tmp->integer_flag = true;
$$ = tmp;
}
| K_time
{ std::list<pform_range_t>*pd = make_range_from_width(64);
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, false, pd);
tmp->reg_flag = !gn_system_verilog();
$$ = tmp;
}
| K_string
@ -2776,12 +2758,8 @@ enum_base_type /* IEEE 1800-2012 A.2.2.1 */
$$ = enum_type;
}
| integer_vector_type unsigned_signed_opt dimensions_opt
{ ivl_variable_type_t use_vtype = $1;
if (use_vtype == IVL_VT_NO_TYPE)
use_vtype = IVL_VT_LOGIC;
enum_type_t*enum_type = new enum_type_t;
enum_type->base_type = use_vtype;
{ enum_type_t*enum_type = new enum_type_t;
enum_type->base_type = $1;
enum_type->signed_flag = $2;
enum_type->integer_flag = false;
enum_type->range.reset($3 ? $3 : make_range_from_width(1));
@ -4552,9 +4530,7 @@ port_declaration
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)
if (dtype->implicit_flag)
use_type = NetNet::IMPLICIT;
else
use_type = NetNet::IMPLICIT_REG;
@ -4596,14 +4572,7 @@ port_declaration
perm_string name = lex_strings.make($5);
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;
}
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, $4, $1);
@ -5009,8 +4978,6 @@ module_item
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;

View File

@ -2652,9 +2652,6 @@ void pform_module_define_port(const struct vlltype&li,
data_type = vec_type->base_type;
signed_flag = vec_type->signed_flag;
prange = vec_type->pdims.get();
if (vec_type->reg_flag)
type = NetNet::REG;
} else if (atom2_type_t*atype = dynamic_cast<atom2_type_t*>(vtype)) {
data_type = IVL_VT_BOOL;
signed_flag = atype->signed_flag;

View File

@ -233,12 +233,7 @@ extern atom2_type_t size_type;
* 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.
* There is one special case:
*
* 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
@ -247,7 +242,7 @@ extern atom2_type_t size_type;
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), integer_flag(false), implicit_flag(false), pdims(pd) { }
: base_type(bt), signed_flag(sf), integer_flag(false), implicit_flag(false), pdims(pd) { }
virtual ivl_variable_type_t figure_packed_base_type(void)const;
virtual void pform_dump(std::ostream&out, unsigned indent) const;
virtual std::ostream& debug_dump(std::ostream&out) const;
@ -255,7 +250,6 @@ struct vector_type_t : public data_type_t {
ivl_variable_type_t base_type;
bool signed_flag;
bool reg_flag; // True if "reg" was used
bool integer_flag; // True if "integer" was used
bool implicit_flag; // True if this type is implicitly logic/reg
std::unique_ptr< std::list<pform_range_t> > pdims;