mirror of
https://github.com/KastnerRG/riffa.git
synced 2025-01-30 23:02:54 +08:00
251 lines
8.0 KiB
Verilog
251 lines
8.0 KiB
Verilog
// ----------------------------------------------------------------------
|
|
// 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.
|
|
// ----------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
// Filename: tx_port_monitor_64.v
|
|
// Version: 1.00.a
|
|
// Verilog Standard: Verilog-2001
|
|
// Description: Detects transaction open/close events from the stream
|
|
// of data from the tx_port_channel_gate. Filters out events and passes data
|
|
// onto the tx_port_buffer.
|
|
// Author: Matt Jacobsen
|
|
// History: @mattj: Version 2.0
|
|
//-----------------------------------------------------------------------------
|
|
`define S_TXPORTMON64_NEXT 5'b0_0001
|
|
`define S_TXPORTMON64_TXN 5'b0_0010
|
|
`define S_TXPORTMON64_READ 5'b0_0100
|
|
`define S_TXPORTMON64_END_0 5'b0_1000
|
|
`define S_TXPORTMON64_END_1 5'b1_0000
|
|
|
|
`timescale 1ns/1ns
|
|
module tx_port_monitor_64 #(
|
|
parameter C_DATA_WIDTH = 9'd64,
|
|
parameter C_FIFO_DEPTH = 512,
|
|
// Local parameters
|
|
parameter C_FIFO_DEPTH_THRESH = (C_FIFO_DEPTH - 4),
|
|
parameter C_FIFO_DEPTH_WIDTH = clog2((2**clog2(C_FIFO_DEPTH))+1),
|
|
parameter C_VALID_HIST = 1
|
|
)
|
|
(
|
|
input RST,
|
|
input CLK,
|
|
|
|
input [C_DATA_WIDTH:0] EVT_DATA, // Event data from tx_port_channel_gate
|
|
input EVT_DATA_EMPTY, // Event data FIFO is empty
|
|
output EVT_DATA_RD_EN, // Event data FIFO read enable
|
|
|
|
output [C_DATA_WIDTH-1:0] WR_DATA, // Output data
|
|
output WR_EN, // Write enable for output data
|
|
input [C_FIFO_DEPTH_WIDTH-1:0] WR_COUNT, // Output FIFO count
|
|
|
|
output TXN, // Transaction parameters are valid
|
|
input ACK, // Transaction parameter read, continue
|
|
output LAST, // Channel last write
|
|
output [31:0] LEN, // Channel write length (in 32 bit words)
|
|
output [30:0] OFF, // Channel write offset
|
|
output [31:0] WORDS_RECVD, // Count of data words received in transaction
|
|
output DONE, // Transaction is closed
|
|
|
|
input TX_ERR // Transaction encountered an error
|
|
);
|
|
|
|
`include "functions.vh"
|
|
|
|
(* syn_encoding = "user" *)
|
|
(* fsm_encoding = "user" *)
|
|
reg [4:0] rState=`S_TXPORTMON64_NEXT, _rState=`S_TXPORTMON64_NEXT;
|
|
reg rRead=0, _rRead=0;
|
|
reg [C_VALID_HIST-1:0] rDataValid={C_VALID_HIST{1'd0}}, _rDataValid={C_VALID_HIST{1'd0}};
|
|
reg rEvent=0, _rEvent=0;
|
|
reg [63:0] rReadData=64'd0, _rReadData=64'd0;
|
|
reg [31:0] rWordsRecvd=0, _rWordsRecvd=0;
|
|
reg [31:0] rWordsRecvdAdv=0, _rWordsRecvdAdv=0;
|
|
reg rAlmostAllRecvd=0, _rAlmostAllRecvd=0;
|
|
reg rAlmostFull=0, _rAlmostFull=0;
|
|
reg rLenEQ0Hi=0, _rLenEQ0Hi=0;
|
|
reg rLenEQ0Lo=0, _rLenEQ0Lo=0;
|
|
reg rLenLE2Lo=0, _rLenLE2Lo=0;
|
|
reg rTxErr=0, _rTxErr=0;
|
|
|
|
|
|
wire wEventData = (rDataValid[0] & EVT_DATA[C_DATA_WIDTH]);
|
|
wire wPayloadData = (rDataValid[0] & !EVT_DATA[C_DATA_WIDTH] & rState[2]); // S_TXPORTMON64_READ
|
|
wire wAllWordsRecvd = ((rAlmostAllRecvd | (rLenEQ0Hi & rLenLE2Lo)) & wPayloadData);
|
|
|
|
assign EVT_DATA_RD_EN = rRead;
|
|
|
|
assign WR_DATA = EVT_DATA[C_DATA_WIDTH-1:0];
|
|
assign WR_EN = wPayloadData; // S_TXPORTMON64_READ
|
|
|
|
assign TXN = rState[1]; // S_TXPORTMON64_TXN
|
|
assign LAST = rReadData[0];
|
|
assign OFF = rReadData[31:1];
|
|
assign LEN = rReadData[63:32];
|
|
assign WORDS_RECVD = rWordsRecvd;
|
|
assign DONE = !rState[2]; // !S_TXPORTMON64_READ
|
|
|
|
|
|
|
|
|
|
// Buffer the input signals that come from outside the tx_port.
|
|
always @ (posedge CLK) begin
|
|
rTxErr <= #1 (RST ? 1'd0 : _rTxErr);
|
|
end
|
|
|
|
always @ (*) begin
|
|
_rTxErr = TX_ERR;
|
|
end
|
|
|
|
|
|
// Transaction monitoring FSM.
|
|
always @ (posedge CLK) begin
|
|
rState <= #1 (RST ? `S_TXPORTMON64_NEXT : _rState);
|
|
end
|
|
|
|
always @ (*) begin
|
|
_rState = rState;
|
|
case (rState)
|
|
|
|
`S_TXPORTMON64_NEXT: begin // Read, wait for start of transaction event
|
|
if (rEvent)
|
|
_rState = `S_TXPORTMON64_TXN;
|
|
end
|
|
|
|
`S_TXPORTMON64_TXN: begin // Don't read, wait until transaction has been acknowledged
|
|
if (ACK)
|
|
_rState = ((rLenEQ0Hi && rLenEQ0Lo) ? `S_TXPORTMON64_END_0 : `S_TXPORTMON64_READ);
|
|
end
|
|
|
|
`S_TXPORTMON64_READ: begin // Continue reading, wait for end of transaction event or all expected data
|
|
if (rEvent)
|
|
_rState = `S_TXPORTMON64_END_1;
|
|
else if (wAllWordsRecvd | rTxErr)
|
|
_rState = `S_TXPORTMON64_END_0;
|
|
end
|
|
|
|
`S_TXPORTMON64_END_0: begin // Continue reading, wait for first end of transaction event
|
|
if (rEvent)
|
|
_rState = `S_TXPORTMON64_END_1;
|
|
end
|
|
|
|
`S_TXPORTMON64_END_1: begin // Continue reading, wait for second end of transaction event
|
|
if (rEvent)
|
|
_rState = `S_TXPORTMON64_NEXT;
|
|
end
|
|
|
|
default: begin
|
|
_rState = `S_TXPORTMON64_NEXT;
|
|
end
|
|
|
|
endcase
|
|
end
|
|
|
|
|
|
// Manage reading from the FIFO and tracking amounts read.
|
|
always @ (posedge CLK) begin
|
|
rRead <= #1 (RST ? 1'd0 : _rRead);
|
|
rDataValid <= #1 (RST ? {C_VALID_HIST{1'd0}} : _rDataValid);
|
|
rEvent <= #1 (RST ? 1'd0 : _rEvent);
|
|
rReadData <= #1 _rReadData;
|
|
rWordsRecvd <= #1 _rWordsRecvd;
|
|
rWordsRecvdAdv <= #1 _rWordsRecvdAdv;
|
|
rAlmostAllRecvd <= #1 _rAlmostAllRecvd;
|
|
rAlmostFull <= #1 _rAlmostFull;
|
|
rLenEQ0Hi <= #1 _rLenEQ0Hi;
|
|
rLenEQ0Lo <= #1 _rLenEQ0Lo;
|
|
rLenLE2Lo <= #1 _rLenLE2Lo;
|
|
end
|
|
|
|
always @ (*) begin
|
|
// Don't get to the full point in the output FIFO
|
|
_rAlmostFull = (WR_COUNT >= C_FIFO_DEPTH_THRESH);
|
|
|
|
// Track read history so we know when data is valid
|
|
_rDataValid = ((rDataValid<<1) | (rRead & !EVT_DATA_EMPTY));
|
|
|
|
// Read until we get a (valid) event
|
|
_rRead = (!rState[1] & !wEventData & !rAlmostFull); // !S_TXPORTMON64_TXN
|
|
|
|
// Track detected events
|
|
_rEvent = wEventData;
|
|
|
|
// Save event data when valid
|
|
if (wEventData)
|
|
_rReadData = EVT_DATA[C_DATA_WIDTH-1:0];
|
|
else
|
|
_rReadData = rReadData;
|
|
|
|
// If LEN == 0, we don't want to send any data to the output
|
|
_rLenEQ0Hi = (LEN[31:16] == 16'd0);
|
|
_rLenEQ0Lo = (LEN[15:0] == 16'd0);
|
|
|
|
// If LEN <= 2, we want to trigger the almost all received flag
|
|
_rLenLE2Lo = (LEN[15:0] <= 16'd2);
|
|
|
|
// Count received non-event data
|
|
_rWordsRecvd = (ACK ? 0 : rWordsRecvd + (wPayloadData<<1));
|
|
_rWordsRecvdAdv = (ACK ? 2*(C_DATA_WIDTH/32) : rWordsRecvdAdv + (wPayloadData<<1));
|
|
_rAlmostAllRecvd = ((rWordsRecvdAdv >= LEN) && wPayloadData);
|
|
end
|
|
|
|
/*
|
|
wire [35:0] wControl0;
|
|
chipscope_icon_1 cs_icon(
|
|
.CONTROL0(wControl0)
|
|
);
|
|
|
|
chipscope_ila_t8_512 a0(
|
|
.CLK(CLK),
|
|
.CONTROL(wControl0),
|
|
.TRIG0({TXN, wPayloadData, wEventData, rState}),
|
|
.DATA({297'd0,
|
|
WR_COUNT, // 10
|
|
wPayloadData, // 1
|
|
EVT_DATA_RD_EN, // 1
|
|
RST, // 1
|
|
rTxErr, // 1
|
|
wEventData, // 1
|
|
rReadData, // 64
|
|
OFF, // 31
|
|
LEN, // 32
|
|
LAST, // 1
|
|
TXN, // 1
|
|
EVT_DATA_EMPTY, // 1
|
|
EVT_DATA, // 65
|
|
rState}) // 5
|
|
);
|
|
*/
|
|
|
|
endmodule
|