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

📄 eth_avalon_txdma.v

📁 ethernet wishbone interface
💻 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.                                                       ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//    History:
//      07/03/08 - Repaired bug with determining number of valid
//                 bytes corresponding to last data read from
//                 memory. Code was examining length field from
//                 descriptor input rather than registered
//                 descriptor data.
//
//      08/12/08 - Added logic to prevent FIFO overflows when 
//                 Avalon BUS has large latency.
//
module eth_avalon_txdma    #(parameter FIFO_DEPTH=128) (
    //Commaon signals
    input               clk,                // System clock
    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)

localparam  FIFO_MARGIN     = 5;            // Cushion between FIFO depth and our perceived depth
localparam  FIFO_THRESHOLD  = RFD - FIFO_MARGIN;

//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,  // Waiting for data to transmit
            TX_SEND     =   1,  // Sending transmit data
            TX_WAIT     =   2;  // Waiting for status from MAC

wire            pre_av_read;    // pre-registered avalon read signal
wire    [31:0]  pre_av_address; // pre_registered avalon address
wire            valid_tx_rd;    // Avalon bus acknowledged read

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

reg     [31:0]  ptr;            // Memory read pointer
reg     [31:0]  desc;           // Registered bd_desc
wire    [15:0]  desc_len;       // Frame length from stored descriptor

wire    [1:0]   valid_cnt;      // Number of valid bytes in current data word
reg     [1:0]   first_valid_cnt;// Number of valid bytes in first data word
reg     [1:0]   last_valid_cnt; // Number of valid bytes in last data word

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)
reg     [13:0]  rd_pending;     // Number of reads pending (used to gate reads for FIFO protection)
reg             pipe_hold;      // Hold the pipeline until some of the reads have come back
wire    [15:0]  next_tg_cnt;    // intentionally 2 bits larger
wire    [13:0]  next_rd_cnt;    // next value of rd_cnt
wire    [13:0]  next_wr_cnt;    // next value of wr_cnt

wire            last_read;      // Last read from memory
reg             last_read_r;    // Registered last_read
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;      // Data FIFO clear
wire    [clogb2(RFD-1)-1:0] dff_wrused; // Amount of space used in data FIFO
reg     [clogb2(RFD-1):0]   dff_used_la;// Future value of dff_wrused when all reads are finished
wire            dff_full;       // Data FIFO full
wire            dff_write;      // Data FIFO write
wire    [35:0]  dff_din;        // Data FIFO data input

wire            dff_read;       // Data FIFO read
wire            dff_empty;      // Data FIFO empty
wire    [35:0]  dff_dout;       // Data FIFO data output

reg     [2:0]   tx_state;       // Transmit state machine bits
reg             tx_stat_valid_r;// Registered tx_stat_valid
wire            tx_start;       // Start signal to transmit state machine
wire            last_byte;      // Indicates last valid byte of current data word
wire    [7:0]   tx_ff_data [0:3];// Transmit bytes from data FIFO
wire    [1:0]   byte_cnt;       // Indicates how many bytes are valid from data FIFO
reg     [1:0]   byte_index;     // Indexes tx_ff_data for byte transmission

//Avalon bus
assign  pre_av_address  = {ptr[31:2],2'b00};
assign  pre_av_read     = state[ST_DMA1 ] & ~pipe_hold;
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];
assign  desc_len    = 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

⌨️ 快捷键说明

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