Verilog开源项目——百兆以太网交换机(八)包缓存模块设计
🔈声明:未经作者允许,禁止转载
😃博主主页:王_嘻嘻的CSDN主页
🔑全新原创以太网交换机项目,Blog内容将聚焦整体架构、模块设计方面;更新周期可能会略慢,希望朋友们多多包涵
🧡关注本专题的朋友们可以学习到原创交换机设计的全流程,包括设计与验证(FPGA)。
🚩第一代交换机 — 从零开始 verilog 以太网交换机系列专栏:点击这里
💥第二代交换机 — Atom(百兆以太网交换机)专栏:点击这里
包缓存模块负责在Atom查询目的端口时,缓存接收到的Packet,以保证在多种场景下端口不会拥塞。Atom DB(DataBuffer)支持2MB的缓存空间,并支持按队列优先级提供QoS服务。
一、Feature
- 数据交换能力支持400 Mbps;
- 支持2MB的数据交换空间;
- 链表形式存储LPH、payload,支持快速drop Packet;
- 支持Packet优先级管理;
- 支持DB -> PM多种仲裁输出方式;
- 支持根据space size和space threshold,向MAC发送pause frame插入信号;
- 支持Flush功能;
- 支持每个优先级队列空间的配置,支持全局共享空间设置;
- 支持多播、广播包的拆分处理,统计广播包被连续反压次数;
二、概述
DB(data buffer)负责在查询目标端口,以及Packet处理过程中缓存大量Packet,Atom支持2MB数据的缓存空间。此外DB还支持按优先级的方式管理缓存,以支持QoS。
当Packet被存入Common Buffer Pool后,会分成LPH和Payload两部分存储,查询过程中仅传输LPH。当查询结束后,Packet的LPH和Payload都将转移到输出队列中,等待PM主动拉取Packet。
三、接口
四、功能设计
a)缓存管理
为了增加有效传输效率,DB与TBM之间仅传输LPH,另一方面,如果LPH和Payload在同一memory中存储,考虑到LPH需要频繁读写,会影响PF->DB和DB->PM通路,所以Atom将使用256x16k和256x64k两块ram分别存储LPH和Payload。
使用下图数据结构管理LPH和Payload,为了减少Pointer数量,Payload将以4x256-bits为单位,若一个Packet没有用完,该单位也不能再被使用。使用两块memory存放LPH的next_pointer和LPH本体,LPH指向Payload的pointer可以从LPH中获取,Payload之间的Pointer存放在free pointer list中。
考虑到PM由于QoS和风暴控制策略导致DB drop Packet的场景,DB需要支持快速drop的功能,以提高drop效率。为此,DB将保存每个Packet Payload链表最后一个pointer,将该packet tail pointer放在LPH中一并存储。
通过上述结构,可以在需要drop时,直接修改free pointer list的tail pointer,来完成drop操作。
LPH Pointer List(LPL)
由于DB通过TBM查询到dst Port后,会将Packet按优先级放到发送队列上,所以对LPH而言,DB中存在17条队列,8条接收队列,8条发送队列,1条空闲队列,每条队列都需要记录各自的头尾指针,以便管理,队列结构如下。
Payload Pointer List(PPL)
PPL和LPL结构相同,同样包括17条队列,只不过存储的是Payload pointer,在此不重复说明。
Receive packet flow
- 根据LPH.priority确定LPH所需前往的链表;
- 确定链表是否还有空间存放Packet,若空间不足,根据配置策略操作;
- 若空间足够,将LPH写入LPL.free list.head pointer中,同时将next LPH pointer和next Payload pointer同步存入LPH本体中,并更新LPL.link list pointer;
根据读取LPL.free list.head pointer读取下一个free list pointer,作为新的LPL.free list.head pointer; - 将Payload写入PPL.free list.head pointer中,一个地址可连续写入4拍Payload,Packet间不交叠使用,并更新PPL.link list pointer;
根据PPL.free list.head pointer读取下一个free list pointer,作为新的PPL.free list.head pointer; - 当写入最后一拍Payload后,以LPH pointer作为地址,向Frame tail buffer中写入payload tail pointer;
Search Port flow
- 当DB接收Packet后,根据仲裁策略,选择一个优先级;
- 根据对应TC的LPL.link list head pointer读取LPH内容,并发送至TBM,此时仅更新LPL.rx.link list head pointer,不做freelist更新;
- 等待TBM返回搜索完毕的LPH(该过程中DB仍可以不断执行1、2);
- 根据TBM返回的LPH,链入LPL.tx.link list tail pointer,并把Payload.rx link list链到tx link list;
Send packet flow
Send packet flow与receive packet flow类似
- 根据QoS策略和PM状态,选择一个tx队列,向PM发送Packet;
- 根据LPL.link list head pointer读出LPH内容和next LPH pointer,获得Payload head pointer,并向后发送该LPH,及更新LPL.link list head pointer;
- 释放LPH pointer;
- 根据Payload head pointer,按顺序读取所有Payload,并使用next LPH pointer,读取新的Payload pointer作为PPL.link list head pointer
- 释放PLP pointer;
Note:因为DB处理TBM乱序包需要修改LPL和PPL的中间链表,影响效率和性能,所以TBM的rsp会进行保序处理。
Drop packet flow
当PM的风暴控制或QoS控制达到较严重程度时,会要求DB直接丢弃对应队列的Packet,如果DB仍然一拍拍drop,遇到huge packet时,将严重影响其它队列性能,所以DB设计了一种快速drop的机制。
- 确定tx.link list仲裁到的队列是否需要drop;
- 根据LPL.link list head pointer读出LPH内容和next LPH pointer,获得Payload head pointer,更新LPL.link list head pointer;
- 通过next LPH pointer,拿到next packet.Payload head pointer,以及next Packet.tail pointer,更新PPL.tx.link list head pointer为next packet.Payload head pointer;
- 释放LPH pointer和Payload pointer,更新原始PPL.free list pointer的next pointer,更新PPL.free list tail pointer;
b)List Space Config
Atom DB根据寄存器可对内部空间进行静态分配:
- 全局模式:当设置为全局模式时,8条优先级链表共享2MB缓存空间,采用先到先得模式;
- 局部模式:每条链表配置了固定空间,并留有一部分空间作为共享空间,禁制越界使用其它链表空间;
两种模式下都需实时监控空间使用情况,并输出给CSR以供上层监测。
c)Flush
Atom flush分为global flush和link-list flush,会在LPH中的flush type区分,flush flow中,DB只需要保证接收到的flush packet不要乱序,它一直保持链表中的位置。当DB把标有flush bit的Packet送给PM后,PM会结束flush flow,并上报。
需要注意,收到flush后,并不绝对保证对应优先级后面没有Packet继续进入DB。
若有不专业或错误之处,欢迎指正!
具体电路实现及验证环境代码会在准备完毕后开源,目前暂时不能给出,请见谅
搜索关注我的微信公众号【IC墨鱼仔】,获取我的更多IC干货分享!