// ---------------------------------------------------------------------- // Copyright (c) 2015, The Regents of the University of California All // rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // // * Neither the name of The Regents of the University of California // nor the names of its contributors may be used to endorse or // promote products derived from this software without specific // prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL REGENTS OF THE // UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH // DAMAGE. // ---------------------------------------------------------------------- `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 19:27:32 06/14/2012 // Design Name: // Module Name: reorder_queue_output // Project Name: // Target Devices: // Tool versions: // Description: // Outputs stored TLPs in increasing tag order. // // Dependencies: // reorder_queue.v // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// `include "trellis.vh" module reorder_queue_output #( parameter C_PCI_DATA_WIDTH = 9'd128, parameter C_NUM_CHNL = 4'd12, parameter C_TAG_WIDTH = 5, // Number of outstanding requests parameter C_TAG_DW_COUNT_WIDTH = 8, // Width of max count DWs per packet parameter C_DATA_ADDR_STRIDE_WIDTH = 5, // Width of max num stored data addr positions per tag parameter C_DATA_ADDR_WIDTH = 10, // Width of stored data address // Local parameters parameter C_PCI_DATA_WORD = C_PCI_DATA_WIDTH/32, parameter C_PCI_DATA_WORD_WIDTH = clog2s(C_PCI_DATA_WORD), parameter C_PCI_DATA_COUNT_WIDTH = clog2s(C_PCI_DATA_WORD+1), parameter C_NUM_TAGS = 2**C_TAG_WIDTH ) ( input CLK, // Clock input RST, // Synchronous reset output [C_DATA_ADDR_WIDTH-1:0] DATA_ADDR, // Address of stored packet data input [C_PCI_DATA_WIDTH-1:0] DATA, // Stored packet data input [C_NUM_TAGS-1:0] TAG_FINISHED, // Bitmap of finished tags output [C_NUM_TAGS-1:0] TAG_CLEAR, // Bitmap of tags to clear output [C_TAG_WIDTH-1:0] TAG, // Tag for which to retrieve packet data input [5:0] TAG_MAPPED, // Mapped tag (i.e. internal tag) input [C_TAG_DW_COUNT_WIDTH-1:0] PKT_WORDS, // Total count of packet payload in DWs input PKT_WORDS_LTE1, // True if total count of packet payload is <= 4 DWs input PKT_WORDS_LTE2, // True if total count of packet payload is <= 8 DWs input PKT_DONE, // Packet done flag input PKT_ERR, // Packet error flag output [C_PCI_DATA_WIDTH-1:0] ENG_DATA, // Engine data output [(C_NUM_CHNL*C_PCI_DATA_COUNT_WIDTH)-1:0] MAIN_DATA_EN, // Main data enable output [C_NUM_CHNL-1:0] MAIN_DONE, // Main data complete output [C_NUM_CHNL-1:0] MAIN_ERR, // Main data completed with error output [(C_NUM_CHNL*C_PCI_DATA_COUNT_WIDTH)-1:0] SG_RX_DATA_EN, // Scatter gather for RX data enable output [C_NUM_CHNL-1:0] SG_RX_DONE, // Scatter gather for RX data complete output [C_NUM_CHNL-1:0] SG_RX_ERR, // Scatter gather for RX data completed with error output [(C_NUM_CHNL*C_PCI_DATA_COUNT_WIDTH)-1:0] SG_TX_DATA_EN, // Scatter gather for TX data enable output [C_NUM_CHNL-1:0] SG_TX_DONE, // Scatter gather for TX data complete output [C_NUM_CHNL-1:0] SG_TX_ERR // Scatter gather for TX data completed with error ); reg [1:0] rState=0; reg [C_DATA_ADDR_WIDTH-1:0] rDataAddr=0; reg [C_PCI_DATA_WIDTH-1:0] rData=0; reg rTagFinished=0; reg [C_NUM_TAGS-1:0] rClear=0; reg [C_TAG_WIDTH-1:0] rTag=0; reg [C_TAG_WIDTH-1:0] rTagCurr=0; wire [C_TAG_WIDTH-1:0] wTagNext = rTag + 1'd1; reg [5:0] rShift; reg rDone=0; reg rDoneLast=0; reg rErr=0; reg rErrLast=0; reg [C_PCI_DATA_COUNT_WIDTH-1:0] rDE=0; reg [C_TAG_DW_COUNT_WIDTH-1:0] rWords=0; reg rLTE2Pkts=0; reg [C_PCI_DATA_WIDTH-1:0] rDataOut={C_PCI_DATA_WIDTH{1'b0}}; reg [(3*16*C_PCI_DATA_COUNT_WIDTH)-1:0] rDEOut={3*16*C_PCI_DATA_COUNT_WIDTH{1'd0}}; reg [(3*16)-1:0] rDoneOut={3*16{1'd0}}; reg [(3*16)-1:0] rErrOut={3*16{1'd0}}; assign DATA_ADDR = rDataAddr; assign TAG = rTag; assign TAG_CLEAR = rClear; assign ENG_DATA = rDataOut; assign MAIN_DATA_EN = rDEOut[(0*16*C_PCI_DATA_COUNT_WIDTH) +:(C_NUM_CHNL*C_PCI_DATA_COUNT_WIDTH)]; assign MAIN_DONE = rDoneOut[(0*16) +:C_NUM_CHNL]; assign MAIN_ERR = rErrOut[(0*16) +:C_NUM_CHNL]; assign SG_RX_DATA_EN = rDEOut[(1*16*C_PCI_DATA_COUNT_WIDTH) +:(C_NUM_CHNL*C_PCI_DATA_COUNT_WIDTH)]; assign SG_RX_DONE = rDoneOut[(1*16) +:C_NUM_CHNL]; assign SG_RX_ERR = rErrOut[(1*16) +:C_NUM_CHNL]; assign SG_TX_DATA_EN = rDEOut[(2*16*C_PCI_DATA_COUNT_WIDTH) +:(C_NUM_CHNL*C_PCI_DATA_COUNT_WIDTH)]; assign SG_TX_DONE = rDoneOut[(2*16) +:C_NUM_CHNL]; assign SG_TX_ERR = rErrOut[(2*16) +:C_NUM_CHNL]; // Output completed data in increasing tag order, avoid stalls if possible always @ (posedge CLK) begin if (RST) begin rState <= #1 0; rTag <= #1 0; rDataAddr <= #1 0; rDone <= #1 0; rErr <= #1 0; rDE <= #1 0; rClear <= #1 0; rTagFinished <= #1 0; rShift <= 0; // Added end else begin rTagFinished <= #1 TAG_FINISHED[rTag]; case (rState) 2'd0: begin // Request initial data and final info, output nothing rDone <= #1 0; rErr <= #1 0; rDE <= #1 0; rClear <= #1 0; if (rTagFinished) begin rTag <= #1 wTagNext; rTagCurr <= #1 rTag; rDataAddr <= #1 rDataAddr + 1'd1; rState <= #1 2'd2; end else begin rState <= #1 2'd0; end end 2'd1: begin // Request initial data and final info, output last data rDone <= #1 rDoneLast; rErr <= #1 rErrLast; rDE <= #1 rWords[C_PCI_DATA_COUNT_WIDTH-1:0]; rClear <= #1 1<