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 | |
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')
18 files changed, 1110 insertions, 0 deletions
diff --git a/ext/dsent/model/optical_graph/OpticalDetector.cc b/ext/dsent/model/optical_graph/OpticalDetector.cc new file mode 100644 index 000000000..8de005099 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalDetector.cc @@ -0,0 +1,32 @@ + +#include "model/optical_graph/OpticalDetector.h" +#include "model/optical_graph/OpticalReceiver.h" + +namespace DSENT +{ + OpticalDetector::OpticalDetector(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, OpticalReceiver* receiver_) + : OpticalNode(OpticalNode::DETECTOR, instance_name_, model_, wavelengths_), m_receiver_(receiver_), m_responsivity_(0) + { + m_sensitivity_ = 0.0; + } + + OpticalDetector::~OpticalDetector() + { + + } + + void OpticalDetector::setResponsivity(double responsivity_) + { + m_responsivity_ = responsivity_; + return; + } + + double OpticalDetector::getSensitivity(double ER_dB_) const + { + // Get responsivity (in Amps) of the receiver, divide by responsivity to get sensitivity in Watts + return m_receiver_->getSensitivity(ER_dB_) / m_responsivity_; + } + +} // namespace DSENT + + diff --git a/ext/dsent/model/optical_graph/OpticalDetector.h b/ext/dsent/model/optical_graph/OpticalDetector.h new file mode 100644 index 000000000..e3994f176 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalDetector.h @@ -0,0 +1,45 @@ +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALDETECTOR_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALDETECTOR_H__ + +#include "model/optical_graph/OpticalNode.h" +#include "util/CommonType.h" + +namespace DSENT +{ + class OpticalReceiver; + + class OpticalDetector : public OpticalNode + { + public: + OpticalDetector(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, OpticalReceiver* receiver_); + ~OpticalDetector(); + + public: + // Set the responsitivity of the photodetector + void setResponsivity(double responsivity_); + + // Get the detector sensitivity given an extinction ratio (in Watts) + double getSensitivity(double ER_dB_) const; + + // Ask the receiver for its power (ONLY use for power optimization, as this + // assumes an activity of 1.0) + double getPower() const; + + private: + // Disable copy constructor + OpticalDetector(const OpticalDetector& node_); + + private: + // The required laser power + double m_sensitivity_; + // The receiver connected to this detector + OpticalReceiver* m_receiver_; + // Responsivity of the photodetector + double m_responsivity_; + + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALDETECTOR_H__ + diff --git a/ext/dsent/model/optical_graph/OpticalFilter.cc b/ext/dsent/model/optical_graph/OpticalFilter.cc new file mode 100644 index 000000000..1bac9a8c9 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalFilter.cc @@ -0,0 +1,65 @@ + +#include "model/optical_graph/OpticalFilter.h" + +namespace DSENT +{ + OpticalFilter::OpticalFilter(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, bool drop_all_, const WavelengthGroup& drop_wavelengths_) + : OpticalNode(OpticalNode::FILTER, instance_name_, model_, wavelengths_), m_drop_all_(drop_all_), m_drop_wavelengths_(drop_wavelengths_) + { + m_drop_loss_ = 0.0; + m_drop_port_ = NULL; + } + + OpticalFilter::~OpticalFilter() + { + + } + + bool OpticalFilter::getDropAll() const + { + return m_drop_all_; + } + + WavelengthGroup OpticalFilter::getDropWavelengths() const + { + return m_drop_wavelengths_; + } + + void OpticalFilter::setDropLoss(double drop_loss_) + { + m_drop_loss_ = drop_loss_; + return; + } + + double OpticalFilter::getDropLoss() const + { + return m_drop_loss_; + } + + void OpticalFilter::setDropPort(OpticalNode* drop_port_) + { + m_drop_port_ = drop_port_; + } + + OpticalNode* OpticalFilter::getDropPort() + { + return m_drop_port_; + } + + bool OpticalFilter::isDropped(const WavelengthGroup& wavelengths_) const + { + // Check that the lower limits are within bounds + bool lower_match = (wavelengths_.first >= getDropWavelengths().first); + // Check that the upper limits are within bounds + bool upper_match = (wavelengths_.second <= getDropWavelengths().second); + // Assert that there are no misalignments + ASSERT(lower_match == upper_match, "[Error] " + getInstanceName() + + " -> Wavelength group misalignment!" + + " InWavelength" + toString(wavelengths_) + + ", DropWavelength" + toString(getDropWavelengths())); + // Both upper and lower bounds must match + return (upper_match && lower_match); + } +} // namespace DSENT + + diff --git a/ext/dsent/model/optical_graph/OpticalFilter.h b/ext/dsent/model/optical_graph/OpticalFilter.h new file mode 100644 index 000000000..e908618e4 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalFilter.h @@ -0,0 +1,48 @@ +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALFILTER_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALFILTER_H__ + +#include "model/optical_graph/OpticalNode.h" +#include "util/CommonType.h" + +namespace DSENT +{ + class OpticalFilter : public OpticalNode + { + public: + OpticalFilter(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, bool drop_all_, const WavelengthGroup& drop_wavelengths_); + ~OpticalFilter(); + + public: + // Get the drop all flag + bool getDropAll() const; + // Get drop wavelengths + WavelengthGroup getDropWavelengths() const; + // Set and get the drop loss + void setDropLoss(double drop_loss_); + double getDropLoss() const; + // Set and get drop port + void setDropPort(OpticalNode* drop_port_); + OpticalNode* getDropPort(); + // Checks to see if a set of wavelengths will be dropped + bool isDropped(const WavelengthGroup& wavelengths_) const; + + private: + // Disable copy constructor + OpticalFilter(const OpticalFilter& node_); + + private: + // Whether to drop all the optical signal for the drop wavelengths + // i.e. so that the drop wavelengths are not traced anymore + const bool m_drop_all_; + // The loss incurred from in to drop port + double m_drop_loss_; + // The wavelengths that are dropped + const WavelengthGroup m_drop_wavelengths_; + // The node at the drop port + OpticalNode* m_drop_port_; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALFILTER_H__ + diff --git a/ext/dsent/model/optical_graph/OpticalGraph.cc b/ext/dsent/model/optical_graph/OpticalGraph.cc new file mode 100644 index 000000000..424f2bcb2 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalGraph.cc @@ -0,0 +1,216 @@ + +#include "model/optical_graph/OpticalGraph.h" + +#include "model/OpticalModel.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" + +namespace DSENT +{ + // Initialize the next visited number to be one above the initial number + // used by OpticalNode + int OpticalGraph::msTreeNum = OpticalNode::OPTICAL_NODE_INIT_VISITED_NUM + 1; + + OpticalGraph::OpticalGraph(const String& instance_name_, OpticalModel* model_) + : m_instance_name_(instance_name_), m_model_(model_) + { + + } + + OpticalGraph::~OpticalGraph() + { + + } + + const String& OpticalGraph::getInstanceName() const + { + return m_instance_name_; + } + + //------------------------------------------------------------------------- + // Perform Datapath power optimization + //------------------------------------------------------------------------- + bool OpticalGraph::performPowerOpt(OpticalNode* node_, const WavelengthGroup& wavelengths_, unsigned int number_detectors_, double util_) + { + // Total number of iterations + unsigned int number_iterations = 1250; + // Maximum IL + ER + double IL_ER_max = 10; + // Figure out the step size used in the sweep + double step = (double) (IL_ER_max / sqrt(2 * number_iterations)); + + // Assume it is possible + bool possible = true; + + // Begin optical data path power optimization + Log::printLine(getInstanceName() + " -> Beginning optical data path power optimization"); + + // Trace the specified wavelengths + OpticalWavelength* wavelength = traceWavelength(wavelengths_, node_); + + // For each data path found in the wavelength + const vector<OpticalDataPath>* data_paths = wavelength->getDataPaths(); + for (unsigned int i = 0; i < data_paths->size(); ++i) + { + const OpticalDataPath& data_path = data_paths->at(i); + // Default to worst possible modulator + double best_power = 1e99; + double best_IL = IL_ER_max - step; + double best_ER = step; + + // Perform power optimization for this data path + Log::printLine(getInstanceName() + " -> Optimize data path - Laser = " + data_path.laser->getInstanceName() + + ", Modulator = " + data_path.modulator->getInstanceName()); + + if (data_path.modulator->canOptimizeLoss()) + { + // Iterate over IL and ER to find optimal set of IL and ER + for (double IL = step; IL < IL_ER_max; IL += step) + { + for (double ER = step; ER <= (IL_ER_max - IL); ER += step) + { + // Ask the modulator to try this new ER and IL + bool success = data_path.modulator->setModulatorSpec(IL, ER); + // If the modulator was successful + if (success) + { + double laser_power = wavelength->getLaserPower(number_detectors_); + double modulator_power = data_path.modulator->getPower(util_); + double total_power = laser_power + modulator_power; + // If this is the new lowest power point + if (total_power < best_power) + { + best_power = total_power; + best_IL = IL; + best_ER = ER; + } + } + } + } + + // Set IL and ER to the best ones we found + bool success = data_path.modulator->setModulatorSpec(best_IL, best_ER); + // If the best one we found was still not possible... + possible = possible && success; + + // Print best IL and ER + Log::printLine(getInstanceName() + " -> Best IL=" + (String) best_IL + ", Best ER=" + (String) best_ER + + ", Best Laser/Mod Power=" + (String) best_power); + } + else + { + // Perform power optimization for this data path + Log::printLine(getInstanceName() + " -> Data path not set to allow optimization"); + } + } + + // End optical data path power optimization + Log::printLine(getInstanceName() + " -> End optical data path power optimization"); + + delete wavelength; + return possible; + } + + + //------------------------------------------------------------------------- + // Trace wavelength(s), returning a wavelength data structure + //------------------------------------------------------------------------- + OpticalWavelength* OpticalGraph::traceWavelength(const WavelengthGroup& wavelengths_, OpticalNode* node_) + { + setTreeNum(getTreeNum() + 1); + OpticalWavelength* wavelength = new OpticalWavelength("TraceWavelength", wavelengths_); + return traceWavelength(wavelength, node_, NULL, NULL, 0.0); + } + + OpticalWavelength* OpticalGraph::traceWavelength(OpticalWavelength* wavelength_, OpticalNode* node_, OpticalLaser* laser_, OpticalModulator* modulator_, double loss_) + { + // If the node has already been visited, don't do anything! + if (node_->getVisitedNum() != getTreeNum()) + { + // Set the new parity for this node + node_->setVisitedNum(getTreeNum()); + + // Calculate the loss of the current path + double current_loss = loss_ + node_->getLoss(); + // Check if the current node is a laser, modulator or detector + if(node_->getType() == OpticalNode::LASER) + { + // Set the laser lighting up the wavelength + ASSERT(laser_ == NULL, "[Error] " + getInstanceName() + " -> Multiple " + + "Lasers lighting up the wavelength!"); + laser_ = (OpticalLaser*) node_; + } + else if (node_->getType() == OpticalNode::MODULATOR) + { + // Check that the path already lit up by a laser and there are no + // modulators already driving data + ASSERT(laser_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " + + "modulator (" + node_->getInstanceName() + ") prior to being lit up by a laser!"); + ASSERT(modulator_ == NULL, "[Error] " + getInstanceName() + " -> Two modulators are driving" + + " the same optical data path (" + node_->getInstanceName() + ")!"); + modulator_ = (OpticalModulator*) node_; + } + else if (node_->getType() == OpticalNode::DETECTOR) + { + // Check that the path is both lit up by a laser and there is + // a modulator driving data + ASSERT(laser_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " + + "detector (" + node_->getInstanceName() + ") prior to being lit up by a laser!"); + ASSERT(modulator_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " + + "detector (" + node_->getInstanceName() + ") prior to being driven by a modulator!"); + // Add a detector to the wavelength + wavelength_->addDataPath(laser_, modulator_, (OpticalDetector*) node_, current_loss); + } + + // Traverse downstream nodes to calculate the delay through each downstream path + vector<OpticalNode*>* d_nodes = node_->getDownstreamNodes(); + bool trace_downstream = (node_->getType() != OpticalNode::DETECTOR); + // Do special things when traversing filters + if (node_->getType() == OpticalNode::FILTER) + { + OpticalFilter* filter_node = (OpticalFilter*) node_; + if (filter_node->isDropped(wavelength_->getWavelengths())) + traceWavelength(wavelength_, filter_node->getDropPort(), laser_, modulator_, loss_ + filter_node->getDropLoss()); + + // If the filter is not modeled as a complete drop, continue tracing downstream + trace_downstream = !filter_node->getDropAll(); + } + + if (trace_downstream) + { + // Trace downstream nodes + for (unsigned int i = 0; i < d_nodes->size(); ++i) + traceWavelength(wavelength_, d_nodes->at(i), laser_, modulator_, current_loss); + } + } + return wavelength_; + } + + //------------------------------------------------------------------------- + OpticalGraph::OpticalGraph(const OpticalGraph& /* graph_ */) + { + // Disabled + } + + OpticalModel* OpticalGraph::getModel() + { + return m_model_; + } + + void OpticalGraph::setTreeNum(int tree_num_) + { + msTreeNum = tree_num_; + return; + } + + int OpticalGraph::getTreeNum() + { + return msTreeNum; + } + +} // namespace DSENT + diff --git a/ext/dsent/model/optical_graph/OpticalGraph.h b/ext/dsent/model/optical_graph/OpticalGraph.h new file mode 100644 index 000000000..43dab1bf8 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalGraph.h @@ -0,0 +1,62 @@ +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALGRAPH_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALGRAPH_H__ + +#include <vector> + +#include "util/CommonType.h" +#include "model/optical_graph/OpticalNode.h" + +namespace DSENT +{ + class OpticalNode; + class OpticalWavelength; + + class OpticalGraph + { + public: + // The visited number for the next timing run. This needs to be + // global because several timing trees may be created to evaluate + // a single timing path, causing problems + static int msTreeNum; + + public: + // Construct timing tree that watches over model_ + OpticalGraph(const String& instance_name_, OpticalModel* model_); + ~OpticalGraph(); + + public: + // Get graph name + const String& getInstanceName() const; + // Perform datapath power optimization by balancing insertion loss and extinction + // ratio with modulator/receiver and laser power, returns false if there are no + // designs that are possible + bool performPowerOpt(OpticalNode* node_, const WavelengthGroup& wavelengths_, unsigned int number_detectors_, double util_); + // Recursively trace a wavelength starting from an OpticalLaser + // source finding all lasers, modulators and detectors that a + // wavelength group hits. + OpticalWavelength* traceWavelength(const WavelengthGroup& wavelengths_, OpticalNode* node_); + OpticalWavelength* traceWavelength(OpticalWavelength* wavelength_, OpticalNode* node_, OpticalLaser* laser_, OpticalModulator* modulator_, double loss_); + // Return the model + OpticalModel* getModel(); + + private: + + // Disable the use of copy constructor + OpticalGraph(const OpticalGraph& graph_); + + public: + // Set the sequence number of the optical graph + static void setTreeNum(int tree_num_); + static int getTreeNum(); + + private: + // Name of the optical graph + const String m_instance_name_; + // A pointer to the model that contains this node + OpticalModel* m_model_; + + }; // class OpticalGraph +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALGRAPH_H__ + diff --git a/ext/dsent/model/optical_graph/OpticalLaser.cc b/ext/dsent/model/optical_graph/OpticalLaser.cc new file mode 100644 index 000000000..8b25f90bd --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalLaser.cc @@ -0,0 +1,31 @@ + +#include "model/optical_graph/OpticalLaser.h" + +namespace DSENT +{ + OpticalLaser::OpticalLaser(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_) + : OpticalNode(OpticalNode::LASER, instance_name_, model_, wavelengths_), m_efficiency_(0) + { + + } + + void OpticalLaser::setEfficiency(double efficiency_) + { + m_efficiency_ = efficiency_; + return; + } + + double OpticalLaser::getEfficiency() const + { + return m_efficiency_; + } + + OpticalLaser::~OpticalLaser() + { + + } + + +} // namespace DSENT + + diff --git a/ext/dsent/model/optical_graph/OpticalLaser.h b/ext/dsent/model/optical_graph/OpticalLaser.h new file mode 100644 index 000000000..911517e1d --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalLaser.h @@ -0,0 +1,32 @@ +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALLASER_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALLASER_H__ + +#include "model/optical_graph/OpticalNode.h" +#include "util/CommonType.h" + +namespace DSENT +{ + class OpticalLaser : public OpticalNode + { + public: + OpticalLaser(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_); + ~OpticalLaser(); + + public: + void setEfficiency(double efficiency_); + double getEfficiency() const; + + private: + // Disable copy constructor + OpticalLaser(const OpticalLaser& node_); + + private: + // Laser efficiency + double m_efficiency_; + + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALLASER_H__ + diff --git a/ext/dsent/model/optical_graph/OpticalModulator.cc b/ext/dsent/model/optical_graph/OpticalModulator.cc new file mode 100644 index 000000000..662560341 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalModulator.cc @@ -0,0 +1,54 @@ + +#include "model/optical_graph/OpticalModulator.h" +#include "model/optical_graph/OpticalTransmitter.h" + +namespace DSENT +{ + OpticalModulator::OpticalModulator(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, bool opt_loss_, OpticalTransmitter* transmitter_) + : OpticalNode(OpticalNode::MODULATOR, instance_name_, model_, wavelengths_), m_transmitter_(transmitter_), m_insertion_loss_(0), m_extinction_ratio_(0), m_opt_loss_(opt_loss_) + { + + } + + OpticalModulator::~OpticalModulator() + { + + } + + bool OpticalModulator::canOptimizeLoss() const + { + return m_opt_loss_; + } + + void OpticalModulator::setLosses(double IL_dB_, double ER_dB_) + { + m_insertion_loss_ = IL_dB_; + m_extinction_ratio_ = ER_dB_; + + return; + } + + bool OpticalModulator::setModulatorSpec(double IL_dB_, double ER_dB_) + { + // Ask the transmitter to design to those specs, returns success or fail + return m_transmitter_->setTransmitterSpec(IL_dB_, ER_dB_); + } + + double OpticalModulator::getPower(double util_) const + { + return m_transmitter_->getPower(util_); + } + + double OpticalModulator::getInsertionLoss() const + { + return m_insertion_loss_; + } + + double OpticalModulator::getExtinctionRatio() const + { + return m_extinction_ratio_; + } + +} // namespace DSENT + + diff --git a/ext/dsent/model/optical_graph/OpticalModulator.h b/ext/dsent/model/optical_graph/OpticalModulator.h new file mode 100644 index 000000000..416c2a0f3 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalModulator.h @@ -0,0 +1,51 @@ +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALMODULATOR_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALMODULATOR_H__ + +#include "model/optical_graph/OpticalNode.h" +#include "util/CommonType.h" + +namespace DSENT +{ + class OpticalTransmitter; + + class OpticalModulator : public OpticalNode + { + public: + OpticalModulator(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_, bool opt_loss_, OpticalTransmitter* transmitter_); + ~OpticalModulator(); + + public: + // Set losses + void setLosses(double IL_dB_, double ER_dB_); + // Tell the modulator to set a new insertion loss and extinction ratio + bool setModulatorSpec(double IL_dB_, double ER_dB_); + // Get modulator insertion loss + double getInsertionLoss() const; + // Get modulator extinction ratio + double getExtinctionRatio() const; + // Ask whether the model is able to optimize for insertion loss + // and extinction ratios + bool canOptimizeLoss() const; + // Ask the modulator for its power at a given utilization + double getPower(double util_) const; + + private: + // Disable copy constructor + OpticalModulator(const OpticalModulator& node_); + + private: + // Optical sender of the modulator + OpticalTransmitter* m_transmitter_; + // Insertion loss of the modulator + double m_insertion_loss_; + // Extinction ratio of the modulator + double m_extinction_ratio_; + // Whether the modulator can be optimized + bool m_opt_loss_; + + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALMODULATOR_H__ + diff --git a/ext/dsent/model/optical_graph/OpticalNode.cc b/ext/dsent/model/optical_graph/OpticalNode.cc new file mode 100644 index 000000000..89e034b09 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalNode.cc @@ -0,0 +1,96 @@ + +#include "model/optical_graph/OpticalNode.h" + +namespace DSENT +{ + // Set the optical node initial visited num + const int OpticalNode::OPTICAL_NODE_INIT_VISITED_NUM = 0; + + OpticalNode::OpticalNode(Type type_, const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_) + :m_type_(type_), m_instance_name_(instance_name_), m_model_(model_), m_wavelengths_(wavelengths_) + { + m_loss_ = 0.0; + setVisitedNum(OpticalNode::OPTICAL_NODE_INIT_VISITED_NUM); + m_downstream_nodes_ = new vector<OpticalNode*>; + } + + OpticalNode::~OpticalNode() + { + + } + + OpticalNode::Type OpticalNode::getType() const + { + return m_type_; + } + + vector<OpticalNode*>* OpticalNode::getDownstreamNodes() const + { + return m_downstream_nodes_; + } + + const String& OpticalNode::getInstanceName() const + { + return m_instance_name_; + } + + OpticalModel* OpticalNode::getModel() + { + return m_model_; + } + + const OpticalModel* OpticalNode::getModel() const + { + return (const OpticalModel*) m_model_; + } + + void OpticalNode::addDownstreamNode(OpticalNode* node_) + { + ASSERT(node_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + + " -> Downstream node not expecting a superset of the current wavelengths"); + m_downstream_nodes_->push_back(node_); + } + + WavelengthGroup OpticalNode::getWavelengths() const + { + return m_wavelengths_; + } + + bool OpticalNode::isExpected(const WavelengthGroup& wavelengths_) const + { + // Check that the lower limits are within bounds + bool lower_match = (wavelengths_.first >= getWavelengths().first); + // Check that the upper limits are within bounds + bool upper_match = (wavelengths_.second <= getWavelengths().second); + // Assert that there are no misalignments + ASSERT(lower_match == upper_match, "[Error] " + getInstanceName() + + " -> Wavelength group misalignment!"); + // Both upper and lower bounds must match + return (upper_match && lower_match); + } + + //------------------------------------------------------------------------- + void OpticalNode::setLoss(double loss_) + { + m_loss_ = loss_; + } + + double OpticalNode::getLoss() const + { + return m_loss_; + } + + void OpticalNode::setVisitedNum(int visited_num_) + { + m_visited_num_ = visited_num_; + } + + int OpticalNode::getVisitedNum() const + { + return m_visited_num_; + } + //------------------------------------------------------------------------- + +} // namespace DSENT + + diff --git a/ext/dsent/model/optical_graph/OpticalNode.h b/ext/dsent/model/optical_graph/OpticalNode.h new file mode 100644 index 000000000..bb88d2da1 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalNode.h @@ -0,0 +1,92 @@ +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALNODE_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALNODE_H__ + +#include "model/OpticalModel.h" +#include "util/CommonType.h" + +namespace DSENT +{ + class OpticalNode; + + //TODO: Change to detector + typedef std::pair<OpticalNode*, double> DetectorEntry; + typedef std::vector<DetectorEntry> DetectorTable; + + class OpticalNode + { + public: + // The starting visited number flag of all optical nodes + static const int OPTICAL_NODE_INIT_VISITED_NUM; + + // The types of optical nodes that can exist + enum Type + { + WAVEGUIDE, + LASER, + MODULATOR, + FILTER, + DETECTOR + }; + + public: + OpticalNode(Type type_, const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_); + ~OpticalNode(); + + public: + // Get the type of optical node + Type getType() const; + // Return instance name + const String& getInstanceName() const; + // Get the downstream optical nodes + vector<OpticalNode*>* getDownstreamNodes() const; + // Connect the downstream optical node + void addDownstreamNode(OpticalNode* node_); + // Return the node's parent model + OpticalModel* getModel(); + const OpticalModel* getModel() const; + // Get wavelength groups + WavelengthGroup getWavelengths() const; + // Returns whether the node is expecting a set of wavelengths + bool isExpected(const WavelengthGroup& wavelengths_) const; + + // Trace wavelengths, find and put all found lasers, modulators, and detectors + //virtual void traceWavelengths(const WavelengthGroup& wavelengths_, OpticalNode* laser_, + // OpticalNode* modulator_, DetectorTable* detectors_, double current_loss_) const; + + //----------------------------------------------------------------- + // Node variables for wavelength tracing + //----------------------------------------------------------------- + // Loss incurred at this optical node + void setLoss(double loss_); + double getLoss() const; + // Visited number marker + void setVisitedNum(int visited_num_); + int getVisitedNum() const; + //----------------------------------------------------------------- + + + private: + // Disable copy constructor + OpticalNode(const OpticalNode& node_); + + private: + // The type of optical node + const Type m_type_; + // Name of this instance + String m_instance_name_; + // A pointer to the model that contains this node + OpticalModel* m_model_; + // Downstream optical node + vector<OpticalNode*>* m_downstream_nodes_; + // Path visited count (so that you don't have to clear it) + int m_visited_num_; + // The amount of loss incurred at this optical node + double m_loss_; + // The wavelengths this optical node is supposed to see + const WavelengthGroup m_wavelengths_; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALNODE_H__ + diff --git a/ext/dsent/model/optical_graph/OpticalReceiver.h b/ext/dsent/model/optical_graph/OpticalReceiver.h new file mode 100644 index 000000000..11c940522 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalReceiver.h @@ -0,0 +1,25 @@ +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALRECEIVER_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALRECEIVER_H__ + +#include "model/OpticalModel.h" +#include "util/CommonType.h" + +namespace DSENT +{ + // The job of an optical receiver interface is to provide a function to + // return a sensitivity (in Amps) + class OpticalReceiver + { + public: + OpticalReceiver(){}; + virtual ~OpticalReceiver(){}; + + public: + // Returns the sensitivity of the receiver given an extinction ratio + virtual double getSensitivity(double ER_dB_) const = 0; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALRECEIVER_H__ + diff --git a/ext/dsent/model/optical_graph/OpticalTransmitter.h b/ext/dsent/model/optical_graph/OpticalTransmitter.h new file mode 100644 index 000000000..235d88880 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalTransmitter.h @@ -0,0 +1,28 @@ +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALTRANSMITTER_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALTRANSMITTER_H__ + +#include "model/OpticalModel.h" +#include "util/CommonType.h" + +namespace DSENT +{ + // The job of a optical sender interface is to provide a function to + // allow the insertion loss and extinction ratio to be changed + class OpticalTransmitter + { + public: + OpticalTransmitter(){}; + virtual ~OpticalTransmitter(){}; + + public: + // Set the transmitter specifications, returns whether it is possible + // to build a modulator that met those specs + virtual bool setTransmitterSpec(double IL_dB_, double ER_dB_) = 0; + // Returns power of the transmitter at a given utilization + virtual double getPower(double util_) const = 0; + }; // class OpticalTransmitter + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALTRANSMITTER_H__ + diff --git a/ext/dsent/model/optical_graph/OpticalWaveguide.cc b/ext/dsent/model/optical_graph/OpticalWaveguide.cc new file mode 100644 index 000000000..7e35a18aa --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalWaveguide.cc @@ -0,0 +1,20 @@ + +#include "model/optical_graph/OpticalWaveguide.h" + +namespace DSENT +{ + OpticalWaveguide::OpticalWaveguide(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_) + : OpticalNode(OpticalNode::WAVEGUIDE, instance_name_, model_, wavelengths_) + { + + } + + OpticalWaveguide::~OpticalWaveguide() + { + + } + + +} // namespace DSENT + + diff --git a/ext/dsent/model/optical_graph/OpticalWaveguide.h b/ext/dsent/model/optical_graph/OpticalWaveguide.h new file mode 100644 index 000000000..6fd03bcf3 --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalWaveguide.h @@ -0,0 +1,27 @@ +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVEGUIDE_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVEGUIDE_H__ + +#include "model/optical_graph/OpticalNode.h" +#include "util/CommonType.h" + +namespace DSENT +{ + class OpticalWaveguide : public OpticalNode + { + public: + OpticalWaveguide(const String& instance_name_, OpticalModel* model_, const WavelengthGroup& wavelengths_); + ~OpticalWaveguide(); + + public: + // Nothing here... + + private: + // Disable copy constructor + OpticalWaveguide(const OpticalWaveguide& node_); + + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVEGUIDE_H__ + 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 + + diff --git a/ext/dsent/model/optical_graph/OpticalWavelength.h b/ext/dsent/model/optical_graph/OpticalWavelength.h new file mode 100644 index 000000000..6a5f31e9a --- /dev/null +++ b/ext/dsent/model/optical_graph/OpticalWavelength.h @@ -0,0 +1,57 @@ +#ifndef __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVELENGTH_H__ +#define __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVELENGTH_H__ + +#include "model/OpticalModel.h" +#include "util/CommonType.h" + +namespace DSENT +{ + // Optical datapath structure storing a detector table consisting of a + // detector, the loss to that detector, and the modulator driving + // the wavelength for that detector + struct OpticalDataPath + { + OpticalLaser* laser; + OpticalModulator* modulator; + vector<OpticalDetector*> detectors; + vector<double> losses; + + OpticalDataPath(OpticalLaser* laser_, OpticalModulator* modulator_, OpticalDetector* detector_, double loss_) + : laser(laser_), modulator(modulator_), detectors(1, detector_), losses(1, loss_) {} + }; + + class OpticalWavelength + { + // A data structure of a wavelength (or a group of wavelengths). This + // keeps track of all lasers sources, modulators, and detectors that + // the wavelength hits. + public: + OpticalWavelength(const String& instance_name_, const WavelengthGroup& wavelengths_); + ~OpticalWavelength(); + + public: + // Get tree name + const String& getInstanceName() const; + // Get wavelength groups + WavelengthGroup getWavelengths() const; + // Add a datapath for this wavelength + void addDataPath(OpticalLaser* laser_, OpticalModulator* modulator_, OpticalDetector* detector_, double loss_); + const vector<OpticalDataPath>* getDataPaths() const; + // Calculate required wavelength power to reach some number of detectors + // If number_detectors < the number of total detectors this wavelength hits then + // it simply returns the laser power required to reach the worst-case detectors + double getLaserPower(unsigned int number_detectors_) const; + + private: + // Name of the wavelength + const String m_instance_name_; + // Keeps track of the wavelengths + const WavelengthGroup m_wavelengths_; + // Keeps track of a table of laser, detector, modulator mappings + vector<OpticalDataPath>* m_data_paths_; + }; + +} // namespace DSENT + +#endif // __DSENT_MODEL_OPTICALGRAPH_OPTICALWAVEGUIDE_H__ + |