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

📄 tx_client_fifo_8.v

📁 Xilinx Virtex5 SGMII高速串行通信例程。
💻 V
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// Title      : 8-bit Client to Local-link Transmitter FIFO
// Project    : Virtex-5 Ethernet MAC Wrappers
//-----------------------------------------------------------------------------
// File       : tx_client_fifo_8.v
// Author     : Xilinx
//-----------------------------------------------------------------------------
// Copyright (c) 2004-2007 by Xilinx, Inc. All rights reserved.
// This text/file contains proprietary, confidential
// information of Xilinx, Inc., is distributed under license
// from Xilinx, Inc., and may be used, copied and/or
// disclosed only pursuant to the terms of a valid license
// agreement with Xilinx, Inc. Xilinx hereby grants you
// a license to use this text/file solely for design, simulation,
// implementation and creation of design files limited
// to Xilinx devices or technologies. Use with non-Xilinx
// devices or technologies is expressly prohibited and
// immediately terminates your license unless covered by
// a separate agreement.
//
// Xilinx is providing this design, code, or information
// "as is" solely for use in developing programs and
// solutions for Xilinx devices. By providing this design,
// code, or information as one possible implementation of
// this feature, application or standard, Xilinx is making no
// representation that this implementation is free from any
// claims of infringement. You are responsible for
// obtaining any rights you may require for your implementation.
// Xilinx expressly disclaims any warranty whatsoever with
// respect to the adequacy of the implementation, including
// but not limited to any warranties or representations that this
// implementation is free from claims of infringement, implied
// warranties of merchantability or fitness for a particular
// purpose.
//
// Xilinx products are not intended for use in life support
// appliances, devices, or systems. Use in such applications are
// expressly prohibited.
//
// This copyright and support notice must be retained as part
// of this text at all times. (c) Copyright 2004-2007 Xilinx, Inc.
// All rights reserved.
//-----------------------------------------------------------------------------
// Description: This is a transmitter side local link fifo implementation for
//              the design example of the Virtex-5 Ethernet MAC Wrapper
//              core.
//              
//              The transmit FIFO is created from 2 Block RAMs of size 2048
//              words of 8-bits per word, giving a total frame memory capacity
//              of 4096 bytes.
//
//              Valid frame data received from local link interface is written
//              into the Block RAM on the write clock.  The FIFO will store
//              frames upto 4kbytes in length.  If larger frames are written
//              to the FIFO the local-link interface will accept the rest of the
//              frame, but that frame will be dropped by the FIFO and
//              the overflow signal will be asserted.
//
//              The FIFO is designed to work with a minimum frame length of 14 bytes.
//              
//              When there is at least one complete frame in the FIFO,
//              the MAC transmitter client interface will be driven to
//              request frame transmission by placing the first byte of
//              the frame onto tx_data[7:0] and by asserting
//              tx_data_valid.  The MAC will later respond by asserting
//              tx_ack.  At this point the remaining frame data is read
//              out of the FIFO in a continuous burst. Data is read out
//              of the FIFO on the rd_clk.
//
//              If the generic FULL_DUPLEX_ONLY is set to false, the FIFO will
//              requeue and retransmit frames as requested by the MAC.  Once a
//              frame has been transmitted by the FIFO it is stored until the
//              possible retransmit window for that frame has expired.
//
//              The FIFO has been designed to operate with different clocks
//              on the write and read sides. The write clock (locallink clock)
//              can be an equal or faster frequency than the read clock (client clock).
//              The minimum write clock frequency is the read clock frequency divided
//              by 2.5.
//
//              The FIFO memory size can be increased by expanding the rd_addr
//              and wr_addr signal widths, to address further BRAMs.
//
//-----------------------------------------------------------------------------

`timescale 1ps / 1ps


module tx_client_fifo_8
    (
        // MAC Interface
        rd_clk,
        rd_sreset,
        rd_enable,
        tx_data,
        tx_data_valid,
        tx_ack,
        tx_collision,
        tx_retransmit,
        overflow,
        
        // Local-link Interface
        wr_clk,
        wr_sreset,
        wr_data,
        wr_sof_n,
        wr_eof_n,
        wr_src_rdy_n,
        wr_dst_rdy_n,
        wr_fifo_status
        );

  //---------------------------------------------------------------------------
  // Define Interface Signals
  //---------------------------------------------------------------------------

  // MAC Interface
  input        rd_clk;
  input        rd_sreset;
  input        rd_enable;
  output [7:0] tx_data;
  output       tx_data_valid;
  input        tx_ack;
  input        tx_collision;
  input        tx_retransmit;
  output       overflow;
        
  // Local-link Interface
  input        wr_clk;
  input        wr_sreset;
  input  [7:0] wr_data;
  input        wr_sof_n;
  input        wr_eof_n;
  input        wr_src_rdy_n;
  output       wr_dst_rdy_n;
  output [3:0] wr_fifo_status;
  
  // If FULL_DUPLEX_ONLY is 1 then all the half duplex logic in the FIFO is removed.
  // The default for the fifo is to include the half duplex functionality 
  parameter    FULL_DUPLEX_ONLY = 0;
  
  reg [7:0]    tx_data;
  reg 	       tx_data_valid;
  reg [3:0]    wr_fifo_status;
 

  //---------------------------------------------------------------------------
  // Define Internal Signals
  //---------------------------------------------------------------------------

  wire        GND;
  wire        VCC;
  wire [7:0]  GND_BUS;

  // Encode rd_state_machine states   
  parameter  IDLE_s = 4'b0000;      parameter  QUEUE1_s = 4'b0001;
  parameter  QUEUE2_s = 4'b0010;    parameter  QUEUE3_s = 4'b0011;
  parameter  QUEUE_ACK_s = 4'b0100; parameter  WAIT_ACK_s = 4'b0101;
  parameter  FRAME_s = 4'b0110;     parameter  DROP_s = 4'b0111;
  parameter  RETRANSMIT_s = 4'b1000;

  reg  [3:0]  rd_state;
  reg  [3:0]  rd_nxt_state;

  // Encode wr_state_machine states 
  parameter WAIT_s = 2'b00;  parameter DATA_s = 2'b01;
  parameter EOF_s = 2'b10;   parameter OVFLOW_s = 2'b11;

  reg  [1:0]  wr_state;
  reg  [1:0]  wr_nxt_state;
  
  reg  [7:0]  wr_data_bram;
  reg  [7:0]  wr_data_pipe[0:1]; 
  reg         wr_sof_pipe[0:1];
  reg         wr_eof_pipe[0:1];
  reg         wr_accept_pipe[0:1];
  reg 	      wr_accept_bram;
  reg  [0:0]  wr_eof_bram;
  reg  [11:0] wr_addr;
  wire	      wr_addr_inc;
  wire        wr_start_addr_load;
  wire	      wr_addr_reload;
  reg  [11:0] wr_start_addr;
  reg         wr_fifo_full;  
  wire        wr_en;
  wire        wr_en_u;
  wire	      wr_en_l;
  reg         wr_ovflow_dst_rdy;
  wire        wr_dst_rdy_int_n;

  reg         frame_in_fifo;
  reg         frame_in_fifo_sync;
  reg         rd_eof;
  reg         rd_eof_reg;
  reg 	      rd_eof_pipe; 
  reg  [11:0] rd_addr;
  wire        rd_addr_inc;
  wire        rd_addr_reload;
  wire [7:0]  rd_data_bram_u;
  wire [7:0]  rd_data_bram_l;
  reg  [7:0]  rd_data_pipe_u;
  reg  [7:0]  rd_data_pipe_l;
  reg  [7:0]  rd_data_pipe;
  wire [0:0]  rd_eof_bram_u;
  wire [0:0]  rd_eof_bram_l;
  wire        rd_en;
  wire        rd_en_bram;
  reg 	      rd_bram_u;
  reg 	      rd_bram_u_reg;

  reg         rd_tran_frame_tog;
  reg         wr_tran_frame_tog;
  reg         wr_tran_frame_sync;
  reg         wr_tran_frame_delay;
  reg         rd_retran_frame_tog;
  reg         wr_retran_frame_tog;
  reg         wr_retran_frame_sync;
  reg         wr_retran_frame_delay;
  wire        wr_store_frame;
  wire        wr_eof_state;
  reg         wr_eof_state_reg;
  reg         wr_transmit_frame;
  reg         wr_retransmit_frame;
  reg  [8:0]  wr_frames;
  reg         wr_frame_in_fifo;
  
  reg   [3:0] rd_16_count;
  wire        rd_txfer_en;
  reg  [11:0] rd_addr_txfer;
  reg         rd_txfer_tog;
  reg         wr_txfer_tog;
  reg         wr_txfer_tog_sync;
  reg         wr_txfer_tog_delay;
  wire        wr_txfer_en;
  reg  [11:0] wr_rd_addr;
  reg  [11:0] wr_addr_diff;

  reg         rd_drop_frame;
  reg         rd_retransmit;
  reg  [11:0] rd_start_addr;
  wire        rd_start_addr_load;
  wire	      rd_start_addr_reload;

  reg  [11:0] rd_dec_addr;

  wire        rd_transmit_frame;
  wire        rd_retransmit_frame;
  reg         rd_col_window_expire;
  reg         rd_col_window_pipe[0:1];
  reg         wr_col_window_pipe[0:1];
  
  wire 	      wr_fifo_overflow;  
  reg  [9:0]  rd_slot_timer;
  reg         wr_col_window_expire;
  wire        rd_idle_state;

  reg         rd_enable_delay;
  reg         rd_enable_delay2;
   
  //---------------------------------------------------------------------------
  // Attributes for FIFO simulation and synthesis
  //---------------------------------------------------------------------------
  // ASYNC_REG attributes added to simulate actual behaviour under
  // asynchronous operating conditions.
  // synthesis attribute ASYNC_REG of wr_tran_frame_tog is "TRUE";
  // synthesis attribute ASYNC_REG of wr_retran_frame_tog is "TRUE";
  // synthesis attribute ASYNC_REG of frame_in_fifo_sync is "TRUE";
  // synthesis attribute ASYNC_REG of wr_rd_addr is "TRUE";
  // synthesis attribute ASYNC_REG of wr_txfer_tog is "TRUE";
  // synthesis attribute ASYNC_REG of wr_col_window_pipe[0] is "TRUE";

  // WRITE_MODE attributes added to Block RAM to mitigate port contention
  // synthesis attribute WRITE_MODE_A of ramgen_u is "READ_FIRST";
  // synthesis attribute WRITE_MODE_B of ramgen_u is "READ_FIRST";
  // synthesis attribute WRITE_MODE_A of ramgen_l is "READ_FIRST";
  // synthesis attribute WRITE_MODE_B of ramgen_l is "READ_FIRST";



  //---------------------------------------------------------------------------
  // Begin FIFO architecture
  //---------------------------------------------------------------------------
   
  assign GND = 1'b0;
  assign VCC = 1'b1;
  assign GND_BUS = 8'b0;

  always @(posedge rd_clk)
  begin
     rd_enable_delay <= rd_enable;
     rd_enable_delay2 <= rd_enable_delay;
  end
  
  //---------------------------------------------------------------------------
  // Write State machine and control
  //---------------------------------------------------------------------------
  // Write state machine
  // states are WAIT, DATA, EOF, OVFLOW
  // clock through next state of sm
  always @(posedge wr_clk)
  begin
     if (wr_sreset == 1'b1)
         wr_state <= WAIT_s;
     else
         wr_state <= wr_nxt_state;
  end
  
  // decode next state, combinitorial
  // should never be able to overflow whilst not in the data state.
  always @(wr_state or wr_sof_pipe[1] or wr_eof_pipe[0] or wr_eof_pipe[1] or wr_eof_bram[0] or wr_fifo_overflow)
  begin
  case (wr_state)
     WAIT_s : begin
        if (wr_sof_pipe[1] == 1'b1)
           wr_nxt_state <= DATA_s;
        else
           wr_nxt_state <= WAIT_s;
        end
     DATA_s : begin
        // wait for the end of frame to be detected
        if (wr_fifo_overflow == 1'b1 && wr_eof_pipe[0] == 1'b0 && wr_eof_pipe[1] == 1'b0)
           wr_nxt_state <= OVFLOW_s;
        else if (wr_eof_pipe[1] == 1'b1)
           wr_nxt_state <= EOF_s;
        else
           wr_nxt_state <= DATA_s;
        end
     EOF_s : begin
        // if the start of frame is already in the pipe, a back to back frame
        // transmission has occured.  move straight back to frame state
        if (wr_sof_pipe[1] == 1'b1)


           wr_nxt_state <= DATA_s;
        else if (wr_eof_bram[0] == 1'b1)
           wr_nxt_state <= WAIT_s;
        else
           wr_nxt_state <= EOF_s;
        end
     OVFLOW_s : begin
        // wait until the end of frame is reached before clearing the overflow
        if (wr_eof_bram[0] == 1'b1)
           wr_nxt_state <= WAIT_s;
        else
           wr_nxt_state <= OVFLOW_s;
        end
     default : begin
        wr_nxt_state <= WAIT_s;
	end
  endcase
  end

   
  // decode output signals.
  assign wr_en = (wr_state == OVFLOW_s) ? 1'b0 : wr_accept_bram;
  assign wr_en_l = wr_en & !wr_addr[11];
  assign wr_en_u = wr_en & wr_addr[11];
 
  assign wr_addr_inc = wr_en;
  
  assign wr_addr_reload = (wr_state == OVFLOW_s) ? 1'b1 : 1'b0;
  assign wr_start_addr_load = (wr_state == EOF_s && wr_nxt_state == WAIT_s) ? 1'b1 : 
                              (wr_state == EOF_s && wr_nxt_state == DATA_s) ? 1'b1 : 1'b0;


  // pause the local link flow when the fifo is full.
  assign wr_dst_rdy_int_n = (wr_state == OVFLOW_s) ? wr_ovflow_dst_rdy : wr_fifo_full;
  assign wr_dst_rdy_n = wr_dst_rdy_int_n;
 
  // when in overflow and have captured ovflow eof send dst rdy high again.
  assign overflow = (wr_state == OVFLOW_s) ? 1'b1 : 1'b0;
  
  // when in overflow and have captured ovflow eof send dst rdy high again.
  always @(posedge wr_clk)
  begin
     if (wr_sreset == 1'b1)
        wr_ovflow_dst_rdy <= 1'b0;
     else
        begin
        if (wr_fifo_overflow == 1'b1 && wr_state == DATA_s)
            wr_ovflow_dst_rdy <= 1'b0;
        else if (wr_eof_n == 1'b0 && wr_src_rdy_n == 1'b0)
            wr_ovflow_dst_rdy <= 1'b1;
        end
  end

    // eof signals for use in overflow logic
  assign wr_eof_state = (wr_state == EOF_s) ? 1'b1 : 1'b0;

  always @(posedge wr_clk)
  begin
     if (wr_sreset == 1'b1)
        wr_eof_state_reg <= 1'b0;
     else
        wr_eof_state_reg <= wr_eof_state;
  end
   
  //---------------------------------------------------------------------------
  // Read state machine and control
  //---------------------------------------------------------------------------

  // clock through the read state machine
  always @(posedge rd_clk)
  begin
     if (rd_sreset == 1'b1)
        rd_state <= IDLE_s;
     else if (rd_enable == 1'b1)
        rd_state <= rd_nxt_state;
  end

  //---------------------------------------------------------------------------
  // Full Duplex Only State Machine
generate if (FULL_DUPLEX_ONLY == 1) begin : gen_fd_sm
  // decode the next state
  always @(rd_state or frame_in_fifo or rd_eof or tx_ack)
  begin
  case (rd_state)
           IDLE_s : begin
              // if there is a frame in the fifo start to queue the new frame
              // to the output
              if (frame_in_fifo == 1'b1)
                 rd_nxt_state <= QUEUE1_s;
              else
                 rd_nxt_state <= IDLE_s;
              end
           QUEUE1_s : begin

⌨️ 快捷键说明

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