diff options
Diffstat (limited to 'fpga/usrp3/lib/vita_200/chdr_12sc_to_16sc.v')
-rw-r--r-- | fpga/usrp3/lib/vita_200/chdr_12sc_to_16sc.v | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/vita_200/chdr_12sc_to_16sc.v b/fpga/usrp3/lib/vita_200/chdr_12sc_to_16sc.v new file mode 100644 index 000000000..fd7851bf8 --- /dev/null +++ b/fpga/usrp3/lib/vita_200/chdr_12sc_to_16sc.v @@ -0,0 +1,179 @@ +// +// Copyright 2013 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + + + + + + +module chdr_12sc_to_16sc + #(parameter BASE = 0) + ( input set_stb, input [7:0] set_addr, input [31:0] set_data, + //input side of device + input clk, input reset, + input [63:0] i_tdata, + input i_tlast, + input i_tvalid, + output i_tready, + //output side of device + output reg [63:0] o_tdata, + output o_tlast, + output o_tvalid, + input o_tready, + + output [31:0] debug + ); + + + + + + wire chdr_has_hdr = 1'b1; + wire chdr_has_time = i_tdata[61]; + wire chdr_has_tlr = 1'b0; + + wire [15:0] chdr_header_lines = chdr_has_time? 16 : 8; + wire [15:0] just_samples_in = i_tdata[47:32] - chdr_header_lines; + + //calculating output length based on input ( 4/3*input = output) + + wire [30:0] calc_output_len = ({just_samples_in,14'h0} + {just_samples_in,12'h0} + {just_samples_in,10'h0} + {just_samples_in,8'h0} + {just_samples_in,6'h0} + {just_samples_in,4'h0} + {just_samples_in,2'h0}+{just_samples_in} +'b0001000000000000)<<2; + + wire [15:0] samples = calc_output_len[30:16]; + wire [15:0] chdr_payload_lines = samples + chdr_header_lines; + + + reg has_exline; + reg in_exline; + + + + wire set_sid; + wire [15:0] my_newhome; + + + setting_reg #(.my_addr(BASE), .width(17)) new_destination + (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data), + .out({set_sid, my_newhome[15:0]})); + + localparam HEADER = 3'd0; // IDLE + localparam TIME = 3'd1; + localparam ODD_LINE_ZERO = 3'd2; + localparam EVEN_LINE_ONE = 3'd3; + localparam ODD_LINE_TWO = 3'd4; + localparam EVEN_LINE_THREE = 3'd5; + + reg [2:0] state; + + + + always @(posedge clk) begin + + if (reset) begin + state <= HEADER; + end + + else if (o_tvalid && o_tready) case(state) + + + HEADER: begin + has_exline <= ( (samples[4:2] == 5) || (samples[4:2] == 7) || (samples[4:2] == 0)); + state <= (chdr_has_time)? TIME : ODD_LINE_ZERO; + end + + TIME: begin + state <= (i_tlast)? HEADER: ODD_LINE_ZERO; + end + + ODD_LINE_ZERO: begin + if ((i_tlast & !has_exline) || in_exline) begin + state <= HEADER; + in_exline <= 0; + end + else if (i_tlast & has_exline) begin + in_exline <= 1; + state <= EVEN_LINE_ONE; + end + else + state <= EVEN_LINE_ONE; + end + + EVEN_LINE_ONE: begin + if ((i_tlast & !has_exline) || in_exline) begin + state <= HEADER; + in_exline <= 0; + end + else if (i_tlast & has_exline) begin + in_exline <= 1; + state <= ODD_LINE_TWO; + end + else + state <= ODD_LINE_TWO; + end + + ODD_LINE_TWO: begin + if ((i_tlast & !has_exline) || in_exline) begin + state <= HEADER; + in_exline <= 0; + end + else if (i_tlast & has_exline) begin + in_exline <= 1; + state <= EVEN_LINE_THREE; + end + else + state <= EVEN_LINE_THREE; + end + + EVEN_LINE_THREE: begin + if (in_exline) begin + state <= HEADER; + in_exline <= 0; + end + else + state <= ODD_LINE_ZERO; + end + + default: state <= HEADER; + + endcase + end + + + //hold data after each input xfer + reg [63:0] hold_tdata; + always @(posedge clk) begin + if (i_tvalid && i_tready) hold_tdata <= i_tdata; + end + + //main mux + + always @(*) + case(state) + + HEADER: o_tdata <= {i_tdata[63:48],chdr_payload_lines, + set_sid ? {i_tdata[15:0], my_newhome[15:0]}:i_tdata[31:0]}; + + TIME: o_tdata <= i_tdata; + + ODD_LINE_ZERO: o_tdata <= {i_tdata[63:52], 4'h0, i_tdata[51:40], 4'h0, i_tdata[39:28],4'h0, i_tdata[27:16], 4'h0}; + + EVEN_LINE_ONE: o_tdata <= {hold_tdata[15:4],4'h0,hold_tdata[3:0],i_tdata[63:56],4'h0,i_tdata[55:44], 4'h0,i_tdata[43:32],4'h0}; + + ODD_LINE_TWO: o_tdata <= {hold_tdata[31:20], 4'h0, hold_tdata[19:8],4'h0, hold_tdata[7:0],i_tdata[63:60],4'h0,i_tdata[59:48],4'h0}; + + EVEN_LINE_THREE: o_tdata <= {hold_tdata[47:36],4'h0,hold_tdata[35:24],4'h0,hold_tdata[23:12],4'h0,hold_tdata[11:0],4'h0}; + + + default: o_tdata <= i_tdata; + + endcase + + assign o_tvalid = (in_exline)? 1'b1: i_tvalid; + assign i_tready = (state != EVEN_LINE_THREE) & o_tready & !in_exline; + assign o_tlast = (has_exline)? in_exline: ((state != EVEN_LINE_THREE) && i_tlast); + +endmodule |