万兆以太网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

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-04-26 06:14:08       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-26 06:14:08       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-26 06:14:08       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-26 06:14:08       20 阅读

热门阅读

  1. DAC音频解码芯片DP7398立体声数模转换芯片

    2024-04-26 06:14:08       10 阅读
  2. Apache Flink 流处理-[CentOS|Rocky] 镜像

    2024-04-26 06:14:08       14 阅读
  3. 使用Python实现简单的Web服务器

    2024-04-26 06:14:08       18 阅读
  4. 【C语言】内存泄漏调试方式

    2024-04-26 06:14:08       13 阅读
  5. 记录如何用php将敏感文字内容替换为星号的方法

    2024-04-26 06:14:08       15 阅读
  6. Mybatis 动态Sql标签使用总结

    2024-04-26 06:14:08       11 阅读
  7. redis模糊查询redis中的key

    2024-04-26 06:14:08       13 阅读
  8. 深入理解Spring Boot钩子函数

    2024-04-26 06:14:08       12 阅读
  9. c# 实现gif转化,视频合成,提取视频帧等

    2024-04-26 06:14:08       16 阅读