Skip to content

Commit 1e4ed54

Browse files
committed
odin - improve hard block port mapping
1 parent a922bdf commit 1e4ed54

File tree

2 files changed

+146
-20
lines changed

2 files changed

+146
-20
lines changed

ODIN_II/SRC/ast_elaborate.cpp

Lines changed: 144 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ ast_node_t *get_chunk_size_node(char *instance_name_prefix, char *array_name, ST
114114
bool verify_terminal(ast_node_t *top, ast_node_t *iterator);
115115
void verify_genvars(ast_node_t *node, STRING_CACHE_LIST *local_string_cache_list, char ***other_genvars, int num_genvars);
116116

117-
ast_node_t *look_for_matching_hard_block(ast_node_t *node, char *hard_block_name);
117+
ast_node_t *look_for_matching_hard_block(ast_node_t *node, char *hard_block_name, STRING_CACHE_LIST *local_string_cache_list);
118118
ast_node_t *look_for_matching_soft_logic(ast_node_t *node, char *hard_block_name);
119119

120120

@@ -249,7 +249,7 @@ ast_node_t *reduce_expressions(ast_node_t *node, ast_node_t *parent, STRING_CACH
249249
|| !strcmp(module_ref_name, DUAL_PORT_RAM_string)
250250
)
251251
{
252-
ast_node_t *hb_node = look_for_matching_hard_block(node->children[0], module_ref_name);
252+
ast_node_t *hb_node = look_for_matching_hard_block(node->children[0], module_ref_name, local_string_cache_list);
253253
if (hb_node != node->children[0])
254254
{
255255
free_whole_tree(node);
@@ -1226,7 +1226,7 @@ void verify_genvars(ast_node_t *node, STRING_CACHE_LIST *local_string_cache_list
12261226
}
12271227
}
12281228

1229-
ast_node_t *look_for_matching_hard_block(ast_node_t *node, char *hard_block_name)
1229+
ast_node_t *look_for_matching_hard_block(ast_node_t *node, char *hard_block_name, STRING_CACHE_LIST *local_string_cache_list)
12301230
{
12311231
t_model *hb_model = find_hard_block(hard_block_name);
12321232
bool is_hb = true;
@@ -1238,7 +1238,6 @@ ast_node_t *look_for_matching_hard_block(ast_node_t *node, char *hard_block_name
12381238
}
12391239
else
12401240
{
1241-
12421241
t_model_ports *hb_input_ports = hb_model->inputs;
12431242
t_model_ports *hb_output_ports = hb_model->outputs;
12441243

@@ -1257,6 +1256,7 @@ ast_node_t *look_for_matching_hard_block(ast_node_t *node, char *hard_block_name
12571256
hb_output_ports = hb_output_ports->next;
12581257
}
12591258

1259+
12601260
ast_node_t *connect_list = node->children[1]->children[1];
12611261

12621262
/* first check if the number of ports match up */
@@ -1265,9 +1265,12 @@ ast_node_t *look_for_matching_hard_block(ast_node_t *node, char *hard_block_name
12651265
is_hb = false;
12661266
}
12671267

1268+
12681269
if (is_hb && connect_list->children[0]->children[0] != NULL)
12691270
{
1270-
/* if all port names match up, this is a hard block */
1271+
/* number of ports match and ports were passed in by name;
1272+
* if all port names match up, this is a hard block */
1273+
12711274
for (int i = 0; i < connect_list->num_children && is_hb; i++)
12721275
{
12731276
oassert(connect_list->children[i]->children[0]);
@@ -1289,42 +1292,165 @@ ast_node_t *look_for_matching_hard_block(ast_node_t *node, char *hard_block_name
12891292
}
12901293
else
12911294
{
1292-
continue; // matching input was found
1295+
/* matching input was found; move on to the next port connection */
1296+
continue;
12931297
}
12941298

12951299
if (hb_output_ports == NULL)
12961300
{
1297-
is_hb = false; // ports don't match up
1301+
/* name doesn't match up with any of the defined ports; this is not a hard block */
1302+
is_hb = false;
12981303
}
12991304
else
13001305
{
1301-
continue; // matching output was found
1306+
/* matching output was found; move on to the next port connection */
1307+
continue;
13021308
}
13031309
}
13041310
}
13051311
else if (is_hb)
13061312
{
1307-
/* number of ports match, so default to a hard block */
1313+
/* number of ports match and ports were passed in by ordered list;
1314+
* this is risky, but we will try to do some "smart" mapping to mark inputs and outputs
1315+
* by evaluating the port connections to determine the order */
1316+
13081317
warning_message(NETLIST_ERROR, connect_list->line_number, connect_list->file_number,
1309-
"Converting this instance to a hard block (%s) - unnamed port connections will be matched according to hard block specification\n", hard_block_name);
1318+
"Attempting to convert this instance to a hard block (%s) - unnamed port connections will be matched according to hard block specification and may produce unexpected results\n", hard_block_name);
1319+
1320+
t_model_ports *hb_ports_1 = NULL, *hb_ports_2 = NULL;
1321+
bool is_input, is_output;
1322+
int num_ports;
13101323

13111324
hb_input_ports = hb_model->inputs;
13121325
hb_output_ports = hb_model->outputs;
1313-
int i = 0;
13141326

1315-
while (hb_output_ports)
1327+
/* decide whether to look for inputs or outputs based on what there are less of */
1328+
if (num_hb_inputs <= num_hb_outputs)
1329+
{
1330+
is_input = true;
1331+
is_output = false;
1332+
num_ports = num_hb_inputs;
1333+
}
1334+
else
1335+
{
1336+
is_input = false;
1337+
is_output = true;
1338+
num_ports = num_hb_outputs;
1339+
}
1340+
1341+
STRING_CACHE *local_symbol_table_sc = local_string_cache_list->local_symbol_table_sc;
1342+
1343+
int i;
1344+
1345+
/* look through the first N (num_ports) port connections to look for a match */
1346+
for (i = 0; i < num_ports; i++)
1347+
{
1348+
char *port_id = connect_list->children[i]->children[1]->types.identifier;
1349+
long sc_spot = sc_lookup_string(local_symbol_table_sc, port_id);
1350+
oassert(sc_spot > -1);
1351+
ast_node_t *var_declare = (ast_node_t *)local_symbol_table_sc->data[sc_spot];
1352+
1353+
if (var_declare->types.variable.is_output == is_output
1354+
&& var_declare->types.variable.is_input == is_input)
1355+
{
1356+
/* found a match! check if it's an input or output */
1357+
if (is_input)
1358+
{
1359+
hb_ports_1 = hb_model->inputs;
1360+
hb_ports_2 = hb_model->outputs;
1361+
}
1362+
else
1363+
{
1364+
hb_ports_1 = hb_model->outputs;
1365+
hb_ports_2 = hb_model->inputs;
1366+
}
1367+
break;
1368+
}
1369+
else if (var_declare->types.variable.is_output != is_output
1370+
&& var_declare->types.variable.is_input != is_input)
1371+
{
1372+
/* found the opposite of what we were looking for */
1373+
if (is_input)
1374+
{
1375+
hb_ports_1 = hb_model->outputs;
1376+
hb_ports_2 = hb_model->inputs;
1377+
}
1378+
else
1379+
{
1380+
hb_ports_1 = hb_model->inputs;
1381+
hb_ports_2 = hb_model->outputs;
1382+
}
1383+
break;
1384+
}
1385+
}
1386+
1387+
/* if a match hasn't been found yet, look through the last N (num_ports) port connections */
1388+
if (!(hb_ports_1 && hb_ports_2))
1389+
{
1390+
for (i = connect_list->num_children - num_ports; i < connect_list->num_children; i++)
1391+
{
1392+
char *port_id = connect_list->children[i]->children[1]->types.identifier;
1393+
long sc_spot = sc_lookup_string(local_symbol_table_sc, port_id);
1394+
oassert(sc_spot > -1);
1395+
ast_node_t *var_declare = (ast_node_t *)local_symbol_table_sc->data[sc_spot];
1396+
1397+
if (var_declare->types.variable.is_output == is_output
1398+
&& var_declare->types.variable.is_input == is_input)
1399+
{
1400+
/* found a match! since we're at the other end, inputs/outputs should be reversed */
1401+
if (is_input)
1402+
{
1403+
hb_ports_1 = hb_model->outputs;
1404+
hb_ports_2 = hb_model->inputs;
1405+
}
1406+
else
1407+
{
1408+
hb_ports_1 = hb_model->inputs;
1409+
hb_ports_2 = hb_model->outputs;
1410+
}
1411+
break;
1412+
}
1413+
else if (var_declare->types.variable.is_output != is_output
1414+
&& var_declare->types.variable.is_input != is_input)
1415+
{
1416+
/* found the opposite of what we were looking for */
1417+
if (is_input)
1418+
{
1419+
hb_ports_1 = hb_model->inputs;
1420+
hb_ports_2 = hb_model->outputs;
1421+
}
1422+
else
1423+
{
1424+
hb_ports_1 = hb_model->outputs;
1425+
hb_ports_2 = hb_model->inputs;
1426+
}
1427+
break;
1428+
}
1429+
}
1430+
}
1431+
1432+
/* if a match hasn't been found, then there is no way to tell what should be done first;
1433+
* we will default to inputs first, then outputs after (this is an arbitrary decision) */
1434+
if (!(hb_ports_1 && hb_ports_2))
1435+
{
1436+
hb_ports_1 = hb_model->inputs;
1437+
hb_ports_2 = hb_model->outputs;
1438+
}
1439+
1440+
/* attach new port identifiers for later reference when building the hard block */
1441+
i = 0;
1442+
while (hb_ports_1)
13161443
{
13171444
oassert(connect_list->children[i] && !connect_list->children[i]->children[0]);
1318-
connect_list->children[i]->children[0] = newSymbolNode(vtr::strdup(hb_output_ports->name), connect_list->line_number);
1319-
hb_output_ports = hb_output_ports->next;
1445+
connect_list->children[i]->children[0] = newSymbolNode(vtr::strdup(hb_ports_1->name), connect_list->line_number);
1446+
hb_ports_1 = hb_ports_1->next;
13201447
i++;
13211448
}
1322-
1323-
while (hb_input_ports)
1449+
while (hb_ports_2)
13241450
{
13251451
oassert(connect_list->children[i] && !connect_list->children[i]->children[0]);
1326-
connect_list->children[i]->children[0] = newSymbolNode(vtr::strdup(hb_input_ports->name), connect_list->line_number);
1327-
hb_input_ports = hb_input_ports->next;
1452+
connect_list->children[i]->children[0] = newSymbolNode(vtr::strdup(hb_ports_2->name), connect_list->line_number);
1453+
hb_ports_2 = hb_ports_2->next;
13281454
i++;
13291455
}
13301456
}

ODIN_II/regression_test/benchmark/task/rs_decoder/task.conf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ script_simulation_params=--time_limit 3600s
1010
arch_dir=../vtr_flow/arch/timing
1111

1212
arch_list_add=k6_N10_40nm.xml
13-
# arch_list_add=k6_N10_mem32K_40nm.xml
14-
#arch_list_add=k6_frac_N10_frac_chain_mem32K_40nm.xml
13+
arch_list_add=k6_N10_mem32K_40nm.xml
14+
arch_list_add=k6_frac_N10_frac_chain_mem32K_40nm.xml
1515

1616
# setup the circuits
1717
circuit_dir=regression_test/benchmark/verilog/syntax

0 commit comments

Comments
 (0)