万兆以太网MAC设计(9)数据流仲裁模块

一、模块接口

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、仿真波形

  1. 第一组通道0数据和第一组通道1数据同时输入,通道0获得仲裁,通道0数据输出。
  2. 第一组通道9数据输出完成后,此时检测到有一组通道1数据还在FIFO当中,并且暂时还没有输入新的通道0数据,于是通道1获得仲裁,输出通道1数据
  3. 通道1第一组数据输出完成。,此时通道0的FIFO当中已经存在俩组通道0数据了,他们的优先级都高于第二组通道1数据,于是连续发送俩次通道0数据,直到通道0的FIFO为空,第二组通道1数据才开始输出。

仿真波形与验证思路符合。

在这里插入图片描述

总结:

完成工程代码参考:https://github.com/shun6-6/Tri_Eth_UDP_pro_stack

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顺子学不会FPGA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值