@@ -3766,6 +3766,10 @@ static void ProcessSegments(pugi::xml_node Parent,
3766
3766
// Unidir requires the following tags
3767
3767
expected_subtags.emplace_back (" mux" );
3768
3768
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" );
3769
3773
}
3770
3774
3771
3775
else {
@@ -3796,28 +3800,78 @@ static void ProcessSegments(pugi::xml_node Parent,
3796
3800
/* Get the wire and opin switches, or mux switch if unidir */
3797
3801
if (UNI_DIRECTIONAL == Segs[i].directionality ) {
3798
3802
// 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
+ }
3806
3813
}
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;
3807
3824
}
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
+ }
3812
3842
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
+ }
3818
3849
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
+ }
3820
3866
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
+ }
3821
3875
else {
3822
3876
VTR_ASSERT (BI_DIRECTIONAL == Segs[i].directionality );
3823
3877
SubElem = get_single_child (Node, " wire_switch" , loc_data);
0 commit comments