From e8ed7b1d1b5bef31e9874f679a5797c2e00d06f1 Mon Sep 17 00:00:00 2001 From: Nilay Vaish Date: Sat, 11 Oct 2014 15:02:23 -0500 Subject: ext: add the source code for DSENT This patch adds a tool called DSENT to the ext/ directory. DSENT is a tool that models power and area for on-chip networks. The next patch adds a script for using the tool. --- ext/dsent/util/CommonType.h | 36 +++++++ ext/dsent/util/Config.cc | 105 +++++++++++++++++++ ext/dsent/util/Config.h | 40 +++++++ ext/dsent/util/Constants.cc | 20 ++++ ext/dsent/util/Constants.h | 21 ++++ ext/dsent/util/Result.cc | 249 ++++++++++++++++++++++++++++++++++++++++++++ ext/dsent/util/Result.h | 105 +++++++++++++++++++ 7 files changed, 576 insertions(+) create mode 100644 ext/dsent/util/CommonType.h create mode 100644 ext/dsent/util/Config.cc create mode 100644 ext/dsent/util/Config.h create mode 100644 ext/dsent/util/Constants.cc create mode 100644 ext/dsent/util/Constants.h create mode 100644 ext/dsent/util/Result.cc create mode 100644 ext/dsent/util/Result.h (limited to 'ext/dsent/util') diff --git a/ext/dsent/util/CommonType.h b/ext/dsent/util/CommonType.h new file mode 100644 index 000000000..e8c9705bb --- /dev/null +++ b/ext/dsent/util/CommonType.h @@ -0,0 +1,36 @@ +#ifndef __DSENT_UTIL_COMMON_TYPE_H__ +#define __DSENT_UTIL_COMMON_TYPE_H__ + +#include + +#include "libutil/LibUtil.h" + +#include "util/Result.h" + +#include "tech/TechModel.h" + +namespace DSENT +{ + using std::cout; + using std::endl; + + // Enable functions + using LibUtil::deletePtrMap; + using LibUtil::clearPtrMap; + using LibUtil::deletePtrVector; + using LibUtil::clearPtrVector; + + // Enable classes + using LibUtil::Exception; + using LibUtil::Log; + using LibUtil::String; + using LibUtil::Map; + using LibUtil::StringMap; + + typedef StringMap ParameterMap; + typedef StringMap PropertyMap; + +} // namespace DSENT + +#endif // __DSENT_UTIL_COMMON_TYPE_H__ + diff --git a/ext/dsent/util/Config.cc b/ext/dsent/util/Config.cc new file mode 100644 index 000000000..a12a30070 --- /dev/null +++ b/ext/dsent/util/Config.cc @@ -0,0 +1,105 @@ +#include "util/Config.h" + +#include "model/std_cells/StdCellLib.h" + +namespace DSENT +{ + + Config* Config::ms_singleton_ = NULL; + + void Config::allocate(const String& cfg_file_name_) + { + Log::printLine("Config::allocate"); + + // Allocate static Config instance + ASSERT(!ms_singleton_, "Config singleton is allocated"); + ms_singleton_ = new Config(); + ms_singleton_->readFile(cfg_file_name_); + + Log::printLine("Config::allocate - End"); + return; + } + + void Config::release() + { + Log::printLine("Config::release"); + + // Release static Config instance + ASSERT(ms_singleton_, "Config singleton is not allocated"); + delete ms_singleton_; + ms_singleton_ = NULL; + + Log::printLine("Config::release - End"); + return; + } + + Config* Config::getSingleton() + { + ASSERT(ms_singleton_, "Config singleton is not allocated"); + return ms_singleton_; + } + + Config::Config() + : m_tech_model_(NULL) + {} + + Config::~Config() + { + delete m_tech_model_; + } + + void Config::setTechModel(const TechModel* tech_model_) + { + ASSERT((tech_model_ != NULL), "tech_model_ is null"); + + m_tech_model_ = tech_model_; + return; + } + + const TechModel* Config::getTechModel() const + { + ASSERT((m_tech_model_ != NULL), "m_tech_model_ is null"); + + return m_tech_model_; + } + + void Config::readFile(const String& file_name_) + { + Log::printLine("Config::readFile"); + + LibUtil::Config::readFile(file_name_); + + Log::printLine("Config::readFile - End"); + return; + } + + void Config::constructTechModel(const String& overwrite_str_) + { + Log::printLine("Config::constructTechModel"); + + // Allocate static TechModel instance + const String& electrical_tech_model_filename = get("ElectricalTechModelFilename"); + + TechModel* tech_model = new TechModel(); + tech_model->readFile(electrical_tech_model_filename); + if(keyExist("PhotonicTechModelFilename")) + { + const String& photonic_tech_model_filename = get("PhotonicTechModelFilename"); + tech_model->readFile(photonic_tech_model_filename); + } + + // Overwrite the settings at runtime + tech_model->readString(overwrite_str_); + + // Allocate static StdCellLib instance + StdCellLib* std_cell_lib = new StdCellLib(tech_model); + + // Set the StdCellLib pointer in static TechModel instance + tech_model->setStdCellLib(std_cell_lib); + + m_tech_model_ = tech_model; + Log::printLine("Config::constructTechModel - End"); + return; + } +} // namespace DSENT + diff --git a/ext/dsent/util/Config.h b/ext/dsent/util/Config.h new file mode 100644 index 000000000..910f5ca8c --- /dev/null +++ b/ext/dsent/util/Config.h @@ -0,0 +1,40 @@ +#ifndef __DSENT_UTIL_CONFIG_H__ +#define __DSENT_UTIL_CONFIG_H__ + +#include "util/CommonType.h" + +namespace DSENT +{ + class TechModel; + class StdCellLib; + + class Config : public LibUtil::Config + { + public: + static void allocate(const String& cfg_file_name_); + static void release(); + static Config* getSingleton(); + + protected: + static Config* ms_singleton_; + + public: + Config(); + ~Config(); + + public: + void setTechModel(const TechModel* tech_model_); + const TechModel* getTechModel() const; + + void constructTechModel(const String& overwrite_str_); + + protected: + void readFile(const String& file_name_); + + protected: + const TechModel* m_tech_model_; + }; // class Config +} // namespace DSENT + +#endif // __DSENT_UTIL_CONFIG_H__ + diff --git a/ext/dsent/util/Constants.cc b/ext/dsent/util/Constants.cc new file mode 100644 index 000000000..6af0a275a --- /dev/null +++ b/ext/dsent/util/Constants.cc @@ -0,0 +1,20 @@ + +#include "util/Constants.h" + +namespace DSENT +{ + // PI + const double Constants::pi = 3.14159; //PI + // Boltzman's + const double Constants::k = 1.3806503e-23; // m^2 * kg / (s^2 * K); + // Speed of light + const double Constants::c = 2.9979246e8; // m/s + // Charge of electron + const double Constants::q = 1.602e-19; // C + // Permitivity of free space + const double Constants::e0 = 8.85e-12; + // Permitivity ratio of silicon + const double Constants::es = 11.7; + +} // namespace DSENT + diff --git a/ext/dsent/util/Constants.h b/ext/dsent/util/Constants.h new file mode 100644 index 000000000..4447e6991 --- /dev/null +++ b/ext/dsent/util/Constants.h @@ -0,0 +1,21 @@ +#ifndef __DSENT_UTIL_CONSTANTS_H__ +#define __DSENT_UTIL_CONSTANTS_H__ + +namespace DSENT +{ + class Constants + { + public: + // Physical constants + static const double pi; + static const double k; + static const double c; + static const double q; + static const double e0; + static const double es; + }; + +} // namespace DSENT + +#endif // __DSENT_UTIL_CONSTANTS_H__ + diff --git a/ext/dsent/util/Result.cc b/ext/dsent/util/Result.cc new file mode 100644 index 000000000..f2a1b23ea --- /dev/null +++ b/ext/dsent/util/Result.cc @@ -0,0 +1,249 @@ +#include "util/Result.h" + +#include + +#include "libutil/Log.h" +#include "libutil/Assert.h" + +namespace DSENT +{ + using std::ostream; + using std::endl; + + Result::SubResult::SubResult(const Result* sub_result_, const String& producer_, double num_results_) + : m_result_(sub_result_), m_producer_(producer_), m_num_results_(num_results_) + { + // Check if the result is not a null pointer + ASSERT((sub_result_ != NULL), "Internal error: sub_result_ is null"); + + // Check if the number of results greater than 0 + ASSERT((num_results_ >= 0), "Internal error: num_results_ (" + String(num_results_) + ") is less than 0"); + } + + Result::SubResult::~SubResult() + {} + + const Result* Result::SubResult::getResult() const + { + return m_result_; + } + + const String& Result::SubResult::getProducer() const + { + return m_producer_; + } + + double Result::SubResult::getNumResults() const + { + return m_num_results_; + } + + Result::SubResult* Result::SubResult::clone() const + { + return new SubResult(*this); + } + + Result::SubResult::SubResult(const SubResult& sub_result_) + : m_result_(sub_result_.m_result_), m_producer_(sub_result_.m_producer_), m_num_results_(sub_result_.m_num_results_) + {} + + Result::Result() + {} + + Result::Result(const String& result_name_) + : m_result_name_(result_name_) + {} + + Result::~Result() + { + // Clear all sub results + for(vector::iterator it = m_sub_results_.begin(); + it != m_sub_results_.end(); ++it) + { + SubResult* sub_result = (*it); + delete sub_result; + } + } + + const String& Result::getName() const + { + return m_result_name_; + } + + void Result::setValue(double /* value_ */) + { + throw LibUtil::Exception("[Error] " + getName() + " -> Cannot set the value of a non-atomic result!"); + return; + } + + void Result::addValue(double /* value_ */) + { + throw LibUtil::Exception("[Error] " + getName() + + " -> Cannot add the value of a non-atomic result"); + return; + } + + double Result::getValue() const + { + throw LibUtil::Exception("[Error] " + getName() + " -> Cannot get the value of a non-atomic result!"); + return 0.0; + } + + void Result::addSubResult(const Result* sub_result_, const String& result_producer_, double num_results_) + { + SubResult* new_sub_result = new SubResult(sub_result_, result_producer_, num_results_); + m_sub_results_.push_back(new_sub_result); + return; + } + + void Result::removeAllSubResults() + { + // Clear all sub results + for(vector::iterator it = m_sub_results_.begin(); + it != m_sub_results_.end(); ++it) + { + SubResult* sub_result = (*it); + delete sub_result; + } + m_sub_results_.clear(); + return; + } + + double Result::calculateSum() const + { + double sum = 0.0; + + // Loop through all sub results and calculate the sum + for(vector::const_iterator it = m_sub_results_.begin(); + it != m_sub_results_.end(); ++it) + { + const SubResult* temp_sub_result = (*it); + const Result* temp_result = temp_sub_result->getResult(); + double num_results = temp_sub_result->getNumResults(); + sum += temp_result->calculateSum()*num_results; + } + return sum; + } + + void Result::print(const String& prepend_str_, int detail_level_, ostream& ost_) const + { + print(prepend_str_, 1.0, detail_level_, ost_); + return; + } + + Result* Result::clone() const + { + return new Result(*this); + } + + Result::Result(const Result& result_) + { + // Copy the result name + m_result_name_ = result_.m_result_name_; + + // Clone all sub results + for(vector::const_iterator it = m_sub_results_.begin(); + it != m_sub_results_.end(); ++it) + { + const SubResult* temp_sub_result = (*it); + SubResult* new_sub_result = temp_sub_result->clone(); + m_sub_results_.push_back(new_sub_result); + } + } + + void Result::print(const String& prepend_str_, double num_results_, int detail_level_, ostream& ost_) const + { + // Go down to lower level if detail_level_ > 0, else print the sthe sthe sthe sum + if(detail_level_ > 0) + { + for(vector::const_iterator it = m_sub_results_.begin(); + it != m_sub_results_.end(); ++it) + { + const SubResult* temp_sub_result = (*it); + const Result* temp_result = temp_sub_result->getResult(); + const String& temp_producer = temp_sub_result->getProducer(); + const String& temp_result_name = temp_result->getName(); + double temp_num_results = temp_sub_result->getNumResults(); + String temp_prepend_str = prepend_str_ + "->" + temp_producer; + + if(!temp_result_name.empty()) + { + temp_prepend_str += ":" + temp_result_name; + } + temp_result->print(temp_prepend_str, num_results_*temp_num_results, detail_level_ - 1, ost_); + } + } + else + { + ost_ << prepend_str_ << " = " << calculateSum()*num_results_; + ost_ << " (" << calculateSum() << " * " << num_results_ << ")" << endl; + } + return; + } + + void Result::printHierarchy(const String& prepend_str_, int detail_level_, ostream& ost_) const + { + if(detail_level_ > 0) + { + for(vector::const_iterator it = m_sub_results_.begin(); it != m_sub_results_.end(); ++it) + { + const SubResult* temp_sub_result = (*it); + const Result* temp_result = temp_sub_result->getResult(); + const String& temp_producer = temp_sub_result->getProducer(); + const String& temp_result_name = temp_result->getName(); + String temp_prepend_str = prepend_str_ + " "; + + ost_ << prepend_str_ << " |--" << temp_producer << "->" << temp_result_name << endl; + + temp_result->printHierarchy(temp_prepend_str, detail_level_ - 1, ost_); + } + } + return; + } + + AtomicResult::AtomicResult(const String& result_name_, double value_) + : Result(result_name_), m_value_(value_) + {} + + AtomicResult::~AtomicResult() + {} + + void AtomicResult::setValue(double value_) + { + m_value_ = value_; + return; + } + + void AtomicResult::addValue(double value_) + { + m_value_ += value_; + return; + } + + double AtomicResult::getValue() const + { + return m_value_; + } + + double AtomicResult::calculateSum() const + { + return m_value_; + } + + AtomicResult* AtomicResult::clone() const + { + return new AtomicResult(*this); + } + + AtomicResult::AtomicResult(const AtomicResult& atomic_result_) + : Result(atomic_result_), m_value_(atomic_result_.m_value_) + {} + + void AtomicResult::print(const String& prepend_str_, double num_results_, int /* detail_level_ */, ostream& ost_) const + { + ost_ << prepend_str_ << " = " << m_value_*num_results_; + ost_ << " (" << m_value_ << " * " << num_results_ << ")" << endl; + return; + } +} // namespace DSENT + diff --git a/ext/dsent/util/Result.h b/ext/dsent/util/Result.h new file mode 100644 index 000000000..96f0e5805 --- /dev/null +++ b/ext/dsent/util/Result.h @@ -0,0 +1,105 @@ +#ifndef __DSENT_UTIL_RESULT_H__ +#define __DSENT_UTIL_RESULT_H__ + +#include +#include + +#include "libutil/String.h" +#include "libutil/Map.h" + +namespace DSENT +{ + using std::ostream; + using std::vector; + using LibUtil::Map; + using LibUtil::String; + + class Result + { + public: + class SubResult + { + public: + SubResult(const Result* result_, const String& producer_, double num_results_); + ~SubResult(); + + public: + const Result* getResult() const; + const String& getProducer() const; + double getNumResults() const; + + SubResult* clone() const; + + protected: + SubResult(const SubResult& sub_result_); + + private: + // Pointer to the actual result + const Result* m_result_; + // Name of the instance that produces this result + String m_producer_; + // Number of the times this result should be produce + double m_num_results_; + }; // class SubResult + + public: + Result(); + Result(const String& result_name_); + virtual ~Result(); + + public: + // Get the name of result + const String& getName() const; + // Add a sub result + void addSubResult(const Result* sub_result_, const String& result_producer_, double num_results_); + // Remove all sub results + void removeAllSubResults(); + // Set the value of a result, not available except for AtomicResult + virtual void setValue(double value_); + // Set the value of a result, not available except for AtomicResult + virtual void addValue(double value_); + // Get the value of a result, not available except for AtomicResult + virtual double getValue() const; + // Loop through all sub results and calculate the sum + virtual double calculateSum() const; + // Print the result with hierarchy if detail_level_ > 0. Print the sum when detail_level_ <= 0 + void print(const String& prepend_str_, int detail_level_, ostream& ost_) const; + // Print the tree of the results + void printHierarchy(const String& prepend_str_, int detail_level_, ostream& ost_) const; + + Result* clone() const; + + protected: + Result(const Result& result_); + virtual void print(const String& prepend_str_, double num_results_, int detail_level_, ostream& ost_) const; + + private: + String m_result_name_; + vector m_sub_results_; + }; // class Result + + class AtomicResult : public Result + { + public: + AtomicResult(const String& result_name_, double value_ = 0.0); + ~AtomicResult(); + + public: + void setValue(double value_); + void addValue(double value_); + double getValue() const; + virtual double calculateSum() const; + AtomicResult* clone() const; + + protected: + AtomicResult(const AtomicResult& atomic_result_); + virtual void print(const String& prepend_str_, double num_results_, int detail_level_, ostream& ost_) const; + + private: + // Actual value of the result + double m_value_; + }; // class AtomicResult +} // namespace DSENT + +#endif // __DSENT_UTIL_RESULT_H__ + -- cgit v1.2.3