文章目录
- 一、模块接口
- 二、模块功能描述
- 2.1、实现思路
- 三、仿真
- 3.1、仿真设计
- 3.2、仿真波形
- 总结:
一、模块接口
c0和c1表示输入的俩个数据通道,c0优先级高,P_ARBITER_LAYER 表示当前是在IP层进行仲裁还是MAC层,可复用于俩个模块。
module Abiter_module#(
parameter P_ARBITER_LAYER = 1
)(
input i_clk ,
input i_rst ,
input [63:0] s_axis_c0_data ,
input [79:0] s_axis_c0_user ,
input [7 :0] s_axis_c0_keep ,
input s_axis_c0_last ,
input s_axis_c0_valid ,
output s_axis_c0_ready ,
input [63:0] s_axis_c1_data ,
input [79:0] s_axis_c1_user ,
input [7 :0] s_axis_c1_keep ,
input s_axis_c1_last ,
input s_axis_c1_valid ,
output s_axis_c1_ready ,
output [63:0] m_axis_out_data ,
output [79:0] m_axis_out_user ,
output [7 :0] m_axis_out_keep ,
output m_axis_out_last ,
output m_axis_out_valid ,
input m_axis_out_ready
);
二、模块功能描述
MAC层负责接收来自IP层和ARP层的数据,IP层负责ICMP和UDP层数据,所以MAC层和IP层需要对上层协议的数据包进行仲裁,以决定先发送哪个上层数据。
于MAC层而言,ARP应当具有更高的优先级,于IP层而言,ICMP具有更高的优先级。
2.1、实现思路
输入数据全部先进入FIFO,当任何一个通道的FIFO不为空时,即可开启仲裁锁,因为此时必然会有一个通道获得仲裁结果。
随后便可以根据当前获得仲裁的通道开启相应的FIFO进行数据输出。
//r_arbiter_flag = 0表示通道0响应仲裁,为1表示通道1响应仲裁
//通道0具有更高的相应优先级
always @(posedge i_clk or posedge i_rst)begin
if(i_rst)
r_arbiter_flag <= 'd0;
else if(!w_fifo_c0_user_empty && !r_arbiter_lock)
r_arbiter_flag <= 'd0;
else if(!w_fifo_c1_user_empty && !r_arbiter_lock)
r_arbiter_flag <= 'd1;
else
r_arbiter_flag <= r_arbiter_flag;
end
//r_arbiter_lock表示仲裁锁,得到一次仲裁结果后,
//只有当前仲裁的通道将一个数据包完整输出后才可以响应下一次仲裁
always @(posedge i_clk or posedge i_rst)begin
if(i_rst)
r_arbiter_lock <= 'd0;
else if(r_send_cnt == r_pkt_len && r_arbiter_lock && r_pkt_len != 0)
r_arbiter_lock <= 'd0;
else if(!r_arbiter_lock && !w_fifo_c0_user_empty)
r_arbiter_lock <= 'd1;
else if(!r_arbiter_lock && !w_fifo_c1_user_empty)
r_arbiter_lock <= 'd1;
else
r_arbiter_lock <= r_arbiter_lock;
end
三、仿真
3.1、仿真设计
输入三组通道0数据以及俩组通道1数据,其中第一组通道0数据和第一组通道1数据是同时产生的
fork
begin
repeat(10)@(posedge clk);
send_c0();
repeat(10)@(posedge clk);
send_c0();
repeat(10)@(posedge clk);
send_c0();
end
begin
repeat(10)@(posedge clk);
send_c1();
repeat(10)@(posedge clk);
send_c1();
end
join
3.2、仿真波形
- 第一组通道0数据和第一组通道1数据同时输入,通道0获得仲裁,通道0数据输出。
- 第一组通道9数据输出完成后,此时检测到有一组通道1数据还在FIFO当中,并且暂时还没有输入新的通道0数据,于是通道1获得仲裁,输出通道1数据
- 通道1第一组数据输出完成。,此时通道0的FIFO当中已经存在俩组通道0数据了,他们的优先级都高于第二组通道1数据,于是连续发送俩次通道0数据,直到通道0的FIFO为空,第二组通道1数据才开始输出。
仿真波形与验证思路符合。
总结:
完成工程代码参考:https://github.com/shun6-6/Tri_Eth_UDP_pro_stack