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: package scope operator #925

Merged
merged 1 commit into from
Jan 13, 2025
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
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* SystemVerilog: $bitstoreal/$bitstoshortreal, $realtobits/$shortrealtobits
* SystemVerilog: $itor, $rtoi
* SystemVerilog: chandle, event
* SystemVerilog: package scope operator

# EBMC 5.4

Expand Down
7 changes: 7 additions & 0 deletions regression/verilog/packages/package2.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CORE
package2.sv

^^\[.*\] always main\.Q == 123: PROVED$
^EXIT=0$
^SIGNAL=0$
--
15 changes: 15 additions & 0 deletions regression/verilog/packages/package2.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package moo;

parameter P = 123;

endpackage

module main;

import moo::*;

parameter Q = moo::P;

assert final (Q == 123);

endmodule
8 changes: 8 additions & 0 deletions regression/verilog/packages/package_enum1.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
KNOWNBUG
package_enum1.sv

^EXIT=0$
^SIGNAL=0$
--
--
Support for enums in packages is missing.
13 changes: 13 additions & 0 deletions regression/verilog/packages/package_enum1.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package moo;

typedef enum { RED, GREEN } my_type;

endpackage

module main;

import moo::*;

assert final (moo::GREEN == 1);

endmodule
8 changes: 8 additions & 0 deletions regression/verilog/packages/package_typedef1.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
KNOWNBUG
package_typedef1.sv

^EXIT=0$
^SIGNAL=0$
--
--
Support for typedefs in packages is missing.
15 changes: 15 additions & 0 deletions regression/verilog/packages/package_typedef1.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package moo;

typedef byte my_type;

endpackage

module main;

import moo::*;

moo::my_type some_var;

assert final ($typename(some_var) == "byte");

endmodule
1 change: 1 addition & 0 deletions src/hw_cbmc_irep_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ IREP_ID_ONE(verilog_class)
IREP_ID_ONE(verilog_module)
IREP_ID_ONE(verilog_package)
IREP_ID_ONE(verilog_package_import)
IREP_ID_ONE(verilog_package_scope)
IREP_ID_ONE(verilog_program)
IREP_ID_ONE(verilog_udp)
IREP_ID_ONE(module_source)
Expand Down
15 changes: 13 additions & 2 deletions src/verilog/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -1355,9 +1355,13 @@ package_import_item_brace:

package_import_item:
package_identifier "::" identifier
{ init($$, ID_verilog_import_item); mto($$, $1); mto($$, $3); }
{ init($$, ID_verilog_import_item);
stack_expr($$).set(ID_verilog_package, stack_expr($1).id());
stack_expr($$).set(ID_identifier, stack_expr($3).id()); }
| package_identifier "::" "*"
{ init($$, ID_verilog_import_item); mto($$, $1); }
{ init($$, ID_verilog_import_item);
stack_expr($$).set(ID_verilog_package, stack_expr($1).id());
stack_expr($$).set(ID_identifier, "*"); }
;

genvar_declaration:
Expand Down Expand Up @@ -4032,6 +4036,10 @@ part_select_range:

primary: primary_literal
| hierarchical_identifier_select
| package_scope hierarchical_identifier_select
{ init($$, ID_verilog_package_scope);
mto($$, $1);
mto($$, $2); }
| concatenation
| multiple_concatenation
| function_subroutine_call
Expand Down Expand Up @@ -4209,6 +4217,9 @@ net_identifier: identifier;

package_identifier: TOK_NON_TYPE_IDENTIFIER;

package_scope: package_identifier "::"
;

param_identifier: TOK_NON_TYPE_IDENTIFIER;

port_identifier: identifier;
Expand Down
8 changes: 8 additions & 0 deletions src/verilog/verilog_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ static void dependencies_rec(
{
dependencies_rec(to_verilog_generate_for(module_item).body(), dest);
}
else if(module_item.id() == ID_verilog_package_import)
{
for(auto &import_item : module_item.get_sub())
{
dest.push_back(
verilog_package_identifier(import_item.get(ID_verilog_package)));
}
}
}

std::vector<irep_idt> verilog_item_containert::dependencies() const
Expand Down
2 changes: 1 addition & 1 deletion src/verilog/verilog_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ void verilog_languaget::dependencies(
std::set<std::string> &dependency_set)
{
verilog_parse_treet::item_mapt::const_iterator it =
parse_tree.item_map.find(id2string(verilog_module_name(module)));
parse_tree.item_map.find(id2string(verilog_item_key(module)));

if(it != parse_tree.item_map.end())
{
Expand Down
7 changes: 7 additions & 0 deletions src/verilog/verilog_parse_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,15 @@ void verilog_parse_treet::modules_provided(
for(auto &item : items)
{
if(item.id() == ID_verilog_module)
{
module_set.insert(id2string(
verilog_module_symbol(to_verilog_module_source(item).base_name())));
}
else if(item.id() == ID_verilog_package)
{
module_set.insert(id2string(verilog_package_identifier(
to_verilog_module_source(item).base_name())));
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/verilog/verilog_parse_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class verilog_parse_treet

// An index into the items list.
// The key is
// package::name for pagages
// package::name for packages
// name for modules, etc.
// as packages have a separate name space (1800-2017 3.13).
typedef std::
Expand Down
48 changes: 12 additions & 36 deletions src/verilog/verilog_typecheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1947,55 +1947,27 @@ Function: verilog_typecheck
bool verilog_typecheck(
const verilog_parse_treet &parse_tree,
symbol_table_baset &symbol_table,
const std::string &module,
const irep_idt &module_identifier,
bool warn_implicit_nets,
message_handlert &message_handler)
{
verilog_parse_treet::item_mapt::const_iterator it =
parse_tree.item_map.find(id2string(verilog_module_name(module)));
parse_tree.item_map.find(id2string(verilog_item_key(module_identifier)));

if(it == parse_tree.item_map.end())
{
messaget message(message_handler);
message.error() << "module `" << module
<< "' not found" << messaget::eom;
message.error() << "module `" << module_identifier << "' not found"
<< messaget::eom;
return true;
}

auto &module_source = to_verilog_module_source(*it->second);

return verilog_typecheck(
symbol_table,
module_source,
parse_tree.standard,
warn_implicit_nets,
message_handler);
}

/*******************************************************************\
Function: verilog_typecheck
Inputs:
Outputs:
Purpose:
\*******************************************************************/

bool verilog_typecheck(
symbol_table_baset &symbol_table,
const verilog_module_sourcet &verilog_module_source,
verilog_standardt standard,
bool warn_implicit_nets,
message_handlert &message_handler)
{
// create symbol
auto &verilog_module_source = to_verilog_module_source(*it->second);

// create the symbol
irep_idt base_name = verilog_module_source.base_name();

symbolt symbol{verilog_module_symbol(base_name), module_typet{}, ID_Verilog};
symbolt symbol{module_identifier, module_typet{}, ID_Verilog};

symbol.base_name = base_name;
symbol.pretty_name = base_name;
Expand All @@ -2017,7 +1989,11 @@ bool verilog_typecheck(
}

verilog_typecheckt verilog_typecheck(
standard, warn_implicit_nets, *new_symbol, symbol_table, message_handler);
parse_tree.standard,
warn_implicit_nets,
*new_symbol,
symbol_table,
message_handler);

return verilog_typecheck.typecheck_main();
}
12 changes: 2 additions & 10 deletions src/verilog/verilog_typecheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,13 @@ Author: Daniel Kroening, [email protected]
bool verilog_typecheck(
const verilog_parse_treet &parse_tree,
symbol_table_baset &,
const std::string &module,
const irep_idt &module_identifier,
bool warn_implicit_nets,
message_handlert &message_handler);

bool verilog_typecheck(
symbol_table_baset &,
const verilog_module_sourcet &verilog_module_source,
verilog_standardt,
bool warn_implicit_nets,
message_handlert &message_handler);

bool verilog_typecheck(
symbol_table_baset &,
const std::string &module_identifier,
verilog_standardt,
const irep_idt &module_identifier,
const exprt::operandst &parameters,
message_handlert &message_handler);

Expand Down
23 changes: 21 additions & 2 deletions src/verilog/verilog_typecheck_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,25 @@ irep_idt verilog_module_symbol(const irep_idt &base_name)

/*******************************************************************\
Function: verilog_package_identifier
Inputs:
Outputs:
Purpose:
\*******************************************************************/

irep_idt verilog_package_identifier(const irep_idt &base_name)
{
// Packages and modules have separate name spaces,
// hence the prefix.
return "Verilog::package::" + id2string(base_name);
}

/*******************************************************************\
Function: strip_verilog_prefix
Inputs:
Expand All @@ -58,7 +77,7 @@ irep_idt strip_verilog_prefix(const irep_idt &identifier)

/*******************************************************************\
Function: verilog_module_name
Function: verilog_item_key
Inputs:
Expand All @@ -68,7 +87,7 @@ Function: verilog_module_name
\*******************************************************************/

irep_idt verilog_module_name(const irep_idt &identifier)
irep_idt verilog_item_key(const irep_idt &identifier)
{
return strip_verilog_prefix(identifier);
}
Expand Down
3 changes: 2 additions & 1 deletion src/verilog/verilog_typecheck_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ Author: Daniel Kroening, [email protected]
#include "verilog_standard.h"

irep_idt verilog_module_symbol(const irep_idt &base_name);
irep_idt verilog_module_name(const irep_idt &identifier);
irep_idt verilog_package_identifier(const irep_idt &base_name);
irep_idt verilog_item_key(const irep_idt &identifier);
irep_idt strip_verilog_prefix(const irep_idt &identifier);

class array_typet;
Expand Down
28 changes: 28 additions & 0 deletions src/verilog/verilog_typecheck_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2790,6 +2790,34 @@ exprt verilog_typecheck_exprt::convert_binary_expr(binary_exprt expr)
{
if(expr.id() == ID_verilog_bit_select)
return convert_bit_select_expr(to_binary_expr(expr));
else if(expr.id() == ID_verilog_package_scope)
{
auto location = expr.source_location();

if(expr.rhs().id() != ID_symbol)
throw errort().with_location(location)
<< expr.id() << " expects symbol on the rhs";

auto package_base = expr.lhs().id();
auto rhs_base = expr.rhs().get(ID_base_name);

// stitch together
irep_idt full_identifier =
id2string(verilog_package_identifier(expr.lhs().id())) + '.' +
id2string(rhs_base);

const symbolt *symbol;
if(ns.lookup(full_identifier, symbol))
{
throw errort().with_location(location)
<< "identifier " << rhs_base << " not found in package "
<< package_base;
}

// found!
return symbol_exprt{full_identifier, symbol->type}.with_source_location(
location);
}
else if(expr.id()==ID_replication)
return convert_replication_expr(to_replication_expr(expr));
else if(expr.id() == ID_and || expr.id() == ID_or)
Expand Down
Loading