Skip to content

Commit efa2b5f

Browse files
committed
Verilog system tasks and functions are always base names
Verilog system tasks and functions are never qualified or decorated, hence use verilog_identifier_exprt for their name.
1 parent 6376b45 commit efa2b5f

File tree

8 files changed

+113
-98
lines changed

8 files changed

+113
-98
lines changed

src/verilog/expr2verilog.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,24 @@ expr2verilogt::resultt expr2verilogt::convert_symbol(const exprt &src)
11781178

11791179
/*******************************************************************\
11801180
1181+
Function: expr2verilogt::convert_verilog_identifier
1182+
1183+
Inputs:
1184+
1185+
Outputs:
1186+
1187+
Purpose:
1188+
1189+
\*******************************************************************/
1190+
1191+
expr2verilogt::resultt
1192+
expr2verilogt::convert_verilog_identifier(const verilog_identifier_exprt &src)
1193+
{
1194+
return {verilog_precedencet::MAX, id2string(src.base_name())};
1195+
}
1196+
1197+
/*******************************************************************\
1198+
11811199
Function: expr2verilogt::convert_nondet_symbol
11821200
11831201
Inputs:
@@ -1809,6 +1827,9 @@ expr2verilogt::resultt expr2verilogt::convert_rec(const exprt &src)
18091827
else if(src.id()==ID_symbol)
18101828
return convert_symbol(src);
18111829

1830+
else if(src.id() == ID_verilog_identifier)
1831+
return convert_symbol(to_verilog_identifier_expr(src));
1832+
18121833
else if(src.id()==ID_nondet_symbol)
18131834
return convert_nondet_symbol(src);
18141835

src/verilog/expr2verilog_class.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class sva_cycle_delay_exprt;
1919
class sva_sequence_first_match_exprt;
2020
class sva_sequence_property_instance_exprt;
2121
class sva_sequence_repetition_exprt;
22+
class verilog_identifier_exprt;
2223

2324
// Precedences (higher means binds more strongly).
2425
// Follows Table 11-2 in IEEE 1800-2017.
@@ -98,6 +99,8 @@ class expr2verilogt
9899

99100
resultt convert_symbol(const exprt &);
100101

102+
resultt convert_verilog_identifier(const verilog_identifier_exprt &);
103+
101104
resultt
102105
convert_hierarchical_identifier(const class hierarchical_identifier_exprt &);
103106

src/verilog/parser.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3718,7 +3718,7 @@ function_statement: statement
37183718
;
37193719

37203720
system_task_name: TOK_SYSIDENT
3721-
{ new_symbol($$, $1); }
3721+
{ new_symbol($$, $1); stack_expr($$).id(ID_verilog_identifier); }
37223722
;
37233723

37243724
// System Verilog standard 1800-2017

src/verilog/verilog_expr.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ typet verilog_declaratort::merged_type(const typet &declaration_type) const
5252

5353
static bool is_system_function_identifier(const exprt &function)
5454
{
55-
return function.id() == ID_symbol &&
56-
has_prefix(id2string(to_symbol_expr(function).get_identifier()), "$");
55+
return function.id() == ID_verilog_identifier &&
56+
has_prefix(
57+
id2string(to_verilog_identifier_expr(function).base_name()), "$");
5758
}
5859

5960
bool function_call_exprt::is_system_function_call() const

src/verilog/verilog_lowering.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -176,68 +176,68 @@ exprt to_bitvector(const exprt &src)
176176

177177
exprt verilog_lowering_system_function(const function_call_exprt &call)
178178
{
179-
auto identifier = to_symbol_expr(call.function()).get_identifier();
179+
auto base_name = to_verilog_identifier_expr(call.function()).base_name();
180180
auto &arguments = call.arguments();
181181

182-
if(identifier == "$signed" || identifier == "$unsigned")
182+
if(base_name == "$signed" || base_name == "$unsigned")
183183
{
184184
// lower to typecast
185185
DATA_INVARIANT(
186-
arguments.size() == 1, id2string(identifier) + " takes one argument");
186+
arguments.size() == 1, id2string(base_name) + " takes one argument");
187187
return typecast_exprt{arguments[0], call.type()};
188188
}
189-
else if(identifier == "$rtoi")
189+
else if(base_name == "$rtoi")
190190
{
191191
DATA_INVARIANT(
192-
arguments.size(), id2string(identifier) + " takes one argument");
192+
arguments.size(), id2string(base_name) + " takes one argument");
193193
// These truncate, and do not round.
194194
return floatbv_typecast_exprt{
195195
arguments[0],
196196
ieee_floatt::rounding_mode_expr(
197197
ieee_floatt::rounding_modet::ROUND_TO_ZERO),
198198
verilog_lowering(call.type())};
199199
}
200-
else if(identifier == "$itor")
200+
else if(base_name == "$itor")
201201
{
202202
DATA_INVARIANT(
203-
arguments.size(), id2string(identifier) + " takes one argument");
203+
arguments.size(), id2string(base_name) + " takes one argument");
204204
// No rounding required, any 32-bit integer will fit into double.
205205
return floatbv_typecast_exprt{
206206
arguments[0],
207207
ieee_floatt::rounding_mode_expr(
208208
ieee_floatt::rounding_modet::ROUND_TO_ZERO),
209209
verilog_lowering(call.type())};
210210
}
211-
else if(identifier == "$bitstoreal")
211+
else if(base_name == "$bitstoreal")
212212
{
213213
DATA_INVARIANT(
214-
arguments.size(), id2string(identifier) + " takes one argument");
214+
arguments.size(), id2string(base_name) + " takes one argument");
215215
// not a conversion -- this returns the given bit-pattern as a real
216216
return typecast_exprt{
217217
zero_extend_exprt{arguments[0], bv_typet{64}},
218218
verilog_lowering(call.type())};
219219
}
220-
else if(identifier == "$bitstoshortreal")
220+
else if(base_name == "$bitstoshortreal")
221221
{
222222
DATA_INVARIANT(
223-
arguments.size(), id2string(identifier) + " takes one argument");
223+
arguments.size(), id2string(base_name) + " takes one argument");
224224
// not a conversion -- this returns the given bit-pattern as a real
225225
return typecast_exprt{
226226
zero_extend_exprt{arguments[0], bv_typet{32}},
227227
verilog_lowering(call.type())};
228228
}
229-
else if(identifier == "$realtobits")
229+
else if(base_name == "$realtobits")
230230
{
231231
DATA_INVARIANT(
232-
arguments.size(), id2string(identifier) + " takes one argument");
232+
arguments.size(), id2string(base_name) + " takes one argument");
233233
// not a conversion -- this returns the given floating-point bit-pattern as [63:0]
234234
return zero_extend_exprt{
235235
typecast_exprt{arguments[0], bv_typet{64}}, call.type()};
236236
}
237-
else if(identifier == "$shortrealtobits")
237+
else if(base_name == "$shortrealtobits")
238238
{
239239
DATA_INVARIANT(
240-
arguments.size(), id2string(identifier) + " takes one argument");
240+
arguments.size(), id2string(base_name) + " takes one argument");
241241
// not a conversion -- this returns the given floating-point bit-pattern as [31:0]
242242
return zero_extend_exprt{
243243
typecast_exprt{arguments[0], bv_typet{32}}, call.type()};
@@ -350,8 +350,8 @@ exprt verilog_lowering(exprt expr)
350350
auto &call = to_function_call_expr(expr);
351351
if(call.is_system_function_call())
352352
{
353-
auto identifier = to_symbol_expr(call.function()).get_identifier();
354-
if(identifier == "$typename")
353+
auto base_name = to_verilog_identifier_expr(call.function()).base_name();
354+
if(base_name == "$typename")
355355
{
356356
// Don't touch.
357357
// Will be expanded by elaborate_constant_system_function_call,

src/verilog/verilog_synthesis.cpp

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,8 @@ exprt verilog_synthesist::expand_function_call(
342342
// Is it a 'system function call'?
343343
if(call.is_system_function_call())
344344
{
345-
auto identifier = to_symbol_expr(call.function()).get_identifier();
346-
if(identifier == "$ND")
345+
auto base_name = to_verilog_identifier_expr(call.function()).base_name();
346+
if(base_name == "$ND")
347347
{
348348
std::string identifier =
349349
id2string(module) + "::nondet::" + std::to_string(nondet_count++);
@@ -354,7 +354,7 @@ exprt verilog_synthesist::expand_function_call(
354354
select_one.set(ID_identifier, identifier);
355355
return select_one.with_source_location(call);
356356
}
357-
else if(identifier == "$past")
357+
else if(base_name == "$past")
358358
{
359359
auto what = call.arguments()[0];
360360
auto ticks = call.arguments().size() < 2
@@ -363,8 +363,8 @@ exprt verilog_synthesist::expand_function_call(
363363
return verilog_past_exprt{what, ticks}.with_source_location(call);
364364
}
365365
else if(
366-
identifier == "$stable" || identifier == "$rose" ||
367-
identifier == "$fell" || identifier == "$changed")
366+
base_name == "$stable" || base_name == "$rose" || base_name == "$fell" ||
367+
base_name == "$changed")
368368
{
369369
DATA_INVARIANT(call.arguments().size() >= 1, "must have argument");
370370
auto what = call.arguments()[0];
@@ -376,18 +376,18 @@ exprt verilog_synthesist::expand_function_call(
376376
std::move(expr), from_integer(0, integer_typet{})};
377377
};
378378

379-
if(identifier == "$stable")
379+
if(base_name == "$stable")
380380
return equal_exprt{what, past};
381-
else if(identifier == "$changed")
381+
else if(base_name == "$changed")
382382
return notequal_exprt{what, past};
383-
else if(identifier == "$rose")
383+
else if(base_name == "$rose")
384384
return and_exprt{not_exprt{lsb(past)}, lsb(what)};
385-
else if(identifier == "$fell")
385+
else if(base_name == "$fell")
386386
return and_exprt{lsb(past), not_exprt{lsb(what)}};
387387
else
388388
DATA_INVARIANT(false, "all cases covered");
389389
}
390-
else if(identifier == "$countones")
390+
else if(base_name == "$countones")
391391
{
392392
// lower to popcount
393393
DATA_INVARIANT(
@@ -3094,21 +3094,15 @@ Function: verilog_synthesist::synth_function_call_or_task_enable
30943094
void verilog_synthesist::synth_function_call_or_task_enable(
30953095
const verilog_function_callt &statement)
30963096
{
3097-
// this is essentially inlined
3098-
const symbol_exprt &function=to_symbol_expr(statement.function());
3099-
3100-
irep_idt identifier=function.get_identifier();
3101-
3102-
// We ignore everyting that starts with a '$',
3103-
// e.g., $display etc
3104-
3105-
if(!identifier.empty() && identifier[0]=='$')
3097+
if(statement.is_system_function_call())
31063098
{
3107-
// ignore
3099+
// ignore system functions
31083100
}
31093101
else
31103102
{
3111-
const symbolt &symbol=ns.lookup(identifier);
3103+
// this is essentially inlined
3104+
const symbol_exprt &function = to_symbol_expr(statement.function());
3105+
const symbolt &symbol = ns.lookup(function);
31123106

31133107
if(symbol.type.id()!=ID_code)
31143108
{

0 commit comments

Comments
 (0)