credit_based流控机制
- [1 credit_based way](#1 credit_based way)
-
- [1.1 Principle](#1.1 Principle)
- [1.3 DFD](#1.3 DFD)
- [1.4 Module](#1.4 Module)
-
- [1.4.1 Interface](#1.4.1 Interface)
- [1.4.2 Code Block](#1.4.2 Code Block)
在网络芯片处理大流量报文中,一般主要是两种机制:1.valid--ready反压(backpressure)机制;2.credit信用机制;
credit机制的好处是可以不用考虑链路的延时;帮助能够自适应调整数据的数据速率;
让我联想到了海底捞的门外取号和叫号的概念
1 credit_based way
1.1 Principle
生产者-->消费者模型;即发送端-->接收端;
基于credit流控思路:发送端发送到接收端,需要提前知道信用值(credits);通过在发送端维护credits(本质上是计数器)进行控制发送发送端发送数据;
有credit值才会继续发送数据Data;
进一步原理如下图所示:在接收端放buffer,一般也是FiFo;在发送端进行发送数据时,内部会有credit信用机制,发送端每发送一次data,会进行credit--;发送端入队FiFO,拿走一个在返回一个Taken给发送端,发送端内部credit++;
这样发送端内部不断对credit>0进行判断,来判断是否能够发出;
在本质一点,credits维护可以放在发送端也可以接收端;在这里是以放在发送端;
credit基本上等于接收端的FiFo的深度;
1.3 DFD
进一步基本逻辑框图如下图所示,在这里主要是针对credit_tracker模块的原理,用来维护credits来进行流量控制;
通过逻辑框图来指导模块代码;
1.4 Module
1.4.1 Interface
在这里不用表格单独列出来了,如上图所示;
1.4.2 Code Block
在这里给出基本伪代码,没有进行逻辑验证,仅供参考;
verilog
//--Auther :colonel
//--Date :2024-05-22
//--Function :credit_based for flow control
//--History :Description
//--05/22 :Firstly create the file
//
module credit_tracker#(
parameter WIDTH = 4
)(
input clk,
input rst_n,
input [WIDTH -1:0] crdt_limit,
input send,
input taken,
output reg has_crdt,
output reg[WIDTH -1:0] crdt_left
);
reg [WIDTH -1:0] crdt_cnt;
wire[WIDTH -1:0] nxt_crdt_cnt = crdt_cnt;//Inital
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
crdt_cnt <= 0;
end else begin
crdt_cnt <= nxt_crdt_cnt;
end
end
always@(*) begin
if(send && !taken && (crdt_cnt != (1<<WIDTH) -1)) begin
nxt_crdt_cnt = crdt_cnt + 1;
end else if(!send && taken && (crdt_cnt!=0)) begin
nxt_crdt_cnt = crdt_cnt - 1;
end
end
always@(posedge clk or negedge rst_n) begin
if(nxt_crdt_cnt < crdt_limit) begin
has_crdt <= 1'b1;
crdt_left<= crdt_limit - nxt_crdt_cnt;
end else begin
has_crdt <= 1'b0;
crdt_left<= 0;
end
end
endmodule
以上仅是我个人的理解和学习,有不对的还请能够帮助指导指正;
Reference:
[1] https://blog.csdn.net/weixin_44260459/article/details/120757630