SWMRLink.cc revision 10447:a465576671d4
17949SAli.Saidi@ARM.com#include "model/optical/SWMRLink.h" 210839Sandreas.sandberg@arm.com 37949SAli.Saidi@ARM.com#include "model/PortInfo.h" 47949SAli.Saidi@ARM.com#include "model/TransitionInfo.h" 57949SAli.Saidi@ARM.com#include "model/EventInfo.h" 67949SAli.Saidi@ARM.com#include "model/optical_graph/OpticalGraph.h" 77949SAli.Saidi@ARM.com#include "model/optical_graph/OpticalWaveguide.h" 87949SAli.Saidi@ARM.com#include "model/optical/RingModulator.h" 97949SAli.Saidi@ARM.com#include "model/optical/RingFilter.h" 107949SAli.Saidi@ARM.com#include "model/optical/RingDetector.h" 117949SAli.Saidi@ARM.com#include "model/optical/LaserSource.h" 127949SAli.Saidi@ARM.com#include "model/optical/ThrottledLaserSource.h" 137949SAli.Saidi@ARM.com 147949SAli.Saidi@ARM.comnamespace DSENT 157949SAli.Saidi@ARM.com{ 167949SAli.Saidi@ARM.com SWMRLink::SWMRLink(const String& instance_name_, const TechModel* tech_model_) 177949SAli.Saidi@ARM.com : OpticalModel(instance_name_, tech_model_) 187949SAli.Saidi@ARM.com { 197949SAli.Saidi@ARM.com initParameters(); 207949SAli.Saidi@ARM.com initProperties(); 217949SAli.Saidi@ARM.com } 227949SAli.Saidi@ARM.com 237949SAli.Saidi@ARM.com SWMRLink::~SWMRLink() 247949SAli.Saidi@ARM.com {} 257949SAli.Saidi@ARM.com 267949SAli.Saidi@ARM.com void SWMRLink::initParameters() 277949SAli.Saidi@ARM.com { 287949SAli.Saidi@ARM.com addParameterName("NumberReaders"); 297949SAli.Saidi@ARM.com addParameterName("NumberWavelengths"); 307949SAli.Saidi@ARM.com addParameterName("DataRate"); 317949SAli.Saidi@ARM.com addParameterName("LaserType"); 327949SAli.Saidi@ARM.com addParameterName("MaxReaders"); 337949SAli.Saidi@ARM.com addParameterName("MinReaders"); 347949SAli.Saidi@ARM.com addParameterName("OptimizeLoss", "TRUE"); 357949SAli.Saidi@ARM.com return; 367949SAli.Saidi@ARM.com } 377949SAli.Saidi@ARM.com 387949SAli.Saidi@ARM.com void SWMRLink::initProperties() 397949SAli.Saidi@ARM.com { 407949SAli.Saidi@ARM.com addPropertyName("Length"); 417949SAli.Saidi@ARM.com addPropertyName("OptUtil", 0.5); // default to 50% utilization (a new word 50% of the time) 427949SAli.Saidi@ARM.com addPropertyName("ExtinctionRatio", 6); // default properties 437949SAli.Saidi@ARM.com addPropertyName("InsertionLoss", 2); // default properties 447949SAli.Saidi@ARM.com return; 459330Schander.sudanthi@arm.com } 469330Schander.sudanthi@arm.com 477949SAli.Saidi@ARM.com void SWMRLink::constructModel() 487949SAli.Saidi@ARM.com { 497949SAli.Saidi@ARM.com // Get parameters 509330Schander.sudanthi@arm.com unsigned int number_wavelengths = getParameter("NumberWavelengths"); 518635Schris.emmons@arm.com unsigned int number_readers = getParameter("NumberReaders"); 527949SAli.Saidi@ARM.com unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt()); 537949SAli.Saidi@ARM.com unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt()); 547949SAli.Saidi@ARM.com 558229Snate@binkert.org // Create electrical ports 567949SAli.Saidi@ARM.com createInputPort("CK"); 577949SAli.Saidi@ARM.com createInputPort("In", makeNetIndex(0, number_wavelengths-1)); 589330Schander.sudanthi@arm.com for (unsigned int i = 0; i < number_readers; ++i) 599330Schander.sudanthi@arm.com createOutputPort("Out" + (String) i, makeNetIndex(0, number_wavelengths-1)); 609330Schander.sudanthi@arm.com 618635Schris.emmons@arm.com // Create Waveguides 629330Schander.sudanthi@arm.com // Temporarily assume its all on one waveguide 637949SAli.Saidi@ARM.com createWaveguide("LaserToMod", makeWavelengthGroup(0, number_wavelengths-1)); 647949SAli.Saidi@ARM.com for (unsigned int i = 0; i <= number_readers; ++i) 657949SAli.Saidi@ARM.com createWaveguide("WaveguideSegment[" + (String) i + "]", makeWavelengthGroup(0, number_wavelengths-1)); 667949SAli.Saidi@ARM.com 677949SAli.Saidi@ARM.com // Add area results 687949SAli.Saidi@ARM.com addAreaResult(new Result("Photonic")); 697949SAli.Saidi@ARM.com createElectricalResults(); 707949SAli.Saidi@ARM.com // Setup idle event 717949SAli.Saidi@ARM.com getEventInfo("Idle")->setStaticTransitionInfos(); 727949SAli.Saidi@ARM.com // Create a waveguide area result 737949SAli.Saidi@ARM.com addAreaResult(new AtomicResult("Waveguide")); 747949SAli.Saidi@ARM.com getAreaResult("Photonic")->addSubResult(getAreaResult("Waveguide"), "Waveguide", 1.0); 757949SAli.Saidi@ARM.com // Add results 767949SAli.Saidi@ARM.com addNddPowerResult(new Result("Laser")); 777949SAli.Saidi@ARM.com // Add event result 787949SAli.Saidi@ARM.com createElectricalEventResult("BroadcastFlit"); 797949SAli.Saidi@ARM.com 807949SAli.Saidi@ARM.com for (unsigned int i = number_min_readers; i <= number_max_readers; ++i) 817949SAli.Saidi@ARM.com createElectricalEventResult("MulticastFlit" + (String) i); 827949SAli.Saidi@ARM.com 837949SAli.Saidi@ARM.com buildLaser(); 847949SAli.Saidi@ARM.com buildModulator(); 857949SAli.Saidi@ARM.com buildDetectors(); 867949SAli.Saidi@ARM.com 877949SAli.Saidi@ARM.com return; 887949SAli.Saidi@ARM.com } 897949SAli.Saidi@ARM.com 907949SAli.Saidi@ARM.com void SWMRLink::updateModel() 917949SAli.Saidi@ARM.com { 927949SAli.Saidi@ARM.com // Get parameters 937949SAli.Saidi@ARM.com double data_rate = getParameter("DataRate"); 947949SAli.Saidi@ARM.com unsigned int number_readers = getParameter("NumberReaders"); 957949SAli.Saidi@ARM.com 967949SAli.Saidi@ARM.com // Get properties 977949SAli.Saidi@ARM.com double length = getProperty("Length"); 987949SAli.Saidi@ARM.com const String& extinction_ratio = getProperty("ExtinctionRatio"); 997949SAli.Saidi@ARM.com const String& insertion_loss = getProperty("InsertionLoss"); 1007949SAli.Saidi@ARM.com const double opt_util = getProperty("OptUtil"); 1017949SAli.Saidi@ARM.com 1027949SAli.Saidi@ARM.com // Calculate loss for each waveguide segment 1037949SAli.Saidi@ARM.com double segment_length = (double) length / number_readers; 1047949SAli.Saidi@ARM.com double segment_loss = getTechModel()->get("Waveguide->LossPerMeter").toDouble() * segment_length; 1057949SAli.Saidi@ARM.com // Set loss of each waveguide segment 1067949SAli.Saidi@ARM.com for (unsigned int i = 0; i < number_readers; ++i) 1077949SAli.Saidi@ARM.com getWaveguide("WaveguideSegment[" + (String) i + "]")->setLoss(segment_loss); 1087949SAli.Saidi@ARM.com // Calculate waveguide area 1097949SAli.Saidi@ARM.com double waveguide_area = length * getTechModel()->get("Waveguide->Pitch").toDouble(); 1107949SAli.Saidi@ARM.com getAreaResult("Waveguide")->setValue(waveguide_area); 1117949SAli.Saidi@ARM.com 1127949SAli.Saidi@ARM.com // Update the laser 1137949SAli.Saidi@ARM.com Model* laser = getSubInstance("Laser"); 1147949SAli.Saidi@ARM.com laser->setProperty("LaserEventTime", 1.0 / data_rate); 1157949SAli.Saidi@ARM.com laser->setProperty("OptUtil", opt_util); 1167949SAli.Saidi@ARM.com laser->update(); 1177949SAli.Saidi@ARM.com 1187949SAli.Saidi@ARM.com // Update the modulator 1197949SAli.Saidi@ARM.com Model* modulator = getSubInstance("Modulator"); 1207949SAli.Saidi@ARM.com modulator->setProperty("ExtinctionRatio", extinction_ratio); 1217949SAli.Saidi@ARM.com modulator->setProperty("InsertionLoss", insertion_loss); 1227949SAli.Saidi@ARM.com modulator->update(); 1237949SAli.Saidi@ARM.com 1247949SAli.Saidi@ARM.com // Update all receivers 1257949SAli.Saidi@ARM.com for (unsigned int i = 0; i < number_readers; ++i) 1267949SAli.Saidi@ARM.com { 1277949SAli.Saidi@ARM.com Model* detector = getSubInstance("Detector_" + (String) i); 1287949SAli.Saidi@ARM.com detector->update(); 1297949SAli.Saidi@ARM.com } 1307949SAli.Saidi@ARM.com 1317949SAli.Saidi@ARM.com return; 1327949SAli.Saidi@ARM.com } 1337949SAli.Saidi@ARM.com 1347949SAli.Saidi@ARM.com void SWMRLink::propagateTransitionInfo() 1357949SAli.Saidi@ARM.com { 1367949SAli.Saidi@ARM.com // Get parameters 1377949SAli.Saidi@ARM.com const String& laser_type = getParameter("LaserType"); 1387949SAli.Saidi@ARM.com unsigned int number_readers = getParameter("NumberReaders"); 1397949SAli.Saidi@ARM.com 1407949SAli.Saidi@ARM.com // Set transition info for the modulator 1417949SAli.Saidi@ARM.com OpticalModel* modulator = (OpticalModel*) getSubInstance("Modulator"); 1427949SAli.Saidi@ARM.com propagatePortTransitionInfo(modulator, "In", "In"); 1437949SAli.Saidi@ARM.com modulator->use(); 1447949SAli.Saidi@ARM.com 1457949SAli.Saidi@ARM.com // Modulator out transition info 1467949SAli.Saidi@ARM.com const TransitionInfo& mod_out_transitions = modulator->getOpticalOutputPort("Out")->getTransitionInfo(); 1477949SAli.Saidi@ARM.com 1487949SAli.Saidi@ARM.com // Set transition info for all receivers 1497949SAli.Saidi@ARM.com for (unsigned int i = 0; i < number_readers; ++i) 1507949SAli.Saidi@ARM.com { 1517949SAli.Saidi@ARM.com OpticalModel* detector = (OpticalModel*) getSubInstance("Detector_" + (String) i); 1527949SAli.Saidi@ARM.com detector->getOpticalInputPort("In")->setTransitionInfo(mod_out_transitions); 1537949SAli.Saidi@ARM.com detector->use(); 1547949SAli.Saidi@ARM.com 1557949SAli.Saidi@ARM.com // Propagate output transition info to output 1567949SAli.Saidi@ARM.com propagatePortTransitionInfo("Out" + (String) i, detector, "Out"); 1577949SAli.Saidi@ARM.com } 1587949SAli.Saidi@ARM.com 1597949SAli.Saidi@ARM.com // Set enable signals for the laser, if applicable 1607949SAli.Saidi@ARM.com if (laser_type == "Throttled") 1617949SAli.Saidi@ARM.com { 1627949SAli.Saidi@ARM.com // Figure out how many cycles the laser needs to be on 1637949SAli.Saidi@ARM.com double cycles = getInputPort("In")->getTransitionInfo().getFrequencyMultiplier(); 1647949SAli.Saidi@ARM.com 1657949SAli.Saidi@ARM.com OpticalModel* laser = (OpticalModel*) getSubInstance("Laser"); 1667949SAli.Saidi@ARM.com laser->getInputPort("LaserEnable")->setTransitionInfo(TransitionInfo(0.0, 1.0, cycles - 1.0)); 1677949SAli.Saidi@ARM.com laser->use(); 1687949SAli.Saidi@ARM.com } 1697949SAli.Saidi@ARM.com return; 1707949SAli.Saidi@ARM.com } 1717949SAli.Saidi@ARM.com 1727949SAli.Saidi@ARM.com void SWMRLink::buildLaser() 1737949SAli.Saidi@ARM.com { 1747949SAli.Saidi@ARM.com // Get parameters 1757949SAli.Saidi@ARM.com unsigned int number_wavelengths = getParameter("NumberWavelengths"); 1767949SAli.Saidi@ARM.com unsigned int number_readers = getParameter("NumberReaders"); 1777949SAli.Saidi@ARM.com unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt()); 1787949SAli.Saidi@ARM.com unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt()); 1797949SAli.Saidi@ARM.com const String& laser_type = getParameter("LaserType"); 1807949SAli.Saidi@ARM.com 1817949SAli.Saidi@ARM.com // Create laser 1827949SAli.Saidi@ARM.com OpticalModel* laser = NULL; 1837949SAli.Saidi@ARM.com if (laser_type == "Throttled") 1847949SAli.Saidi@ARM.com laser = new ThrottledLaserSource("Laser", getTechModel()); 1857949SAli.Saidi@ARM.com else if (laser_type == "Standard") 1867949SAli.Saidi@ARM.com laser = new LaserSource("Laser", getTechModel()); 1877949SAli.Saidi@ARM.com else 1887949SAli.Saidi@ARM.com ASSERT(false, "[Error] " + getInstanceName() + " -> Unknown laser type '" + laser_type + "'!"); 1897949SAli.Saidi@ARM.com 1907949SAli.Saidi@ARM.com laser->setParameter("OutStart", 0); 1917949SAli.Saidi@ARM.com laser->setParameter("OutEnd", number_wavelengths-1); 1927949SAli.Saidi@ARM.com laser->setParameter("MaxDetectors", number_max_readers); 1937949SAli.Saidi@ARM.com laser->setParameter("MinDetectors", number_min_readers); 1947949SAli.Saidi@ARM.com laser->construct(); 1957949SAli.Saidi@ARM.com 1967949SAli.Saidi@ARM.com addSubInstances(laser, 1.0); 1977949SAli.Saidi@ARM.com getAreaResult("Photonic")->addSubResult(laser->getAreaResult("Photonic"), "Laser", 1.0); 1987949SAli.Saidi@ARM.com // Connect laser output port 1997949SAli.Saidi@ARM.com opticalPortConnect(laser, "Out", "LaserToMod"); 2007949SAli.Saidi@ARM.com 2017949SAli.Saidi@ARM.com // Without laser gating, laser is pure NDD power 2027949SAli.Saidi@ARM.com if (laser_type == "Standard") 2037949SAli.Saidi@ARM.com getNddPowerResult("Laser")->addSubResult(laser->getNddPowerResult("Laser"), "Laser", 1.0); 2047949SAli.Saidi@ARM.com // With laser power gating, laser is an event 2057949SAli.Saidi@ARM.com else 2067949SAli.Saidi@ARM.com { 2077949SAli.Saidi@ARM.com // If laser is throttled, only pay for the amount needed to reach some number of readers 2087949SAli.Saidi@ARM.com getEventResult("BroadcastFlit")->addSubResult(laser->getEventResult("Laser" + (String) number_max_readers), "Laser", 1.0); 2097949SAli.Saidi@ARM.com for (unsigned int i = number_min_readers; i <= number_max_readers; ++i) 2107949SAli.Saidi@ARM.com getEventResult("MulticastFlit" + (String) i)->addSubResult(laser->getEventResult("Laser" + (String) i), "Laser", 1.0); 2117949SAli.Saidi@ARM.com } 2127949SAli.Saidi@ARM.com 2137949SAli.Saidi@ARM.com return; 2147949SAli.Saidi@ARM.com } 2157949SAli.Saidi@ARM.com 2167949SAli.Saidi@ARM.com void SWMRLink::buildModulator() 2177949SAli.Saidi@ARM.com { 2187949SAli.Saidi@ARM.com // Get parameters 2197949SAli.Saidi@ARM.com double data_rate = getParameter("DataRate"); 2207949SAli.Saidi@ARM.com const String& optimize_loss = getParameter("OptimizeLoss"); 2217949SAli.Saidi@ARM.com unsigned int number_wavelengths = getParameter("NumberWavelengths"); 2227949SAli.Saidi@ARM.com unsigned int number_readers = getParameter("NumberReaders"); 2237949SAli.Saidi@ARM.com unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt()); 2247949SAli.Saidi@ARM.com unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt()); 2257949SAli.Saidi@ARM.com 2267949SAli.Saidi@ARM.com // Create modulator 2277949SAli.Saidi@ARM.com RingModulator* modulator = new RingModulator("Modulator", getTechModel()); 2287949SAli.Saidi@ARM.com modulator->setParameter("DataRate", data_rate); 2297949SAli.Saidi@ARM.com modulator->setParameter("InStart", 0); 2307949SAli.Saidi@ARM.com modulator->setParameter("InEnd", number_wavelengths-1); 2317949SAli.Saidi@ARM.com modulator->setParameter("ModStart", 0); 2327949SAli.Saidi@ARM.com modulator->setParameter("ModEnd", number_wavelengths-1); 2337949SAli.Saidi@ARM.com modulator->setParameter("OptimizeLoss", optimize_loss); 2347949SAli.Saidi@ARM.com modulator->construct(); 2357949SAli.Saidi@ARM.com addSubInstances(modulator, 1.0); 2367949SAli.Saidi@ARM.com getAreaResult("Photonic")->addSubResult(modulator->getAreaResult("Photonic"), "Modulator", 1.0); 2377949SAli.Saidi@ARM.com addElectricalSubResults(modulator, 1.0); 2387949SAli.Saidi@ARM.com 2397949SAli.Saidi@ARM.com // Connect electrical port 2407949SAli.Saidi@ARM.com portConnect(modulator, "In", "In"); 2417949SAli.Saidi@ARM.com // Connect modulator input, output port 2427949SAli.Saidi@ARM.com opticalPortConnect(modulator, "In", "LaserToMod"); 2437949SAli.Saidi@ARM.com opticalPortConnect(modulator, "Out", "WaveguideSegment[0]"); 2447949SAli.Saidi@ARM.com 2457949SAli.Saidi@ARM.com // Add modulator energy event for all broadcast events 2467949SAli.Saidi@ARM.com getEventResult("BroadcastFlit")->addSubResult(modulator->getEventResult("Modulate"), "Modulator", 1.0); 2477949SAli.Saidi@ARM.com for (unsigned int i = number_min_readers; i <= number_max_readers; ++i) 2487949SAli.Saidi@ARM.com getEventResult("MulticastFlit" + (String) i)->addSubResult(modulator->getEventResult("Modulate"), "Modulator", 1.0); 2497949SAli.Saidi@ARM.com 2507949SAli.Saidi@ARM.com return; 2517949SAli.Saidi@ARM.com } 2527949SAli.Saidi@ARM.com 2537949SAli.Saidi@ARM.com void SWMRLink::buildDetectors() 2547949SAli.Saidi@ARM.com { 2557949SAli.Saidi@ARM.com // Get parameters 2567949SAli.Saidi@ARM.com double data_rate = getParameter("DataRate"); 2577949SAli.Saidi@ARM.com unsigned int number_wavelengths = getParameter("NumberWavelengths"); 2587949SAli.Saidi@ARM.com unsigned int number_readers = getParameter("NumberReaders"); 2597949SAli.Saidi@ARM.com unsigned int number_max_readers = std::min(number_readers, getParameter("MaxReaders").toUInt()); 2607949SAli.Saidi@ARM.com unsigned int number_min_readers = std::min(number_max_readers, getParameter("MinReaders").toUInt()); 2617949SAli.Saidi@ARM.com 2627949SAli.Saidi@ARM.com // Create a SWMR Configuration 2637949SAli.Saidi@ARM.com for (unsigned int i = 0; i < number_readers; ++i) 2647949SAli.Saidi@ARM.com { 2657949SAli.Saidi@ARM.com String n = (String) i; 2667949SAli.Saidi@ARM.com 2677949SAli.Saidi@ARM.com // Create resonant ring detector 2687949SAli.Saidi@ARM.com RingDetector* detector = new RingDetector("Detector_" + n, getTechModel()); 2697949SAli.Saidi@ARM.com detector->setParameter("DataRate", data_rate); 2707949SAli.Saidi@ARM.com detector->setParameter("InStart", 0); 2717949SAli.Saidi@ARM.com detector->setParameter("InEnd", number_wavelengths-1); 2727949SAli.Saidi@ARM.com detector->setParameter("DetStart", 0); 2737949SAli.Saidi@ARM.com detector->setParameter("DetEnd", number_wavelengths-1); 2747949SAli.Saidi@ARM.com detector->setParameter("DropAll", "FALSE"); 2757949SAli.Saidi@ARM.com detector->setParameter("Topology", RingDetector::INTEGRATINGSENSEAMP); 2767949SAli.Saidi@ARM.com detector->construct(); 2777949SAli.Saidi@ARM.com addSubInstances(detector, 1.0); 2787949SAli.Saidi@ARM.com getAreaResult("Photonic")->addSubResult(detector->getAreaResult("Photonic"), "Detector_" + n, 1.0); 2797949SAli.Saidi@ARM.com addElectricalSubResults(detector, 1.0); 2807949SAli.Saidi@ARM.com 2817949SAli.Saidi@ARM.com // connect to electrical port 2827949SAli.Saidi@ARM.com portConnect(detector, "Out", "Out" + (String) i); 2837949SAli.Saidi@ARM.com // connect optical input, output port 2847949SAli.Saidi@ARM.com opticalPortConnect(detector, "In", "WaveguideSegment[" + (String) i + "]"); 2857949SAli.Saidi@ARM.com opticalPortConnect(detector, "Out", "WaveguideSegment[" + (String) (i + 1) + "]"); 2867949SAli.Saidi@ARM.com } 2877949SAli.Saidi@ARM.com 2887949SAli.Saidi@ARM.com // Add an average receiver energy for all multicast events (and broadcast) 2897949SAli.Saidi@ARM.com Result* broadcast_event = getEventResult("BroadcastFlit"); 2907949SAli.Saidi@ARM.com for (unsigned int i = 0; i < number_readers; ++i) 2917949SAli.Saidi@ARM.com { 2927949SAli.Saidi@ARM.com const String detector_name = "Detector_" + (String) i; 2937949SAli.Saidi@ARM.com broadcast_event->addSubResult(getSubInstance(detector_name)->getEventResult("Receive"), detector_name, 1.0); 2947949SAli.Saidi@ARM.com } 2957949SAli.Saidi@ARM.com for (unsigned int i = number_min_readers; i <= number_max_readers; ++i) 2967949SAli.Saidi@ARM.com { 2977949SAli.Saidi@ARM.com Result* multicast_event = getEventResult("MulticastFlit" + (String) i); 2987949SAli.Saidi@ARM.com for (unsigned int j = 0; j < number_readers; ++j) 2997949SAli.Saidi@ARM.com { 3007949SAli.Saidi@ARM.com const String detector_name = "Detector_" + (String) j; 3017949SAli.Saidi@ARM.com multicast_event->addSubResult(getSubInstance(detector_name)->getEventResult("Receive"), detector_name, (double) i / number_readers); 3027949SAli.Saidi@ARM.com } 3037949SAli.Saidi@ARM.com } 3047949SAli.Saidi@ARM.com 3057949SAli.Saidi@ARM.com return; 3067949SAli.Saidi@ARM.com } 30710839Sandreas.sandberg@arm.com 30810839Sandreas.sandberg@arm.com} // namespace DSENT 3097949SAli.Saidi@ARM.com 31011168Sandreas.hansson@arm.com