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/RepeatedLink.h"
2310447Snilay@cs.wisc.edu
2410447Snilay@cs.wisc.edu#include "model/PortInfo.h"
2510447Snilay@cs.wisc.edu#include "model/EventInfo.h"
2610447Snilay@cs.wisc.edu#include "model/TransitionInfo.h"
2710447Snilay@cs.wisc.edu#include "model/std_cells/StdCellLib.h"
2810447Snilay@cs.wisc.edu#include "model/std_cells/StdCell.h"
2910447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalTimingTree.h"
3010447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalTimingNode.h"
3110447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalNet.h"
3210447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalDriver.h"
3310447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalDelay.h"
3410447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalLoad.h"
3510447Snilay@cs.wisc.edu
3610447Snilay@cs.wisc.edunamespace DSENT
3710447Snilay@cs.wisc.edu{
3810447Snilay@cs.wisc.edu    RepeatedLink::RepeatedLink(const String& instance_name_, const TechModel* tech_model_)
3910447Snilay@cs.wisc.edu        : ElectricalModel(instance_name_, tech_model_)
4010447Snilay@cs.wisc.edu    {
4110447Snilay@cs.wisc.edu        m_repeater_ = NULL;
4210447Snilay@cs.wisc.edu        m_repeater_load_ = NULL;
4310447Snilay@cs.wisc.edu        m_timing_tree_ = NULL;
4410447Snilay@cs.wisc.edu
4510447Snilay@cs.wisc.edu        initParameters();
4610447Snilay@cs.wisc.edu        initProperties();
4710447Snilay@cs.wisc.edu    }
4810447Snilay@cs.wisc.edu
4910447Snilay@cs.wisc.edu    RepeatedLink::~RepeatedLink()
5010447Snilay@cs.wisc.edu    {
5110447Snilay@cs.wisc.edu        delete m_repeater_;
5210447Snilay@cs.wisc.edu        delete m_repeater_load_;
5310447Snilay@cs.wisc.edu        delete m_timing_tree_;
5410447Snilay@cs.wisc.edu    }
5510447Snilay@cs.wisc.edu
5610447Snilay@cs.wisc.edu    void RepeatedLink::initParameters()
5710447Snilay@cs.wisc.edu    {
5810447Snilay@cs.wisc.edu        addParameterName("NumberBits");
5910447Snilay@cs.wisc.edu        addParameterName("WireLayer");
6010447Snilay@cs.wisc.edu        addParameterName("WireWidthMultiplier", 1.0);
6110447Snilay@cs.wisc.edu        addParameterName("WireSpacingMultiplier", 1.0);
6210447Snilay@cs.wisc.edu        return;
6310447Snilay@cs.wisc.edu    }
6410447Snilay@cs.wisc.edu
6510447Snilay@cs.wisc.edu    void RepeatedLink::initProperties()
6610447Snilay@cs.wisc.edu    {
6710447Snilay@cs.wisc.edu        addPropertyName("WireLength");
6810447Snilay@cs.wisc.edu        addPropertyName("Delay");
6910447Snilay@cs.wisc.edu        addPropertyName("IsKeepParity", "TRUE");
7010447Snilay@cs.wisc.edu        return;
7110447Snilay@cs.wisc.edu    }
7210447Snilay@cs.wisc.edu
7310447Snilay@cs.wisc.edu    RepeatedLink* RepeatedLink::clone() const
7410447Snilay@cs.wisc.edu    {
7510447Snilay@cs.wisc.edu        // TODO
7610447Snilay@cs.wisc.edu        return NULL;
7710447Snilay@cs.wisc.edu    }
7810447Snilay@cs.wisc.edu
7910447Snilay@cs.wisc.edu    void RepeatedLink::constructModel()
8010447Snilay@cs.wisc.edu    {
8110447Snilay@cs.wisc.edu        // Get parameters
8210447Snilay@cs.wisc.edu        unsigned int number_bits = getParameter("NumberBits").toUInt();
8310447Snilay@cs.wisc.edu        const String& wire_layer = getParameter("WireLayer");
8410447Snilay@cs.wisc.edu        double wire_width_multiplier = getParameter("WireWidthMultiplier").toDouble();
8510447Snilay@cs.wisc.edu        double wire_spacing_multiplier = getParameter("WireSpacingMultiplier").toDouble();
8610447Snilay@cs.wisc.edu
8710447Snilay@cs.wisc.edu        ASSERT(number_bits > 0, "[Error] " + getInstanceName() +
8810447Snilay@cs.wisc.edu                " -> Number of bits must be > 0!");
8910447Snilay@cs.wisc.edu        ASSERT(getTechModel()->isWireLayerExist(wire_layer), "[Error] " + getInstanceName() +
9010447Snilay@cs.wisc.edu                " -> Wire layer does not exist!");
9110447Snilay@cs.wisc.edu        ASSERT(wire_width_multiplier >= 1.0, "[Error] " + getInstanceName() +
9210447Snilay@cs.wisc.edu                " -> Wire width multiplier must be >= 1.0!");
9310447Snilay@cs.wisc.edu        ASSERT(wire_spacing_multiplier >= 1.0, "[Error] " + getInstanceName() +
9410447Snilay@cs.wisc.edu                " -> Wire spacing multiplier must be >= 1.0!");
9510447Snilay@cs.wisc.edu
9610447Snilay@cs.wisc.edu        double wire_min_width = getTechModel()->get("Wire->" + wire_layer + "->MinWidth").toDouble();
9710447Snilay@cs.wisc.edu        double wire_min_spacing = getTechModel()->get("Wire->" + wire_layer + "->MinSpacing").toDouble();
9810447Snilay@cs.wisc.edu
9910447Snilay@cs.wisc.edu        double wire_width = wire_min_width * wire_width_multiplier;
10010447Snilay@cs.wisc.edu        double wire_spacing = wire_min_spacing * wire_spacing_multiplier;
10110447Snilay@cs.wisc.edu
10210447Snilay@cs.wisc.edu        double wire_cap_per_len = getTechModel()->calculateWireCapacitance(wire_layer, wire_width, wire_spacing, 1.0);
10310447Snilay@cs.wisc.edu        double wire_res_per_len = getTechModel()->calculateWireResistance(wire_layer, wire_width, 1.0);
10410447Snilay@cs.wisc.edu
10510447Snilay@cs.wisc.edu        getGenProperties()->set("WireWidth", wire_width);
10610447Snilay@cs.wisc.edu        getGenProperties()->set("WireSpacing", wire_spacing);
10710447Snilay@cs.wisc.edu        getGenProperties()->set("WireCapacitancePerLength", wire_cap_per_len);
10810447Snilay@cs.wisc.edu        getGenProperties()->set("WireResistancePerLength", wire_res_per_len);
10910447Snilay@cs.wisc.edu
11010447Snilay@cs.wisc.edu        // Create ports
11110447Snilay@cs.wisc.edu        createInputPort("In", makeNetIndex(0, number_bits-1));
11210447Snilay@cs.wisc.edu        createOutputPort("Out", makeNetIndex(0, number_bits-1));
11310447Snilay@cs.wisc.edu
11410447Snilay@cs.wisc.edu        // Create area, power, and event results
11510447Snilay@cs.wisc.edu        createElectricalAtomicResults();
11610447Snilay@cs.wisc.edu        createElectricalEventAtomicResult("Send");
11710447Snilay@cs.wisc.edu
11810447Snilay@cs.wisc.edu        // Create connections
11910447Snilay@cs.wisc.edu        // Since the length is not set yet, we only to virtual fan-in and virtual fan-out
12010447Snilay@cs.wisc.edu        createNet("InTmp");
12110447Snilay@cs.wisc.edu        createNet("OutTmp");
12210447Snilay@cs.wisc.edu        assignVirtualFanin("InTmp", "In");
12310447Snilay@cs.wisc.edu        assignVirtualFanout("Out", "OutTmp");
12410447Snilay@cs.wisc.edu
12510447Snilay@cs.wisc.edu        // Build Electrical Connectivity
12610447Snilay@cs.wisc.edu        createLoad("In_Cap");
12710447Snilay@cs.wisc.edu        createDelay("In_to_Out_delay");
12810447Snilay@cs.wisc.edu        createDriver("Out_Ron", false); // Indicate this driver is not sizable
12910447Snilay@cs.wisc.edu
13010447Snilay@cs.wisc.edu        ElectricalLoad* in_cap = getLoad("In_Cap");
13110447Snilay@cs.wisc.edu        ElectricalDelay* in_to_out_delay = getDelay("In_to_Out_delay");
13210447Snilay@cs.wisc.edu        ElectricalDriver* out_ron = getDriver("Out_Ron");
13310447Snilay@cs.wisc.edu
13410447Snilay@cs.wisc.edu        getNet("InTmp")->addDownstreamNode(in_cap);
13510447Snilay@cs.wisc.edu        in_cap->addDownstreamNode(in_to_out_delay);
13610447Snilay@cs.wisc.edu        in_to_out_delay->addDownstreamNode(out_ron);
13710447Snilay@cs.wisc.edu        out_ron->addDownstreamNode(getNet("OutTmp"));
13810447Snilay@cs.wisc.edu
13910447Snilay@cs.wisc.edu        // Init a repeater and a load to mimic a segment of a repeated link
14010447Snilay@cs.wisc.edu        m_repeater_ = getTechModel()->getStdCellLib()->createStdCell("INV", "Repeater");
14110447Snilay@cs.wisc.edu        m_repeater_->construct();
14210447Snilay@cs.wisc.edu        m_repeater_load_ = new ElectricalLoad("RepeaterIn_Cap", this);
14310447Snilay@cs.wisc.edu        // Make path repeater_ -> repeater_load_
14410447Snilay@cs.wisc.edu        // to catch the repeater's input/output cap and ensure only one inverter delay
14510447Snilay@cs.wisc.edu        // is added
14610447Snilay@cs.wisc.edu        m_repeater_->getNet("Y")->addDownstreamNode(m_repeater_load_);
14710447Snilay@cs.wisc.edu        // Init a timing object to calculate delay
14810447Snilay@cs.wisc.edu        m_timing_tree_ = new ElectricalTimingTree("RepeatedLink", this);
14910447Snilay@cs.wisc.edu        m_timing_tree_->performCritPathExtract(m_repeater_->getNet("A"));
15010447Snilay@cs.wisc.edu        return;
15110447Snilay@cs.wisc.edu    }
15210447Snilay@cs.wisc.edu
15310447Snilay@cs.wisc.edu    void RepeatedLink::updateModel()
15410447Snilay@cs.wisc.edu    {
15510447Snilay@cs.wisc.edu        unsigned int number_bits = getParameter("NumberBits").toUInt();
15610447Snilay@cs.wisc.edu
15710447Snilay@cs.wisc.edu        // Get properties
15810447Snilay@cs.wisc.edu        double wire_length = getProperty("WireLength").toDouble();
15910447Snilay@cs.wisc.edu        double required_delay = getProperty("Delay").toDouble();
16010447Snilay@cs.wisc.edu        bool isKeepParity = getProperty("IsKeepParity").toBool();
16110447Snilay@cs.wisc.edu
16210447Snilay@cs.wisc.edu        ASSERT(wire_length >= 0, "[Error] " + getInstanceName() +
16310447Snilay@cs.wisc.edu                " -> Wire length must be >= 0!");
16410447Snilay@cs.wisc.edu        ASSERT(required_delay >= 0, "[Error] " + getInstanceName() +
16510447Snilay@cs.wisc.edu                " -> Required delay must be >= 0!");
16610447Snilay@cs.wisc.edu
16710447Snilay@cs.wisc.edu        const String& wire_layer = getParameter("WireLayer");
16810447Snilay@cs.wisc.edu        double wire_width = getGenProperties()->get("WireWidth").toDouble();
16910447Snilay@cs.wisc.edu        double wire_spacing = getGenProperties()->get("WireSpacing").toDouble();
17010447Snilay@cs.wisc.edu
17110447Snilay@cs.wisc.edu        // Calculate the total wire cap and total wire res
17210447Snilay@cs.wisc.edu        double wire_cap_per_len = getGenProperties()->get("WireCapacitancePerLength").toDouble();
17310447Snilay@cs.wisc.edu        double wire_res_per_len = getGenProperties()->get("WireResistancePerLength").toDouble();
17410447Snilay@cs.wisc.edu        double total_wire_cap = wire_cap_per_len * wire_length;
17510447Snilay@cs.wisc.edu        double total_wire_res = wire_res_per_len * wire_length;
17610447Snilay@cs.wisc.edu
17710447Snilay@cs.wisc.edu        m_repeater_->update();
17810447Snilay@cs.wisc.edu
17910447Snilay@cs.wisc.edu        unsigned int increment_segments = (isKeepParity)? 2:1;
18010447Snilay@cs.wisc.edu        unsigned int number_segments = increment_segments;
18110447Snilay@cs.wisc.edu        double delay;
18210447Snilay@cs.wisc.edu        m_repeater_->setMinDrivingStrength();
18310447Snilay@cs.wisc.edu        m_repeater_->getNet("Y")->setDistributedCap(total_wire_cap / number_segments);
18410447Snilay@cs.wisc.edu        m_repeater_->getNet("Y")->setDistributedRes(total_wire_res / number_segments);
18510447Snilay@cs.wisc.edu        m_repeater_load_->setLoadCap(m_repeater_->getNet("A")->getTotalDownstreamCap());
18610447Snilay@cs.wisc.edu        m_timing_tree_->performCritPathExtract(m_repeater_->getNet("A"));
18710447Snilay@cs.wisc.edu        delay = m_timing_tree_->calculateCritPathDelay(m_repeater_->getNet("A")) * number_segments;
18810447Snilay@cs.wisc.edu
18910447Snilay@cs.wisc.edu        // If everything is 0, use number_segments min-sized repeater
19010447Snilay@cs.wisc.edu        if(wire_length != 0)
19110447Snilay@cs.wisc.edu        {
19210447Snilay@cs.wisc.edu            // Set the initial number of segments based on isKeepParity
19310447Snilay@cs.wisc.edu            double last_min_size_delay = 0;
19410447Snilay@cs.wisc.edu            unsigned int iteration = 0;
19510447Snilay@cs.wisc.edu
19610447Snilay@cs.wisc.edu            // First set the repeater to the minimum driving strength
19710447Snilay@cs.wisc.edu            last_min_size_delay = delay;
19810447Snilay@cs.wisc.edu
19910447Snilay@cs.wisc.edu            Log::printLine(getInstanceName() + " -> Beginning Repeater Insertion");
20010447Snilay@cs.wisc.edu
20110447Snilay@cs.wisc.edu            while(required_delay < delay)
20210447Snilay@cs.wisc.edu            {
20310447Snilay@cs.wisc.edu                Log::printLine(getInstanceName() + " -> Repeater Insertion Iteration " + (String)iteration +
20410447Snilay@cs.wisc.edu                        ": Required delay = " + (String)required_delay +
20510447Snilay@cs.wisc.edu                        ", Delay = " + (String)delay +
20610447Snilay@cs.wisc.edu                        ", Slack = " + (String)(required_delay - delay) +
20710447Snilay@cs.wisc.edu                        ", Number of repeaters = " + (String)number_segments);
20810447Snilay@cs.wisc.edu
20910447Snilay@cs.wisc.edu                // Size up if timing is not met
21010447Snilay@cs.wisc.edu                while(required_delay < delay)
21110447Snilay@cs.wisc.edu                {
21210447Snilay@cs.wisc.edu                    if(m_repeater_->hasMaxDrivingStrength())
21310447Snilay@cs.wisc.edu                    {
21410447Snilay@cs.wisc.edu                        break;
21510447Snilay@cs.wisc.edu                    }
21610447Snilay@cs.wisc.edu                    m_repeater_->increaseDrivingStrength();
21710447Snilay@cs.wisc.edu                    m_repeater_load_->setLoadCap(m_repeater_->getNet("A")->getTotalDownstreamCap());
21810447Snilay@cs.wisc.edu                    m_timing_tree_->performCritPathExtract(m_repeater_->getNet("A"));
21910447Snilay@cs.wisc.edu                    delay = m_timing_tree_->calculateCritPathDelay(m_repeater_->getNet("A")) * number_segments;
22010447Snilay@cs.wisc.edu
22110447Snilay@cs.wisc.edu                    iteration++;
22210447Snilay@cs.wisc.edu                    Log::printLine(getInstanceName() + " -> Slack: " + (String)(required_delay - delay));
22310447Snilay@cs.wisc.edu                }
22410447Snilay@cs.wisc.edu                // Increase number of segments if timing is not met
22510447Snilay@cs.wisc.edu                if(required_delay < delay)
22610447Snilay@cs.wisc.edu                {
22710447Snilay@cs.wisc.edu                    number_segments += increment_segments;
22810447Snilay@cs.wisc.edu                    m_repeater_->setMinDrivingStrength();
22910447Snilay@cs.wisc.edu                    m_repeater_->getNet("Y")->setDistributedCap(total_wire_cap / number_segments);
23010447Snilay@cs.wisc.edu                    m_repeater_->getNet("Y")->setDistributedRes(total_wire_res / number_segments);
23110447Snilay@cs.wisc.edu                    m_repeater_load_->setLoadCap(m_repeater_->getNet("A")->getTotalDownstreamCap());
23210447Snilay@cs.wisc.edu                    m_timing_tree_->performCritPathExtract(m_repeater_->getNet("A"));
23310447Snilay@cs.wisc.edu                    delay = m_timing_tree_->calculateCritPathDelay(m_repeater_->getNet("A")) * number_segments;
23410447Snilay@cs.wisc.edu
23510447Snilay@cs.wisc.edu                    // Abort if adding more min sized repeaters does not decrease the delay
23610447Snilay@cs.wisc.edu                    if(delay > last_min_size_delay)
23710447Snilay@cs.wisc.edu                    {
23810447Snilay@cs.wisc.edu                        break;
23910447Snilay@cs.wisc.edu                    }
24010447Snilay@cs.wisc.edu                    last_min_size_delay = delay;
24110447Snilay@cs.wisc.edu                }
24210447Snilay@cs.wisc.edu            }
24310447Snilay@cs.wisc.edu            Log::printLine(getInstanceName() + " -> Repeater Insertion Ended after Iteration: " + (String)iteration +
24410447Snilay@cs.wisc.edu                    ": Required delay = " + (String)required_delay +
24510447Snilay@cs.wisc.edu                    ", Delay = " + (String)delay +
24610447Snilay@cs.wisc.edu                    ", Slack = " + (String)(required_delay - delay) +
24710447Snilay@cs.wisc.edu                    ", Number of repeaters = " + (String)number_segments);
24810447Snilay@cs.wisc.edu
24910447Snilay@cs.wisc.edu            // Print a warning if the timing is not met
25010447Snilay@cs.wisc.edu            if(required_delay < delay)
25110447Snilay@cs.wisc.edu            {
25210447Snilay@cs.wisc.edu                const String& warning_msg = "[Warning] " + getInstanceName() + " -> Timing not met" +
25310447Snilay@cs.wisc.edu                    ": Required delay = " + (String)required_delay +
25410447Snilay@cs.wisc.edu                    ", Delay = " + (String)delay +
25510447Snilay@cs.wisc.edu                    ", Slack = " + (String)(required_delay - delay) +
25610447Snilay@cs.wisc.edu                    ", Number of repeaters = " + (String)number_segments;
25710447Snilay@cs.wisc.edu                Log::printLine(std::cerr, warning_msg);
25810447Snilay@cs.wisc.edu            }
25910447Snilay@cs.wisc.edu        }
26010447Snilay@cs.wisc.edu
26110447Snilay@cs.wisc.edu        // Update electrical interfaces
26210447Snilay@cs.wisc.edu        getLoad("In_Cap")->setLoadCap(m_repeater_->getNet("A")->getTotalDownstreamCap());
26310447Snilay@cs.wisc.edu        getDelay("In_to_Out_delay")->setDelay(delay);
26410447Snilay@cs.wisc.edu        getDriver("Out_Ron")->setOutputRes(m_repeater_->getDriver("Y_Ron")->getOutputRes() + (total_wire_res / number_segments));
26510447Snilay@cs.wisc.edu
26610447Snilay@cs.wisc.edu        getGenProperties()->set("NumberSegments", number_segments);
26710447Snilay@cs.wisc.edu
26810447Snilay@cs.wisc.edu        // Update area, power results
26910447Snilay@cs.wisc.edu        resetElectricalAtomicResults();
27010447Snilay@cs.wisc.edu        addElecticalAtomicResultValues(m_repeater_, number_segments * number_bits);
27110447Snilay@cs.wisc.edu        double wire_area = wire_length * (wire_width + wire_spacing) * number_bits;
27210447Snilay@cs.wisc.edu        addElecticalWireAtomicResultValue(wire_layer, wire_area);
27310447Snilay@cs.wisc.edu
27410447Snilay@cs.wisc.edu        return;
27510447Snilay@cs.wisc.edu    }
27610447Snilay@cs.wisc.edu
27710447Snilay@cs.wisc.edu    void RepeatedLink::useModel()
27810447Snilay@cs.wisc.edu    {
27910447Snilay@cs.wisc.edu        // Update the transition information for the modeled repeater
28010447Snilay@cs.wisc.edu        // Since we only modeled one repeater. So the transition information for 0->0 and 1->1
28110447Snilay@cs.wisc.edu        // is averaged out
28210447Snilay@cs.wisc.edu        const TransitionInfo& trans_In = getInputPort("In")->getTransitionInfo();
28310447Snilay@cs.wisc.edu        double average_static_transition = (trans_In.getNumberTransitions00() + trans_In.getNumberTransitions11()) / 2.0;
28410447Snilay@cs.wisc.edu        TransitionInfo mod_trans_In(average_static_transition, trans_In.getNumberTransitions01(), average_static_transition);
28510447Snilay@cs.wisc.edu        m_repeater_->getInputPort("A")->setTransitionInfo(mod_trans_In);
28610447Snilay@cs.wisc.edu        m_repeater_->use();
28710447Snilay@cs.wisc.edu
28810447Snilay@cs.wisc.edu        // Get parameters
28910447Snilay@cs.wisc.edu        unsigned int number_bits = getParameter("NumberBits").toUInt();
29010447Snilay@cs.wisc.edu        unsigned int number_segments = getGenProperties()->get("NumberSegments").toUInt();
29110447Snilay@cs.wisc.edu
29210447Snilay@cs.wisc.edu        // Propagate the transition information
29310447Snilay@cs.wisc.edu        propagateTransitionInfo();
29410447Snilay@cs.wisc.edu
29510447Snilay@cs.wisc.edu        // Update leakage power
29610447Snilay@cs.wisc.edu        double power = 0.0;
29710447Snilay@cs.wisc.edu        power += m_repeater_->getNddPowerResult("Leakage")->calculateSum() * number_segments * number_bits;
29810447Snilay@cs.wisc.edu        getNddPowerResult("Leakage")->setValue(power);
29910447Snilay@cs.wisc.edu
30010447Snilay@cs.wisc.edu        // Update event result
30110447Snilay@cs.wisc.edu        double energy = 0.0;
30210447Snilay@cs.wisc.edu        energy += m_repeater_->getEventResult("INV")->calculateSum() * number_segments * number_bits;
30310447Snilay@cs.wisc.edu        getEventResult("Send")->setValue(energy);
30410447Snilay@cs.wisc.edu
30510447Snilay@cs.wisc.edu        return;
30610447Snilay@cs.wisc.edu    }
30710447Snilay@cs.wisc.edu
30810447Snilay@cs.wisc.edu    void RepeatedLink::propagateTransitionInfo()
30910447Snilay@cs.wisc.edu    {
31010447Snilay@cs.wisc.edu        unsigned int number_segments = getGenProperties()->get("NumberSegments");
31110447Snilay@cs.wisc.edu
31210447Snilay@cs.wisc.edu        if((number_segments % 2) == 0)
31310447Snilay@cs.wisc.edu        {
31410447Snilay@cs.wisc.edu            propagatePortTransitionInfo("Out", "In");
31510447Snilay@cs.wisc.edu        }
31610447Snilay@cs.wisc.edu        else
31710447Snilay@cs.wisc.edu        {
31810447Snilay@cs.wisc.edu            const TransitionInfo& trans_In = getInputPort("In")->getTransitionInfo();
31910447Snilay@cs.wisc.edu            TransitionInfo trans_Out(trans_In.getNumberTransitions11(), trans_In.getNumberTransitions01(), trans_In.getNumberTransitions00());
32010447Snilay@cs.wisc.edu            getOutputPort("Out")->setTransitionInfo(trans_Out);
32110447Snilay@cs.wisc.edu        }
32210447Snilay@cs.wisc.edu        return;
32310447Snilay@cs.wisc.edu    }
32410447Snilay@cs.wisc.edu
32510447Snilay@cs.wisc.edu} // namespace DSENT
32610447Snilay@cs.wisc.edu
327