ElectricalClos.cc revision 10447
111308Santhony.gutierrez@amd.com#include "model/network/ElectricalClos.h"
211308Santhony.gutierrez@amd.com
311308Santhony.gutierrez@amd.com#include <cmath>
411308Santhony.gutierrez@amd.com
511308Santhony.gutierrez@amd.com#include "model/ModelGen.h"
611308Santhony.gutierrez@amd.com#include "model/timing_graph/ElectricalTimingTree.h"
711308Santhony.gutierrez@amd.com#include "model/timing_graph/ElectricalNet.h"
811308Santhony.gutierrez@amd.com
911308Santhony.gutierrez@amd.comnamespace DSENT
1011308Santhony.gutierrez@amd.com{
1111308Santhony.gutierrez@amd.com    using std::sqrt;
1211308Santhony.gutierrez@amd.com
1311308Santhony.gutierrez@amd.com    ElectricalClos::ElectricalClos(const String& instance_name_, const TechModel* tech_model_)
1411308Santhony.gutierrez@amd.com        : ElectricalModel(instance_name_, tech_model_)
1511308Santhony.gutierrez@amd.com    {
1611308Santhony.gutierrez@amd.com        initParameters();
1711308Santhony.gutierrez@amd.com        initProperties();
1811308Santhony.gutierrez@amd.com    }
1911308Santhony.gutierrez@amd.com
2011308Santhony.gutierrez@amd.com    ElectricalClos::~ElectricalClos()
2111308Santhony.gutierrez@amd.com    {}
2211308Santhony.gutierrez@amd.com
2311308Santhony.gutierrez@amd.com    void ElectricalClos::initParameters()
2411308Santhony.gutierrez@amd.com    {
2511308Santhony.gutierrez@amd.com        // Frequency
2611308Santhony.gutierrez@amd.com        addParameterName("Frequency");
2711308Santhony.gutierrez@amd.com        // Physical Parameters
2811308Santhony.gutierrez@amd.com        addParameterName("NumberInputSites");
2911308Santhony.gutierrez@amd.com        addParameterName("NumberOutputSites");
3011308Santhony.gutierrez@amd.com        addParameterName("NumberBitsPerFlit");
3111308Santhony.gutierrez@amd.com        // Number of each type of routers
3211308Santhony.gutierrez@amd.com        addParameterName("NumberIngressRouters");
3311308Santhony.gutierrez@amd.com        addParameterName("NumberMiddleRouters");
3411308Santhony.gutierrez@amd.com        addParameterName("NumberEgressRouters");
3511308Santhony.gutierrez@amd.com        // Router parameters
3611308Santhony.gutierrez@amd.com        addParameterName("Router->NumberVirtualNetworks");
3711308Santhony.gutierrez@amd.com        addParameterName("Router->NumberVirtualChannelsPerVirtualNetwork");
3811308Santhony.gutierrez@amd.com        addParameterName("Router->NumberBuffersPerVirtualChannel");
3911308Santhony.gutierrez@amd.com        addParameterName("Router->InputPort->BufferModel");
4011308Santhony.gutierrez@amd.com        addParameterName("Router->CrossbarModel");
4111308Santhony.gutierrez@amd.com        addParameterName("Router->SwitchAllocator->ArbiterModel");
4211308Santhony.gutierrez@amd.com        addParameterName("Router->ClockTreeModel");
4311308Santhony.gutierrez@amd.com        addParameterName("Router->ClockTree->NumberLevels");
4411308Santhony.gutierrez@amd.com        addParameterName("Router->ClockTree->WireLayer");
4511308Santhony.gutierrez@amd.com        addParameterName("Router->ClockTree->WireWidthMultiplier");
4611308Santhony.gutierrez@amd.com        addParameterName("Router->ClockTree->WireSpacingMultiplier", 3.0);
4711308Santhony.gutierrez@amd.com        // Link parameters
4811308Santhony.gutierrez@amd.com        addParameterName("Link->WireLayer");
4911308Santhony.gutierrez@amd.com        addParameterName("Link->WireWidthMultiplier");
5011308Santhony.gutierrez@amd.com        addParameterName("Link->WireSpacingMultiplier");
5111308Santhony.gutierrez@amd.com        return;
5211308Santhony.gutierrez@amd.com    }
5311308Santhony.gutierrez@amd.com
5411308Santhony.gutierrez@amd.com    void ElectricalClos::initProperties()
5511308Santhony.gutierrez@amd.com    {
5611308Santhony.gutierrez@amd.com        addPropertyName("InputSitePitch");
5711308Santhony.gutierrez@amd.com        addPropertyName("OutputSitePitch");
5811308Santhony.gutierrez@amd.com        return;
5911308Santhony.gutierrez@amd.com    }
6011308Santhony.gutierrez@amd.com
6111308Santhony.gutierrez@amd.com    ElectricalClos* ElectricalClos::clone() const
6211308Santhony.gutierrez@amd.com    {
6311308Santhony.gutierrez@amd.com        // TODO
6411308Santhony.gutierrez@amd.com        return NULL;
6511308Santhony.gutierrez@amd.com    }
6611308Santhony.gutierrez@amd.com
6711308Santhony.gutierrez@amd.com    void ElectricalClos::constructModel()
6811308Santhony.gutierrez@amd.com    {
6911308Santhony.gutierrez@amd.com        // Get input parameters
7011308Santhony.gutierrez@amd.com        unsigned int number_input_sites = getParameter("NumberInputSites").toUInt();
7111308Santhony.gutierrez@amd.com        unsigned int number_output_sites = getParameter("NumberOutputSites").toUInt();
7211308Santhony.gutierrez@amd.com        unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt();
7311308Santhony.gutierrez@amd.com        unsigned int number_ingress_routers = getParameter("NumberIngressRouters").toUInt();
7411308Santhony.gutierrez@amd.com        unsigned int number_middle_routers = getParameter("NumberMiddleRouters").toUInt();
7511308Santhony.gutierrez@amd.com        unsigned int number_egress_routers = getParameter("NumberEgressRouters").toUInt();
7611308Santhony.gutierrez@amd.com
7711308Santhony.gutierrez@amd.com        ASSERT(number_input_sites > 0, "[Error] " + getInstanceName() +
7811308Santhony.gutierrez@amd.com                " -> Number of input sites must be > 0!");
7911308Santhony.gutierrez@amd.com        ASSERT(number_output_sites > 0, "[Error] " + getInstanceName() +
8011308Santhony.gutierrez@amd.com                " -> Number of output sites must be > 0!");
8111308Santhony.gutierrez@amd.com        ASSERT(number_bits_per_flit > 0, "[Error] " + getInstanceName() +
8211308Santhony.gutierrez@amd.com                " -> Number of bits per flit must be > 0!");
8311308Santhony.gutierrez@amd.com        ASSERT(number_ingress_routers > 0, "[Error] " + getInstanceName() +
8411308Santhony.gutierrez@amd.com                " -> Number of ingress routers must be > 0!");
8511308Santhony.gutierrez@amd.com        ASSERT(number_middle_routers > 0, "[Error] " + getInstanceName() +
8611534Sjohn.kalamatianos@amd.com                " -> Number of middle routers must be > 0!");
8711308Santhony.gutierrez@amd.com        ASSERT(number_egress_routers > 0, "[Error] " + getInstanceName() +
8811308Santhony.gutierrez@amd.com                " -> Number of egress routers must be > 0!");
8911308Santhony.gutierrez@amd.com
9011308Santhony.gutierrez@amd.com        // Get input parameters that will be forwarded to the sub instances
9111308Santhony.gutierrez@amd.com        const String& router_number_vns = getParameter("Router->NumberVirtualNetworks");
9211308Santhony.gutierrez@amd.com        const String& router_number_vcs_per_vn = getParameter("Router->NumberVirtualChannelsPerVirtualNetwork");
9311308Santhony.gutierrez@amd.com        const String& router_number_bufs_per_vc = getParameter("Router->NumberBuffersPerVirtualChannel");
9411534Sjohn.kalamatianos@amd.com        const String& router_buffer_model = getParameter("Router->InputPort->BufferModel");
9511308Santhony.gutierrez@amd.com        const String& router_crossbar_model = getParameter("Router->CrossbarModel");
9611308Santhony.gutierrez@amd.com        const String& link_wire_layer = getParameter("Link->WireLayer");
9711534Sjohn.kalamatianos@amd.com        const String& link_wire_width_multiplier = getParameter("Link->WireWidthMultiplier");
9811534Sjohn.kalamatianos@amd.com        const String& link_wire_spacing_multiplier = getParameter("Link->WireSpacingMultiplier");
9911308Santhony.gutierrez@amd.com
10011534Sjohn.kalamatianos@amd.com        // Calculate properties from input parameters
10111308Santhony.gutierrez@amd.com        unsigned int ingress_router_number_input_ports = number_input_sites / number_ingress_routers;
10211308Santhony.gutierrez@amd.com        unsigned int ingress_router_number_output_ports = number_middle_routers;
10311308Santhony.gutierrez@amd.com        unsigned int middle_router_number_input_ports = number_ingress_routers;
10411308Santhony.gutierrez@amd.com        unsigned int middle_router_number_output_ports = number_egress_routers;
10511308Santhony.gutierrez@amd.com        unsigned int egress_router_number_input_ports = number_middle_routers;
10611308Santhony.gutierrez@amd.com        unsigned int egress_router_number_output_ports = number_output_sites / number_egress_routers;
10711308Santhony.gutierrez@amd.com        unsigned int number_input_to_ingress_links = number_input_sites;
10811308Santhony.gutierrez@amd.com        unsigned int number_ingress_to_middle_links = number_ingress_routers * number_middle_routers;
10911308Santhony.gutierrez@amd.com        unsigned int number_middle_to_egress_links = number_middle_routers * number_egress_routers;
11011308Santhony.gutierrez@amd.com        unsigned int number_egress_to_output_links = number_output_sites;
11111308Santhony.gutierrez@amd.com
11211308Santhony.gutierrez@amd.com        getGenProperties()->set("NumberInputSitesPerIngressRouter", ingress_router_number_input_ports);
11311308Santhony.gutierrez@amd.com        getGenProperties()->set("NumberOutputSitesPerEgressRouter", egress_router_number_output_ports);
11411308Santhony.gutierrez@amd.com        getGenProperties()->set("IngressRouter->NumberInputPorts", ingress_router_number_input_ports);
11511308Santhony.gutierrez@amd.com        getGenProperties()->set("IngressRouter->NumberOutputPorts", ingress_router_number_output_ports);
11611308Santhony.gutierrez@amd.com        getGenProperties()->set("MiddleRouter->NumberInputPorts", middle_router_number_input_ports);
11711308Santhony.gutierrez@amd.com        getGenProperties()->set("MiddleRouter->NumberOutputPorts", middle_router_number_output_ports);
11811308Santhony.gutierrez@amd.com        getGenProperties()->set("EgressRouter->NumberInputPorts", egress_router_number_input_ports);
11911308Santhony.gutierrez@amd.com        getGenProperties()->set("EgressRouter->NumberOutputPorts", egress_router_number_output_ports);
12011308Santhony.gutierrez@amd.com
12111308Santhony.gutierrez@amd.com        // Create ports
12211308Santhony.gutierrez@amd.com        createInputPort("CK");
12311308Santhony.gutierrez@amd.com
12411308Santhony.gutierrez@amd.com        // Init ingress router
12511308Santhony.gutierrez@amd.com        ElectricalModel* ingress_router = (ElectricalModel*)ModelGen::createModel("Router", "IngressRouter", getTechModel());
12611308Santhony.gutierrez@amd.com        ingress_router->setParameter("NumberInputPorts", ingress_router_number_input_ports);
12711308Santhony.gutierrez@amd.com        ingress_router->setParameter("NumberOutputPorts", ingress_router_number_output_ports);
12811308Santhony.gutierrez@amd.com        ingress_router->setParameter("NumberVirtualNetworks", router_number_vns);
12911308Santhony.gutierrez@amd.com        ingress_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn);
13011308Santhony.gutierrez@amd.com        ingress_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc);
13111308Santhony.gutierrez@amd.com        ingress_router->setParameter("NumberBitsPerFlit", number_bits_per_flit);
13211308Santhony.gutierrez@amd.com        ingress_router->setParameter("InputPort->BufferModel", router_buffer_model);
13311308Santhony.gutierrez@amd.com        ingress_router->setParameter("CrossbarModel", router_crossbar_model);
13411308Santhony.gutierrez@amd.com        ingress_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel"));
13511308Santhony.gutierrez@amd.com        ingress_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel"));
13611308Santhony.gutierrez@amd.com        ingress_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels"));
13711308Santhony.gutierrez@amd.com        ingress_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer"));
13811308Santhony.gutierrez@amd.com        ingress_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier"));
13911308Santhony.gutierrez@amd.com        ingress_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier"));
14011308Santhony.gutierrez@amd.com        ingress_router->construct();
14111308Santhony.gutierrez@amd.com        // Init middle routers
14211308Santhony.gutierrez@amd.com        ElectricalModel* middle_router = (ElectricalModel*)ModelGen::createModel("Router", "MiddleRouter", getTechModel());
14311308Santhony.gutierrez@amd.com        middle_router->setParameter("NumberInputPorts", middle_router_number_input_ports);
14411308Santhony.gutierrez@amd.com        middle_router->setParameter("NumberOutputPorts", middle_router_number_output_ports);
14511308Santhony.gutierrez@amd.com        middle_router->setParameter("NumberVirtualNetworks", router_number_vns);
14611308Santhony.gutierrez@amd.com        middle_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn);
14711308Santhony.gutierrez@amd.com        middle_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc);
14811308Santhony.gutierrez@amd.com        middle_router->setParameter("NumberBitsPerFlit", number_bits_per_flit);
14911308Santhony.gutierrez@amd.com        middle_router->setParameter("InputPort->BufferModel", router_buffer_model);
15011308Santhony.gutierrez@amd.com        middle_router->setParameter("CrossbarModel", router_crossbar_model);
15111308Santhony.gutierrez@amd.com        middle_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel"));
15211308Santhony.gutierrez@amd.com        middle_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel"));
15311308Santhony.gutierrez@amd.com        middle_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels"));
15411308Santhony.gutierrez@amd.com        middle_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer"));
15511308Santhony.gutierrez@amd.com        middle_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier"));
15611308Santhony.gutierrez@amd.com        middle_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier"));
15711308Santhony.gutierrez@amd.com        middle_router->construct();
15811639Salexandru.dutu@amd.com        // Init egress routers
15911308Santhony.gutierrez@amd.com        ElectricalModel* egress_router = (ElectricalModel*)ModelGen::createModel("Router", "EgressRouter", getTechModel());
16011639Salexandru.dutu@amd.com        egress_router->setParameter("NumberInputPorts", egress_router_number_input_ports);
16111639Salexandru.dutu@amd.com        egress_router->setParameter("NumberOutputPorts", egress_router_number_output_ports);
16211639Salexandru.dutu@amd.com        egress_router->setParameter("NumberVirtualNetworks", router_number_vns);
16311639Salexandru.dutu@amd.com        egress_router->setParameter("NumberVirtualChannelsPerVirtualNetwork", router_number_vcs_per_vn);
16411308Santhony.gutierrez@amd.com        egress_router->setParameter("NumberBuffersPerVirtualChannel", router_number_bufs_per_vc);
16511308Santhony.gutierrez@amd.com        egress_router->setParameter("NumberBitsPerFlit", number_bits_per_flit);
16611308Santhony.gutierrez@amd.com        egress_router->setParameter("InputPort->BufferModel", router_buffer_model);
16711639Salexandru.dutu@amd.com        egress_router->setParameter("CrossbarModel", router_crossbar_model);
16811308Santhony.gutierrez@amd.com        egress_router->setParameter("SwitchAllocator->ArbiterModel", getParameter("Router->SwitchAllocator->ArbiterModel"));
16911308Santhony.gutierrez@amd.com        egress_router->setParameter("ClockTreeModel", getParameter("Router->ClockTreeModel"));
17011308Santhony.gutierrez@amd.com        egress_router->setParameter("ClockTree->NumberLevels", getParameter("Router->ClockTree->NumberLevels"));
17111308Santhony.gutierrez@amd.com        egress_router->setParameter("ClockTree->WireLayer", getParameter("Router->ClockTree->WireLayer"));
17211308Santhony.gutierrez@amd.com        egress_router->setParameter("ClockTree->WireWidthMultiplier", getParameter("Router->ClockTree->WireWidthMultiplier"));
17311308Santhony.gutierrez@amd.com        egress_router->setParameter("ClockTree->WireSpacingMultiplier", getParameter("Router->ClockTree->WireSpacingMultiplier"));
17411308Santhony.gutierrez@amd.com        egress_router->construct();
17511308Santhony.gutierrez@amd.com        // Init input to ingress link
17611308Santhony.gutierrez@amd.com        ElectricalModel* input_to_ingress_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "InputToIngressLink", getTechModel());
17711308Santhony.gutierrez@amd.com        input_to_ingress_link->setParameter("NumberBits", number_bits_per_flit);
17811308Santhony.gutierrez@amd.com        input_to_ingress_link->setParameter("WireLayer", link_wire_layer);
17911308Santhony.gutierrez@amd.com        input_to_ingress_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier);
18011308Santhony.gutierrez@amd.com        input_to_ingress_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier);
18111308Santhony.gutierrez@amd.com        input_to_ingress_link->construct();
18211308Santhony.gutierrez@amd.com        // Init ingress to middle link
18311308Santhony.gutierrez@amd.com        ElectricalModel* ingress_to_middle_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "IngressToMiddleLink", getTechModel());
18411308Santhony.gutierrez@amd.com        ingress_to_middle_link->setParameter("NumberBits", number_bits_per_flit);
18511308Santhony.gutierrez@amd.com        ingress_to_middle_link->setParameter("WireLayer", link_wire_layer);
18611308Santhony.gutierrez@amd.com        ingress_to_middle_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier);
18711308Santhony.gutierrez@amd.com        ingress_to_middle_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier);
18811308Santhony.gutierrez@amd.com        ingress_to_middle_link->construct();
18911308Santhony.gutierrez@amd.com        // Init middle to egress link
19011308Santhony.gutierrez@amd.com        ElectricalModel* middle_to_egress_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "MiddleToEgressLink", getTechModel());
19111308Santhony.gutierrez@amd.com        middle_to_egress_link->setParameter("NumberBits", number_bits_per_flit);
19211308Santhony.gutierrez@amd.com        middle_to_egress_link->setParameter("WireLayer", link_wire_layer);
19311308Santhony.gutierrez@amd.com        middle_to_egress_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier);
19411308Santhony.gutierrez@amd.com        middle_to_egress_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier);
19511308Santhony.gutierrez@amd.com        middle_to_egress_link->construct();
19611639Salexandru.dutu@amd.com        // Init egress to output link
19711639Salexandru.dutu@amd.com        ElectricalModel* egress_to_output_link = (ElectricalModel*)ModelGen::createModel("RepeatedLink", "EgressToOutputLink", getTechModel());
19811639Salexandru.dutu@amd.com        egress_to_output_link->setParameter("NumberBits", number_bits_per_flit);
19911639Salexandru.dutu@amd.com        egress_to_output_link->setParameter("WireLayer", link_wire_layer);
20011639Salexandru.dutu@amd.com        egress_to_output_link->setParameter("WireWidthMultiplier", link_wire_width_multiplier);
20111639Salexandru.dutu@amd.com        egress_to_output_link->setParameter("WireSpacingMultiplier", link_wire_spacing_multiplier);
20211639Salexandru.dutu@amd.com        egress_to_output_link->construct();
20311639Salexandru.dutu@amd.com
20411639Salexandru.dutu@amd.com        // Connect ports
20511639Salexandru.dutu@amd.com        createNet("InputToIngressLink_Out", makeNetIndex(0, number_bits_per_flit-1));
20611639Salexandru.dutu@amd.com        createNet("InputToIngressLink_In", makeNetIndex(0, number_bits_per_flit-1));
20711308Santhony.gutierrez@amd.com        portConnect(input_to_ingress_link, "In", "InputToIngressLink_In");
20811639Salexandru.dutu@amd.com        portConnect(input_to_ingress_link, "Out", "InputToIngressLink_Out");
20911308Santhony.gutierrez@amd.com
21011308Santhony.gutierrez@amd.com        createNet("IngressToMiddleLink_In", makeNetIndex(0, number_bits_per_flit-1));
21111639Salexandru.dutu@amd.com        createNet("IngressToMiddleLink_Out", makeNetIndex(0, number_bits_per_flit-1));
21211308Santhony.gutierrez@amd.com        portConnect(ingress_to_middle_link, "In", "IngressToMiddleLink_In");
21311639Salexandru.dutu@amd.com        portConnect(ingress_to_middle_link, "Out", "IngressToMiddleLink_Out");
21411308Santhony.gutierrez@amd.com
21511639Salexandru.dutu@amd.com        createNet("MiddleToEgressLink_In", makeNetIndex(0, number_bits_per_flit-1));
21611308Santhony.gutierrez@amd.com        createNet("MiddleToEgressLink_Out", makeNetIndex(0, number_bits_per_flit-1));
21711639Salexandru.dutu@amd.com        portConnect(middle_to_egress_link, "In", "MiddleToEgressLink_In");
21811308Santhony.gutierrez@amd.com        portConnect(middle_to_egress_link, "Out", "MiddleToEgressLink_Out");
21911639Salexandru.dutu@amd.com
22011639Salexandru.dutu@amd.com        createNet("EgressToOutputLink_In", makeNetIndex(0, number_bits_per_flit-1));
22111639Salexandru.dutu@amd.com        createNet("EgressToOutputLink_Out", makeNetIndex(0, number_bits_per_flit-1));
22211639Salexandru.dutu@amd.com        portConnect(egress_to_output_link, "In", "EgressToOutputLink_In");
22311639Salexandru.dutu@amd.com        portConnect(egress_to_output_link, "Out", "EgressToOutputLink_Out");
22411308Santhony.gutierrez@amd.com
22511639Salexandru.dutu@amd.com
22611639Salexandru.dutu@amd.com        portConnect(ingress_router, "CK", "CK");
22711308Santhony.gutierrez@amd.com        for(unsigned int i = 0; i < ingress_router_number_input_ports; ++i)
22811308Santhony.gutierrez@amd.com        {
22911308Santhony.gutierrez@amd.com            createNet("IngressRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1));
23011308Santhony.gutierrez@amd.com            for (unsigned int j = 0; j < number_bits_per_flit; ++j)
23111308Santhony.gutierrez@amd.com                assignVirtualFanout("IngressRouter_In" + (String)i, makeNetIndex(j), "InputToIngressLink_Out", makeNetIndex(j));
23211308Santhony.gutierrez@amd.com            portConnect(ingress_router, "FlitIn" + (String)i, "IngressRouter_In" + (String)i);
23311308Santhony.gutierrez@amd.com        }
23411639Salexandru.dutu@amd.com        for(unsigned int i = 0; i < ingress_router_number_output_ports; ++i)
23511308Santhony.gutierrez@amd.com        {
23611639Salexandru.dutu@amd.com            // VFI
23711308Santhony.gutierrez@amd.com            portConnect(ingress_router, "FlitOut" + (String)i, "IngressToMiddleLink_In");
23811639Salexandru.dutu@amd.com        }
23911308Santhony.gutierrez@amd.com
24011308Santhony.gutierrez@amd.com        portConnect(middle_router, "CK", "CK");
24111639Salexandru.dutu@amd.com        for(unsigned int i = 0; i < middle_router_number_input_ports; ++i)
24211308Santhony.gutierrez@amd.com        {
24311639Salexandru.dutu@amd.com            createNet("MiddleRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1));
24411308Santhony.gutierrez@amd.com            for (unsigned int j = 0; j < number_bits_per_flit; ++j)
24511639Salexandru.dutu@amd.com                assignVirtualFanout("MiddleRouter_In" + (String)i, makeNetIndex(j), "IngressToMiddleLink_Out", makeNetIndex(j));
24611308Santhony.gutierrez@amd.com            portConnect(middle_router, "FlitIn" + (String)i, "MiddleRouter_In" + (String)i);
24711308Santhony.gutierrez@amd.com        }
24811639Salexandru.dutu@amd.com        for(unsigned int i = 0; i < middle_router_number_output_ports; ++i)
24911308Santhony.gutierrez@amd.com        {
25011308Santhony.gutierrez@amd.com            // VFI
25111639Salexandru.dutu@amd.com            portConnect(middle_router, "FlitOut" + (String)i, "MiddleToEgressLink_In");
25211639Salexandru.dutu@amd.com        }
25311308Santhony.gutierrez@amd.com
25411308Santhony.gutierrez@amd.com        portConnect(egress_router, "CK", "CK");
25511308Santhony.gutierrez@amd.com        for(unsigned int i = 0; i < egress_router_number_input_ports; ++i)
25611308Santhony.gutierrez@amd.com        {
25711308Santhony.gutierrez@amd.com            createNet("EgressRouter_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1));
25811308Santhony.gutierrez@amd.com            for (unsigned int j = 0; j < number_bits_per_flit; ++j)
25911308Santhony.gutierrez@amd.com                assignVirtualFanout("EgressRouter_In" + (String)i, makeNetIndex(j), "MiddleToEgressLink_Out", makeNetIndex(j));
26011308Santhony.gutierrez@amd.com            portConnect(egress_router, "FlitIn" + (String)i, "EgressRouter_In" + (String)i);
26111308Santhony.gutierrez@amd.com        }
26211308Santhony.gutierrez@amd.com        for(unsigned int i = 0; i < egress_router_number_output_ports; ++i)
26311308Santhony.gutierrez@amd.com        {
26411308Santhony.gutierrez@amd.com            // VFI
26511308Santhony.gutierrez@amd.com            portConnect(egress_router, "FlitOut" + (String)i, "EgressToOutputLink_In");
26611308Santhony.gutierrez@amd.com        }
26711308Santhony.gutierrez@amd.com
26811308Santhony.gutierrez@amd.com        // Create area, power, and event results
26911308Santhony.gutierrez@amd.com        createElectricalResults();
27011308Santhony.gutierrez@amd.com        createElectricalEventResult("AvgUnicast");
27111308Santhony.gutierrez@amd.com        createElectricalEventResult("AvgBroadcast");
27211308Santhony.gutierrez@amd.com
27311308Santhony.gutierrez@amd.com        // Add all instances
27411308Santhony.gutierrez@amd.com        addSubInstances(ingress_router, number_ingress_routers);
27511308Santhony.gutierrez@amd.com        addElectricalSubResults(ingress_router, number_ingress_routers);
27611308Santhony.gutierrez@amd.com        addSubInstances(middle_router, number_middle_routers);
27711308Santhony.gutierrez@amd.com        addElectricalSubResults(middle_router, number_middle_routers);
27811308Santhony.gutierrez@amd.com        addSubInstances(egress_router, number_egress_routers);
27911308Santhony.gutierrez@amd.com        addElectricalSubResults(egress_router, number_egress_routers);
28011308Santhony.gutierrez@amd.com        addSubInstances(input_to_ingress_link, number_input_to_ingress_links);
28111308Santhony.gutierrez@amd.com        addElectricalSubResults(input_to_ingress_link, number_input_to_ingress_links);
28211308Santhony.gutierrez@amd.com        addSubInstances(ingress_to_middle_link, number_ingress_to_middle_links);
28311308Santhony.gutierrez@amd.com        addElectricalSubResults(ingress_to_middle_link, number_ingress_to_middle_links);
28411308Santhony.gutierrez@amd.com        addSubInstances(middle_to_egress_link, number_middle_to_egress_links);
28511308Santhony.gutierrez@amd.com        addElectricalSubResults(middle_to_egress_link, number_middle_to_egress_links);
28611308Santhony.gutierrez@amd.com        addSubInstances(egress_to_output_link, number_egress_to_output_links);
28711308Santhony.gutierrez@amd.com        addElectricalSubResults(egress_to_output_link, number_egress_to_output_links);
28811308Santhony.gutierrez@amd.com
28911308Santhony.gutierrez@amd.com        // Update unicast event
29011308Santhony.gutierrez@amd.com        Result* avg_unicast_event = getEventResult("AvgUnicast");
29111308Santhony.gutierrez@amd.com        avg_unicast_event->addSubResult(input_to_ingress_link->getEventResult("Send"), "InputToIngressLink", 1.0);
29211308Santhony.gutierrez@amd.com        if(ingress_router->hasEventResult("WriteBuffer"))
29311308Santhony.gutierrez@amd.com        {
29411308Santhony.gutierrez@amd.com            avg_unicast_event->addSubResult(ingress_router->getEventResult("WriteBuffer"), "IngressRouter", 1.0);
29511308Santhony.gutierrez@amd.com        }
29611308Santhony.gutierrez@amd.com        if(ingress_router->hasEventResult("ReadBuffer"))
29711308Santhony.gutierrez@amd.com        {
29811308Santhony.gutierrez@amd.com            avg_unicast_event->addSubResult(ingress_router->getEventResult("ReadBuffer"), "IngressRouter", 1.0);
29911308Santhony.gutierrez@amd.com        }
30011534Sjohn.kalamatianos@amd.com        avg_unicast_event->addSubResult(ingress_router->getEventResult("TraverseCrossbar->Multicast1"), "IngressRouter", 1.0);
30111308Santhony.gutierrez@amd.com        avg_unicast_event->addSubResult(ingress_to_middle_link->getEventResult("Send"), "IngressToMiddleLink", 1.0);
30211534Sjohn.kalamatianos@amd.com        if(middle_router->hasEventResult("WriteBuffer"))
30311308Santhony.gutierrez@amd.com        {
30411308Santhony.gutierrez@amd.com            avg_unicast_event->addSubResult(middle_router->getEventResult("WriteBuffer"), "MiddleRouter", 1.0);
30511308Santhony.gutierrez@amd.com        }
30611308Santhony.gutierrez@amd.com        if(middle_router->hasEventResult("ReadBuffer"))
30711308Santhony.gutierrez@amd.com        {
30811308Santhony.gutierrez@amd.com            avg_unicast_event->addSubResult(middle_router->getEventResult("ReadBuffer"), "MiddleRouter", 1.0);
30911308Santhony.gutierrez@amd.com        }
31011308Santhony.gutierrez@amd.com        avg_unicast_event->addSubResult(middle_router->getEventResult("TraverseCrossbar->Multicast1"), "MiddleRouter", 1.0);
31111308Santhony.gutierrez@amd.com        avg_unicast_event->addSubResult(middle_to_egress_link->getEventResult("Send"), "MiddleToEgressLink", 1.0);
31211308Santhony.gutierrez@amd.com        if(egress_router->hasEventResult("WriteBuffer"))
31311308Santhony.gutierrez@amd.com        {
31411308Santhony.gutierrez@amd.com            avg_unicast_event->addSubResult(egress_router->getEventResult("WriteBuffer"), "EgressRouter", 1.0);
31511308Santhony.gutierrez@amd.com        }
31611308Santhony.gutierrez@amd.com        if(egress_router->hasEventResult("ReadBuffer"))
31711308Santhony.gutierrez@amd.com        {
31811308Santhony.gutierrez@amd.com            avg_unicast_event->addSubResult(egress_router->getEventResult("ReadBuffer"), "EgressRouter", 1.0);
31911308Santhony.gutierrez@amd.com        }
32011308Santhony.gutierrez@amd.com        avg_unicast_event->addSubResult(egress_router->getEventResult("TraverseCrossbar->Multicast1"), "EgressRouter", 1.0);
32111308Santhony.gutierrez@amd.com        avg_unicast_event->addSubResult(egress_to_output_link->getEventResult("Send"), "EgressToOutputLink", 1.0);
32211308Santhony.gutierrez@amd.com
32311308Santhony.gutierrez@amd.com        // Update broadcast event
32411308Santhony.gutierrez@amd.com        Result* avg_broadcast_event = getEventResult("AvgBroadcast");
32511308Santhony.gutierrez@amd.com        avg_broadcast_event->addSubResult(input_to_ingress_link->getEventResult("Send"), "InputToIngressLink", 1.0);
32611308Santhony.gutierrez@amd.com        if(ingress_router->hasEventResult("WriteBuffer"))
32711308Santhony.gutierrez@amd.com        {
32811308Santhony.gutierrez@amd.com            avg_broadcast_event->addSubResult(ingress_router->getEventResult("WriteBuffer"), "IngressRouter", 1.0);
32911308Santhony.gutierrez@amd.com        }
33011308Santhony.gutierrez@amd.com        if(ingress_router->hasEventResult("ReadBuffer"))
33111308Santhony.gutierrez@amd.com        {
33211308Santhony.gutierrez@amd.com            avg_broadcast_event->addSubResult(ingress_router->getEventResult("ReadBuffer"), "IngressRouter", 1.0);
33311308Santhony.gutierrez@amd.com        }
33411308Santhony.gutierrez@amd.com        avg_broadcast_event->addSubResult(ingress_router->getEventResult("TraverseCrossbar->Multicast1"), "IngressRouter", 1.0);
33511308Santhony.gutierrez@amd.com        avg_broadcast_event->addSubResult(ingress_to_middle_link->getEventResult("Send"), "IngressToMiddleLink", 1.0);
33611639Salexandru.dutu@amd.com        if(middle_router->hasEventResult("WriteBuffer"))
33711308Santhony.gutierrez@amd.com        {
33811308Santhony.gutierrez@amd.com            avg_broadcast_event->addSubResult(middle_router->getEventResult("WriteBuffer"), "MiddleRouter", 1.0);
33911308Santhony.gutierrez@amd.com        }
34011308Santhony.gutierrez@amd.com        if(middle_router->hasEventResult("ReadBuffer"))
34111308Santhony.gutierrez@amd.com        {
34211308Santhony.gutierrez@amd.com            avg_broadcast_event->addSubResult(middle_router->getEventResult("ReadBuffer"), "MiddleRouter", 1.0);
34311308Santhony.gutierrez@amd.com        }
34411308Santhony.gutierrez@amd.com        avg_broadcast_event->addSubResult(middle_router->getEventResult("TraverseCrossbar->Multicast1"), "MiddleRouter", 1.0);
34511308Santhony.gutierrez@amd.com        avg_broadcast_event->addSubResult(middle_to_egress_link->getEventResult("Send"), "MiddleToEgressLink", number_egress_routers);
34611308Santhony.gutierrez@amd.com        if(egress_router->hasEventResult("WriteBuffer"))
34711308Santhony.gutierrez@amd.com        {
34811308Santhony.gutierrez@amd.com            avg_broadcast_event->addSubResult(egress_router->getEventResult("WriteBuffer"), "EgressRouter", number_egress_routers);
34911308Santhony.gutierrez@amd.com        }
35011308Santhony.gutierrez@amd.com        if(egress_router->hasEventResult("ReadBuffer"))
35111308Santhony.gutierrez@amd.com        {
35211308Santhony.gutierrez@amd.com            avg_broadcast_event->addSubResult(egress_router->getEventResult("ReadBuffer"), "EgressRouter", number_egress_routers);
35311308Santhony.gutierrez@amd.com        }
35411308Santhony.gutierrez@amd.com        avg_broadcast_event->addSubResult(egress_router->getEventResult("TraverseCrossbar->Multicast" + (String)number_egress_routers), "EgressRouter", 1.0);
35511308Santhony.gutierrez@amd.com        avg_broadcast_event->addSubResult(egress_to_output_link->getEventResult("Send"), "EgressToOutputLink", number_output_sites);
35611308Santhony.gutierrez@amd.com        return;
35711308Santhony.gutierrez@amd.com    }
35811308Santhony.gutierrez@amd.com
35911308Santhony.gutierrez@amd.com    void ElectricalClos::updateModel()
36011308Santhony.gutierrez@amd.com    {
36111308Santhony.gutierrez@amd.com        // Get properties
36211308Santhony.gutierrez@amd.com        double input_site_pitch = getProperty("InputSitePitch").toDouble();
36311308Santhony.gutierrez@amd.com        double output_site_pitch = getProperty("OutputSitePitch").toDouble();
36411308Santhony.gutierrez@amd.com        double clock_freq = getParameter("Frequency");
36511308Santhony.gutierrez@amd.com
36611308Santhony.gutierrez@amd.com        ASSERT(input_site_pitch > 0, "[Error] " + getInstanceName() +
36711308Santhony.gutierrez@amd.com                " -> Input site pitch must be > 0!");
36811308Santhony.gutierrez@amd.com        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