RippleAdder.cc revision 10447:a465576671d4
1#include "model/electrical/RippleAdder.h"
2
3#include <cmath>
4
5#include "model/PortInfo.h"
6#include "model/TransitionInfo.h"
7#include "model/EventInfo.h"
8#include "model/std_cells/StdCell.h"
9#include "model/std_cells/StdCellLib.h"
10
11namespace DSENT
12{
13    RippleAdder::RippleAdder(const String& instance_name_, const TechModel* tech_model_)
14        : ElectricalModel(instance_name_, tech_model_)
15    {
16        initParameters();
17        initProperties();
18    }
19
20    RippleAdder::~RippleAdder()
21    {}
22
23    void RippleAdder::initParameters()
24    {
25        addParameterName("NumberBits");
26        return;
27    }
28
29    void RippleAdder::initProperties()
30    {
31        return;
32    }
33
34    void RippleAdder::constructModel()
35    {
36        // Get properties
37        unsigned int number_bits = (unsigned int) getParameter("NumberBits");
38
39        //Construct electrical ports and nets
40        createInputPort("CI");
41        createOutputPort("CO");
42        for(unsigned int i = 0; i < number_bits; ++i)
43        {
44            createInputPort("A" + String(i));
45            createInputPort("B" + String(i));
46            createOutputPort("S" + String(i));
47            createNet("C" + String(i));
48        }
49        createNet("C" + String(number_bits));
50
51        //Create energy, power, and area results
52        createElectricalResults();
53        getEventInfo("Idle")->setStaticTransitionInfos();
54        createElectricalEventResult("Add");
55        Result* add_event = getEventResult("Add");
56
57        // Connect all nets
58        assign("C0", "CI");
59        assign("CO", "C" + String(number_bits));
60        for (unsigned int i = 0; i < number_bits; ++i)
61        {
62            String n = (String) i;
63            StdCell* adder = getTechModel()->getStdCellLib()->createStdCell("ADDF", "ADDF_" + n);
64            adder->construct();
65
66            //Build electrical connectivity
67            portConnect(adder, "A", "A" + String(i));
68            portConnect(adder, "B", "B" + String(i));
69            portConnect(adder, "CI", "C" + String(i));
70            portConnect(adder, "S", "S" + String(i));
71            portConnect(adder, "CO", "C" + String(i + 1));
72
73            //Add ADDF instance, leakage power, energy, and add event results
74            addSubInstances(adder, 1.0);
75            addElectricalSubResults(adder, 1.0);
76            add_event->addSubResult(adder->getEventResult("ADDF"), "ADDF_" + n, 1.0);
77        }
78
79        return;
80    }
81
82    void RippleAdder::propagateTransitionInfo()
83    {
84        unsigned int number_bits = getParameter("NumberBits").toUInt();
85
86        TransitionInfo current_trans_CI = getInputPort("CI")->getTransitionInfo();
87        for(unsigned int i = 0; i < number_bits; ++i)
88        {
89            ElectricalModel* adder = (ElectricalModel*)getSubInstance("ADDF_" + String(i));
90
91            // Propagate input transition info
92            propagatePortTransitionInfo(adder, "A", "A" + String(i));
93            propagatePortTransitionInfo(adder, "B", "B" + String(i));
94            assignPortTransitionInfo(adder, "CI", current_trans_CI);
95            adder->use();
96
97            // Assign output transition info
98            propagatePortTransitionInfo("S" + String(i), adder, "S");
99            current_trans_CI = adder->getOutputPort("CO")->getTransitionInfo();
100        }
101        getOutputPort("CO")->setTransitionInfo(current_trans_CI);
102        return;
103    }
104
105} // namespace DSENT
106
107