Pushing the bulk of UHD-3.7.0 code.
Original-commit: ff1546f8137f7f92bb250f685561b0c34cc0e053
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
//
|
||||
// Ultra fast critical path FIFO.
|
||||
// Only 2 entrys but no combinatorial feed through paths
|
||||
//
|
||||
|
||||
|
||||
module axi_fast_extract_tlast
|
||||
#(parameter WIDTH=64)
|
||||
(
|
||||
input clk,
|
||||
input reset,
|
||||
input clear,
|
||||
//
|
||||
input [WIDTH-1:0] i_tdata,
|
||||
input i_tvalid,
|
||||
output reg i_tready,
|
||||
//
|
||||
output [WIDTH-1:0] o_tdata,
|
||||
output o_tlast,
|
||||
output reg o_tvalid,
|
||||
input o_tready
|
||||
);
|
||||
|
||||
reg [WIDTH:0] data_reg1, data_reg2;
|
||||
|
||||
reg [1:0] fifo_state;
|
||||
|
||||
localparam EMPTY = 0;
|
||||
localparam HALF = 1;
|
||||
localparam FULL = 2;
|
||||
|
||||
reg [1:0] extract_state;
|
||||
|
||||
localparam IDLE = 0;
|
||||
localparam EXTRACT1 = 1;
|
||||
localparam EXTRACT2 = 2;
|
||||
localparam EXTRACT3 = 3;
|
||||
|
||||
|
||||
always @(posedge clk)
|
||||
if (reset | clear) begin
|
||||
fifo_state <= EMPTY;
|
||||
end else begin
|
||||
case (fifo_state)
|
||||
// Nothing in either register.
|
||||
// Upstream can always push data to us.
|
||||
// Downstream has nothing to take from us.
|
||||
EMPTY: begin
|
||||
if ((extract_state == IDLE) && (i_tdata == 64'hDEADBEEFFEEDCAFE) && i_tvalid) begin
|
||||
// Embeded escpae code received.
|
||||
extract_state <= EXTRACT1;
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b0;
|
||||
fifo_state <= EMPTY;
|
||||
end else if ((extract_state == EXTRACT1) && i_tvalid) begin
|
||||
// Now work out if its a genuine embeded tlast or emulation.
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b0;
|
||||
fifo_state <= EMPTY;
|
||||
if (i_tdata[31:0] == 'h1) begin
|
||||
extract_state <= EXTRACT2;
|
||||
end else begin
|
||||
extract_state <= EXTRACT3;
|
||||
end
|
||||
end else if ((extract_state == EXTRACT2) && i_tvalid) begin
|
||||
// Extract tlast.
|
||||
data_reg1 <= {1'b1,i_tdata};
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b1;
|
||||
fifo_state <= HALF;
|
||||
extract_state <= IDLE;
|
||||
end else if (i_tvalid) begin
|
||||
// Get here both for normal data and for EXTRACT3 emulation data.
|
||||
data_reg1 <= {1'b0,i_tdata};
|
||||
fifo_state <= HALF;
|
||||
extract_state <= IDLE;
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b1;
|
||||
end else begin
|
||||
// Nothing to do.
|
||||
fifo_state <= EMPTY;
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
// First Register Full.
|
||||
// Upstream can always push data to us.
|
||||
// Downstream can always read from us.
|
||||
HALF: begin
|
||||
if ((extract_state == IDLE) && (i_tdata == 64'hDEADBEEFFEEDCAFE) && i_tvalid) begin
|
||||
// Embeded escpae code received.
|
||||
extract_state <= EXTRACT1;
|
||||
if (o_tready) begin
|
||||
// If meanwhile we get read then go empty...
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b0;
|
||||
fifo_state <= EMPTY;
|
||||
end else begin
|
||||
// ...else stay half full.
|
||||
fifo_state <= HALF;
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b1;
|
||||
end
|
||||
end else if ((extract_state == EXTRACT1) && i_tvalid) begin
|
||||
// Now work out if its a genuine embeded tlast or emulation.
|
||||
if (i_tdata[31:0] == 'h1) begin
|
||||
extract_state <= EXTRACT2;
|
||||
end else begin
|
||||
extract_state <= EXTRACT3;
|
||||
end
|
||||
if (o_tready) begin
|
||||
// If meanwhile we get read then go empty...
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b0;
|
||||
fifo_state <= EMPTY;
|
||||
end else begin
|
||||
// ...else stay half full.
|
||||
fifo_state <= HALF;
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b1;
|
||||
end
|
||||
end else if ((extract_state == EXTRACT2) && i_tvalid) begin
|
||||
// Extract tlast.
|
||||
data_reg1 <= {1'b1,i_tdata};
|
||||
extract_state <= IDLE;
|
||||
if (o_tready) begin
|
||||
// We get read and writen same cycle...
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b1;
|
||||
fifo_state <= HALF;
|
||||
end else begin
|
||||
// ...or we get written and go full.
|
||||
data_reg2 <= data_reg1;
|
||||
i_tready <= 1'b0;
|
||||
o_tvalid <= 1'b1;
|
||||
fifo_state <= FULL;
|
||||
end
|
||||
end else if (i_tvalid) begin
|
||||
// Get here both for normal data and for EXTRACT3 emulation data.
|
||||
data_reg1 <= {1'b0,i_tdata};
|
||||
extract_state <= IDLE;
|
||||
if (o_tready) begin
|
||||
// We get read and writen same cycle...
|
||||
fifo_state <= HALF;
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b1;
|
||||
end else begin
|
||||
// ...or we get written and go full.
|
||||
data_reg2 <= data_reg1;
|
||||
i_tready <= 1'b0;
|
||||
o_tvalid <= 1'b1;
|
||||
fifo_state <= FULL;
|
||||
end
|
||||
end else if (o_tready) begin // if (i_tvalid)
|
||||
// Only getting read this cycle so go empty
|
||||
fifo_state <= EMPTY;
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b0;
|
||||
end else begin
|
||||
// Absolutley nothing happens, everything stays the same.
|
||||
fifo_state <= HALF;
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b1;
|
||||
end
|
||||
end // case: HALF
|
||||
// Both Registers Full.
|
||||
// Upstream can not push to us in this fifo_state.
|
||||
// Downstream can always read from us.
|
||||
FULL: begin
|
||||
if (o_tready) begin
|
||||
fifo_state <= HALF;
|
||||
i_tready <= 1'b1;
|
||||
o_tvalid <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
fifo_state <= FULL;
|
||||
i_tready <= 1'b0;
|
||||
o_tvalid <= 1'b1;
|
||||
end
|
||||
end
|
||||
endcase // case(fifo_state)
|
||||
end // else: !if(reset | clear)
|
||||
|
||||
assign {o_tlast,o_tdata} = (fifo_state == FULL) ? data_reg2 : data_reg1;
|
||||
|
||||
|
||||
endmodule // axi_fast_fifo
|
||||
Reference in New Issue
Block a user