📄 fifo_pause_control.v
字号:
/////////////////////////////////////////////////////////////////////////////////// Project: 1 Gig Ethernet MAC FIFO Reference Design// Version: 2.0// File : fifo_pause_control.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.///////////////////////////////////////////////////////////////////////////////////// One Gigabit Ethernet MAC Backend Pause Conrol Sub-block// Author: Xilinx Inc.//// Description: The entity will automatically send a Pause Request to the 1 // Gigabit Ethernet MAC if the occupancy of the Receiver FIFO // exceeds the Almost Full HIGH Threshold.//// Functionality:// 1. The input STATUS_NEARLY_FULL_HIGH is active when the // Receiver FIFO occupancy is greater than the configurable // Nearly Full HIGH threshold. This is used to generate // PAUSE_REQ_OUT,which is active for a single clock pulse. // This causes the MAC's Flow Control to transmit a single // Pause Frame. Whatever the state of STATUS_NEARLY_FULL_HIGH, // PAUSE_REQ_OUT will only be pulsed again after the current // Pause Time has expired. //// 2. The input STATUS_NEARLY_FULL_LOW is active when the Reciever // FIFO occupancy is less than the configurable Nearly Full LOW // threshold. This is used to effectively cancel an active // Pause period if the Receiver FIFO drops below the // configurable Nearly Full LOW threshold whilst the current // Pause Time is still active. This is achieved by signalling // the MAC to transmit a Pause Frame with an embedded Pause // Time of zero.//// 3. Alternatively, PAUSE_REQ_OUT can be triggered through the // Management Interface by writing to a configuration register.// This asserts the PAUSE_REQ_MAN input. This will always // trigger a pause request regardless of the state of the // automatic logic described in points 1. and 2. // ///////////////////////////////////////////////////////////////////////////////`timescale 1 ps / 1 ps module FIFO_PAUSE_CONTROL ( TX_CLK, TX_SRESET, PAUSE_AUTO_ENABLE, PAUSE_REQ_MAN, STATUS_NEARLY_FULL_HIGH, STATUS_NEARLY_FULL_LOW, PAUSE_VALUE_IN, PAUSE_VALUE_OUT, PAUSE_REQ_OUT ); input TX_CLK; // MAC Transmitter clock. input TX_SRESET; // Synchronous Reset. input PAUSE_AUTO_ENABLE; // Enable automatic Pause Request funtionality. input PAUSE_REQ_MAN; // Initiate a manual Pause Request. input STATUS_NEARLY_FULL_HIGH; // Initiate an automatic Pause Request. input STATUS_NEARLY_FULL_LOW; // Send a Pause time of zero to cancel pause. input [15:0] PAUSE_VALUE_IN; // Number of Pause Quanta in Pause Period. output [15:0] PAUSE_VALUE_OUT; // Number of Pause Quanta in Pause Period. output PAUSE_REQ_OUT; // A pulse sent to MAC to trigger a Pause Frame. reg [5:0] PAUSE_QUANTA; // A counter to count for the Pause Quanta Period. reg [15:0] PAUSE_TIME; // A counter to count Pause Quanta Periods. reg PAUSE_TIME_MSB; // The most significant bit of PAUSE_TIME. reg PAUSE_REQ_MAN_REG; // PAUSE_REQ_MAN reclocked: HOST_CLK to TX_CLK. reg STATUS_NEARLY_FULL_HIGH_REG;// STATUS_NEARLY_FULL_HIGH reclocked: HOST_CLK to TX_CLK. reg PAUSE_ACTIVE; // The active pause period. reg PAUSE_ACTIVE_COMB; reg STATUS_NEARLY_FULL_LOW_REG1;// STATUS_NEARLY_FULL_LOW reclocked from HOST_CLK to TX_CLK. reg STATUS_NEARLY_FULL_LOW_REG2;// STATUS_NEARLY_FULL_LOW_REG1 reclocked on TX_CLK. reg PAUSE_CANCEL_NOW; // This will trigger a zero time pause frame. wire PAUSE_CANCEL_NOW_COMB; reg [15:0] PAUSE_VALUE_OUT_COMB; wire PAUSE_REQ_OUT_COMB; reg PAUSE_REQ_OUT; reg [15:0] PAUSE_VALUE_OUT;// purpose: Reclock the PAUSE_REQ_MAN. This will be used to detect a '0' to '1' transition of PAUSE_REQ_MAN. // type : sequential always @(posedge TX_CLK) begin if (TX_SRESET == 1'b1) PAUSE_REQ_MAN_REG <= 1'b0; else PAUSE_REQ_MAN_REG <= PAUSE_REQ_MAN; end // purpose: Reclock the STATUS_NEARLY_FULL_HIGH from FIFO_CLK to TX_CLK // type : sequential always @(posedge TX_CLK) begin if (TX_SRESET == 1'b1) STATUS_NEARLY_FULL_HIGH_REG <= 1'b0; else STATUS_NEARLY_FULL_HIGH_REG <= STATUS_NEARLY_FULL_HIGH; end // purpose: Count the Pause Quanta Period (512 bit times = 64 clocks for 8 bit words) // type : sequential always @(posedge TX_CLK) begin if (TX_SRESET == 1'b1) PAUSE_QUANTA <= 6'b000000; else if (PAUSE_ACTIVE == 1'b0) // reset when Pause period is inactive. PAUSE_QUANTA <= 6'b000000; else PAUSE_QUANTA <= PAUSE_QUANTA + 6'b000001; end // purpose: Count the Pause Time Period in units of Pause Quanta // type : sequential always @(posedge TX_CLK) begin if (TX_SRESET == 1'b1) begin PAUSE_TIME <= 0; PAUSE_TIME_MSB <= 1'b0; end else if (PAUSE_ACTIVE == 1'b0 && STATUS_NEARLY_FULL_HIGH_REG == 1'b1) begin PAUSE_TIME <= PAUSE_VALUE_IN; // set the value of PAUSE_TIME when PAUSE_TIME_MSB <= PAUSE_VALUE_IN[15]; // a Pause Request is triggered. end else if (PAUSE_QUANTA == 6'b111111) begin PAUSE_TIME <= PAUSE_TIME - 16'h0001;// Count down the Pause Time. PAUSE_TIME_MSB <= PAUSE_TIME[15]; end end // purpose: Reclock the STATUS_NEARLY_FULL_LOW from FIFO_CLK to TX_CLK // type : sequential always @(posedge TX_CLK) begin if (TX_SRESET == 1'b1) begin STATUS_NEARLY_FULL_LOW_REG1 <= 1'b0; STATUS_NEARLY_FULL_LOW_REG2 <= 1'b0; end else begin STATUS_NEARLY_FULL_LOW_REG1 <= STATUS_NEARLY_FULL_LOW; STATUS_NEARLY_FULL_LOW_REG2 <= STATUS_NEARLY_FULL_LOW_REG1; end end // purpose: Generate a "Pause Cancel" request when the STATUS_NEARLY_FULL_LOW is crossed and the Receiver// FIFO occupancy is decreasing when the Pause Time is still active. // type : sequential assign PAUSE_CANCEL_NOW_COMB = (~STATUS_NEARLY_FULL_LOW_REG1) & STATUS_NEARLY_FULL_LOW_REG2 & PAUSE_ACTIVE & PAUSE_AUTO_ENABLE; always @(posedge TX_CLK) begin if (TX_SRESET == 1'b1) PAUSE_CANCEL_NOW <= 1'b0; else PAUSE_CANCEL_NOW <= PAUSE_CANCEL_NOW_COMB; end // purpose: Generate PAUSE_ACTIVE. This signal is asserted during the Pause Time. // type : sequential always @(PAUSE_TIME_MSB or PAUSE_TIME[15] or PAUSE_CANCEL_NOW or STATUS_NEARLY_FULL_HIGH_REG or PAUSE_AUTO_ENABLE) begin if ((PAUSE_TIME_MSB == 1'b0 && PAUSE_TIME[15] == 1'b1) || PAUSE_CANCEL_NOW == 1'b1) PAUSE_ACTIVE_COMB <= 1'b0; // Start of active pause time else if (STATUS_NEARLY_FULL_HIGH_REG == 1'b1 && PAUSE_AUTO_ENABLE == 1'b1) PAUSE_ACTIVE_COMB <= 1'b1; else PAUSE_ACTIVE_COMB <= 1'b0; end always @(posedge TX_CLK) begin if (TX_SRESET == 1'b1) PAUSE_ACTIVE <= 1'b0; // End active pause time on detecting PAUSE_TIME wrap-around (PAUSE_TIME has decremented to zero) // or after a "pause cancel". else PAUSE_ACTIVE <= PAUSE_ACTIVE_COMB; end assign PAUSE_REQ_OUT_COMB = (PAUSE_REQ_MAN & (~PAUSE_REQ_MAN_REG)) | // manual trigger ((~PAUSE_ACTIVE) & STATUS_NEARLY_FULL_HIGH_REG // automatic trigger & PAUSE_AUTO_ENABLE) | (PAUSE_CANCEL_NOW & PAUSE_AUTO_ENABLE); // automatic pause cancel trigger.// purpose: Generate the PAUSE_REQ_OUT pulse from Automatic or Manual Pause logic. // type : sequential always @(PAUSE_REQ_MAN or PAUSE_REQ_MAN_REG or PAUSE_VALUE_IN or PAUSE_CANCEL_NOW) begin if (PAUSE_CANCEL_NOW == 1'b1 && // Transmit a zero pause frame. (PAUSE_REQ_MAN & (~PAUSE_REQ_MAN_REG)) == 1'b0) // Manual mode still has priority. PAUSE_VALUE_OUT_COMB <= 0; // Transmit zero pause time to cancel pause. else PAUSE_VALUE_OUT_COMB <= PAUSE_VALUE_IN; // Transmit a normal pause frame. end always @(posedge TX_CLK) begin if (TX_SRESET == 1'b1) begin PAUSE_REQ_OUT <= 1'b0; PAUSE_VALUE_OUT <= 0; end else begin PAUSE_REQ_OUT <= PAUSE_REQ_OUT_COMB; PAUSE_VALUE_OUT <= PAUSE_VALUE_OUT_COMB; end end endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -