📄 rx_client_fifo_8.v
字号:
//-----------------------------------------------------------------------------
// Title : 8-bit Client to Local-link Receiver FIFO
// Project : Virtex-5 Ethernet MAC Wrappers
//-----------------------------------------------------------------------------
// File : rx_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 the receiver side local link fifo for the design example
// of the Virtex-5 Ethernet MAC Wrapper core.
//
// The 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.
//
// Frame data received from the MAC receiver is written into the
// FIFO on the wr_clk. An End Of Frame marker is written to the
// BRAM parity bit on the last byte of data stored for a frame.
// This acts as frame deliniation.
//
// The rx_good_frame and rx_bad_frame signals are used to
// qualify the frame. A frame for which rx_bad_frame was
// asserted will cause the FIFO write address pointer to be
// reset to the base address of that frame. In this way
// the bad frame will be overwritten with the next received
// frame and is therefore dropped from the FIFO.
//
// Frames will also be dropped from the FIFO if an overflow occurs.
// If there is not enough memory capacity in the FIFO to store the
// whole of an incoming frame, the write address pointer will be
// reset and the overflow signal asserted.
//
// When there is at least one complete frame in the FIFO,
// the 8 bit Local-link read interface will be enabled allowing
// data to be read from the fifo.
//
// The FIFO has been designed to operate with different clocks
// on the write and read sides. The read clock (locallink clock)
// should always operate at an equal or faster frequency
// than the write clock (client clock).
//
// The FIFO is designed to work with a minimum frame length of 8 bytes.
//
// The FIFO memory size can be increased by expanding the rd_addr
// and wr_addr signal widths, to address further BRAMs.
//
// Requirements :
// * Minimum frame size of 8 bytes
// * Spacing between good/bad frame flags is at least 64 clock cycles
// * Wr clock is 125MHz downto 1.25MHz
// * Rd clock is downto 20MHz
//
//-------------------------------------------------------------------------------
`timescale 1ps / 1ps
module rx_client_fifo_8
(
// Local-link Interface
rd_clk,
rd_sreset,
rd_data_out,
rd_sof_n,
rd_eof_n,
rd_src_rdy_n,
rd_dst_rdy_n,
rx_fifo_status,
// Client Interface
wr_sreset,
wr_clk,
wr_enable,
rx_data,
rx_data_valid,
rx_good_frame,
rx_bad_frame,
overflow
);
//---------------------------------------------------------------------------
// Define Interface Signals
//--------------------------------------------------------------------------
// Local-link Interface
input rd_clk;
input rd_sreset;
output [7:0] rd_data_out;
output rd_sof_n;
output rd_eof_n;
output rd_src_rdy_n;
input rd_dst_rdy_n;
output [3:0] rx_fifo_status;
// Client Interface
input wr_sreset;
input wr_clk;
input wr_enable;
input [7:0] rx_data;
input rx_data_valid;
input rx_good_frame;
input rx_bad_frame;
output overflow;
reg rd_sof_n;
reg rd_src_rdy_n;
reg [7:0] rd_data_out;
//---------------------------------------------------------------------------
// Define Internal Signals
//---------------------------------------------------------------------------
wire GND;
wire VCC;
wire [7:0] GND_BUS;
// Encode rd_state_machine states
parameter WAIT_s = 3'b000; parameter QUEUE1_s = 3'b001;
parameter QUEUE2_s = 3'b010; parameter QUEUE3_s = 3'b011;
parameter QUEUE_SOF_s = 3'b100; parameter SOF_s = 3'b101;
parameter DATA_s = 3'b110; parameter EOF_s = 3'b111;
reg [2:0] rd_state;
reg [2:0] rd_nxt_state;
// Encode wr_state_machine states
parameter IDLE_s = 3'b000; parameter FRAME_s = 3'b001;
parameter END_s= 3'b010; parameter GF_s = 3'b011;
parameter BF_s = 3'b100; parameter OVFLOW_s = 3'b101;
reg [2:0] wr_state;
reg [2:0] wr_nxt_state;
wire wr_en;
wire wr_en_u;
wire wr_en_l;
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 [7:0] wr_data_bram;
reg [7:0] wr_data_pipe[0:1];
reg [0:0] wr_eof_bram;
reg wr_dv_pipe[0:1];
reg wr_gf_pipe[0:1];
reg wr_bf_pipe[0:1];
reg frame_in_fifo;
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;
reg rd_en;
reg rd_bram_u;
reg rd_bram_u_reg;
wire rd_pull_frame;
reg rd_eof;
reg wr_store_frame_tog;
reg rd_store_frame_tog;
reg rd_store_frame_delay;
reg rd_store_frame_sync;
reg rd_store_frame;
reg [8:0] rd_frames;
reg wr_fifo_full;
reg [11:0] rd_addr_gray;
reg [11:0] wr_rd_addr_gray_sync;
reg [11:0] wr_rd_addr_gray;
wire [11:0] wr_rd_addr;
reg [11:0] wr_addr_diff;
reg [3:0] wr_fifo_status;
reg rd_eof_n_int;
//---------------------------------------------------------------------------
// Attributes for FIFO simulation and synthesis
//---------------------------------------------------------------------------
// ASYNC_REG attributes added to simulate actual behaviour under
// asynchronous operating conditions.
// synthesis attribute ASYNC_REG of rd_store_frame_tog is "TRUE";
// synthesis attribute ASYNC_REG of wr_rd_addr_gray_sync 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";
//---------------------------------------------------------------------------
// Functions for gray code conversion
//---------------------------------------------------------------------------
function [11:0] bin_to_gray;
input [11:0] bin;
integer i;
begin
for (i=0;i<12;i=i+1)
begin
if (i == 11)
bin_to_gray[i] = bin[i];
else
bin_to_gray[i] = bin[i+1] ^ bin[i];
end
end
endfunction
function [11:0] gray_to_bin;
input [11:0] gray;
integer i;
begin
for (i=11;i>=0;i=i-1)
begin
if (i == 11)
gray_to_bin[i] = gray[i];
else
gray_to_bin[i] = gray_to_bin[i+1] ^ gray[i];
end
end
endfunction // gray_to_bin
//---------------------------------------------------------------------------
// Begin FIFO architecture
//---------------------------------------------------------------------------
assign GND = 1'b0;
assign VCC = 1'b1;
assign GND_BUS = 8'b0;
//---------------------------------------------------------------------------
// Read State machines and control
//---------------------------------------------------------------------------
// local link state machine
// states are WAIT, QUEUE1, QUEUE2, QUEUE3, SOF, DATA, EOF
// clock state to next state
always @(posedge rd_clk)
begin
if (rd_sreset == 1'b1)
rd_state <= WAIT_s;
else
rd_state <= rd_nxt_state;
end
assign rd_eof_n = rd_eof_n_int;
// decode next state, combinatorial
always @(rd_state or frame_in_fifo or rd_eof or rd_dst_rdy_n or rd_eof_n_int)
begin
case (rd_state)
WAIT_s : begin
// wait till there is a full frame in the fifo
// then start to load the pipeline
if (frame_in_fifo == 1'b1 && rd_eof_n_int == 1'b1)
rd_nxt_state <= QUEUE1_s;
else
rd_nxt_state <= WAIT_s;
end
QUEUE1_s : begin
// load the output pipeline
// this takes three clocks
rd_nxt_state <= QUEUE2_s;
end
QUEUE2_s : begin
rd_nxt_state <= QUEUE3_s;
end
QUEUE3_s : begin
rd_nxt_state <= QUEUE_SOF_s;
end
QUEUE_SOF_s : begin
// used mark sof at end of queue
rd_nxt_state <= DATA_s; // move straight to frame.
end
SOF_s : begin
// used to mark sof when following straight from eof
if (rd_dst_rdy_n == 1'b0)
rd_nxt_state <= DATA_s;
else
rd_nxt_state <= SOF_s;
end
DATA_s : begin
// When the eof marker is detected from the BRAM output
// move to EOF state
if (rd_dst_rdy_n == 1'b0 && rd_eof == 1'b1)
rd_nxt_state <= EOF_s;
else
rd_nxt_state <= DATA_s;
end
EOF_s : begin
// hold in this state until dst rdy is low
// and eof bit is accepted on interface
// If there is a frame in the fifo, then the next frame
// will already be queued into the pipe line so move straight
// to sof state.
if (rd_dst_rdy_n == 1'b0)
if (frame_in_fifo == 1'b1)
rd_nxt_state <= SOF_s;
else
rd_nxt_state <= WAIT_s;
else
rd_nxt_state <= EOF_s;
end
default : begin
rd_nxt_state <= WAIT_s;
end
endcase
end
// decode the output signals depending on current state.
// decode sof signal.
always @(posedge rd_clk)
begin
if (rd_sreset == 1'b1)
rd_sof_n <= 1'b1;
else
case (rd_state)
QUEUE_SOF_s :
// no need to wait for dst rdy to be low, as there is valid data
rd_sof_n <= 1'b0;
SOF_s :
// needed to wait till rd_dst_rdy is low to ensure eof signal has
// been accepted onto the interface before asserting sof.
if (rd_dst_rdy_n == 1'b0)
rd_sof_n <= 1'b0;
default :
// needed to wait till rd_dst_rdy is low to ensure sof signal has
// been accepted onto the interface.
if (rd_dst_rdy_n == 1'b0)
rd_sof_n <= 1'b1;
endcase
end
// decode eof signal
// check init value of this reg is 1.
always @(posedge rd_clk)
begin
if (rd_sreset == 1'b1)
rd_eof_n_int <= 1'b1;
else if (rd_dst_rdy_n == 1'b0)
// needed to wait till rd_dst_rdy is low to ensure penultimate byte of frame has
// been accepted onto the interface before asserting eof and that
// eof is accepted before moving on
case (rd_state)
EOF_s :
rd_eof_n_int <= 1'b0;
default :
rd_eof_n_int <= 1'b1;
endcase
// queue sof is not needed if init value is 1
end
// decode data output
always @(posedge rd_clk)
begin
if (rd_en == 1'b1)
rd_data_out <= rd_data_pipe;
end
// decode the output scr_rdy signal
// want to remove the dependancy of src_rdy from dst rdy
// check init value of this reg is 1'b1
always @(posedge rd_clk)
begin
if (rd_sreset == 1'b1)
rd_src_rdy_n <= 1'b1;
else
case (rd_state)
QUEUE_SOF_s :
rd_src_rdy_n <= 1'b0;
SOF_s :
rd_src_rdy_n <= 1'b0;
DATA_s :
rd_src_rdy_n <= 1'b0;
EOF_s :
rd_src_rdy_n <= 1'b0;
default :
if (rd_dst_rdy_n == 1'b0)
rd_src_rdy_n <= 1'b1;
endcase
end
// decode internal control signals
// rd_en is used to enable the BRAM read and load the output pipe
always @(rd_state or rd_dst_rdy_n)
begin
case (rd_state)
WAIT_s :
rd_en <= 1'b0;
QUEUE1_s :
rd_en <= 1'b1;
QUEUE2_s :
rd_en <= 1'b1;
QUEUE3_s :
rd_en <= 1'b1;
QUEUE_SOF_s :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -