Skip to content

Commit 1940921

Browse files
committed
SystemVerilog .* wildcard port connections
SystemVerilog 1800-2005 has introduced the .* operator, used for a) wildcard port connections (23.3.2.4), and b) wildcard patterns (12.6). This adds support to the scanner, parser, and type checker for wildcard port connections.
1 parent a9a9214 commit 1940921

File tree

8 files changed

+68
-8
lines changed

8 files changed

+68
-8
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Verilog: $isunknown
88
* SystemVerilog: fix for #-# and #=# for empty matches
99
* SystemVerilog: fix for |-> and |=> for empty matches
10+
* SystemVerilog: support 1800-2005 .* wildcard port connections
1011
* LTL/SVA to Buechi with --buechi
1112
* SMV: abs, bool, count, max, min, toint, word1
1213
* BMC: new encoding for F, avoiding spurious traces
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
wildcard_port_connection1.sv
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module M(input a, b);
2+
assert final (a);
3+
assert final (!b);
4+
endmodule
5+
6+
module main;
7+
wire a = 0, b = 1;
8+
M m(.*);
9+
endmodule

src/hw_cbmc_irep_ids.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ IREP_ID_ONE(verilog_always)
214214
IREP_ID_ONE(verilog_always_comb)
215215
IREP_ID_ONE(verilog_always_ff)
216216
IREP_ID_ONE(verilog_always_latch)
217-
IREP_ID_ONE(named_port_connection)
217+
IREP_ID_ONE(verilog_named_port_connection)
218+
IREP_ID_ONE(verilog_wildcard_port_connection)
218219
IREP_ID_ONE(verilog_final)
219220
IREP_ID_ONE(initial)
220221
IREP_ID_ONE(verilog_label_statement)

src/verilog/parser.y

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ int yyverilogerror(const char *error)
405405
%token TOK_LSQPLUS "[+"
406406
%token TOK_LSQEQUAL "[="
407407
%token TOK_LSQMINUSGREATER "[->"
408+
%token TOK_DOTASTERIC ".*"
408409

409410
/* System Verilog Keywords */
410411
%token TOK_ACCEPT_ON "accept_on"
@@ -3100,9 +3101,10 @@ named_port_connection_brace:
31003101

31013102
named_port_connection:
31023103
'.' port_identifier '(' expression_opt ')'
3103-
{ init($$, ID_named_port_connection);
3104+
{ init($$, ID_verilog_named_port_connection);
31043105
mto($$, $2);
31053106
mto($$, $4); }
3107+
| ".*" { init($$, ID_verilog_wildcard_port_connection); }
31063108
;
31073109

31083110
// System Verilog standard 1800-2017
@@ -3736,6 +3738,26 @@ open_value_range: value_range;
37363738
// System Verilog standard 1800-2017
37373739
// A.6.7.1 Patterns
37383740

3741+
pattern:
3742+
"." variable_identifier
3743+
| ".*"
3744+
| constant_expression
3745+
| "tagged" member_identifier
3746+
| "tagged" member_identifier pattern
3747+
| "'{" pattern_list "}"
3748+
| "'{" member_pattern_list "}"
3749+
;
3750+
3751+
pattern_list:
3752+
pattern
3753+
| pattern_list "," pattern
3754+
;
3755+
3756+
member_pattern_list:
3757+
member_identifier ":" pattern
3758+
| member_pattern_list "," member_identifier ":" pattern
3759+
;
3760+
37393761
assignment_pattern:
37403762
'\'' '{' expression_brace '}'
37413763
{ init($$, ID_verilog_assignment_pattern); swapop($$, $3); }

src/verilog/scanner.l

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ void verilog_scanner_init()
273273
"[+" { SYSTEM_VERILOG_OPERATOR(TOK_LSQPLUS, "[+"); }
274274
"[=" { SYSTEM_VERILOG_OPERATOR(TOK_LSQEQUAL, "[="); }
275275
"[->" { SYSTEM_VERILOG_OPERATOR(TOK_LSQMINUSGREATER, "[->"); }
276+
/* port connections, patterns */
277+
".*" { SYSTEM_VERILOG_OPERATOR(TOK_DOTASTERIC, ".*"); }
276278

277279
/* Verilog 1364-1995 keywords */
278280

src/verilog/verilog_expr.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ class verilog_inst_baset : public verilog_module_itemt
799799
named_port_connectiont(exprt _port, exprt _value)
800800
: binary_exprt(
801801
std::move(_port),
802-
ID_named_port_connection,
802+
ID_verilog_named_port_connection,
803803
std::move(_value),
804804
typet{})
805805
{
@@ -863,7 +863,8 @@ class verilog_inst_baset : public verilog_module_itemt
863863
{
864864
auto &connections = this->connections();
865865
return connections.empty() ||
866-
connections.front().id() == ID_named_port_connection;
866+
(connections.front().id() == ID_verilog_named_port_connection ||
867+
connections.front().id() == ID_verilog_wildcard_port_connection);
867868
}
868869

869870
protected:
@@ -889,15 +890,15 @@ class verilog_inst_baset : public verilog_module_itemt
889890
inline const verilog_inst_baset::named_port_connectiont &
890891
to_verilog_named_port_connection(const exprt &expr)
891892
{
892-
PRECONDITION(expr.id() == ID_named_port_connection);
893+
PRECONDITION(expr.id() == ID_verilog_named_port_connection);
893894
verilog_inst_baset::named_port_connectiont::check(expr);
894895
return static_cast<const verilog_inst_baset::named_port_connectiont &>(expr);
895896
}
896897

897898
inline verilog_inst_baset::named_port_connectiont &
898899
to_verilog_named_port_connection(exprt &expr)
899900
{
900-
PRECONDITION(expr.id() == ID_named_port_connection);
901+
PRECONDITION(expr.id() == ID_verilog_named_port_connection);
901902
verilog_inst_baset::named_port_connectiont::check(expr);
902903
return static_cast<verilog_inst_baset::named_port_connectiont &>(expr);
903904
}

src/verilog/verilog_typecheck.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,27 @@ void verilog_typecheckt::typecheck_port_connections(
115115
// We don't require that all ports are connected.
116116

117117
std::set<irep_idt> assigned_ports;
118+
bool wildcard = false;
118119

119120
for(auto &connection : inst.connections())
120121
{
121-
if(connection.id() != ID_named_port_connection)
122+
if(connection.id() == ID_verilog_wildcard_port_connection)
123+
{
124+
// .*
125+
if(wildcard)
126+
{
127+
// .* can only be given once
128+
throw errort{}.with_location(connection.source_location())
129+
<< "wildcard connection given more than once";
130+
}
131+
else
132+
{
133+
wildcard = true;
134+
continue;
135+
}
136+
}
137+
138+
if(connection.id() != ID_verilog_named_port_connection)
122139
{
123140
throw errort().with_location(inst.source_location())
124141
<< "expected a named port connection";
@@ -165,7 +182,7 @@ void verilog_typecheckt::typecheck_port_connections(
165182
assigned_ports.insert(identifier);
166183
}
167184
}
168-
else // just a list without names
185+
else // Positional connections, i.e., just a list without port names
169186
{
170187
if(inst.connections().size() != ports.size())
171188
{

0 commit comments

Comments
 (0)