@@ -114,7 +114,7 @@ ast_node_t *get_chunk_size_node(char *instance_name_prefix, char *array_name, ST
114
114
bool verify_terminal (ast_node_t *top, ast_node_t *iterator);
115
115
void verify_genvars (ast_node_t *node, STRING_CACHE_LIST *local_string_cache_list, char ***other_genvars, int num_genvars);
116
116
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 );
118
118
ast_node_t *look_for_matching_soft_logic (ast_node_t *node, char *hard_block_name);
119
119
120
120
@@ -249,7 +249,7 @@ ast_node_t *reduce_expressions(ast_node_t *node, ast_node_t *parent, STRING_CACH
249
249
|| !strcmp (module_ref_name, DUAL_PORT_RAM_string)
250
250
)
251
251
{
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 );
253
253
if (hb_node != node->children [0 ])
254
254
{
255
255
free_whole_tree (node);
@@ -1226,7 +1226,7 @@ void verify_genvars(ast_node_t *node, STRING_CACHE_LIST *local_string_cache_list
1226
1226
}
1227
1227
}
1228
1228
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 )
1230
1230
{
1231
1231
t_model *hb_model = find_hard_block (hard_block_name);
1232
1232
bool is_hb = true ;
@@ -1238,7 +1238,6 @@ ast_node_t *look_for_matching_hard_block(ast_node_t *node, char *hard_block_name
1238
1238
}
1239
1239
else
1240
1240
{
1241
-
1242
1241
t_model_ports *hb_input_ports = hb_model->inputs ;
1243
1242
t_model_ports *hb_output_ports = hb_model->outputs ;
1244
1243
@@ -1257,6 +1256,7 @@ ast_node_t *look_for_matching_hard_block(ast_node_t *node, char *hard_block_name
1257
1256
hb_output_ports = hb_output_ports->next ;
1258
1257
}
1259
1258
1259
+
1260
1260
ast_node_t *connect_list = node->children [1 ]->children [1 ];
1261
1261
1262
1262
/* 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
1265
1265
is_hb = false ;
1266
1266
}
1267
1267
1268
+
1268
1269
if (is_hb && connect_list->children [0 ]->children [0 ] != NULL )
1269
1270
{
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
+
1271
1274
for (int i = 0 ; i < connect_list->num_children && is_hb; i++)
1272
1275
{
1273
1276
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
1289
1292
}
1290
1293
else
1291
1294
{
1292
- continue ; // matching input was found
1295
+ /* matching input was found; move on to the next port connection */
1296
+ continue ;
1293
1297
}
1294
1298
1295
1299
if (hb_output_ports == NULL )
1296
1300
{
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 ;
1298
1303
}
1299
1304
else
1300
1305
{
1301
- continue ; // matching output was found
1306
+ /* matching output was found; move on to the next port connection */
1307
+ continue ;
1302
1308
}
1303
1309
}
1304
1310
}
1305
1311
else if (is_hb)
1306
1312
{
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
+
1308
1317
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;
1310
1323
1311
1324
hb_input_ports = hb_model->inputs ;
1312
1325
hb_output_ports = hb_model->outputs ;
1313
- int i = 0 ;
1314
1326
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)
1316
1443
{
1317
1444
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 ;
1320
1447
i++;
1321
1448
}
1322
-
1323
- while (hb_input_ports)
1449
+ while (hb_ports_2)
1324
1450
{
1325
1451
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 ;
1328
1454
i++;
1329
1455
}
1330
1456
}
0 commit comments