Router.cc revision 10448
110448Snilay@cs.wisc.edu/* Copyright (c) 2012 Massachusetts Institute of Technology 210448Snilay@cs.wisc.edu * 310448Snilay@cs.wisc.edu * Permission is hereby granted, free of charge, to any person obtaining a copy 410448Snilay@cs.wisc.edu * of this software and associated documentation files (the "Software"), to deal 510448Snilay@cs.wisc.edu * in the Software without restriction, including without limitation the rights 610448Snilay@cs.wisc.edu * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 710448Snilay@cs.wisc.edu * copies of the Software, and to permit persons to whom the Software is 810448Snilay@cs.wisc.edu * furnished to do so, subject to the following conditions: 910448Snilay@cs.wisc.edu * 1010448Snilay@cs.wisc.edu * The above copyright notice and this permission notice shall be included in 1110448Snilay@cs.wisc.edu * all copies or substantial portions of the Software. 1210448Snilay@cs.wisc.edu * 1310448Snilay@cs.wisc.edu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1410448Snilay@cs.wisc.edu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1510448Snilay@cs.wisc.edu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1610448Snilay@cs.wisc.edu * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1710448Snilay@cs.wisc.edu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1810448Snilay@cs.wisc.edu * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 1910448Snilay@cs.wisc.edu * THE SOFTWARE. 2010448Snilay@cs.wisc.edu */ 2110448Snilay@cs.wisc.edu 2210447Snilay@cs.wisc.edu#include "model/electrical/router/Router.h" 2310447Snilay@cs.wisc.edu 2410447Snilay@cs.wisc.edu#include <cmath> 2510447Snilay@cs.wisc.edu#include <vector> 2610447Snilay@cs.wisc.edu 2710447Snilay@cs.wisc.edu#include "model/PortInfo.h" 2810447Snilay@cs.wisc.edu#include "model/EventInfo.h" 2910447Snilay@cs.wisc.edu#include "model/TransitionInfo.h" 3010447Snilay@cs.wisc.edu#include "model/ModelGen.h" 3110447Snilay@cs.wisc.edu#include "model/std_cells/StdCellLib.h" 3210447Snilay@cs.wisc.edu#include "model/std_cells/StdCell.h" 3310447Snilay@cs.wisc.edu#include "model/electrical/router/RouterInputPort.h" 3410447Snilay@cs.wisc.edu#include "model/electrical/router/RouterSwitchAllocator.h" 3510447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalNet.h" 3610447Snilay@cs.wisc.edu 3710447Snilay@cs.wisc.edunamespace DSENT 3810447Snilay@cs.wisc.edu{ 3910447Snilay@cs.wisc.edu using std::sqrt; 4010447Snilay@cs.wisc.edu using std::vector; 4110447Snilay@cs.wisc.edu 4210447Snilay@cs.wisc.edu using LibUtil::castStringVector; 4310447Snilay@cs.wisc.edu using LibUtil::vectorToString; 4410447Snilay@cs.wisc.edu 4510447Snilay@cs.wisc.edu Router::Router(const String& instance_name_, const TechModel* tech_model_) 4610447Snilay@cs.wisc.edu : ElectricalModel(instance_name_, tech_model_) 4710447Snilay@cs.wisc.edu { 4810447Snilay@cs.wisc.edu initParameters(); 4910447Snilay@cs.wisc.edu initProperties(); 5010447Snilay@cs.wisc.edu } 5110447Snilay@cs.wisc.edu 5210447Snilay@cs.wisc.edu Router::~Router() 5310447Snilay@cs.wisc.edu {} 5410447Snilay@cs.wisc.edu 5510447Snilay@cs.wisc.edu void Router::initParameters() 5610447Snilay@cs.wisc.edu { 5710447Snilay@cs.wisc.edu addParameterName("NumberInputPorts"); 5810447Snilay@cs.wisc.edu addParameterName("NumberOutputPorts"); 5910447Snilay@cs.wisc.edu addParameterName("NumberBitsPerFlit"); 6010447Snilay@cs.wisc.edu addParameterName("NumberVirtualNetworks"); 6110447Snilay@cs.wisc.edu addParameterName("NumberVirtualChannelsPerVirtualNetwork"); 6210447Snilay@cs.wisc.edu addParameterName("NumberBuffersPerVirtualChannel"); 6310447Snilay@cs.wisc.edu // Spec for input port 6410447Snilay@cs.wisc.edu addParameterName("InputPort->BufferModel"); 6510447Snilay@cs.wisc.edu // Spec for crossbar 6610447Snilay@cs.wisc.edu addParameterName("CrossbarModel"); 6710447Snilay@cs.wisc.edu // Spec for switch allocator 6810447Snilay@cs.wisc.edu addParameterName("SwitchAllocator->ArbiterModel"); 6910447Snilay@cs.wisc.edu // Spec for clock tree 7010447Snilay@cs.wisc.edu addParameterName("ClockTreeModel"); 7110447Snilay@cs.wisc.edu addParameterName("ClockTree->NumberLevels"); 7210447Snilay@cs.wisc.edu addParameterName("ClockTree->WireLayer"); 7310447Snilay@cs.wisc.edu addParameterName("ClockTree->WireWidthMultiplier"); 7410447Snilay@cs.wisc.edu addParameterName("ClockTree->WireSpacingMultiplier", 3.0); 7510447Snilay@cs.wisc.edu return; 7610447Snilay@cs.wisc.edu } 7710447Snilay@cs.wisc.edu 7810447Snilay@cs.wisc.edu void Router::initProperties() 7910447Snilay@cs.wisc.edu { 8010447Snilay@cs.wisc.edu return; 8110447Snilay@cs.wisc.edu } 8210447Snilay@cs.wisc.edu 8310447Snilay@cs.wisc.edu Router* Router::clone() const 8410447Snilay@cs.wisc.edu { 8510447Snilay@cs.wisc.edu // TODO 8610447Snilay@cs.wisc.edu return NULL; 8710447Snilay@cs.wisc.edu } 8810447Snilay@cs.wisc.edu 8910447Snilay@cs.wisc.edu void Router::constructModel() 9010447Snilay@cs.wisc.edu { 9110447Snilay@cs.wisc.edu // Get parameters 9210447Snilay@cs.wisc.edu unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); 9310447Snilay@cs.wisc.edu unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); 9410447Snilay@cs.wisc.edu unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); 9510447Snilay@cs.wisc.edu 9610447Snilay@cs.wisc.edu ASSERT(number_input_ports > 0, "[Error] " + getInstanceName() + 9710447Snilay@cs.wisc.edu " -> Number of input ports must be > 0!"); 9810447Snilay@cs.wisc.edu ASSERT(number_output_ports > 0, "[Error] " + getInstanceName() + 9910447Snilay@cs.wisc.edu " -> Number of output ports must be > 0!"); 10010447Snilay@cs.wisc.edu ASSERT(number_bits_per_flit > 0, "[Error] " + getInstanceName() + 10110447Snilay@cs.wisc.edu " -> Number of bits per buffer must be > 0!"); 10210447Snilay@cs.wisc.edu 10310447Snilay@cs.wisc.edu // Create ports 10410447Snilay@cs.wisc.edu createInputPort("CK"); 10510447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_input_ports; ++i) 10610447Snilay@cs.wisc.edu { 10710447Snilay@cs.wisc.edu createInputPort("FlitIn" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); 10810447Snilay@cs.wisc.edu } 10910447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_output_ports; ++i) 11010447Snilay@cs.wisc.edu { 11110447Snilay@cs.wisc.edu createOutputPort("FlitOut" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); 11210447Snilay@cs.wisc.edu } 11310447Snilay@cs.wisc.edu 11410447Snilay@cs.wisc.edu // Create area, power, event results 11510447Snilay@cs.wisc.edu createElectricalResults(); 11610447Snilay@cs.wisc.edu getEventInfo("Idle")->setStaticTransitionInfos(); 11710447Snilay@cs.wisc.edu getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); 11810447Snilay@cs.wisc.edu 11910447Snilay@cs.wisc.edu createElectricalEventResult("ReadBuffer"); 12010447Snilay@cs.wisc.edu getEventInfo("ReadBuffer")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); 12110447Snilay@cs.wisc.edu createElectricalEventResult("WriteBuffer"); 12210447Snilay@cs.wisc.edu getEventInfo("WriteBuffer")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); 12310447Snilay@cs.wisc.edu for(unsigned int i = 1; i <= number_output_ports; ++i) 12410447Snilay@cs.wisc.edu { 12510447Snilay@cs.wisc.edu createElectricalEventResult("TraverseCrossbar->Multicast" + (String)i); 12610447Snilay@cs.wisc.edu getEventInfo("TraverseCrossbar->Multicast" + (String)i)->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); 12710447Snilay@cs.wisc.edu } 12810447Snilay@cs.wisc.edu createElectricalEventResult("ArbitrateSwitch->ArbitrateStage1"); 12910447Snilay@cs.wisc.edu createElectricalEventResult("ArbitrateSwitch->ArbitrateStage2"); 13010447Snilay@cs.wisc.edu createElectricalEventResult("DistributeClock"); 13110447Snilay@cs.wisc.edu getEventInfo("DistributeClock")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); 13210447Snilay@cs.wisc.edu 13310447Snilay@cs.wisc.edu // Create intermediate nets 13410447Snilay@cs.wisc.edu createNet("PipelineReg0_In"); 13510447Snilay@cs.wisc.edu createNet("PipelineReg0_Out"); 13610447Snilay@cs.wisc.edu createNet("PipelineReg1_In"); 13710447Snilay@cs.wisc.edu createNet("PipelineReg1_Out"); 13810447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_output_ports; ++i) 13910447Snilay@cs.wisc.edu { 14010447Snilay@cs.wisc.edu createNet("PipelineReg2_In" + (String)i); 14110447Snilay@cs.wisc.edu createNet("PipelineReg2_Out" + (String)i); 14210447Snilay@cs.wisc.edu } 14310447Snilay@cs.wisc.edu 14410447Snilay@cs.wisc.edu createRouterInputPort(); 14510447Snilay@cs.wisc.edu createSwitchAllocator(); 14610447Snilay@cs.wisc.edu createVirtualChannelAllocator(); 14710447Snilay@cs.wisc.edu createCrossbar(); 14810447Snilay@cs.wisc.edu createClockTree(); 14910447Snilay@cs.wisc.edu createPipelineReg(); 15010447Snilay@cs.wisc.edu 15110447Snilay@cs.wisc.edu // Get generated numbers 15210447Snilay@cs.wisc.edu unsigned int number_crossbar_selects = getGenProperties()->get("Crossbar->NumberSelects"); 15310447Snilay@cs.wisc.edu 15410447Snilay@cs.wisc.edu // Add write buffer event 15510447Snilay@cs.wisc.edu getEventResult("WriteBuffer")->addSubResult(getSubInstance("PipelineReg0")->getEventResult("DFFD"), "PipelineReg0", number_bits_per_flit); 15610447Snilay@cs.wisc.edu getEventResult("WriteBuffer")->addSubResult(getSubInstance("PipelineReg0")->getEventResult("DFFQ"), "PipelineReg0", number_bits_per_flit); 15710447Snilay@cs.wisc.edu getEventResult("WriteBuffer")->addSubResult(getSubInstance("PipelineReg0")->getEventResult("CK"), "PipelineReg0", number_bits_per_flit); 15810447Snilay@cs.wisc.edu getEventResult("WriteBuffer")->addSubResult(getSubInstance("InputPort")->getEventResult("WriteBuffer"), "InputPort", 1.0); 15910447Snilay@cs.wisc.edu 16010447Snilay@cs.wisc.edu // Add read buffer event 16110447Snilay@cs.wisc.edu getEventResult("ReadBuffer")->addSubResult(getSubInstance("InputPort")->getEventResult("ReadBuffer"), "InputPort", 1.0); 16210447Snilay@cs.wisc.edu getEventResult("ReadBuffer")->addSubResult(getSubInstance("PipelineReg1")->getEventResult("DFFD"), "PipelineReg1", number_bits_per_flit); 16310447Snilay@cs.wisc.edu getEventResult("ReadBuffer")->addSubResult(getSubInstance("PipelineReg1")->getEventResult("DFFQ"), "PipelineReg1", number_bits_per_flit); 16410447Snilay@cs.wisc.edu getEventResult("ReadBuffer")->addSubResult(getSubInstance("PipelineReg1")->getEventResult("CK"), "PipelineReg1", number_bits_per_flit); 16510447Snilay@cs.wisc.edu 16610447Snilay@cs.wisc.edu // Add crossbar traversal event 16710447Snilay@cs.wisc.edu for(unsigned int i = 1; i <= number_output_ports; ++i) 16810447Snilay@cs.wisc.edu { 16910447Snilay@cs.wisc.edu Result* traverse_crossbar_event = getEventResult("TraverseCrossbar->Multicast" + (String)i); 17010447Snilay@cs.wisc.edu traverse_crossbar_event->addSubResult(getSubInstance("Crossbar_Sel_DFF")->getEventResult("DFFD"), "Crossbar_Sel_DFF", number_crossbar_selects); 17110447Snilay@cs.wisc.edu traverse_crossbar_event->addSubResult(getSubInstance("Crossbar_Sel_DFF")->getEventResult("DFFQ"), "Crossbar_Sel_DFF", number_crossbar_selects); 17210447Snilay@cs.wisc.edu traverse_crossbar_event->addSubResult(getSubInstance("Crossbar_Sel_DFF")->getEventResult("CK"), "Crossbar_Sel_DFF", number_crossbar_selects); 17310447Snilay@cs.wisc.edu traverse_crossbar_event->addSubResult(getSubInstance("Crossbar")->getEventResult("Multicast" + (String)i), "Crossbar", 1.0); 17410447Snilay@cs.wisc.edu for(unsigned int j = 0; j < i; ++j) 17510447Snilay@cs.wisc.edu { 17610447Snilay@cs.wisc.edu traverse_crossbar_event->addSubResult(getSubInstance("PipelineReg2_" + (String)j)->getEventResult("DFFD"), "PipelineReg2_" + (String)j, number_bits_per_flit); 17710447Snilay@cs.wisc.edu traverse_crossbar_event->addSubResult(getSubInstance("PipelineReg2_" + (String)j)->getEventResult("DFFQ"), "PipelineReg2_" + (String)j, number_bits_per_flit); 17810447Snilay@cs.wisc.edu traverse_crossbar_event->addSubResult(getSubInstance("PipelineReg2_" + (String)j)->getEventResult("CK"), "PipelineReg2_" + (String)j, number_bits_per_flit); 17910447Snilay@cs.wisc.edu } 18010447Snilay@cs.wisc.edu } 18110447Snilay@cs.wisc.edu 18210447Snilay@cs.wisc.edu // Add stage1 allocator arbitrate 18310447Snilay@cs.wisc.edu Result* arb_sw_stage1_event = getEventResult("ArbitrateSwitch->ArbitrateStage1"); 18410447Snilay@cs.wisc.edu arb_sw_stage1_event->addSubResult(getSubInstance("SwitchAllocator")->getEventResult("ArbitrateStage1"), "SwitchAllocator", 1.0); 18510447Snilay@cs.wisc.edu 18610447Snilay@cs.wisc.edu // Add stage2 allocator arbitrate 18710447Snilay@cs.wisc.edu Result* arb_sw_stage2_event = getEventResult("ArbitrateSwitch->ArbitrateStage2"); 18810447Snilay@cs.wisc.edu arb_sw_stage2_event->addSubResult(getSubInstance("SwitchAllocator")->getEventResult("ArbitrateStage2"), "SwitchAllocator", 1.0); 18910447Snilay@cs.wisc.edu 19010447Snilay@cs.wisc.edu // Add CK event 19110447Snilay@cs.wisc.edu getEventResult("DistributeClock")->addSubResult(getSubInstance("ClockTree")->getEventResult("Send"), "ClockTree", 1.0); 19210447Snilay@cs.wisc.edu return; 19310447Snilay@cs.wisc.edu } 19410447Snilay@cs.wisc.edu 19510447Snilay@cs.wisc.edu void Router::updateModel() 19610447Snilay@cs.wisc.edu { 19710447Snilay@cs.wisc.edu // Get parameters 19810447Snilay@cs.wisc.edu unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); 19910447Snilay@cs.wisc.edu 20010447Snilay@cs.wisc.edu // Update other components 20110447Snilay@cs.wisc.edu getSubInstance("PipelineReg0")->update(); 20210447Snilay@cs.wisc.edu getSubInstance("InputPort")->update(); 20310447Snilay@cs.wisc.edu getSubInstance("PipelineReg1")->update(); 20410447Snilay@cs.wisc.edu getSubInstance("Crossbar_Sel_DFF")->update(); 20510447Snilay@cs.wisc.edu getSubInstance("Crossbar")->update(); 20610447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_output_ports; ++i) 20710447Snilay@cs.wisc.edu { 20810447Snilay@cs.wisc.edu getSubInstance("PipelineReg2_" + (String)i)->update(); 20910447Snilay@cs.wisc.edu } 21010447Snilay@cs.wisc.edu getSubInstance("SwitchAllocator")->update(); 21110447Snilay@cs.wisc.edu 21210447Snilay@cs.wisc.edu // Update clock tree 21310447Snilay@cs.wisc.edu double total_clock_tree_cap = getNet("CK")->getTotalDownstreamCap(); 21410447Snilay@cs.wisc.edu double router_area = getAreaResult("Active")->calculateSum(); 21510447Snilay@cs.wisc.edu Model* clock_tree = getSubInstance("ClockTree"); 21610447Snilay@cs.wisc.edu clock_tree->setProperty("SitePitch", sqrt(router_area)); 21710447Snilay@cs.wisc.edu clock_tree->setProperty("TotalLoadCapPerBit", total_clock_tree_cap); 21810447Snilay@cs.wisc.edu clock_tree->update(); 21910447Snilay@cs.wisc.edu 22010447Snilay@cs.wisc.edu return; 22110447Snilay@cs.wisc.edu } 22210447Snilay@cs.wisc.edu 22310447Snilay@cs.wisc.edu void Router::propagateTransitionInfo() 22410447Snilay@cs.wisc.edu { 22510447Snilay@cs.wisc.edu // Update probability 22610447Snilay@cs.wisc.edu unsigned int number_output_ports = getParameter("NumberOutputPorts"); 22710447Snilay@cs.wisc.edu 22810447Snilay@cs.wisc.edu // Current event 22910447Snilay@cs.wisc.edu const String& current_event = getGenProperties()->get("UseModelEvent"); 23010447Snilay@cs.wisc.edu 23110447Snilay@cs.wisc.edu ElectricalModel* pipeline_reg0 = (ElectricalModel*)getSubInstance("PipelineReg0"); 23210447Snilay@cs.wisc.edu propagatePortTransitionInfo(pipeline_reg0, "D", "FlitIn0"); 23310447Snilay@cs.wisc.edu propagatePortTransitionInfo(pipeline_reg0, "CK", "CK"); 23410447Snilay@cs.wisc.edu pipeline_reg0->use(); 23510447Snilay@cs.wisc.edu 23610447Snilay@cs.wisc.edu ElectricalModel* input_port = (ElectricalModel*)getSubInstance("InputPort"); 23710447Snilay@cs.wisc.edu propagatePortTransitionInfo(input_port, "FlitIn", pipeline_reg0, "Q"); 23810447Snilay@cs.wisc.edu propagatePortTransitionInfo(input_port, "CK", "CK"); 23910447Snilay@cs.wisc.edu input_port->getGenProperties()->set("UseModelEvent", "ReadWrite"); 24010447Snilay@cs.wisc.edu input_port->use(); 24110447Snilay@cs.wisc.edu 24210447Snilay@cs.wisc.edu ElectricalModel* pipeline_reg1 = (ElectricalModel*)getSubInstance("PipelineReg1"); 24310447Snilay@cs.wisc.edu propagatePortTransitionInfo(pipeline_reg1, "D", "FlitIn0"); 24410447Snilay@cs.wisc.edu propagatePortTransitionInfo(pipeline_reg1, "CK", "CK"); 24510447Snilay@cs.wisc.edu pipeline_reg1->use(); 24610447Snilay@cs.wisc.edu 24710447Snilay@cs.wisc.edu ElectricalModel* crossbar_sel_dff = (ElectricalModel*)getSubInstance("Crossbar_Sel_DFF"); 24810447Snilay@cs.wisc.edu assignPortTransitionInfo(crossbar_sel_dff, "D", TransitionInfo()); 24910447Snilay@cs.wisc.edu propagatePortTransitionInfo(crossbar_sel_dff, "CK", "CK"); 25010447Snilay@cs.wisc.edu crossbar_sel_dff->use(); 25110447Snilay@cs.wisc.edu 25210447Snilay@cs.wisc.edu ElectricalModel* crossbar = (ElectricalModel*)getSubInstance("Crossbar"); 25310447Snilay@cs.wisc.edu bool is_crossbar_event = false; 25410447Snilay@cs.wisc.edu for(unsigned int i = 1; i <= number_output_ports; ++i) 25510447Snilay@cs.wisc.edu { 25610447Snilay@cs.wisc.edu if(current_event == ("TraverseCrossbar->Multicast" + (String)i)) 25710447Snilay@cs.wisc.edu { 25810447Snilay@cs.wisc.edu is_crossbar_event = true; 25910447Snilay@cs.wisc.edu // Assume the flit is sent from port 0 to port 0~i-1 26010447Snilay@cs.wisc.edu // Apply default transition info 26110447Snilay@cs.wisc.edu crossbar->applyTransitionInfo("Multicast" + (String)i); 26210447Snilay@cs.wisc.edu // Overwrite transition info 26310447Snilay@cs.wisc.edu propagatePortTransitionInfo(crossbar, "In0", "FlitIn0"); 26410447Snilay@cs.wisc.edu break; 26510447Snilay@cs.wisc.edu } 26610447Snilay@cs.wisc.edu } 26710447Snilay@cs.wisc.edu if(is_crossbar_event == false) 26810447Snilay@cs.wisc.edu { 26910447Snilay@cs.wisc.edu crossbar->applyTransitionInfo("Multicast1"); 27010447Snilay@cs.wisc.edu propagatePortTransitionInfo(crossbar, "In0", "FlitIn0"); 27110447Snilay@cs.wisc.edu } 27210447Snilay@cs.wisc.edu crossbar->use(); 27310447Snilay@cs.wisc.edu 27410447Snilay@cs.wisc.edu vector<ElectricalModel*> pipeline_reg2s(number_output_ports, NULL); 27510447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_output_ports; ++i) 27610447Snilay@cs.wisc.edu { 27710447Snilay@cs.wisc.edu pipeline_reg2s[i] = (ElectricalModel*)getSubInstance("PipelineReg2_" + (String)i); 27810447Snilay@cs.wisc.edu propagatePortTransitionInfo(pipeline_reg2s[i], "D", "FlitIn0"); 27910447Snilay@cs.wisc.edu propagatePortTransitionInfo(pipeline_reg2s[i], "CK", "CK"); 28010447Snilay@cs.wisc.edu pipeline_reg2s[i]->use(); 28110447Snilay@cs.wisc.edu } 28210447Snilay@cs.wisc.edu 28310447Snilay@cs.wisc.edu ElectricalModel* sw_allocator = (ElectricalModel*)getSubInstance("SwitchAllocator"); 28410447Snilay@cs.wisc.edu if(current_event == "ArbitrateSwitch->ArbitrateStage1") 28510447Snilay@cs.wisc.edu { 28610447Snilay@cs.wisc.edu sw_allocator->applyTransitionInfo("ArbitrateStage1"); 28710447Snilay@cs.wisc.edu } 28810447Snilay@cs.wisc.edu else if(current_event == "ArbitrateSwitch->ArbitrateStage2") 28910447Snilay@cs.wisc.edu { 29010447Snilay@cs.wisc.edu sw_allocator->applyTransitionInfo("ArbitrateStage2"); 29110447Snilay@cs.wisc.edu } 29210447Snilay@cs.wisc.edu else 29310447Snilay@cs.wisc.edu { 29410447Snilay@cs.wisc.edu sw_allocator->applyTransitionInfo("Idle"); 29510447Snilay@cs.wisc.edu } 29610447Snilay@cs.wisc.edu sw_allocator->use(); 29710447Snilay@cs.wisc.edu 29810447Snilay@cs.wisc.edu ElectricalModel* clock_tree = (ElectricalModel*)getSubInstance("ClockTree"); 29910447Snilay@cs.wisc.edu propagatePortTransitionInfo(clock_tree, "In", "CK"); 30010447Snilay@cs.wisc.edu clock_tree->use(); 30110447Snilay@cs.wisc.edu return; 30210447Snilay@cs.wisc.edu } 30310447Snilay@cs.wisc.edu 30410447Snilay@cs.wisc.edu void Router::createRouterInputPort() 30510447Snilay@cs.wisc.edu { 30610447Snilay@cs.wisc.edu // Get parameters 30710447Snilay@cs.wisc.edu unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); 30810447Snilay@cs.wisc.edu unsigned int number_vns = getParameter("NumberVirtualNetworks").toUInt(); 30910447Snilay@cs.wisc.edu const String& number_vcs_per_vn = getParameter("NumberVirtualChannelsPerVirtualNetwork"); 31010447Snilay@cs.wisc.edu const String& number_bufs_per_vc = getParameter("NumberBuffersPerVirtualChannel"); 31110447Snilay@cs.wisc.edu unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); 31210447Snilay@cs.wisc.edu const String& buffer_model = getParameter("InputPort->BufferModel"); 31310447Snilay@cs.wisc.edu 31410447Snilay@cs.wisc.edu // Init input port model 31510447Snilay@cs.wisc.edu const String& input_port_name = "InputPort"; 31610447Snilay@cs.wisc.edu RouterInputPort* input_port = new RouterInputPort(input_port_name, getTechModel()); 31710447Snilay@cs.wisc.edu input_port->setParameter("NumberVirtualNetworks", number_vns); 31810447Snilay@cs.wisc.edu input_port->setParameter("NumberVirtualChannelsPerVirtualNetwork", number_vcs_per_vn); 31910447Snilay@cs.wisc.edu input_port->setParameter("NumberBuffersPerVirtualChannel", number_bufs_per_vc); 32010447Snilay@cs.wisc.edu input_port->setParameter("NumberBitsPerFlit", number_bits_per_flit); 32110447Snilay@cs.wisc.edu input_port->setParameter("BufferModel", buffer_model); 32210447Snilay@cs.wisc.edu input_port->construct(); 32310447Snilay@cs.wisc.edu 32410447Snilay@cs.wisc.edu unsigned int number_input_port_outputs = input_port->getGenProperties()->get("NumberOutputs"); 32510447Snilay@cs.wisc.edu unsigned int number_input_port_addr_bits = input_port->getGenProperties()->get("NumberAddressBits"); 32610447Snilay@cs.wisc.edu getGenProperties()->set("InputPort->NumberOutputs", number_input_port_outputs); 32710447Snilay@cs.wisc.edu getGenProperties()->set("InputPort->NumberAddressBits", number_input_port_addr_bits); 32810447Snilay@cs.wisc.edu 32910447Snilay@cs.wisc.edu unsigned int total_number_vcs = input_port->getGenProperties()->get("TotalNumberVirtualChannels"); 33010447Snilay@cs.wisc.edu getGenProperties()->set("TotalNumberVirtualChannels", total_number_vcs); 33110447Snilay@cs.wisc.edu 33210447Snilay@cs.wisc.edu // Add the instance and the results 33310447Snilay@cs.wisc.edu addSubInstances(input_port, number_input_ports); 33410447Snilay@cs.wisc.edu addElectricalSubResults(input_port, number_input_ports); 33510447Snilay@cs.wisc.edu 33610447Snilay@cs.wisc.edu // Create connections 33710447Snilay@cs.wisc.edu createNet("InputPort_In", makeNetIndex(0, number_bits_per_flit-1)); 33810447Snilay@cs.wisc.edu createNet("InputPort_Out", makeNetIndex(0, number_bits_per_flit-1)); 33910447Snilay@cs.wisc.edu 34010447Snilay@cs.wisc.edu assignVirtualFanout("InputPort_In", "PipelineReg0_Out"); 34110447Snilay@cs.wisc.edu portConnect(input_port, "FlitIn", "InputPort_In"); 34210447Snilay@cs.wisc.edu portConnect(input_port, "CK", "CK"); 34310447Snilay@cs.wisc.edu portConnect(input_port, "FlitOut", "InputPort_Out"); 34410447Snilay@cs.wisc.edu assignVirtualFanin("PipelineReg1_In", "InputPort_Out"); 34510447Snilay@cs.wisc.edu 34610447Snilay@cs.wisc.edu return; 34710447Snilay@cs.wisc.edu } 34810447Snilay@cs.wisc.edu 34910447Snilay@cs.wisc.edu void Router::createVirtualChannelAllocator() 35010447Snilay@cs.wisc.edu {} 35110447Snilay@cs.wisc.edu 35210447Snilay@cs.wisc.edu void Router::createSwitchAllocator() 35310447Snilay@cs.wisc.edu { 35410447Snilay@cs.wisc.edu // Get parameters 35510447Snilay@cs.wisc.edu unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); 35610447Snilay@cs.wisc.edu unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); 35710447Snilay@cs.wisc.edu unsigned int total_number_vcs = getGenProperties()->get("TotalNumberVirtualChannels").toUInt(); 35810447Snilay@cs.wisc.edu const String& arb_model = getParameter("SwitchAllocator->ArbiterModel"); 35910447Snilay@cs.wisc.edu 36010447Snilay@cs.wisc.edu // Init switch allocator model 36110447Snilay@cs.wisc.edu const String& sw_allocator_name = "SwitchAllocator"; 36210447Snilay@cs.wisc.edu RouterSwitchAllocator* sw_allocator = new RouterSwitchAllocator(sw_allocator_name, getTechModel()); 36310447Snilay@cs.wisc.edu sw_allocator->setParameter("NumberInputPorts", number_input_ports); 36410447Snilay@cs.wisc.edu sw_allocator->setParameter("NumberOutputPorts", number_output_ports); 36510447Snilay@cs.wisc.edu sw_allocator->setParameter("TotalNumberVirtualChannels", total_number_vcs); 36610447Snilay@cs.wisc.edu sw_allocator->setParameter("ArbiterModel", arb_model); 36710447Snilay@cs.wisc.edu sw_allocator->construct(); 36810447Snilay@cs.wisc.edu 36910447Snilay@cs.wisc.edu // Add the instance and the results 37010447Snilay@cs.wisc.edu addSubInstances(sw_allocator, 1.0); 37110447Snilay@cs.wisc.edu addElectricalSubResults(sw_allocator, 1.0); 37210447Snilay@cs.wisc.edu 37310447Snilay@cs.wisc.edu // Create connections (currently connect CK only) 37410447Snilay@cs.wisc.edu portConnect(sw_allocator, "CK", "CK"); 37510447Snilay@cs.wisc.edu return; 37610447Snilay@cs.wisc.edu } 37710447Snilay@cs.wisc.edu 37810447Snilay@cs.wisc.edu void Router::createCrossbar() 37910447Snilay@cs.wisc.edu { 38010447Snilay@cs.wisc.edu // Get parameters 38110447Snilay@cs.wisc.edu const String& crossbar_model = getParameter("CrossbarModel"); 38210447Snilay@cs.wisc.edu unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); 38310447Snilay@cs.wisc.edu unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); 38410447Snilay@cs.wisc.edu unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); 38510447Snilay@cs.wisc.edu unsigned int number_input_port_outputs = getGenProperties()->get("InputPort->NumberOutputs").toUInt(); 38610447Snilay@cs.wisc.edu 38710447Snilay@cs.wisc.edu unsigned int number_crossbar_inputs = number_input_port_outputs * number_input_ports; 38810447Snilay@cs.wisc.edu unsigned int number_crossbar_outputs = number_output_ports; 38910447Snilay@cs.wisc.edu getGenProperties()->set("Crossbar->NumberInputs", number_crossbar_inputs); 39010447Snilay@cs.wisc.edu getGenProperties()->set("Crossbar->NumberOutputs", number_crossbar_outputs); 39110447Snilay@cs.wisc.edu 39210447Snilay@cs.wisc.edu // Init crossbar model 39310447Snilay@cs.wisc.edu const String& crossbar_name = "Crossbar"; 39410447Snilay@cs.wisc.edu ElectricalModel* crossbar = ModelGen::createCrossbar(crossbar_model, crossbar_name, getTechModel()); 39510447Snilay@cs.wisc.edu crossbar->setParameter("NumberInputs", number_crossbar_inputs); 39610447Snilay@cs.wisc.edu crossbar->setParameter("NumberOutputs", number_crossbar_outputs); 39710447Snilay@cs.wisc.edu crossbar->setParameter("NumberBits", number_bits_per_flit); 39810447Snilay@cs.wisc.edu crossbar->setParameter("BitDuplicate", "TRUE"); 39910447Snilay@cs.wisc.edu crossbar->construct(); 40010447Snilay@cs.wisc.edu 40110447Snilay@cs.wisc.edu unsigned int number_crossbar_selects = crossbar->getGenProperties()->get("NumberSelectsPerPort"); 40210447Snilay@cs.wisc.edu getGenProperties()->set("Crossbar->NumberSelects", number_crossbar_selects); 40310447Snilay@cs.wisc.edu 40410447Snilay@cs.wisc.edu // Init DFF for crossbar selections 40510447Snilay@cs.wisc.edu const String& crossbar_sel_dff_name = "Crossbar_Sel_DFF"; 40610447Snilay@cs.wisc.edu StdCell* crossbar_sel_dff = getTechModel()->getStdCellLib()->createStdCell("DFFQ", crossbar_sel_dff_name); 40710447Snilay@cs.wisc.edu crossbar_sel_dff->construct(); 40810447Snilay@cs.wisc.edu 40910447Snilay@cs.wisc.edu // Add instances and results 41010447Snilay@cs.wisc.edu addSubInstances(crossbar, 1.0); 41110447Snilay@cs.wisc.edu addElectricalSubResults(crossbar, 1.0); 41210447Snilay@cs.wisc.edu 41310447Snilay@cs.wisc.edu addSubInstances(crossbar_sel_dff, number_crossbar_outputs * number_crossbar_selects); 41410447Snilay@cs.wisc.edu addElectricalSubResults(crossbar_sel_dff, number_crossbar_outputs * number_crossbar_selects); 41510447Snilay@cs.wisc.edu 41610447Snilay@cs.wisc.edu // Create connections 41710447Snilay@cs.wisc.edu createNet("Crossbar_Sel_DFF_Out"); 41810447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_crossbar_outputs; ++i) 41910447Snilay@cs.wisc.edu { 42010447Snilay@cs.wisc.edu for(unsigned int j = 0; j < number_crossbar_selects; ++j) 42110447Snilay@cs.wisc.edu { 42210447Snilay@cs.wisc.edu createNet(String::format("Crossbar_Sel%d_%d", i, j)); 42310447Snilay@cs.wisc.edu } 42410447Snilay@cs.wisc.edu createNet("Crossbar_Out" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); 42510447Snilay@cs.wisc.edu } 42610447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_crossbar_inputs; ++i) 42710447Snilay@cs.wisc.edu { 42810447Snilay@cs.wisc.edu createNet("Crossbar_In" + (String)i, makeNetIndex(0, number_bits_per_flit-1)); 42910447Snilay@cs.wisc.edu } 43010447Snilay@cs.wisc.edu 43110447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_crossbar_selects; ++i) 43210447Snilay@cs.wisc.edu { 43310447Snilay@cs.wisc.edu portConnect(crossbar_sel_dff, "CK", "CK"); 43410447Snilay@cs.wisc.edu } 43510447Snilay@cs.wisc.edu portConnect(crossbar_sel_dff, "Q", "Crossbar_Sel_DFF_Out"); 43610447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_crossbar_inputs; ++i) 43710447Snilay@cs.wisc.edu { 43810447Snilay@cs.wisc.edu assignVirtualFanout("Crossbar_In" + (String)i, "PipelineReg1_Out"); 43910447Snilay@cs.wisc.edu portConnect(crossbar, "In" + (String)i, "Crossbar_In" + (String)i); 44010447Snilay@cs.wisc.edu } 44110447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_crossbar_outputs; ++i) 44210447Snilay@cs.wisc.edu { 44310447Snilay@cs.wisc.edu for(unsigned int j = 0; j < number_crossbar_selects; ++j) 44410447Snilay@cs.wisc.edu { 44510447Snilay@cs.wisc.edu assignVirtualFanout(String::format("Crossbar_Sel%d_%d", i, j), "Crossbar_Sel_DFF_Out"); 44610447Snilay@cs.wisc.edu portConnect(crossbar, String::format("Sel%d_%d", i, j), String::format("Crossbar_Sel%d_%d", i, j)); 44710447Snilay@cs.wisc.edu } 44810447Snilay@cs.wisc.edu portConnect(crossbar, "Out" + (String)i, "Crossbar_Out" + (String)i); 44910447Snilay@cs.wisc.edu assignVirtualFanin("PipelineReg2_In" + (String)i, "Crossbar_Out" + (String)i); 45010447Snilay@cs.wisc.edu } 45110447Snilay@cs.wisc.edu 45210447Snilay@cs.wisc.edu return; 45310447Snilay@cs.wisc.edu } 45410447Snilay@cs.wisc.edu 45510447Snilay@cs.wisc.edu void Router::createPipelineReg() 45610447Snilay@cs.wisc.edu { 45710447Snilay@cs.wisc.edu // Get parameters 45810447Snilay@cs.wisc.edu unsigned int number_input_ports = getParameter("NumberInputPorts").toUInt(); 45910447Snilay@cs.wisc.edu unsigned int number_output_ports = getParameter("NumberOutputPorts").toUInt(); 46010447Snilay@cs.wisc.edu unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); 46110447Snilay@cs.wisc.edu unsigned int number_crossbar_inputs = getGenProperties()->get("Crossbar->NumberInputs"); 46210447Snilay@cs.wisc.edu 46310447Snilay@cs.wisc.edu // Init pipeline reg model 46410447Snilay@cs.wisc.edu // First stage: from router input to input port 46510447Snilay@cs.wisc.edu const String& pipeline_reg0_name = "PipelineReg0"; 46610447Snilay@cs.wisc.edu StdCell* pipeline_reg0 = getTechModel()->getStdCellLib()->createStdCell("DFFQ", pipeline_reg0_name); 46710447Snilay@cs.wisc.edu pipeline_reg0->construct(); 46810447Snilay@cs.wisc.edu // Second stage: from input port to crossbar 46910447Snilay@cs.wisc.edu const String& pipeline_reg1_name = "PipelineReg1"; 47010447Snilay@cs.wisc.edu StdCell* pipeline_reg1 = getTechModel()->getStdCellLib()->createStdCell("DFFQ", pipeline_reg1_name); 47110447Snilay@cs.wisc.edu pipeline_reg1->construct(); 47210447Snilay@cs.wisc.edu 47310447Snilay@cs.wisc.edu // Third stage: from crossbar to router output 47410447Snilay@cs.wisc.edu vector<StdCell*> pipeline_reg2s(number_output_ports, (StdCell*)NULL); 47510447Snilay@cs.wisc.edu vector<String> pipeline_reg2_names(number_output_ports, ""); 47610447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_output_ports; ++i) 47710447Snilay@cs.wisc.edu { 47810447Snilay@cs.wisc.edu pipeline_reg2_names[i] = "PipelineReg2_" + (String)i; 47910447Snilay@cs.wisc.edu pipeline_reg2s[i] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", pipeline_reg2_names[i]); 48010447Snilay@cs.wisc.edu pipeline_reg2s[i]->construct(); 48110447Snilay@cs.wisc.edu } 48210447Snilay@cs.wisc.edu 48310447Snilay@cs.wisc.edu // Add instances and results 48410447Snilay@cs.wisc.edu addSubInstances(pipeline_reg0, number_input_ports * number_bits_per_flit); 48510447Snilay@cs.wisc.edu addElectricalSubResults(pipeline_reg0, number_input_ports * number_bits_per_flit); 48610447Snilay@cs.wisc.edu 48710447Snilay@cs.wisc.edu addSubInstances(pipeline_reg1, number_crossbar_inputs * number_bits_per_flit); 48810447Snilay@cs.wisc.edu addElectricalSubResults(pipeline_reg1, number_crossbar_inputs * number_bits_per_flit); 48910447Snilay@cs.wisc.edu 49010447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_output_ports; ++i) 49110447Snilay@cs.wisc.edu { 49210447Snilay@cs.wisc.edu addSubInstances(pipeline_reg2s[i], number_bits_per_flit); 49310447Snilay@cs.wisc.edu addElectricalSubResults(pipeline_reg2s[i], number_bits_per_flit); 49410447Snilay@cs.wisc.edu } 49510447Snilay@cs.wisc.edu 49610447Snilay@cs.wisc.edu // Create data connections 49710447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_input_ports; ++i) 49810447Snilay@cs.wisc.edu { 49910447Snilay@cs.wisc.edu assignVirtualFanin("PipelineReg0_In", "FlitIn" + (String)i); 50010447Snilay@cs.wisc.edu } 50110447Snilay@cs.wisc.edu portConnect(pipeline_reg0, "D", "PipelineReg0_In"); 50210447Snilay@cs.wisc.edu portConnect(pipeline_reg0, "Q", "PipelineReg0_Out"); 50310447Snilay@cs.wisc.edu portConnect(pipeline_reg1, "D", "PipelineReg1_In"); 50410447Snilay@cs.wisc.edu portConnect(pipeline_reg1, "Q", "PipelineReg1_Out"); 50510447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_output_ports; ++i) 50610447Snilay@cs.wisc.edu { 50710447Snilay@cs.wisc.edu portConnect(pipeline_reg2s[i], "D", "PipelineReg2_In" + (String)i); 50810447Snilay@cs.wisc.edu portConnect(pipeline_reg2s[i], "Q", "PipelineReg2_Out" + (String)i); 50910447Snilay@cs.wisc.edu assignVirtualFanout("FlitOut" + (String)i, "PipelineReg2_Out" + (String)i); 51010447Snilay@cs.wisc.edu } 51110447Snilay@cs.wisc.edu 51210447Snilay@cs.wisc.edu // Create CK connections 51310447Snilay@cs.wisc.edu for(unsigned int n = 0; n < number_bits_per_flit; ++n) 51410447Snilay@cs.wisc.edu { 51510447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_input_ports; ++i) 51610447Snilay@cs.wisc.edu { 51710447Snilay@cs.wisc.edu portConnect(pipeline_reg0, "CK", "CK"); 51810447Snilay@cs.wisc.edu } 51910447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_crossbar_inputs; ++i) 52010447Snilay@cs.wisc.edu { 52110447Snilay@cs.wisc.edu portConnect(pipeline_reg1, "CK", "CK"); 52210447Snilay@cs.wisc.edu } 52310447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_output_ports; ++i) 52410447Snilay@cs.wisc.edu { 52510447Snilay@cs.wisc.edu portConnect(pipeline_reg2s[i], "CK", "CK"); 52610447Snilay@cs.wisc.edu } 52710447Snilay@cs.wisc.edu } 52810447Snilay@cs.wisc.edu return; 52910447Snilay@cs.wisc.edu } 53010447Snilay@cs.wisc.edu 53110447Snilay@cs.wisc.edu void Router::createClockTree() 53210447Snilay@cs.wisc.edu { 53310447Snilay@cs.wisc.edu // Get parameters 53410447Snilay@cs.wisc.edu const String& clock_tree_model = getParameter("ClockTreeModel"); 53510447Snilay@cs.wisc.edu const String& clock_tree_number_levels = getParameter("ClockTree->NumberLevels"); 53610447Snilay@cs.wisc.edu const String& clock_tree_wire_layer = getParameter("ClockTree->WireLayer"); 53710447Snilay@cs.wisc.edu const String& clock_tree_wire_width_multiplier = getParameter("ClockTree->WireWidthMultiplier"); 53810447Snilay@cs.wisc.edu const String& clock_tree_wire_spacing_multiplier = getParameter("ClockTree->WireSpacingMultiplier"); 53910447Snilay@cs.wisc.edu 54010447Snilay@cs.wisc.edu // Init clock tree model 54110447Snilay@cs.wisc.edu const String& clock_tree_name = "ClockTree"; 54210447Snilay@cs.wisc.edu ElectricalModel* clock_tree = (ElectricalModel*)ModelGen::createModel(clock_tree_model, clock_tree_name, getTechModel()); 54310447Snilay@cs.wisc.edu clock_tree->setParameter("NumberLevels", clock_tree_number_levels); 54410447Snilay@cs.wisc.edu clock_tree->setParameter("NumberBits", 1); 54510447Snilay@cs.wisc.edu clock_tree->setParameter("WireLayer", clock_tree_wire_layer); 54610447Snilay@cs.wisc.edu clock_tree->setParameter("WireWidthMultiplier", clock_tree_wire_width_multiplier); 54710447Snilay@cs.wisc.edu clock_tree->setParameter("WireSpacingMultiplier", clock_tree_wire_spacing_multiplier); 54810447Snilay@cs.wisc.edu clock_tree->construct(); 54910447Snilay@cs.wisc.edu 55010447Snilay@cs.wisc.edu // Add instances and results 55110447Snilay@cs.wisc.edu addSubInstances(clock_tree, 1.0); 55210447Snilay@cs.wisc.edu addElectricalSubResults(clock_tree, 1.0); 55310447Snilay@cs.wisc.edu 55410447Snilay@cs.wisc.edu return; 55510447Snilay@cs.wisc.edu } 55610447Snilay@cs.wisc.edu} // namespace DSENT 55710447Snilay@cs.wisc.edu 558