Merge pull request #634 from larsclausen/wire-type-error
Correctly handle data types on nets
This commit is contained in:
commit
98a87b49c8
134
elab_sig.cc
134
elab_sig.cc
|
|
@ -90,6 +90,90 @@ void Statement::elaborate_sig(Design*, NetScope*) const
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sig_check_data_type(Design*des, NetScope*scope,
|
||||||
|
PWire *wire, NetNet *sig)
|
||||||
|
{
|
||||||
|
ivl_type_t type = sig->net_type();
|
||||||
|
|
||||||
|
if (!type)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (type->packed()) {
|
||||||
|
switch (type->base_type()) {
|
||||||
|
case IVL_VT_LOGIC: // 4-state packed is allowed by the standard
|
||||||
|
case IVL_VT_BOOL: // Icarus allows 2-state packed as an extension
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Icarus allows real nets as an extension
|
||||||
|
if (type->base_type() == IVL_VT_REAL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (wire->symbol_type() == PNamedItem::NET) {
|
||||||
|
cerr << wire->get_fileline() << ": error: Net `"
|
||||||
|
<< wire->basename() << "` can not be of type `"
|
||||||
|
<< sig->data_type() << "`." << endl;
|
||||||
|
des->errors++;
|
||||||
|
} else if (scope->type() == NetScope::MODULE &&
|
||||||
|
sig->port_type() != NetNet::NOT_A_PORT) {
|
||||||
|
// Module ports only support wire types a the moment
|
||||||
|
cerr << wire->get_fileline() << ": sorry: Port `"
|
||||||
|
<< wire->basename() << "` of module `"
|
||||||
|
<< scope->module_name()
|
||||||
|
<< "` with type `" << sig->data_type()
|
||||||
|
<< "` is not supported."
|
||||||
|
<< endl;
|
||||||
|
des->errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_check_port_type(Design*des, NetScope*scope,
|
||||||
|
PWire *wire, NetNet *sig)
|
||||||
|
{
|
||||||
|
if (sig->port_type() == NetNet::PREF) {
|
||||||
|
cerr << wire->get_fileline() << ": sorry: "
|
||||||
|
<< "Reference ports not supported yet." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some extra checks for module ports
|
||||||
|
if (scope->type() != NetScope::MODULE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If the signal is an input and is also declared as a
|
||||||
|
reg, then report an error. */
|
||||||
|
|
||||||
|
if (sig->port_type() == NetNet::PINPUT &&
|
||||||
|
sig->type() == NetNet::REG) {
|
||||||
|
cerr << wire->get_fileline() << ": error: Port `"
|
||||||
|
<< wire->basename() << "` of module `"
|
||||||
|
<< scope->module_name()
|
||||||
|
<< "` is declared as input and as a reg type." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sig->port_type() == NetNet::PINOUT &&
|
||||||
|
sig->type() == NetNet::REG) {
|
||||||
|
cerr << wire->get_fileline() << ": error: Port `"
|
||||||
|
<< wire->basename() << "` of module `"
|
||||||
|
<< scope->module_name()
|
||||||
|
<< "` is declared as inout and as a reg type." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sig->port_type() == NetNet::PINOUT &&
|
||||||
|
sig->data_type() == IVL_VT_REAL) {
|
||||||
|
cerr << wire->get_fileline() << ": error: Port `"
|
||||||
|
<< wire->basename() << "` of module `"
|
||||||
|
<< scope->module_name()
|
||||||
|
<< "` is declared as a real inout port." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
|
bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
bool flag = true;
|
bool flag = true;
|
||||||
|
|
@ -100,53 +184,11 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
|
||||||
PWire*cur = (*wt).second;
|
PWire*cur = (*wt).second;
|
||||||
NetNet*sig = cur->elaborate_sig(des, scope);
|
NetNet*sig = cur->elaborate_sig(des, scope);
|
||||||
|
|
||||||
if (sig && (sig->scope() == scope)
|
if (!sig || sig->scope() != scope)
|
||||||
&& (sig->port_type() == NetNet::PREF)) {
|
continue;
|
||||||
|
|
||||||
cerr << cur->get_fileline() << ": sorry: "
|
sig_check_data_type(des, scope, cur, sig);
|
||||||
<< "Reference ports not supported yet." << endl;
|
sig_check_port_type(des, scope, cur, sig);
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If the signal is an input and is also declared as a
|
|
||||||
reg, then report an error. */
|
|
||||||
|
|
||||||
if (sig && (sig->scope() == scope)
|
|
||||||
&& (scope->type() == NetScope::MODULE)
|
|
||||||
&& (sig->port_type() == NetNet::PINPUT)
|
|
||||||
&& (sig->type() == NetNet::REG)) {
|
|
||||||
|
|
||||||
cerr << cur->get_fileline() << ": error: Port "
|
|
||||||
<< cur->basename() << " of module "
|
|
||||||
<< scope->module_name()
|
|
||||||
<< " is declared as input and as a reg type." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sig && (sig->scope() == scope)
|
|
||||||
&& (scope->type() == NetScope::MODULE)
|
|
||||||
&& (sig->port_type() == NetNet::PINOUT)
|
|
||||||
&& (sig->type() == NetNet::REG)) {
|
|
||||||
|
|
||||||
cerr << cur->get_fileline() << ": error: Port "
|
|
||||||
<< cur->basename() << " of module "
|
|
||||||
<< scope->module_name()
|
|
||||||
<< " is declared as inout and as a reg type." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sig && (sig->scope() == scope)
|
|
||||||
&& (scope->type() == NetScope::MODULE)
|
|
||||||
&& (sig->port_type() == NetNet::PINOUT)
|
|
||||||
&& (sig->data_type() == IVL_VT_REAL)) {
|
|
||||||
|
|
||||||
cerr << cur->get_fileline() << ": error: Port "
|
|
||||||
<< cur->basename() << " of module "
|
|
||||||
<< scope->module_name()
|
|
||||||
<< " is declared as a real inout port." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
./ivltests/pr2976242c.v:43: error: Port out of module io_real_to_vec is declared as a real inout port.
|
./ivltests/pr2976242c.v:43: error: Port `out` of module `io_real_to_vec` is declared as a real inout port.
|
||||||
./ivltests/pr2976242c.v:11: error: Cannot connect an arrayed instance of module vec_to_real to real signal r_vec.
|
./ivltests/pr2976242c.v:11: error: Cannot connect an arrayed instance of module vec_to_real to real signal r_vec.
|
||||||
./ivltests/pr2976242c.v:14: error: When automatically converting a real port of an arrayed instance to a bit signal
|
./ivltests/pr2976242c.v:14: error: When automatically converting a real port of an arrayed instance to a bit signal
|
||||||
./ivltests/pr2976242c.v:14: : the signal width (5) must be an integer multiple of the instance count (2).
|
./ivltests/pr2976242c.v:14: : the signal width (5) must be an integer multiple of the instance count (2).
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Check Verilog types on a module inout port. In Verilog this is an error, but
|
||||||
|
// in SystemVerilog it is supported
|
||||||
|
|
||||||
|
module test (
|
||||||
|
inout reg a,
|
||||||
|
inout time b,
|
||||||
|
inout integer c
|
||||||
|
);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("PASSED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Check Verilog types on a module input port. In Verilog this is an error, but
|
||||||
|
// in SystemVerilog it is supported
|
||||||
|
|
||||||
|
module test (
|
||||||
|
input reg a,
|
||||||
|
input time b,
|
||||||
|
input integer c
|
||||||
|
);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("PASSED");
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
// Check that declaring a net of a class type results in an error
|
||||||
|
|
||||||
|
module test;
|
||||||
|
class C;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
wire C x;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Check that declaring a net of a dynamic array type results in an error
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire x[];
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Check that declaring a net of a queue type results in an error
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire x[$];
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Check that declaring a net of string type results in an error
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
wire string x;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -77,6 +77,8 @@ br_gh25b normal ivltests
|
||||||
br_gh567 normal ivltests
|
br_gh567 normal ivltests
|
||||||
check_constant_3 normal ivltests
|
check_constant_3 normal ivltests
|
||||||
function4 normal ivltests
|
function4 normal ivltests
|
||||||
|
module_inout_port_type normal ivltests
|
||||||
|
module_input_port_type normal ivltests
|
||||||
parameter_in_generate1 normal ivltests
|
parameter_in_generate1 normal ivltests
|
||||||
parameter_no_default normal ivltests
|
parameter_no_default normal ivltests
|
||||||
parameter_omit1 normal ivltests
|
parameter_omit1 normal ivltests
|
||||||
|
|
|
||||||
|
|
@ -318,6 +318,10 @@ named_begin normal,-g2009 ivltests
|
||||||
named_begin_fail CE,-g2009 ivltests
|
named_begin_fail CE,-g2009 ivltests
|
||||||
named_fork normal,-g2009 ivltests
|
named_fork normal,-g2009 ivltests
|
||||||
named_fork_fail CE,-g2009 ivltests
|
named_fork_fail CE,-g2009 ivltests
|
||||||
|
net_class_fail CE,-g2005-sv ivltests
|
||||||
|
net_darray_fail CE,-g2005-sv ivltests
|
||||||
|
net_queue_fail CE,-g2005-sv ivltests
|
||||||
|
net_string_fail CE,-g2005-sv ivltests
|
||||||
packeda normal,-g2009 ivltests
|
packeda normal,-g2009 ivltests
|
||||||
packeda2 normal,-g2009 ivltests
|
packeda2 normal,-g2009 ivltests
|
||||||
parameter_in_generate2 CE,-g2005-sv ivltests
|
parameter_in_generate2 CE,-g2005-sv ivltests
|
||||||
|
|
|
||||||
|
|
@ -644,6 +644,8 @@ mixed_width_case normal ivltests
|
||||||
modparam normal ivltests top # Override parameter via passed down value
|
modparam normal ivltests top # Override parameter via passed down value
|
||||||
module3.12A normal ivltests main
|
module3.12A normal ivltests main
|
||||||
module3.12B normal ivltests
|
module3.12B normal ivltests
|
||||||
|
module_inout_port_type CE ivltests
|
||||||
|
module_input_port_type CE ivltests
|
||||||
module_output_port_var1 normal ivltests
|
module_output_port_var1 normal ivltests
|
||||||
module_output_port_var2 normal ivltests
|
module_output_port_var2 normal ivltests
|
||||||
modulus normal ivltests # wire % and reg % operators
|
modulus normal ivltests # wire % and reg % operators
|
||||||
|
|
|
||||||
48
parse.y
48
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)) {
|
|
||||||
if (dtype->reg_flag)
|
|
||||||
use_type = NetNet::REG;
|
|
||||||
else
|
|
||||||
use_type = NetNet::IMPLICIT_REG;
|
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);
|
||||||
|
|
@ -4891,6 +4860,7 @@ module_item
|
||||||
| attribute_list_opt net_type data_type_or_implicit delay3_opt net_variable_list ';'
|
| attribute_list_opt net_type data_type_or_implicit delay3_opt net_variable_list ';'
|
||||||
|
|
||||||
{ data_type_t*data_type = $3;
|
{ data_type_t*data_type = $3;
|
||||||
|
pform_check_net_data_type(@2, $2, $3);
|
||||||
if (data_type == 0) {
|
if (data_type == 0) {
|
||||||
data_type = new vector_type_t(IVL_VT_LOGIC, false, 0);
|
data_type = new vector_type_t(IVL_VT_LOGIC, false, 0);
|
||||||
FILE_NAME(data_type, @2);
|
FILE_NAME(data_type, @2);
|
||||||
|
|
@ -4925,6 +4895,7 @@ module_item
|
||||||
|
|
||||||
| attribute_list_opt net_type data_type_or_implicit delay3_opt net_decl_assigns ';'
|
| attribute_list_opt net_type data_type_or_implicit delay3_opt net_decl_assigns ';'
|
||||||
{ data_type_t*data_type = $3;
|
{ data_type_t*data_type = $3;
|
||||||
|
pform_check_net_data_type(@2, $2, $3);
|
||||||
if (data_type == 0) {
|
if (data_type == 0) {
|
||||||
data_type = new vector_type_t(IVL_VT_LOGIC, false, 0);
|
data_type = new vector_type_t(IVL_VT_LOGIC, false, 0);
|
||||||
FILE_NAME(data_type, @2);
|
FILE_NAME(data_type, @2);
|
||||||
|
|
@ -4938,6 +4909,7 @@ module_item
|
||||||
|
|
||||||
| attribute_list_opt net_type data_type_or_implicit drive_strength net_decl_assigns ';'
|
| attribute_list_opt net_type data_type_or_implicit drive_strength net_decl_assigns ';'
|
||||||
{ data_type_t*data_type = $3;
|
{ data_type_t*data_type = $3;
|
||||||
|
pform_check_net_data_type(@2, $2, $3);
|
||||||
if (data_type == 0) {
|
if (data_type == 0) {
|
||||||
data_type = new vector_type_t(IVL_VT_LOGIC, false, 0);
|
data_type = new vector_type_t(IVL_VT_LOGIC, false, 0);
|
||||||
FILE_NAME(data_type, @2);
|
FILE_NAME(data_type, @2);
|
||||||
|
|
@ -5006,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;
|
||||||
|
|
||||||
|
|
|
||||||
36
pform.cc
36
pform.cc
|
|
@ -2634,6 +2634,8 @@ void pform_module_define_port(const struct vlltype&li,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pform_check_net_data_type(li, type, vtype);
|
||||||
|
|
||||||
// Packed ranges
|
// Packed ranges
|
||||||
list<pform_range_t>*prange = 0;
|
list<pform_range_t>*prange = 0;
|
||||||
// Unpacked dimensions
|
// Unpacked dimensions
|
||||||
|
|
@ -2650,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;
|
||||||
|
|
@ -3748,6 +3747,37 @@ bool pform_requires_sv(const struct vlltype&loc, const char *feature)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pform_check_net_data_type(const struct vlltype&loc, NetNet::Type net_type,
|
||||||
|
const data_type_t *data_type)
|
||||||
|
{
|
||||||
|
// For SystemVerilog the type is checked during elaboration since due to
|
||||||
|
// forward typedefs and type parameters the actual type might not be known
|
||||||
|
// yet.
|
||||||
|
if (gn_system_verilog())
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (net_type) {
|
||||||
|
case NetNet::REG:
|
||||||
|
case NetNet::IMPLICIT_REG:
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data_type)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const vector_type_t*vec_type = dynamic_cast<const vector_type_t*>(data_type);
|
||||||
|
if (vec_type && vec_type->implicit_flag)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const real_type_t*rtype = dynamic_cast<const real_type_t*>(data_type);
|
||||||
|
if (rtype && rtype->type_code() == real_type_t::REAL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pform_requires_sv(loc, "Net data type");
|
||||||
|
}
|
||||||
|
|
||||||
FILE*vl_input = 0;
|
FILE*vl_input = 0;
|
||||||
extern void reset_lexor();
|
extern void reset_lexor();
|
||||||
|
|
||||||
|
|
|
||||||
3
pform.h
3
pform.h
|
|
@ -587,4 +587,7 @@ bool pform_requires_sv(const struct vlltype&loc, const char *feature);
|
||||||
void pform_start_parameter_port_list();
|
void pform_start_parameter_port_list();
|
||||||
void pform_end_parameter_port_list();
|
void pform_end_parameter_port_list();
|
||||||
|
|
||||||
|
void pform_check_net_data_type(const struct vlltype&loc, NetNet::Type net_type,
|
||||||
|
const data_type_t *data_type);
|
||||||
|
|
||||||
#endif /* IVL_pform_H */
|
#endif /* IVL_pform_H */
|
||||||
|
|
|
||||||
|
|
@ -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