Is there an empty/do-nothing statement I can put at the end of my verilog macros that will expect a semicolon at the end?
For example:
`define count_clocks(number,clock) repeat (number) @(posedge clock)
expects a semicolon at the end because there's not one after the statement, i.e.:
`count_clocks(5,uart_clk);
is syntactically correct and
`count_clocks(5,uart_clk)
isn't because that turns into
repeat (number) @(posedge clock)
which requires a semicolon.
I'd like to get that same behavior from:
`define assert_ex(signal, value, format) \
if (signal !== value) begin \
$write("ASSERTION FAILED in %m: (");\
$write(format,signal);\
$write(" != ");\
$write(format,value);\
$display(")"); \
$finish; \
end
`define assert(signal, value) `assert_ex(signal,value,"%d")
so that it errors if I do(leave off the semicolon):
`assert(error,0)
mostly because it bothers me that macros don't need the semicolon, but so many other places do. Adding one accidentally creates the 'empty statement in sequential block' warning, but then I have to go searching for the macro that has a semicolon after it.
And I don't think system verilog is a possibility. It seems like Vivado xsim doesn't support systemverilog at the top level? (At least I think? I'm a bit of a newbie, hence this question)
FWIW, this is a pretty common pattern in C/C++ to make macros syntactically behave more like functions and the rest of the language.
Most methodologies (UVM for example) are written so you never need a semicolon after the macro because of this issue. They do this by wrapping the body of the macro in begin/end
keywords.
But if you want to require a terminating semicolon, you can put
repeat (0) write("")
and hopefully the simulation compiler optimizes it away. But it might cause a problem with some synthesis tools seeing a system task.
Note that Vivado fully supports a large enough subset of SystemVerilog so your original code would not have a problem with extra semicolons.