mirror of
https://github.com/KastnerRG/riffa.git
synced 2025-01-30 23:02:54 +08:00
904 lines
39 KiB
Verilog
904 lines
39 KiB
Verilog
// ----------------------------------------------------------------------
|
|
// Copyright (c) 2016, 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.
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Filename: tx_engine_classic.v
|
|
// Version: 1.0
|
|
// Verilog Standard: Verilog-2001
|
|
// Description: The TX Engine takes unformatted request and completions,
|
|
// formats these packets into "TLP's" or Transaction Layer Packets and abitrates
|
|
// their sending over the PCIe bus. These packets must meet max-request,
|
|
// max-payload, and payload termination requirements (see Read Completion
|
|
// Boundary). The TX Engine does not check these requirements during operation,
|
|
// but may do so during simulation.
|
|
//
|
|
// Valid packets are transmitted over the shared PCIe bus as determined
|
|
// by the arbiter.
|
|
//
|
|
// This Engine is capable of operating at "line rate".
|
|
// Author: Dustin Richmond (@darichmond)
|
|
//-----------------------------------------------------------------------------
|
|
`include "trellis.vh"
|
|
`include "tlp.vh"
|
|
module tx_engine_classic
|
|
#(parameter C_PCI_DATA_WIDTH = 128,
|
|
parameter C_PIPELINE_INPUT = 1,
|
|
parameter C_PIPELINE_OUTPUT = 1,
|
|
parameter C_MAX_PAYLOAD_DWORDS = 256,
|
|
parameter C_VENDOR = "ALTERA")
|
|
(// Interface: Clocks
|
|
input CLK,
|
|
|
|
// Interface: Resets
|
|
input RST_BUS, // Replacement for generic RST_IN
|
|
input RST_LOGIC, // Addition for RIFFA_RST
|
|
output DONE_TXC_RST,
|
|
output DONE_TXR_RST,
|
|
|
|
// Interface: Configuration
|
|
input [`SIG_CPLID_W-1:0] CONFIG_COMPLETER_ID,
|
|
|
|
// Interface: TX Classic
|
|
input TX_TLP_READY,
|
|
output [C_PCI_DATA_WIDTH-1:0] TX_TLP,
|
|
output TX_TLP_VALID,
|
|
output TX_TLP_START_FLAG,
|
|
output [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TX_TLP_START_OFFSET,
|
|
output TX_TLP_END_FLAG,
|
|
output [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TX_TLP_END_OFFSET,
|
|
|
|
// Interface: TXC Engine
|
|
input TXC_DATA_VALID,
|
|
input [C_PCI_DATA_WIDTH-1:0] TXC_DATA,
|
|
input TXC_DATA_START_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXC_DATA_START_OFFSET,
|
|
input TXC_DATA_END_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXC_DATA_END_OFFSET,
|
|
output TXC_DATA_READY,
|
|
|
|
input TXC_META_VALID,
|
|
input [`SIG_FBE_W-1:0] TXC_META_FDWBE,
|
|
input [`SIG_LBE_W-1:0] TXC_META_LDWBE,
|
|
input [`SIG_LOWADDR_W-1:0] TXC_META_ADDR,
|
|
input [`SIG_TYPE_W-1:0] TXC_META_TYPE,
|
|
input [`SIG_LEN_W-1:0] TXC_META_LENGTH,
|
|
input [`SIG_BYTECNT_W-1:0] TXC_META_BYTE_COUNT,
|
|
input [`SIG_TAG_W-1:0] TXC_META_TAG,
|
|
input [`SIG_REQID_W-1:0] TXC_META_REQUESTER_ID,
|
|
input [`SIG_TC_W-1:0] TXC_META_TC,
|
|
input [`SIG_ATTR_W-1:0] TXC_META_ATTR,
|
|
input TXC_META_EP,
|
|
output TXC_META_READY,
|
|
output TXC_SENT,
|
|
|
|
// Interface: TXR Engine
|
|
input TXR_DATA_VALID,
|
|
input [C_PCI_DATA_WIDTH-1:0] TXR_DATA,
|
|
input TXR_DATA_START_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXR_DATA_START_OFFSET,
|
|
input TXR_DATA_END_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXR_DATA_END_OFFSET,
|
|
output TXR_DATA_READY,
|
|
|
|
input TXR_META_VALID,
|
|
input [`SIG_FBE_W-1:0] TXR_META_FDWBE,
|
|
input [`SIG_LBE_W-1:0] TXR_META_LDWBE,
|
|
input [`SIG_ADDR_W-1:0] TXR_META_ADDR,
|
|
input [`SIG_LEN_W-1:0] TXR_META_LENGTH,
|
|
input [`SIG_TAG_W-1:0] TXR_META_TAG,
|
|
input [`SIG_TC_W-1:0] TXR_META_TC,
|
|
input [`SIG_ATTR_W-1:0] TXR_META_ATTR,
|
|
input [`SIG_TYPE_W-1:0] TXR_META_TYPE,
|
|
input TXR_META_EP,
|
|
output TXR_META_READY,
|
|
output TXR_SENT);
|
|
|
|
localparam C_MUX_TYPE = "SHIFT";
|
|
localparam C_DEPTH_PACKETS = 10;
|
|
localparam C_RST_COUNT = 10;
|
|
/*AUTOWIRE*/
|
|
/*AUTOINPUT*/
|
|
|
|
wire [C_PCI_DATA_WIDTH-1:0] _TXC_DATA;
|
|
wire [C_PCI_DATA_WIDTH-1:0] _TXR_DATA;
|
|
wire [C_PCI_DATA_WIDTH-1:0] wTxcTlp;
|
|
wire wTxcTlpEndFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxcTlpEndOffset;
|
|
wire wTxcTlpReady;
|
|
wire wTxcTlpStartFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxcTlpStartOffset;
|
|
wire wTxcTlpValid;
|
|
|
|
wire [C_PCI_DATA_WIDTH-1:0] wTxrTlp;
|
|
wire wTxrTlpEndFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxrTlpEndOffset;
|
|
wire wTxrTlpReady;
|
|
wire wTxrTlpStartFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxrTlpStartOffset;
|
|
wire wTxrTlpValid;
|
|
|
|
wire [C_PCI_DATA_WIDTH-1:0] wTxTlp;
|
|
wire wTxTlpEndFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxTlpEndOffset;
|
|
wire wTxTlpReady;
|
|
wire wTxTlpStartFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxTlpStartOffset;
|
|
wire wTxTlpValid;
|
|
|
|
wire wDoneTxcEngRst;
|
|
wire wDoneTxrEngRst;
|
|
wire wDoneRst;
|
|
wire wRstWaiting;
|
|
wire wRstRc;
|
|
wire wRstEng;
|
|
wire [C_RST_COUNT:0] wShiftRst;
|
|
|
|
reg rTxValid;
|
|
reg [`TLP_TYPE_W-1:0] rTxType;
|
|
reg rTxEndFlag;
|
|
reg rTxrSent;
|
|
reg rTxcSent;
|
|
|
|
assign DONE_TXC_RST = wDoneRst & wDoneTxcEngRst;
|
|
assign DONE_TXR_RST = wDoneRst & wDoneTxrEngRst;
|
|
assign TXC_SENT = rTxcSent;
|
|
assign TXR_SENT = rTxrSent;
|
|
|
|
assign wRstEng = wShiftRst[C_RST_COUNT-3];
|
|
assign wDoneEngRst = ~wShiftRst[C_RST_COUNT];
|
|
|
|
always @(posedge CLK) begin
|
|
if(TX_TLP_START_FLAG) begin
|
|
rTxType <= TX_TLP[`TLP_TYPE_R];
|
|
end
|
|
rTxEndFlag <= TX_TLP_END_FLAG;
|
|
rTxValid <= TX_TLP_VALID & TX_TLP_READY;
|
|
rTxcSent <= rTxEndFlag & rTxValid & (rTxType == `TLP_TYPE_CPL);
|
|
rTxrSent <= rTxEndFlag & rTxValid & (rTxType == `TLP_TYPE_REQ);
|
|
end
|
|
|
|
generate
|
|
if(C_VENDOR == "XILINX") begin : xilinx_data
|
|
if(C_PCI_DATA_WIDTH == 128) begin : x_be_swap128
|
|
assign _TXC_DATA = {TXC_DATA[103:96], TXC_DATA[111:104], TXC_DATA[119:112], TXC_DATA[127:120],
|
|
TXC_DATA[71:64], TXC_DATA[79:72], TXC_DATA[87:80], TXC_DATA[95:88],
|
|
TXC_DATA[39:32], TXC_DATA[47:40], TXC_DATA[55:48], TXC_DATA[63:56],
|
|
TXC_DATA[07:00], TXC_DATA[15:08], TXC_DATA[23:16], TXC_DATA[31:24]};
|
|
assign _TXR_DATA = {TXR_DATA[103:96], TXR_DATA[111:104], TXR_DATA[119:112], TXR_DATA[127:120],
|
|
TXR_DATA[71:64], TXR_DATA[79:72], TXR_DATA[87:80], TXR_DATA[95:88],
|
|
TXR_DATA[39:32], TXR_DATA[47:40], TXR_DATA[55:48], TXR_DATA[63:56],
|
|
TXR_DATA[07:00], TXR_DATA[15:08], TXR_DATA[23:16], TXR_DATA[31:24]};
|
|
end else if(C_PCI_DATA_WIDTH == 64) begin: x_be_swap64
|
|
assign _TXC_DATA = {TXC_DATA[39:32], TXC_DATA[47:40], TXC_DATA[55:48], TXC_DATA[63:56],
|
|
TXC_DATA[07:00], TXC_DATA[15:08], TXC_DATA[23:16], TXC_DATA[31:24]};
|
|
assign _TXR_DATA = {TXR_DATA[39:32], TXR_DATA[47:40], TXR_DATA[55:48], TXR_DATA[63:56],
|
|
TXR_DATA[07:00], TXR_DATA[15:08], TXR_DATA[23:16], TXR_DATA[31:24]};
|
|
end else if(C_PCI_DATA_WIDTH == 32) begin: x_be_swap32
|
|
assign _TXC_DATA = {TXC_DATA[07:00], TXC_DATA[15:08], TXC_DATA[23:16], TXC_DATA[31:24]};
|
|
assign _TXR_DATA = {TXR_DATA[07:00], TXR_DATA[15:08], TXR_DATA[23:16], TXR_DATA[31:24]};
|
|
end
|
|
end else begin : altera_data
|
|
assign _TXC_DATA = TXC_DATA;
|
|
assign _TXR_DATA = TXR_DATA;
|
|
end
|
|
endgenerate
|
|
|
|
txc_engine_classic
|
|
#(.C_PIPELINE_OUTPUT (0),
|
|
/*AUTOINSTPARAM*/
|
|
// Parameters
|
|
.C_PCI_DATA_WIDTH (C_PCI_DATA_WIDTH),
|
|
.C_PIPELINE_INPUT (C_PIPELINE_INPUT),
|
|
.C_MAX_PAYLOAD_DWORDS (C_MAX_PAYLOAD_DWORDS),
|
|
.C_DEPTH_PACKETS (C_DEPTH_PACKETS),
|
|
.C_VENDOR (C_VENDOR))
|
|
txc_engine_inst
|
|
(// Outputs
|
|
.TXC_TLP (wTxcTlp[C_PCI_DATA_WIDTH-1:0] ),
|
|
.TXC_TLP_VALID (wTxcTlpValid),
|
|
.TXC_TLP_START_FLAG (wTxcTlpStartFlag),
|
|
.TXC_TLP_START_OFFSET (wTxcTlpStartOffset[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TXC_TLP_END_FLAG (wTxcTlpEndFlag),
|
|
.TXC_TLP_END_OFFSET (wTxcTlpEndOffset[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.DONE_TXC_RST (wDoneTxcEngRst),
|
|
// Inputs
|
|
.TXC_TLP_READY (wTxcTlpReady),
|
|
.TXC_DATA (_TXC_DATA[C_PCI_DATA_WIDTH-1:0]),
|
|
.RST_IN (wRstEng),
|
|
/*AUTOINST*/
|
|
// Outputs
|
|
.TXC_DATA_READY (TXC_DATA_READY),
|
|
.TXC_META_READY (TXC_META_READY),
|
|
// Inputs
|
|
.CLK (CLK),
|
|
.CONFIG_COMPLETER_ID (CONFIG_COMPLETER_ID[`SIG_CPLID_W-1:0]),
|
|
.TXC_DATA_VALID (TXC_DATA_VALID),
|
|
.TXC_DATA_START_FLAG (TXC_DATA_START_FLAG),
|
|
.TXC_DATA_START_OFFSET (TXC_DATA_START_OFFSET[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TXC_DATA_END_FLAG (TXC_DATA_END_FLAG),
|
|
.TXC_DATA_END_OFFSET (TXC_DATA_END_OFFSET[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TXC_META_VALID (TXC_META_VALID),
|
|
.TXC_META_FDWBE (TXC_META_FDWBE[`SIG_FBE_W-1:0]),
|
|
.TXC_META_LDWBE (TXC_META_LDWBE[`SIG_LBE_W-1:0]),
|
|
.TXC_META_ADDR (TXC_META_ADDR[`SIG_LOWADDR_W-1:0]),
|
|
.TXC_META_TYPE (TXC_META_TYPE[`SIG_TYPE_W-1:0]),
|
|
.TXC_META_LENGTH (TXC_META_LENGTH[`SIG_LEN_W-1:0]),
|
|
.TXC_META_BYTE_COUNT (TXC_META_BYTE_COUNT[`SIG_BYTECNT_W-1:0]),
|
|
.TXC_META_TAG (TXC_META_TAG[`SIG_TAG_W-1:0]),
|
|
.TXC_META_REQUESTER_ID (TXC_META_REQUESTER_ID[`SIG_REQID_W-1:0]),
|
|
.TXC_META_TC (TXC_META_TC[`SIG_TC_W-1:0]),
|
|
.TXC_META_ATTR (TXC_META_ATTR[`SIG_ATTR_W-1:0]),
|
|
.TXC_META_EP (TXC_META_EP));
|
|
|
|
txr_engine_classic
|
|
#(.C_PIPELINE_OUTPUT (0),
|
|
/*AUTOINSTPARAM*/
|
|
// Parameters
|
|
.C_PCI_DATA_WIDTH (C_PCI_DATA_WIDTH),
|
|
.C_PIPELINE_INPUT (C_PIPELINE_INPUT),
|
|
.C_MAX_PAYLOAD_DWORDS (C_MAX_PAYLOAD_DWORDS),
|
|
.C_DEPTH_PACKETS (C_DEPTH_PACKETS),
|
|
.C_VENDOR (C_VENDOR))
|
|
txr_engine_inst
|
|
(// Outputs
|
|
.TXR_TLP (wTxrTlp[C_PCI_DATA_WIDTH-1:0]),
|
|
.TXR_TLP_VALID (wTxrTlpValid),
|
|
.TXR_TLP_START_FLAG (wTxrTlpStartFlag),
|
|
.TXR_TLP_START_OFFSET (wTxrTlpStartOffset[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TXR_TLP_END_FLAG (wTxrTlpEndFlag),
|
|
.TXR_TLP_END_OFFSET (wTxrTlpEndOffset[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TXR_DATA (_TXR_DATA[C_PCI_DATA_WIDTH-1:0]),
|
|
.DONE_TXR_RST (wDoneTxrEngRst),
|
|
// Inputs
|
|
.TXR_TLP_READY (wTxrTlpReady),
|
|
.RST_IN (wRstEng),
|
|
/*AUTOINST*/
|
|
// Outputs
|
|
.TXR_DATA_READY (TXR_DATA_READY),
|
|
.TXR_META_READY (TXR_META_READY),
|
|
// Inputs
|
|
.CLK (CLK),
|
|
.CONFIG_COMPLETER_ID (CONFIG_COMPLETER_ID[`SIG_CPLID_W-1:0]),
|
|
.TXR_DATA_VALID (TXR_DATA_VALID),
|
|
.TXR_DATA_START_FLAG (TXR_DATA_START_FLAG),
|
|
.TXR_DATA_START_OFFSET (TXR_DATA_START_OFFSET[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TXR_DATA_END_FLAG (TXR_DATA_END_FLAG),
|
|
.TXR_DATA_END_OFFSET (TXR_DATA_END_OFFSET[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TXR_META_VALID (TXR_META_VALID),
|
|
.TXR_META_FDWBE (TXR_META_FDWBE[`SIG_FBE_W-1:0]),
|
|
.TXR_META_LDWBE (TXR_META_LDWBE[`SIG_LBE_W-1:0]),
|
|
.TXR_META_ADDR (TXR_META_ADDR[`SIG_ADDR_W-1:0]),
|
|
.TXR_META_LENGTH (TXR_META_LENGTH[`SIG_LEN_W-1:0]),
|
|
.TXR_META_TAG (TXR_META_TAG[`SIG_TAG_W-1:0]),
|
|
.TXR_META_TC (TXR_META_TC[`SIG_TC_W-1:0]),
|
|
.TXR_META_ATTR (TXR_META_ATTR[`SIG_ATTR_W-1:0]),
|
|
.TXR_META_TYPE (TXR_META_TYPE[`SIG_TYPE_W-1:0]),
|
|
.TXR_META_EP (TXR_META_EP));
|
|
|
|
tx_mux
|
|
#(.C_PIPELINE_INPUT (0),
|
|
/*AUTOINSTPARAM*/
|
|
// Parameters
|
|
.C_PCI_DATA_WIDTH (C_PCI_DATA_WIDTH),
|
|
.C_PIPELINE_OUTPUT (C_PIPELINE_OUTPUT),
|
|
.C_MUX_TYPE (C_MUX_TYPE),
|
|
.C_VENDOR (C_VENDOR))
|
|
tx_mux_inst
|
|
(// Inputs
|
|
.TXC_TLP (wTxcTlp[C_PCI_DATA_WIDTH-1:0]),
|
|
.TXC_TLP_VALID (wTxcTlpValid),
|
|
.TXC_TLP_START_FLAG (wTxcTlpStartFlag),
|
|
.TXC_TLP_START_OFFSET (wTxcTlpStartOffset[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TXC_TLP_END_FLAG (wTxcTlpEndFlag),
|
|
.TXC_TLP_END_OFFSET (wTxcTlpEndOffset[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TXR_TLP (wTxrTlp[C_PCI_DATA_WIDTH-1:0]),
|
|
.TXR_TLP_VALID (wTxrTlpValid),
|
|
.TXR_TLP_START_FLAG (wTxrTlpStartFlag),
|
|
.TXR_TLP_START_OFFSET (wTxrTlpStartOffset[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TXR_TLP_END_FLAG (wTxrTlpEndFlag),
|
|
.TXR_TLP_END_OFFSET (wTxrTlpEndOffset[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.RST_IN (wRstEng),
|
|
// Outputs
|
|
.TXC_TLP_READY (wTxcTlpReady),
|
|
.TXR_TLP_READY (wTxrTlpReady),
|
|
.TX_TLP (wTxTlp[C_PCI_DATA_WIDTH-1:0]),
|
|
.TX_TLP_VALID (wTxTlpValid),
|
|
.TX_TLP_START_FLAG (wTxTlpStartFlag),
|
|
.TX_TLP_START_OFFSET (wTxTlpStartOffset[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TX_TLP_END_FLAG (wTxTlpEndFlag),
|
|
.TX_TLP_END_OFFSET (wTxTlpEndOffset[clog2s(C_PCI_DATA_WIDTH/32)-1:0]),
|
|
.TX_TLP_READY (wTxTlpReady),
|
|
/*AUTOINST*/
|
|
// Inputs
|
|
.CLK (CLK));
|
|
|
|
shiftreg
|
|
#(// Parameters
|
|
.C_DEPTH (C_RST_COUNT),
|
|
.C_WIDTH (1),
|
|
.C_VALUE (1)
|
|
/*AUTOINSTPARAM*/)
|
|
rst_shiftreg
|
|
(// Outputs
|
|
.RD_DATA (wShiftRst),
|
|
// Inputs
|
|
.RST_IN (RST_BUS),
|
|
.WR_DATA (wRstRc),
|
|
/*AUTOINST*/
|
|
// Inputs
|
|
.CLK (CLK));
|
|
|
|
reset_controller
|
|
#(// Parameters
|
|
.C_RST_COUNT (C_RST_COUNT)
|
|
/*AUTOINSTPARAM*/)
|
|
rc_inst
|
|
(// Outputs
|
|
.DONE_RST (wDoneRst),
|
|
.WAITING_RESET (wRstWaiting),
|
|
.RST_OUT (wRstRc),
|
|
// Inputs
|
|
.RST_IN (RST_BUS),
|
|
.SIGNAL_RST (RST_LOGIC),
|
|
.WAIT_RST (TX_TLP_VALID),
|
|
.NEXT_CYC_RST (TX_TLP_END_FLAG & TX_TLP_READY),
|
|
/*AUTOINST*/
|
|
// Inputs
|
|
.CLK (CLK));
|
|
|
|
pipeline
|
|
#(// Parameters
|
|
.C_DEPTH (1),
|
|
.C_WIDTH (C_PCI_DATA_WIDTH +
|
|
2*(1 + clog2s(C_PCI_DATA_WIDTH/32))),
|
|
.C_USE_MEMORY (0)
|
|
/*AUTOINSTPARAM*/)
|
|
output_reg_inst
|
|
(// Outputs
|
|
.WR_DATA_READY (wTxTlpReady),
|
|
.RD_DATA ({TX_TLP,
|
|
TX_TLP_START_FLAG, TX_TLP_START_OFFSET,
|
|
TX_TLP_END_FLAG, TX_TLP_END_OFFSET}),
|
|
.RD_DATA_VALID (TX_TLP_VALID),
|
|
// Inputs
|
|
.RST_IN (wRstRc),
|
|
.WR_DATA ({wTxTlp,
|
|
wTxTlpStartFlag, wTxTlpStartOffset,
|
|
wTxTlpEndFlag, wTxTlpEndOffset}),
|
|
.WR_DATA_VALID (wTxTlpValid & ~wRstWaiting),
|
|
.RD_DATA_READY (TX_TLP_READY),
|
|
/*AUTOINST*/
|
|
// Inputs
|
|
.CLK (CLK));
|
|
|
|
// Put output pipeline stage here, OR, at TX Engine outputs
|
|
endmodule
|
|
// Local Variables:
|
|
// verilog-library-directories:("." "../../common/")
|
|
// End:
|
|
/*
|
|
Filename: tx_mux.v
|
|
Version: 1.0
|
|
Verilog Standard: Verilog-2001
|
|
|
|
Description: The tx_mux arbitrates access to the PCI TX interface
|
|
between the the Request and Completion engines. The top level tx_mux
|
|
module instantiates two sub-modules (also declared in this file):
|
|
tx_arbiter and tx_phi. The arbiter choses the next packet that will
|
|
be granted the TX interface, based on the priorities given to
|
|
it. Each priority is the count of how many successive, back-to-back
|
|
packets can be sent by either the TXC or TXR interface before
|
|
granting time to the other engine. The mux is a simple multiplexer
|
|
that uses the select signals from the arbiter.
|
|
|
|
Notes: Any modifications to this file should meet the conditions set
|
|
forth in the "Trellis Style Guide"
|
|
|
|
- The pipeline stage at the start of the mux means that ready stays high for
|
|
both TXC and TXR. This the behavior we want?
|
|
|
|
Author: Dustin Richmond (@darichmond)
|
|
Co-Authors:
|
|
*/
|
|
`timescale 1ns/1ns
|
|
`include "trellis.vh"
|
|
module tx_mux
|
|
#(parameter C_PCI_DATA_WIDTH = 128,
|
|
parameter C_PIPELINE_INPUT = 1,
|
|
parameter C_PIPELINE_OUTPUT = 1,
|
|
parameter C_MUX_TYPE = "SHIFT",
|
|
parameter C_VENDOR = "ALTERA")
|
|
(// Interface: Clocks
|
|
input CLK,
|
|
|
|
// Interface: Resets
|
|
input RST_IN,
|
|
|
|
// Interface: TXC
|
|
input [C_PCI_DATA_WIDTH-1:0] TXC_TLP,
|
|
output TXC_TLP_READY,
|
|
input TXC_TLP_VALID,
|
|
input TXC_TLP_START_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXC_TLP_START_OFFSET,
|
|
input TXC_TLP_END_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXC_TLP_END_OFFSET,
|
|
|
|
// Interface: TXR
|
|
input [C_PCI_DATA_WIDTH-1:0] TXR_TLP,
|
|
input TXR_TLP_VALID,
|
|
input TXR_TLP_START_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXR_TLP_START_OFFSET,
|
|
input TXR_TLP_END_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXR_TLP_END_OFFSET,
|
|
output TXR_TLP_READY,
|
|
|
|
// Interface: TX Classic
|
|
input TX_TLP_READY,
|
|
output [C_PCI_DATA_WIDTH-1:0] TX_TLP,
|
|
output TX_TLP_VALID,
|
|
output TX_TLP_START_FLAG,
|
|
output [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TX_TLP_START_OFFSET,
|
|
output TX_TLP_END_FLAG,
|
|
output [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TX_TLP_END_OFFSET);
|
|
|
|
localparam C_WIDTH = (C_PCI_DATA_WIDTH + 2 * (clog2s(C_PCI_DATA_WIDTH/32) + 1));
|
|
localparam C_TXC_PRIORITY = 1;
|
|
localparam C_TXR_PRIORITY = 2;
|
|
/*AUTOWIRE*/
|
|
/*AUTOINPUT*/
|
|
/*AUTOOUTPUT*/
|
|
|
|
// Input Pipeline Stage to Mux
|
|
wire [C_PCI_DATA_WIDTH-1:0] wTxcTlp;
|
|
wire wTxcTlpReady;
|
|
wire wTxcTlpValid;
|
|
wire wTxcTlpStartFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxcTlpStartOffset;
|
|
wire wTxcTlpEndFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxcTlpEndOffset;
|
|
|
|
wire [C_PCI_DATA_WIDTH-1:0] wTxrTlp;
|
|
wire wTxrTlpReady;
|
|
wire wTxrTlpValid;
|
|
wire wTxrTlpStartFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxrTlpStartOffset;
|
|
wire wTxrTlpEndFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxrTlpEndOffset;
|
|
|
|
// Output of Mux to
|
|
wire [C_PCI_DATA_WIDTH-1:0] wTxTlp;
|
|
wire wTxTlpReady;
|
|
wire wTxTlpValid;
|
|
wire wTxTlpStartFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxTlpStartOffset;
|
|
wire wTxTlpEndFlag;
|
|
wire [clog2s(C_PCI_DATA_WIDTH/32)-1:0] wTxTlpEndOffset;
|
|
|
|
pipeline
|
|
#(// Parameters
|
|
.C_DEPTH (C_PIPELINE_INPUT?1:0),
|
|
.C_USE_MEMORY (0),
|
|
/*AUTOINSTPARAM*/
|
|
// Parameters
|
|
.C_WIDTH (C_WIDTH))
|
|
txr_capture_inst
|
|
(// Outputs
|
|
.WR_DATA_READY (TXR_TLP_READY),
|
|
.RD_DATA ({wTxrTlp, wTxrTlpStartFlag, wTxrTlpStartOffset,
|
|
wTxrTlpEndFlag, wTxrTlpEndOffset}),
|
|
.RD_DATA_VALID (wTxrTlpValid),
|
|
// Inputs
|
|
.WR_DATA ({TXR_TLP,
|
|
TXR_TLP_START_FLAG, TXR_TLP_START_OFFSET,
|
|
TXR_TLP_END_FLAG, TXR_TLP_END_OFFSET}),
|
|
.WR_DATA_VALID (TXR_TLP_VALID),
|
|
.RD_DATA_READY (wTxrTlpReady),
|
|
/*AUTOINST*/
|
|
// Inputs
|
|
.CLK (CLK),
|
|
.RST_IN (RST_IN));
|
|
|
|
pipeline
|
|
#(// Parameters
|
|
.C_DEPTH (C_PIPELINE_INPUT?1:0),
|
|
.C_USE_MEMORY (0),
|
|
/*AUTOINSTPARAM*/
|
|
// Parameters
|
|
.C_WIDTH (C_WIDTH))
|
|
txc_capture_inst
|
|
(// Outputs
|
|
.WR_DATA_READY (TXC_TLP_READY),
|
|
.RD_DATA ({wTxcTlp, wTxcTlpStartFlag, wTxcTlpStartOffset,
|
|
wTxcTlpEndFlag, wTxcTlpEndOffset}),
|
|
.RD_DATA_VALID (wTxcTlpValid),
|
|
// Inputs
|
|
.WR_DATA ({TXC_TLP,
|
|
TXC_TLP_START_FLAG, TXC_TLP_START_OFFSET,
|
|
TXC_TLP_END_FLAG, TXC_TLP_END_OFFSET}),
|
|
.WR_DATA_VALID (TXC_TLP_VALID),
|
|
.RD_DATA_READY (wTxcTlpReady),
|
|
/*AUTOINST*/
|
|
// Inputs
|
|
.CLK (CLK),
|
|
.RST_IN (RST_IN));
|
|
|
|
tx_arbiter
|
|
#(/*AUTOINSTPARAM*/
|
|
// Parameters
|
|
.C_TXC_PRIORITY (C_TXC_PRIORITY),
|
|
.C_TXR_PRIORITY (C_TXR_PRIORITY))
|
|
tx_arbiter_inst
|
|
(// Outputs
|
|
.TXR_TLP_READY (wTxrTlpReady),
|
|
.TXC_TLP_READY (wTxcTlpReady),
|
|
// Inputs
|
|
.TX_TLP_READY (wTxTlpReady),
|
|
.TXC_TLP_VALID (wTxcTlpValid),
|
|
.TXC_TLP_START_FLAG (wTxcTlpStartFlag),
|
|
.TXC_TLP_END_FLAG (wTxcTlpEndFlag),
|
|
.TXR_TLP_VALID (wTxrTlpValid),
|
|
.TXR_TLP_START_FLAG (wTxrTlpStartFlag),
|
|
.TXR_TLP_END_FLAG (wTxrTlpEndFlag),
|
|
/*AUTOINST*/
|
|
// Inputs
|
|
.CLK (CLK),
|
|
.RST_IN (RST_IN));
|
|
|
|
// MUX Selector
|
|
|
|
tx_phi
|
|
#(/*AUTOINSTPARAM*/
|
|
// Parameters
|
|
.C_PCI_DATA_WIDTH (C_PCI_DATA_WIDTH),
|
|
.C_MUX_TYPE (C_MUX_TYPE),
|
|
.C_WIDTH (C_WIDTH))
|
|
tx_phi_inst
|
|
(// Outputs
|
|
.TXC_TLP_READY (wTxcTlpReady),
|
|
.TXR_TLP_READY (wTxrTlpReady),
|
|
|
|
.TX_TLP (wTxTlp),
|
|
.TX_TLP_VALID (wTxTlpValid),
|
|
.TX_TLP_START_FLAG (wTxTlpStartFlag),
|
|
.TX_TLP_START_OFFSET (wTxTlpStartOffset),
|
|
.TX_TLP_END_FLAG (wTxTlpEndFlag),
|
|
.TX_TLP_END_OFFSET (wTxTlpEndOffset),
|
|
// Inputs
|
|
.TXC_TLP (wTxcTlp),
|
|
.TXC_TLP_VALID (wTxcTlpValid),
|
|
.TXC_TLP_START_FLAG (wTxcTlpStartFlag),
|
|
.TXC_TLP_START_OFFSET (wTxcTlpStartOffset),
|
|
.TXC_TLP_END_FLAG (wTxcTlpEndFlag),
|
|
.TXC_TLP_END_OFFSET (wTxcTlpEndOffset),
|
|
|
|
.TXR_TLP (wTxrTlp),
|
|
.TXR_TLP_VALID (wTxrTlpValid),
|
|
.TXR_TLP_START_FLAG (wTxrTlpStartFlag),
|
|
.TXR_TLP_START_OFFSET (wTxrTlpStartOffset),
|
|
.TXR_TLP_END_FLAG (wTxrTlpEndFlag),
|
|
.TXR_TLP_END_OFFSET (wTxrTlpEndOffset),
|
|
/*AUTOINST*/
|
|
// Inputs
|
|
.CLK (CLK),
|
|
.RST_IN (RST_IN));
|
|
|
|
pipeline
|
|
#(// Parameters
|
|
.C_DEPTH (C_PIPELINE_OUTPUT?1:0),
|
|
.C_USE_MEMORY (0),
|
|
/*AUTOINSTPARAM*/
|
|
// Parameters
|
|
.C_WIDTH (C_WIDTH))
|
|
tx_output_inst
|
|
(// Outputs
|
|
.WR_DATA_READY (wTxTlpReady),
|
|
.RD_DATA ({TX_TLP,
|
|
TX_TLP_START_FLAG, TX_TLP_START_OFFSET,
|
|
TX_TLP_END_FLAG, TX_TLP_END_OFFSET}),
|
|
.RD_DATA_VALID (TX_TLP_VALID),
|
|
// Inputs
|
|
.WR_DATA ({wTxTlp, wTxTlpStartFlag, wTxTlpStartOffset,
|
|
wTxTlpEndFlag, wTxTlpEndOffset}),
|
|
.WR_DATA_VALID (wTxTlpValid),
|
|
.RD_DATA_READY (TX_TLP_READY),
|
|
/*AUTOINST*/
|
|
// Inputs
|
|
.CLK (CLK),
|
|
.RST_IN (RST_IN));
|
|
|
|
endmodule
|
|
// Local Variables:
|
|
// verilog-library-directories:("." "../../../common/")
|
|
// End:
|
|
|
|
/*
|
|
Description: The tx_arbiter arbitrates between TXC and TXR channels. The C_TX*_PRIORITY
|
|
values are counters are the maximum number of uninterrupted TXR or TXC packets that can be
|
|
transmitted without transmitting a packet of the other type.
|
|
|
|
Notes: Any modifications to this file should meet the conditions set
|
|
forth in the "Trellis Style Guide"
|
|
|
|
Author: Dustin Richmond (@darichmond)
|
|
Co-Authors:
|
|
*/
|
|
module tx_arbiter
|
|
#(parameter C_TXC_PRIORITY = 1,
|
|
parameter C_TXR_PRIORITY = 1)
|
|
(
|
|
// Interface: Clocks
|
|
input CLK,
|
|
|
|
// Interface: Resets
|
|
input RST_IN,
|
|
|
|
// Interface: TX Classic Flow Control
|
|
input TX_TLP_READY,
|
|
|
|
// Interface: TXR Flow Control
|
|
output TXR_TLP_READY,
|
|
input TXR_TLP_VALID,
|
|
input TXR_TLP_START_FLAG,
|
|
input TXR_TLP_END_FLAG,
|
|
|
|
// Interface: TXC Flow Control
|
|
output TXC_TLP_READY,
|
|
input TXC_TLP_VALID,
|
|
input TXC_TLP_START_FLAG,
|
|
input TXC_TLP_END_FLAG);
|
|
|
|
localparam S_TXARB_IDLE = 0; // STATE: Idle state for the arbiter (not currently used)
|
|
localparam S_TXARB_TRANSMIT_TXR = 1; // STATE: Transmit TXR packets until the priority counter is reached
|
|
localparam S_TXARB_TRANSMIT_TXC = 2; // STATE: Transmit TXC packets until the priority counter is reached
|
|
|
|
// S_TXARB_PRIORITY is a special state that encodes the type (TXR/TXC) with
|
|
// higher priority so that the state machine (below) is general.
|
|
localparam S_TXARB_PRIORITY = (S_TXARB_TRANSMIT_TXR >= S_TXARB_TRANSMIT_TXC)? S_TXARB_TRANSMIT_TXR: S_TXARB_TRANSMIT_TXC;
|
|
localparam C_NUM_STATES = S_TXARB_TRANSMIT_TXC;
|
|
|
|
wire wTxrGrant;
|
|
wire wTxrReq;
|
|
wire wTxrDone;
|
|
|
|
wire wTxcGrant;
|
|
wire wTxcReq;
|
|
wire wTxcDone;
|
|
|
|
reg [clog2s(C_NUM_STATES):0] rArbState,_rArbState;
|
|
|
|
reg rTxrLast,_rTxrLast; // Reset on RST_IN or TXC_TLP_READY
|
|
reg rTxcLast,_rTxcLast; // Reset on RST_IN or TXR_TLP_READY
|
|
|
|
reg rTxrActive,_rTxrActive; // Reset on RST_IN or TXC_TLP_READY
|
|
reg rTxcActive,_rTxcActive; // Reset on RST_IN or TXR_TLP_READY
|
|
|
|
reg [clog2s(C_TXC_PRIORITY)-1:0] rTxcCounter,_rTxcCounter; // Reset on RST_IN or TXC_TLP_READY
|
|
reg [clog2s(C_TXR_PRIORITY)-1:0] rTxrCounter,_rTxrCounter; // Reset on RST_IN or TXR_TLP_READY
|
|
|
|
assign TXR_TLP_READY = wTxrGrant & TX_TLP_READY; // TODO: Not great
|
|
assign wTxrReq = TXR_TLP_START_FLAG & TXR_TLP_VALID;
|
|
assign wTxrDone = TXR_TLP_END_FLAG & TXR_TLP_READY;
|
|
assign wTxrGrant = (rArbState == S_TXARB_TRANSMIT_TXR);
|
|
|
|
assign TXC_TLP_READY = wTxcGrant & TX_TLP_READY; // TODO: Not great
|
|
assign wTxcReq = TXC_TLP_START_FLAG & TXC_TLP_VALID;
|
|
assign wTxcDone = TXC_TLP_END_FLAG & TXC_TLP_READY;
|
|
assign wTxcGrant = (rArbState == S_TXARB_TRANSMIT_TXC);
|
|
|
|
always @(*) begin
|
|
// Defaults
|
|
_rTxcCounter = rTxcCounter;
|
|
_rTxcActive = rTxcActive;
|
|
_rTxcLast = rTxcLast;
|
|
|
|
if(wTxrGrant) begin
|
|
_rTxcCounter = 0;
|
|
end else if(wTxcReq & wTxcGrant & ~rTxcLast) begin
|
|
_rTxcCounter = _rTxcCounter + 1;
|
|
end
|
|
|
|
if(wTxcReq & wTxcGrant) begin
|
|
_rTxcActive = 1;
|
|
end else if(wTxcDone) begin
|
|
_rTxcActive = 0;
|
|
end
|
|
|
|
if(wTxrGrant | RST_IN) begin
|
|
_rTxcLast = 0;
|
|
end else if(wTxcReq & wTxcGrant) begin
|
|
_rTxcLast = (rTxcCounter == (C_TXC_PRIORITY - 1));
|
|
end
|
|
end // always @ (*)
|
|
|
|
always @(posedge CLK) begin
|
|
if(RST_IN) begin
|
|
rTxcCounter <= #1 0;
|
|
rTxcActive <= #1 0;
|
|
rTxcLast <= #1 0;
|
|
end else begin
|
|
rTxcCounter <= #1 _rTxcCounter;
|
|
rTxcActive <= #1 _rTxcActive;
|
|
rTxcLast <= #1 _rTxcLast;
|
|
end
|
|
end
|
|
|
|
always @(*) begin
|
|
// Defaults
|
|
_rTxrCounter = rTxrCounter;
|
|
_rTxrActive = rTxrActive;
|
|
_rTxrLast = rTxrLast;
|
|
|
|
if(wTxcGrant) begin
|
|
_rTxrCounter = 0;
|
|
end else if(wTxrReq & wTxrGrant & ~rTxrLast) begin
|
|
_rTxrCounter = _rTxrCounter + 1;
|
|
end
|
|
|
|
if(wTxrReq & wTxrGrant) begin
|
|
_rTxrActive = 1;
|
|
end else if(wTxrDone) begin
|
|
_rTxrActive = 0;
|
|
end
|
|
|
|
if(wTxcGrant | RST_IN) begin
|
|
_rTxrLast = 0;
|
|
end else if(wTxrReq & wTxrGrant) begin
|
|
/* verilator lint_off WIDTH */
|
|
_rTxrLast = (rTxrCounter == (C_TXR_PRIORITY - 1));
|
|
/* verilator lint_on WIDTH */
|
|
end
|
|
end
|
|
|
|
always @(posedge CLK) begin
|
|
if(RST_IN) begin
|
|
rTxrCounter <= #1 0;
|
|
rTxrActive <= #1 0;
|
|
rTxrLast <= #1 0;
|
|
end else begin
|
|
rTxrCounter <= #1 _rTxrCounter;
|
|
rTxrActive <= #1 _rTxrActive;
|
|
rTxrLast <= #1 _rTxrLast;
|
|
end
|
|
end
|
|
|
|
// User encoded state machine
|
|
always @(*) begin
|
|
_rArbState = rArbState;
|
|
|
|
case(rArbState)
|
|
S_TXARB_TRANSMIT_TXR: begin
|
|
if((rTxrLast & wTxrDone & wTxcReq) | (~rTxrActive & ~wTxrReq & wTxcReq)) begin
|
|
_rArbState = S_TXARB_TRANSMIT_TXC;
|
|
end
|
|
end
|
|
S_TXARB_TRANSMIT_TXC: begin
|
|
if((rTxcLast & wTxcDone & wTxrReq) | (~rTxcActive & ~wTxcReq & wTxrReq)) begin
|
|
_rArbState = S_TXARB_TRANSMIT_TXR;
|
|
end
|
|
end
|
|
default: begin
|
|
// Error! This should never happen...
|
|
end
|
|
endcase
|
|
end // always @ begin
|
|
|
|
always @(posedge CLK) begin
|
|
if(RST_IN) begin
|
|
rArbState <= #1 S_TXARB_PRIORITY;
|
|
end else begin
|
|
rArbState <= #1 _rArbState;
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
/*
|
|
Description: The tx_phi wraps a mux instantiation for the tx_mux. It is
|
|
controlled by the tx_arbiter
|
|
|
|
Notes: Any modifications to this file should meet the conditions set
|
|
forth in the "Trellis Style Guide"
|
|
|
|
Author: Dustin Richmond (@darichmond)
|
|
Co-Authors:
|
|
*/
|
|
module tx_phi
|
|
#(parameter C_PCI_DATA_WIDTH = 10'd128,
|
|
parameter C_MUX_TYPE = "SHIFT",
|
|
parameter C_WIDTH = (C_PCI_DATA_WIDTH + 2 * (clog2s(C_PCI_DATA_WIDTH/32) + 1)))
|
|
(// Interface: Clocks
|
|
input CLK,
|
|
|
|
// Interface: Resets
|
|
input RST_IN,
|
|
|
|
// Interface: TXC Flow Control
|
|
input TXC_TLP_READY,
|
|
|
|
// Interface: TXR Flow Control
|
|
input TXR_TLP_READY,
|
|
|
|
// Interface: TXC
|
|
input [C_PCI_DATA_WIDTH-1:0] TXC_TLP,
|
|
input TXC_TLP_VALID,
|
|
input TXC_TLP_START_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXC_TLP_START_OFFSET,
|
|
input TXC_TLP_END_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXC_TLP_END_OFFSET,
|
|
|
|
// Interface: TXR
|
|
input [C_PCI_DATA_WIDTH-1:0] TXR_TLP,
|
|
input TXR_TLP_VALID,
|
|
input TXR_TLP_START_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXR_TLP_START_OFFSET,
|
|
input TXR_TLP_END_FLAG,
|
|
input [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TXR_TLP_END_OFFSET,
|
|
|
|
// Interface: TX Classic
|
|
output [C_PCI_DATA_WIDTH-1:0] TX_TLP,
|
|
output TX_TLP_VALID,
|
|
output TX_TLP_START_FLAG,
|
|
output [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TX_TLP_START_OFFSET,
|
|
output TX_TLP_END_FLAG,
|
|
output [clog2s(C_PCI_DATA_WIDTH/32)-1:0] TX_TLP_END_OFFSET);
|
|
|
|
// Width = 2 * (DATA WIDTH + VALID + START FLAG + START OFFSET + END FLAG + END OFFSET)
|
|
localparam C_MUX_WIDTH = C_PCI_DATA_WIDTH + 3 + 2*clog2s(C_PCI_DATA_WIDTH/32);
|
|
|
|
wire [2*C_MUX_WIDTH-1:0] wAggregate;
|
|
|
|
assign wAggregate = {{TXR_TLP,TXR_TLP_VALID,TXR_TLP_START_FLAG,
|
|
TXR_TLP_START_OFFSET,TXR_TLP_END_FLAG,TXR_TLP_END_OFFSET},
|
|
{TXC_TLP,TXC_TLP_VALID,TXC_TLP_START_FLAG,
|
|
TXC_TLP_START_OFFSET,TXC_TLP_END_FLAG,TXC_TLP_END_OFFSET}};
|
|
|
|
mux
|
|
#(// Parameters
|
|
.C_NUM_INPUTS (2),
|
|
.C_CLOG_NUM_INPUTS (1),
|
|
.C_WIDTH (C_MUX_WIDTH),
|
|
.C_MUX_TYPE ("SELECT")
|
|
/*AUTOINSTPARAM*/)
|
|
mux_inst
|
|
(// Outputs
|
|
.MUX_OUTPUT ({TX_TLP,TX_TLP_VALID,TX_TLP_START_FLAG,
|
|
TX_TLP_START_OFFSET,TX_TLP_END_FLAG,
|
|
TX_TLP_END_OFFSET}),
|
|
// Inputs
|
|
.MUX_INPUTS (wAggregate),
|
|
.MUX_SELECT (TXR_TLP_READY)
|
|
/*AUTOINST*/);
|
|
|
|
endmodule
|