diff options
author | Nilay Vaish <nilay@cs.wisc.edu> | 2014-10-11 15:02:23 -0500 |
---|---|---|
committer | Nilay Vaish <nilay@cs.wisc.edu> | 2014-10-11 15:02:23 -0500 |
commit | e8ed7b1d1b5bef31e9874f679a5797c2e00d06f1 (patch) | |
tree | 421c9c50377aa664958685914f5504c4c019e21f /ext/dsent/model/optical_graph/OpticalWavelength.cc | |
parent | a098fad174d8559037602b248b8e6f7f46bfebbb (diff) | |
download | gem5-e8ed7b1d1b5bef31e9874f679a5797c2e00d06f1.tar.xz |
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.
Diffstat (limited to 'ext/dsent/model/optical_graph/OpticalWavelength.cc')
-rw-r--r-- | ext/dsent/model/optical_graph/OpticalWavelength.cc | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/ext/dsent/model/optical_graph/OpticalWavelength.cc b/ext/dsent/model/optical_graph/OpticalWavelength.cc new file mode 100644 index 000000000..fa5e36f63 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalWavelength.cc @@ -0,0 +1,129 @@ + +#include "model/optical_graph/OpticalWavelength.h" +#include "model/optical_graph/OpticalNode.h" +#include "model/optical_graph/OpticalLaser.h" +#include "model/optical_graph/OpticalModulator.h" +#include "model/optical_graph/OpticalFilter.h" +#include "model/optical_graph/OpticalDetector.h" +#include "model/optical_graph/OpticalWavelength.h" +#include <list> +#include <cmath> + +namespace DSENT +{ + using std::list; + using std::min; + + OpticalWavelength::OpticalWavelength(const String& instance_name_, const WavelengthGroup& wavelengths_) + : m_instance_name_(instance_name_), m_wavelengths_(wavelengths_) + { + m_data_paths_ = new vector<OpticalDataPath>; + } + + OpticalWavelength::~OpticalWavelength() + { + delete m_data_paths_; + } + + const String& OpticalWavelength::getInstanceName() const + { + return m_instance_name_; + } + + void OpticalWavelength::addDataPath(OpticalLaser* laser_, OpticalModulator* modulator_, OpticalDetector* detector_, double loss_) + { + // Expected wavelengths check + ASSERT(laser_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + + " -> " + laser_->getInstanceName() + " is not expecting the set wavelengths!"); + ASSERT(modulator_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + + " -> " + modulator_->getInstanceName() + " is not expecting the set wavelengths!"); + ASSERT(detector_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + + " -> " + detector_->getInstanceName() + " is not expecting the set wavelengths!"); + + // Check to see if the modulator and laser already have a data path entry + bool entry_exists = false; + for (unsigned int i = 0; i < m_data_paths_->size(); ++i) + { + OpticalDataPath& current = m_data_paths_->at(i); + bool current_laser = current.laser == laser_; + bool current_modulator = current.modulator == modulator_; + + ASSERT((current_modulator && current_laser) || !current_modulator, "[Error] " + + getInstanceName() + " -> Modulator is the same, but laser is different?"); + + // If it is already in the table + if (current_modulator) + { + entry_exists = true; + current.detectors.push_back(detector_); + current.losses.push_back(loss_); + } + } + + // If it wasn't found, add the entry + if (!entry_exists) + m_data_paths_->push_back(OpticalDataPath(laser_, modulator_, detector_, loss_)); + return; + } + + const vector<OpticalDataPath>* OpticalWavelength::getDataPaths() const + { + return (const vector<OpticalDataPath>*) m_data_paths_; + } + + WavelengthGroup OpticalWavelength::getWavelengths() const + { + return m_wavelengths_; + } + + double OpticalWavelength::getLaserPower(unsigned int number_detectors_) const + { + ASSERT(number_detectors_ > 0, "[Error] " + getInstanceName() + + " -> Number of detectors must be non-zero!"); + // Find the number of actual wavelengths + int number_wavelengths = getWavelengths().second - getWavelengths().first + 1; + // Laser power sum + double laser_power_sum = 0; + // Loop through all data paths + for (unsigned int i = 0; i < getDataPaths()->size(); ++i) + { + // Get the current data_path + const OpticalDataPath& current_path = getDataPaths()->at(i); + // Create data structure holding the worstcase detectors + list<double>* detectors = new list<double>(); + // Get the extinction ratio of the modulator + double ER_dB = current_path.modulator->getExtinctionRatio(); + // Get the insertion loss of the modulator + double IR_dB = current_path.modulator->getInsertionLoss(); + // Walk through all detectors in a data path + for (unsigned int j = 0; j < current_path.detectors.size(); ++j) + { + // Convert sensitivity, extinction ratio, and path loss to a required laser power + double current_laser_power = current_path.detectors[j]->getSensitivity(ER_dB) * + std::pow(10.0, (current_path.losses[j] + IR_dB) / 10.0) * + 1.0 / (1.0 - pow(10, -ER_dB / 10)); + + // Add the laser power + detectors->push_back(current_laser_power); + } + // Cap the number of detectors + number_detectors_ = std::min(number_detectors_, (unsigned int) current_path.detectors.size()); + // Sort the detectors list in ascending order, only necessary if the number + // of detectors is < total number of detectors + if (number_detectors_ < detectors->size()) + detectors->sort(); + // Sum up the laser power from the worst-case detectors + list<double>::reverse_iterator iter = detectors->rbegin(); + for (unsigned int j = 0; j < number_detectors_; ++j) + { + laser_power_sum += (*iter) / current_path.laser->getEfficiency(); + ++iter; + } + delete detectors; + } + return number_wavelengths * laser_power_sum; + } + +} // namespace DSENT + + |