-
Notifications
You must be signed in to change notification settings - Fork 0
/
ifft4.v
201 lines (184 loc) · 6.77 KB
/
ifft4.v
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
module ifft4 #(
parameter DATA_WIDTH = 8
)
(
input wire clk,
input wire rst_n,
input wire en,
// 4点的FFT,四个输入实部和虚部
input wire signed [DATA_WIDTH-1:0] in0_real,
input wire signed [DATA_WIDTH-1:0] in0_imag,
input wire signed [DATA_WIDTH-1:0] in1_real,
input wire signed [DATA_WIDTH-1:0] in1_imag,
input wire signed [DATA_WIDTH-1:0] in2_real,
input wire signed [DATA_WIDTH-1:0] in2_imag,
input wire signed [DATA_WIDTH-1:0] in3_real,
input wire signed [DATA_WIDTH-1:0] in3_imag,
// 4点的FFT需要进行两层Butterfly, 因此为其多富余两个位宽
output wire signed [DATA_WIDTH+1:0] out0_real,
output wire signed [DATA_WIDTH+1:0] out0_imag,
output wire signed [DATA_WIDTH+1:0] out1_real,
output wire signed [DATA_WIDTH+1:0] out1_imag,
output wire signed [DATA_WIDTH+1:0] out2_real,
output wire signed [DATA_WIDTH+1:0] out2_imag,
output wire signed [DATA_WIDTH+1:0] out3_real,
output wire signed [DATA_WIDTH+1:0] out3_imag,
output wire valid
);
// 1 << 9 = 512 故下面的旋转因子参数也被扩大了512倍
localparam EXPAND = 9;
// 四点fft
localparam POINTS = 4;
// 旋转因子
reg signed [EXPAND+1:0] RO_ARRAY[POINTS-1:0][1:0];
// 初始化旋转因子
initial begin
RO_ARRAY[0][0] <= 512;
RO_ARRAY[0][1] <= 0;
RO_ARRAY[1][0] <= 0;
RO_ARRAY[1][1] <= 512;
RO_ARRAY[2][0] <= -512;
RO_ARRAY[2][1] <= 0;
RO_ARRAY[3][0] <= 0;
RO_ARRAY[3][1] <= -512;
end
// 四点的fft共需要三层连线:码位倒置一层,第一次蝶形运算一层,第二次蝶形运算一层
// [DATA_WIDTH+EXPAND-1:0]表示每个数据的位宽
// [2:0]表示 共需要三层
// [3:0]表示每个层有四个数据,即四点的数据
// wire signed [DATA_WIDTH+EXPAND-1:0] in_real[2:0][3:0];
// wire signed [DATA_WIDTH+EXPAND-1:0] in_imag[2:0][3:0];
// 用于原始数据层和第一计算层
wire signed [DATA_WIDTH-1:0] in_real[3:0];
wire signed [DATA_WIDTH-1:0] in_imag[3:0];
// 用于第一计算层和第二计算层
wire signed [DATA_WIDTH+0:0] in_real_step1[3:0];
wire signed [DATA_WIDTH+0:0] in_imag_step1[3:0];
// 用于第二计算层和输出层
wire signed [DATA_WIDTH+1:0] in_real_step2[3:0];
wire signed [DATA_WIDTH+1:0] in_imag_step2[3:0];
// 用于连接各个模块的en引脚
wire en_connect [3:0][1:0];
// 连接引脚第一层蝶形运算模块
assign en_connect[0][0] = en;
assign en_connect[1][0] = en;
// 第一步: 码位倒置
assign in_real[0] = in0_real;
assign in_imag[0] = in0_imag;
assign in_real[1] = in2_real;
assign in_imag[1] = in2_imag;
assign in_real[2] = in1_real;
assign in_imag[2] = in1_imag;
assign in_real[3] = in3_real;
assign in_imag[3] = in3_imag;
// 第二步: 连接倒置后的数据和第一层蝶形运算
Butterfly #(
.DATA_WIDTH(DATA_WIDTH), .EXPAND(EXPAND)
) butterfly_unit_0_0 (
// 控制信号
.clk(clk),
.rst_n(rst_n),
.en(en_connect[0][0]),
// 输入
.in1_real(in_real[0]),
.in1_imag(in_imag[0]),
.in2_real(in_real[1]),
.in2_imag(in_imag[1]),
// 旋转因子
.ro_real(RO_ARRAY[0][0]),
.ro_imag(RO_ARRAY[0][1]),
// 输出
.out1_real(in_real_step1[0]),
.out1_imag(in_imag_step1[0]),
.out2_real(in_real_step1[1]),
.out2_imag(in_imag_step1[1]),
// 输出是否有效信号
// 有效代表该数据可用,否则则不可用
.valid(en_connect[0][1])
);
Butterfly #(
.DATA_WIDTH(DATA_WIDTH), .EXPAND(EXPAND)
) butterfly_unit_0_1 (
// 控制信号
.clk(clk),
.rst_n(rst_n),
.en(en_connect[1][0]),
// 输入
.in1_real(in_real[2]),
.in1_imag(in_imag[2]),
.in2_real(in_real[3]),
.in2_imag(in_imag[3]),
// 旋转因子
.ro_real(RO_ARRAY[0][0]),
.ro_imag(RO_ARRAY[0][1]),
// 输出
.out1_real(in_real_step1[2]),
.out1_imag(in_imag_step1[2]),
.out2_real(in_real_step1[3]),
.out2_imag(in_imag_step1[3]),
// 输出是否有效信号
// 有效代表该数据可用,否则则不可用
.valid(en_connect[1][1])
);
// 连接第一层蝶形运算模块valid和第二层蝶形运算模块en
assign en_connect[2][0] = en_connect[0][1];
assign en_connect[3][0] = en_connect[1][1];
// 第二层蝶形运算
Butterfly #(
.DATA_WIDTH(DATA_WIDTH+1), .EXPAND(EXPAND)
) butterfly_unit_1_0 (
// 控制信号
.clk(clk),
.rst_n(rst_n),
.en(en_connect[2][0]),
// 输入
.in1_real(in_real_step1[0]),
.in1_imag(in_imag_step1[0]),
.in2_real(in_real_step1[2]),
.in2_imag(in_imag_step1[2]),
// 旋转因子
.ro_real(RO_ARRAY[0][0]),
.ro_imag(RO_ARRAY[0][1]),
// 输出
.out1_real(in_real_step2[0]),
.out1_imag(in_imag_step2[0]),
.out2_real(in_real_step2[2]),
.out2_imag(in_imag_step2[2]),
// 输出是否有效信号
// 有效代表该数据可用,否则则不可用
.valid(en_connect[2][1])
);
Butterfly #(
.DATA_WIDTH(DATA_WIDTH+1), .EXPAND(EXPAND)
) butterfly_unit_1_1 (
// 控制信号
.clk(clk),
.rst_n(rst_n),
.en(en_connect[3][0]),
// 输入
.in1_real(in_real_step1[1]),
.in1_imag(in_imag_step1[1]),
.in2_real(in_real_step1[3]),
.in2_imag(in_imag_step1[3]),
// 旋转因子
.ro_real(RO_ARRAY[1][0]),
.ro_imag(RO_ARRAY[1][1]),
// 输出
.out1_real(in_real_step2[1]),
.out1_imag(in_imag_step2[1]),
.out2_real(in_real_step2[3]),
.out2_imag(in_imag_step2[3]),
// 输出是否有效信号
// 有效代表该数据可用,否则则不可用
.valid(en_connect[3][1])
);
assign valid = en_connect[3][1];
assign out0_real = in_real_step2[0] >>> 2;
assign out0_imag = in_imag_step2[0] >>> 2;
assign out1_real = in_real_step2[1] >>> 2;
assign out1_imag = in_imag_step2[1] >>> 2;
assign out2_real = in_real_step2[2] >>> 2;
assign out2_imag = in_imag_step2[2] >>> 2;
assign out3_real = in_real_step2[3] >>> 2;
assign out3_imag = in_imag_step2[3] >>> 2;
endmodule