Skip to content

Commit 80aae52

Browse files
author
djns1
committed
Initial InOut attempt
1 parent 774fbed commit 80aae52

File tree

10 files changed

+104
-51
lines changed

10 files changed

+104
-51
lines changed

ODIN_II/SRC/ast_elaborate.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2426,6 +2426,8 @@ void verify_genvars(ast_node_t* node, sc_hierarchy* local_ref, char*** other_gen
24262426
}
24272427

24282428
ast_node_t* look_for_matching_hard_block(ast_node_t* node, char* hard_block_name, sc_hierarchy* local_ref) {
2429+
// TODO Update this to match inouts as valid inputs or outputs to the hardblock
2430+
24292431
t_model* hb_model = find_hard_block(hard_block_name);
24302432
bool is_hb = true;
24312433

@@ -2660,12 +2662,12 @@ void create_param_table_for_scope(ast_node_t* module_items, sc_hierarchy* local_
26602662
/* symbols are already dealt with */
26612663
if (var_declare->types.variable.is_input
26622664
|| var_declare->types.variable.is_output
2665+
|| var_declare->types.variable.is_inout
26632666
|| var_declare->types.variable.is_reg
26642667
|| var_declare->types.variable.is_integer
26652668
|| var_declare->types.variable.is_genvar
26662669
|| var_declare->types.variable.is_wire
26672670
|| var_declare->types.variable.is_defparam)
2668-
26692671
continue;
26702672

26712673
oassert(module_items->children[i]->children[j]->type == VAR_DECLARE);

ODIN_II/SRC/netlist_create_from_ast.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,7 @@ void create_symbol_table_for_scope(ast_node_t* module_items, sc_hierarchy* local
12641264
continue;
12651265

12661266
oassert(module_items->children[i]->children[j]->type == VAR_DECLARE);
1267-
oassert((var_declare->types.variable.is_input) || (var_declare->types.variable.is_output) || (var_declare->types.variable.is_reg) || (var_declare->types.variable.is_integer) || (var_declare->types.variable.is_genvar) || (var_declare->types.variable.is_wire));
1267+
oassert((var_declare->types.variable.is_input) || (var_declare->types.variable.is_output) || (var_declare->types.variable.is_inout) || (var_declare->types.variable.is_reg) || (var_declare->types.variable.is_integer) || (var_declare->types.variable.is_genvar) || (var_declare->types.variable.is_wire));
12681268

12691269
if (var_declare->types.variable.is_input
12701270
&& var_declare->types.variable.is_reg) {
@@ -1802,6 +1802,7 @@ void connect_module_instantiation_and_alias(short PASS, ast_node_t* module_insta
18021802
error_message(NETLIST, module_var_node->children[5]->line_number, module_var_node->children[5]->file_number, "%s\n", "Unhandled implicit memory in connect_module_instantiation_and_alias");
18031803
}
18041804
for (j = 0; j < port_size; j++) {
1805+
bool is_inout = module_var_node->types.variable.is_inout;
18051806
if (module_var_node->types.variable.is_input) {
18061807
/* IF - this spot in the module list is an input, then we need to find it in the
18071808
* string cache (as its old name), check if the new_name (the instantiation name)
@@ -1908,7 +1909,9 @@ void connect_module_instantiation_and_alias(short PASS, ast_node_t* module_insta
19081909

19091910
vtr::free(full_name);
19101911
vtr::free(alias_name);
1911-
} else if (module_var_node->types.variable.is_output) {
1912+
}
1913+
1914+
if (module_var_node->types.variable.is_output) {
19121915
/* ELSE IF - this is an output pin from the module. We need to alias this output
19131916
* pin with it's calling name here so that everyone can see it at this level */
19141917
char* name_of_module_instance_of_input = NULL;

ODIN_II/SRC/parse_making_ast.cpp

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,17 @@
4545
//for module
4646
STRING_CACHE* modules_inputs_sc;
4747
STRING_CACHE* modules_outputs_sc;
48+
STRING_CACHE* modules_inouts_sc;
4849
STRING_CACHE* module_instances_sc;
4950

5051
//for function
5152
STRING_CACHE* functions_inputs_sc;
5253
STRING_CACHE* functions_outputs_sc;
54+
STRING_CACHE* functions_inouts_sc;
5355

5456
STRING_CACHE* tasks_inputs_sc;
5557
STRING_CACHE* tasks_outputs_sc;
58+
STRING_CACHE* tasks_inouts_sc;
5659

5760
STRING_CACHE* module_names_to_idx;
5861
STRING_CACHE* instantiated_modules;
@@ -124,10 +127,13 @@ ast_t* init_parser() {
124127
/* create string caches to hookup PORTS with INPUT and OUTPUTs. This is made per module and will be cleaned and remade at next_module */
125128
modules_inputs_sc = sc_new_string_cache();
126129
modules_outputs_sc = sc_new_string_cache();
130+
modules_inouts_sc = sc_new_string_cache();
127131
functions_inputs_sc = sc_new_string_cache();
128132
functions_outputs_sc = sc_new_string_cache();
133+
functions_inouts_sc = sc_new_string_cache();
129134
tasks_inputs_sc = sc_new_string_cache();
130135
tasks_outputs_sc = sc_new_string_cache();
136+
tasks_inouts_sc = sc_new_string_cache();
131137
instantiated_modules = sc_new_string_cache();
132138
module_instances_sc = sc_new_string_cache();
133139
/* record of each of the individual modules */
@@ -158,10 +164,13 @@ ast_t* init_parser() {
158164
void cleanup_parser() {
159165
modules_inputs_sc = sc_free_string_cache(modules_inputs_sc);
160166
modules_outputs_sc = sc_free_string_cache(modules_outputs_sc);
167+
modules_inouts_sc = sc_free_string_cache(modules_inouts_sc);
161168
functions_inputs_sc = sc_free_string_cache(functions_inputs_sc);
162169
functions_outputs_sc = sc_free_string_cache(functions_outputs_sc);
170+
functions_inouts_sc = sc_free_string_cache(functions_inouts_sc);
163171
tasks_inputs_sc = sc_free_string_cache(tasks_inputs_sc);
164172
tasks_outputs_sc = sc_free_string_cache(tasks_outputs_sc);
173+
tasks_inouts_sc = sc_free_string_cache(tasks_inouts_sc);
165174
instantiated_modules = sc_free_string_cache(instantiated_modules);
166175
module_instances_sc = sc_free_string_cache(module_instances_sc);
167176
}
@@ -357,53 +366,58 @@ ast_node_t* resolve_ports(ids top_type, ast_node_t* symbol_list) {
357366
}
358367
} else {
359368
long sc_spot = -1;
360-
369+
STRING_CACHE* sc = NULL;
370+
361371
if (top_type == MODULE) {
372+
362373
/* find the related INPUT or OUTPUT definition and store that instead */
363374
if ((sc_spot = sc_lookup_string(modules_inputs_sc, symbol_list->children[i]->children[0]->types.identifier)) != -1) {
364-
oassert(((ast_node_t*)modules_inputs_sc->data[sc_spot])->type == VAR_DECLARE);
365-
free_whole_tree(symbol_list->children[i]);
366-
symbol_list->children[i] = (ast_node_t*)modules_inputs_sc->data[sc_spot];
367-
oassert(symbol_list->children[i]->types.variable.is_input);
375+
sc = modules_inputs_sc;
376+
oassert(((ast_node_t*)sc->data[sc_spot])->types.variable.is_input);
368377
} else if ((sc_spot = sc_lookup_string(modules_outputs_sc, symbol_list->children[i]->children[0]->types.identifier)) != -1) {
369-
oassert(((ast_node_t*)modules_outputs_sc->data[sc_spot])->type == VAR_DECLARE);
370-
free_whole_tree(symbol_list->children[i]);
371-
symbol_list->children[i] = (ast_node_t*)modules_outputs_sc->data[sc_spot];
372-
oassert(symbol_list->children[i]->types.variable.is_output);
378+
sc = modules_outputs_sc;
379+
oassert(((ast_node_t*)sc->data[sc_spot])->types.variable.is_output);
380+
} else if ((sc_spot = sc_lookup_string(modules_inouts_sc, symbol_list->children[i]->children[0]->types.identifier)) != -1) {
381+
sc = modules_inouts_sc;
382+
oassert(((ast_node_t*)sc->data[sc_spot])->types.variable.is_inout);
373383
} else {
374384
error_message(AST, symbol_list->children[i]->line_number, current_parse_file, "No matching declaration for port %s\n", symbol_list->children[i]->children[0]->types.identifier);
375385
}
376386
} else if (top_type == FUNCTION) {
377387
/* find the related INPUT or OUTPUT definition and store that instead */
378388
if ((sc_spot = sc_lookup_string(functions_inputs_sc, symbol_list->children[i]->children[0]->types.identifier)) != -1) {
379-
oassert(((ast_node_t*)functions_inputs_sc->data[sc_spot])->type == VAR_DECLARE);
380-
free_whole_tree(symbol_list->children[i]);
381-
symbol_list->children[i] = (ast_node_t*)functions_inputs_sc->data[sc_spot];
382-
oassert(symbol_list->children[i]->types.variable.is_input);
389+
sc = functions_inputs_sc;
390+
oassert(((ast_node_t*)sc->data[sc_spot])->types.variable.is_input);
383391
} else if ((sc_spot = sc_lookup_string(functions_outputs_sc, symbol_list->children[i]->children[0]->types.identifier)) != -1) {
384-
oassert(((ast_node_t*)functions_outputs_sc->data[sc_spot])->type == VAR_DECLARE);
385-
free_whole_tree(symbol_list->children[i]);
386-
symbol_list->children[i] = (ast_node_t*)functions_outputs_sc->data[sc_spot];
387-
oassert(symbol_list->children[i]->types.variable.is_output);
392+
sc = functions_outputs_sc;
393+
oassert(((ast_node_t*)sc->data[sc_spot])->types.variable.is_output);
394+
} else if ((sc_spot = sc_lookup_string(functions_inouts_sc, symbol_list->children[i]->children[0]->types.identifier)) != -1) {
395+
sc = functions_inouts_sc;
396+
oassert(((ast_node_t*)sc->data[sc_spot])->types.variable.is_inout);
388397
} else {
389398
error_message(AST, symbol_list->children[i]->line_number, current_parse_file, "No matching declaration for port %s\n", symbol_list->children[i]->children[0]->types.identifier);
390399
}
391400
} else if (top_type == TASK) {
392401
/* find the related INPUT or OUTPUT definition and store that instead */
393402
if ((sc_spot = sc_lookup_string(tasks_inputs_sc, symbol_list->children[i]->children[0]->types.identifier)) != -1) {
394-
oassert(((ast_node_t*)tasks_inputs_sc->data[sc_spot])->type == VAR_DECLARE);
395-
free_whole_tree(symbol_list->children[i]);
396-
symbol_list->children[i] = (ast_node_t*)tasks_inputs_sc->data[sc_spot];
397-
oassert(symbol_list->children[i]->types.variable.is_input);
403+
sc = tasks_inputs_sc;
404+
oassert(((ast_node_t*)sc->data[sc_spot])->types.variable.is_input);
398405
} else if ((sc_spot = sc_lookup_string(tasks_outputs_sc, symbol_list->children[i]->children[0]->types.identifier)) != -1) {
399-
oassert(((ast_node_t*)tasks_outputs_sc->data[sc_spot])->type == VAR_DECLARE);
400-
free_whole_tree(symbol_list->children[i]);
401-
symbol_list->children[i] = (ast_node_t*)tasks_outputs_sc->data[sc_spot];
402-
oassert(symbol_list->children[i]->types.variable.is_output);
406+
sc = tasks_outputs_sc;
407+
oassert(((ast_node_t*)sc->data[sc_spot])->types.variable.is_output);
408+
} else if ((sc_spot = sc_lookup_string(tasks_inouts_sc, symbol_list->children[i]->children[0]->types.identifier)) != -1) {
409+
sc = tasks_inouts_sc;
410+
oassert(((ast_node_t*)sc->data[sc_spot])->types.variable.is_inout);
403411
} else {
404412
error_message(AST, symbol_list->children[i]->line_number, current_parse_file, "No matching declaration for port %s\n", symbol_list->children[i]->children[0]->types.identifier);
405413
}
406414
}
415+
416+
if( sc ) {
417+
oassert(((ast_node_t*)sc->data[sc_spot])->type == VAR_DECLARE);
418+
free_whole_tree(symbol_list->children[i]);
419+
symbol_list->children[i] = (ast_node_t*)sc->data[sc_spot];
420+
}
407421
}
408422
symbol_list->children[i]->types.variable.is_port = true;
409423
}
@@ -420,6 +434,7 @@ ast_node_t* markAndProcessPortWith(ids top_type, ids port_id, ids net_id, ast_no
420434
const char* top_type_name = NULL;
421435
STRING_CACHE* this_inputs_sc = NULL;
422436
STRING_CACHE* this_outputs_sc = NULL;
437+
STRING_CACHE* this_inouts_sc = NULL;
423438

424439
if (top_type == MODULE) {
425440
top_type_name = "Module";
@@ -431,20 +446,20 @@ ast_node_t* markAndProcessPortWith(ids top_type, ids port_id, ids net_id, ast_no
431446

432447
ids temp_net_id = NO_ID;
433448

434-
if (port->types.variable.is_port) {
435-
oassert(false && "Port was already marked");
436-
}
449+
oassert(!port->types.variable.is_port && "Port was already marked");
437450

438451
if (top_type == MODULE) {
439452
this_inputs_sc = modules_inputs_sc;
440453
this_outputs_sc = modules_outputs_sc;
441-
454+
this_inouts_sc = modules_inouts_sc;
442455
} else if (top_type == FUNCTION) {
443456
this_inputs_sc = functions_inputs_sc;
444457
this_outputs_sc = functions_outputs_sc;
458+
this_inouts_sc = functions_inouts_sc;
445459
} else if (top_type == TASK) {
446460
this_inputs_sc = tasks_inputs_sc;
447461
this_outputs_sc = tasks_outputs_sc;
462+
this_inouts_sc = tasks_inouts_sc;
448463
}
449464

450465
/* look for processed inputs with this name */
@@ -460,6 +475,13 @@ ast_node_t* markAndProcessPortWith(ids top_type, ids port_id, ids net_id, ast_no
460475
error_message(AST, port->line_number, current_parse_file, "%s already has output with this name %s\n",
461476
top_type_name, ((ast_node_t*)this_outputs_sc->data[sc_spot])->children[0]->types.identifier);
462477
}
478+
479+
/* look for processed inouts with this name */
480+
sc_spot = sc_lookup_string(this_inouts_sc, port->children[0]->types.identifier);
481+
if (sc_spot > -1 && ((ast_node_t*)this_inouts_sc->data[sc_spot])->types.variable.is_port) {
482+
error_message(PARSE_ERROR, port->line_number, current_parse_file, "%s already has inout with this name %s\n",
483+
top_type_name, ((ast_node_t*)this_inouts_sc->data[sc_spot])->children[0]->types.identifier);
484+
}
463485

464486
switch (net_id) {
465487
case REG:
@@ -565,9 +587,15 @@ ast_node_t* markAndProcessPortWith(ids top_type, ids port_id, ids net_id, ast_no
565587

566588
case INOUT:
567589
port->types.variable.is_inout = true;
568-
port->types.variable.is_input = false;
569-
port->types.variable.is_output = false;
570-
error_message(AST, port->line_number, current_parse_file, "Odin does not handle inouts (%s)\n", port->children[0]->types.identifier);
590+
port->types.variable.is_input = true;
591+
port->types.variable.is_output = true;
592+
593+
/* add this output to the modules string cache */
594+
sc_spot = sc_add_string(this_inouts_sc, port->children[0]->types.identifier);
595+
596+
/* store the data which is an idx here */
597+
this_inouts_sc->data[sc_spot] = (void*)port;
598+
571599
break;
572600

573601
default:
@@ -582,10 +610,10 @@ ast_node_t* markAndProcessPortWith(ids top_type, ids port_id, ids net_id, ast_no
582610
} else if (port->types.variable.is_inout
583611
&& !(port->types.variable.is_input)
584612
&& !(port->types.variable.is_output)) {
585-
error_message(AST, port->line_number, current_parse_file, "Odin does not handle inouts (%s)\n", port->children[0]->types.identifier);
586613
port = markAndProcessPortWith(top_type, INOUT, net_id, port, is_signed);
587614
} else {
588615
// shouldn't ever get here...
616+
oassert( false && "This is just my own debugging thing and if this gets merged I have a bad memory and noone reviewed it"); // TODO Check if this is valid
589617
oassert(port->types.variable.is_input
590618
|| port->types.variable.is_output
591619
|| port->types.variable.is_inout);
@@ -1776,9 +1804,11 @@ void next_task() {
17761804
/* old ones are done so clean */
17771805
sc_free_string_cache(tasks_inputs_sc);
17781806
sc_free_string_cache(tasks_outputs_sc);
1807+
sc_free_string_cache(tasks_inouts_sc);
17791808
/* make for next task */
17801809
tasks_inputs_sc = sc_new_string_cache();
17811810
tasks_outputs_sc = sc_new_string_cache();
1811+
tasks_inouts_sc = sc_new_string_cache();
17821812
}
17831813
/*---------------------------------------------------------------------------------------------
17841814
* (function: next_function)
@@ -1793,9 +1823,11 @@ void next_function() {
17931823
/* old ones are done so clean */
17941824
sc_free_string_cache(functions_inputs_sc);
17951825
sc_free_string_cache(functions_outputs_sc);
1826+
sc_free_string_cache(functions_inouts_sc);
17961827
/* make for next function */
17971828
functions_inputs_sc = sc_new_string_cache();
17981829
functions_outputs_sc = sc_new_string_cache();
1830+
functions_inouts_sc = sc_new_string_cache();
17991831
}
18001832
/*---------------------------------------------------------------------------------------------
18011833
* (function: next_module)
@@ -1813,10 +1845,12 @@ void next_module() {
18131845
/* old ones are done so clean */
18141846
sc_free_string_cache(modules_inputs_sc);
18151847
sc_free_string_cache(modules_outputs_sc);
1848+
sc_free_string_cache(modules_inouts_sc);
18161849
sc_free_string_cache(module_instances_sc);
18171850
/* make for next module */
18181851
modules_inputs_sc = sc_new_string_cache();
18191852
modules_outputs_sc = sc_new_string_cache();
1853+
modules_inouts_sc = sc_new_string_cache();
18201854
module_instances_sc = sc_new_string_cache();
18211855
}
18221856

ODIN_II/regression_test/benchmark/verilog/syntax/inout-syntax/inout_basic.v

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module inout_assign(inout a);
2+
reg r;
3+
always @(*)
4+
begin
5+
r = a;
6+
end
7+
endmodule
8+
9+
module inout_basic(b);
10+
input b;
11+
inout_assign c(b);
12+
endmodule
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
GLOBAL_SIM_BASE_CLK a
2+
0 0
3+
0 1

ODIN_II/regression_test/benchmark/verilog/syntax/inout-syntax/inout_input_only_output

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
GLOBAL_SIM_BASE_CLK
2+
0
3+
0
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
b
2+
1
3+
1
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module inout_assign(inout a);
2+
assign a = 1;
3+
endmodule
4+
5+
module inout_basic(b);
6+
output b;
7+
inout_assign c(b);
8+
endmodule

0 commit comments

Comments
 (0)