SWMRLink.cc revision 10447:a465576671d4
1#include "model/optical/SWMRLink.h"
2
3#include "model/PortInfo.h"
4#include "model/TransitionInfo.h"
5#include "model/EventInfo.h"
6#include "model/optical_graph/OpticalGraph.h"
7#include "model/optical_graph/OpticalWaveguide.h"
8#include "model/optical/RingModulator.h"
9#include "model/optical/RingFilter.h"
10#include "model/optical/RingDetector.h"
11#include "model/optical/LaserSource.h"
12#include "model/optical/ThrottledLaserSource.h"
13
14namespace DSENT
15{
16    SWMRLink::SWMRLink(const String& instance_name_, const TechModel* tech_model_)
17        : OpticalModel(instance_name_, tech_model_)
18    {
19        initParameters();
20        initProperties();
21    }
22
23    SWMRLink::~SWMRLink()
24    {}
25
26    void SWMRLink::initParameters()
27    {
28        addParameterName("NumberReaders");
29        addParameterName("NumberWavelengths");
30        addParameterName("DataRate");
31        addParameterName("LaserType");
32        addParameterName("MaxReaders");
33        addParameterName("MinReaders");
34        addParameterName("OptimizeLoss", "TRUE");
35        return;
36    }
37
38    void SWMRLink::initProperties()
39    {
40        addPropertyName("Length");
41		addPropertyName("OptUtil", 0.5);        // default to 50% utilization (a new word 50% of the time)
42        addPropertyName("ExtinctionRatio", 6);  // default properties
43        addPropertyName("InsertionLoss", 2);    // default properties
44        return;
45    }
46
47    void SWMRLink::constructModel()
48    {
49        // Get parameters
50        unsigned int number_wavelengths = getParameter("NumberWavelengths");
51        unsigned int number_readers = getParameter("NumberReaders");
52        unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt());
53        unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt());
54
55        // Create electrical ports
56        createInputPort("CK");
57        createInputPort("In", makeNetIndex(0, number_wavelengths-1));
58        for (unsigned int i = 0; i < number_readers; ++i)
59            createOutputPort("Out" + (String) i, makeNetIndex(0, number_wavelengths-1));
60
61        // Create Waveguides
62        // Temporarily assume its all on one waveguide
63        createWaveguide("LaserToMod", makeWavelengthGroup(0, number_wavelengths-1));
64        for (unsigned int i = 0; i <= number_readers; ++i)
65            createWaveguide("WaveguideSegment[" + (String) i + "]", makeWavelengthGroup(0, number_wavelengths-1));
66
67        // Add area results
68        addAreaResult(new Result("Photonic"));
69        createElectricalResults();
70        // Setup idle event
71        getEventInfo("Idle")->setStaticTransitionInfos();
72        // Create a waveguide area result
73        addAreaResult(new AtomicResult("Waveguide"));
74        getAreaResult("Photonic")->addSubResult(getAreaResult("Waveguide"), "Waveguide", 1.0);
75        // Add results
76        addNddPowerResult(new Result("Laser"));
77        // Add event result
78        createElectricalEventResult("BroadcastFlit");
79
80        for (unsigned int i = number_min_readers; i <= number_max_readers; ++i)
81            createElectricalEventResult("MulticastFlit" + (String) i);
82
83        buildLaser();
84        buildModulator();
85        buildDetectors();
86
87        return;
88    }
89
90    void SWMRLink::updateModel()
91    {
92        // Get parameters
93        double data_rate = getParameter("DataRate");
94        unsigned int number_readers = getParameter("NumberReaders");
95
96        // Get properties
97        double length = getProperty("Length");
98        const String& extinction_ratio = getProperty("ExtinctionRatio");
99        const String& insertion_loss = getProperty("InsertionLoss");
100		const double opt_util = getProperty("OptUtil");
101
102        // Calculate loss for each waveguide segment
103        double segment_length = (double) length / number_readers;
104        double segment_loss = getTechModel()->get("Waveguide->LossPerMeter").toDouble() * segment_length;
105        // Set loss of each waveguide segment
106        for (unsigned int i = 0; i < number_readers; ++i)
107            getWaveguide("WaveguideSegment[" + (String) i + "]")->setLoss(segment_loss);
108        // Calculate waveguide area
109        double waveguide_area = length * getTechModel()->get("Waveguide->Pitch").toDouble();
110        getAreaResult("Waveguide")->setValue(waveguide_area);
111
112        // Update the laser
113        Model* laser = getSubInstance("Laser");
114        laser->setProperty("LaserEventTime", 1.0 / data_rate);
115        laser->setProperty("OptUtil", opt_util);
116        laser->update();
117
118        // Update the modulator
119        Model* modulator = getSubInstance("Modulator");
120        modulator->setProperty("ExtinctionRatio", extinction_ratio);
121        modulator->setProperty("InsertionLoss", insertion_loss);
122        modulator->update();
123
124        // Update all receivers
125        for (unsigned int i = 0; i < number_readers; ++i)
126        {
127            Model* detector = getSubInstance("Detector_" + (String) i);
128            detector->update();
129        }
130
131        return;
132    }
133
134    void SWMRLink::propagateTransitionInfo()
135    {
136        // Get parameters
137        const String& laser_type = getParameter("LaserType");
138        unsigned int number_readers = getParameter("NumberReaders");
139
140        // Set transition info for the modulator
141        OpticalModel* modulator = (OpticalModel*) getSubInstance("Modulator");
142        propagatePortTransitionInfo(modulator, "In", "In");
143        modulator->use();
144
145        // Modulator out transition info
146        const TransitionInfo& mod_out_transitions = modulator->getOpticalOutputPort("Out")->getTransitionInfo();
147
148        // Set transition info for all receivers
149        for (unsigned int i = 0; i < number_readers; ++i)
150        {
151            OpticalModel* detector = (OpticalModel*) getSubInstance("Detector_" + (String) i);
152            detector->getOpticalInputPort("In")->setTransitionInfo(mod_out_transitions);
153            detector->use();
154
155            // Propagate output transition info to output
156            propagatePortTransitionInfo("Out" + (String) i, detector, "Out");
157        }
158
159        // Set enable signals for the laser, if applicable
160        if (laser_type == "Throttled")
161        {
162            // Figure out how many cycles the laser needs to be on
163            double cycles = getInputPort("In")->getTransitionInfo().getFrequencyMultiplier();
164
165            OpticalModel* laser = (OpticalModel*) getSubInstance("Laser");
166            laser->getInputPort("LaserEnable")->setTransitionInfo(TransitionInfo(0.0, 1.0, cycles - 1.0));
167            laser->use();
168        }
169        return;
170    }
171
172    void SWMRLink::buildLaser()
173    {
174        // Get parameters
175        unsigned int number_wavelengths = getParameter("NumberWavelengths");
176        unsigned int number_readers = getParameter("NumberReaders");
177        unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt());
178        unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt());
179        const String& laser_type = getParameter("LaserType");
180
181        // Create laser
182        OpticalModel* laser = NULL;
183        if (laser_type == "Throttled")
184            laser = new ThrottledLaserSource("Laser", getTechModel());
185        else if (laser_type == "Standard")
186            laser = new LaserSource("Laser", getTechModel());
187        else
188            ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown laser type '" + laser_type + "'!");
189
190        laser->setParameter("OutStart", 0);
191        laser->setParameter("OutEnd", number_wavelengths-1);
192        laser->setParameter("MaxDetectors", number_max_readers);
193        laser->setParameter("MinDetectors", number_min_readers);
194        laser->construct();
195
196        addSubInstances(laser, 1.0);
197        getAreaResult("Photonic")->addSubResult(laser->getAreaResult("Photonic"), "Laser", 1.0);
198        // Connect laser output port
199        opticalPortConnect(laser, "Out", "LaserToMod");
200
201        // Without laser gating, laser is pure NDD power
202        if (laser_type == "Standard")
203            getNddPowerResult("Laser")->addSubResult(laser->getNddPowerResult("Laser"), "Laser", 1.0);
204        // With laser power gating, laser is an event
205        else
206        {
207            // If laser is throttled, only pay for the amount needed to reach some number of readers
208            getEventResult("BroadcastFlit")->addSubResult(laser->getEventResult("Laser" + (String) number_max_readers), "Laser", 1.0);
209            for (unsigned int i = number_min_readers; i <= number_max_readers; ++i)
210                getEventResult("MulticastFlit" + (String) i)->addSubResult(laser->getEventResult("Laser" + (String) i), "Laser", 1.0);
211        }
212
213        return;
214    }
215
216    void SWMRLink::buildModulator()
217    {
218        // Get parameters
219        double data_rate = getParameter("DataRate");
220        const String& optimize_loss = getParameter("OptimizeLoss");
221        unsigned int number_wavelengths = getParameter("NumberWavelengths");
222        unsigned int number_readers = getParameter("NumberReaders");
223        unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt());
224        unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt());
225
226        // Create modulator
227        RingModulator* modulator = new RingModulator("Modulator", getTechModel());
228        modulator->setParameter("DataRate", data_rate);
229        modulator->setParameter("InStart", 0);
230        modulator->setParameter("InEnd", number_wavelengths-1);
231        modulator->setParameter("ModStart", 0);
232        modulator->setParameter("ModEnd", number_wavelengths-1);
233        modulator->setParameter("OptimizeLoss", optimize_loss);
234        modulator->construct();
235        addSubInstances(modulator, 1.0);
236        getAreaResult("Photonic")->addSubResult(modulator->getAreaResult("Photonic"), "Modulator", 1.0);
237        addElectricalSubResults(modulator, 1.0);
238
239        // Connect electrical port
240        portConnect(modulator, "In", "In");
241        // Connect modulator input, output port
242        opticalPortConnect(modulator, "In", "LaserToMod");
243        opticalPortConnect(modulator, "Out", "WaveguideSegment[0]");
244
245        // Add modulator energy event for all broadcast events
246        getEventResult("BroadcastFlit")->addSubResult(modulator->getEventResult("Modulate"), "Modulator", 1.0);
247        for (unsigned int i = number_min_readers; i <= number_max_readers; ++i)
248            getEventResult("MulticastFlit" + (String) i)->addSubResult(modulator->getEventResult("Modulate"), "Modulator", 1.0);
249
250        return;
251    }
252
253    void SWMRLink::buildDetectors()
254    {
255        // Get parameters
256        double data_rate = getParameter("DataRate");
257        unsigned int number_wavelengths = getParameter("NumberWavelengths");
258        unsigned int number_readers = getParameter("NumberReaders");
259        unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt());
260        unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt());
261
262        // Create a SWMR Configuration
263        for (unsigned int i = 0; i < number_readers; ++i)
264        {
265            String n = (String) i;
266
267            // Create resonant ring detector
268            RingDetector* detector = new RingDetector("Detector_" + n, getTechModel());
269            detector->setParameter("DataRate", data_rate);
270            detector->setParameter("InStart", 0);
271            detector->setParameter("InEnd", number_wavelengths-1);
272            detector->setParameter("DetStart", 0);
273            detector->setParameter("DetEnd", number_wavelengths-1);
274            detector->setParameter("DropAll", "FALSE");
275            detector->setParameter("Topology", RingDetector::INTEGRATINGSENSEAMP);
276            detector->construct();
277            addSubInstances(detector, 1.0);
278            getAreaResult("Photonic")->addSubResult(detector->getAreaResult("Photonic"), "Detector_" + n, 1.0);
279            addElectricalSubResults(detector, 1.0);
280
281            // connect to electrical port
282            portConnect(detector, "Out", "Out" + (String) i);
283            // connect optical input, output port
284            opticalPortConnect(detector, "In", "WaveguideSegment[" + (String) i + "]");
285            opticalPortConnect(detector, "Out", "WaveguideSegment[" + (String) (i + 1) + "]");
286        }
287
288        // Add an average receiver energy for all multicast events (and broadcast)
289        Result* broadcast_event = getEventResult("BroadcastFlit");
290        for (unsigned int i = 0; i < number_readers; ++i)
291        {
292            const String detector_name = "Detector_" + (String) i;
293            broadcast_event->addSubResult(getSubInstance(detector_name)->getEventResult("Receive"), detector_name, 1.0);
294        }
295        for (unsigned int i = number_min_readers; i <= number_max_readers; ++i)
296        {
297            Result* multicast_event = getEventResult("MulticastFlit" + (String) i);
298            for (unsigned int j = 0; j < number_readers; ++j)
299            {
300                const String detector_name = "Detector_" + (String) j;
301                multicast_event->addSubResult(getSubInstance(detector_name)->getEventResult("Receive"), detector_name, (double) i / number_readers);
302            }
303        }
304
305        return;
306    }
307
308} // namespace DSENT
309
310