Skip to content

Commit fb147ad

Browse files
committed
arch: refactoring of pin location processing
Signed-off-by: Alessandro Comodi <[email protected]>
1 parent 5f75b3a commit fb147ad

File tree

2 files changed

+91
-77
lines changed

2 files changed

+91
-77
lines changed

libs/libarchfpga/src/physical_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,8 @@ struct t_sub_tile {
637637
std::vector<t_physical_tile_port> ports;
638638

639639
std::vector<t_logical_block_type_ptr> equivalent_sites;
640+
641+
int index = -1;
640642
}
641643

642644
/** A logical pin defines the pin index of a logical block type (i.e. a top level PB type)

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 89 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -83,24 +83,21 @@ struct t_pin_counts {
8383
}
8484
};
8585

86-
struct t_pin_loc_assignments {
87-
private bool pin_distribution_set = false;
86+
struct t_pin_loc {
87+
private bool distribution_set = false;
8888

89-
enum e_pin_location_distr pin_location_distribution = E_SPREAD_PIN_DISTR;
89+
enum e_pin_location_distr distribution = E_SPREAD_PIN_DISTR;
9090

91-
/* [0..width-1][0..height-1][0..3] */
92-
std::vector<std::vector<std::vector<int>>> num_assignments;
91+
/* [0..num_sub_tiles-1][0..width-1][0..height-1][0..3][0..num_tokens-1] */
92+
std::vector<std::vector<std::vector<std::vector<std::vector<std::string>>>>> assignments;
9393

94-
/* [0..width-1][0..height-1][0..3][0..num_tokens-1][string_name] */
95-
std::vector<std::vector<std::vector<std::vector<std::string>>>> assignments;
96-
97-
bool is_pin_distribution_set() {
98-
return pin_distribution_set;
94+
bool is_distribution_set() {
95+
return distribution_set;
9996
}
10097

101-
void set_pin_distribution() {
102-
VTR_ASSERT(pin_distribution_set == false);
103-
pin_distribution = true;
98+
void set_distribution() {
99+
VTR_ASSERT(distribution_set == false);
100+
distribution = true;
104101
}
105102

106103
};
@@ -111,12 +108,13 @@ static const char* arch_file_name = nullptr;
111108

112109
/* Function prototypes */
113110
/* Populate data */
114-
static void SetupPinLocationsAndPinClasses(pugi::xml_node Locations,
115-
t_physical_tile_type* PhysicalTileType,
116-
const pugiutil::loc_data& loc_data);
111+
static void SetupPinClasses(pugi::xml_node Locations,
112+
t_physical_tile_type* PhysicalTileType,
113+
const pugiutil::loc_data& loc_data);
117114

118115
static void LoadPinLoc(pugi::xml_node Locations,
119116
t_physical_tile_type* type,
117+
t_pin_loc* pin_loc,
120118
const pugiutil::loc_data& loc_data);
121119
template<typename T>
122120
static std::pair<int, int> ProcessPinString(pugi::xml_node Locations,
@@ -160,7 +158,7 @@ static void ProcessEquivalentSiteCustomConnection(pugi::xml_node Parent,
160158
static void ProcessPinLocations(pugi::xml_node Locations,
161159
t_physical_tile_type* PhysicalTileType,
162160
t_sub_tile* SubTile,
163-
t_pin_loc_assignments* pin_loc_assignments,
161+
t_pin_loc* pin_loc,
164162
const pugiutil::loc_data& loc_data);
165163
static void ProcessSubTiles(pugi::xml_node Node,
166164
t_physical_tile_type* PhysicalTileType
@@ -463,16 +461,14 @@ void XmlReadArch(const char* ArchFile,
463461
*
464462
*/
465463

466-
/* Sets up the pinloc map and pin classes for the type.
467-
* Pins and pin classes must already be setup by SetupPinClasses */
468-
static void SetupPinLocationsAndPinClasses(pugi::xml_node Locations,
469-
t_physical_tile_type* PhysicalTileType,
470-
const pugiutil::loc_data& loc_data) {
464+
/* Sets up the pin classes for the type. */
465+
static void SetupPinClasses(pugi::xml_node Locations,
466+
t_physical_tile_type* PhysicalTileType,
467+
const pugiutil::loc_data& loc_data) {
471468
int i, k, Count;
472469
int capacity
473470
int pin_count;
474471
int num_class;
475-
const char* Prop;
476472

477473
pugi::xml_node Cur;
478474

@@ -551,12 +547,13 @@ static void SetupPinLocationsAndPinClasses(pugi::xml_node Locations,
551547

552548
static void LoadPinLoc(pugi::xml_node Locations,
553549
t_physical_tile_type* type,
550+
t_pin_loc* pin_loc;
554551
const pugiutil::loc_data& loc_data) {
555552
type->pin_width_offset.resize(type->num_pins, 0);
556553
type->pin_height_offset.resize(type->num_pins, 0);
557554

558555
std::vector<int> physical_pin_counts(type->num_pins, 0);
559-
if (type->pin_location_distribution == E_SPREAD_PIN_DISTR) {
556+
if (pin_loc->distribution == E_SPREAD_PIN_DISTR) {
560557
/* evenly distribute pins starting at bottom left corner */
561558

562559
int num_sides = 4 * (type->width * type->height);
@@ -581,7 +578,7 @@ static void LoadPinLoc(pugi::xml_node Locations,
581578
}
582579
VTR_ASSERT(side_index == num_sides);
583580
VTR_ASSERT(count == type->num_pins);
584-
} else if (type->pin_location_distribution == E_PERIMETER_PIN_DISTR) {
581+
} else if (pin_loc->distribution == E_PERIMETER_PIN_DISTR) {
585582
//Add one pin at-a-time to perimeter sides in round-robin order
586583
int ipin = 0;
587584
while (ipin < type->num_pins) {
@@ -607,7 +604,7 @@ static void LoadPinLoc(pugi::xml_node Locations,
607604
}
608605
VTR_ASSERT(ipin == type->num_pins);
609606

610-
} else if (type->pin_location_distribution == E_SPREAD_INPUTS_PERIMETER_OUTPUTS_PIN_DISTR) {
607+
} else if (pin_loc->distribution == E_SPREAD_INPUTS_PERIMETER_OUTPUTS_PIN_DISTR) {
611608
//Collect the sets of block input/output pins
612609
std::vector<int> input_pins;
613610
std::vector<int> output_pins;
@@ -675,22 +672,28 @@ static void LoadPinLoc(pugi::xml_node Locations,
675672

676673
} else {
677674
VTR_ASSERT(type->pin_location_distribution == E_CUSTOM_PIN_DISTR);
678-
for (int width = 0; width < type->width; ++width) {
679-
for (int height = 0; height < type->height; ++height) {
680-
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
681-
for (int pin = 0; pin < type->num_pin_loc_assignments[width][height][side]; ++pin) {
682-
auto pin_range = ProcessPinString<t_physical_tile_type_ptr>(Locations,
683-
type,
684-
type->pin_loc_assignments[width][height][side][pin],
685-
loc_data);
686-
687-
for (int pin_num = pin_range.first; pin_num < pin_range.second; ++pin_num) {
688-
VTR_ASSERT(pin_num < type->num_pins / type->capacity);
689-
for (int capacity = 0; capacity < type->capacity; ++capacity) {
690-
type->pinloc[width][height][side][pin_num + capacity * type->num_pins / type->capacity] = true;
691-
type->pin_width_offset[pin_num + capacity * type->num_pins / type->capacity] += width;
692-
type->pin_height_offset[pin_num + capacity * type->num_pins / type->capacity] += height;
693-
physical_pin_counts[pin_num + capacity * type->num_pins / type->capacity] += 1;
675+
for (const auto& sub_tile : PhysicalTileType->sub_tiles) {
676+
int sub_tile_index = sub_tile->index;
677+
678+
for (int width = 0; width < type->width; ++width) {
679+
for (int height = 0; height < type->height; ++height) {
680+
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
681+
for (auto token : pin_loc->assignments[sub_tile_index][width][height][side]) {
682+
auto pin_range = ProcessPinString<t_sub_tile>(Locations,
683+
sub_tile,
684+
token.c_str(),
685+
loc_data);
686+
687+
for (int pin_num = pin_range.first; pin_num < pin_range.second; ++pin_num) {
688+
VTR_ASSERT(pin_num < sub_tile->sub_tile_to_tile_pin_indices.size() / sub_tile->capacity);
689+
for (int capacity = 0; capacity < sub_tile->capacity; ++capacity) {
690+
int sub_tile_pin_index = pin_num + capacity * type->num_pins / sub_tile->capacity;
691+
int physical_pin_index = sub_tile->sub_tile_to_tile_pin_indices[sub_tile_pin_index];
692+
type->pinloc[width][height][side][physical_pin_index] = true;
693+
type->pin_width_offset[physical_pin_index] += width;
694+
type->pin_height_offset[physical_pin_index] += height;
695+
physical_pin_counts[physical_pin_index] += 1;
696+
}
694697
}
695698
}
696699
}
@@ -3203,31 +3206,47 @@ static void ProcessEquivalentSiteCustomConnection(pugi::xml_node Parent,
32033206
static void ProcessPinLocations(pugi::xml_node Locations,
32043207
t_physical_tile_type* PhysicalTileType,
32053208
t_sub_tile* SubTile,
3206-
t_pin_loc_assignments* pin_loc_assignments,
3209+
t_pin_loc* pin_loc,
32073210
const pugiutil::loc_data& loc_data) {
3208-
32093211
pugi::xml_node Cur;
3212+
char* Prop;
3213+
enum e_pin_location_distr distribution;
32103214

32113215
if (Locations) {
32123216
expect_only_attributes(Locations, {"pattern"}, loc_data);
32133217

32143218
Prop = get_attribute(Locations, "pattern", loc_data).value();
32153219
if (strcmp(Prop, "spread") == 0) {
3216-
PhysicalTileType->pin_location_distribution = E_SPREAD_PIN_DISTR;
3220+
distribution = E_SPREAD_PIN_DISTR;
32173221
} else if (strcmp(Prop, "perimeter") == 0) {
3218-
PhysicalTileType->pin_location_distribution = E_PERIMETER_PIN_DISTR;
3222+
distribution = E_PERIMETER_PIN_DISTR;
32193223
} else if (strcmp(Prop, "spread_inputs_perimeter_outputs") == 0) {
3220-
PhysicalTileType->pin_location_distribution = E_SPREAD_INPUTS_PERIMETER_OUTPUTS_PIN_DISTR;
3224+
distribution = E_SPREAD_INPUTS_PERIMETER_OUTPUTS_PIN_DISTR;
32213225
} else if (strcmp(Prop, "custom") == 0) {
3222-
PhysicalTileType->pin_location_distribution = E_CUSTOM_PIN_DISTR;
3226+
distribution = E_CUSTOM_PIN_DISTR;
32233227
} else {
32243228
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Locations),
32253229
"%s is an invalid pin location pattern.\n", Prop);
32263230
}
3231+
} else {
3232+
distribution = E_SPREAD_PIN_DISTR;
3233+
}
3234+
3235+
if (pin_loc->is_pin_distribution_set()) {
3236+
if (pin_loc->distribution != distribution) {
3237+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Locations),
3238+
"Sub Tile %s has a different pin location pattern (%s) with respect "
3239+
"to the sibling sub tiles", SubTile->name, Prop);
3240+
}
3241+
} else {
3242+
pin_loc->distribution = distribution;
3243+
pin_loc->set_pin_distribution();
32273244
}
32283245

3246+
int sub_tile_index = SubTile->index;
3247+
32293248
/* Load the pin locations */
3230-
if (pin_location_distribution == E_CUSTOM_PIN_DISTR) {
3249+
if (distribution == E_CUSTOM_PIN_DISTR) {
32313250
expect_only_children(Locations, {"loc"}, loc_data);
32323251
Cur = Locations.first_child();
32333252
std::set<std::tuple<e_side, int, int>> seen_sides;
@@ -3279,12 +3298,10 @@ static void ProcessPinLocations(pugi::xml_node Locations,
32793298
/* Go through lists of pins */
32803299
const std::vector<std::string> Tokens = vtr::split(Cur.child_value());
32813300
Count = Tokens.size();
3282-
PhysicalTileType->num_pin_loc_assignments[x_offset][y_offset][side] = Count;
32833301
if (Count > 0) {
3284-
PhysicalTileType->pin_loc_assignments[x_offset][y_offset][side] = (char**)vtr::calloc(Count, sizeof(char*));
32853302
for (int pin = 0; pin < Count; ++pin) {
32863303
/* Store location assignment */
3287-
PhysicalTileType->pin_loc_assignments[x_offset][y_offset][side][pin] = vtr::strdup(Tokens[pin].c_str());
3304+
pin_loc->assignments[sub_tile_index][x_offset][y_offset][side].push_back(vtr::strdup(Tokens[pin]));
32883305

32893306
/* Advance through list of pins in this location */
32903307
}
@@ -3299,9 +3316,8 @@ static void ProcessPinLocations(pugi::xml_node Locations,
32993316
for (int w = 0; w < PhysicalTileType->width; ++w) {
33003317
for (int h = 0; h < PhysicalTileType->height; ++h) {
33013318
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
3302-
for (int itoken = 0; itoken < PhysicalTileType->num_pin_loc_assignments[w][h][side]; ++itoken) {
3303-
const char* pin_spec = PhysicalTileType->pin_loc_assignments[w][h][side][itoken];
3304-
InstPort inst_port(PhysicalTileType->pin_loc_assignments[w][h][side][itoken]);
3319+
for (auto token : pin_loc->assignments[sub_tile_index][w][h][side]) {
3320+
InstPort inst_port(token.c_str());
33053321

33063322
//A pin specification should contain only the block name, and not any instace count information
33073323
if (inst_port.instance_low_index() != InstPort::UNSPECIFIED || inst_port.instance_high_index() != InstPort::UNSPECIFIED) {
@@ -3325,7 +3341,7 @@ static void ProcessPinLocations(pugi::xml_node Locations,
33253341

33263342
//Find the matching pb type to get the total number of pins
33273343
const t_physical_tile_port* port = nullptr;
3328-
for (const auto& tmp_port : PhysicalTileType->ports) {
3344+
for (const auto& tmp_port : SubTile->ports) {
33293345
if (tmp_port.name == inst_port.port_name()) {
33303346
port = &tmp_port;
33313347
break;
@@ -3338,7 +3354,7 @@ static void ProcessPinLocations(pugi::xml_node Locations,
33383354
} else {
33393355
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Locations),
33403356
"Failed to find port named '%s' on block '%s'",
3341-
inst_port.port_name().c_str(), PhysicalTileType->name);
3357+
inst_port.port_name().c_str(), SubTile->name);
33423358
}
33433359
}
33443360
VTR_ASSERT(pin_low_idx >= 0);
@@ -3354,21 +3370,20 @@ static void ProcessPinLocations(pugi::xml_node Locations,
33543370
}
33553371

33563372
//Check for any pins missing location specs
3357-
for (const auto& port : PhysicalTileType->ports) {
3373+
for (const auto& port : SubTile->ports) {
33583374
for (int ipin = 0; ipin < port.num_pins; ++ipin) {
33593375
if (!port_pins_with_specified_locations[port.name].count(ipin)) {
33603376
//Missing
33613377
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Locations),
33623378
"Pin '%s.%s[%d]' has no pin location specificed (a location is required for pattern=\"custom\")",
3363-
PhysicalTileType->name, port.name, ipin);
3379+
SubTile->name, port.name, ipin);
33643380
}
33653381
}
33663382
}
33673383
} else if (Locations) {
33683384
//Non-custom pin locations. There should be no child tags
33693385
expect_child_node_count(Locations, 0, loc_data);
33703386
}
3371-
33723387
}
33733388

33743389
static void ProcessSubTiles(pugi::xml_node Node,
@@ -3379,30 +3394,32 @@ static void ProcessSubTiles(pugi::xml_node Node,
33793394
const pugiutil::loc_data& loc_data) {
33803395
pugi::xml_node CurSubTile;
33813396
pugi::xml_node Cur;
3397+
int index = 0;
33823398

33833399
int width = PhysicalTileType->width;
33843400
int height = PhysicalTileType->height;
33853401
int num_sides = 4;
3402+
int num_sub_tiles = count_children(Node, "sub_tile", loc_data);
33863403

33873404
std::map<std::string, int> sub_tile_names;
33883405

3389-
t_pin_loc_assignments pin_loc_assignments;
3390-
3391-
pin_loc_assignments.num_assignments = std::vector(width, std::vector(height, std::vector(num_sides, 0)))
3392-
pin_loc_assignments.assignments = std::vector(width, std::vector(height, std::vector(num_sides, 0)))
3406+
t_pin_loc pin_loc;
3407+
pin_loc.assignments = std::vector(num_sub_tiles, std::vector(width, std::vector(height, std::vector(num_sides, 0))))
33933408

3394-
CurSubTile = get_single_child(Node, "sub_tile", loc_data);
3395-
3396-
if (!CurSubTile) {
3409+
if (num_sub_tiles == 0) {
33973410
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
33983411
"No sub tile found for the Physical Tile %s.\n"
33993412
"At least one sub tile is needed to correctly describe the Physical Tile.\n",
34003413
PhysicalTileType->name)
34013414
}
34023415

3416+
CurSubTile = get_single_child(Node, "sub_tile", loc_data);
3417+
34033418
while (CurSubTile) {
34043419
t_sub_tile SubTile;
34053420

3421+
SubTile.index = index;
3422+
34063423
expect_only_attributes(CurSubTile, {"name", "capacity"}, loc_data);
34073424

34083425
/* Load type name */
@@ -3444,7 +3461,7 @@ static void ProcessSubTiles(pugi::xml_node Node,
34443461
PhysicalTileType->num_drivers += capacity * pin_counts.output;
34453462

34463463
Cur = get_single_child(CurTileType, "pinlocations", loc_data, ReqOpt::OPTIONAL);
3447-
ProcessPinLocations(Cur, PhysicalTileType, &SubTile, &pin_loc_assignments, loc_data);
3464+
ProcessPinLocations(Cur, PhysicalTileType, &SubTile, &pin_loc, loc_data);
34483465

34493466
/* Load Fc */
34503467
Cur = get_single_child(CurTileType, "fc", loc_data, ReqOpt::OPTIONAL);
@@ -3456,22 +3473,17 @@ static void ProcessSubTiles(pugi::xml_node Node,
34563473

34573474
PhysicalTileType->sub_tiles.push_back(SubTile);
34583475

3476+
index++;
3477+
34593478
CurSubTile = CurSubTile.next_sibling(CurSubTile.name());
34603479
}
34613480

34623481
// Initialize pinloc data structure.
34633482
int num_pins = PhysicalTileType->num_pins;
34643483
PhysicalTileType->pinloc = std::vector(width, std::vector(height, std::vector(num_sides, std::vector(num_pins, false))));
34653484

3466-
SetupPinLocationsAndPinClasses(Cur, PhysicalTileType, loc_data);
3467-
3468-
CurSubTile = get_single_child(Node, "sub_tile", loc_data);
3469-
3470-
while (CurSubTile) {
3471-
/* Load pin names and classes and locations */
3472-
Cur = get_single_child(CurTileType, "pinlocations", loc_data, ReqOpt::OPTIONAL);
3473-
LoadPinLoc(Cur, PhysicalTileType, loc_data);
3474-
}
3485+
SetupPinClasses(Cur, PhysicalTileType, loc_data);
3486+
LoadPinLoc(Cur, PhysicalTileType, &pin_loc, loc_data);
34753487
}
34763488

34773489
/* Takes in node pointing to <typelist> and loads all the

0 commit comments

Comments
 (0)