mirror of
https://github.com/KastnerRG/riffa.git
synced 2025-01-30 23:02:54 +08:00
222 lines
6.9 KiB
Verilog
222 lines
6.9 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_port_channel_gate_64.v
|
|
// Version: 1.00.a
|
|
// Verilog Standard: Verilog-2001
|
|
// Description: Captures transaction open/close events as well as data
|
|
// and passes it to the RD_CLK domain through the async_fifo. CHNL_TX_DATA_REN can
|
|
// only be high after CHNL_TX goes high and after the CHNL_TX_ACK pulse. When
|
|
// CHNL_TX drops, the channel closes (until the next transaction -- signaled by
|
|
// CHNL_TX going up again).
|
|
// Author: Matt Jacobsen
|
|
// History: @mattj: Version 2.0
|
|
//-----------------------------------------------------------------------------
|
|
`define S_TXPORTGATE64_IDLE 2'b00
|
|
`define S_TXPORTGATE64_OPENING 2'b01
|
|
`define S_TXPORTGATE64_OPEN 2'b10
|
|
`define S_TXPORTGATE64_CLOSED 2'b11
|
|
|
|
`timescale 1ns/1ns
|
|
module tx_port_channel_gate_64 #(
|
|
parameter C_DATA_WIDTH = 9'd64,
|
|
// Local parameters
|
|
parameter C_FIFO_DEPTH = 8,
|
|
parameter C_FIFO_DATA_WIDTH = C_DATA_WIDTH+1
|
|
)
|
|
(
|
|
input RST,
|
|
|
|
input RD_CLK, // FIFO read clock
|
|
output [C_FIFO_DATA_WIDTH-1:0] RD_DATA, // FIFO read data
|
|
output RD_EMPTY, // FIFO is empty
|
|
input RD_EN, // FIFO read enable
|
|
|
|
input CHNL_CLK, // Channel write clock
|
|
input CHNL_TX, // Channel write receive signal
|
|
output CHNL_TX_ACK, // Channel write acknowledgement signal
|
|
input CHNL_TX_LAST, // Channel last write
|
|
input [31:0] CHNL_TX_LEN, // Channel write length (in 32 bit words)
|
|
input [30:0] CHNL_TX_OFF, // Channel write offset
|
|
input [C_DATA_WIDTH-1:0] CHNL_TX_DATA, // Channel write data
|
|
input CHNL_TX_DATA_VALID, // Channel write data valid
|
|
output CHNL_TX_DATA_REN // Channel write data has been recieved
|
|
);
|
|
|
|
(* syn_encoding = "user" *)
|
|
(* fsm_encoding = "user" *)
|
|
reg [1:0] rState=`S_TXPORTGATE64_IDLE, _rState=`S_TXPORTGATE64_IDLE;
|
|
reg rFifoWen=0, _rFifoWen=0;
|
|
reg [C_FIFO_DATA_WIDTH-1:0] rFifoData=0, _rFifoData=0;
|
|
wire wFifoFull;
|
|
|
|
reg rChnlTx=0, _rChnlTx=0;
|
|
reg rChnlLast=0, _rChnlLast=0;
|
|
reg [31:0] rChnlLen=0, _rChnlLen=0;
|
|
reg [30:0] rChnlOff=0, _rChnlOff=0;
|
|
reg rAck=0, _rAck=0;
|
|
reg rPause=0, _rPause=0;
|
|
reg rClosed=0, _rClosed=0;
|
|
|
|
|
|
assign CHNL_TX_ACK = rAck;
|
|
assign CHNL_TX_DATA_REN = (rState[1] & !rState[0] & !wFifoFull); // S_TXPORTGATE64_OPEN
|
|
|
|
|
|
// Buffer the input signals that come from outside the tx_port.
|
|
always @ (posedge CHNL_CLK) begin
|
|
rChnlTx <= #1 (RST ? 1'd0 : _rChnlTx);
|
|
rChnlLast <= #1 _rChnlLast;
|
|
rChnlLen <= #1 _rChnlLen;
|
|
rChnlOff <= #1 _rChnlOff;
|
|
end
|
|
|
|
always @ (*) begin
|
|
_rChnlTx = CHNL_TX;
|
|
_rChnlLast = CHNL_TX_LAST;
|
|
_rChnlLen = CHNL_TX_LEN;
|
|
_rChnlOff = CHNL_TX_OFF;
|
|
end
|
|
|
|
|
|
// FIFO for temporarily storing data from the channel.
|
|
(* RAM_STYLE="DISTRIBUTED" *)
|
|
async_fifo #(.C_WIDTH(C_FIFO_DATA_WIDTH), .C_DEPTH(C_FIFO_DEPTH)) fifo (
|
|
.WR_CLK(CHNL_CLK),
|
|
.WR_RST(RST),
|
|
.WR_EN(rFifoWen),
|
|
.WR_DATA(rFifoData),
|
|
.WR_FULL(wFifoFull),
|
|
.RD_CLK(RD_CLK),
|
|
.RD_RST(RST),
|
|
.RD_EN(RD_EN),
|
|
.RD_DATA(RD_DATA),
|
|
.RD_EMPTY(RD_EMPTY)
|
|
);
|
|
|
|
|
|
// Pass the transaction open event, transaction data, and the transaction
|
|
// close event through to the RD_CLK domain via the async_fifo.
|
|
always @ (posedge CHNL_CLK) begin
|
|
rState <= #1 (RST ? `S_TXPORTGATE64_IDLE : _rState);
|
|
rFifoWen <= #1 (RST ? 1'd0 : _rFifoWen);
|
|
rFifoData <= #1 _rFifoData;
|
|
rAck <= #1 (RST ? 1'd0 : _rAck);
|
|
rPause <= #1 (RST ? 1'd0 : _rPause);
|
|
rClosed <= #1 (RST ? 1'd0 : _rClosed);
|
|
end
|
|
|
|
always @ (*) begin
|
|
_rState = rState;
|
|
_rFifoWen = rFifoWen;
|
|
_rFifoData = rFifoData;
|
|
_rPause = rPause;
|
|
_rAck = rAck;
|
|
_rClosed = rClosed;
|
|
case (rState)
|
|
|
|
`S_TXPORTGATE64_IDLE: begin // Write the len, off, last
|
|
_rPause = 0;
|
|
_rClosed = 0;
|
|
if (!wFifoFull) begin
|
|
_rAck = rChnlTx;
|
|
_rFifoWen = rChnlTx;
|
|
_rFifoData = {1'd1, rChnlLen, rChnlOff, rChnlLast};
|
|
if (rChnlTx)
|
|
_rState = `S_TXPORTGATE64_OPENING;
|
|
end
|
|
end
|
|
|
|
`S_TXPORTGATE64_OPENING: begin // Write the len, off, last (again)
|
|
_rAck = 0;
|
|
_rClosed = (rClosed | !rChnlTx);
|
|
if (!wFifoFull) begin
|
|
if (rClosed | !rChnlTx)
|
|
_rState = `S_TXPORTGATE64_CLOSED;
|
|
else
|
|
_rState = `S_TXPORTGATE64_OPEN;
|
|
end
|
|
end
|
|
|
|
`S_TXPORTGATE64_OPEN: begin // Copy channel data into the FIFO
|
|
if (!wFifoFull) begin
|
|
_rFifoWen = CHNL_TX_DATA_VALID; // CHNL_TX_DATA_VALID & CHNL_TX_DATA should really be buffered
|
|
_rFifoData = {1'd0, CHNL_TX_DATA}; // but the VALID+REN model seem to make this difficult.
|
|
end
|
|
if (!rChnlTx)
|
|
_rState = `S_TXPORTGATE64_CLOSED;
|
|
end
|
|
|
|
`S_TXPORTGATE64_CLOSED: begin // Write the end marker (twice)
|
|
if (!wFifoFull) begin
|
|
_rPause = 1;
|
|
_rFifoWen = 1;
|
|
_rFifoData = {1'd1, {C_DATA_WIDTH{1'd0}}};
|
|
if (rPause)
|
|
_rState = `S_TXPORTGATE64_IDLE;
|
|
end
|
|
end
|
|
|
|
endcase
|
|
end
|
|
|
|
/*
|
|
wire [35:0] wControl0;
|
|
chipscope_icon_1 cs_icon(
|
|
.CONTROL0(wControl0)
|
|
);
|
|
|
|
chipscope_ila_t8_512 a0(
|
|
.CLK(CHNL_CLK),
|
|
.CONTROL(wControl0),
|
|
.TRIG0({4'd0, wFifoFull, CHNL_TX, rState}),
|
|
.DATA({313'd0,
|
|
rChnlOff, // 31
|
|
rChnlLen, // 32
|
|
rChnlLast, // 1
|
|
rChnlTx, // 1
|
|
CHNL_TX_OFF, // 31
|
|
CHNL_TX_LEN, // 32
|
|
CHNL_TX_LAST, // 1
|
|
CHNL_TX, // 1
|
|
wFifoFull, // 1
|
|
rFifoData, // 65
|
|
rFifoWen, // 1
|
|
rState}) // 2
|
|
);
|
|
*/
|
|
|
|
endmodule
|