📄 generic_receive_fifo.v
字号:
/////////////////////////////////////////////////////////////////////////////////// Project: 1 Gig Ethernet MAC FIFO Reference Design// Version: 2.0// File : generic_receive_fifo.v//// Company: Xilinx// Contributors: Xilinx Inc.//// Disclaimer: 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, AND 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 AND FITNESS FOR A PARTICULAR// PURPOSE.//// (c) Copyright 2003 Xilinx, Inc.// All rights reserved.///////////////////////////////////////////////////////////////////////////////////// Receiver MAC => Backend Generic Interface// Author: Xilinx Inc.//// Description: This module is the interface between the 1 Gigabit Ethernet // MAC Receiver and the Client Interface to the Receiver FIFO. //// Functionality:// 1. The module writes the 8-bit data words received from the // MAC into a 16-bit word FIFO. Thus two 8-bit words must // arrive to complete a single entry into the FIFO. Words // read out of the FIFO are 16-bits wide.// 2. The module completes each frame by appending a code word to // it. This states whether or not errors were detected in the // frame by the MAC Receiver as well as acting as a // recognisable spacer between the frames.// 3. The Clock used to synchronise reading of the FIFO can be at // a different clock rate to that used by the MAC Receiver to // write to the FIFO.// 4. The module provides full, empty, nearly full, and nearly // empty flags. This has been performed by converting the // binary read and write pointers of the FIFO into GRAY Codes, // from which accurate flags can be produced. Please refer to // Xilinx Application Note 131 for a complete description of // this logic.// /////////////////////////////////////////////////////////////////////////////////`timescale 1 ps / 1 ps module GENERIC_RECEIVE_FIFO ( RX_CLK, RX_SRESET, RX_FIFO_SRESET, RX_DATA, RX_DATA_VALID, GOOD_FRAME, BAD_FRAME, FIFO_CLK, RD_ENABLE, NEARLY_EMPTY_THRESH, NEARLY_FULL_HIGH_THRESH, NEARLY_FULL_LOW_THRESH, RD_ACK, RD_ERR, DATA_OUT, DATA_VALID_OUT, STATUS_FULL, STATUS_EMPTY, STATUS_NEARLY_FULL_HIGH, STATUS_NEARLY_FULL_LOW, STATUS_NEARLY_EMPTY ); // CHANGES REQUIRED parameter FIFO_SIZE = 1024; // 512, 1024, 2048, 4096, 8192 or 16384 words. parameter log2_FIFO_SIZE = (FIFO_SIZE == 512 ? 9 : (FIFO_SIZE == 1024 ? 10 : (FIFO_SIZE == 2048 ? 11 : (FIFO_SIZE == 4096 ? 12 : (FIFO_SIZE == 8192 ? 13 : 14))))); input RX_CLK; // MAC Receiver clock. input RX_SRESET; // Synchronous Reset. input RX_FIFO_SRESET; input [7:0] RX_DATA; // Data from MAC Receiver. input RX_DATA_VALID; // Indication of valid bytes for RX_DATA. input GOOD_FRAME; // The previous MAC Frame contained no errors. input BAD_FRAME; // The previous MAC Frame contained errors. input FIFO_CLK; // The Host/Backend Clock. input RD_ENABLE; input [log2_FIFO_SIZE-1:0] NEARLY_EMPTY_THRESH; // Nearly Empty Threshold. input [log2_FIFO_SIZE-1:0] NEARLY_FULL_HIGH_THRESH; // Nearly Full High Threshold. input [log2_FIFO_SIZE-1:0] NEARLY_FULL_LOW_THRESH; // Nearly Full Low Threshold. output RD_ACK; // Data was successfully read from RX_FIFO. output RD_ERR; // Data was not successfully read from RX_FIFO. output [15:0] DATA_OUT; // Data to be read by Backend Bus. output [1:0] DATA_VALID_OUT ; // Indicates valid bytes of RD_DATA. output STATUS_FULL; // Status indicator that RX_FIFO is full. output STATUS_EMPTY; // Status indicator that RX_FIFO is empty. output STATUS_NEARLY_FULL_HIGH;// Status indicator that RX_FIFO is almost full. output STATUS_NEARLY_FULL_LOW; // Status indicator that RX_FIFO is almost full. output STATUS_NEARLY_EMPTY; // Status indicator that RX_FIFO is almost empty. wire LOGIC1; wire LOGIC0; reg WR_UPPER; // Registered WE request for upper FIFO word. reg WR_LOWER; // Registered WE request for lower FIFO word. wire WR_UPPER_COMB; // WE request for upper FIFO word. wire WR_LOWER_COMB; // WE request for lower FIFO word. wire WR_UPPER_ALLOW; // WE grant for upper FIFO word. wire WR_LOWER_ALLOW; // WE grant for lower FIFO word. reg [log2_FIFO_SIZE-1:0] WR_ADDR; // Write Address of FIFO reg [log2_FIFO_SIZE-1:0] WR_GRAY; // WR_ADDR as a Gray Code. reg [log2_FIFO_SIZE-1:0] WR_TRUEGRAY; // WR_GRAY registered. reg [log2_FIFO_SIZE-1:0] WR_NEXTGRAY; // Next Gray Code Write Address. reg [log2_FIFO_SIZE-1:0] WR_ADDRGRAY; // Current Gray Code Write Address. reg [log2_FIFO_SIZE-1:0] WR_LASTGRAY; // Previous Gray Code Write Address. reg [log2_FIFO_SIZE-1:0] RD_ADDR; // Read Address of FIFO reg [log2_FIFO_SIZE-1:0] RD_NEXTGRAY; // Next Gray Code Read Address. reg [log2_FIFO_SIZE-1:0] RD_ADDRGRAY; // Current Gray Code Read Address. reg [log2_FIFO_SIZE-1:0] RD_LASTGRAY; // Previous Gray Code Read Address. reg [log2_FIFO_SIZE-1:0] HOST_WR_ADDRGRAY; // WR_NEXTGRAY on FIFO_CLK. wire [log2_FIFO_SIZE-1:0] HOST_WR_ADDR; // WR_ADDR on FIFO_CLK. reg [7:0] RX_DATA_REG; // RX_DATA after 1 clock. reg [15:0] RX_DATA_16BIT; // Combined 2 8-bit words. reg RX_DATA_VALID_REG1; // RX_DATA_VALID after 1 clock. reg RX_DATA_VALID_REG2; // RX_DATA_VALID after 2 clocks. reg [1:0] DATA_VALID_2BIT; // Combined 2 1-bit valids. reg GOOD_FRAME_HELD; // GOOD_FRAME held constant. reg BAD_FRAME_HELD; // BAD_FRAME held constant. reg TRIGGER_CODEWORD; // initiated by good or bad frames. reg TRIGGER_CODEWORD_REG; // TRIGGER_CODEWORD after 1 clock. reg FULL_HELD; // FULL held for code word. reg LAST_VALID_HELD; // RX_DATA_VALID held for code word. wire RD_ALLOW; // A read can be made from the FIFO. reg FULL; // The FIFO is full. reg REALLY_EMPTY; // The FIFO is empty. reg [log2_FIFO_SIZE-1:0] OCCUPANCY; // The FIFO Occupancy. wire [log2_FIFO_SIZE-1:0] EMPTY_COMPARE; // FIFO Empty Comparator. wire [log2_FIFO_SIZE-1:0] EMPTY_MUXCYO; // Comparator Carry-chain. wire [log2_FIFO_SIZE-1:0] FULL_COMPARE; // FIFO Full Comparator. wire [log2_FIFO_SIZE-1:0] FULL_MUXCYO; // Comparator Carry-chain. reg [log2_FIFO_SIZE-2:0] FRAME_COUNT; // Count how many frames in FIFO (max of 5 times smaller than FIFO) wire [log2_FIFO_SIZE-4:0] FRAME_COUNT_ZERO; // := (others => '0'); wire FRAME_WRITE; // Indicate when a frame is starting to be read reg FRAME_READ_FIFO; // Indicates when a frame has been written in clk domain reg FRAME_READ; // Indicate when a frame has been written in tx_clk domain reg FRAME_READ_REG; wire [1:0] DATA_VALID_OUT_INT; reg FRAME_COUNT_EMPTY ; // Indicate when no complete frames in FIFO reg RD_ACK_INT; reg FRAME_WRITE_HELD; reg FRAME_READ_FIFO_HOLD; reg TRIGGER_CODEWORD_REG_REG; reg FRAME_READ_ADD; reg CODE_READ; reg CODE_READ_REG; reg CODE_READ_FIFO; reg RD_ERR; reg STATUS_FULL; wire STATUS_EMPTY; reg STATUS_NEARLY_FULL_HIGH; reg STATUS_NEARLY_FULL_LOW; reg STATUS_NEARLY_EMPTY; reg GOOD_BAD_FRAME_RECENT; wire FRAME_RECEIVE; reg FRAME_RECEIVE_REG; integer i; assign DATA_VALID_OUT = DATA_VALID_OUT_INT; assign LOGIC1 = 1'b1; assign LOGIC0 = 1'b0; assign RD_ACK = RD_ACK_INT; assign FRAME_COUNT_ZERO = 0;/*------------------------------------------------------------------------------------- THE FOLLOWING CODE CREATES THE FIFO WRITE LOGIC FOR THE MAC RECEIVER DATA -------------------------------------------------------------------------------------*/// purpose: Reclock Signals for pipelined logic. // type : sequential always @(posedge RX_CLK) begin if(RX_SRESET == 1'b1) begin RX_DATA_VALID_REG1 <= 1'b0; RX_DATA_VALID_REG2 <= 1'b0; RX_DATA_REG <= 0; end else begin RX_DATA_VALID_REG1 <= RX_DATA_VALID; RX_DATA_VALID_REG2 <= RX_DATA_VALID_REG1; RX_DATA_REG <= RX_DATA; end end // purpose: Capture Signals for the code word. // type : sequential always @(posedge RX_CLK) begin if(RX_SRESET == 1'b1) begin GOOD_FRAME_HELD <= 1'b0; BAD_FRAME_HELD <= 1'b0; TRIGGER_CODEWORD <= 1'b0; TRIGGER_CODEWORD_REG <= 1'b0; TRIGGER_CODEWORD_REG_REG <= 1'b0; FULL_HELD <= 1'b0; LAST_VALID_HELD <= 1'b0; end else begin GOOD_FRAME_HELD <= (GOOD_FRAME | GOOD_FRAME_HELD) & (~BAD_FRAME); BAD_FRAME_HELD <= (BAD_FRAME | BAD_FRAME_HELD) & (~GOOD_FRAME); TRIGGER_CODEWORD <= (GOOD_FRAME | BAD_FRAME) & (!GOOD_BAD_FRAME_RECENT); TRIGGER_CODEWORD_REG <= TRIGGER_CODEWORD; TRIGGER_CODEWORD_REG_REG <= TRIGGER_CODEWORD_REG; if (RX_DATA_VALID_REG2 == 1'b1) // update only during frame reception. begin FULL_HELD <= FULL; LAST_VALID_HELD <= RX_DATA_VALID_REG1; end end end // purpose: Determine if any data has been received in frame// type : Sequential always @(posedge RX_CLK) begin if (RX_SRESET == 1'b1 || GOOD_FRAME == 1'b1 || BAD_FRAME == 1'b1) GOOD_BAD_FRAME_RECENT <= 1'b1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -