Skip to content

Commit 8593839

Browse files
authored
Merge pull request #2067 from byuccl/diagonals
Addition of switch_override feature to custom SB
2 parents 130ec92 + c8553e5 commit 8593839

File tree

7 files changed

+643
-30
lines changed

7 files changed

+643
-30
lines changed

doc/src/arch/reference.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2301,7 +2301,7 @@ The full format is documented below.
23012301
Defined under the ``<switchfuncs>`` XML node, one or more ``<func...>`` entries is used to specify permutation functions that connect different sides of a switch block.
23022302

23032303

2304-
.. arch:tag:: <wireconn num_conns="expr" from_type="string, string, string, ..." to_type="string, string, string, ..." from_switchpoint="int, int, int, ..." to_switchpoint="int, int, int, ..." from_order="{fixed | shuffled}" to_order="{fixed | shuffled}"/>
2304+
.. arch:tag:: <wireconn num_conns="expr" from_type="string, string, string, ..." to_type="string, string, string, ..." from_switchpoint="int, int, int, ..." to_switchpoint="int, int, int, ..." from_order="{fixed | shuffled}" to_order="{fixed | shuffled}" switch_override="string"/>
23052305
23062306
:req_param num_conns:
23072307
Specifies how many connections should be created between the from_type/from_switchpoint set and the to_type/to_switchpoint set.
@@ -2401,6 +2401,14 @@ The full format is documented below.
24012401
24022402
.. note:: See ``from_switchpoint_order`` for value descritpions.
24032403

2404+
:opt_param switch_override:
2405+
2406+
Specifies the name of a switch to be used to override the wire_switch of the segments in the ``to`` set.
2407+
Can be used to create switch patterns where different switches are used for different types of connections.
2408+
By using a zero-delay and zero-resistance switch one can also create T and L shaped wire segments.
2409+
2410+
**Default:** If no override is specified, the usual wire_switch that drives the ``to`` wire will be used.
2411+
24042412
.. arch:tag:: <from type="string" switchpoint="int, int, int, ..."/>
24052413
24062414
:req_param type:

libs/libarchfpga/src/parse_switchblocks.cpp

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,16 @@ using vtr::t_formula_data;
4141
/*---- Functions for Parsing Switchblocks from Architecture ----*/
4242

4343
//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);
4545

4646
//Process the desired order of a wireconn
4747
static void parse_switchpoint_order(const char* order, SwitchPointOrder& switchpoint_order);
4848

4949
//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);
5151

5252
//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);
5454

5555
//Process a <from> or <to> sub-node of a multinode wireconn
5656
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
6565
/* Parses the number of connections type */
6666
static void parse_num_conns(std::string num_conns, t_wireconn_inf& wireconn);
6767

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+
6871
/* checks for correctness of a unidir switchblock. */
6972
static void check_unidir_switchblock(const t_switchblock_inf* sb);
7073

@@ -79,7 +82,7 @@ static void check_wireconn(const t_arch* arch, const t_wireconn_inf& wireconn);
7982
/*---- Functions for Parsing Switchblocks from Architecture ----*/
8083

8184
/* 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) {
8386
/* Make sure that Node is a switchblock */
8487
check_node(Node, "switchblock", loc_data);
8588

@@ -94,33 +97,33 @@ void read_sb_wireconns(const t_arch_switch_inf* /*switches*/, int /*num_switches
9497
SubElem = get_first_child(Node, "wireconn", loc_data);
9598
}
9699
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
98101
sb->wireconns.push_back(wc);
99102
SubElem = SubElem.next_sibling(SubElem.name());
100103
}
101104

102105
return;
103106
}
104107

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) {
106109
t_wireconn_inf wc;
107110

108111
size_t num_children = count_children(node, "from", loc_data, ReqOpt::OPTIONAL);
109112
num_children += count_children(node, "to", loc_data, ReqOpt::OPTIONAL);
110113

111114
if (num_children == 0) {
112-
parse_wireconn_inline(node, loc_data, wc);
115+
parse_wireconn_inline(node, loc_data, wc, switches, num_switches);
113116
} else {
114117
VTR_ASSERT(num_children > 0);
115-
parse_wireconn_multinode(node, loc_data, wc);
118+
parse_wireconn_multinode(node, loc_data, wc, switches, num_switches);
116119
}
117120

118121
return wc;
119122
}
120123

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) {
122125
//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);
124127

125128
/* get the connection style */
126129
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
147150

148151
char_prop = get_attribute(node, "to_order", loc_data, ReqOpt::OPTIONAL).value();
149152
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);
150157
}
151158

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) {
153160
expect_only_children(node, {"from", "to"}, loc_data);
154161

155162
/* get the connection style */
@@ -162,6 +169,9 @@ void parse_wireconn_multinode(pugi::xml_node node, const pugiutil::loc_data& loc
162169
char_prop = get_attribute(node, "to_order", loc_data, ReqOpt::OPTIONAL).value();
163170
parse_switchpoint_order(char_prop, wc.to_switchpoint_order);
164171

172+
char_prop = get_attribute(node, "switch_override", loc_data, ReqOpt::OPTIONAL).value();
173+
parse_switch_override(char_prop, wc, switches, num_switches);
174+
165175
size_t num_from_children = count_children(node, "from", loc_data);
166176
size_t num_to_children = count_children(node, "to", loc_data);
167177

@@ -331,6 +341,24 @@ void read_sb_switchfuncs(pugi::xml_node Node, t_switchblock_inf* sb, const pugiu
331341
return;
332342
}
333343

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+
334362
/* checks for correctness of switch block read-in from the XML architecture file */
335363
void check_switchblock(const t_switchblock_inf* sb, const t_arch* arch) {
336364
/* get directionality */

libs/libarchfpga/src/physical_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,6 +1711,8 @@ struct t_wireconn_inf {
17111711
std::vector<t_wire_switchpoints> to_switchpoint_set; //The set of segment/wirepoints representing the 'to' set (union of all t_wire_switchpoints in vector)
17121712
SwitchPointOrder from_switchpoint_order = SwitchPointOrder::FIXED; //The desired from_switchpoint_set ordering
17131713
SwitchPointOrder to_switchpoint_order = SwitchPointOrder::FIXED; //The desired to_switchpoint_set ordering
1714+
int switch_override_indx = DEFAULT_SWITCH; // index in switch array of the switch used to override wire_switch of the 'to' set.
1715+
// DEFAULT_SWITCH is a sentinel value (i.e. the usual driving switch from a wire for the receiving wire will be used)
17141716

17151717
std::string num_conns_formula; /* Specifies how many connections should be made for this wireconn.
17161718
*

vpr/src/route/build_switchblocks.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,13 @@ static void compute_wireconn_connections(
983983
t_switchblock_edge sb_edge;
984984
sb_edge.from_wire = from_wire;
985985
sb_edge.to_wire = to_wire;
986-
sb_edge.switch_ind = to_chan_details[to_x][to_y][to_wire].arch_wire_switch();
986+
987+
// if the switch override has been set, use that. Otherwise use default
988+
if (wireconn_ptr->switch_override_indx != DEFAULT_SWITCH) {
989+
sb_edge.switch_ind = wireconn_ptr->switch_override_indx;
990+
} else {
991+
sb_edge.switch_ind = to_chan_details[to_x][to_y][to_wire].arch_wire_switch();
992+
}
987993
VTR_LOGV(verbose, " make_conn: %d -> %d switch=%d\n", sb_edge.from_wire, sb_edge.to_wire, sb_edge.switch_ind);
988994

989995
/* and now, finally, add this switchblock connection to the switchblock connections map */

0 commit comments

Comments
 (0)