Skip to content

Commit 776c8d9

Browse files
committed
SystemVerilog: ++/-- for generate for
SystemVerilog generate for allows both pre- and post-increment and -decrement.
1 parent 71355fe commit 776c8d9

File tree

7 files changed

+98
-7
lines changed

7 files changed

+98
-7
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CORE
2+
generate-for4.sv
3+
--bound 1
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module main;
2+
3+
wire [15:0] some_wire;
4+
5+
generate
6+
genvar i;
7+
for (i = 0; i <= 15; ++i)
8+
assign some_wire[i] = (i%2) == 0;
9+
endgenerate
10+
11+
// should pass
12+
always assert property1: some_wire == 'b0101_0101_0101_0101;
13+
14+
endmodule
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CORE
2+
generate-for5.sv
3+
--bound 1
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module main;
2+
3+
wire [15:0] some_wire;
4+
5+
generate
6+
genvar i;
7+
for (i = 16; i != 0; i--)
8+
assign some_wire[i - 1] = ((i-1)%2) == 0;
9+
endgenerate
10+
11+
// should pass
12+
always assert property1: some_wire == 'b0101_0101_0101_0101;
13+
14+
endmodule

src/verilog/parser.y

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3123,8 +3123,8 @@ generate_item_brace:
31233123

31243124
loop_generate_construct:
31253125
TOK_FOR '(' genvar_initialization ';'
3126-
constant_expression ';'
3127-
genvar_initialization ')'
3126+
genvar_expression ';'
3127+
genvar_iteration ')'
31283128
generate_block
31293129
{ init($$, ID_generate_for);
31303130
stack_expr($$).reserve_operands(4);
@@ -3135,11 +3135,22 @@ loop_generate_construct:
31353135
}
31363136
;
31373137

3138+
genvar_expression: constant_expression;
3139+
31383140
genvar_initialization:
31393141
genvar_identifier '=' constant_expression
31403142
{ init($$, ID_generate_assign); mto($$, $1); mto($$, $3); }
31413143
;
31423144

3145+
genvar_iteration:
3146+
genvar_identifier assignment_operator genvar_expression
3147+
{ init($$, ID_generate_assign); mto($$, $1); mto($$, $3); }
3148+
| inc_or_dec_operator genvar_identifier
3149+
{ $$ = $1; mto($$, $2); }
3150+
| genvar_identifier inc_or_dec_operator
3151+
{ $$ = $2; mto($$, $1); }
3152+
;
3153+
31433154
conditional_generate_construct:
31443155
if_generate_construct
31453156
| case_generate_construct
@@ -4441,6 +4452,11 @@ unary_operator:
44414452
| TOK_TILDECARET { init($$, ID_reduction_xnor); }
44424453
;
44434454

4455+
inc_or_dec_operator:
4456+
TOK_PLUSPLUS { init($$, ID_preincrement); }
4457+
| TOK_MINUSMINUS { init($$, ID_predecrement); }
4458+
;
4459+
44444460
// System Verilog standard 1800-2017
44454461
// A.8.7 Numbers
44464462

src/verilog/verilog_expr.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,12 @@ inline verilog_module_itemt &to_verilog_module_item(irept &irep)
408408
class verilog_generate_assignt : public verilog_module_itemt
409409
{
410410
public:
411+
verilog_generate_assignt(exprt __lhs, exprt __rhs)
412+
: verilog_module_itemt{ID_generate_assign}
413+
{
414+
add_to_operands(std::move(__lhs), std::move(__rhs));
415+
}
416+
411417
const exprt &lhs() const
412418
{
413419
return op0();
@@ -562,9 +568,10 @@ class verilog_generate_fort : public verilog_module_itemt
562568
return op1();
563569
}
564570

565-
const verilog_generate_assignt &increment() const
571+
// assignment, ++, --
572+
const verilog_module_itemt &iteration() const
566573
{
567-
return static_cast<const verilog_generate_assignt &>(op2());
574+
return static_cast<const verilog_module_itemt &>(op2());
568575
}
569576

570577
const verilog_module_itemt &body() const

src/verilog/verilog_generate.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ Author: Daniel Kroening, [email protected]
66
77
\*******************************************************************/
88

9-
#include "verilog_typecheck.h"
9+
#include <util/arith_tools.h>
1010

1111
#include "verilog_expr.h"
12+
#include "verilog_typecheck.h"
1213

1314
/*******************************************************************\
1415
@@ -268,7 +269,34 @@ void verilog_typecheckt::elaborate_generate_for(
268269

269270
elaborate_generate_item(copy_of_body, dest);
270271

271-
// Now increase the loop counter.
272-
elaborate_generate_assign(for_statement.increment(), dest);
272+
// Now increase/decrease the loop counter.
273+
{
274+
auto statement = for_statement.iteration().id();
275+
if(statement == ID_generate_assign)
276+
{
277+
elaborate_generate_assign(
278+
to_verilog_generate_assign(for_statement.iteration()), dest);
279+
}
280+
else if(statement == ID_preincrement || statement == ID_predecrement)
281+
{
282+
// turn ++x and x++ into x = x + 1
283+
// turn --x and x-- into x = x - 1
284+
// The expressions are parse trees, prior to typechecking
285+
auto &op = to_unary_expr(for_statement.iteration()).op();
286+
auto one = constant_exprt{ID_1, typet{}};
287+
auto new_value = binary_exprt{
288+
op, statement == ID_preincrement ? ID_plus : ID_minus, one, typet{}};
289+
auto assignment = verilog_generate_assignt{op, new_value};
290+
291+
elaborate_generate_assign(assignment, dest);
292+
}
293+
else
294+
{
295+
DATA_INVARIANT_WITH_DIAGNOSTICS(
296+
false,
297+
"unexpected genvar_iteration item",
298+
for_statement.iteration().pretty());
299+
}
300+
}
273301
}
274302
}

0 commit comments

Comments
 (0)