1/* Copyright (c) 2012 Massachusetts Institute of Technology 2 * 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: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 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 19 * THE SOFTWARE. 20 */ 21 22#include "model/network/PhotonicClos.h" 23 24#include <cmath> 25 26#include "model/ModelGen.h" 27#include "model/timing_graph/ElectricalTimingTree.h" 28#include "model/timing_graph/ElectricalNet.h" 29 30namespace DSENT 31{ 32 using std::sqrt; 33 34 PhotonicClos::PhotonicClos(const String& instance_name_, const TechModel* tech_model_) 35 : ElectricalModel(instance_name_, tech_model_) 36 { 37 initParameters(); 38 initProperties(); 39 } 40 41 PhotonicClos::~PhotonicClos() 42 {} 43 44 void PhotonicClos::initParameters() 45 { 46 // Clock Frequency 47 addParameterName("Frequency"); 48 // Physical Parameters 49 addParameterName("NumberInputSites"); 50 addParameterName("NumberOutputSites"); 51 addParameterName("NumberBitsPerFlit"); 52 // Number of each type of routers 53 addParameterName("NumberIngressRouters"); 54 addParameterName("NumberMiddleRouters"); 55 addParameterName("NumberEgressRouters"); 56 // Optical link parameters 57 addParameterName("SWSR->LinkDataRate"); 58 addParameterName("SWSR->LaserType"); 59 addParameterName("SWSR->RingTuningMethod"); 60 // Router parameters 61 addParameterName("Router->NumberVirtualNetworks"); 62 addParameterName("Router->NumberVirtualChannelsPerVirtualNetwork"); 63 addParameterName("Router->NumberBuffersPerVirtualChannel"); 64 addParameterName("Router->InputPort->BufferModel"); 65 addParameterName("Router->CrossbarModel"); 66 addParameterName("Router->SwitchAllocator->ArbiterModel"); 67 addParameterName("Router->ClockTreeModel"); 68 addParameterName("Router->ClockTree->NumberLevels"); 69 addParameterName("Router->ClockTree->WireLayer"); 70 addParameterName("Router->ClockTree->WireWidthMultiplier"); 71 addParameterName("Router->ClockTree->WireSpacingMultiplier", 3.0); 72 // Link parameters 73 addParameterName("Link->WireLayer"); 74 addParameterName("Link->WireWidthMultiplier"); 75 addParameterName("Link->WireSpacingMultiplier"); 76 return; 77 } 78 79 void PhotonicClos::initProperties() 80 { 81 addPropertyName("InputSitePitch"); 82 addPropertyName("OutputSitePitch"); 83 addPropertyName("SWSR->OptUtil", 1.0); 84 return; 85 } 86 87 PhotonicClos* PhotonicClos::clone() const 88 { 89 // TODO 90 return NULL; 91 } 92 93 void PhotonicClos::constructModel() 94 { 95 // Get input parameters 96 double clock_freq = getParameter("Frequency"); 97 unsigned int number_input_sites = getParameter("NumberInputSites").toUInt(); 98 unsigned int number_output_sites = getParameter("NumberOutputSites").toUInt(); 99 unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); 100 unsigned int number_ingress_routers = getParameter("NumberIngressRouters").toUInt(); 101 unsigned int number_middle_routers = getParameter("NumberMiddleRouters").toUInt(); 102 unsigned int number_egress_routers = getParameter("NumberEgressRouters").toUInt(); 103 104 ASSERT(clock_freq > 0, "[Error] " + getInstanceName() + 105 " -> Clock frequency must be > 0!"); 106 ASSERT(number_input_sites > 0, "[Error] " + getInstanceName() + 107 " -> Number of input sites must be > 0!"); 108 ASSERT(number_output_sites > 0, "[Error] " + getInstanceName() + 109 " -> Number of output sites must be > 0!"); 110 ASSERT(number_bits_per_flit > 0, "[Error] " + getInstanceName() + 111 " -> Number of bits per flit must be > 0!"); 112 ASSERT(number_ingress_routers > 0, "[Error] " + getInstanceName() + 113 " -> Number of ingress routers must be > 0!"); 114 ASSERT(number_middle_routers > 0, "[Error] " + getInstanceName() + 115 " -> Number of middle routers must be > 0!"); 116 ASSERT(number_egress_routers > 0, "[Error] " + getInstanceName() + 117 " -> Number of egress routers must be > 0!"); 118 119 // Get input parameters that will be forwarded to the sub instances 120 const String& swsr_link_data_rate = getParameter("SWSR->LinkDataRate"); 121 const String& swsr_laser_type = getParameter("SWSR->LaserType"); 122 const String& swsr_ring_tuning_method = getParameter("SWSR->RingTuningMethod"); 123 const String& router_number_vns = getParameter("Router->NumberVirtualNetworks"); 124 const String& router_number_vcs_per_vn = getParameter("Router->NumberVirtualChannelsPerVirtualNetwork"); 125 const String& router_number_bufs_per_vc = getParameter("Router->NumberBuffersPerVirtualChannel"); 126 const String& router_buffer_model = getParameter("Router->InputPort->BufferModel"); 127 const String& router_crossbar_model = getParameter("Router->CrossbarModel"); 128 const String& link_wire_layer = getParameter("Link->WireLayer"); 129 const String& link_wire_width_multiplier = getParameter("Link->WireWidthMultiplier"); 130 const String& link_wire_spacing_multiplier = getParameter("Link->WireSpacingMultiplier"); 131 132 // Calculate properties from input parameters 133 unsigned int ingress_router_number_input_ports = number_input_sites / number_ingress_routers; 134 unsigned int ingress_router_number_output_ports = number_middle_routers; 135 unsigned int middle_router_number_input_ports = number_ingress_routers; 136 unsigned int middle_router_number_output_ports = number_egress_routers; 137 unsigned int egress_router_number_input_ports = number_middle_routers; 138 unsigned int egress_router_number_output_ports = number_output_sites / number_egress_routers; 139 unsigned int number_input_to_ingress_links = number_input_sites; 140 unsigned int number_ingress_to_middle_links = number_ingress_routers * number_middle_routers; 141 unsigned int number_middle_to_egress_links = number_middle_routers * number_egress_routers; 142 unsigned int number_egress_to_output_links = number_output_sites; 143 144 getGenProperties()->set("NumberInputSitesPerIngressRouter", ingress_router_number_input_ports); 145 getGenProperties()->set("NumberOutputSitesPerEgressRouter", egress_router_number_output_ports); 146 getGenProperties()->set("IngressRouter->NumberInputPorts", ingress_router_number_input_ports); 147 getGenProperties()->set("IngressRouter->NumberOutputPorts", ingress_router_number_output_ports); 148 getGenProperties()->set("MiddleRouter->NumberInputPorts", middle_router_number_input_ports); 149 getGenProperties()->set("MiddleRouter->NumberOutputPorts", middle_router_number_output_ports); 150 getGenProperties()->set("EgressRouter->NumberInputPorts", egress_router_number_input_ports); 151 getGenProperties()->set("EgressRouter->NumberOutputPorts", egress_router_number_output_ports); 152 153 // Create ports 154 createInputPort("CK"); 155 156 // Init ingress router 157 ElectricalModel* ingress_router = (ElectricalModel*)ModelGen::createModel("Router", "IngressRouter", getTechModel()); 158 ingress_router->setParameter("NumberInputPorts", ingress_router_number_input_ports); 159 ingress_router->setParameter("NumberOutputPorts", ingress_router_number_output_ports); 160 ingress_router->setParameter("NumberVirtualNetworks", router_number_vns); 161 ingress_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn); 162 ingress_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc); 163 ingress_router->setParameter("NumberBitsPerFlit", number_bits_per_flit); 164 ingress_router->setParameter("InputPort->BufferModel", router_buffer_model); 165 ingress_router->setParameter("CrossbarModel", router_crossbar_model); 166 ingress_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel")); 167 ingress_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel")); 168 ingress_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels")); 169 ingress_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer")); 170 ingress_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier")); 171 ingress_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier")); 172 ingress_router->construct(); 173 // Init middle routers 174 ElectricalModel* middle_router = (ElectricalModel*)ModelGen::createModel("Router", "MiddleRouter", getTechModel()); 175 middle_router->setParameter("NumberInputPorts", middle_router_number_input_ports); 176 middle_router->setParameter("NumberOutputPorts", middle_router_number_output_ports); 177 middle_router->setParameter("NumberVirtualNetworks", router_number_vns); 178 middle_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn); 179 middle_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc); 180 middle_router->setParameter("NumberBitsPerFlit", number_bits_per_flit); 181 middle_router->setParameter("InputPort->BufferModel", router_buffer_model); 182 middle_router->setParameter("CrossbarModel", router_crossbar_model); 183 middle_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel")); 184 middle_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel")); 185 middle_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels")); 186 middle_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer")); 187 middle_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier")); 188 middle_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier")); 189 middle_router->construct(); 190 // Init egress routers 191 ElectricalModel* egress_router = (ElectricalModel*)ModelGen::createModel("Router", "EgressRouter", getTechModel()); 192 egress_router->setParameter("NumberInputPorts", egress_router_number_input_ports); 193 egress_router->setParameter("NumberOutputPorts", egress_router_number_output_ports); 194 egress_router->setParameter("NumberVirtualNetworks", router_number_vns); 195 egress_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn); 196 egress_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc); 197 egress_router->setParameter("NumberBitsPerFlit", number_bits_per_flit); 198 egress_router->setParameter("InputPort->BufferModel", router_buffer_model); 199 egress_router->setParameter("CrossbarModel", router_crossbar_model); 200 egress_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel")); 201 egress_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel")); 202 egress_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels")); 203 egress_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer")); 204 egress_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier")); 205 egress_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier")); 206 egress_router->construct(); 207 // Init input to ingress link 208 ElectricalModel* input_to_ingress_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "InputToIngressLink", getTechModel()); 209 input_to_ingress_link->setParameter("NumberBits", number_bits_per_flit); 210 input_to_ingress_link->setParameter("WireLayer", link_wire_layer); 211 input_to_ingress_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier); 212 input_to_ingress_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier); 213 input_to_ingress_link->construct(); 214 // Init ingress to middle link 215 ElectricalModel* ingress_to_middle_link = (ElectricalModel*)ModelGen::createModel("SWSRLink", "IngressToMiddleLink", getTechModel()); 216 ingress_to_middle_link->setParameter("NumberBits", number_bits_per_flit); 217 ingress_to_middle_link->setParameter("CoreDataRate", clock_freq); 218 ingress_to_middle_link->setParameter("LinkDataRate", swsr_link_data_rate); 219 ingress_to_middle_link->setParameter("LaserType", swsr_laser_type); 220 ingress_to_middle_link->setParameter("RingTuningMethod", swsr_ring_tuning_method); 221 ingress_to_middle_link->construct(); 222 // Init middle to egress link 223 ElectricalModel* middle_to_egress_link = (ElectricalModel*)ModelGen::createModel("SWSRLink", "MiddleToEgressLink", getTechModel()); 224 middle_to_egress_link->setParameter("NumberBits", number_bits_per_flit); 225 middle_to_egress_link->setParameter("CoreDataRate", clock_freq); 226 middle_to_egress_link->setParameter("LinkDataRate", swsr_link_data_rate); 227 middle_to_egress_link->setParameter("LaserType", swsr_laser_type); 228 middle_to_egress_link->setParameter("RingTuningMethod", swsr_ring_tuning_method); 229 middle_to_egress_link->construct(); 230 // Init egress to output link 231 ElectricalModel* egress_to_output_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "EgressToOutputLink", getTechModel()); 232 egress_to_output_link->setParameter("NumberBits", number_bits_per_flit); 233 egress_to_output_link->setParameter("WireLayer", link_wire_layer); 234 egress_to_output_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier); 235 egress_to_output_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier); 236 egress_to_output_link->construct(); 237 238 // Connect ports 239 createNet("InputToIngressLink_Out", makeNetIndex(0, number_bits_per_flit - 1)); 240 createNet("InputToIngressLink_In", makeNetIndex(0, number_bits_per_flit - 1)); 241 portConnect(input_to_ingress_link, "In", "InputToIngressLink_In"); 242 portConnect(input_to_ingress_link, "Out", "InputToIngressLink_Out"); 243 244 createNet("IngressToMiddleLink_In", makeNetIndex(0, number_bits_per_flit - 1)); 245 createNet("IngressToMiddleLink_Out", makeNetIndex(0, number_bits_per_flit - 1)); 246 portConnect(ingress_to_middle_link, "In", "IngressToMiddleLink_In"); 247 portConnect(ingress_to_middle_link, "Out", "IngressToMiddleLink_Out"); 248 249 createNet("MiddleToEgressLink_In", makeNetIndex(0, number_bits_per_flit - 1)); 250 createNet("MiddleToEgressLink_Out", makeNetIndex(0, number_bits_per_flit - 1)); 251 portConnect(middle_to_egress_link, "In", "MiddleToEgressLink_In"); 252 portConnect(middle_to_egress_link, "Out", "MiddleToEgressLink_Out"); 253 254 createNet("EgressToOutputLink_In", makeNetIndex(0, number_bits_per_flit - 1)); 255 createNet("EgressToOutputLink_Out", makeNetIndex(0, number_bits_per_flit - 1)); 256 portConnect(egress_to_output_link, "In", "EgressToOutputLink_In"); 257 portConnect(egress_to_output_link, "Out", "EgressToOutputLink_Out"); 258 259 portConnect(ingress_router, "CK", "CK"); 260 for(unsigned int i = 0; i < ingress_router_number_input_ports; ++i) 261 { 262 createNet("IngressRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); 263 for (unsigned int j = 0; j < number_bits_per_flit; ++j) 264 assignVirtualFanout("IngressRouter_In" + (String)i, makeNetIndex(j), "InputToIngressLink_Out", makeNetIndex(j)); 265 portConnect(ingress_router, "FlitIn" + (String)i, "IngressRouter_In" + (String)i); 266 } 267 for(unsigned int i = 0; i < ingress_router_number_output_ports; ++i) 268 { 269 // VFI 270 portConnect(ingress_router, "FlitOut" + (String)i, "IngressToMiddleLink_In"); 271 } 272 portConnect(middle_router, "CK", "CK"); 273 for(unsigned int i = 0; i < middle_router_number_input_ports; ++i) 274 { 275 createNet("MiddleRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); 276 for (unsigned int j = 0; j < number_bits_per_flit; ++j) 277 assignVirtualFanout("MiddleRouter_In" + (String)i, makeNetIndex(j), "IngressToMiddleLink_Out", makeNetIndex(j)); 278 portConnect(middle_router, "FlitIn" + (String)i, "MiddleRouter_In" + (String)i); 279 } 280 for(unsigned int i = 0; i < middle_router_number_output_ports; ++i) 281 { 282 // VFI 283 portConnect(middle_router, "FlitOut" + (String)i, "MiddleToEgressLink_In"); 284 } 285 portConnect(egress_router, "CK", "CK"); 286 for(unsigned int i = 0; i < egress_router_number_input_ports; ++i) 287 { 288 createNet("EgressRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); 289 for (unsigned int j = 0; j < number_bits_per_flit; ++j) 290 assignVirtualFanout("EgressRouter_In" + (String)i, makeNetIndex(j), "MiddleToEgressLink_Out", makeNetIndex(j)); 291 portConnect(egress_router, "FlitIn" + (String)i, "EgressRouter_In" + (String)i); 292 } 293 for(unsigned int i = 0; i < egress_router_number_output_ports; ++i) 294 { 295 // VFI 296 portConnect(egress_router, "FlitOut" + (String)i, "EgressToOutputLink_In"); 297 } 298 299 // Create area, power, and event results 300 createElectricalResults(); 301 createElectricalEventResult("AvgUnicast"); 302 createElectricalEventResult("AvgBroadcast"); 303 addNddPowerResult(new Result("Laser")); 304 addNddPowerResult(new Result("RingTuning")); 305 addAreaResult(new Result("Photonic")); 306 307 // Add all instances 308 addSubInstances(ingress_router, number_ingress_routers); 309 addElectricalSubResults(ingress_router, number_ingress_routers); 310 addSubInstances(middle_router, number_middle_routers); 311 addElectricalSubResults(middle_router, number_middle_routers); 312 addSubInstances(egress_router, number_egress_routers); 313 addElectricalSubResults(egress_router, number_egress_routers); 314 addSubInstances(input_to_ingress_link, number_input_to_ingress_links); 315 addElectricalSubResults(input_to_ingress_link, number_input_to_ingress_links); 316 addSubInstances(ingress_to_middle_link, number_ingress_to_middle_links); 317 addElectricalSubResults(ingress_to_middle_link, number_ingress_to_middle_links); 318 getAreaResult("Photonic")->addSubResult(ingress_to_middle_link->getAreaResult("Photonic"), "IngressToMiddleLink", number_ingress_to_middle_links); 319 getNddPowerResult("Laser")->addSubResult(ingress_to_middle_link->getNddPowerResult("Laser"), "IngressToMiddleLink", number_ingress_to_middle_links); 320 getNddPowerResult("RingTuning")->addSubResult(ingress_to_middle_link->getNddPowerResult("RingTuning"), "IngressToMiddleLink", number_ingress_to_middle_links); 321 addSubInstances(middle_to_egress_link, number_middle_to_egress_links); 322 addElectricalSubResults(middle_to_egress_link, number_middle_to_egress_links); 323 getAreaResult("Photonic")->addSubResult(middle_to_egress_link->getAreaResult("Photonic"), "MiddletoEgressLink", number_middle_to_egress_links); 324 getNddPowerResult("Laser")->addSubResult(middle_to_egress_link->getNddPowerResult("Laser"), "MiddleToEgressLink", number_middle_to_egress_links); 325 getNddPowerResult("RingTuning")->addSubResult(middle_to_egress_link->getNddPowerResult("RingTuning"), "MiddleToEgressLink", number_middle_to_egress_links); 326 addSubInstances(egress_to_output_link, number_egress_to_output_links); 327 addElectricalSubResults(egress_to_output_link, number_egress_to_output_links); 328 329 // Update unicast event 330 Result* avg_unicast_event = getEventResult("AvgUnicast"); 331 avg_unicast_event->addSubResult(input_to_ingress_link->getEventResult("Send"), "InputToIngressLink", 1.0); 332 if(ingress_router->hasEventResult("WriteBuffer")) 333 { 334 avg_unicast_event->addSubResult(ingress_router->getEventResult("WriteBuffer"), "IngressRouter", 1.0); 335 } 336 if(ingress_router->hasEventResult("ReadBuffer")) 337 { 338 avg_unicast_event->addSubResult(ingress_router->getEventResult("ReadBuffer"), "IngressRouter", 1.0); 339 } 340 avg_unicast_event->addSubResult(ingress_router->getEventResult("TraverseCrossbar->Multicast1"), "IngressRouter", 1.0); 341 avg_unicast_event->addSubResult(ingress_to_middle_link->getEventResult("Send"), "IngressToMiddleLink", 1.0); 342 if(middle_router->hasEventResult("WriteBuffer")) 343 { 344 avg_unicast_event->addSubResult(middle_router->getEventResult("WriteBuffer"), "MiddleRouter", 1.0); 345 } 346 if(middle_router->hasEventResult("ReadBuffer")) 347 { 348 avg_unicast_event->addSubResult(middle_router->getEventResult("ReadBuffer"), "MiddleRouter", 1.0); 349 } 350 avg_unicast_event->addSubResult(middle_router->getEventResult("TraverseCrossbar->Multicast1"), "MiddleRouter", 1.0); 351 avg_unicast_event->addSubResult(middle_to_egress_link->getEventResult("Send"), "MiddleToEgressLink", 1.0); 352 if(egress_router->hasEventResult("WriteBuffer")) 353 { 354 avg_unicast_event->addSubResult(egress_router->getEventResult("WriteBuffer"), "EgressRouter", 1.0); 355 } 356 if(egress_router->hasEventResult("ReadBuffer")) 357 { 358 avg_unicast_event->addSubResult(egress_router->getEventResult("ReadBuffer"), "EgressRouter", 1.0); 359 } 360 avg_unicast_event->addSubResult(egress_router->getEventResult("TraverseCrossbar->Multicast1"), "EgressRouter", 1.0); 361 avg_unicast_event->addSubResult(egress_to_output_link->getEventResult("Send"), "EgressToOutputLink", 1.0); 362 363 // Update broadcast event 364 Result* avg_broadcast_event = getEventResult("AvgBroadcast"); 365 avg_broadcast_event->addSubResult(input_to_ingress_link->getEventResult("Send"), "InputToIngressLink", 1.0); 366 if(ingress_router->hasEventResult("WriteBuffer")) 367 { 368 avg_broadcast_event->addSubResult(ingress_router->getEventResult("WriteBuffer"), "IngressRouter", 1.0); 369 } 370 if(ingress_router->hasEventResult("ReadBuffer")) 371 { 372 avg_broadcast_event->addSubResult(ingress_router->getEventResult("ReadBuffer"), "IngressRouter", 1.0); 373 } 374 avg_broadcast_event->addSubResult(ingress_router->getEventResult("TraverseCrossbar->Multicast1"), "IngressRouter", 1.0); 375 avg_broadcast_event->addSubResult(ingress_to_middle_link->getEventResult("Send"), "IngressToMiddleLink", 1.0); 376 if(middle_router->hasEventResult("WriteBuffer")) 377 { 378 avg_broadcast_event->addSubResult(middle_router->getEventResult("WriteBuffer"), "MiddleRouter", 1.0); 379 } 380 if(middle_router->hasEventResult("ReadBuffer")) 381 { 382 avg_broadcast_event->addSubResult(middle_router->getEventResult("ReadBuffer"), "MiddleRouter", 1.0); 383 } 384 avg_broadcast_event->addSubResult(middle_router->getEventResult("TraverseCrossbar->Multicast1"), "MiddleRouter", 1.0); 385 avg_broadcast_event->addSubResult(middle_to_egress_link->getEventResult("Send"), "MiddleToEgressLink", number_egress_routers); 386 if(egress_router->hasEventResult("WriteBuffer")) 387 { 388 avg_broadcast_event->addSubResult(egress_router->getEventResult("WriteBuffer"), "EgressRouter", number_egress_routers); 389 } 390 if(egress_router->hasEventResult("ReadBuffer")) 391 { 392 avg_broadcast_event->addSubResult(egress_router->getEventResult("ReadBuffer"), "EgressRouter", number_egress_routers); 393 } 394 avg_broadcast_event->addSubResult(egress_router->getEventResult("TraverseCrossbar->Multicast" + (String)number_egress_routers), "EgressRouter", 1.0); 395 avg_broadcast_event->addSubResult(egress_to_output_link->getEventResult("Send"), "EgressToOutputLink", number_output_sites); 396 return; 397 } 398 399 void PhotonicClos::updateModel() 400 { 401 // Assumes waveguide runs adjacent to ingress and egress routers 402 // Assumes input sites belonging to each ingress router are centered around the ingress router 403 // Assumes middle routers are distributed around the chip adjacent to the main waveguide 404 // Assumes output sites belonging to each egress router are centered around the egress router 405 406 // Get properties 407 double input_site_pitch = getProperty("InputSitePitch").toDouble(); 408 double output_site_pitch = getProperty("OutputSitePitch").toDouble(); 409 double clock_freq = getParameter("Frequency"); 410 const double swsr_opt_util = getProperty("SWSR->OptUtil"); 411 412 ASSERT(input_site_pitch > 0, "[Error] " + getInstanceName() + 413 " -> Input site pitch must be > 0!"); 414 ASSERT(output_site_pitch > 0, "[Error] " + getInstanceName() + 415 " -> Output site pitch must be > 0!"); 416 417 unsigned int number_input_sites_per_ingress_router = getGenProperties()->get("NumberInputSitesPerIngressRouter"); 418 unsigned int number_ingress_routers = getParameter("NumberIngressRouters"); 419 unsigned int number_output_sites_per_egress_router = getGenProperties()->get("NumberOutputSitesPerEgressRouter"); 420 unsigned int number_egress_routers = getParameter("NumberEgressRouters"); 421 double delay = 1.0 / clock_freq; 422 423 //Calculate the length of the waveguide 424 double input_to_ingress_link_length = input_site_pitch * (sqrt(number_input_sites_per_ingress_router) - 1.0); 425 double input_to_ingress_link_delay = delay * 0.8; 426 double ingress_to_middle_link_length = input_site_pitch * (sqrt(number_input_sites_per_ingress_router) * number_ingress_routers); 427 double middle_to_egress_link_length = output_site_pitch * (sqrt(number_output_sites_per_egress_router) * number_egress_routers); 428 double egress_to_output_link_length = output_site_pitch * (sqrt(number_output_sites_per_egress_router) - 1.0); 429 double egress_to_output_link_delay = delay * 0.8; 430 double ingress_router_delay = delay; 431 double middle_router_delay = delay; 432 double egress_router_delay = delay; 433 434 Model* input_to_ingress_link = getSubInstance("InputToIngressLink"); 435 input_to_ingress_link->setProperty("WireLength", input_to_ingress_link_length); 436 input_to_ingress_link->setProperty("Delay", input_to_ingress_link_delay); 437 input_to_ingress_link->setProperty("IsKeepParity", "TRUE"); 438 input_to_ingress_link->update(); 439 440 Model* ingress_to_middle_link = getSubInstance("IngressToMiddleLink"); 441 ingress_to_middle_link->setProperty("Length", ingress_to_middle_link_length); 442 ingress_to_middle_link->setProperty("OptUtil", swsr_opt_util); 443 ingress_to_middle_link->update(); 444 445 Model* middle_to_egress_link = getSubInstance("MiddleToEgressLink"); 446 middle_to_egress_link->setProperty("Length", middle_to_egress_link_length); 447 middle_to_egress_link->setProperty("OptUtil", swsr_opt_util); 448 middle_to_egress_link->update(); 449 450 Model* egress_to_output_link = getSubInstance("EgressToOutputLink"); 451 egress_to_output_link->setProperty("WireLength", egress_to_output_link_length); 452 egress_to_output_link->setProperty("Delay", egress_to_output_link_delay); 453 egress_to_output_link->setProperty("IsKeepParity", "TRUE"); 454 egress_to_output_link->update(); 455 456 ElectricalModel* ingress_router = (ElectricalModel*)getSubInstance("IngressRouter"); 457 ingress_router->update(); 458 ElectricalTimingTree ingress_router_timing_tree("IngressRouter", ingress_router); 459 ingress_router_timing_tree.performTimingOpt(ingress_router->getNet("CK"), ingress_router_delay); 460 461 ElectricalModel* middle_router = (ElectricalModel*)getSubInstance("MiddleRouter"); 462 middle_router->update(); 463 ElectricalTimingTree middle_router_timing_tree("MiddleRouter", middle_router); 464 middle_router_timing_tree.performTimingOpt(middle_router->getNet("CK"), middle_router_delay); 465 466 ElectricalModel* egress_router = (ElectricalModel*)getSubInstance("EgressRouter"); 467 egress_router->update(); 468 ElectricalTimingTree egress_router_timing_tree("EgressRouter", egress_router); 469 egress_router_timing_tree.performTimingOpt(egress_router->getNet("CK"), egress_router_delay); 470 471 return; 472 } 473 474 void PhotonicClos::propagateTransitionInfo() 475 { 476 // Get parameters 477 double clock_freq = getParameter("Frequency"); 478 double swsr_link_data_rate = getParameter("SWSR->LinkDataRate"); 479 480 // Get properties 481 unsigned int ingress_router_number_input_ports = getGenProperties()->get("IngressRouter->NumberInputPorts"); 482 unsigned int middle_router_number_input_ports = getGenProperties()->get("MiddleRouter->NumberInputPorts"); 483 unsigned int egress_router_number_input_ports = getGenProperties()->get("EgressRouter->NumberInputPorts"); 484 485 ElectricalModel* input_to_ingress_link = (ElectricalModel*)getSubInstance("InputToIngressLink"); 486 assignPortTransitionInfo(input_to_ingress_link, "In", TransitionInfo(0.25, 0.25, 0.25)); 487 input_to_ingress_link->use(); 488 489 ElectricalModel* ingress_to_middle_link = (ElectricalModel*)getSubInstance("IngressToMiddleLink"); 490 assignPortTransitionInfo(ingress_to_middle_link, "LinkCK", TransitionInfo(0.0, (double) clock_freq / (swsr_link_data_rate * 2.0), 0.0)); 491 assignPortTransitionInfo(ingress_to_middle_link, "In", TransitionInfo(0.25, 0.25, 0.25)); 492 ingress_to_middle_link->use(); 493 494 ElectricalModel* middle_to_egress_link = (ElectricalModel*)getSubInstance("MiddleToEgressLink"); 495 assignPortTransitionInfo(middle_to_egress_link, "LinkCK", TransitionInfo(0.0, (double) clock_freq / (swsr_link_data_rate * 2.0), 0.0)); 496 assignPortTransitionInfo(middle_to_egress_link, "In", TransitionInfo(0.25, 0.25, 0.25)); 497 middle_to_egress_link->use(); 498 499 ElectricalModel* egress_to_output_link = (ElectricalModel*)getSubInstance("EgressToOutputLink"); 500 assignPortTransitionInfo(egress_to_output_link, "In", TransitionInfo(0.25, 0.25, 0.25)); 501 egress_to_output_link->use(); 502 503 ElectricalModel* ingress_router = (ElectricalModel*)getSubInstance("IngressRouter"); 504 for(unsigned int i = 0; i < ingress_router_number_input_ports; ++i) 505 { 506 assignPortTransitionInfo(ingress_router, "FlitIn" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); 507 } 508 assignPortTransitionInfo(ingress_router, "CK", TransitionInfo(0.0, 1.0, 0.0)); 509 ingress_router->getGenProperties()->set("UseModelEvent", ""); 510 ingress_router->use(); 511 512 ElectricalModel* middle_router = (ElectricalModel*)getSubInstance("MiddleRouter"); 513 for(unsigned int i = 0; i < middle_router_number_input_ports; ++i) 514 { 515 assignPortTransitionInfo(middle_router, "FlitIn" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); 516 } 517 assignPortTransitionInfo(middle_router, "CK", TransitionInfo(0.0, 1.0, 0.0)); 518 middle_router->getGenProperties()->set("UseModelEvent", ""); 519 middle_router->use(); 520 521 ElectricalModel* egress_router = (ElectricalModel*)getSubInstance("EgressRouter"); 522 for(unsigned int i = 0; i < egress_router_number_input_ports; ++i) 523 { 524 assignPortTransitionInfo(egress_router, "FlitIn" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); 525 } 526 assignPortTransitionInfo(egress_router, "CK", TransitionInfo(0.0, 1.0, 0.0)); 527 egress_router->getGenProperties()->set("UseModelEvent", ""); 528 egress_router->use(); 529 530 return; 531 } 532} // namespace DSENT 533 534