📄 tx_client_fifo_8.v
字号:
//-----------------------------------------------------------------------------
// 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 + -