Skip to content

Commit 938687c

Browse files
committed
vtr_arch: added tile parsing capability to vtr
Signed-off-by: Alessandro Comodi <[email protected]>
1 parent 1cf4f1b commit 938687c

File tree

1 file changed

+168
-68
lines changed

1 file changed

+168
-68
lines changed

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 168 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static void Process_Fc(pugi::xml_node Node, t_type_descriptor * Type, std::vecto
106106
static t_fc_override Process_Fc_override(pugi::xml_node node, const pugiutil::loc_data& loc_data);
107107
static void ProcessSwitchblockLocations(pugi::xml_node swtichblock_locations, t_type_descriptor* type, const t_arch& arch, const pugiutil::loc_data& loc_data);
108108
static e_fc_value_type string_to_fc_value_type(const std::string& str, pugi::xml_node node, const pugiutil::loc_data& loc_data);
109-
static void ProcessComplexBlockProps(pugi::xml_node Node, t_type_descriptor * Type, const pugiutil::loc_data& loc_data);
109+
static void ProcessTileProps(pugi::xml_node Node, t_type_descriptor * Type, const pugiutil::loc_data& loc_data);
110110
static void ProcessChanWidthDistr(pugi::xml_node Node,
111111
t_arch *arch, const pugiutil::loc_data& loc_data);
112112
static void ProcessChanWidthDistrDir(pugi::xml_node Node, t_chan * chan, const pugiutil::loc_data& loc_data);
@@ -115,12 +115,22 @@ static void ProcessModelPorts(pugi::xml_node port_group, t_model* model, std::se
115115
static void ProcessLayout(pugi::xml_node Node, t_arch *arch, const pugiutil::loc_data& loc_data);
116116
static t_grid_def ProcessGridLayout(pugi::xml_node layout_type_tag, const pugiutil::loc_data& loc_data);
117117
static void ProcessDevice(pugi::xml_node Node, t_arch *arch, t_default_fc_spec &arch_def_fc, const pugiutil::loc_data& loc_data);
118+
static void ProcessTiles(pugi::xml_node Node,
119+
t_type_descriptor ** Types,
120+
int *NumTypes,
121+
const pugiutil::loc_data& loc_data);
122+
static void ProcessTilesTags(pugi::xml_node Node,
123+
t_type_descriptor ** Types,
124+
int NumTypes,
125+
t_arch& arch,
126+
const t_default_fc_spec &arch_def_fc,
127+
const pugiutil::loc_data& loc_data);
118128
static void ProcessComplexBlocks(pugi::xml_node Node,
119-
t_type_descriptor ** Types, int *NumTypes,
129+
t_type_descriptor ** Types,
130+
int NumTypes,
120131
t_arch& arch,
121-
const bool timing_enabled,
122-
const t_default_fc_spec &arch_def_fc,
123-
const pugiutil::loc_data& loc_data);
132+
const bool timing_enabled,
133+
const pugiutil::loc_data& loc_data);
124134
static void ProcessSwitches(pugi::xml_node Node,
125135
t_arch_switch_inf **Switches, int *NumSwitches,
126136
const bool timing_enabled, const pugiutil::loc_data& loc_data);
@@ -185,6 +195,7 @@ int find_switch_by_name(const t_arch& arch, std::string switch_name);
185195

186196
e_side string_to_side(std::string side_str);
187197

198+
static t_type_descriptor* get_correspondent_tile(t_type_descriptor ** Types, int NumTypes, const char * type_name);
188199
/*
189200
*
190201
*
@@ -257,7 +268,6 @@ void XmlReadArch(const char *ArchFile, const bool timing_enabled,
257268
bool switchblocklist_required = (arch->SBType == CUSTOM); //require this section only if custom switchblocks are used
258269
SWITCHBLOCKLIST_REQD = BoolToReqOpt(switchblocklist_required);
259270

260-
261271
/* Process segments. This depends on switches */
262272
Next = get_single_child(architecture, "segmentlist", loc_data);
263273
ProcessSegments(Next, arch->Segments,
@@ -269,11 +279,19 @@ void XmlReadArch(const char *ArchFile, const bool timing_enabled,
269279
ProcessSwitchblocks(Next, arch, loc_data);
270280
}
271281

272-
/* Process types */
282+
/* Process tiles */
283+
Next = get_single_child(architecture, "tiles", loc_data);
284+
ProcessTiles(Next, Types, NumTypes, loc_data);
285+
286+
/* Process pb_types */
273287
Next = get_single_child(architecture, "complexblocklist", loc_data);
274-
ProcessComplexBlocks(Next, Types, NumTypes, *arch, timing_enabled, arch_def_fc, loc_data);
288+
ProcessComplexBlocks(Next, Types, *NumTypes, *arch, timing_enabled, loc_data);
275289

276-
/* Process directs */
290+
/* Process tile tags that after pb_type have been parsed */
291+
Next = get_single_child(architecture, "tiles", loc_data);
292+
ProcessTilesTags(Next, Types, *NumTypes, *arch, arch_def_fc, loc_data);
293+
294+
/* Process directs */
277295
Next = get_single_child(architecture, "directlist", loc_data, OPTIONAL);
278296
if (Next) {
279297
ProcessDirects(Next, &(arch->Directs), &(arch->num_directs),
@@ -1001,14 +1019,6 @@ static void ProcessPb_Type(pugi::xml_node Parent, t_pb_type * pb_type,
10011019
children_to_expect.push_back("model");
10021020
children_to_expect.push_back("pb_type");
10031021
children_to_expect.push_back("interconnect");
1004-
1005-
if (is_root_pb_type) {
1006-
VTR_ASSERT(!is_leaf_pb_type);
1007-
//Top level pb_type's may also have the following tag types
1008-
children_to_expect.push_back("fc");
1009-
children_to_expect.push_back("pinlocations");
1010-
children_to_expect.push_back("switchblock_locations");
1011-
}
10121022
} else {
10131023
VTR_ASSERT(is_leaf_pb_type);
10141024
VTR_ASSERT(!is_root_pb_type);
@@ -1745,7 +1755,7 @@ static void Process_Fc(pugi::xml_node Node, t_type_descriptor * Type, std::vecto
17451755
/* Use the default value, if available */
17461756
if (!arch_def_fc.specified) {
17471757
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
1748-
"<pb_type> is missing child <fc>, and no <default_fc> specified in architecture\n");
1758+
"<tile> is missing child <fc>, and no <default_fc> specified in architecture\n");
17491759
}
17501760
def_fc_spec = arch_def_fc;
17511761
}
@@ -2066,28 +2076,6 @@ static void ProcessSwitchblockLocations(pugi::xml_node switchblock_locations, t_
20662076
}
20672077
}
20682078

2069-
/* Thie processes attributes of the 'type' tag */
2070-
static void ProcessComplexBlockProps(pugi::xml_node Node, t_type_descriptor * Type, const pugiutil::loc_data& loc_data) {
2071-
const char *Prop;
2072-
2073-
expect_only_attributes(Node, {"name", "capacity", "width", "height", "area"}, loc_data);
2074-
2075-
/* Load type name */
2076-
Prop = get_attribute(Node, "name", loc_data).value();
2077-
Type->name = vtr::strdup(Prop);
2078-
2079-
/* Load properties */
2080-
Type->capacity = get_attribute(Node, "capacity", loc_data, OPTIONAL).as_uint(1); /* TODO: Any block with capacity > 1 that is not I/O has not been tested, must test */
2081-
Type->width = get_attribute(Node, "width", loc_data, OPTIONAL).as_uint(1);
2082-
Type->height = get_attribute(Node, "height", loc_data, OPTIONAL).as_uint(1);
2083-
Type->area = get_attribute(Node, "area", loc_data, OPTIONAL).as_float(UNDEFINED);
2084-
2085-
if (atof(Prop) < 0) {
2086-
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
2087-
"Area for type %s must be non-negative\n", Type->name);
2088-
}
2089-
}
2090-
20912079
/* Takes in node pointing to <models> and loads all the
20922080
* child type objects. */
20932081
static void ProcessModels(pugi::xml_node Node, t_arch *arch, const pugiutil::loc_data& loc_data) {
@@ -2675,15 +2663,35 @@ static void ProcessChanWidthDistrDir(pugi::xml_node Node, t_chan * chan, const p
26752663
}
26762664

26772665

2666+
/* Thie processes attributes of the 'type' tag */
2667+
static void ProcessTileProps(pugi::xml_node Node, t_type_descriptor * Type, const pugiutil::loc_data& loc_data) {
2668+
const char *Prop;
26782669

2679-
/* Takes in node pointing to <typelist> and loads all the
2680-
* child type objects. */
2681-
static void ProcessComplexBlocks(pugi::xml_node Node,
2682-
t_type_descriptor ** Types, int *NumTypes,
2683-
t_arch& arch,
2684-
const bool timing_enabled,
2685-
const t_default_fc_spec &arch_def_fc,
2686-
const pugiutil::loc_data& loc_data) {
2670+
expect_only_attributes(Node, {"name", "capacity", "width", "height", "area"}, loc_data);
2671+
2672+
/* Load type name */
2673+
Prop = get_attribute(Node, "name", loc_data).value();
2674+
Type->name = vtr::strdup(Prop);
2675+
2676+
/* Load properties */
2677+
Type->capacity = get_attribute(Node, "capacity", loc_data, OPTIONAL).as_uint(1); /* TODO: Any block with capacity > 1 that is not I/O has not been tested, must test */
2678+
Type->width = get_attribute(Node, "width", loc_data, OPTIONAL).as_uint(1);
2679+
Type->height = get_attribute(Node, "height", loc_data, OPTIONAL).as_uint(1);
2680+
Type->area = get_attribute(Node, "area", loc_data, OPTIONAL).as_float(UNDEFINED);
2681+
2682+
if (atof(Prop) < 0) {
2683+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
2684+
"Area for type %s must be non-negative\n", Type->name);
2685+
}
2686+
}
2687+
2688+
2689+
/* Takes in node pointing to <tiles> and loads all the *
2690+
* child type objects. */
2691+
static void ProcessTiles(pugi::xml_node Node,
2692+
t_type_descriptor ** Types,
2693+
int *NumTypes,
2694+
const pugiutil::loc_data& loc_data) {
26872695
pugi::xml_node CurType, Prev;
26882696
pugi::xml_node Cur;
26892697
t_type_descriptor * Type;
@@ -2693,7 +2701,7 @@ static void ProcessComplexBlocks(pugi::xml_node Node,
26932701
/* Alloc the type list. Need one additional t_type_desctiptors:
26942702
* 1: empty psuedo-type
26952703
*/
2696-
*NumTypes = count_children(Node, "pb_type", loc_data) + 1;
2704+
*NumTypes = count_children(Node, "tile", loc_data) + 1;
26972705
*Types = new t_type_descriptor[*NumTypes];
26982706

26992707
cb_type_descriptors = *Types;
@@ -2709,31 +2717,58 @@ static void ProcessComplexBlocks(pugi::xml_node Node,
27092717

27102718
CurType = Node.first_child();
27112719
while (CurType) {
2712-
check_node(CurType, "pb_type", loc_data);
2720+
check_node(CurType, "tile", loc_data);
27132721

27142722
/* Alias to current type */
27152723
Type = &(*Types)[i];
27162724

27172725
/* Parses the properties fields of the type */
2718-
ProcessComplexBlockProps(CurType, Type, loc_data);
2726+
ProcessTileProps(CurType, Type, loc_data);
27192727

27202728
ret_pb_type_descriptors = pb_type_descriptors.insert(
27212729
pair<string, int>(Type->name, 0));
27222730
if (!ret_pb_type_descriptors.second) {
27232731
archfpga_throw(loc_data.filename_c_str(), loc_data.line(CurType),
2724-
"Duplicate pb_type descriptor name: '%s'.\n", Type->name);
2732+
"Duplicate tile descriptor name: '%s'.\n", Type->name);
27252733
}
27262734

2727-
/* Load pb_type info */
2728-
Type->pb_type = new t_pb_type;
2729-
Type->pb_type->name = vtr::strdup(Type->name);
2730-
ProcessPb_Type(CurType, Type->pb_type, nullptr, timing_enabled, arch, loc_data);
2731-
Type->num_pins = Type->capacity
2732-
* (Type->pb_type->num_input_pins
2733-
+ Type->pb_type->num_output_pins
2734-
+ Type->pb_type->num_clock_pins);
2735-
Type->num_receivers = Type->capacity * Type->pb_type->num_input_pins;
2736-
Type->num_drivers = Type->capacity * Type->pb_type->num_output_pins;
2735+
Type->index = i;
2736+
2737+
/* Type fully read */
2738+
++i;
2739+
2740+
/* Free this node and get its next sibling node */
2741+
CurType = CurType.next_sibling (CurType.name());
2742+
2743+
}
2744+
pb_type_descriptors.clear();
2745+
}
2746+
2747+
// This step has to be performed after the root pb_type has been parsed
2748+
static void ProcessTilesTags(pugi::xml_node Node,
2749+
t_type_descriptor ** Types,
2750+
int NumTypes,
2751+
t_arch& arch,
2752+
const t_default_fc_spec &arch_def_fc,
2753+
const pugiutil::loc_data& loc_data) {
2754+
pugi::xml_node Cur, CurType;
2755+
t_type_descriptor *Type;
2756+
/* Process the types */
2757+
CurType = Node.first_child();
2758+
while(CurType) {
2759+
check_node(CurType, "tile", loc_data);
2760+
2761+
/* Load type name */
2762+
const char * NameProp = get_attribute(CurType, "name", loc_data).value();
2763+
2764+
/* Alias to current type */
2765+
Type = get_correspondent_tile(Types, NumTypes, vtr::strdup(NameProp));
2766+
if(Type == nullptr) {
2767+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(CurType),
2768+
"No tiles found correspondent to current root level pb type: '%s'.\n", Type->pb_type->name);
2769+
}
2770+
2771+
VTR_ASSERT(Type->pb_type != nullptr);
27372772

27382773
/* Load pin names and classes and locations */
27392774
Cur = get_single_child(CurType, "pinlocations", loc_data, OPTIONAL);
@@ -2758,16 +2793,66 @@ static void ProcessComplexBlocks(pugi::xml_node Node,
27582793
Cur = get_single_child(CurType, "switchblock_locations", loc_data, OPTIONAL);
27592794
ProcessSwitchblockLocations(Cur, Type, arch, loc_data);
27602795

2761-
Type->index = i;
2762-
2763-
/* Type fully read */
2764-
++i;
2765-
27662796
/* Free this node and get its next sibling node */
27672797
CurType = CurType.next_sibling (CurType.name());
2798+
}
2799+
}
2800+
2801+
static void ProcessComplexBlocks(pugi::xml_node Node,
2802+
t_type_descriptor ** Types,
2803+
int NumTypes,
2804+
t_arch& arch,
2805+
const bool timing_enabled,
2806+
const pugiutil::loc_data& loc_data) {
2807+
pugi::xml_node CurPbType, Prev;
2808+
t_type_descriptor * Type;
2809+
2810+
map<string, int> pb_types;
2811+
pair<map<string, int>::iterator, bool> ret_pb_types;
2812+
2813+
CurPbType = Node.first_child();
2814+
while (CurPbType) {
2815+
check_node(CurPbType, "pb_type", loc_data);
2816+
2817+
char *type_name;
2818+
2819+
for(pugi::xml_attribute attr : CurPbType.attributes()) {
2820+
if(attr.name() != std::string("name")) {
2821+
bad_attribute(attr, CurPbType, loc_data);
2822+
} else {
2823+
type_name = vtr::strdup(attr.value());
2824+
}
2825+
}
2826+
2827+
Type = get_correspondent_tile(Types, NumTypes, type_name);
2828+
if(Type == nullptr) {
2829+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(CurPbType),
2830+
"No tiles found correspondent to current root level pb type: '%s'.\n", Type->pb_type->name);
2831+
}
2832+
2833+
Type->pb_type = new t_pb_type;
2834+
Type->pb_type->name = vtr::strdup(type_name);
2835+
2836+
ret_pb_types = pb_types.insert(
2837+
pair<string, int>(Type->pb_type->name, 0));
2838+
if (!ret_pb_types.second) {
2839+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(CurPbType),
2840+
"Duplicate pb_type descriptor name: '%s'.\n", Type->pb_type->name);
2841+
}
27682842

2843+
ProcessPb_Type(CurPbType, Type->pb_type, nullptr, timing_enabled, arch, loc_data);
2844+
Type->num_pins = Type->capacity
2845+
* (Type->pb_type->num_input_pins
2846+
+ Type->pb_type->num_output_pins
2847+
+ Type->pb_type->num_clock_pins);
2848+
Type->num_receivers = Type->capacity * Type->pb_type->num_input_pins;
2849+
Type->num_drivers = Type->capacity * Type->pb_type->num_output_pins;
2850+
2851+
/* Load pin names and classes and locations */
2852+
2853+
CurPbType = CurPbType.next_sibling(CurPbType.name());
27692854
}
2770-
pb_type_descriptors.clear();
2855+
pb_types.clear();
27712856
}
27722857

27732858

@@ -4217,3 +4302,18 @@ e_side string_to_side(std::string side_str) {
42174302
}
42184303
return side;
42194304
}
4305+
4306+
static t_type_descriptor* get_correspondent_tile(t_type_descriptor ** Types, int NumTypes, const char *type_name) {
4307+
t_type_descriptor *Type;
4308+
4309+
for(int i = 1 /* Skip empty tile */; i < NumTypes; i++) {
4310+
/* Alias to current type */
4311+
Type = &(*Types)[i];
4312+
4313+
if(0 == strcmp(Type->name, type_name)){
4314+
return Type;
4315+
}
4316+
}
4317+
4318+
return nullptr;
4319+
}

0 commit comments

Comments
 (0)