00001 // Torc - Copyright 2011 University of Southern California. All Rights Reserved. 00002 // $HeadURL: https://torc-isi.svn.sourceforge.net/svnroot/torc-isi/branches/staging/0.9/src/torc/physical/ConfigMap.hpp $ 00003 // $Id: ConfigMap.hpp 10 2011-10-12 18:40:16Z nsteiner $ 00004 00005 // This program is free software: you can redistribute it and/or modify it under the terms of the 00006 // GNU General Public License as published by the Free Software Foundation, either version 3 of the 00007 // License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 00010 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 00011 // the GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License along with this program. If 00014 // not, see <http://www.gnu.org/licenses/>. 00015 00016 /// \file 00017 /// \brief Header for the ConfigMap class. 00018 00019 #ifndef TORC_PHYSICAL_CONFIGMAP_HPP 00020 #define TORC_PHYSICAL_CONFIGMAP_HPP 00021 00022 #include "torc/physical/Config.hpp" 00023 #include <map> 00024 00025 namespace torc { 00026 namespace physical { 00027 00028 /// \brief Configuration setting map. 00029 /// \details A configuration map is a collection of {setting:name:value} triplets, used to 00030 /// represent additional information for netlist design elements. Every physical netlist 00031 /// element that can be configured inherits from this class: Design, Module, Instance, Net. 00032 /// \details Special Xilinx settings beginning with underscores are permitted to exist multiple 00033 /// times in the same ConfigMap. This is consistent with XDL usage, particularly in the 00034 /// case of XDL design statements. 00035 /// \note The name mentioned here is a user-specified name stemming from the design. It is not 00036 /// the configuration setting name. For example, in configuration "DFF:blink:#FF", "DFF" 00037 /// is the specified setting, "blink" is the name that the design assigns to the 00038 /// corresponding resource, and "#FF" is the value to which "DFF" is set. 00039 class ConfigMap : private std::multimap<std::string, Config> { 00040 protected: 00041 // types 00042 /// \brief Imported type name. 00043 typedef std::string string; 00044 /// \brief Convenience typedef to represent our superclass. 00045 typedef std::multimap<std::string, Config> super; 00046 // members 00047 /// \brief Sequence index to use for the next configuration added to this map. 00048 SequenceIndex mNextSequenceIndex; 00049 public: 00050 // types 00051 /// \brief Constant iterator to {setting,Config} pairs. 00052 typedef const_iterator const_iterator; 00053 // constructors 00054 /// \brief Null constructor. 00055 ConfigMap(void) : super(), mNextSequenceIndex(eSequenceIndexFirst) {} 00056 // iterators 00057 /// \brief Returns the begin constant iterator for configurations. 00058 const_iterator configBegin(void) const { return super::begin(); } 00059 /// \brief Returns the end constant iterator for configurations. 00060 const_iterator configEnd(void) const { return super::end(); } 00061 // functions 00062 /// \brief Returns the number of configurations in the map. 00063 size_t getConfigCount(void) const { return super::size(); } 00064 /// \brief Returns true if the configuration map is empty. 00065 bool configIsEmpty(void) const { return super::empty(); } 00066 /// \brief Clears the configuration map. 00067 void clearConfig(void) { ConfigMap::clear(); } 00068 /// \brief Returns true if the specified setting exists in the map. 00069 bool hasConfig(const string& inSetting) const { 00070 /// \todo Acquire mutex. 00071 const_iterator result = find(inSetting); 00072 return result != end(); 00073 /// \todo Release mutex. 00074 } 00075 /// \brief Looks up the specified setting in the map. 00076 /// \param inSetting The setting to query. 00077 /// \param outConfig Reference to a configuration to be populated if the setting exists in 00078 /// the map. Default values are used if the setting does not exist. 00079 /// \note If this is a special setting with multiple configuration entries, only the first 00080 /// one will be placed in outConfig. 00081 /// \returns true if the settings exists in the map, or false otherwise. 00082 bool getConfig(const string& inSetting, Config& outConfig) { 00083 // employ friendship status to reach in and reference the config name and value members 00084 return getConfig(inSetting, outConfig.mName, outConfig.mValue); 00085 } 00086 /// \brief Looks up the specified setting in the map. 00087 /// \param inSetting The setting to query. 00088 /// \param outName Reference to a string to accept the configuration name, or the default 00089 /// name if the setting does not exist. 00090 /// \param outValue Reference to a string to accept the configuration value, or the default 00091 /// value if the setting does not exist. 00092 /// \note If this is a special setting with multiple configuration entries, only the first 00093 /// one will be placed in outName and outValue. 00094 /// \returns true if the settings exists in the map, or false otherwise. 00095 bool getConfig(const string& inSetting, string& outName, string& outValue) { 00096 /// \todo Acquire mutex. 00097 iterator result = find(inSetting); 00098 if(result == end()) { 00099 // if the key doesn't exist, return default values 00100 outName = Config::sConfigDefaultName; 00101 outValue = Config::sConfigDefaultValue; 00102 return false; 00103 } else { 00104 // otherwise return the config data 00105 Config& config = result->second; 00106 outName = config.getName(); 00107 outValue = config.getValue(); 00108 return true; 00109 } 00110 /// \todo Release mutex. 00111 } 00112 /// \brief Sets the configuration for the given setting. 00113 /// \details If this is a regular setting, then any existing configuration for the setting 00114 /// will be replaced, but if this is a special setting for which multiple 00115 /// configurations are allowed, it will be added to the map alongside the existing 00116 /// configurations. 00117 /// \param inSetting The setting of interest. 00118 /// \param inConfig The configuration to set. 00119 void setConfig(const string& inSetting, const Config& inConfig) { 00120 setConfig(inSetting, inConfig.getName(), inConfig.getValue()); 00121 } 00122 /// \brief Sets the configuration for the given setting. 00123 /// \details If this is a regular setting, then any existing configuration for the setting 00124 /// will be replaced, but if this is a special setting for which multiple 00125 /// configurations are allowed, it will be added to the map alongside the existing 00126 /// configurations. 00127 /// \param inSetting The setting of interest. 00128 /// \param inName The configuration name to set. 00129 /// \param inValue The configuration value to set. 00130 void setConfig(const string& inSetting, const string& inName, const string& inValue) { 00131 /// \todo Acquire mutex. 00132 // if duplicates are disallowed for this setting, erase any matching entries 00133 if(!allowConfigDuplicates(inSetting)) { 00134 std::pair<iterator, iterator> range = equal_range(inSetting); 00135 if(range.first != range.second) erase(range.first, range.second); 00136 } 00137 // insert the config entry 00138 insert(make_pair(inSetting, Config(inName, inValue, mNextSequenceIndex++))); 00139 /// \todo Release mutex. 00140 } 00141 /// \brief Merges the configurations from the given ConfigMap into this one. 00142 /// \details For each setting, if the setting does not already exist in the map, it is 00143 /// added. If the setting does exist, then the incoming configuration either replaces 00144 /// the existing setting (in the case of regular settings), or is added to the map (in 00145 /// the case of special settings for which multiple configurations are allowed). 00146 void addConfigs(const ConfigMap& inConfigMap) { 00147 if(inConfigMap.empty()) return; 00148 /// \todo Acquire mutex. 00149 const_iterator p = inConfigMap.begin(); 00150 const_iterator e = inConfigMap.end(); 00151 while(p != e) { 00152 // look up the config information 00153 const string& setting = p->first; 00154 const Config& config = p->second; 00155 // try to insert the setting into the map (while respecting our special semantics) 00156 setConfig(setting, config); 00157 p++; 00158 } 00159 /// \todo Release mutex. 00160 } 00161 /// \brief Returns true if multiple configurations are allowed for the given setting. 00162 /// \details Special Xilinx settings prefixed with an underscore may have multiple 00163 /// configurations in the map. 00164 static bool allowConfigDuplicates(const string& inSetting) { 00165 return inSetting.size() >= 1 && inSetting[0] == '_'; 00166 } 00167 /// \brief Returns a range that encompasses all of the configurations for the given setting. 00168 /// \returns An iterator pair that encompasses all configurations for the setting. Refer 00169 /// to std::pair to determine how to extract the iterators. 00170 std::pair<iterator, iterator> getMultiConfigValues(const string& inSetting) 00171 { return equal_range(inSetting); } 00172 /// \brief Returns the number of configurations for the given setting. 00173 size_type getMultiConfigCount(const string& inSetting) { return count(inSetting); } 00174 }; 00175 00176 } // namespace physical 00177 } // namespace torc 00178 00179 #endif // TORC_PHYSICAL_CONFIGMAP_HPP