Skip to content

Commit e0ad04e

Browse files
committed
libarchfpga: SyncModelsPbTypes: sync secondary models
Signed-off-by: Pawel Czarnecki <pczarnecki@antmicro.com>
1 parent ad23895 commit e0ad04e

File tree

2 files changed

+95
-64
lines changed

2 files changed

+95
-64
lines changed

libs/libarchfpga/src/arch_util.cpp

Lines changed: 91 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
11951271
void 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

12041280
void 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++) {

libs/libarchfpga/src/arch_util.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ e_power_estimation_method power_method_inherited(e_power_estimation_method paren
8686

8787
void CreateModelLibrary(t_arch* arch);
8888

89+
void SyncModel(t_pb_type* pb_type,
90+
t_model* model_match_prim,
91+
bool is_secondary_model);
92+
8993
void SyncModelsPbTypes(t_arch* arch,
9094
const std::vector<t_logical_block_type>& Types);
9195

0 commit comments

Comments
 (0)