Skip to content

Commit b4be0a5

Browse files
committed
changed the architecture parser to allow definition of mux_inc and mux_dec for specifiying different switches for wires with different direction
1 parent 5d0486f commit b4be0a5

File tree

2 files changed

+82
-20
lines changed

2 files changed

+82
-20
lines changed

libs/libarchfpga/src/physical_types.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,12 @@ enum e_Fc_type {
15611561
* relation to the switches from the architecture file, *
15621562
* not the expanded list of switches that is built *
15631563
* at the end of build_rr_graph *
1564+
* @param arch_wire_switch_dec: Same as arch_wire_switch but used only for *
1565+
* decremental tracks if it is specified in the *
1566+
* architecture file. *
1567+
* @param arch_opin_switch_dec: Same as arch_opin_switch but used only for *
1568+
* decremental tracks if it is specified in the *
1569+
* architecture file *
15641570
* *
15651571
* @param arch_opin_between_dice_switch: Index of the switch type that *
15661572
* connects output pins (OPINs) *to* this segment from *
@@ -1579,14 +1585,14 @@ enum e_Fc_type {
15791585
* Cmetal: Capacitance of a routing track, per unit logic block length. *
15801586
* Rmetal: Resistance of a routing track, per unit logic block length. *
15811587
* (UDSD by AY) drivers: How do signals driving a routing track connect to *
1582-
* the track?
1588+
* the track? *
15831589
* seg_index: The index of the segment as stored in the appropriate Segs list*
15841590
* Upon loading the architecture, we use this field to keep track *
15851591
* the segment's index in the unified segment_inf vector. This is *
15861592
* useful when building the rr_graph for different Y & X channels *
1587-
* in terms of track distribution and segment type. *
1593+
* in terms of track distribution and segment type. *
15881594
* res_type: Determines the routing network to which the segment belongs. *
1589-
* Possible values are:
1595+
* Possible values are: *
15901596
* - GENERAL: The segment is part of the general routing *
15911597
* resources. *
15921598
* - GCLK: The segment is part of the global routing network. *
@@ -1600,6 +1606,8 @@ struct t_segment_inf {
16001606
int length;
16011607
short arch_wire_switch;
16021608
short arch_opin_switch;
1609+
short arch_wire_switch_dec;
1610+
short arch_opin_switch_dec;
16031611
short arch_opin_between_dice_switch = -1;
16041612
float frac_cb;
16051613
float frac_sb;

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3766,6 +3766,10 @@ static void ProcessSegments(pugi::xml_node Parent,
37663766
//Unidir requires the following tags
37673767
expected_subtags.emplace_back("mux");
37683768
expected_subtags.emplace_back("mux_inter_die");
3769+
//with the following two tags, we can allow the architecture file to define
3770+
//different muxes with different delays for wires with different directions
3771+
expected_subtags.emplace_back("mux_inc");
3772+
expected_subtags.emplace_back("mux_dec");
37693773
}
37703774

37713775
else {
@@ -3796,28 +3800,78 @@ static void ProcessSegments(pugi::xml_node Parent,
37963800
/* Get the wire and opin switches, or mux switch if unidir */
37973801
if (UNI_DIRECTIONAL == Segs[i].directionality) {
37983802
//Get the switch name for same die wire and track connections
3799-
SubElem = get_single_child(Node, "mux", loc_data);
3800-
tmp = get_attribute(SubElem, "name", loc_data).value();
3801-
3802-
/* Match names */
3803-
for (j = 0; j < NumSwitches; ++j) {
3804-
if (0 == strcmp(tmp, Switches[j].name.c_str())) {
3805-
break; /* End loop so j is where we want it */
3803+
SubElem = get_single_child(Node, "mux", loc_data, ReqOpt::OPTIONAL);
3804+
tmp = get_attribute(SubElem, "name", loc_data, ReqOpt::OPTIONAL).as_string(nullptr);
3805+
3806+
//check if <mux> tag is defined in the architecture, otherwise we should look for <mux_inc> and <mux_dec>
3807+
if(tmp){
3808+
/* Match names */
3809+
for (j = 0; j < NumSwitches; ++j) {
3810+
if (0 == strcmp(tmp, Switches[j].name.c_str())) {
3811+
break; /* End loop so j is where we want it */
3812+
}
38063813
}
3814+
if (j >= NumSwitches) {
3815+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem),
3816+
"'%s' is not a valid mux name.\n", tmp);
3817+
}
3818+
3819+
/* Unidir muxes must have the same switch
3820+
* for wire and opin fanin since there is
3821+
* really only the mux in unidir. */
3822+
Segs[i].arch_wire_switch = j;
3823+
Segs[i].arch_opin_switch = j;
38073824
}
3808-
if (j >= NumSwitches) {
3809-
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem),
3810-
"'%s' is not a valid mux name.\n", tmp);
3811-
}
3825+
else { //if a general mux is not defined, we should look for specific mux for each direction in the architecture file
3826+
SubElem = get_single_child(Node, "mux_inc", loc_data, ReqOpt::OPTIONAL);
3827+
tmp = get_attribute(SubElem, "name", loc_data, ReqOpt::OPTIONAL).as_string(nullptr);
3828+
if(!tmp){
3829+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem),
3830+
"if mux is not specified in a wire segment, both mux_inc and mux_dec should be specified");
3831+
} else{
3832+
/* Match names */
3833+
for (j = 0; j < NumSwitches; ++j) {
3834+
if (0 == strcmp(tmp, Switches[j].name.c_str())) {
3835+
break; /* End loop so j is where we want it */
3836+
}
3837+
}
3838+
if (j >= NumSwitches) {
3839+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem),
3840+
"'%s' is not a valid mux name.\n", tmp);
3841+
}
38123842

3813-
/* Unidir muxes must have the same switch
3814-
* for wire and opin fanin since there is
3815-
* really only the mux in unidir. */
3816-
Segs[i].arch_wire_switch = j;
3817-
Segs[i].arch_opin_switch = j;
3843+
/* Unidir muxes must have the same switch
3844+
* for wire and opin fanin since there is
3845+
* really only the mux in unidir. */
3846+
Segs[i].arch_wire_switch = j;
3847+
Segs[i].arch_opin_switch = j;
3848+
}
38183849

3819-
}
3850+
SubElem = get_single_child(Node, "mux_dec", loc_data, ReqOpt::OPTIONAL);
3851+
tmp = get_attribute(SubElem, "name", loc_data, ReqOpt::OPTIONAL).as_string(nullptr);
3852+
if(!tmp){
3853+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem),
3854+
"if mux is not specified in a wire segment, both mux_inc and mux_dec should be specified");
3855+
} else{
3856+
/* Match names */
3857+
for (j = 0; j < NumSwitches; ++j) {
3858+
if (0 == strcmp(tmp, Switches[j].name.c_str())) {
3859+
break; /* End loop so j is where we want it */
3860+
}
3861+
}
3862+
if (j >= NumSwitches) {
3863+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem),
3864+
"'%s' is not a valid mux name.\n", tmp);
3865+
}
38203866

3867+
/* Unidir muxes must have the same switch
3868+
* for wire and opin fanin since there is
3869+
* really only the mux in unidir. */
3870+
Segs[i].arch_wire_switch_dec = j;
3871+
Segs[i].arch_opin_switch_dec = j;
3872+
}
3873+
}
3874+
}
38213875
else {
38223876
VTR_ASSERT(BI_DIRECTIONAL == Segs[i].directionality);
38233877
SubElem = get_single_child(Node, "wire_switch", loc_data);

0 commit comments

Comments
 (0)