Skip to content

Commit 1d9b571

Browse files
committed
Add error check for duplicate pin location side specifications
Cases such as: <pinlocations pattern="custom"> <loc side="left">clb.I clb.clk</loc> <loc side="left">clb.O</loc> </pinlocations> are now treated as illegal, since pins are specified multiple times for the 'left' side. Previously the last of the matching specifications would overwrite the earlier specifications. The correct format would be: <pinlocations pattern="custom"> <loc side="left">clb.O clb.I clb.clk</loc> </pinlocations>
1 parent 78b6c24 commit 1d9b571

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ static void SetupPinLocationsAndPinClasses(pugi::xml_node Locations,
365365
/* Load the pin locations */
366366
if (Type->pin_location_distribution == E_CUSTOM_PIN_DISTR) {
367367
Cur = Locations.first_child();
368+
std::set<e_side> seen_sides;
368369
while (Cur) {
369370
check_node(Cur, "loc", loc_data);
370371

@@ -377,7 +378,7 @@ static void SetupPinLocationsAndPinClasses(pugi::xml_node Locations,
377378
}
378379

379380
/* Get side */
380-
int side = 0;
381+
e_side side;
381382
Prop = get_attribute(Cur, "side", loc_data).value();
382383
if (0 == strcmp(Prop, "left")) {
383384
side = LEFT;
@@ -392,6 +393,14 @@ static void SetupPinLocationsAndPinClasses(pugi::xml_node Locations,
392393
"'%s' is not a valid side.\n", Prop);
393394
}
394395

396+
//Check for duplicate side specifications, since the code below silently overwrites if there are duplicates
397+
if (seen_sides.count(side)) {
398+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
399+
"Duplicate pin location side specification. Only a single <loc> per side is permitted.\n");
400+
} else {
401+
seen_sides.insert(side);
402+
}
403+
395404
/* Check location is on perimeter */
396405
if ((TOP == side) && (height != (Type->height - 1))) {
397406
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
@@ -408,12 +417,10 @@ static void SetupPinLocationsAndPinClasses(pugi::xml_node Locations,
408417
Count = Tokens.size();
409418
Type->num_pin_loc_assignments[0][height][side] = Count;
410419
if (Count > 0) {
411-
Type->pin_loc_assignments[0][height][side] = (char**) vtr::calloc(
412-
Count, sizeof(char*));
420+
Type->pin_loc_assignments[0][height][side] = (char**) vtr::calloc(Count, sizeof(char*));
413421
for (int pin = 0; pin < Count; ++pin) {
414422
/* Store location assignment */
415-
Type->pin_loc_assignments[0][height][side][pin] = vtr::strdup(
416-
Tokens[pin].c_str());
423+
Type->pin_loc_assignments[0][height][side][pin] = vtr::strdup(Tokens[pin].c_str());
417424

418425
/* Advance through list of pins in this location */
419426
}

0 commit comments

Comments
 (0)