设为首页 加入收藏

TOP

FPGA设计千兆以太网MAC(3)——数据缓存及位宽转换模块设计与验证(一)
2019-08-24 00:06:49 】 浏览:181
Tags:FPGA 设计 千兆 以太网 MAC 数据 转换 模块 验证

  本文设计思想采用明德扬至简设计法。上一篇博文中定制了自定义MAC IP的结构,在用户侧需要位宽转换及数据缓存。本文以TX方向为例,设计并验证发送缓存模块。这里定义该模块可缓存4个最大长度数据包,用户根据需求改动即可。

  该模块核心是利用异步FIFO进行跨时钟域处理,位宽转换由VerilogHDL实现。需要注意的是用户数据包位宽32bit,因此包尾可能有无效字节,而转换为8bit位宽数据帧后是要丢弃无效字节的。内部逻辑非常简单,直接上代码:

  1 `timescale 1ns / 1ps
  2 
  3 // Description: MAC IP TX方向用户数据缓存及位宽转换模块
  4 // 整体功能:将TX方向用户32bit位宽的数据包转换成8bit位宽数据包
  5 //用户侧时钟100MHZ,MAC侧125MHZ
  6 //缓存深度:保证能缓存4个最长数据包,TX方向用户数据包包括
  7 //目的MAC地址  源MAC地址 类型/长度 数据 最长1514byte
  8 
  9 
 10 module tx_buffer#(parameter DATA_W = 32)//位宽不能改动
 11 (
 12     
 13     //全局信号
 14     input                         rst_n,//保证拉低三个时钟周期,否则FIF可能不会正确复位
 15 
 16     //用户侧信号
 17     input                         user_clk,
 18     input         [DATA_W-1:0]     din,
 19     input                         din_vld,
 20     input                         din_sop,
 21     input                         din_eop,
 22     input         [2-1:0]         din_mod,
 23     output                         rdy,
 24 
 25     //MAC侧信号
 26     input                         eth_tx_clk,
 27     output reg     [8-1:0]         dout,
 28     output reg                     dout_sop,
 29     output reg                     dout_eop,
 30     output reg                     dout_vld
 31     );
 32 
 33 
 34     reg wr_en = 0;
 35     reg [DATA_W+4-1:0] fifo_din = 0;
 36     reg [ (2-1):0]  rd_cnt = 0     ;
 37     wire        add_rd_cnt ;
 38     wire        end_rd_cnt ;
 39     wire rd_en;
 40     wire [DATA_W+4-1:0] fifo_dout;
 41     wire rst;
 42     reg [ (2-1):0]  rst_cnt =0    ;
 43     wire        add_rst_cnt ;
 44     wire        end_rst_cnt ;
 45     reg rst_flag = 0;
 46     wire [11 : 0] wr_data_count;
 47     wire empty;
 48     wire full;
 49 
 50 /****************************************写侧*************************************************/
 51 always  @(posedge user_clk or negedge rst_n)begin
 52     if(rst_n==1'b0)begin
 53         wr_en <= 0;
 54     end
 55     else if(rdy)
 56         wr_en <= din_vld;
 57 end
 58 
 59 always  @(posedge user_clk or negedge rst_n)begin
 60     if(rst_n==1'b0)begin
 61         fifo_din <= 0; 
 62     end
 63     else begin//[35] din_sop    [34] din_eop    [33:32] din_mod    [31:0] din
 64         fifo_din <= {din_sop,din_eop,din_mod,din};
 65     end
 66 end
 67 
 68 assign rdy = wr_data_count <= 1516 && !rst && !rst_flag && !full;
 69 
 70 /****************************************读侧*************************************************/
 71 
 72 always @(posedge eth_tx_clk or negedge rst_n) begin 
 73     if (rst_n==0) begin
 74         rd_cnt <= 0; 
 75     end
 76     else if(add_rd_cnt) begin
 77         if(end_rd_cnt)
 78             rd_cnt <= 0; 
 79         else
 80             rd_cnt <= rd_cnt+1 ;
 81    end
 82 end
 83 assign add_rd_cnt = (!empty);
 84 assign end_rd_cnt = add_rd_cnt  && rd_cnt == (4)-1 ;
 85 
 86 assign rd_en = end_rd_cnt;
 87 
 88 always  @(posedge eth_tx_clk or negedge rst_n)begin
 89     if(rst_n==1'b0)begin
 90         dout <= 0;
 91     end
 92     else if(add_rd_cnt)begin
 93         dout <= fifo_dout[DATA_W-1-rd_cnt*8 -:8];
 94     end
 95 end
 96 
 97 always  @(posedge eth_tx_clk or negedge rst_n)begin
 98     if(rst_n==1'b0)begin
 99         dout_vld <= 0;
100     end
101     else if(add_rd_cnt && ((rd_cnt <= 3 - fifo_dout[33:32] && fifo_dout[34]) || !fifo_dout[34]))begin
102         dout_vld <= 1;
103     end
104     else
105         dout_vld <= 0;
106 end
107 
108 always  @(posedge eth_tx_clk or negedge rst_n)begin
109     if(rst_n==1'b0)begin
110         dout_sop <= 0;
111     end
112     else if(add_rd_cnt && rd_cnt == 0 && fifo_dout[35])begin
113         dout_sop <= 1;
114     end
115     else
116         dout_sop <= 0 ;
117 end
118 
119 always  @(posedge eth_tx_clk or negedge rst_n)begin
120     if(rst_n==1'b0)begin
121         dout_eop <= 0;
122     end
123     else if(add_rd_cnt && rd_cnt == 3 - fifo_dout[33:32] && fifo_dout[34])b
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇基于FPGA的DDS设计(一) 下一篇FPGA驱动VGA显示静态图片

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目