Skip to content

Commit e738a1c

Browse files
Fix wireconn parsing required fields for scatter-gather patterns
1 parent 5240fc9 commit e738a1c

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
lines changed

libs/libarchfpga/src/parse_switchblocks.cpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,15 @@ static void parse_switchpoint_order(const char* order, SwitchPointOrder& switchp
4747
* @param node XML node containing inline wireconn attributes.
4848
* @param loc_data Location data for error reporting.
4949
* @param switches List of architecture switch definitions (used for switch overrides).
50+
* @param can_skip_from_to Determines if the from or to attributes are optional or mandatory.
51+
* <wireconn> tags for switch blocks require mandatory from/to attributes while those for scatter-gather
52+
* patterns are optional.
5053
* @return A `t_wireconn_inf` structure populated with parsed data.
5154
*/
5255
static t_wireconn_inf parse_wireconn_inline(pugi::xml_node node,
5356
const pugiutil::loc_data& loc_data,
54-
const std::vector<t_arch_switch_inf>& switches);
57+
const std::vector<t_arch_switch_inf>& switches,
58+
bool can_skip_from_to);
5559

5660
/**
5761
* @brief Parses a multi-node `<wireconn>` definition with `<from>` and `<to>` children.
@@ -126,14 +130,15 @@ void read_sb_wireconns(const std::vector<t_arch_switch_inf>& switches,
126130

127131
t_wireconn_inf parse_wireconn(pugi::xml_node node,
128132
const pugiutil::loc_data& loc_data,
129-
const std::vector<t_arch_switch_inf>& switches) {
133+
const std::vector<t_arch_switch_inf>& switches,
134+
bool can_skip_from_to) {
130135

131136
size_t num_children = count_children(node, "from", loc_data, ReqOpt::OPTIONAL);
132137
num_children += count_children(node, "to", loc_data, ReqOpt::OPTIONAL);
133138

134139
t_wireconn_inf wireconn;
135140
if (num_children == 0) {
136-
wireconn = parse_wireconn_inline(node, loc_data, switches);
141+
wireconn = parse_wireconn_inline(node, loc_data, switches, can_skip_from_to);
137142
} else {
138143
VTR_ASSERT(num_children > 0);
139144
wireconn = parse_wireconn_multinode(node, loc_data, switches);
@@ -154,33 +159,40 @@ t_wireconn_inf parse_wireconn(pugi::xml_node node,
154159

155160
static t_wireconn_inf parse_wireconn_inline(pugi::xml_node node,
156161
const pugiutil::loc_data& loc_data,
157-
const std::vector<t_arch_switch_inf>& switches) {
162+
const std::vector<t_arch_switch_inf>& switches,
163+
bool can_skip_from_to) {
158164

159165
// Parse an inline wireconn definition, using attributes
160-
expect_only_attributes(node, {"num_conns", "from_type", "to_type", "from_switchpoint", "to_switchpoint", "from_order", "to_order", "switch_override"}, loc_data);
166+
expect_only_attributes(node, {"num_conns", "from_type", "to_type", "from_switchpoint", "to_switchpoint", "from_order", "to_order", "switch_override", "side"}, loc_data);
161167

162168
t_wireconn_inf wc;
163169

170+
ReqOpt from_to_required = can_skip_from_to ? ReqOpt::OPTIONAL : ReqOpt::REQUIRED;
171+
164172
// get the connection style
165173
const char* char_prop = get_attribute(node, "num_conns", loc_data).value();
166174
parse_num_conns(char_prop, wc);
167175

168176
// get from type
169-
char_prop = get_attribute(node, "from_type", loc_data).value();
170-
parse_comma_separated_wire_types(char_prop, wc.from_switchpoint_set);
171-
177+
char_prop = get_attribute(node, "from_type", loc_data, from_to_required).value();
178+
if (!can_skip_from_to) {
179+
parse_comma_separated_wire_types(char_prop, wc.from_switchpoint_set);
180+
}
172181
// get to type
173-
char_prop = get_attribute(node, "to_type", loc_data).value();
174-
parse_comma_separated_wire_types(char_prop, wc.to_switchpoint_set);
175-
182+
char_prop = get_attribute(node, "to_type", loc_data, from_to_required).value();
183+
if (!can_skip_from_to) {
184+
parse_comma_separated_wire_types(char_prop, wc.to_switchpoint_set);
185+
}
176186
// get the source wire point
177-
char_prop = get_attribute(node, "from_switchpoint", loc_data).value();
178-
parse_comma_separated_wire_points(char_prop, wc.from_switchpoint_set);
179-
187+
char_prop = get_attribute(node, "from_switchpoint", loc_data, from_to_required).value();
188+
if (!can_skip_from_to) {
189+
parse_comma_separated_wire_points(char_prop, wc.from_switchpoint_set);
190+
}
180191
// get the destination wire point
181-
char_prop = get_attribute(node, "to_switchpoint", loc_data).value();
182-
parse_comma_separated_wire_points(char_prop, wc.to_switchpoint_set);
183-
192+
char_prop = get_attribute(node, "to_switchpoint", loc_data, from_to_required).value();
193+
if (!can_skip_from_to) {
194+
parse_comma_separated_wire_points(char_prop, wc.to_switchpoint_set);
195+
}
184196
char_prop = get_attribute(node, "from_order", loc_data, ReqOpt::OPTIONAL).value();
185197
parse_switchpoint_order(char_prop, wc.from_switchpoint_order);
186198

libs/libarchfpga/src/parse_switchblocks.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ void read_sb_wireconns(const std::vector<t_arch_switch_inf>& switches,
5757
*/
5858
t_wireconn_inf parse_wireconn(pugi::xml_node node,
5959
const pugiutil::loc_data& loc_data,
60-
const std::vector<t_arch_switch_inf>& switches);
60+
const std::vector<t_arch_switch_inf>& switches,
61+
bool can_skip_from_to = false);
6162

6263
/* checks for correctness of switch block read-in from the XML architecture file */
6364
void check_switchblock(const t_switchblock_inf& sb, const t_arch* arch);

libs/libarchfpga/src/read_xml_arch_file_sg.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,15 @@ void process_sg_tag(pugi::xml_node sg_list_tag,
113113

114114
// Parse gather pattern
115115
pugi::xml_node gather_node = pugiutil::get_single_child(sg_tag, "gather", loc_data);
116-
t_wireconn_inf gather_wireconn = parse_wireconn(pugiutil::get_single_child(gather_node, "wireconn", loc_data), loc_data, switches);
116+
t_wireconn_inf gather_wireconn = parse_wireconn(pugiutil::get_single_child(gather_node, "wireconn", loc_data), loc_data, switches, true);
117117
if (!gather_wireconn.to_switchpoint_set.empty()) {
118118
archfpga_throw(loc_data.filename_c_str(), loc_data.line(sg_tag), "Gather wireconn specification should not set any 'to' switchpoints");
119119
}
120120
sg.gather_pattern = gather_wireconn;
121121

122122
// Parse scatter pattern
123123
pugi::xml_node scatter_node = pugiutil::get_single_child(sg_tag, "scatter", loc_data);
124-
t_wireconn_inf scatter_wireconn = parse_wireconn(pugiutil::get_single_child(scatter_node, "wireconn", loc_data), loc_data, switches);
124+
t_wireconn_inf scatter_wireconn = parse_wireconn(pugiutil::get_single_child(scatter_node, "wireconn", loc_data), loc_data, switches, true);
125125
if (!gather_wireconn.from_switchpoint_set.empty()) {
126126
archfpga_throw(loc_data.filename_c_str(), loc_data.line(sg_tag), "Scatter wireconn specification should not set any 'from' switchpoints");
127127
}

0 commit comments

Comments
 (0)