⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eth_avalon_rxdma.v

📁 sopc builder 中网络的eth_ocm核
💻 V
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////
////                                                              ////
////  eth_avalon_rxdma.v                                          ////
////                                                              ////
////  This file is a patch used in conjunction with the           ////
////  Ethernet IP core project.                                   ////
////  http://www.opencores.org/projects/ethmac/                   ////
////                                                              ////
////  Author(s):                                                  ////
////      - Jakob Jones (jrjonsie@gmail.com)                      ////
////                                                              ////
////  All additional information is available in the Readme.txt   ////
////  file.                                                       ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
module  eth_avalon_rxdma   #(  parameter FIFO_DEPTH = 4096) (
    //Commaon signals
    input               clk,
    input               reset,

    //Descriptor ram interface
    input       [6:0]   max_rx_bd,          //Highest index RX Descriptor
    input       [31:0]  bd_desc,            //Descriptor Control data input
    input       [31:0]  bd_ptr,             //Descriptor pointer input
    input               bd_wait,            //Descriptor RAM is busy

    output              bd_write,           //write control data to BD RAM
    output              bd_read,            //read control and pointer data from BD RAM
    output  reg [6:0]   bd_index,           //Which descriptor to read
    output      [31:0]  bd_writedata,       //Control data to be written to descriptor

    //Memory port interface
    input               av_waitrequest,     //Memory port is busy

    output  reg         av_write,           //Memory port write
    output  reg [31:0]  av_address,         //Memory port address
    output  reg [31:0]  av_writedata,       //Memory port writedata
    output  reg [3:0]   av_byteenable,      //Memory port byteenable

    //Streaming interface
    input               RxEn,               //Receive Enable
    input               rxclk,              //Receive clock
    input       [7:0]   rx_data,            //input data
    input               rx_dv,              //qualifies datain, startofpacket, and endofpacket
    input       [8:0]   rx_err,             //error bits
    input               rx_sop,             //start of data packet
    input               rx_eop,             //end of data packet

    //Interrupt outputs
    output  reg         RxB_IRQ,
    output  reg         RxE_IRQ,
    output              Busy_IRQ  
);

`include "eth_avalon_functions.v"

//Let's determine the FIFO Depths. We use two FIFOs. One to pass data.
//and one to pass error information. The error FIFO does not need to be as
//large because it is only written to on an end of packet. We'll make the
//assumption that normally packets will be a minimum of 64 bytes long. So
//We divide the FIFO depth by 64 to get the Error FIFO depth. To be on the
//safe side, we double that number (really divide by 32). If Either one of
//these FIFOs overflow, on overrun will occur.
localparam  MINFD   = max(FIFO_DEPTH,128);  //Minimum 128 byte FIFO depth
localparam  RFD     = nextPow2(MINFD)>>2; //FIFO depth next power of 2 (and divide by 4)
localparam  EFD     = max((RFD>>3), 4);     //Minimum error FIFO depth of 4

//Descriptor status bit defines
localparam  BIT_LEN_H   = 31,   //Upper bit of length field
            BIT_LEN_L   = 16,   //Lower bit of length field
            //Control bits
            BIT_EMPTY   = 15,   //Empty control bit (1=EMPTY Controller can write to it)
            BIT_IRQ     = 14,   //Generate an interrupt at end of RX
            BIT_WRAP    = 13,   //Wrap to first RX descriptor after this one
            BIT_RSVD_H  = 12,   //Upper bit of reserved field
            BIT_RSVD_L  = 11,   //Lower bit of reserved field
            //Status bits
            BIT_CF      = 8,    //Control Frame was received
            BIT_M       = 7,    //Miss
            BIT_OR      = 6,    //FIFO overrun
            BIT_IS      = 5,    //Invalid Symbol
            BIT_DN      = 4,    //Dribble Nibble
            BIT_TL      = 3,    //Frame too long
            BIT_SF      = 2,    //Frame short
            BIT_CRC     = 1,    //CRC error
            BIT_LC      = 0;    //Late Collision

//DMA State Machine Bits
localparam  ST_IDLE     =   0,
            ST_BD_RD    =   1,
            ST_DMA1     =   2,
            ST_DMA2     =   3,
            ST_BD_WR    =   4;

//RX State Machine Bits
localparam  RX_IDLE = 0,
            RX_REC  = 1,
            RX_DISC = 2,
            RX_EOP  = 3;

//Avalon interface signals
wire    [31:0]  pre_av_writedata;
wire    [3:0]   pre_av_byteenable;
wire            pre_av_write;
wire    [31:0]  pre_av_address;

//Descriptor signals
reg     [31:0]  desc;       //Descriptor control word
reg     [31:0]  ptr;        //Write pointer (from descriptor)
reg     [15:0]  len;        //Length counter

//DMA controller signals
reg     [5:0]   state;      //One-hot state machine bits
wire    [1:0]   cnt;        //Valid byte count (out of FIFO);
wire            eop;        //End of packet flag (out of FIFO)
wire            err_r;

reg             first_write;//First write to memory
wire    [3:0]   lsb_be;     //LSB byteenable (First write)
wire    [12:0]  msb_be;
reg     [2:0]   msb_be2;
wire    [63:0]  sdata;      //shifted data
wire            rx_write;
wire            valid_rx_wr;

//FIFO Signals
//(DMA side)
wire            dff_empty;  //data FIFO empty
wire    [35:0]  dff_dout;   //data FIFO output  
reg     [35:0]  dff_dout_r; //registered dff_out
wire            dff_read;   //data FIFO read

wire            eff_empty;  //error FIFO empty
wire    [8:0]   eff_dout;   //error FIFO output
reg     [8:0]   eff_dout_r; //registered eff_dout
wire            eff_read;   //error FIFO read
//(Streaming Side)
wire    [35:0]  dff_in;         // data fifo input data
reg     [7:0]   dff_in_reg[3:0];// registered incoming data word (to make a x4)
reg     [3:0]   dff_stat;       // {errors,eop,#valid bytes}
wire            dff_wr;         // write data to FIFO
wire            dff_full;       // data FIFO full
wire            eff_wr;
wire            eff_full;

//Streaming interface signals
reg     [3:0]   rx_state;   // RX state bits
reg     [1:0]   rx_cnt;     // # of valid bytes in data word
reg             rx_wr;      // indicates normal write to FIFO
wire            rx_rdy;     // indicates FIFO is ready to receive (not full)
reg             rx_overrun; // an overrun as occurred
wire    [8:0]   rx_res;     // RX result (errors and status)

//*****************************************************************************
//************************* Avalon Interface Logic ****************************
always @(posedge clk or posedge reset)
    if(reset)                   av_write    <= 1'b0;
    else if(~av_waitrequest)    av_write    <= pre_av_write;

always @(posedge clk)
    if(~av_waitrequest) begin
                        av_writedata    <= pre_av_writedata;
                        av_address      <= pre_av_address;
                        av_byteenable   <= pre_av_byteenable;
    end
//*********************** End Avalon Interface Logic **************************
//*****************************************************************************

//*****************************************************************************
//************************** DMA Interface Logic ******************************

assign  err_r       = dff_dout_r [35];
assign  eop         = dff_dout   [34];
assign  cnt         = dff_dout   [33:32];

//Avalon Memory Master interface
assign  pre_av_writedata    = sdata[63:32];
assign  pre_av_byteenable   =  first_write     ?   lsb_be: 
                            state[ST_DMA2 ] ?   {1'b0,msb_be2}:
                            msb_be[9:6];

assign  pre_av_address      = {ptr[31:2],2'b00};
assign  pre_av_write        = rx_write;

assign  rx_write    = (state[ST_DMA1] & ~dff_empty) | (state[ST_DMA2] & ~eff_empty);
assign  valid_rx_wr = rx_write & ~av_waitrequest;
assign  dff_read    = state[ST_DMA1] & ~dff_empty & ~av_waitrequest;
assign  eff_read    = state[ST_DMA2] & ~eff_empty & ~av_waitrequest;

//Shift data for unaligned transfers
assign  sdata   = {dff_dout[31:0], dff_dout_r[31:0]}  << {ptr[1:0],3'd0};
//Shift byteenable for first unaligned transfer
assign  lsb_be  = 4'b1111 << ptr[1:0];
assign  msb_be  = 13'b0000001111111 << ({1'b0,ptr[1:0]} + {1'b0,cnt});

//State machine (one-hot) encoding
always @(posedge clk or posedge reset)
    if(reset)   begin                               state           <= 5'd0;
                                                    state[ST_IDLE]  <= 1'b1;
    end else begin
        /*default case-->*/                         state           <= 5'd0;
        case(1'b1) // synopsys parallel_case 
            state[ST_IDLE ]:
                if(RxEn)                            state[ST_BD_RD] <= 1'b1;
                else                                state[ST_IDLE ] <= 1'b1;
            state[ST_BD_RD]:    
                if(~bd_wait & bd_desc[BIT_EMPTY])   state[ST_DMA1 ] <= 1'b1;
                else                                state[ST_BD_RD] <= 1'b1;
            state[ST_DMA1 ]:
                if(valid_rx_wr & eop)               state[ST_DMA2 ] <= 1'b1;
                else                                state[ST_DMA1 ] <= 1'b1;
            state[ST_DMA2 ]: 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -