diff options
author | michael-west <michael.west@ettus.com> | 2014-03-25 15:59:03 -0700 |
---|---|---|
committer | michael-west <michael.west@ettus.com> | 2014-03-25 15:59:03 -0700 |
commit | 04292f9b109479b639add31f83fd240a6387f488 (patch) | |
tree | 4b8723a4ae63626029704f901ee0083bb23bc1e9 /fpga/usrp3/lib/axi/axi_embed_tlast.v | |
parent | 09915aa57bc88099cbcbbe925946ae65bc0ad8f0 (diff) | |
parent | ff8a1252f3a51369abe0a165d963b781089ec66c (diff) | |
download | uhd-04292f9b109479b639add31f83fd240a6387f488.tar.gz uhd-04292f9b109479b639add31f83fd240a6387f488.tar.bz2 uhd-04292f9b109479b639add31f83fd240a6387f488.zip |
Merge branch 'master' into mwest/b200_docs
Diffstat (limited to 'fpga/usrp3/lib/axi/axi_embed_tlast.v')
-rw-r--r-- | fpga/usrp3/lib/axi/axi_embed_tlast.v | 128 |
1 files changed, 128 insertions, 0 deletions
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 + + + |