Skip to content

Commit fb0b2c8

Browse files
authored
Merge pull request #740 from CAS-Atlantic/generate_expansion
ODIN II: support nested loops in generate
2 parents cd783f4 + 3010fd2 commit fb0b2c8

File tree

10 files changed

+504
-127
lines changed

10 files changed

+504
-127
lines changed

ODIN_II/SRC/ast_loop_unroll.cpp

Lines changed: 156 additions & 96 deletions
Large diffs are not rendered by default.

ODIN_II/SRC/include/ast_loop_unroll.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ inline bool is_unsupported_pre(ast_node_t* node){
3333
bool is_unsupported_post(ast_node_t* node, ast_node_t* symbol);
3434
bool is_unsupported_condition(ast_node_t* node, ast_node_t* symbol);
3535

36-
ast_node_t* for_preprocessor(ast_node_t *ast_module, ast_node_t* node, ast_node_t ****instances, int *num_unrolled, int *num_original);
37-
ast_node_t* replace_fors(ast_node_t *ast_module, ast_node_t* node, ast_node_t ****instances, int *num_unrolled, int *num_original);
36+
ast_node_t* for_preprocessor(ast_node_t *ast_module, ast_node_t* node, ast_node_t ***removed_instances, int *num_removed);
37+
ast_node_t* replace_fors(ast_node_t *ast_module, ast_node_t* node, ast_node_t ***removed_instances, int *num_removed);
3838
ast_node_t* resolve_for(ast_node_t *ast_module, ast_node_t* node, ast_node_t ****instances, int *num_unrolled, int *num_original);
3939
int resolve_pre_condition(ast_node_t* node, ast_node_t** number);
4040
condition_function resolve_condition(ast_node_t* node, ast_node_t* symbol, int* error_code);
4141
post_condition_function resolve_binary_operation(ast_node_t* node);
4242
post_condition_function resolve_post_condition(ast_node_t* assignment, ast_node_t* symbol, int* error_code);
43-
ast_node_t* dup_and_fill_body(ast_node_t *ast_module, ast_node_t* body, ast_node_t* pre, ast_node_t** value, int* error_code, ast_node_t ****instances, int *num_unrolled, int *num_original);
43+
ast_node_t* dup_and_fill_body(ast_node_t *ast_module, ast_node_t* body, ast_node_t* pre, ast_node_t** value, int* error_code, ast_node_t ****instances, int *num_unrolled, int *num_original, bool is_nested);
4444
ast_node_t *replace_named_module(ast_node_t* module, ast_node_t** value);
4545

4646
#endif

ODIN_II/SRC/include/odin_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ struct typ
349349
short is_wire;
350350
short is_reg;
351351
short is_integer;
352+
short is_genvar;
352353
short is_signed;
353354
short is_initialized; // should the variable be initialized with some value?
354355
long initial_value;

ODIN_II/SRC/include/odin_util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const char *name_based_on_op(operation_list op);
1616

1717
char *make_signal_name(char *signal_name, int bit);
1818
char *make_full_ref_name(const char *previous, const char *module_name, const char *module_instance_name, const char *signal_name, long bit);
19+
char *make_full_name_w_o_array_ref(const char *previous, const char *module_name, const char *module_instance_name);
1920

2021
char *twos_complement(char *str);
2122
int is_string_of_radix(char *string, int radix);

ODIN_II/SRC/odin_util.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,33 @@ char *make_full_ref_name(const char *previous, const char *module_name, const ch
127127
return vtr::strdup(return_string.str().c_str());
128128
}
129129

130+
/*---------------------------------------------------------------------------------------------
131+
* (function: make_full_name_w_o_array_ref)
132+
// {previous_string}.module_name+instance_name
133+
*-------------------------------------------------------------------------------------------*/
134+
char *make_full_name_w_o_array_ref(const char *previous, const char *module_name, const char *module_instance_name)
135+
{
136+
137+
std::stringstream return_string;
138+
if(previous)
139+
return_string << previous;
140+
141+
if(module_name)
142+
return_string << "." << module_name << "+" << module_instance_name;
143+
144+
145+
std::string name = return_string.str();
146+
147+
size_t idx = name.find_first_of('[', 0);
148+
if (idx != std::string::npos)
149+
{
150+
// delete array refs
151+
name.erase(idx, std::string::npos);
152+
}
153+
154+
return vtr::strdup(name.c_str());
155+
}
156+
130157
/*---------------------------------------------------------------------------------------------
131158
* (function: twos_complement)
132159
* Changes a bit string to its twos complement value

ODIN_II/SRC/parse_making_ast.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,11 +864,15 @@ ast_node_t *markAndProcessSymbolListWith(ids top_type, ids id, ast_node_t *symbo
864864
symbol_list->children[i]->types.variable.is_reg = true;
865865
break;
866866
case INTEGER:
867-
case GENVAR:
868867
oassert(is_signed && "Integers must always be signed");
869868
symbol_list->children[i]->types.variable.is_signed = is_signed;
870869
symbol_list->children[i]->types.variable.is_integer = true;
871870
break;
871+
case GENVAR:
872+
oassert(is_signed && "Genvars must always be signed");
873+
symbol_list->children[i]->types.variable.is_signed = is_signed;
874+
symbol_list->children[i]->types.variable.is_integer = true; // TODO: flip to is_genvar
875+
break;
872876
default:
873877
oassert(false);
874878
}

ODIN_II/SRC/verilog_bison.y

Lines changed: 81 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,16 @@ int yylex(void);
101101
%type <node> gate_declaration single_input_gate_instance
102102
%type <node> module_instantiation module_instance function_instance list_of_module_connections list_of_function_connections
103103
%type <node> list_of_multiple_inputs_gate_connections
104-
%type <node> module_connection always statement function_statement blocking_assignment generate
105-
%type <node> non_blocking_assignment case_item_list case_items seq_block generate_for
106-
%type <node> stmt_list delay_control event_expression_list event_expression
104+
%type <node> module_connection always statement function_statement blocking_assignment
105+
%type <node> non_blocking_assignment conditional_statement case_statement case_item_list case_items seq_block
106+
%type <node> stmt_list delay_control event_expression_list event_expression loop_statement
107107
%type <node> expression primary probable_expression_list expression_list module_parameter
108-
%type <node> list_of_module_parameters
108+
%type <node> list_of_module_parameters localparam_declaration
109109
%type <node> specify_block list_of_specify_items specify_item specparam_declaration
110110
%type <node> specify_pal_connect_declaration c_function_expression_list c_function
111111
%type <node> initial_block parallel_connection list_of_blocking_assignment
112+
%type <node> list_of_generate_items generate_item generate loop_generate_construct if_generate_construct
113+
%type <node> case_generate_construct case_generate_item_list case_generate_items generate_block
112114

113115
%%
114116

@@ -193,19 +195,31 @@ module_item:
193195
| input_declaration {$$ = $1;}
194196
| output_declaration {$$ = $1;}
195197
| inout_declaration {$$ = $1;}
196-
| net_declaration {$$ = $1;}
197-
| genvar_declaration {$$ = $1;}
198-
| integer_declaration {$$ = $1;}
199-
| continuous_assign {$$ = $1;}
200-
| gate_declaration {$$ = $1;}
201-
| generate {$$ = $1;}
202-
| module_instantiation {$$ = $1;}
203-
| function_declaration {$$ = $1;}
204-
| initial_block {$$ = $1;}
205-
| always {$$ = $1;}
206-
| defparam_declaration {$$ = $1;}
207198
| specify_block {$$ = $1;}
208-
| c_function ';' {$$ = $1;}
199+
| generate_item {$$ = $1;}
200+
| generate {$$ = $1;}
201+
;
202+
203+
list_of_generate_items:
204+
list_of_generate_items generate_item {$$ = newList_entry($1, $2);}
205+
| generate_item {$$ = newList(BLOCK, $1);}
206+
207+
generate_item:
208+
localparam_declaration {$$ = $1;}
209+
| net_declaration {$$ = $1;}
210+
| genvar_declaration {$$ = $1;}
211+
| integer_declaration {$$ = $1;}
212+
| continuous_assign {$$ = $1;}
213+
| gate_declaration {$$ = $1;}
214+
| module_instantiation {$$ = $1;}
215+
| function_declaration {$$ = $1;}
216+
| initial_block {$$ = $1;}
217+
| always {$$ = $1;}
218+
| defparam_declaration {$$ = $1;}
219+
| c_function ';' {$$ = $1;}
220+
| if_generate_construct {$$ = $1;}
221+
| case_generate_construct {$$ = $1;}
222+
| loop_generate_construct {$$ = $1;}
209223
;
210224

211225
function_declaration:
@@ -242,8 +256,11 @@ function_input_declaration:
242256

243257
parameter_declaration:
244258
vPARAMETER vSIGNED variable_list ';' {$$ = markAndProcessSymbolListWith(MODULE,PARAMETER, $3, true);}
245-
| vLOCALPARAM vSIGNED variable_list ';' {$$ = markAndProcessSymbolListWith(MODULE,LOCALPARAM, $3, true);}
246259
| vPARAMETER variable_list ';' {$$ = markAndProcessSymbolListWith(MODULE,PARAMETER, $2, false);}
260+
;
261+
262+
localparam_declaration:
263+
vLOCALPARAM vSIGNED variable_list ';' {$$ = markAndProcessSymbolListWith(MODULE,LOCALPARAM, $3, true);}
247264
| vLOCALPARAM variable_list ';' {$$ = markAndProcessSymbolListWith(MODULE,LOCALPARAM, $2, false);}
248265
;
249266

@@ -424,28 +441,65 @@ always:
424441
;
425442

426443
generate:
427-
vGENERATE generate_for vENDGENERATE {$$ = newGenerate($2, yylineno);}
444+
vGENERATE list_of_generate_items vENDGENERATE {$$ = newGenerate($2, yylineno);}
445+
;
446+
447+
loop_generate_construct:
448+
vFOR '(' blocking_assignment ';' expression ';' blocking_assignment ')' generate_block {$$ = newFor($3, $5, $7, $9, yylineno);}
449+
;
450+
451+
if_generate_construct:
452+
vIF '(' expression ')' generate_block %prec LOWER_THAN_ELSE {$$ = newIf($3, $5, NULL, yylineno);}
453+
| vIF '(' expression ')' generate_block vELSE generate_block {$$ = newIf($3, $5, $7, yylineno);}
454+
;
455+
456+
case_generate_construct:
457+
vCASE '(' expression ')' case_generate_item_list vENDCASE {$$ = newCase($3, $5, yylineno);}
458+
;
459+
460+
case_generate_item_list:
461+
case_generate_item_list case_generate_items {$$ = newList_entry($1, $2);}
462+
| case_generate_items {$$ = newList(CASE_LIST, $1);}
463+
;
464+
465+
case_generate_items:
466+
expression ':' generate_block {$$ = newCaseItem($1, $3, yylineno);}
467+
| vDEFAULT ':' generate_block {$$ = newDefaultCase($3, yylineno);}
468+
;
469+
470+
generate_block:
471+
generate_item {$$ = $1;}
472+
| vBEGIN list_of_generate_items vEND {$$ = $2;}
473+
| vBEGIN ':' vSYMBOL_ID list_of_generate_items vEND {$$ = $4;}
428474
;
429475

430476
function_statement:
431477
statement {$$ = newAlways(NULL, $1, yylineno);}
432478
;
433479

434-
generate_for:
435-
vFOR '(' blocking_assignment ';' expression ';' blocking_assignment ')' vBEGIN module_instantiation vEND {$$ = newFor($3, $5, $7, $10, yylineno);}
436-
;
437-
438480
statement:
439481
seq_block {$$ = $1;}
440482
| c_function ';' {$$ = $1;}
441483
| blocking_assignment ';' {$$ = $1;}
442484
| non_blocking_assignment ';' {$$ = $1;}
443-
| vIF '(' expression ')' statement %prec LOWER_THAN_ELSE {$$ = newIf($3, $5, NULL, yylineno);}
444-
| vIF '(' expression ')' statement vELSE statement {$$ = newIf($3, $5, $7, yylineno);}
445-
| vCASE '(' expression ')' case_item_list vENDCASE {$$ = newCase($3, $5, yylineno);}
446-
| vFOR '(' blocking_assignment ';' expression ';' blocking_assignment ')' statement {$$ = newFor($3, $5, $7, $9, yylineno);}
485+
| conditional_statement {$$ = $1;}
486+
| case_statement {$$ = $1;}
487+
| loop_statement {$$ = $1;}
488+
| ';' {$$ = NULL;}
489+
;
490+
491+
loop_statement:
492+
vFOR '(' blocking_assignment ';' expression ';' blocking_assignment ')' statement {$$ = newFor($3, $5, $7, $9, yylineno);}
447493
| vWHILE '(' expression ')' statement {$$ = newWhile($3, $5, yylineno);}
448-
| ';' {$$ = NULL;}
494+
;
495+
496+
case_statement:
497+
vCASE '(' expression ')' case_item_list vENDCASE {$$ = newCase($3, $5, yylineno);}
498+
;
499+
500+
conditional_statement:
501+
vIF '(' expression ')' statement %prec LOWER_THAN_ELSE {$$ = newIf($3, $5, NULL, yylineno);}
502+
| vIF '(' expression ')' statement vELSE statement {$$ = newIf($3, $5, $7, yylineno);}
449503
;
450504

451505
list_of_specify_items:
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module down_counter
2+
(
3+
clk, out1
4+
);
5+
input rst1, rst2, clk;
6+
output reg [15:0] out1;
7+
8+
wire [15:0] a;
9+
10+
genvar i;
11+
genvar j;
12+
generate
13+
for (i=0; i<4; i=i+1) begin : outer_loop
14+
for (j=0; j<4; j=j+1) begin : inner_loop
15+
assign a[(i*4)+j] = 1'b1;
16+
end
17+
end
18+
endgenerate
19+
20+
always @ (posedge clk)
21+
begin
22+
if (rst1 && rst2)
23+
out1 <= a;
24+
else
25+
out1 <= out1 - 1;
26+
end
27+
28+
endmodule
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
GLOBAL_SIM_BASE_CLK rst1 rst2 clk
2+
1 0 1 1
3+
0 1 0 1
4+
1 1 0 0
5+
0 1 1 0
6+
1 0 0 1
7+
0 0 1 1
8+
1 0 0 0
9+
0 1 1 0
10+
1 0 1 1
11+
0 0 1 1
12+
1 1 1 0
13+
0 1 0 0
14+
1 0 1 1
15+
0 0 0 1
16+
1 0 0 0
17+
0 1 0 0
18+
1 1 0 1
19+
0 1 0 1
20+
1 1 0 0
21+
0 0 1 0
22+
1 0 0 1
23+
0 0 1 1
24+
1 1 0 0
25+
0 0 1 0
26+
1 0 0 1
27+
0 0 0 1
28+
1 1 1 0
29+
0 0 0 0
30+
1 0 0 1
31+
0 1 0 1
32+
1 1 1 0
33+
0 1 1 0
34+
1 1 1 1
35+
0 1 0 1
36+
1 1 1 0
37+
0 1 0 0
38+
1 1 0 1
39+
0 1 0 1
40+
1 1 0 0
41+
0 1 1 0
42+
1 0 0 1
43+
0 0 1 1
44+
1 0 0 0
45+
0 0 1 0
46+
1 1 1 1
47+
0 1 1 1
48+
1 1 0 0
49+
0 1 1 0
50+
1 1 0 1
51+
0 1 0 1
52+
1 0 1 0
53+
0 0 0 0
54+
1 0 0 1
55+
0 1 1 1
56+
1 1 0 0
57+
0 1 0 0
58+
1 0 1 1
59+
0 0 1 1
60+
1 0 1 0
61+
0 0 0 0
62+
1 0 1 1
63+
0 0 0 1
64+
1 0 1 0
65+
0 0 0 0
66+
1 0 0 1
67+
0 1 0 1
68+
1 0 0 0
69+
0 0 0 0
70+
1 1 1 1
71+
0 1 1 1
72+
1 0 1 0
73+
0 1 1 0
74+
1 0 1 1
75+
0 0 0 1
76+
1 0 0 0
77+
0 0 0 0
78+
1 1 1 1
79+
0 0 1 1
80+
1 0 1 0
81+
0 0 0 0
82+
1 1 1 1
83+
0 1 1 1
84+
1 0 1 0
85+
0 1 1 0
86+
1 0 0 1
87+
0 0 0 1
88+
1 1 0 0
89+
0 0 0 0
90+
1 1 0 1
91+
0 0 0 1
92+
1 0 0 0
93+
0 1 1 0
94+
1 1 0 1
95+
0 1 1 1
96+
1 1 0 0
97+
0 0 1 0
98+
1 1 0 1
99+
0 0 0 1
100+
1 0 0 0
101+
0 1 0 0

0 commit comments

Comments
 (0)