processing element模块
#ifndef __NOXIMPROCESSINGELEMENT_H__
#define __NOXIMPROCESSINGELEMENT_H__ #include <queue>
#include <systemc.h> #include "DataStructs.h"
#include "GlobalTrafficTable.h"
#include "Utils.h" using namespace std; SC_MODULE(ProcessingElement)
{
............................
};
#endif
// I/O Ports
sc_in_clk clock; // The input clock for the PE
sc_in < bool > reset; // The reset signal for the PE,清除信号 sc_in < Flit > flit_rx; // The input channel
sc_in < bool > req_rx; // The request associated with the input channel
sc_out < bool > ack_rx; // The outgoing ack signal associated with the input channel sc_out < Flit > flit_tx; // The output channel
sc_out < bool > req_tx; // The request associated with the output channel
sc_in < bool > ack_tx; // The outgoing ack signal associated with the output channel sc_in < int > free_slots_neighbor; //获取相邻Router中空闲VC的数目,类似credit?
// Registers
int local_id; // Unique identification number
bool current_level_rx; // Current level for Alternating Bit Protocol (ABP)交替位协议
bool current_level_tx; // Current level for Alternating Bit Protocol (ABP)
queue < Packet > packet_queue; // Local queue of packets
bool transmittedAtPreviousCycle; // Used for distributions with memory
ABP具有比特差错的丢包信道的可靠数据传输, 因为分组序号在0和1之间交替,因此有时被称为比特交替协议。
//Receiving and transmitting process
void rxProcess(); // The receiving process
void txProcess(); // The transmitting process
bool canShot(Packet & packet); // True when the packet must be shot
Flit nextFlit(); // Take the next flit of the current packet
//<-------receive packet
void ProcessingElement::rxProcess()
{
if (reset.read()) {//停止receive packet
ack_rx.write();//表示0已收到
current_level_rx = ;
}
else {//开始receive packet
if (req_rx.read() == - current_level_rx) {
Flit flit_tmp = flit_rx.read();
current_level_rx = - current_level_rx; // Negate the old value for Alternating Bit Protocol (ABP)
}
ack_rx.write(current_level_rx);
}
}
rxProcess()
//------->transmit packet
void ProcessingElement::txProcess()
{
if (reset.read()) {//停止transmit packet
req_tx.write();
current_level_tx = ;
transmittedAtPreviousCycle = false;
}
else {//开始transmit packet
Packet packet; if (canShot(packet)) {// True when the packet must be shot
packet_queue.push(packet);
transmittedAtPreviousCycle = true;// Used for distributions with memory
} else
transmittedAtPreviousCycle = false; if (ack_tx.read() == current_level_tx) {
if (!packet_queue.empty()) {
Flit flit = nextFlit(); // Generate a new flit
flit_tx->write(flit); // Send the generated flit
current_level_tx = - current_level_tx; // Negate the old value for Alternating Bit Protocol (ABP)
req_tx.write(current_level_tx);
}
}
}
}
txProcess()
bool ProcessingElement::canShot(Packet & packet)
{
#ifdef DEADLOCK_AVOIDANCE//条件编译
if (local_id % == )
return false;
#endif
bool shot;
double threshold; double now = sc_time_stamp().to_double() / GlobalParams::clock_period_ps; if (GlobalParams::traffic_distribution != TRAFFIC_TABLE_BASED) {
if (!transmittedAtPreviousCycle)
threshold = GlobalParams::packet_injection_rate;
else
threshold = GlobalParams::probability_of_retransmission; shot = (((double) rand()) / RAND_MAX < threshold);
if (shot) {
if (GlobalParams::traffic_distribution == TRAFFIC_RANDOM)
packet = trafficRandom();
else if (GlobalParams::traffic_distribution == TRAFFIC_TRANSPOSE1)
packet = trafficTranspose1();
else if (GlobalParams::traffic_distribution == TRAFFIC_TRANSPOSE2)
packet = trafficTranspose2();
else if (GlobalParams::traffic_distribution == TRAFFIC_BIT_REVERSAL)
packet = trafficBitReversal();
else if (GlobalParams::traffic_distribution == TRAFFIC_SHUFFLE)
packet = trafficShuffle();
else if (GlobalParams::traffic_distribution == TRAFFIC_BUTTERFLY)
packet = trafficButterfly();
else if (GlobalParams::traffic_distribution == TRAFFIC_LOCAL)
packet = trafficLocal();
else if (GlobalParams::traffic_distribution == TRAFFIC_ULOCAL)
packet = trafficULocal();
else
assert(false);//调用abort函数,结束程序执行
}
} else { // Table based communication traffic
if (never_transmit)
return false; bool use_pir = (transmittedAtPreviousCycle == false);
vector < pair < int, double > > dst_prob;
double threshold =
traffic_table->getCumulativePirPor(local_id, (int) now,
use_pir, dst_prob); double prob = (double) rand() / RAND_MAX;
shot = (prob < threshold);
if (shot) {
for (unsigned int i = ; i < dst_prob.size(); i++) {
if (prob < dst_prob[i].second) {
packet.make(local_id, dst_prob[i].first, now,
getRandomSize());
break;
}
}
}
}
return shot;
}
canShot(Packet & packet)
Flit ProcessingElement::nextFlit()
{
Flit flit;
Packet packet = packet_queue.front(); flit.src_id = packet.src_id;
flit.dst_id = packet.dst_id;
flit.timestamp = packet.timestamp;// Unix timestamp at packet generation
flit.sequence_no = packet.size - packet.flit_left;// The sequence number of the flit inside the packet
flit.sequence_length = packet.size;
flit.hop_no = ;// Current number of hops from source to destination
// flit.payload = DEFAULT_PAYLOAD; if (packet.size == packet.flit_left)
flit.flit_type = FLIT_TYPE_HEAD;
else if (packet.flit_left == )
flit.flit_type = FLIT_TYPE_TAIL;
else
flit.flit_type = FLIT_TYPE_BODY; packet_queue.front().flit_left--;
if (packet_queue.front().flit_left == )
packet_queue.pop(); return flit;
}
nextFlit()
//Traffic patterns
Packet trafficTest(); // used for testing traffic
Packet trafficRandom(); // Random destination distribution
Packet trafficTranspose1(); // Transpose 1 destination distribution
Packet trafficTranspose2(); // Transpose 2 destination distribution
Packet trafficBitReversal(); // Bit-reversal destination distribution
Packet trafficShuffle(); // Shuffle destination distribution
Packet trafficButterfly(); // Butterfly destination distribution
Packet trafficLocal(); // Random with locality
Packet trafficULocal(); // Random with locality
GlobalTrafficTable *traffic_table; // Reference to the Global traffic Table
bool never_transmit; // true if the PE does not transmit any packet
// (valid only for the table based traffic)
void fixRanges(const Coord, Coord &); // Fix the ranges of the destination
int randInt(int min, int max); // Extracts a random integer number between min and max
int getRandomSize(); // Returns a random size in flits for the packet
void setBit(int &x, int w, int v);
int getBit(int x, int w);
double log2ceil(double x); int roulett();
int findRandomDestination(int local_id,int hops);
int ProcessingElement::randInt(int min, int max)
{
//rand()返回一随机数值的范围在0至RAND_MAX 间
//rand() / (RAND_MAX + 1.0)产生一个概率
return min + (int) ((double) (max - min + ) * rand() / (RAND_MAX + 1.0));
}
randInt(int min, int max)
//Fix the ranges of the destination
void ProcessingElement::fixRanges(const Coord src, Coord & dst)
{
// Fix ranges
if (dst.x < )
dst.x = ;
if (dst.y < )
dst.y = ; if (dst.x >= GlobalParams::mesh_dim_x)
dst.x = GlobalParams::mesh_dim_x - ; if (dst.y >= GlobalParams::mesh_dim_y)
dst.y = GlobalParams::mesh_dim_y - ;
}
fixRanges(const Coord src, Coord & dst)
int ProcessingElement::getRandomSize()
{
return randInt(GlobalParams::min_packet_size, GlobalParams::max_packet_size);
}
getRandomSize()
//将x二进制倒数第w位设置为v
void ProcessingElement::setBit(int &x, int w, int v)
{
int mask = << w;//1左移w位 if (v == )
x = x | mask;//将x二进制中倒数第w位设置为1
else if (v == )
x = x & ~mask;//将x二进制中倒数第w位设置为0
else
assert(false);
}
setBit(int &x, int w, int v)
//获取x二进制倒数第w位
int ProcessingElement::getBit(int x, int w)
{
return (x >> w) & ;
}
getBit(int x, int w)
//返回大于或者等于log_x(2)的最小整数
inline double ProcessingElement::log2ceil(double x)
{
return ceil(log(x) / log(2.0));
}
log2ceil(double x)
// Constructor
SC_CTOR(ProcessingElement) {
SC_METHOD(rxProcess);//描述组合逻辑,由输入信号的变化触发
sensitive << reset;
sensitive << clock.pos();//clock.pos()表示在时钟上升沿触发,反之使用neg() SC_METHOD(txProcess);
sensitive << reset;//只要reset和clock.pos()的值发生变化, 进程txProcess就完整执行一遍
sensitive << clock.pos();
}