1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/////////////////////////////////////////////////////////////////////
//
// Copyright 2018 Ettus Research, A National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: chdr_deframer_2clk
// Description:
// - Takes a sample stream in and uses the tuser input to frame
// a CHDR packet which is output by the module
// samples at the output
//
/////////////////////////////////////////////////////////////////////
module chdr_deframer_2clk #(
parameter WIDTH = 32 // 32 and 64 bits supported
) (
input samp_clk, input samp_rst, input pkt_clk, input pkt_rst,
input [63:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
output [WIDTH-1:0] o_tdata, output [127:0] o_tuser, output o_tlast, output o_tvalid, input o_tready
);
localparam [1:0] ST_HEAD = 2'd0;
localparam [1:0] ST_TIME = 2'd1;
localparam [1:0] ST_BODY = 2'd2;
reg [1:0] chdr_state;
wire [127:0] hdr_i_tuser, hdr_o_tuser;
wire hdr_i_tvalid, hdr_i_tready;
wire hdr_o_tvalid, hdr_o_tready;
wire [63:0] body_i_tdata, body_o_tdata;
wire body_i_tlast, body_o_tlast;
wire body_i_tvalid, body_o_tvalid;
wire body_i_tready, body_o_tready;
wire has_time = i_tdata[61];
reg [63:0] held_i_tdata;
reg second_half;
assign body_i_tdata = i_tdata;
assign body_i_tlast = i_tlast;
assign body_i_tvalid = (chdr_state == ST_BODY) ? i_tvalid : 1'b0;
assign hdr_i_tuser = (chdr_state == ST_HEAD) ? { i_tdata, i_tdata } : { held_i_tdata, i_tdata }; // 2nd half ignored if no time
assign hdr_i_tvalid = (chdr_state == ST_TIME) ? i_tvalid :
((chdr_state == ST_HEAD) & ~has_time) ? i_tvalid :
1'b0;
assign i_tready = (chdr_state == ST_BODY) ? body_i_tready : hdr_i_tready;
// FIXME handle packets with no body
always @(posedge pkt_clk) begin
if (pkt_rst) begin
chdr_state <= ST_HEAD;
end else begin
case(chdr_state)
ST_HEAD:
if (i_tvalid & hdr_i_tready)
if (has_time) begin
chdr_state <= ST_TIME;
held_i_tdata <= i_tdata;
end else begin
chdr_state <= ST_BODY;
end
ST_TIME:
if (i_tvalid & hdr_i_tready)
chdr_state <= ST_BODY;
ST_BODY:
if (i_tvalid & body_i_tready & i_tlast)
chdr_state <= ST_HEAD;
endcase
end
end
wire pkt_rst_stretch;
pulse_stretch #(.SCALE('d10)) pkt_reset_i (
.clk(pkt_clk),
.rst(1'b0),
.pulse(pkt_rst),
.pulse_stretched(pkt_rst_stretch)
);
axi_fifo_2clk #(.WIDTH(128), .SIZE(5)) hdr_fifo_i (
.i_aclk(pkt_clk), .o_aclk(samp_clk), .reset(pkt_rst_stretch),
.i_tdata(hdr_i_tuser), .i_tvalid(hdr_i_tvalid), .i_tready(hdr_i_tready),
.o_tdata(hdr_o_tuser), .o_tvalid(hdr_o_tvalid), .o_tready(hdr_o_tready)
);
axi_fifo_2clk #(.WIDTH(65), .SIZE(9)) body_fifo (
.i_aclk(pkt_clk), .o_aclk(samp_clk), .reset(pkt_rst_stretch),
.i_tdata({body_i_tlast, body_i_tdata}), .i_tvalid(body_i_tvalid), .i_tready(body_i_tready),
.o_tdata({body_o_tlast, body_o_tdata}), .o_tvalid(body_o_tvalid), .o_tready(body_o_tready)
);
wire odd_len = hdr_o_tuser[98] ^ |hdr_o_tuser[97:96];
generate
if (WIDTH == 32) begin : gen_32bit_output
// 32-bit Output
always @(posedge samp_clk) begin
if(samp_rst) begin
second_half <= 1'b0;
end else begin
if(o_tvalid & o_tready) begin
if(o_tlast)
second_half <= 1'b0;
else
second_half <= ~second_half;
end
end
end
assign o_tdata = second_half ? body_o_tdata[WIDTH-1:0] : body_o_tdata[(2*WIDTH)-1:WIDTH];
assign o_tlast = body_o_tlast & (second_half | odd_len);
assign o_tuser = hdr_o_tuser;
assign o_tvalid = hdr_o_tvalid & body_o_tvalid;
assign hdr_o_tready = o_tvalid & o_tready & o_tlast;
assign body_o_tready = o_tvalid & o_tready & (o_tlast | second_half);
end else begin : gen_64bit_output
// 64-bit Output
assign o_tdata = body_o_tdata;
assign o_tlast = body_o_tlast;
assign o_tuser = hdr_o_tuser;
assign o_tvalid = hdr_o_tvalid & body_o_tvalid;
assign hdr_o_tready = o_tvalid & o_tready & o_tlast;
assign body_o_tready = o_tvalid & o_tready;
end
endgenerate
endmodule
|