summaryrefslogtreecommitdiff
path: root/ext/dsent/model/optical_graph
diff options
context:
space:
mode:
authorNilay Vaish <nilay@cs.wisc.edu>2014-10-11 15:02:23 -0500
committerNilay Vaish <nilay@cs.wisc.edu>2014-10-11 15:02:23 -0500
commite8ed7b1d1b5bef31e9874f679a5797c2e00d06f1 (patch)
tree421c9c50377aa664958685914f5504c4c019e21f /ext/dsent/model/optical_graph
parenta098fad174d8559037602b248b8e6f7f46bfebbb (diff)
downloadgem5-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')
-rw-r--r--ext/dsent/model/optical_graph/OpticalDetector.cc32
-rw-r--r--ext/dsent/model/optical_graph/OpticalDetector.h45
-rw-r--r--ext/dsent/model/optical_graph/OpticalFilter.cc65
-rw-r--r--ext/dsent/model/optical_graph/OpticalFilter.h48
-rw-r--r--ext/dsent/model/optical_graph/OpticalGraph.cc216
-rw-r--r--ext/dsent/model/optical_graph/OpticalGraph.h62
-rw-r--r--ext/dsent/model/optical_graph/OpticalLaser.cc31
-rw-r--r--ext/dsent/model/optical_graph/OpticalLaser.h32
-rw-r--r--ext/dsent/model/optical_graph/OpticalModulator.cc54
-rw-r--r--ext/dsent/model/optical_graph/OpticalModulator.h51
-rw-r--r--ext/dsent/model/optical_graph/OpticalNode.cc96
-rw-r--r--ext/dsent/model/optical_graph/OpticalNode.h92
-rw-r--r--ext/dsent/model/optical_graph/OpticalReceiver.h25
-rw-r--r--ext/dsent/model/optical_graph/OpticalTransmitter.h28
-rw-r--r--ext/dsent/model/optical_graph/OpticalWaveguide.cc20
-rw-r--r--ext/dsent/model/optical_graph/OpticalWaveguide.h27
-rw-r--r--ext/dsent/model/optical_graph/OpticalWavelength.cc129
-rw-r--r--ext/dsent/model/optical_graph/OpticalWavelength.h57
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__
+