@@ -66,7 +66,7 @@ using namespace pugiutil;
66
66
struct t_fc_override {
67
67
std::string port_name;
68
68
std::string seg_name;
69
- e_fc_type fc_type ;
69
+ e_fc_value_type fc_value_type ;
70
70
float fc_value;
71
71
};
72
72
@@ -103,7 +103,7 @@ static void ProcessMode(pugi::xml_node Parent, t_mode * mode, const t_arch& arch
103
103
const pugiutil::loc_data& loc_data);
104
104
static void Process_Fc (pugi::xml_node Node, t_type_descriptor * Type, t_segment_inf *segments, int num_segments, const pugiutil::loc_data& loc_data);
105
105
static t_fc_override Process_Fc_override (pugi::xml_node node, const pugiutil::loc_data& loc_data);
106
- static e_fc_type string_to_fc_type (const std::string& str, pugi::xml_node node, const pugiutil::loc_data& loc_data);
106
+ static e_fc_value_type string_to_fc_value_type (const std::string& str, pugi::xml_node node, const pugiutil::loc_data& loc_data);
107
107
static void ProcessComplexBlockProps (pugi::xml_node Node, t_type_descriptor * Type, const pugiutil::loc_data& loc_data);
108
108
static void ProcessSizingTimingIpinCblock (pugi::xml_node Node,
109
109
struct s_arch *arch, const bool timing_enabled, const pugiutil::loc_data& loc_data);
@@ -1626,21 +1626,21 @@ static void ProcessMode(pugi::xml_node Parent, t_mode * mode, const t_arch& arch
1626
1626
/* Takes in the node ptr for the 'fc' elements and initializes
1627
1627
* the appropriate fields of type. */
1628
1628
static void Process_Fc (pugi::xml_node Node, t_type_descriptor * Type, t_segment_inf *segments, int num_segments, const pugiutil::loc_data& loc_data) {
1629
- e_fc_type default_fc_in_type = e_fc_type ::FRACTIONAL;
1630
- e_fc_type default_fc_out_type = e_fc_type ::FRACTIONAL;
1629
+ e_fc_value_type default_fc_in_value_type = e_fc_value_type ::FRACTIONAL;
1630
+ e_fc_value_type default_fc_out_value_type = e_fc_value_type ::FRACTIONAL;
1631
1631
float default_fc_in_value = std::numeric_limits<float >::quiet_NaN ();
1632
1632
float default_fc_out_value = std::numeric_limits<float >::quiet_NaN ();
1633
1633
1634
1634
/* Load the default fc_in */
1635
1635
auto default_fc_in_attrib = get_attribute (Node, " default_in_type" , loc_data);
1636
- default_fc_in_type = string_to_fc_type (default_fc_in_attrib.value (), Node, loc_data);
1636
+ default_fc_in_value_type = string_to_fc_value_type (default_fc_in_attrib.value (), Node, loc_data);
1637
1637
1638
1638
auto default_in_val_attrib = get_attribute (Node, " default_in_val" , loc_data);
1639
1639
default_fc_in_value = vtr::atof (default_in_val_attrib.value ());
1640
1640
1641
1641
/* Load the default fc_out */
1642
1642
auto default_fc_out_attrib = get_attribute (Node, " default_out_type" , loc_data);
1643
- default_fc_out_type = string_to_fc_type (default_fc_out_attrib.value (), Node, loc_data);
1643
+ default_fc_out_value_type = string_to_fc_value_type (default_fc_out_attrib.value (), Node, loc_data);
1644
1644
1645
1645
auto default_out_val_attrib = get_attribute (Node, " default_out_val" , loc_data);
1646
1646
default_fc_out_value = vtr::atof (default_out_val_attrib.value ());
@@ -1669,25 +1669,60 @@ static void Process_Fc(pugi::xml_node Node, t_type_descriptor * Type, t_segment_
1669
1669
const t_port* port = &pb_type->ports [iport];
1670
1670
1671
1671
t_fc_specification fc_spec;
1672
+
1672
1673
fc_spec.seg_index = iseg;
1673
1674
1674
- // Apply the defaults
1675
+ // Apply type and defaults
1675
1676
if (port->type == IN_PORT) {
1676
- fc_spec.fc_type = default_fc_in_type;
1677
+ fc_spec.fc_type = e_fc_type::IN;
1678
+ fc_spec.fc_value_type = default_fc_in_value_type;
1677
1679
fc_spec.fc_value = default_fc_in_value;
1678
1680
} else {
1679
1681
VTR_ASSERT (port->type == OUT_PORT);
1680
- fc_spec.fc_type = default_fc_out_type;
1682
+ fc_spec.fc_type = e_fc_type::OUT;
1683
+ fc_spec.fc_value_type = default_fc_out_value_type;
1681
1684
fc_spec.fc_value = default_fc_out_value;
1682
1685
}
1683
1686
1684
1687
// Apply any matching overrides
1688
+ bool default_overriden = false ;
1685
1689
for (const auto & fc_override : fc_overrides) {
1686
- if (fc_override.port_name == port->name || fc_override.seg_name == segments[iseg].name ) {
1690
+ bool apply_override = false ;
1691
+ if (!fc_override.port_name .empty () && !fc_override.seg_name .empty ()) {
1692
+ // Both port and seg names are specified require exact match on both
1693
+ if (fc_override.port_name == port->name && fc_override.seg_name == segments[iseg].name ) {
1694
+ apply_override = true ;
1695
+ }
1696
+
1697
+ } else if (!fc_override.port_name .empty ()) {
1698
+ VTR_ASSERT (fc_override.seg_name .empty ());
1699
+ // Only the port name specified, require it to match
1700
+ if (fc_override.port_name == port->name ) {
1701
+ apply_override = true ;
1702
+ }
1703
+ } else {
1704
+ VTR_ASSERT (!fc_override.seg_name .empty ());
1705
+ VTR_ASSERT (fc_override.port_name .empty ());
1706
+ // Only the seg name specified, require it to match
1707
+ if (fc_override.seg_name == segments[iseg].name ) {
1708
+ apply_override = true ;
1709
+ }
1710
+ }
1711
+
1712
+ if (apply_override) {
1687
1713
// Exact match, or partial match to either port or seg name
1688
- // Note that we continue searching, this ensures that the last matching override is applied last
1689
- fc_spec.fc_type = fc_override.fc_type ;
1714
+ // Note that we continue searching, this ensures that the last matching override (in file order)
1715
+ // is applied last
1716
+
1717
+ if (default_overriden) {
1718
+ // Warn if multiple overrides match
1719
+ vtr::printf_warning (loc_data.filename_c_str (), loc_data.line (Node), " Multiple matching Fc overrides found; the last will be applied\n " );
1720
+ }
1721
+
1722
+ fc_spec.fc_value_type = fc_override.fc_value_type ;
1690
1723
fc_spec.fc_value = fc_override.fc_value ;
1724
+
1725
+ default_overriden = true ;
1691
1726
}
1692
1727
}
1693
1728
@@ -1727,7 +1762,7 @@ static t_fc_override Process_Fc_override(pugi::xml_node node, const pugiutil::lo
1727
1762
fc_override.seg_name = attrib.value ();
1728
1763
seen_port_or_seg |= true ;
1729
1764
} else if (attrib.name () == std::string (" fc_type" )) {
1730
- fc_override.fc_type = string_to_fc_type (attrib.value (), node, loc_data);
1765
+ fc_override.fc_value_type = string_to_fc_value_type (attrib.value (), node, loc_data);
1731
1766
seen_fc_type = true ;
1732
1767
} else if (attrib.name () == std::string (" fc_val" )) {
1733
1768
fc_override.fc_value = vtr::atof (attrib.value ());
@@ -1756,20 +1791,20 @@ static t_fc_override Process_Fc_override(pugi::xml_node node, const pugiutil::lo
1756
1791
return fc_override;
1757
1792
}
1758
1793
1759
- static e_fc_type string_to_fc_type (const std::string& str, pugi::xml_node node, const pugiutil::loc_data& loc_data) {
1760
- e_fc_type fc_type = e_fc_type ::FRACTIONAL;
1794
+ static e_fc_value_type string_to_fc_value_type (const std::string& str, pugi::xml_node node, const pugiutil::loc_data& loc_data) {
1795
+ e_fc_value_type fc_value_type = e_fc_value_type ::FRACTIONAL;
1761
1796
1762
1797
if (str == " frac" ) {
1763
- fc_type = e_fc_type ::FRACTIONAL;
1798
+ fc_value_type = e_fc_value_type ::FRACTIONAL;
1764
1799
} else if (str == " abs" ) {
1765
- fc_type = e_fc_type ::ABSOLUTE;
1800
+ fc_value_type = e_fc_value_type ::ABSOLUTE;
1766
1801
} else {
1767
1802
archfpga_throw (loc_data.filename_c_str (), loc_data.line (node),
1768
1803
" Invalid fc_type '%s'. Must be 'abs' or 'frac'.\n " ,
1769
1804
str.c_str ());
1770
1805
}
1771
1806
1772
- return fc_type ;
1807
+ return fc_value_type ;
1773
1808
}
1774
1809
1775
1810
/* Thie processes attributes of the 'type' tag */
0 commit comments