-
Notifications
You must be signed in to change notification settings - Fork 0
/
routercrossbar.cpp
133 lines (109 loc) · 3.56 KB
/
routercrossbar.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
* routercrossbar.cpp
* PhoenixSim
*
* Created by Johnnie Chan on 6/10/11.
* Copyright 2011 Johnnie Chan. All rights reserved.
*
*/
#include "routercrossbar.h"
#include <sstream>
using namespace PhoenixSim;
RouterCrossbar::RouterCrossbar(sc_module_name name, int p_numOfInputPorts, int p_numOfOutputPorts, sc_time p_clockPeriod, const COrionPowerParams& powerParams)
: sc_module(name), numOfInputPorts(p_numOfInputPorts), numOfOutputPorts(p_numOfOutputPorts), controlInputPort(p_numOfInputPorts), dataInputPort(p_numOfInputPorts), dataOutputPort(p_numOfOutputPorts), clockPeriod(p_clockPeriod)
{
for (int i = 0; i < numOfInputPorts; i++)
{
std::stringstream so ,so1;
so << "controlInputPort" << "<" << i << ">";
controlInputPort[i] = new sc_in<int>(so.str().c_str());
so1 << "dataInputPort" << "<" << i << ">";
dataInputPort[i] = new sc_in<ElectronicMessage*>(so1.str().c_str());
}
for (int i = 0; i < numOfOutputPorts; i++)
{
std::stringstream so;
so << "dataOutputPort" << "<" << i << ">";
dataOutputPort[i] = new sc_out<ElectronicMessage*>(so.str().c_str());
//dataOutputPort[i]->initialize(ElectronicMessage());
}
SC_METHOD(UpdateCrossbar);
dont_initialize();
sensitive << updateEvent;
SC_METHOD(SetUpdateDelay);
dont_initialize();
for(int i = 0; i < numOfInputPorts; i++)
{
sensitive << controlInputPort[i]->value_changed();
sensitive << dataInputPort[i]->value_changed();
}
power_ = new ORION_Crossbar();
int model = MATRIX_CROSSBAR;
int ins = numOfInputPorts;
int outs = numOfOutputPorts;
int in_seg = 0; //used by segmented crossbar
int out_seg = 0; //used by segmented crossbar
int data_width = 32;
int degree = 4; //used by multree crossbar
int connect_type = TRISTATE_GATE;
int trans_type = powerParams.m_transType;
double in_len = 0; //use 0 if unknown, ORION will figure it out
double out_len = 0;
int technology = powerParams.m_technology;
double voltage = powerParams.m_voltage;
double frequency =powerParams.m_frequency;
ORION_Tech_Config *conf = new ORION_Tech_Config(technology, trans_type,
voltage, frequency);
power_->init(model, ins, outs, in_seg, out_seg, data_width, degree,
connect_type, trans_type, in_len, out_len, conf);
#ifdef __REPORT_STATIC_POWER_AT_STARTUP__
std::cout << "Reporting crossbar static POWER: " << power_->report_static_power() << " W \n";
#endif
}
RouterCrossbar::~RouterCrossbar()
{
double power = power_->report();
#ifdef __REPORT_TOTAL_ENERGY_AT_TEARDOWN__
std::cout.precision(10);
std::cout << "Reporting final ENERGY for crossbar: " << power << " J \n";
#endif
delete power_;
for (int i = 0; i < numOfInputPorts; i++)
{
delete controlInputPort[i];
delete dataInputPort[i];
delete dataOutputPort[i];
}
}
void RouterCrossbar::UpdateCrossbar()
{
//std::cout<<sc_time_stamp()<<" "<<this->name()<<" updating crossbar"<<endl;
bool writeOutput;
for(int i = 0; i < numOfOutputPorts; i++)
{
writeOutput = false;
for(int j = 0; j < numOfInputPorts; j++)
{
// if this input routing matches the output then do this
if(controlInputPort[j]->read() == i)
{
if(dataOutputPort[i]->read() != dataInputPort[j]->read())
{
dataOutputPort[controlInputPort[j]->read()]->write(dataInputPort[j]->read());
power_->record(1, j, i, dataInputPort[j]->read()->messageSize); //input
power_->record(0, j, i, dataInputPort[j]->read()->messageSize); //output
messagesRouted +=1;
}
writeOutput = true;
}
}
if(!writeOutput)
{
dataOutputPort[i]->write(NULL);
}
}
}
void RouterCrossbar::SetUpdateDelay()
{
updateEvent.notify(clockPeriod);
}