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

📄 eth_avalon_txdma.v

📁 sopc builder 中网络的eth_ocm核
💻 V
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////
////                                                              ////
////  eth_avalon_txdma.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_txdma    #(parameter FIFO_DEPTH=128) (
    //Commaon signals
    input               clk,
    input               reset,

    //Descriptor ram interface
    input       [6:0]   max_tx_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
    input       [31:0]  av_readdata,        //Memory port readdata
    input               av_readdatavalid,   //Memory port readdata valid signal

    output  reg         av_read,            //Memory port read
    output  reg [31:0]  av_address,         //Memory port address

    //Streaming interface
    input               TxEn,               //Enable transmit
    input               txclk,              //Transmit clock
    output      [7:0]   tx_data,            //output data
    output              tx_dv,              //qualifies dataout, startofpacket, and endofpacket
    output              tx_sop,             //start of data packet
    output              tx_eop,             //end of data packet
    input               tx_ack,             //Acknowledge TX data
    input       [8:0]   tx_stat,            //Status bits
    input               tx_stat_valid,      //Status is valid
    output              tx_stat_ack,
    input               tx_retry,

    output              PerPacketPad,       //Per packet pad
    output              PerPacketCrc,       //Per packet crc
    output              TxUnderRun,         //An underrun occured

    //Interrupt outputs
    output  reg         TxB_IRQ,
    output  reg         TxE_IRQ 
);

//Some useful constant functions
`include "eth_avalon_functions.v"

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)

//FF_FULL_THRESHOLD is the number of words in the FIFO before we set the
//almost FULL flag. In other words. We pause reading data from memory if
//the FIFO reaches this level. If we are overrunning the FIFO, this
//number needs to be reduced.
localparam  FF_FULL_THRESHOLD = RFD - 16;

//Bit descriptions for TX descriptor
localparam  BIT_LEN_H   = 31,   //Upper bit of length field
            BIT_LEN_L   = 16,   //Lower bit of length field
            //Control bits
            BIT_READY   = 15,   //Ready control bit (1=READY Controller can write to it)
            BIT_IRQ     = 14,   //Generate an interrupt at end of TX
            BIT_WRAP    = 13,   //Wrap to first RX descriptor after this one
            BIT_PAD     = 12,   //Add Padding to small frames
            BIT_CRC     = 11,   //Add CRC
            BIT_RSVD_H  = 10,   //Upper bit of reserved field
            BIT_RSVD_L  = 9,    //Lower bit of reserved field
            //Status bits
            BIT_UR      = 8,    //Buffer Underrun
            BIT_RTRY_H  = 7,    //Upper bit of retry count
            BIT_RTRY_L  = 4,    //Lower bit of retry count
            BIT_RL      = 3,    //Retransmission Limit
            BIT_LC      = 2,    //Late Collision
            BIT_DF      = 1,    //Defer Indication
            BIT_CS      = 0;    //Carrier Sense Lost

//State bits
localparam  ST_IDLE     =   0,
            ST_BD_RD    =   1,  //Read Descriptor
            ST_DMA1     =   2,  //Transfer first word
            ST_DMA2     =   3,  //Wait for data to be written to FIFO 
            ST_STAT     =   4,  //Wait for status from MAC
            ST_BD_WR    =   5;  //Write status back to MAC

//TX State machine bits
localparam  TX_IDLE     =   0,
            TX_SEND     =   1,
            TX_WAIT     =   2;

wire            pre_av_read;
wire    [31:0]  pre_av_address;

reg     [5:0]   state;
wire    [15:0]  bd_len;         //Frame length from descriptor

reg     [31:0]  ptr;
reg     [31:0]  desc;

wire    [1:0]   valid_cnt;
reg     [1:0]   first_valid_cnt;
reg     [1:0]   last_valid_cnt;

reg     [13:0]  tg_cnt;         //target count (number of words to read from memory)
reg     [13:0]  rd_cnt;         //read count (number of words read from memory)
reg     [13:0]  wr_cnt;         //write count (number of words written to FIFO)
wire    [15:0]  next_tg_cnt;    //intentionally 2 bits larger
wire    [13:0]  next_rd_cnt;
wire    [13:0]  next_wr_cnt;

wire            last_read;      //Last read from memory
reg             last_read_r;
wire            first_write;    //First write to FIFO
wire            last_write;     //Last write to FIFO

reg     [31:0]  rdata;          //registered av_readdata
reg             valid_rdata;    //registered av_readdatavalid

wire            stat_ready;     //Status ready from TX
reg     [BIT_UR:BIT_CS] stat;
wire            stat_error;     //Status indicates error


wire            dff_clear;
wire    [clogb2(RFD-1):0]   dff_wrused;
wire            dff_almost_full;
wire            dff_full;
wire            dff_write;
wire    [35:0]  dff_din;

wire            dff_read;
wire            dff_empty;
wire    [35:0]  dff_dout;

reg     [2:0]   tx_state;
reg             tx_stat_valid_r;
wire            last_byte;
wire    [7:0]   tx_ff_data [0:3];
wire    [1:0]   byte_cnt;
reg     [1:0]   byte_index;

//Avalon bus
assign  pre_av_address  = {ptr[31:2],2'b00};
assign  pre_av_read     = state[ST_DMA1 ] & ~dff_almost_full;
assign  valid_tx_rd     = pre_av_read & ~av_waitrequest;

//Descriptor bus
assign  bd_read     = state[ST_BD_RD];
assign  bd_write    = state[ST_BD_WR];
//Descriptor writeback data
assign  bd_writedata[BIT_LEN_H:BIT_LEN_L]   = desc[BIT_LEN_H:BIT_LEN_L];    //No modification to length
assign  bd_writedata[BIT_READY]             = 1'b0;             // Clear ready flag
assign  bd_writedata[BIT_IRQ]               = desc[BIT_IRQ];    //leave IRQ
assign  bd_writedata[BIT_WRAP]              = desc[BIT_WRAP];   //leave WRAP
assign  bd_writedata[BIT_PAD]               = desc[BIT_PAD];    //leave PAD
assign  bd_writedata[BIT_CRC]               = desc[BIT_CRC];    //leave CRC
assign  bd_writedata[BIT_RSVD_H:BIT_RSVD_L] = desc[BIT_RSVD_H:BIT_RSVD_L]; //leave reserved field
assign  bd_writedata[BIT_UR:BIT_CS]         = stat[BIT_UR:BIT_CS];  //set status flags

assign  bd_len      = bd_desc[BIT_LEN_H:BIT_LEN_L];

//Add a pipeline stage for Avalon reads
always @(posedge clk or posedge reset)
    if(reset)                   av_read     <= 1'b0;
    else if(~av_waitrequest)    av_read     <= pre_av_read;

always @(posedge clk)
        if(~av_waitrequest)     av_address  <= pre_av_address;

always @(posedge clk or posedge reset)
    if(reset)                                       state   <= 6'd1;
    else begin                                      state   <= 6'd0;
        //This really is a parallel case 
        case(1'b1) // synopsys parallel_case 
            state[ST_IDLE ]: // do nothing
                if(TxEn & ~stat_ready)              state[ST_BD_RD] <= 1'b1;
                else                                state[ST_IDLE]  <= 1'b1;
            state[ST_BD_RD]: // read descriptor
                if(~bd_wait & bd_desc[BIT_READY])   state[ST_DMA1 ] <= 1'b1;
                else                                state[ST_BD_RD] <= 1'b1;
            state[ST_DMA1 ]: // issue all reads
                if(valid_tx_rd & last_read)
                                                    state[ST_DMA2 ] <= 1'b1;
                else                                state[ST_DMA1 ] <= 1'b1;
            state[ST_DMA2 ]: // wait here for stat                    
                if(last_write & valid_rdata)        state[ST_STAT ] <= 1'b1;
                else                                state[ST_DMA2 ] <= 1'b1;

⌨️ 快捷键说明

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