Gem5 Flit类

本文是对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 对象分解成多个具有相同属性的新对象,并将它们返回,函数的参数如下:

  1. ser_id:整数,表示当前要序列化的 flit 对象在新序列中的 ID。
  2. parts:整数,表示要序列化的 flit 对象在新序列中的数量。
  3. 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 对象恢复到原始状态,函数的参数如下:

  1. des_id:整数,表示当前要恢复的 flit 对象在新序列中的 ID。
  2. num_flits:整数,表示要恢复的 flit 对象在新序列中的数量。
  3. 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);
}

分别用于读取和写入消息:

  1. functionalRead(Packet *pkt, WriteMask &mask)用于从消息中读取数据。它接受一个 Packet 类型的对象 pkt 和一个 WriteMask 类型的 &mask 作为参数。函数首先获取消息对象的指针 msg,然后调用该对象的 functionalRead 函数,将数据从消息中读取到 pkt 中,并更新 mask,最后返回读取操作值

  2. functionalWrite(Packet *pkt)用于将数据写入消息。它接受一个 Packet 类型的对象 pkt 为参数,函数首先获取消息对象的指针 msg,然后调用该对象的 functionalWrite 函数,将数据从 pkt 中写入消息中,最后返回写入操作值

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值