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