Skip to content

Commit f8cc12c

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

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
@@ -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+
11971273
void 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

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

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)