@@ -106,7 +106,7 @@ static void Process_Fc(pugi::xml_node Node, t_type_descriptor * Type, std::vecto
106
106
static t_fc_override Process_Fc_override (pugi::xml_node node, const pugiutil::loc_data& loc_data);
107
107
static void ProcessSwitchblockLocations (pugi::xml_node swtichblock_locations, t_type_descriptor* type, const t_arch& arch, const pugiutil::loc_data& loc_data);
108
108
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);
110
110
static void ProcessChanWidthDistr (pugi::xml_node Node,
111
111
t_arch *arch, const pugiutil::loc_data& loc_data);
112
112
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
115
115
static void ProcessLayout (pugi::xml_node Node, t_arch *arch, const pugiutil::loc_data& loc_data);
116
116
static t_grid_def ProcessGridLayout (pugi::xml_node layout_type_tag, const pugiutil::loc_data& loc_data);
117
117
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);
118
128
static void ProcessComplexBlocks (pugi::xml_node Node,
119
- t_type_descriptor ** Types, int *NumTypes,
129
+ t_type_descriptor ** Types,
130
+ int NumTypes,
120
131
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);
124
134
static void ProcessSwitches (pugi::xml_node Node,
125
135
t_arch_switch_inf **Switches, int *NumSwitches,
126
136
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);
185
195
186
196
e_side string_to_side (std::string side_str);
187
197
198
+ static t_type_descriptor* get_correspondent_tile (t_type_descriptor ** Types, int NumTypes, const char * type_name);
188
199
/*
189
200
*
190
201
*
@@ -257,7 +268,6 @@ void XmlReadArch(const char *ArchFile, const bool timing_enabled,
257
268
bool switchblocklist_required = (arch->SBType == CUSTOM); // require this section only if custom switchblocks are used
258
269
SWITCHBLOCKLIST_REQD = BoolToReqOpt (switchblocklist_required);
259
270
260
-
261
271
/* Process segments. This depends on switches */
262
272
Next = get_single_child (architecture, " segmentlist" , loc_data);
263
273
ProcessSegments (Next, arch->Segments ,
@@ -269,11 +279,19 @@ void XmlReadArch(const char *ArchFile, const bool timing_enabled,
269
279
ProcessSwitchblocks (Next, arch, loc_data);
270
280
}
271
281
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 */
273
287
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);
275
289
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 */
277
295
Next = get_single_child (architecture, " directlist" , loc_data, OPTIONAL);
278
296
if (Next) {
279
297
ProcessDirects (Next, &(arch->Directs ), &(arch->num_directs ),
@@ -1001,14 +1019,6 @@ static void ProcessPb_Type(pugi::xml_node Parent, t_pb_type * pb_type,
1001
1019
children_to_expect.push_back (" model" );
1002
1020
children_to_expect.push_back (" pb_type" );
1003
1021
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
- }
1012
1022
} else {
1013
1023
VTR_ASSERT (is_leaf_pb_type);
1014
1024
VTR_ASSERT (!is_root_pb_type);
@@ -1745,7 +1755,7 @@ static void Process_Fc(pugi::xml_node Node, t_type_descriptor * Type, std::vecto
1745
1755
/* Use the default value, if available */
1746
1756
if (!arch_def_fc.specified ) {
1747
1757
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 " );
1749
1759
}
1750
1760
def_fc_spec = arch_def_fc;
1751
1761
}
@@ -2066,28 +2076,6 @@ static void ProcessSwitchblockLocations(pugi::xml_node switchblock_locations, t_
2066
2076
}
2067
2077
}
2068
2078
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
-
2091
2079
/* Takes in node pointing to <models> and loads all the
2092
2080
* child type objects. */
2093
2081
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
2675
2663
}
2676
2664
2677
2665
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;
2678
2669
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) {
2687
2695
pugi::xml_node CurType, Prev;
2688
2696
pugi::xml_node Cur;
2689
2697
t_type_descriptor * Type;
@@ -2693,7 +2701,7 @@ static void ProcessComplexBlocks(pugi::xml_node Node,
2693
2701
/* Alloc the type list. Need one additional t_type_desctiptors:
2694
2702
* 1: empty psuedo-type
2695
2703
*/
2696
- *NumTypes = count_children (Node, " pb_type " , loc_data) + 1 ;
2704
+ *NumTypes = count_children (Node, " tile " , loc_data) + 1 ;
2697
2705
*Types = new t_type_descriptor[*NumTypes];
2698
2706
2699
2707
cb_type_descriptors = *Types;
@@ -2709,31 +2717,58 @@ static void ProcessComplexBlocks(pugi::xml_node Node,
2709
2717
2710
2718
CurType = Node.first_child ();
2711
2719
while (CurType) {
2712
- check_node (CurType, " pb_type " , loc_data);
2720
+ check_node (CurType, " tile " , loc_data);
2713
2721
2714
2722
/* Alias to current type */
2715
2723
Type = &(*Types)[i];
2716
2724
2717
2725
/* Parses the properties fields of the type */
2718
- ProcessComplexBlockProps (CurType, Type, loc_data);
2726
+ ProcessTileProps (CurType, Type, loc_data);
2719
2727
2720
2728
ret_pb_type_descriptors = pb_type_descriptors.insert (
2721
2729
pair<string, int >(Type->name , 0 ));
2722
2730
if (!ret_pb_type_descriptors.second ) {
2723
2731
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 );
2725
2733
}
2726
2734
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 );
2737
2772
2738
2773
/* Load pin names and classes and locations */
2739
2774
Cur = get_single_child (CurType, " pinlocations" , loc_data, OPTIONAL);
@@ -2758,16 +2793,66 @@ static void ProcessComplexBlocks(pugi::xml_node Node,
2758
2793
Cur = get_single_child (CurType, " switchblock_locations" , loc_data, OPTIONAL);
2759
2794
ProcessSwitchblockLocations (Cur, Type, arch, loc_data);
2760
2795
2761
- Type->index = i;
2762
-
2763
- /* Type fully read */
2764
- ++i;
2765
-
2766
2796
/* Free this node and get its next sibling node */
2767
2797
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
+ }
2768
2842
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 ());
2769
2854
}
2770
- pb_type_descriptors .clear ();
2855
+ pb_types .clear ();
2771
2856
}
2772
2857
2773
2858
@@ -4217,3 +4302,18 @@ e_side string_to_side(std::string side_str) {
4217
4302
}
4218
4303
return side;
4219
4304
}
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