RouterInputPort.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/RouterInputPort.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 3410447Snilay@cs.wisc.edunamespace DSENT 3510447Snilay@cs.wisc.edu{ 3610447Snilay@cs.wisc.edu using std::ceil; 3710447Snilay@cs.wisc.edu using std::vector; 3810447Snilay@cs.wisc.edu using LibUtil::castStringVector; 3910447Snilay@cs.wisc.edu 4010447Snilay@cs.wisc.edu RouterInputPort::RouterInputPort(const String& instance_name_, const TechModel* tech_model_) 4110447Snilay@cs.wisc.edu : ElectricalModel(instance_name_, tech_model_) 4210447Snilay@cs.wisc.edu { 4310447Snilay@cs.wisc.edu initParameters(); 4410447Snilay@cs.wisc.edu initProperties(); 4510447Snilay@cs.wisc.edu } 4610447Snilay@cs.wisc.edu 4710447Snilay@cs.wisc.edu RouterInputPort::~RouterInputPort() 4810447Snilay@cs.wisc.edu {} 4910447Snilay@cs.wisc.edu 5010447Snilay@cs.wisc.edu void RouterInputPort::initParameters() 5110447Snilay@cs.wisc.edu { 5210447Snilay@cs.wisc.edu addParameterName("NumberVirtualNetworks"); 5310447Snilay@cs.wisc.edu addParameterName("NumberVirtualChannelsPerVirtualNetwork"); 5410447Snilay@cs.wisc.edu addParameterName("NumberBuffersPerVirtualChannel"); 5510447Snilay@cs.wisc.edu addParameterName("NumberBitsPerFlit"); 5610447Snilay@cs.wisc.edu addParameterName("BufferModel"); 5710447Snilay@cs.wisc.edu return; 5810447Snilay@cs.wisc.edu } 5910447Snilay@cs.wisc.edu 6010447Snilay@cs.wisc.edu void RouterInputPort::initProperties() 6110447Snilay@cs.wisc.edu { 6210447Snilay@cs.wisc.edu return; 6310447Snilay@cs.wisc.edu } 6410447Snilay@cs.wisc.edu 6510447Snilay@cs.wisc.edu RouterInputPort* RouterInputPort::clone() const 6610447Snilay@cs.wisc.edu { 6710447Snilay@cs.wisc.edu // TODO 6810447Snilay@cs.wisc.edu return NULL; 6910447Snilay@cs.wisc.edu } 7010447Snilay@cs.wisc.edu 7110447Snilay@cs.wisc.edu void RouterInputPort::constructModel() 7210447Snilay@cs.wisc.edu { 7310447Snilay@cs.wisc.edu // Get parameters 7410447Snilay@cs.wisc.edu unsigned int number_vns = getParameter("NumberVirtualNetworks").toUInt(); 7510447Snilay@cs.wisc.edu const vector<unsigned int>& number_vcs_per_vn_vector = castStringVector<unsigned int>(getParameter("NumberVirtualChannelsPerVirtualNetwork").split("[,]")); 7610447Snilay@cs.wisc.edu const vector<unsigned int>& number_bufs_per_vc_vector = castStringVector<unsigned int>(getParameter("NumberBuffersPerVirtualChannel").split("[,]")); 7710447Snilay@cs.wisc.edu unsigned int number_bits_per_flit = getParameter("NumberBitsPerFlit").toUInt(); 7810447Snilay@cs.wisc.edu const String& buffer_model = getParameter("BufferModel"); 7910447Snilay@cs.wisc.edu 8010447Snilay@cs.wisc.edu ASSERT(number_vns > 0, "[Error] " + getInstanceName() + 8110447Snilay@cs.wisc.edu " -> Number of virtual networks must be > 0!"); 8210447Snilay@cs.wisc.edu ASSERT(number_vcs_per_vn_vector.size() == number_vns, "[Error] " + getInstanceName() + 8310447Snilay@cs.wisc.edu " -> Expecting " + (String)number_vns + " number of vcs, got " + 8410447Snilay@cs.wisc.edu getParameter("NumberVirtualChannelsPerVirtualNetwork")); 8510447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_vns; ++i) 8610447Snilay@cs.wisc.edu { 8710447Snilay@cs.wisc.edu ASSERT(number_vcs_per_vn_vector[i] > 0, "[Error] " + getInstanceName() + 8810447Snilay@cs.wisc.edu " -> Number of virtual channels per virtual network must be > 0!"); 8910447Snilay@cs.wisc.edu } 9010447Snilay@cs.wisc.edu ASSERT(number_bufs_per_vc_vector.size() == number_vns, "[Error] " + getInstanceName() + 9110447Snilay@cs.wisc.edu " -> Expecting " + (String)number_vns + " number of bufs per vc, got " + 9210447Snilay@cs.wisc.edu getParameter("NumberBuffersPerVirtualChannel")); 9310447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_vns; ++i) 9410447Snilay@cs.wisc.edu { 9510447Snilay@cs.wisc.edu ASSERT(number_bufs_per_vc_vector[i] > 0, "[Error] " + getInstanceName() + 9610447Snilay@cs.wisc.edu " -> Number of buffers per virtual channel must be > 0!"); 9710447Snilay@cs.wisc.edu } 9810447Snilay@cs.wisc.edu ASSERT(number_bits_per_flit > 0, "[Error] " + getInstanceName() + 9910447Snilay@cs.wisc.edu " -> Number of bits per buffer must be > 0!"); 10010447Snilay@cs.wisc.edu 10110447Snilay@cs.wisc.edu // Calculate total number of buffers needed in the RAM 10210447Snilay@cs.wisc.edu unsigned int total_number_vcs = 0; 10310447Snilay@cs.wisc.edu unsigned int total_number_bufs = 0; 10410447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_vns; ++i) 10510447Snilay@cs.wisc.edu { 10610447Snilay@cs.wisc.edu total_number_vcs += number_vcs_per_vn_vector[i]; 10710447Snilay@cs.wisc.edu total_number_bufs += number_vcs_per_vn_vector[i] * number_bufs_per_vc_vector[i]; 10810447Snilay@cs.wisc.edu } 10910447Snilay@cs.wisc.edu unsigned int number_addr_bits = (unsigned int)ceil(log2(total_number_bufs)); 11010447Snilay@cs.wisc.edu 11110447Snilay@cs.wisc.edu getGenProperties()->set("TotalNumberVirtualChannels", total_number_vcs); 11210447Snilay@cs.wisc.edu getGenProperties()->set("TotalNumberBuffers", total_number_bufs); 11310447Snilay@cs.wisc.edu getGenProperties()->set("NumberAddressBits", number_addr_bits); 11410447Snilay@cs.wisc.edu getGenProperties()->set("NumberOutputs", 1); 11510447Snilay@cs.wisc.edu 11610447Snilay@cs.wisc.edu createInputPort("CK"); 11710447Snilay@cs.wisc.edu createInputPort("FlitIn", makeNetIndex(0, number_bits_per_flit-1)); 11810447Snilay@cs.wisc.edu createOutputPort("FlitOut", makeNetIndex(0, number_bits_per_flit-1)); 11910447Snilay@cs.wisc.edu 12010447Snilay@cs.wisc.edu // Create energy, power, and area results 12110447Snilay@cs.wisc.edu createElectricalResults(); 12210447Snilay@cs.wisc.edu getEventInfo("Idle")->setStaticTransitionInfos(); 12310447Snilay@cs.wisc.edu getEventInfo("Idle")->setTransitionInfo("CK", TransitionInfo(0.0, 1.0, 0.0)); 12410447Snilay@cs.wisc.edu 12510447Snilay@cs.wisc.edu addEventResult(new Result("ReadBuffer")); 12610447Snilay@cs.wisc.edu addEventResult(new Result("WriteBuffer")); 12710447Snilay@cs.wisc.edu 12810447Snilay@cs.wisc.edu // Init RAM 12910447Snilay@cs.wisc.edu const String& ram_name = "RAM"; 13010447Snilay@cs.wisc.edu ElectricalModel* ram = ModelGen::createRAM(buffer_model, ram_name, getTechModel()); 13110447Snilay@cs.wisc.edu ram->setParameter("NumberEntries", total_number_bufs); 13210447Snilay@cs.wisc.edu ram->setParameter("NumberBits", number_bits_per_flit); 13310447Snilay@cs.wisc.edu ram->construct(); 13410447Snilay@cs.wisc.edu 13510447Snilay@cs.wisc.edu // Init DFF for read address 13610447Snilay@cs.wisc.edu vector<String> rd_addr_dff_names(number_addr_bits, ""); 13710447Snilay@cs.wisc.edu vector<StdCell*> rd_addr_dffs(number_addr_bits, NULL); 13810447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_addr_bits; ++i) 13910447Snilay@cs.wisc.edu { 14010447Snilay@cs.wisc.edu rd_addr_dff_names[i] = "RDAddr_DFF" + (String)i; 14110447Snilay@cs.wisc.edu rd_addr_dffs[i] = getTechModel()->getStdCellLib()->createStdCell("DFFQ", rd_addr_dff_names[i]); 14210447Snilay@cs.wisc.edu rd_addr_dffs[i]->construct(); 14310447Snilay@cs.wisc.edu } 14410447Snilay@cs.wisc.edu 14510447Snilay@cs.wisc.edu // Connect RDAddr_DFFs 14610447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_addr_bits; ++i) 14710447Snilay@cs.wisc.edu { 14810447Snilay@cs.wisc.edu createNet("RDAddr_DFF_Out" + (String)i); 14910447Snilay@cs.wisc.edu 15010447Snilay@cs.wisc.edu portConnect(rd_addr_dffs[i], "CK", "CK"); 15110447Snilay@cs.wisc.edu portConnect(rd_addr_dffs[i], "Q", "RDAddr_DFF_Out" + (String)i); 15210447Snilay@cs.wisc.edu } 15310447Snilay@cs.wisc.edu 15410447Snilay@cs.wisc.edu // Connect RAM 15510447Snilay@cs.wisc.edu portConnect(ram, "In", "FlitIn"); 15610447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_addr_bits; ++i) 15710447Snilay@cs.wisc.edu { 15810447Snilay@cs.wisc.edu portConnect(ram, "WRAddr" + (String)i, "FlitIn", makeNetIndex(i)); 15910447Snilay@cs.wisc.edu portConnect(ram, "RDAddr" + (String)i, "RDAddr_DFF_Out" + (String)i); 16010447Snilay@cs.wisc.edu } 16110447Snilay@cs.wisc.edu portConnect(ram, "WE", "FlitIn", makeNetIndex(number_bits_per_flit-1)); 16210447Snilay@cs.wisc.edu portConnect(ram, "CK", "CK"); 16310447Snilay@cs.wisc.edu portConnect(ram, "Out", "FlitOut"); 16410447Snilay@cs.wisc.edu 16510447Snilay@cs.wisc.edu // Add area, power, event results 16610447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_addr_bits; ++i) 16710447Snilay@cs.wisc.edu { 16810447Snilay@cs.wisc.edu addSubInstances(rd_addr_dffs[i], number_addr_bits); 16910447Snilay@cs.wisc.edu addElectricalSubResults(rd_addr_dffs[i], number_addr_bits); 17010447Snilay@cs.wisc.edu } 17110447Snilay@cs.wisc.edu addSubInstances(ram, 1.0); 17210447Snilay@cs.wisc.edu addElectricalSubResults(ram, 1.0); 17310447Snilay@cs.wisc.edu 17410447Snilay@cs.wisc.edu getEventResult("WriteBuffer")->addSubResult(ram->getEventResult("Write"), ram_name, 1.0); 17510447Snilay@cs.wisc.edu 17610447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_addr_bits; ++i) 17710447Snilay@cs.wisc.edu { 17810447Snilay@cs.wisc.edu getEventResult("ReadBuffer")->addSubResult(rd_addr_dffs[i]->getEventResult("DFFD"), rd_addr_dff_names[i], number_addr_bits); 17910447Snilay@cs.wisc.edu getEventResult("ReadBuffer")->addSubResult(rd_addr_dffs[i]->getEventResult("DFFQ"), rd_addr_dff_names[i], number_addr_bits); 18010447Snilay@cs.wisc.edu getEventResult("ReadBuffer")->addSubResult(rd_addr_dffs[i]->getEventResult("CK"), rd_addr_dff_names[i], number_addr_bits); 18110447Snilay@cs.wisc.edu } 18210447Snilay@cs.wisc.edu getEventResult("ReadBuffer")->addSubResult(ram->getEventResult("Read"), ram_name, 1.0); 18310447Snilay@cs.wisc.edu 18410447Snilay@cs.wisc.edu return; 18510447Snilay@cs.wisc.edu } 18610447Snilay@cs.wisc.edu 18710447Snilay@cs.wisc.edu void RouterInputPort::propagateTransitionInfo() 18810447Snilay@cs.wisc.edu { 18910447Snilay@cs.wisc.edu // Update probability and activity 19010447Snilay@cs.wisc.edu unsigned int number_addr_bits = getGenProperties()->get("NumberAddressBits").toUInt(); 19110447Snilay@cs.wisc.edu 19210447Snilay@cs.wisc.edu vector<ElectricalModel*> rd_addr_dffs(number_addr_bits, NULL); 19310447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_addr_bits; ++i) 19410447Snilay@cs.wisc.edu { 19510447Snilay@cs.wisc.edu rd_addr_dffs[i] = (ElectricalModel*)getSubInstance("RDAddr_DFF" + (String)i); 19610447Snilay@cs.wisc.edu assignPortTransitionInfo(rd_addr_dffs[i], "D", TransitionInfo()); 19710447Snilay@cs.wisc.edu propagatePortTransitionInfo(rd_addr_dffs[i], "CK", "CK"); 19810447Snilay@cs.wisc.edu rd_addr_dffs[i]->use(); 19910447Snilay@cs.wisc.edu } 20010447Snilay@cs.wisc.edu 20110447Snilay@cs.wisc.edu ElectricalModel* ram = (ElectricalModel*)getSubInstance("RAM"); 20210447Snilay@cs.wisc.edu 20310447Snilay@cs.wisc.edu // Setup default transition info 20410447Snilay@cs.wisc.edu const String& current_event = getGenProperties()->get("UseModelEvent"); 20510447Snilay@cs.wisc.edu if(current_event != "Idle") 20610447Snilay@cs.wisc.edu { 20710447Snilay@cs.wisc.edu propagatePortTransitionInfo(ram, "In", "FlitIn"); 20810447Snilay@cs.wisc.edu propagatePortTransitionInfo(ram, "CK", "CK"); 20910447Snilay@cs.wisc.edu assignPortTransitionInfo(ram, "WE", TransitionInfo(0.0, 0.0, 1.0)); 21010447Snilay@cs.wisc.edu for(unsigned int i = 0; i < number_addr_bits; ++i) 21110447Snilay@cs.wisc.edu { 21210447Snilay@cs.wisc.edu assignPortTransitionInfo(ram, "WRAddr" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); 21310447Snilay@cs.wisc.edu assignPortTransitionInfo(ram, "RDAddr" + (String)i, TransitionInfo(0.25, 0.25, 0.25)); 21410447Snilay@cs.wisc.edu } 21510447Snilay@cs.wisc.edu } 21610447Snilay@cs.wisc.edu ram->use(); 21710447Snilay@cs.wisc.edu // Set output probability 21810447Snilay@cs.wisc.edu propagatePortTransitionInfo("FlitOut", ram, "Out"); 21910447Snilay@cs.wisc.edu return; 22010447Snilay@cs.wisc.edu } 22110447Snilay@cs.wisc.edu} // namespace DSENT 22210447Snilay@cs.wisc.edu 223