1 /* Copyright (c) 2012 Massachusetts Institute of Technology
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 #include "model/optical/SWMRLink.h"
24 #include "model/PortInfo.h"
25 #include "model/TransitionInfo.h"
26 #include "model/EventInfo.h"
27 #include "model/optical_graph/OpticalGraph.h"
28 #include "model/optical_graph/OpticalWaveguide.h"
29 #include "model/optical/RingModulator.h"
30 #include "model/optical/RingFilter.h"
31 #include "model/optical/RingDetector.h"
32 #include "model/optical/LaserSource.h"
33 #include "model/optical/ThrottledLaserSource.h"
37 SWMRLink::SWMRLink(const String
& instance_name_
, const TechModel
* tech_model_
)
38 : OpticalModel(instance_name_
, tech_model_
)
47 void SWMRLink::initParameters()
49 addParameterName("NumberReaders");
50 addParameterName("NumberWavelengths");
51 addParameterName("DataRate");
52 addParameterName("LaserType");
53 addParameterName("MaxReaders");
54 addParameterName("MinReaders");
55 addParameterName("OptimizeLoss", "TRUE");
59 void SWMRLink::initProperties()
61 addPropertyName("Length");
62 addPropertyName("OptUtil", 0.5); // default to 50% utilization (a new word 50% of the time)
63 addPropertyName("ExtinctionRatio", 6); // default properties
64 addPropertyName("InsertionLoss", 2); // default properties
68 void SWMRLink::constructModel()
71 unsigned int number_wavelengths
= getParameter("NumberWavelengths");
72 unsigned int number_readers
= getParameter("NumberReaders");
73 unsigned int number_max_readers
= std::min(number_readers
, getParameter("MaxReaders").toUInt());
74 unsigned int number_min_readers
= std::min(number_max_readers
, getParameter("MinReaders").toUInt());
76 // Create electrical ports
77 createInputPort("CK");
78 createInputPort("In", makeNetIndex(0, number_wavelengths
-1));
79 for (unsigned int i
= 0; i
< number_readers
; ++i
)
80 createOutputPort("Out" + (String
) i
, makeNetIndex(0, number_wavelengths
-1));
83 // Temporarily assume its all on one waveguide
84 createWaveguide("LaserToMod", makeWavelengthGroup(0, number_wavelengths
-1));
85 for (unsigned int i
= 0; i
<= number_readers
; ++i
)
86 createWaveguide("WaveguideSegment[" + (String
) i
+ "]", makeWavelengthGroup(0, number_wavelengths
-1));
89 addAreaResult(new Result("Photonic"));
90 createElectricalResults();
92 getEventInfo("Idle")->setStaticTransitionInfos();
93 // Create a waveguide area result
94 addAreaResult(new AtomicResult("Waveguide"));
95 getAreaResult("Photonic")->addSubResult(getAreaResult("Waveguide"), "Waveguide", 1.0);
97 addNddPowerResult(new Result("Laser"));
99 createElectricalEventResult("BroadcastFlit");
101 for (unsigned int i
= number_min_readers
; i
<= number_max_readers
; ++i
)
102 createElectricalEventResult("MulticastFlit" + (String
) i
);
111 void SWMRLink::updateModel()
114 double data_rate
= getParameter("DataRate");
115 unsigned int number_readers
= getParameter("NumberReaders");
118 double length
= getProperty("Length");
119 const String
& extinction_ratio
= getProperty("ExtinctionRatio");
120 const String
& insertion_loss
= getProperty("InsertionLoss");
121 const double opt_util
= getProperty("OptUtil");
123 // Calculate loss for each waveguide segment
124 double segment_length
= (double) length
/ number_readers
;
125 double segment_loss
= getTechModel()->get("Waveguide->LossPerMeter").toDouble() * segment_length
;
126 // Set loss of each waveguide segment
127 for (unsigned int i
= 0; i
< number_readers
; ++i
)
128 getWaveguide("WaveguideSegment[" + (String
) i
+ "]")->setLoss(segment_loss
);
129 // Calculate waveguide area
130 double waveguide_area
= length
* getTechModel()->get("Waveguide->Pitch").toDouble();
131 getAreaResult("Waveguide")->setValue(waveguide_area
);
134 Model
* laser
= getSubInstance("Laser");
135 laser
->setProperty("LaserEventTime", 1.0 / data_rate
);
136 laser
->setProperty("OptUtil", opt_util
);
139 // Update the modulator
140 Model
* modulator
= getSubInstance("Modulator");
141 modulator
->setProperty("ExtinctionRatio", extinction_ratio
);
142 modulator
->setProperty("InsertionLoss", insertion_loss
);
145 // Update all receivers
146 for (unsigned int i
= 0; i
< number_readers
; ++i
)
148 Model
* detector
= getSubInstance("Detector_" + (String
) i
);
155 void SWMRLink::propagateTransitionInfo()
158 const String
& laser_type
= getParameter("LaserType");
159 unsigned int number_readers
= getParameter("NumberReaders");
161 // Set transition info for the modulator
162 OpticalModel
* modulator
= (OpticalModel
*) getSubInstance("Modulator");
163 propagatePortTransitionInfo(modulator
, "In", "In");
166 // Modulator out transition info
167 const TransitionInfo
& mod_out_transitions
= modulator
->getOpticalOutputPort("Out")->getTransitionInfo();
169 // Set transition info for all receivers
170 for (unsigned int i
= 0; i
< number_readers
; ++i
)
172 OpticalModel
* detector
= (OpticalModel
*) getSubInstance("Detector_" + (String
) i
);
173 detector
->getOpticalInputPort("In")->setTransitionInfo(mod_out_transitions
);
176 // Propagate output transition info to output
177 propagatePortTransitionInfo("Out" + (String
) i
, detector
, "Out");
180 // Set enable signals for the laser, if applicable
181 if (laser_type
== "Throttled")
183 // Figure out how many cycles the laser needs to be on
184 double cycles
= getInputPort("In")->getTransitionInfo().getFrequencyMultiplier();
186 OpticalModel
* laser
= (OpticalModel
*) getSubInstance("Laser");
187 laser
->getInputPort("LaserEnable")->setTransitionInfo(TransitionInfo(0.0, 1.0, cycles
- 1.0));
193 void SWMRLink::buildLaser()
196 unsigned int number_wavelengths
= getParameter("NumberWavelengths");
197 unsigned int number_readers
= getParameter("NumberReaders");
198 unsigned int number_max_readers
= std::min(number_readers
, getParameter("MaxReaders").toUInt());
199 unsigned int number_min_readers
= std::min(number_max_readers
, getParameter("MinReaders").toUInt());
200 const String
& laser_type
= getParameter("LaserType");
203 OpticalModel
* laser
= NULL
;
204 if (laser_type
== "Throttled")
205 laser
= new ThrottledLaserSource("Laser", getTechModel());
206 else if (laser_type
== "Standard")
207 laser
= new LaserSource("Laser", getTechModel());
209 ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown laser type '" + laser_type
+ "'!");
211 laser
->setParameter("OutStart", 0);
212 laser
->setParameter("OutEnd", number_wavelengths
-1);
213 laser
->setParameter("MaxDetectors", number_max_readers
);
214 laser
->setParameter("MinDetectors", number_min_readers
);
217 addSubInstances(laser
, 1.0);
218 getAreaResult("Photonic")->addSubResult(laser
->getAreaResult("Photonic"), "Laser", 1.0);
219 // Connect laser output port
220 opticalPortConnect(laser
, "Out", "LaserToMod");
222 // Without laser gating, laser is pure NDD power
223 if (laser_type
== "Standard")
224 getNddPowerResult("Laser")->addSubResult(laser
->getNddPowerResult("Laser"), "Laser", 1.0);
225 // With laser power gating, laser is an event
228 // If laser is throttled, only pay for the amount needed to reach some number of readers
229 getEventResult("BroadcastFlit")->addSubResult(laser
->getEventResult("Laser" + (String
) number_max_readers
), "Laser", 1.0);
230 for (unsigned int i
= number_min_readers
; i
<= number_max_readers
; ++i
)
231 getEventResult("MulticastFlit" + (String
) i
)->addSubResult(laser
->getEventResult("Laser" + (String
) i
), "Laser", 1.0);
237 void SWMRLink::buildModulator()
240 double data_rate
= getParameter("DataRate");
241 const String
& optimize_loss
= getParameter("OptimizeLoss");
242 unsigned int number_wavelengths
= getParameter("NumberWavelengths");
243 unsigned int number_readers
= getParameter("NumberReaders");
244 unsigned int number_max_readers
= std::min(number_readers
, getParameter("MaxReaders").toUInt());
245 unsigned int number_min_readers
= std::min(number_max_readers
, getParameter("MinReaders").toUInt());
248 RingModulator
* modulator
= new RingModulator("Modulator", getTechModel());
249 modulator
->setParameter("DataRate", data_rate
);
250 modulator
->setParameter("InStart", 0);
251 modulator
->setParameter("InEnd", number_wavelengths
-1);
252 modulator
->setParameter("ModStart", 0);
253 modulator
->setParameter("ModEnd", number_wavelengths
-1);
254 modulator
->setParameter("OptimizeLoss", optimize_loss
);
255 modulator
->construct();
256 addSubInstances(modulator
, 1.0);
257 getAreaResult("Photonic")->addSubResult(modulator
->getAreaResult("Photonic"), "Modulator", 1.0);
258 addElectricalSubResults(modulator
, 1.0);
260 // Connect electrical port
261 portConnect(modulator
, "In", "In");
262 // Connect modulator input, output port
263 opticalPortConnect(modulator
, "In", "LaserToMod");
264 opticalPortConnect(modulator
, "Out", "WaveguideSegment[0]");
266 // Add modulator energy event for all broadcast events
267 getEventResult("BroadcastFlit")->addSubResult(modulator
->getEventResult("Modulate"), "Modulator", 1.0);
268 for (unsigned int i
= number_min_readers
; i
<= number_max_readers
; ++i
)
269 getEventResult("MulticastFlit" + (String
) i
)->addSubResult(modulator
->getEventResult("Modulate"), "Modulator", 1.0);
274 void SWMRLink::buildDetectors()
277 double data_rate
= getParameter("DataRate");
278 unsigned int number_wavelengths
= getParameter("NumberWavelengths");
279 unsigned int number_readers
= getParameter("NumberReaders");
280 unsigned int number_max_readers
= std::min(number_readers
, getParameter("MaxReaders").toUInt());
281 unsigned int number_min_readers
= std::min(number_max_readers
, getParameter("MinReaders").toUInt());
283 // Create a SWMR Configuration
284 for (unsigned int i
= 0; i
< number_readers
; ++i
)
286 String n
= (String
) i
;
288 // Create resonant ring detector
289 RingDetector
* detector
= new RingDetector("Detector_" + n
, getTechModel());
290 detector
->setParameter("DataRate", data_rate
);
291 detector
->setParameter("InStart", 0);
292 detector
->setParameter("InEnd", number_wavelengths
-1);
293 detector
->setParameter("DetStart", 0);
294 detector
->setParameter("DetEnd", number_wavelengths
-1);
295 detector
->setParameter("DropAll", "FALSE");
296 detector
->setParameter("Topology", RingDetector::INTEGRATINGSENSEAMP
);
297 detector
->construct();
298 addSubInstances(detector
, 1.0);
299 getAreaResult("Photonic")->addSubResult(detector
->getAreaResult("Photonic"), "Detector_" + n
, 1.0);
300 addElectricalSubResults(detector
, 1.0);
302 // connect to electrical port
303 portConnect(detector
, "Out", "Out" + (String
) i
);
304 // connect optical input, output port
305 opticalPortConnect(detector
, "In", "WaveguideSegment[" + (String
) i
+ "]");
306 opticalPortConnect(detector
, "Out", "WaveguideSegment[" + (String
) (i
+ 1) + "]");
309 // Add an average receiver energy for all multicast events (and broadcast)
310 Result
* broadcast_event
= getEventResult("BroadcastFlit");
311 for (unsigned int i
= 0; i
< number_readers
; ++i
)
313 const String detector_name
= "Detector_" + (String
) i
;
314 broadcast_event
->addSubResult(getSubInstance(detector_name
)->getEventResult("Receive"), detector_name
, 1.0);
316 for (unsigned int i
= number_min_readers
; i
<= number_max_readers
; ++i
)
318 Result
* multicast_event
= getEventResult("MulticastFlit" + (String
) i
);
319 for (unsigned int j
= 0; j
< number_readers
; ++j
)
321 const String detector_name
= "Detector_" + (String
) j
;
322 multicast_event
->addSubResult(getSubInstance(detector_name
)->getEventResult("Receive"), detector_name
, (double) i
/ number_readers
);