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:
parent
472598dd74
commit
f67cdddecf
47
parse.y
47
parse.y
|
|
@ -1221,14 +1221,7 @@ packed_array_data_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
|
|
||||||
data_type /* IEEE1800-2005: A.2.2.1 */
|
data_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
: integer_vector_type unsigned_signed_opt dimensions_opt
|
: integer_vector_type unsigned_signed_opt dimensions_opt
|
||||||
{ ivl_variable_type_t use_vtype = $1;
|
{ vector_type_t*tmp = new vector_type_t($1, $2, $3);
|
||||||
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;
|
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -1245,14 +1238,12 @@ data_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
| K_integer signed_unsigned_opt
|
| K_integer signed_unsigned_opt
|
||||||
{ std::list<pform_range_t>*pd = make_range_from_width(integer_width);
|
{ 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);
|
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $2, pd);
|
||||||
tmp->reg_flag = true;
|
|
||||||
tmp->integer_flag = true;
|
tmp->integer_flag = true;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_time unsigned_signed_opt
|
| K_time unsigned_signed_opt
|
||||||
{ std::list<pform_range_t>*pd = make_range_from_width(64);
|
{ std::list<pform_range_t>*pd = make_range_from_width(64);
|
||||||
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $2, pd);
|
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $2, pd);
|
||||||
tmp->reg_flag = !gn_system_verilog();
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| packed_array_data_type dimensions_opt
|
| 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 */
|
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_bit { $$ = IVL_VT_BOOL; }
|
||||||
| K_logic { $$ = IVL_VT_LOGIC; }
|
| K_logic { $$ = IVL_VT_LOGIC; }
|
||||||
| K_bool { $$ = IVL_VT_BOOL; } /* Icarus Verilog xtypes extension */
|
| 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 */
|
simple_type_or_string /* IEEE1800-2005: A.2.2.1 */
|
||||||
: integer_vector_type
|
: integer_vector_type
|
||||||
{ ivl_variable_type_t use_vtype = $1;
|
{ vector_type_t*tmp = new vector_type_t($1, false, 0);
|
||||||
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;
|
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -2203,14 +2187,12 @@ simple_type_or_string /* IEEE1800-2005: A.2.2.1 */
|
||||||
| K_integer
|
| K_integer
|
||||||
{ std::list<pform_range_t>*pd = make_range_from_width(integer_width);
|
{ 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);
|
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, true, pd);
|
||||||
tmp->reg_flag = true;
|
|
||||||
tmp->integer_flag = true;
|
tmp->integer_flag = true;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_time
|
| K_time
|
||||||
{ std::list<pform_range_t>*pd = make_range_from_width(64);
|
{ std::list<pform_range_t>*pd = make_range_from_width(64);
|
||||||
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, false, pd);
|
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, false, pd);
|
||||||
tmp->reg_flag = !gn_system_verilog();
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_string
|
| K_string
|
||||||
|
|
@ -2776,12 +2758,8 @@ enum_base_type /* IEEE 1800-2012 A.2.2.1 */
|
||||||
$$ = enum_type;
|
$$ = enum_type;
|
||||||
}
|
}
|
||||||
| integer_vector_type unsigned_signed_opt dimensions_opt
|
| integer_vector_type unsigned_signed_opt dimensions_opt
|
||||||
{ ivl_variable_type_t use_vtype = $1;
|
{ enum_type_t*enum_type = new enum_type_t;
|
||||||
if (use_vtype == IVL_VT_NO_TYPE)
|
enum_type->base_type = $1;
|
||||||
use_vtype = IVL_VT_LOGIC;
|
|
||||||
|
|
||||||
enum_type_t*enum_type = new enum_type_t;
|
|
||||||
enum_type->base_type = use_vtype;
|
|
||||||
enum_type->signed_flag = $2;
|
enum_type->signed_flag = $2;
|
||||||
enum_type->integer_flag = false;
|
enum_type->integer_flag = false;
|
||||||
enum_type->range.reset($3 ? $3 : make_range_from_width(1));
|
enum_type->range.reset($3 ? $3 : make_range_from_width(1));
|
||||||
|
|
@ -4552,9 +4530,7 @@ port_declaration
|
||||||
NetNet::Type use_type = $3;
|
NetNet::Type use_type = $3;
|
||||||
if (use_type == NetNet::IMPLICIT) {
|
if (use_type == NetNet::IMPLICIT) {
|
||||||
if (vector_type_t*dtype = dynamic_cast<vector_type_t*> ($4)) {
|
if (vector_type_t*dtype = dynamic_cast<vector_type_t*> ($4)) {
|
||||||
if (dtype->reg_flag)
|
if (dtype->implicit_flag)
|
||||||
use_type = NetNet::REG;
|
|
||||||
else if (dtype->implicit_flag)
|
|
||||||
use_type = NetNet::IMPLICIT;
|
use_type = NetNet::IMPLICIT;
|
||||||
else
|
else
|
||||||
use_type = NetNet::IMPLICIT_REG;
|
use_type = NetNet::IMPLICIT_REG;
|
||||||
|
|
@ -4596,14 +4572,7 @@ port_declaration
|
||||||
perm_string name = lex_strings.make($5);
|
perm_string name = lex_strings.make($5);
|
||||||
NetNet::Type use_type = $3;
|
NetNet::Type use_type = $3;
|
||||||
if (use_type == NetNet::IMPLICIT) {
|
if (use_type == NetNet::IMPLICIT) {
|
||||||
if (vector_type_t*dtype = dynamic_cast<vector_type_t*> ($4)) {
|
use_type = NetNet::IMPLICIT_REG;
|
||||||
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);
|
ptmp = pform_module_port_reference(name, @2.text, @2.first_line);
|
||||||
pform_module_define_port(@2, name, NetNet::POUTPUT, use_type, $4, $1);
|
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 (vector_type_t*dtype = dynamic_cast<vector_type_t*> ($3)) {
|
||||||
if (dtype->implicit_flag)
|
if (dtype->implicit_flag)
|
||||||
use_type = NetNet::NONE;
|
use_type = NetNet::NONE;
|
||||||
else if (dtype->reg_flag)
|
|
||||||
use_type = NetNet::REG;
|
|
||||||
else
|
else
|
||||||
use_type = NetNet::IMPLICIT_REG;
|
use_type = NetNet::IMPLICIT_REG;
|
||||||
|
|
||||||
|
|
|
||||||
3
pform.cc
3
pform.cc
|
|
@ -2652,9 +2652,6 @@ void pform_module_define_port(const struct vlltype&li,
|
||||||
data_type = vec_type->base_type;
|
data_type = vec_type->base_type;
|
||||||
signed_flag = vec_type->signed_flag;
|
signed_flag = vec_type->signed_flag;
|
||||||
prange = vec_type->pdims.get();
|
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)) {
|
} else if (atom2_type_t*atype = dynamic_cast<atom2_type_t*>(vtype)) {
|
||||||
data_type = IVL_VT_BOOL;
|
data_type = IVL_VT_BOOL;
|
||||||
signed_flag = atype->signed_flag;
|
signed_flag = atype->signed_flag;
|
||||||
|
|
|
||||||
|
|
@ -233,12 +233,7 @@ extern atom2_type_t size_type;
|
||||||
* bit unsigned foo
|
* bit unsigned foo
|
||||||
* reg foo
|
* reg foo
|
||||||
*
|
*
|
||||||
* There are a few special cases:
|
* There is one special case:
|
||||||
*
|
|
||||||
* 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
|
* 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
|
* 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 {
|
struct vector_type_t : public data_type_t {
|
||||||
inline explicit vector_type_t(ivl_variable_type_t bt, bool sf,
|
inline explicit vector_type_t(ivl_variable_type_t bt, bool sf,
|
||||||
std::list<pform_range_t>*pd)
|
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 ivl_variable_type_t figure_packed_base_type(void)const;
|
||||||
virtual void pform_dump(std::ostream&out, unsigned indent) const;
|
virtual void pform_dump(std::ostream&out, unsigned indent) const;
|
||||||
virtual std::ostream& debug_dump(std::ostream&out) 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;
|
ivl_variable_type_t base_type;
|
||||||
bool signed_flag;
|
bool signed_flag;
|
||||||
bool reg_flag; // True if "reg" was used
|
|
||||||
bool integer_flag; // True if "integer" was used
|
bool integer_flag; // True if "integer" was used
|
||||||
bool implicit_flag; // True if this type is implicitly logic/reg
|
bool implicit_flag; // True if this type is implicitly logic/reg
|
||||||
std::unique_ptr< std::list<pform_range_t> > pdims;
|
std::unique_ptr< std::list<pform_range_t> > pdims;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue