Skip to content

Commit b98c149

Browse files
kroeningtautschnig
authored andcommitted
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 b98c149

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)