Skip to content

Commit eb60dae

Browse files
committed
SystemVerilog .*
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.
1 parent e281a3d commit eb60dae

File tree

9 files changed

+83
-10
lines changed

9 files changed

+83
-10
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Verilog: $onehot and $onehot0 are now elaboration-time constant
66
* SystemVerilog: fix for #-# and #=# for empty matches
77
* SystemVerilog: fix for |-> and |=> for empty matches
8+
* SystemVerilog: support 1800-2005 .*
89
* LTL/SVA to Buechi with --buechi
910
* SMV: abs, bool, count, max, min, toint, word1
1011
* 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
@@ -212,7 +212,8 @@ IREP_ID_ONE(verilog_always)
212212
IREP_ID_ONE(verilog_always_comb)
213213
IREP_ID_ONE(verilog_always_ff)
214214
IREP_ID_ONE(verilog_always_latch)
215-
IREP_ID_ONE(named_port_connection)
215+
IREP_ID_ONE(verilog_named_port_connection)
216+
IREP_ID_ONE(verilog_wildcard_port_connection)
216217
IREP_ID_ONE(verilog_final)
217218
IREP_ID_ONE(initial)
218219
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"
@@ -3101,9 +3102,10 @@ named_port_connection_brace:
31013102

31023103
named_port_connection:
31033104
'.' port_identifier '(' expression_opt ')'
3104-
{ init($$, ID_named_port_connection);
3105+
{ init($$, ID_verilog_named_port_connection);
31053106
mto($$, $2);
31063107
mto($$, $4); }
3108+
| ".*" { init($$, ID_verilog_wildcard_port_connection); }
31073109
;
31083110

31093111
// System Verilog standard 1800-2017
@@ -3737,6 +3739,26 @@ open_value_range: value_range;
37373739
// System Verilog standard 1800-2017
37383740
// A.6.7.1 Patterns
37393741

3742+
pattern:
3743+
"." variable_identifier
3744+
| ".*"
3745+
| constant_expression
3746+
| "tagged" member_identifier
3747+
| "tagged" member_identifier pattern
3748+
| "'{" pattern_list "}"
3749+
| "'{" member_pattern_list "}"
3750+
;
3751+
3752+
pattern_list:
3753+
pattern
3754+
| pattern_list "," pattern
3755+
;
3756+
3757+
member_pattern_list:
3758+
member_identifier ":" pattern
3759+
| member_pattern_list "," member_identifier ":" pattern
3760+
;
3761+
37403762
assignment_pattern:
37413763
'\'' '{' expression_brace '}'
37423764
{ 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: 16 additions & 3 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
{
@@ -854,6 +854,19 @@ class verilog_inst_baset : public verilog_module_itemt
854854
return operands();
855855
}
856856

857+
bool positional_connections() const
858+
{
859+
auto &connections = this->connections();
860+
return connections.empty() ||
861+
connections.front().id() == ID_verilog_named_port_connection ||
862+
connections.front().id() == ID_verilog_wildcard_port_connection;
863+
}
864+
865+
bool named_connections() const
866+
{
867+
return !positional_connections();
868+
}
869+
857870
protected:
858871
using exprt::operands;
859872
};
@@ -877,15 +890,15 @@ class verilog_inst_baset : public verilog_module_itemt
877890
inline const verilog_inst_baset::named_port_connectiont &
878891
to_verilog_named_port_connection(const exprt &expr)
879892
{
880-
PRECONDITION(expr.id() == ID_named_port_connection);
893+
PRECONDITION(expr.id() == ID_verilog_named_port_connection);
881894
verilog_inst_baset::named_port_connectiont::check(expr);
882895
return static_cast<const verilog_inst_baset::named_port_connectiont &>(expr);
883896
}
884897

885898
inline verilog_inst_baset::named_port_connectiont &
886899
to_verilog_named_port_connection(exprt &expr)
887900
{
888-
PRECONDITION(expr.id() == ID_named_port_connection);
901+
PRECONDITION(expr.id() == ID_verilog_named_port_connection);
889902
verilog_inst_baset::named_port_connectiont::check(expr);
890903
return static_cast<verilog_inst_baset::named_port_connectiont &>(expr);
891904
}

src/verilog/verilog_synthesis.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1386,7 +1386,9 @@ void verilog_synthesist::instantiate_ports(
13861386

13871387
// named port connection?
13881388

1389-
if(to_multi_ary_expr(inst).op0().id() == ID_named_port_connection)
1389+
if(
1390+
to_multi_ary_expr(inst).op0().id() == ID_verilog_named_port_connection ||
1391+
to_multi_ary_expr(inst).op0().id() == ID_verilog_wildcard_port_connection)
13901392
{
13911393
const irept::subt &ports = symbol.type.find(ID_ports).get_sub();
13921394

src/verilog/verilog_typecheck.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,32 @@ void verilog_typecheckt::typecheck_port_connections(
123123
}
124124

125125
// named port connection?
126-
127-
if(inst.connections().front().id() == ID_named_port_connection)
126+
if(inst.named_connections())
128127
{
129128
// We don't require that all ports are connected.
130129

131130
std::set<irep_idt> assigned_ports;
131+
bool wildcard = false;
132132

133133
for(auto &connection : inst.connections())
134134
{
135-
if(connection.id() != ID_named_port_connection)
135+
if(connection.id() == ID_verilog_wildcard_port_connection)
136+
{
137+
// .*
138+
if(wildcard)
139+
{
140+
// .* can only be given once
141+
throw errort{}.with_location(connection.source_location())
142+
<< "wildcard connection given more than once";
143+
}
144+
else
145+
{
146+
wildcard = true;
147+
continue;
148+
}
149+
}
150+
151+
if(connection.id() != ID_verilog_named_port_connection)
136152
{
137153
throw errort().with_location(inst.source_location())
138154
<< "expected a named port connection";
@@ -179,7 +195,7 @@ void verilog_typecheckt::typecheck_port_connections(
179195
assigned_ports.insert(identifier);
180196
}
181197
}
182-
else // just a list without names
198+
else // Positional connections, i.e., just a list without port names
183199
{
184200
if(inst.connections().size() != ports.size())
185201
{

0 commit comments

Comments
 (0)