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