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
140
141
142
143
144
145
146
147
148
149
|
//
// Copyright 2021 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: rf_down_4to2
//
// Description:
//
// Implements a down-sampling filter that accepts 4 samples per cycle on the
// input and outputs 2 samples per cycle. A 2x speed clock is used to perform
// the DSP computation, so that less logic can be used to implement the
// half-band filter.
//
// Data Path : In --> Gearbox --> Filter --> Gearbox --> Out
// SPC : 4 2 1 2
// Clock Rate : 1x 2x 2x 1x
//
`default_nettype none
module rf_down_4to2 #(
parameter NUM_CHANNELS = 1
) (
input wire clk,
input wire clk_2x,
// Synchronous resets
input wire rst,
input wire rst_2x,
// Input - 4 SPC, synchronous to "clk"
input wire [NUM_CHANNELS*128-1:0] i_tdata,
input wire [NUM_CHANNELS* 1-1:0] i_tvalid,
// Output - 2 SPC, synchronous to "clk"
output wire [NUM_CHANNELS*64-1:0] o_tdata,
output wire [NUM_CHANNELS* 1-1:0] o_tvalid
);
generate
genvar ch;
for (ch = 0; ch < NUM_CHANNELS; ch = ch + 1) begin : gen_channel
//-----------------------------------------------------------------------
// Input Gearbox
//-----------------------------------------------------------------------
//
// Convert from 4 SPC on clk to 2 SPC on clk_2x.
//
//-----------------------------------------------------------------------
wire [63:0] gear_to_filt_tdata;
wire gear_to_filt_tvalid;
gearbox_2x1 #(
.WORD_W (32),
.IN_WORDS (4),
.OUT_WORDS (2),
.BIG_ENDIAN (0)
) gearbox_2x1_in (
.i_clk (clk),
.i_rst (rst),
.i_tdata (i_tdata[ch*128 +: 128]),
.i_tvalid (i_tvalid[ch]),
.o_clk (clk_2x),
.o_rst (rst_2x),
.o_tdata (gear_to_filt_tdata),
.o_tvalid (gear_to_filt_tvalid)
);
//-----------------------------------------------------------------------
// Interpolating Filter
//-----------------------------------------------------------------------
wire [47:0] filt_to_clip_tdata;
wire filt_to_clip_tvalid;
hb47_2to1 hb47_2to1_i (
.aresetn (~rst_2x),
.aclk (clk_2x),
.s_axis_data_tvalid (gear_to_filt_tvalid),
.s_axis_data_tready (),
.s_axis_data_tdata (gear_to_filt_tdata),
.m_axis_data_tvalid (filt_to_clip_tvalid),
.m_axis_data_tuser (),
.m_axis_data_tdata (filt_to_clip_tdata)
);
//-----------------------------------------------------------------------
// Saturation
//-----------------------------------------------------------------------
wire [31:0] clip_to_gear_tdata;
wire clip_to_gear_tvalid;
genvar word;
for (word = 0; word < 2; word = word+1) begin : gen_sat
axi_clip #(
.WIDTH_IN (24),
.WIDTH_OUT (16),
.FIFOSIZE (0)
) axi_clip_i (
.clk (clk_2x),
.reset (rst_2x),
.i_tdata (filt_to_clip_tdata[word*24 +: 24]),
.i_tlast (1'b0),
.i_tvalid (filt_to_clip_tvalid),
.i_tready (),
.o_tdata (clip_to_gear_tdata[word*16 +: 16]),
.o_tlast (),
.o_tvalid (clip_to_gear_tvalid),
.o_tready (1'b1)
);
end
//-----------------------------------------------------------------------
// Output Gearbox
//-----------------------------------------------------------------------
//
// Convert from 1 SPC on clk_2x to 2 SPC on clk.
//
//-----------------------------------------------------------------------
gearbox_2x1 #(
.WORD_W (32),
.IN_WORDS (1),
.OUT_WORDS (2),
.BIG_ENDIAN (0)
) gearbox_2x1_out (
.i_clk (clk_2x),
.i_rst (rst_2x),
.i_tdata (clip_to_gear_tdata),
.i_tvalid (clip_to_gear_tvalid),
.o_clk (clk),
.o_rst (rst),
.o_tdata (o_tdata[ch*64 +: 64]),
.o_tvalid (o_tvalid[ch])
);
end // for
endgenerate
endmodule
`default_nettype wire
|