Pushing the bulk of UHD-3.7.0 code.
Original-commit: ff1546f8137f7f92bb250f685561b0c34cc0e053
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// AXI stream neds N+1 bits to transmit packets of N bits so that the LAST bit can be represented.
|
||||
// LAST occurs relatively infrequently and can be synthesized by using an in-band ESC code to generate
|
||||
// a multi-word sequence to encode it (and the escape character when it appears as data input).
|
||||
//
|
||||
// 0x1234567887654321 with last becomes
|
||||
// 0xDEADBEEFFEEDCAFE 0x0000000000000001 0x1234567887654321
|
||||
//
|
||||
// 0xDEADBEEFFEEDCAFE with last becomes
|
||||
// 0xDEADBEEFFEEDCAFE 0x0000000000000001 0xDEADBEEFFEEDCAFE
|
||||
//
|
||||
// 0xDEADBEEFFEEDCAFE without last becomes
|
||||
// 0xDEADBEEFFEEDCAFE 0x0000000000000000 0xDEADBEEFFEEDCAFE
|
||||
//
|
||||
|
||||
module axi_embed_tlast
|
||||
#(parameter WIDTH=64)
|
||||
(
|
||||
input clk,
|
||||
input reset,
|
||||
input clear,
|
||||
//
|
||||
input [WIDTH-1:0] i_tdata,
|
||||
input i_tlast,
|
||||
input i_tvalid,
|
||||
output i_tready,
|
||||
//
|
||||
output reg [WIDTH-1:0] o_tdata,
|
||||
output o_tvalid,
|
||||
input o_tready
|
||||
|
||||
);
|
||||
|
||||
localparam PASS = 0;
|
||||
localparam ZERO = 1;
|
||||
localparam ONE = 2;
|
||||
localparam ESCAPE = 3;
|
||||
|
||||
localparam IDLE = 0;
|
||||
localparam LAST = 1;
|
||||
localparam ESC = 2;
|
||||
localparam FINISH = 3;
|
||||
|
||||
reg [1:0] state, next_state;
|
||||
|
||||
reg [1:0] select;
|
||||
|
||||
reg [31:0] checksum;
|
||||
|
||||
always @(posedge clk)
|
||||
if (reset | clear) begin
|
||||
checksum <= 0;
|
||||
end else if (i_tready && i_tvalid && i_tlast) begin
|
||||
checksum <= 0;
|
||||
end else if (i_tready && i_tvalid) begin
|
||||
checksum <= checksum + i_tdata[31:0] + i_tdata[63:32];
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
if (reset | clear) begin
|
||||
state <= IDLE;
|
||||
end else begin if (o_tready)
|
||||
state <= next_state;
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case(state)
|
||||
IDLE: begin
|
||||
if (i_tlast && i_tvalid)
|
||||
begin
|
||||
next_state = LAST;
|
||||
select = ESCAPE;
|
||||
end
|
||||
else if ((i_tdata == 64'hDEADBEEFFEEDCAFE) && i_tvalid)
|
||||
begin
|
||||
next_state = ESC;
|
||||
select = ESCAPE;
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_state = IDLE;
|
||||
select = PASS;
|
||||
end
|
||||
end // case: IDLE
|
||||
//
|
||||
//
|
||||
LAST: begin
|
||||
select = ONE;
|
||||
next_state = FINISH;
|
||||
end
|
||||
//
|
||||
//
|
||||
ESC: begin
|
||||
select = ZERO;
|
||||
next_state = FINISH;
|
||||
end
|
||||
//
|
||||
//
|
||||
FINISH: begin
|
||||
select = PASS;
|
||||
if (i_tvalid)
|
||||
next_state = IDLE;
|
||||
else
|
||||
next_state = FINISH;
|
||||
end
|
||||
endcase // case(state)
|
||||
end // always @ (*)
|
||||
|
||||
//
|
||||
// Muxes
|
||||
//
|
||||
always @*
|
||||
begin
|
||||
case(select)
|
||||
PASS: o_tdata = i_tdata;
|
||||
ZERO: o_tdata = 0;
|
||||
ONE: o_tdata = {checksum[31:0],32'h1};
|
||||
ESCAPE: o_tdata = 64'hDEADBEEFFEEDCAFE;
|
||||
endcase // case(select)
|
||||
end
|
||||
|
||||
assign o_tvalid = (select == PASS) ? i_tvalid : 1'b1;
|
||||
assign i_tready = (select == PASS) ? o_tready : 1'b0;
|
||||
|
||||
endmodule // axi_embed_tlast
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user