@@ -41,16 +41,16 @@ using vtr::t_formula_data;
41
41
/* ---- Functions for Parsing Switchblocks from Architecture ----*/
42
42
43
43
// Load an XML wireconn specification into a t_wireconn_inf
44
- t_wireconn_inf parse_wireconn (pugi::xml_node node, const pugiutil::loc_data& loc_data);
44
+ t_wireconn_inf parse_wireconn (pugi::xml_node node, const pugiutil::loc_data& loc_data, const t_arch_switch_inf* switches, int num_switches );
45
45
46
46
// Process the desired order of a wireconn
47
47
static void parse_switchpoint_order (const char * order, SwitchPointOrder& switchpoint_order);
48
48
49
49
// Process a wireconn defined in the inline style (using attributes)
50
- void parse_wireconn_inline (pugi::xml_node node, const pugiutil::loc_data& loc_data, t_wireconn_inf& wc);
50
+ void parse_wireconn_inline (pugi::xml_node node, const pugiutil::loc_data& loc_data, t_wireconn_inf& wc, const t_arch_switch_inf* switches, int num_switches );
51
51
52
52
// Process a wireconn defined in the multinode style (more advanced specification)
53
- void parse_wireconn_multinode (pugi::xml_node node, const pugiutil::loc_data& loc_data, t_wireconn_inf& wc);
53
+ void parse_wireconn_multinode (pugi::xml_node node, const pugiutil::loc_data& loc_data, t_wireconn_inf& wc, const t_arch_switch_inf* switches, int num_switches );
54
54
55
55
// Process a <from> or <to> sub-node of a multinode wireconn
56
56
t_wire_switchpoints parse_wireconn_from_to_node (pugi::xml_node node, const pugiutil::loc_data& loc_data);
@@ -65,6 +65,9 @@ static void parse_comma_separated_wire_points(const char* ch, std::vector<t_wire
65
65
/* Parses the number of connections type */
66
66
static void parse_num_conns (std::string num_conns, t_wireconn_inf& wireconn);
67
67
68
+ /* parse switch_override in wireconn */
69
+ static void parse_switch_override (const char * switch_override, t_wireconn_inf& wireconn, const t_arch_switch_inf* switches, int num_switches);
70
+
68
71
/* checks for correctness of a unidir switchblock. */
69
72
static void check_unidir_switchblock (const t_switchblock_inf* sb);
70
73
@@ -79,7 +82,7 @@ static void check_wireconn(const t_arch* arch, const t_wireconn_inf& wireconn);
79
82
/* ---- Functions for Parsing Switchblocks from Architecture ----*/
80
83
81
84
/* Reads-in the wire connections specified for the switchblock in the xml arch file */
82
- void read_sb_wireconns (const t_arch_switch_inf* /* switches*/ , int /* num_switches*/ , pugi::xml_node Node, t_switchblock_inf* sb, const pugiutil::loc_data& loc_data) {
85
+ void read_sb_wireconns (const t_arch_switch_inf* switches, int num_switches, pugi::xml_node Node, t_switchblock_inf* sb, const pugiutil::loc_data& loc_data) {
83
86
/* Make sure that Node is a switchblock */
84
87
check_node (Node, " switchblock" , loc_data);
85
88
@@ -94,33 +97,33 @@ void read_sb_wireconns(const t_arch_switch_inf* /*switches*/, int /*num_switches
94
97
SubElem = get_first_child (Node, " wireconn" , loc_data);
95
98
}
96
99
for (int i = 0 ; i < num_wireconns; i++) {
97
- t_wireconn_inf wc = parse_wireconn (SubElem, loc_data);
100
+ t_wireconn_inf wc = parse_wireconn (SubElem, loc_data, switches, num_switches); // need to pass in switch info for switch override
98
101
sb->wireconns .push_back (wc);
99
102
SubElem = SubElem.next_sibling (SubElem.name ());
100
103
}
101
104
102
105
return ;
103
106
}
104
107
105
- t_wireconn_inf parse_wireconn (pugi::xml_node node, const pugiutil::loc_data& loc_data) {
108
+ t_wireconn_inf parse_wireconn (pugi::xml_node node, const pugiutil::loc_data& loc_data, const t_arch_switch_inf* switches, int num_switches ) {
106
109
t_wireconn_inf wc;
107
110
108
111
size_t num_children = count_children (node, " from" , loc_data, ReqOpt::OPTIONAL);
109
112
num_children += count_children (node, " to" , loc_data, ReqOpt::OPTIONAL);
110
113
111
114
if (num_children == 0 ) {
112
- parse_wireconn_inline (node, loc_data, wc);
115
+ parse_wireconn_inline (node, loc_data, wc, switches, num_switches );
113
116
} else {
114
117
VTR_ASSERT (num_children > 0 );
115
- parse_wireconn_multinode (node, loc_data, wc);
118
+ parse_wireconn_multinode (node, loc_data, wc, switches, num_switches );
116
119
}
117
120
118
121
return wc;
119
122
}
120
123
121
- void parse_wireconn_inline (pugi::xml_node node, const pugiutil::loc_data& loc_data, t_wireconn_inf& wc) {
124
+ void parse_wireconn_inline (pugi::xml_node node, const pugiutil::loc_data& loc_data, t_wireconn_inf& wc, const t_arch_switch_inf* switches, int num_switches ) {
122
125
// Parse an inline wireconn definition, using attributes
123
- expect_only_attributes (node, {" num_conns" , " from_type" , " to_type" , " from_switchpoint" , " to_switchpoint" , " from_order" , " to_order" }, loc_data);
126
+ expect_only_attributes (node, {" num_conns" , " from_type" , " to_type" , " from_switchpoint" , " to_switchpoint" , " from_order" , " to_order" , " switch_override " }, loc_data);
124
127
125
128
/* get the connection style */
126
129
const char * char_prop = get_attribute (node, " num_conns" , loc_data).value ();
@@ -147,9 +150,13 @@ void parse_wireconn_inline(pugi::xml_node node, const pugiutil::loc_data& loc_da
147
150
148
151
char_prop = get_attribute (node, " to_order" , loc_data, ReqOpt::OPTIONAL).value ();
149
152
parse_switchpoint_order (char_prop, wc.to_switchpoint_order );
153
+
154
+ // parse switch overrides if they exist:
155
+ char_prop = get_attribute (node, " switch_override" , loc_data, ReqOpt::OPTIONAL).value ();
156
+ parse_switch_override (char_prop, wc, switches, num_switches);
150
157
}
151
158
152
- void parse_wireconn_multinode (pugi::xml_node node, const pugiutil::loc_data& loc_data, t_wireconn_inf& wc) {
159
+ void parse_wireconn_multinode (pugi::xml_node node, const pugiutil::loc_data& loc_data, t_wireconn_inf& wc, const t_arch_switch_inf* switches, int num_switches ) {
153
160
expect_only_children (node, {" from" , " to" }, loc_data);
154
161
155
162
/* get the connection style */
@@ -162,6 +169,9 @@ void parse_wireconn_multinode(pugi::xml_node node, const pugiutil::loc_data& loc
162
169
char_prop = get_attribute (node, " to_order" , loc_data, ReqOpt::OPTIONAL).value ();
163
170
parse_switchpoint_order (char_prop, wc.to_switchpoint_order );
164
171
172
+ char_prop = get_attribute (node, " switch_override" , loc_data, ReqOpt::OPTIONAL).value ();
173
+ parse_switch_override (char_prop, wc, switches, num_switches);
174
+
165
175
size_t num_from_children = count_children (node, " from" , loc_data);
166
176
size_t num_to_children = count_children (node, " to" , loc_data);
167
177
@@ -331,6 +341,24 @@ void read_sb_switchfuncs(pugi::xml_node Node, t_switchblock_inf* sb, const pugiu
331
341
return ;
332
342
}
333
343
344
+ static void parse_switch_override (const char * switch_override, t_wireconn_inf& wireconn, const t_arch_switch_inf* switches, int num_switches) {
345
+ // sentinel value to use default driving switch for the receiving wire type
346
+ if (switch_override == std::string (" " )) {
347
+ wireconn.switch_override_indx = DEFAULT_SWITCH; // Default
348
+ return ;
349
+ }
350
+
351
+ // iterate through the valid switch names in the arch looking for the requested switch_override
352
+ for (int i = 0 ; i < num_switches; i++) {
353
+ if (0 == strcmp (switch_override, switches[i].name )) {
354
+ wireconn.switch_override_indx = i;
355
+ return ;
356
+ }
357
+ }
358
+ // if we haven't found a switch that matched, then throw an error
359
+ archfpga_throw (__FILE__, __LINE__, " Unknown switch_override specified in wireconn of custom switch blocks: \" %s\"\n " , switch_override);
360
+ }
361
+
334
362
/* checks for correctness of switch block read-in from the XML architecture file */
335
363
void check_switchblock (const t_switchblock_inf* sb, const t_arch* arch) {
336
364
/* get directionality */
0 commit comments