本文是对Flit的学习记录
定义:
各种TYPE的定义:
src/mem/ruby/network/garnet/CommonTypes.hh:
enum flit_type {HEAD_, BODY_, TAIL_, HEAD_TAIL_,CREDIT_, NUM_FLIT_TYPE_};
enum VC_state_type {IDLE_, VC_AB_, ACTIVE_, NUM_VC_STATE_TYPE_};
enum VNET_type {CTRL_VNET_, DATA_VNET_, NULL_VNET_, NUM_VNET_TYPE_};
enum flit_stage {I_, VA_, SA_, ST_, LT_, NUM_FLIT_STAGE_};
enum link_type {EXT_IN_, EXT_OUT_, INT_, NUM_LINK_TYPES_ };
enum RoutingAlgorithm {TABLE_ = 0, XY_ = 1, CUSTOM_ = 2,NUM_ROUTING_ALGORITHM_};
src/mem/ruby/network/garnet/flit.cc:
用C++构造Flit函数,附带参数如下:
flit::flit(int packet_id, int id, int vc, int vnet, RouteInfo route, int size,
MsgPtr msg_ptr, int MsgSize, uint32_t bWidth, Tick curTime)
{
m_size = size;
m_msg_ptr = msg_ptr;
m_enqueue_time = curTime;
m_dequeue_time = curTime;
m_time = curTime;
m_packet_id = packet_id;
m_id = id;
m_vnet = vnet;
m_vc = vc;
m_route = route;
m_stage.first = I_;
m_stage.second = curTime;
m_width = bWidth;
msgSize = MsgSize;
//定义m_XXX实参接受形参
if (size == 1) {
m_type = HEAD_TAIL_;
return;
}
if (id == 0)
m_type = HEAD_;
else if (id == (size - 1))
m_type = TAIL_;
else
m_type = BODY_;
//划分Flit
}
补充RouteInfo:::src/mem/ruby/network/garnet/CommonTypes.hh
RouteInfo用于存储路由的信息:
struct RouteInfo
{
RouteInfo()
: vnet(0), src_ni(0), src_router(0), dest_ni(0), dest_router(0),
hops_traversed(0)
{}
// destination format for table-based routing
int vnet;
NetDest net_dest;
// src and dest format for topology-specific routing
int src_ni;
int src_router;
int dest_ni;
int dest_router;
int hops_traversed;
};
serialize()
flit flit::serialize(int ser_id, int parts, uint32_t bWidth)
{
assert(m_width > bWidth);
int ratio = (int)divCeil(m_width, bWidth); //应该是向上取整
int new_id = (m_id*ratio) + ser_id;
int new_size = (int)divCeil((float)msgSize, (float)bWidth);
assert(new_id < new_size);
flit *fl = new flit(m_packet_id, new_id, m_vc, m_vnet, m_route,
new_size, m_msg_ptr, msgSize, bWidth, m_time);
fl->set_enqueue_time(m_enqueue_time);
fl->set_src_delay(src_delay);
return fl;
}
serialize函数
用于将一个 flit
对象分解成多个具有相同属性的新对象,并将它们返回,函数的参数如下:
ser_id
:整数,表示当前要序列化的flit
对象在新序列中的 ID。parts
:整数,表示要序列化的flit
对象在新序列中的数量。bWidth
:无符号整数,表示要将flit
对象分解成具有多少位宽度的子对象。
函数首先计算 flit
对象在新序列中的比例(ratio)和新的 ID。然后,根据新的比例和 ID 计算新序列的大小(new_size)。接着,为每个子对象分配一个新的 ID,并创建一个新的 flit
对象,函数的返回值是一个指向新序列中第一个对象的指针。
对于新创建的每个子对象,函数都会设置其基本属性,如消息大小、消息内容、传输带宽等。
deserialize()
flit *flit::deserialize(int des_id, int num_flits, uint32_t bWidth)
{
int ratio = (int)divCeil((float)bWidth, (float)m_width);
int new_id = ((int)divCeil((float)(m_id+1), (float)ratio)) - 1;
int new_size = (int)divCeil((float)msgSize, (float)bWidth);
assert(new_id < new_size);
flit *fl = new flit(m_packet_id, new_id, m_vc, m_vnet, m_route,
new_size, m_msg_ptr, msgSize, bWidth, m_time);
fl->set_enqueue_time(m_enqueue_time);
fl->set_src_delay(src_delay);
return fl;
}
函数名为 deserialize
,用于将一个具有多个子对象的 flit
对象恢复到原始状态,函数的参数如下:
des_id
:整数,表示当前要恢复的flit
对象在新序列中的 ID。num_flits
:整数,表示要恢复的flit
对象在新序列中的数量。bWidth
:无符号整数,表示要将flit
对象分解成具有多少位宽度的子对象。
函数的返回值是一个指向恢复后 flit
对象的指针。
函数内部首先计算 flit
对象在新序列中的比例(ratio)和新的 ID。然后,根据新的比例和 ID 计算新序列的大小(new_size)。接着,为每个子对象分配一个新的 ID,并创建一个新的 flit
对象。
对于新创建的每个子对象,函数都会设置其基本属性,如消息大小、消息内容、传输带宽等。
print()
void flit::print(std::ostream& out) const
{
out << "[flit:: ";
out << "PacketId=" << m_packet_id << " ";
out << "Id=" << m_id << " ";
out << "Type=" << m_type << " ";
out << "Size=" << m_size << " ";
out << "Vnet=" << m_vnet << " ";
out << "VC=" << m_vc << " ";
out << "Src NI=" << m_route.src_ni << " ";
out << "Src Router=" << m_route.src_router << " ";
out << "Dest NI=" << m_route.dest_ni << " ";
out << "Dest Router=" << m_route.dest_router << " ";
out << "Set Time=" << m_time << " ";
out << "Width=" << m_width<< " ";
out << "]";
}
functionalRead()、functionalWrite()
bool flit::functionalRead(Packet *pkt, WriteMask &mask)
{
Message *msg = m_msg_ptr.get();
return msg->functionalRead(pkt, mask);
}
bool flit::functionalWrite(Packet *pkt)
{
Message *msg = m_msg_ptr.get();
return msg->functionalWrite(pkt);
}
分别用于读取和写入消息:
-
functionalRead(Packet *pkt, WriteMask &mask)
用于从消息中读取数据。它接受一个Packet
类型的对象pkt
和一个WriteMask
类型的 &mask
作为参数。函数首先获取消息对象的指针msg
,然后调用该对象的functionalRead
函数,将数据从消息中读取到pkt
中,并更新mask,
最后返回读取操作值 -
functionalWrite(Packet *pkt)
用于将数据写入消息。它接受一个Packet
类型的对象pkt
为参数,函数首先获取消息对象的指针msg
,然后调用该对象的functionalWrite
函数,将数据从pkt
中写入消息中,最后返回写入操作值