Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SystemVerilog: type parameters #464

Merged
merged 1 commit into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions regression/verilog/modules/type_parameters1.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CORE
type_parameters1.sv
--bound 0
^\[main\.property\.p1\] always 1 == 1: PROVED up to bound 0$
^\[main\.property\.p2\] always 32 == 32: PROVED up to bound 0$
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
9 changes: 9 additions & 0 deletions regression/verilog/modules/type_parameters1.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module main;

parameter type T1 = bit;
localparam type T2 = bit [31:0];

p1: assert property ($bits(T1) == 1);
p2: assert property ($bits(T2) == 32);

endmodule
23 changes: 23 additions & 0 deletions src/verilog/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -1040,13 +1040,21 @@ local_parameter_declaration:
{ init($$, ID_local_parameter_decl);
stack_expr($$).type() = std::move(stack_type($2));
swapop($$, $3); }
| TOK_LOCALPARAM TOK_TYPE list_of_type_assignments
{ init($$, ID_local_parameter_decl);
stack_expr($$).type() = typet(ID_type);
swapop($$, $3); }
;

parameter_declaration:
TOK_PARAMETER data_type_or_implicit list_of_param_assignments
{ init($$, ID_parameter_decl);
stack_expr($$).type() = std::move(stack_type($2));
swapop($$, $3); }
| TOK_PARAMETER TOK_TYPE list_of_type_assignments
{ init($$, ID_parameter_decl);
stack_expr($$).type() = typet(ID_type);
swapop($$, $3); }
;

specparam_declaration:
Expand Down Expand Up @@ -1585,6 +1593,21 @@ param_assignment: param_identifier '=' constant_param_expression
addswap($$, ID_value, $3); }
;

list_of_type_assignments:
type_assignment
{ init($$); mto($$, $1); }
| list_of_type_assignments ',' type_assignment
{ $$=$1; mto($$, $3); }
;

type_assignment: param_identifier '=' data_type
{ init($$, ID_parameter);
auto base_name = stack_expr($1).id();
stack_expr($$).set(ID_identifier, base_name);
stack_expr($$).set(ID_base_name, base_name);
addswap($$, ID_type, $3); }
;

data_type_or_implicit:
data_type
| implicit_data_type
Expand Down
44 changes: 32 additions & 12 deletions src/verilog/verilog_elaborate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,42 @@ void verilog_typecheckt::collect_symbols(

auto full_identifier = hierarchical_identifier(base_name);

// If there's no type, parameters take the type of the
// value. We signal this using the special type "derive_from_value".
// Is this a type or a value parameter?
if(type.id() == ID_type)
{
// much like a typedef
auto symbol_type = to_be_elaborated_typet{declarator.type()};

auto symbol_type =
to_be_elaborated_typet(type.is_nil() ? derive_from_value_typet() : type);
type_symbolt symbol{full_identifier, symbol_type, mode};

symbolt symbol{full_identifier, symbol_type, mode};
symbol.module = module_identifier;
symbol.base_name = base_name;
symbol.pretty_name = strip_verilog_prefix(symbol.name);
symbol.is_macro = true;
symbol.value = nil_exprt{};
symbol.location = declarator.source_location();

add_symbol(std::move(symbol));
}
else // It's a value parameter.
{
// If there's no type, parameters take the type of the
// value. We signal this using the special type "derive_from_value".

symbol.module = module_identifier;
symbol.base_name = base_name;
symbol.pretty_name = strip_verilog_prefix(symbol.name);
symbol.is_macro = true;
symbol.value = declarator.value();
symbol.location = declarator.source_location();
auto symbol_type =
to_be_elaborated_typet(type.is_nil() ? derive_from_value_typet() : type);

add_symbol(std::move(symbol));
symbolt symbol{full_identifier, symbol_type, mode};

symbol.module = module_identifier;
symbol.base_name = base_name;
symbol.pretty_name = strip_verilog_prefix(symbol.name);
symbol.is_macro = true;
symbol.value = declarator.value();
symbol.location = declarator.source_location();

add_symbol(std::move(symbol));
}
}

void verilog_typecheckt::collect_symbols(const typet &type)
Expand Down
4 changes: 4 additions & 0 deletions src/verilog/verilog_typecheck_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,10 @@ typet verilog_typecheck_exprt::convert_type(const typet &src)
return struct_union_typet{src.id(), std::move(components)}
.with_source_location(src.source_location());
}
else if(src.id() == ID_type)
{
return src;
}
else
{
throw errort().with_location(source_location)
Expand Down