Skip to content

Commit

Permalink
Verilog: parse tree now stores package_items
Browse files Browse the repository at this point in the history
SystemVerilog allows any package_item at the top level of the file.  This
extends the parse tree to store these, generalising from typedefs, which are
package_items.
  • Loading branch information
kroening committed Mar 5, 2024
1 parent 362a6f7 commit 4a45806
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 30 deletions.
1 change: 1 addition & 0 deletions src/verilog/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,7 @@ description:
| program_declaration
| package_declaration
| attribute_instance_brace package_item
{ PARSER.parse_tree.create_package_item(stack_expr($2)); }
| attribute_instance_brace bind_directive
| config_declaration
;
Expand Down
9 changes: 9 additions & 0 deletions src/verilog/verilog_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,15 @@ bool verilog_languaget::typecheck(
{
if(module=="") return false;

if(!top_scope_package_items_done)
{
// Verilog allows 'package items' at the top-level scope,
// outside of a module. These only need to be done once.
top_scope_package_items_done = true;
if(verilog_typecheck_package_items(parse_tree, symbol_table, message_handler))
return true;
}

if(verilog_typecheck(parse_tree, symbol_table, module, message_handler))
return true;

Expand Down
1 change: 1 addition & 0 deletions src/verilog/verilog_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class verilog_languaget:public languaget

protected:
verilog_parse_treet parse_tree;
bool top_scope_package_items_done = false;
};

std::unique_ptr<languaget> new_verilog_language();
Expand Down
11 changes: 5 additions & 6 deletions src/verilog/verilog_parse_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ void verilog_parse_treet::create_module(
exprt &ports,
exprt &module_items)
{
items.push_back(itemt());
items.push_back(itemt(itemt::MODULE));
itemt &item=items.back();

item.type=itemt::MODULE;

verilog_modulet &new_module=item.verilog_module;

Expand Down Expand Up @@ -135,9 +133,10 @@ void verilog_parse_treet::itemt::show(std::ostream &out) const
case itemt::MODULE:
verilog_module.show(out);
break;

case itemt::TYPEDEF:
verilog_typedef.show(out);

case itemt::PACKAGE_ITEM:
out << "Package item:\n";
out << verilog_package_item.pretty() << '\n';
break;

default:
Expand Down
41 changes: 17 additions & 24 deletions src/verilog/verilog_parse_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,32 @@ Author: Daniel Kroening, kroening@kroening.com
class verilog_parse_treet
{
public:
class verilog_typedeft
struct itemt
{
public:
typet symbol;
typet type;

void show(std::ostream &out) const
typedef enum
{
MODULE,
PACKAGE_ITEM
} item_typet;
item_typet type;

explicit itemt(item_typet __type) : type(__type)
{
out << "Typedef:\n";
out << "\n";
}
};

struct itemt
{
public:
typedef enum { MODULE, TYPEDEF } item_typet;
item_typet type;

verilog_modulet verilog_module;
verilog_typedeft verilog_typedef;

exprt verilog_package_item;

bool is_module() const
{
return type==MODULE;
}

bool is_typedef() const
bool is_package_item() const
{
return type==TYPEDEF;
return type == PACKAGE_ITEM;
}

void show(std::ostream &out) const;
Expand Down Expand Up @@ -80,12 +75,10 @@ class verilog_parse_treet
exprt &ports,
exprt &statements);

void create_typedef(irept &declaration)
void create_package_item(exprt package_item)
{
items.push_back(itemt());
items.back().type=itemt::TYPEDEF;
items.back().verilog_typedef.symbol.swap(declaration.get_sub()[0]);
items.back().verilog_typedef.type.swap(declaration.add(ID_type));
items.push_back(itemt(itemt::PACKAGE_ITEM));
items.back().verilog_package_item = std::move(package_item);
}

void swap(verilog_parse_treet &parse_tree)
Expand Down
57 changes: 57 additions & 0 deletions src/verilog/verilog_typecheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1753,3 +1753,60 @@ bool verilog_typecheck(
verilog_typecheckt verilog_typecheck(*new_symbol, symbol_table, message_handler);
return verilog_typecheck.typecheck_main();
}

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

bool verilog_typecheck_package_items(
const verilog_parse_treet &parse_tree,
symbol_table_baset &symbol_table,
message_handlert &message_handler)
{
for(auto &item : parse_tree.items)
if(item.is_package_item())
{
// These might be typedefs, with enums

#if 0
// create symbol
symbolt symbol;

symbol.mode=ID_Verilog;
symbol.base_name=verilog_module.name;
symbol.type=module_typet();
symbol.name=verilog_module_symbol(verilog_module.name);
symbol.base_name=verilog_module.name;
symbol.pretty_name=verilog_module.name;
symbol.module=symbol.name;
symbol.location=verilog_module.location;

symbol.type.add(ID_module_source)=verilog_module.to_irep();

// put symbol into symbol_table
symbolt *new_symbol;

if(symbol_table.move(symbol, new_symbol))
{
messaget message(message_handler);
message.error() << "duplicate definition of "
<< symbol.base_name << messaget::eom;
return true;
}

verilog_typecheckt verilog_typecheck(*new_symbol, symbol_table, message_handler);

return verilog_typecheck.typecheck_main();
#endif
}

return false;
}
5 changes: 5 additions & 0 deletions src/verilog/verilog_typecheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ Author: Daniel Kroening, kroening@kroening.com
#include "verilog_symbol_table.h"
#include "verilog_typecheck_expr.h"

bool verilog_typecheck_package_items(
const verilog_parse_treet &,
symbol_table_baset &,
message_handlert &);

bool verilog_typecheck(
const verilog_parse_treet &parse_tree,
symbol_table_baset &,
Expand Down

0 comments on commit 4a45806

Please sign in to comment.