Deleted Added
sdiff udiff text old ( 10447:a465576671d4 ) new ( 10448:bc1a3b7ab5ef )
full compact
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