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
|