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