@@ -1194,6 +1194,82 @@ void CreateModelLibrary(t_arch* arch) {
11941194 arch->model_library = model_library;
11951195}
11961196
1197+ void SyncModel (t_pb_type* pb_type, t_model* model_match_prim, bool is_secondary_model) {
1198+ vtr::t_linked_vptr* old;
1199+ bool found;
1200+ t_model_ports* model_port;
1201+ t_port* pb_type_ports;
1202+ int p;
1203+
1204+ if (is_secondary_model) {
1205+ pb_type->model_sec = model_match_prim;
1206+ pb_type_ports = pb_type->ports_sec ;
1207+ } else {
1208+ pb_type->model = model_match_prim;
1209+ pb_type_ports = pb_type->ports ;
1210+ }
1211+
1212+ old = model_match_prim->pb_types ;
1213+ model_match_prim->pb_types = (vtr::t_linked_vptr*)vtr::malloc (sizeof (vtr::t_linked_vptr));
1214+ model_match_prim->pb_types ->next = old;
1215+ model_match_prim->pb_types ->data_vptr = pb_type;
1216+ for (p = 0 ; p < pb_type->num_ports ; p++) {
1217+ found = false ;
1218+ /* TODO: Parse error checking - check if INPUT matches INPUT and OUTPUT matches OUTPUT (not yet done) */
1219+ model_port = model_match_prim->inputs ;
1220+ while (model_port && !found) {
1221+ if (strcmp (model_port->name , pb_type_ports[p].name ) == 0 ) {
1222+ if (model_port->size < pb_type_ports[p].num_pins ) {
1223+ model_port->size = pb_type_ports[p].num_pins ;
1224+ }
1225+ if (model_port->min_size > pb_type_ports[p].num_pins
1226+ || model_port->min_size == -1 ) {
1227+ model_port->min_size = pb_type_ports[p].num_pins ;
1228+ }
1229+ pb_type_ports[p].model_port = model_port;
1230+ if (pb_type_ports[p].type != model_port->dir ) {
1231+ archfpga_throw (get_arch_file_name (), 0 ,
1232+ " Direction for port '%s' on model does not match port direction in pb_type '%s', secondary: %d\n " ,
1233+ pb_type_ports[p].name , pb_type->name , is_secondary_model);
1234+ }
1235+ if (pb_type_ports[p].is_clock != model_port->is_clock ) {
1236+ archfpga_throw (get_arch_file_name (), 0 ,
1237+ " Port '%s' on model does not match is_clock in pb_type '%s', secondary: %d\n " ,
1238+ pb_type_ports[p].name , pb_type->name , is_secondary_model);
1239+ }
1240+ found = true ;
1241+ }
1242+ model_port = model_port->next ;
1243+ }
1244+ model_port = model_match_prim->outputs ;
1245+ while (model_port && !found) {
1246+ if (strcmp (model_port->name , pb_type_ports[p].name ) == 0 ) {
1247+ if (model_port->size < pb_type_ports[p].num_pins ) {
1248+ model_port->size = pb_type_ports[p].num_pins ;
1249+ }
1250+ if (model_port->min_size > pb_type_ports[p].num_pins
1251+ || model_port->min_size == -1 ) {
1252+ model_port->min_size = pb_type_ports[p].num_pins ;
1253+ }
1254+
1255+ pb_type_ports[p].model_port = model_port;
1256+ if (pb_type_ports[p].type != model_port->dir ) {
1257+ archfpga_throw (get_arch_file_name (), 0 ,
1258+ " Direction for port '%s' on model does not match port direction in pb_type '%s', secondary: %d\n " ,
1259+ pb_type_ports[p].name , pb_type->name , is_secondary_model);
1260+ }
1261+ found = true ;
1262+ }
1263+ model_port = model_port->next ;
1264+ }
1265+ if (found != true ) {
1266+ archfpga_throw (get_arch_file_name (), 0 ,
1267+ " No matching model port for port %s in pb_type %s, secondary: %d\n " ,
1268+ pb_type_ports[p].name , pb_type->name , is_secondary_model);
1269+ }
1270+ }
1271+ }
1272+
11971273void SyncModelsPbTypes (t_arch* arch,
11981274 const std::vector<t_logical_block_type>& Types) {
11991275 for (auto & Type : Types) {
@@ -1205,12 +1281,10 @@ void SyncModelsPbTypes(t_arch* arch,
12051281
12061282void SyncModelsPbTypes_rec (t_arch* arch,
12071283 t_pb_type* pb_type) {
1208- int i, j, p ;
1284+ int i, j;
12091285 t_model *model_match_prim, *cur_model;
1210- t_model_ports* model_port;
1211- vtr::t_linked_vptr* old;
12121286 char * blif_model_name = nullptr ;
1213-
1287+ bool sync_secondary_model = false ;
12141288 bool found;
12151289
12161290 if (pb_type->blif_model != nullptr ) {
@@ -1239,6 +1313,15 @@ void SyncModelsPbTypes_rec(t_arch* arch,
12391313 while (cur_model && !found) {
12401314 /* blif model always starts with .subckt so need to skip first 8 characters */
12411315 if (strcmp (blif_model_name, cur_model->name ) == 0 ) {
1316+ if (strcmp (blif_model_name, MODEL_LATCH) == 0 ) {
1317+ /* *
1318+ * Special case for .latch: this model exists in 2 variations which are
1319+ * defined one after another in linked list, make sure the second variant match
1320+ * and mark secondary model for sync.
1321+ */
1322+ VTR_ASSERT (strcmp (blif_model_name, cur_model->next ->name ) == 0 );
1323+ sync_secondary_model = true ;
1324+ }
12421325 found = true ;
12431326 model_match_prim = cur_model;
12441327 }
@@ -1249,67 +1332,11 @@ void SyncModelsPbTypes_rec(t_arch* arch,
12491332 " No matching model for pb_type %s\n " , pb_type->blif_model );
12501333 }
12511334
1252- pb_type->model = model_match_prim;
1253- old = model_match_prim->pb_types ;
1254- model_match_prim->pb_types = (vtr::t_linked_vptr*)vtr::malloc (sizeof (vtr::t_linked_vptr));
1255- model_match_prim->pb_types ->next = old;
1256- model_match_prim->pb_types ->data_vptr = pb_type;
1257-
1258- for (p = 0 ; p < pb_type->num_ports ; p++) {
1259- found = false ;
1260- /* TODO: Parse error checking - check if INPUT matches INPUT and OUTPUT matches OUTPUT (not yet done) */
1261- model_port = model_match_prim->inputs ;
1262- while (model_port && !found) {
1263- if (strcmp (model_port->name , pb_type->ports [p].name ) == 0 ) {
1264- if (model_port->size < pb_type->ports [p].num_pins ) {
1265- model_port->size = pb_type->ports [p].num_pins ;
1266- }
1267- if (model_port->min_size > pb_type->ports [p].num_pins
1268- || model_port->min_size == -1 ) {
1269- model_port->min_size = pb_type->ports [p].num_pins ;
1270- }
1271- pb_type->ports [p].model_port = model_port;
1272- if (pb_type->ports [p].type != model_port->dir ) {
1273- archfpga_throw (get_arch_file_name (), 0 ,
1274- " Direction for port '%s' on model does not match port direction in pb_type '%s'\n " ,
1275- pb_type->ports [p].name , pb_type->name );
1276- }
1277- if (pb_type->ports [p].is_clock != model_port->is_clock ) {
1278- archfpga_throw (get_arch_file_name (), 0 ,
1279- " Port '%s' on model does not match is_clock in pb_type '%s'\n " ,
1280- pb_type->ports [p].name , pb_type->name );
1281- }
1282- found = true ;
1283- }
1284- model_port = model_port->next ;
1285- }
1286- model_port = model_match_prim->outputs ;
1287- while (model_port && !found) {
1288- if (strcmp (model_port->name , pb_type->ports [p].name ) == 0 ) {
1289- if (model_port->size < pb_type->ports [p].num_pins ) {
1290- model_port->size = pb_type->ports [p].num_pins ;
1291- }
1292- if (model_port->min_size > pb_type->ports [p].num_pins
1293- || model_port->min_size == -1 ) {
1294- model_port->min_size = pb_type->ports [p].num_pins ;
1295- }
1335+ SyncModel (pb_type, model_match_prim, false );
1336+ // Synchronize secondary model
1337+ if (sync_secondary_model)
1338+ SyncModel (pb_type, model_match_prim->next , true );
12961339
1297- pb_type->ports [p].model_port = model_port;
1298- if (pb_type->ports [p].type != model_port->dir ) {
1299- archfpga_throw (get_arch_file_name (), 0 ,
1300- " Direction for port '%s' on model does not match port direction in pb_type '%s'\n " ,
1301- pb_type->ports [p].name , pb_type->name );
1302- }
1303- found = true ;
1304- }
1305- model_port = model_port->next ;
1306- }
1307- if (found != true ) {
1308- archfpga_throw (get_arch_file_name (), 0 ,
1309- " No matching model port for port %s in pb_type %s\n " ,
1310- pb_type->ports [p].name , pb_type->name );
1311- }
1312- }
13131340 } else {
13141341 for (i = 0 ; i < pb_type->num_modes ; i++) {
13151342 for (j = 0 ; j < pb_type->modes [i].num_pb_type_children ; j++) {
0 commit comments