From ff1546f8137f7f92bb250f685561b0c34cc0e053 Mon Sep 17 00:00:00 2001 From: Ben Hilburn Date: Fri, 14 Feb 2014 12:05:07 -0800 Subject: Pushing the bulk of UHD-3.7.0 code. --- fpga/usrp3/lib/axi/axi_embed_tlast.v | 128 +++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 fpga/usrp3/lib/axi/axi_embed_tlast.v (limited to 'fpga/usrp3/lib/axi/axi_embed_tlast.v') diff --git a/fpga/usrp3/lib/axi/axi_embed_tlast.v b/fpga/usrp3/lib/axi/axi_embed_tlast.v new file mode 100644 index 000000000..065f59fd4 --- /dev/null +++ b/fpga/usrp3/lib/axi/axi_embed_tlast.v @@ -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 + + + -- cgit v1.2.3