├── images ├── FFT.png └── simulation1.png ├── src ├── simulation.pdf ├── shift_2.v ├── shift_1.v ├── shift_4.v ├── shift_8.v ├── shift_16.v ├── ROM_2.v ├── radix2.v ├── ROM_4.v ├── ROM_8.v ├── ROM_16.v ├── FFTtb.v ├── MyTestbed.v └── FFT.v ├── README.md └── LICENSE /images/FFT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AugustinJose1221/FFTx32/HEAD/images/FFT.png -------------------------------------------------------------------------------- /src/simulation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AugustinJose1221/FFTx32/HEAD/src/simulation.pdf -------------------------------------------------------------------------------- /images/simulation1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AugustinJose1221/FFTx32/HEAD/images/simulation1.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fast Fourier Transform using Cooley-Tukey Algorithm in Verilog 2 | A 32 point radix-2 FFT module written in Verilog 3 | 4 | 5 | Clone this repository 6 | ``` 7 | git clone https://github.com/AugustinJose1221/FFTx32.git 8 | ``` 9 | 10 | Change directory 11 | ``` 12 | cd FFTx32/src 13 | ``` 14 | 15 | iverilog Installation 16 | ``` 17 | sudo apt-get install iverilog 18 | ``` 19 | 20 | Run program 21 | ``` 22 | iverilog -o main FFT.v MyTestbed.v FFTtb.v 23 | vvp main 24 | ``` 25 | This creates a main.vcd file in the same directory. 26 | To do simulation of the program, you have to install gtkwave. 27 | 28 | gtkwave Installation 29 | ``` 30 | sudo apt-get install gtkwave 31 | ``` 32 | 33 | Run simulation 34 | ``` 35 | gtkwave main.vcd 36 | ``` 37 | 38 |
40 |
44 | Output of our Verilog FFT module in comparison with FFT function in Python. The output is plotted using matplotlib
45 |
46 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Augustin Jose
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/shift_2.v:
--------------------------------------------------------------------------------
1 | module shift_2(
2 | input clk,
3 | input rst_n,
4 | input in_valid,
5 | input signed [23:0] din_r,
6 | input signed [23:0] din_i,
7 | output signed [23:0] dout_r,
8 | output signed [23:0] dout_i
9 | );
10 | integer i ;
11 | reg [47:0] shift_reg_r ;
12 | reg [47:0] shift_reg_i ;
13 | reg [47:0] tmp_reg_r ;
14 | reg [47:0] tmp_reg_i ;
15 | reg [2:0] counter_2,next_counter_2;
16 | reg valid,next_valid;
17 |
18 | assign dout_r = shift_reg_r[47:24];
19 | assign dout_i = shift_reg_i[47:24];
20 |
21 | always@(*)begin
22 | next_counter_2 = counter_2 + 2'd1;
23 | tmp_reg_r = shift_reg_r;
24 | tmp_reg_i = shift_reg_i;
25 | next_valid = valid;
26 | end
27 |
28 | always@(posedge clk or negedge rst_n)begin
29 | if(~rst_n)begin
30 | shift_reg_r <= 0;
31 | shift_reg_i <= 0;
32 | counter_2 <= 0;
33 | valid <= 0;
34 | end
35 | else
36 | if (in_valid)begin
37 | counter_2 <= next_counter_2;
38 | shift_reg_r <= (tmp_reg_r<<24) + din_r;
39 | shift_reg_i <= (tmp_reg_i<<24) + din_i;
40 | valid <= in_valid;
41 | end else if(valid)begin
42 | counter_2 <= next_counter_2;
43 | shift_reg_r <= (tmp_reg_r<<24) + din_r;
44 | shift_reg_i <= (tmp_reg_i<<24) + din_i;
45 | valid <= next_valid;
46 | end
47 | end
48 |
49 | endmodule
--------------------------------------------------------------------------------
/src/shift_1.v:
--------------------------------------------------------------------------------
1 | module shift_1(
2 | input clk,
3 | input rst_n,
4 | input in_valid,
5 | input signed [23:0] din_r,
6 | input signed [23:0] din_i,
7 | output signed [23:0] dout_r,
8 | output signed [23:0] dout_i
9 | );
10 | integer i ;
11 | reg [23:0] shift_reg_r ;
12 | reg [23:0] shift_reg_i ;
13 | reg [23:0] tmp_reg_r ;
14 | reg [23:0] tmp_reg_i ;
15 | reg [1:0] counter_1,next_counter_1;
16 | reg valid,next_valid;
17 |
18 | assign dout_r = shift_reg_r[23:0];
19 | assign dout_i = shift_reg_i[23:0];
20 |
21 | always@(*)begin
22 | next_counter_1 = counter_1 + 2'd1;
23 | tmp_reg_r = shift_reg_r;
24 | tmp_reg_i = shift_reg_i;
25 | next_valid = valid;
26 | end
27 |
28 | always@(posedge clk or negedge rst_n)begin
29 | if(~rst_n)begin
30 | shift_reg_r <= 0;
31 | shift_reg_i <= 0;
32 | counter_1 <= 0;
33 | valid <= 0;
34 | end
35 | else
36 | if (in_valid)begin
37 | counter_1 <= next_counter_1;
38 | shift_reg_r <= (tmp_reg_r<<24) + din_r;
39 | shift_reg_i <= (tmp_reg_i<<24) + din_i;
40 | valid <= in_valid;
41 | end else if(valid)begin
42 | counter_1 <= next_counter_1;
43 | shift_reg_r <= (tmp_reg_r<<24) + din_r;
44 | shift_reg_i <= (tmp_reg_i<<24) + din_i;
45 | valid <= next_valid;
46 | end
47 | end
48 |
49 | endmodule
--------------------------------------------------------------------------------
/src/shift_4.v:
--------------------------------------------------------------------------------
1 | module shift_4(
2 | input clk,
3 | input rst_n,
4 | input in_valid,
5 | input signed [23:0] din_r,
6 | input signed [23:0] din_i,
7 | output signed [23:0] dout_r,
8 | output signed [23:0] dout_i
9 | );
10 | integer i ;
11 | reg [95:0] shift_reg_r ;
12 | reg [95:0] shift_reg_i ;
13 | reg [95:0] tmp_reg_r ;
14 | reg [95:0] tmp_reg_i ;
15 | reg [3:0] counter_4,next_counter_4;
16 | reg valid,next_valid;
17 |
18 | assign dout_r = shift_reg_r[95:72];
19 | assign dout_i = shift_reg_i[95:72];
20 |
21 | always@(*)begin
22 | next_counter_4 = counter_4 + 3'd1;
23 | tmp_reg_r = shift_reg_r;
24 | tmp_reg_i = shift_reg_i;
25 | next_valid = valid;
26 | end
27 |
28 | always@(posedge clk or negedge rst_n)begin
29 | if(~rst_n)begin
30 | shift_reg_r <= 0;
31 | shift_reg_i <= 0;
32 | counter_4 <= 0;
33 | valid <= 0;
34 | end
35 | else
36 | if (in_valid)begin
37 | counter_4 <= next_counter_4;
38 | shift_reg_r <= (tmp_reg_r<<24) + din_r;
39 | shift_reg_i <= (tmp_reg_i<<24) + din_i;
40 | valid <= in_valid;
41 | end else if(valid)begin
42 | counter_4 <= next_counter_4;
43 | shift_reg_r <= (tmp_reg_r<<24) + din_r;
44 | shift_reg_i <= (tmp_reg_i<<24) + din_i;
45 | valid <= next_valid;
46 | end
47 | end
48 |
49 | endmodule
--------------------------------------------------------------------------------
/src/shift_8.v:
--------------------------------------------------------------------------------
1 | module shift_8(
2 | input clk,
3 | input rst_n,
4 | input in_valid,
5 | input signed [23:0] din_r,
6 | input signed [23:0] din_i,
7 | output signed [23:0] dout_r,
8 | output signed [23:0] dout_i
9 | );
10 | integer i ;
11 | reg [191:0] shift_reg_r ;
12 | reg [191:0] shift_reg_i ;
13 | reg [191:0] tmp_reg_r ;
14 | reg [191:0] tmp_reg_i ;
15 | reg [4:0] counter_8,next_counter_8;
16 | reg valid,next_valid;
17 |
18 | assign dout_r = shift_reg_r[191:168];
19 | assign dout_i = shift_reg_i[191:168];
20 |
21 | always@(*)begin
22 | next_counter_8 = counter_8 + 4'd1;
23 | tmp_reg_r = shift_reg_r;
24 | tmp_reg_i = shift_reg_i;
25 | next_valid = valid;
26 | end
27 |
28 | always@(posedge clk or negedge rst_n)begin
29 | if(~rst_n)begin
30 | shift_reg_r <= 0;
31 | shift_reg_i <= 0;
32 | counter_8 <= 0;
33 | valid <= 0;
34 | end
35 | else
36 | if (in_valid)begin
37 | counter_8 <= next_counter_8;
38 | shift_reg_r <= (tmp_reg_r<<24) + din_r;
39 | shift_reg_i <= (tmp_reg_i<<24) + din_i;
40 | valid <= in_valid;
41 | end else if(valid)begin
42 | counter_8 <= next_counter_8;
43 | shift_reg_r <= (tmp_reg_r<<24) + din_r;
44 | shift_reg_i <= (tmp_reg_i<<24) + din_i;
45 | valid <= next_valid;
46 | end
47 | end
48 |
49 | endmodule
--------------------------------------------------------------------------------
/src/shift_16.v:
--------------------------------------------------------------------------------
1 | module shift_16(
2 | input clk,
3 | input rst_n,
4 | input in_valid,
5 | input signed [23:0] din_r,
6 | input signed [23:0] din_i,
7 | output signed [23:0] dout_r,
8 | output signed [23:0] dout_i
9 | );
10 | integer i ;
11 | reg [383:0] shift_reg_r ;
12 | reg [383:0] shift_reg_i ;
13 | reg [383:0] tmp_reg_r ;
14 | reg [383:0] tmp_reg_i ;
15 | reg [5:0] counter_16,next_counter_16;
16 | reg valid,next_valid;
17 |
18 | assign dout_r = shift_reg_r[383:360];
19 | assign dout_i = shift_reg_i[383:360];
20 |
21 | always@(*)begin
22 | next_counter_16 = counter_16 + 5'd1;
23 | tmp_reg_r = shift_reg_r;
24 | tmp_reg_i = shift_reg_i;
25 | next_valid = valid;
26 | end
27 |
28 | always@(posedge clk or negedge rst_n)begin
29 | if(~rst_n)begin
30 | shift_reg_r <= 0;
31 | shift_reg_i <= 0;
32 | counter_16 <= 0;
33 | valid <= 0;
34 | end
35 | else
36 | if (in_valid)begin
37 | counter_16 <= next_counter_16;
38 | shift_reg_r <= (tmp_reg_r<<24) + din_r;
39 | shift_reg_i <= (tmp_reg_i<<24) + din_i;
40 | valid <= in_valid;
41 | end
42 | else if (valid)begin
43 | counter_16 <= next_counter_16;
44 | shift_reg_r <= (tmp_reg_r<<24) + din_r;
45 | shift_reg_i <= (tmp_reg_i<<24) + din_i;
46 | valid <= next_valid;
47 | end
48 | end
49 |
50 | endmodule
--------------------------------------------------------------------------------
/src/ROM_2.v:
--------------------------------------------------------------------------------
1 | module ROM_2(
2 | input clk,
3 | input in_valid,
4 | input rst_n,
5 | output reg [23:0] w_r,
6 | output reg [23:0] w_i,
7 | output reg[1:0] state
8 | );
9 |
10 | reg valid,next_valid;
11 | reg [5:0] count,next_count;
12 | reg [1:0] s_count,next_s_count;
13 |
14 | always @(*) begin
15 | state = 2'd0;
16 | if(in_valid || valid)
17 | begin
18 | next_count = count + 1;
19 | next_s_count = s_count;
20 | end
21 | else begin
22 | next_count = count;
23 | next_s_count = s_count;
24 | end
25 |
26 | if (count<6'd2)
27 | state = 2'd0;
28 | else if (count >= 6'd2 && s_count < 2'd2)begin
29 | state = 2'd1;
30 | next_s_count = s_count + 1;
31 | end else if (count >= 6'd2 && s_count >= 2'd2)begin
32 | state = 2'd2;
33 | next_s_count = s_count + 1;
34 | end
35 | case(s_count)
36 | 2'd2: begin
37 | w_r = 24'b 00000000_00000001_00000000;
38 | w_i = 24'b 00000000_00000000_00000000;
39 | end
40 | 2'd3: begin
41 | w_r = 24'b 00000000_00000000_00000000;
42 | w_i = 24'b 11111111_11111111_00000000;
43 | end
44 | default: begin
45 | w_r = 24'b 00000000_00000001_00000000;
46 | w_i = 24'b 00000000_00000000_00000000;
47 | end
48 | endcase
49 | end
50 |
51 | always@(posedge clk or negedge rst_n)begin
52 | if(~rst_n)begin
53 | count <= 0;
54 | s_count <= 0;
55 | end
56 | else begin
57 | count <= next_count;
58 | s_count <= next_s_count;
59 | end
60 | end
61 | endmodule
--------------------------------------------------------------------------------
/src/radix2.v:
--------------------------------------------------------------------------------
1 | module radix2(
2 | input [1:0] state,
3 | input signed [23:0] din_a_r,
4 | input signed [23:0] din_a_i,
5 | input signed [23:0] din_b_r,//a
6 | input signed [23:0] din_b_i,//b
7 | input signed [23:0] w_r,//c
8 | input signed [23:0] w_i,//d
9 | output reg signed[23:0] op_r,
10 | output reg signed[23:0] op_i,
11 | output reg signed[23:0] delay_r,
12 | output reg signed[23:0] delay_i,
13 | output reg outvalid
14 | );
15 |
16 | reg signed [41:0] inter,mul_r,mul_i;//was 27
17 | reg signed [23:0] a,b,c,d;
18 |
19 | always@(*)begin
20 | op_r = 0;
21 | op_i = 0;
22 | delay_r = din_b_r;
23 | delay_i = din_b_i;
24 | case(state)
25 | 2'b00:begin
26 | //waiting
27 | delay_r = din_b_r;
28 | delay_i = din_b_i;
29 | outvalid = 1'b0;
30 | end
31 | 2'b01:begin
32 | //first half
33 | a = din_a_r + din_b_r;
34 | b = din_a_i + din_b_i;
35 |
36 | c = (din_a_r - din_b_r);//a-b
37 | d = (din_a_i - din_b_i);//a-b
38 |
39 | op_r = a;
40 | op_i = b;
41 | delay_r = c;
42 | delay_i = d;
43 | outvalid = 1'b1;
44 | end
45 | 2'b10:begin
46 | //second half
47 | a = din_a_r;
48 | b = din_a_i;
49 | delay_r = din_b_r;
50 | delay_i = din_b_i;
51 |
52 | inter = b * (w_r - w_i); //b(c-d)
53 | mul_r = w_r * (a - b) + inter;
54 | mul_i = w_i * (a + b) + inter;
55 |
56 | op_r = (mul_r[31:8]);
57 | op_i = (mul_i[31:8]);
58 | outvalid = 1'b1;
59 | end
60 | 2'b11:begin
61 | //disable
62 | outvalid = 1'b0;
63 | end
64 | default:begin
65 | delay_r = din_b_r;
66 | delay_i = din_b_i;
67 | end
68 | endcase
69 |
70 | end
71 |
72 |
73 | endmodule
--------------------------------------------------------------------------------
/src/ROM_4.v:
--------------------------------------------------------------------------------
1 | module ROM_4(
2 | input clk,
3 | input in_valid,
4 | input rst_n,
5 | output reg [23:0] w_r,
6 | output reg [23:0] w_i,
7 | output reg[1:0] state
8 | );
9 |
10 | reg valid,next_valid;
11 | reg [5:0] count,next_count;
12 | reg [2:0] s_count,next_s_count;
13 |
14 | always @(*) begin
15 | if(in_valid || valid)
16 | begin
17 | next_count = count + 1;
18 | next_s_count = s_count;
19 | end
20 | else begin
21 | next_count = count;
22 | next_s_count = s_count;
23 | end
24 |
25 | if (count<6'd4)
26 | state = 2'd0;
27 | else if (count >= 6'd4 && s_count < 3'd4)begin
28 | state = 2'd1;
29 | next_s_count = s_count + 1;
30 | end
31 | else if (count >= 6'd4 && s_count >= 3'd4)begin
32 | state = 2'd2;
33 | next_s_count = s_count + 1;
34 | end
35 | case(s_count)
36 | 3'd4: begin
37 | w_r = 24'b 00000000_00000001_00000000;
38 | w_i = 24'b 00000000_00000000_00000000;
39 | end
40 | 3'd5: begin
41 | w_r = 24'b 00000000_00000000_10110101;
42 | w_i = 24'b 11111111_11111111_01001011;
43 | end
44 | 3'd6: begin
45 | w_r = 24'b 00000000_00000000_00000000;
46 | w_i = 24'b 11111111_11111111_00000000;
47 | end
48 | 3'd7: begin
49 | w_r = 24'b 11111111_11111111_01001011;
50 | w_i = 24'b 11111111_11111111_01001011;
51 | end
52 | default: begin
53 | w_r = 24'b 00000000_00000001_00000000;
54 | w_i = 24'b 00000000_00000000_00000000;
55 | end
56 | endcase
57 | end
58 |
59 | always@(posedge clk or negedge rst_n)begin
60 | if(~rst_n)begin
61 | count <= 0;
62 | s_count <= 0;
63 | end
64 | else begin
65 | count <= next_count;
66 | s_count <= next_s_count;
67 | end
68 | end
69 | endmodule
--------------------------------------------------------------------------------
/src/ROM_8.v:
--------------------------------------------------------------------------------
1 | module ROM_8(
2 | input clk,
3 | input in_valid,
4 | input rst_n,
5 | output reg [23:0] w_r,
6 | output reg [23:0] w_i,
7 | output reg[1:0] state
8 | );
9 |
10 | reg valid,next_valid;
11 | reg [5:0] count,next_count;
12 | reg [3:0] s_count,next_s_count;
13 |
14 | always @(*) begin
15 | if(in_valid || valid)
16 | begin
17 | next_count = count + 1;
18 | next_s_count = s_count;
19 | end
20 | else begin
21 | next_count = count;
22 | next_s_count = s_count;
23 | end
24 |
25 | if (count<6'd8)
26 | state = 2'd0;
27 | else if (count >= 6'd8 && s_count < 4'd8)begin
28 | state = 2'd1;
29 | next_s_count = s_count + 1;
30 | end
31 | else if (count >= 6'd8 && s_count >= 4'd8)begin
32 | state = 2'd2;
33 | next_s_count = s_count + 1;
34 | end
35 | case(s_count)
36 | 4'd8: begin
37 | w_r = 24'b 00000000_00000001_00000000;
38 | w_i = 24'b 00000000_00000000_00000000;
39 | end
40 | 4'd9: begin
41 | w_r = 24'b 00000000_00000000_11101101;
42 | w_i = 24'b 11111111_11111111_10011110;
43 | end
44 | 4'd10: begin
45 | w_r = 24'b 00000000_00000000_10110101;
46 | w_i = 24'b 11111111_11111111_01001011;
47 | end
48 | 4'd11: begin
49 | w_r = 24'b 00000000_00000000_01100010;
50 | w_i = 24'b 11111111_11111111_00010011;
51 | end
52 | 4'd12: begin
53 | w_r = 24'b 00000000_00000000_00000000;
54 | w_i = 24'b 11111111_11111111_00000000;
55 | end
56 | 4'd13: begin
57 | w_r = 24'b 11111111_11111111_10011110;
58 | w_i = 24'b 11111111_11111111_00010011;
59 | end
60 | 4'd14: begin
61 | w_r = 24'b 11111111_11111111_01001011;
62 | w_i = 24'b 11111111_11111111_01001011;
63 | end
64 | 4'd15: begin
65 | w_r = 24'b 11111111_11111111_00010011;
66 | w_i = 24'b 11111111_11111111_10011110;
67 | end
68 | default: begin
69 | w_r = 24'b 00000000_00000001_00000000;
70 | w_i = 24'b 00000000_00000000_00000000;
71 | end
72 | endcase
73 | end
74 |
75 | always@(posedge clk or negedge rst_n)begin
76 | if(~rst_n)begin
77 | count <= 0;
78 | s_count <= 0;
79 | end
80 | else begin
81 | count <= next_count;
82 | s_count <= next_s_count;
83 | end
84 | end
85 | endmodule
--------------------------------------------------------------------------------
/src/ROM_16.v:
--------------------------------------------------------------------------------
1 | module ROM_16(
2 | input clk,
3 | input in_valid,
4 | input rst_n,
5 | output reg [23:0] w_r,
6 | output reg [23:0] w_i,
7 | output reg[1:0] state
8 | );
9 |
10 | reg valid,next_valid;
11 | reg [5:0] count,next_count;
12 | always @(*) begin
13 | if(in_valid || valid)next_count = count + 1;
14 | else next_count = count;
15 |
16 | if (count<6'd16)
17 | state = 2'd0;
18 | else if (count >= 6'd16 && count < 6'd32)
19 | state = 2'd1;
20 | else if (count >= 6'd32 && count < 6'd48)
21 | state = 2'd2;
22 | else state = 2'd3;
23 | case(count)
24 | 6'd32: begin
25 | w_r = 24'b 00000000_00000001_00000000;
26 | w_i = 24'b 00000000_00000000_00000000;
27 | next_valid = 1'b1;
28 | end
29 | 6'd33: begin
30 | w_r = 24'b 00000000_00000000_11111011;
31 | w_i = 24'b 11111111_11111111_11001110;
32 | next_valid = 1'b1;
33 | end
34 | 6'd34: begin
35 | w_r = 24'b 00000000_00000000_11101101;
36 | w_i = 24'b 11111111_11111111_10011110;
37 | next_valid = 1'b1;
38 | end
39 | 6'd35: begin
40 | w_r = 24'b 00000000_00000000_11010101;
41 | w_i = 24'b 11111111_11111111_01110010;
42 | next_valid = 1'b1;
43 | end
44 | 6'd36: begin
45 | w_r = 24'b 00000000_00000000_10110101;
46 | w_i = 24'b 11111111_11111111_01001011;
47 | next_valid = 1'b1;
48 | end
49 | 6'd37: begin
50 | w_r = 24'b 00000000_00000000_10001110;
51 | w_i = 24'b 11111111_11111111_00101011;
52 | next_valid = 1'b1;
53 | end
54 | 6'd38: begin
55 | w_r = 24'b 00000000_00000000_01100010;
56 | w_i = 24'b 11111111_11111111_00010011;
57 | next_valid = 1'b1;
58 | end
59 | 6'd39: begin
60 | w_r = 24'b 00000000_00000000_00110010;
61 | w_i = 24'b 11111111_11111111_00000101;
62 | next_valid = 1'b1;
63 | end
64 | 6'd40: begin
65 | w_r = 24'b 00000000_00000000_00000000;
66 | w_i = 24'b 11111111_11111111_00000000;
67 | next_valid = 1'b1;
68 | end
69 | 6'd41: begin
70 | w_r = 24'b 11111111_11111111_11001110;
71 | w_i = 24'b 11111111_11111111_00000101;
72 | next_valid = 1'b1;
73 | end
74 | 6'd42: begin
75 | w_r = 24'b 11111111_11111111_10011110;
76 | w_i = 24'b 11111111_11111111_00010011;
77 | next_valid = 1'b1;
78 | end
79 | 6'd43: begin
80 | w_r = 24'b 11111111_11111111_01110010;
81 | w_i = 24'b 11111111_11111111_00101011;
82 | next_valid = 1'b1;
83 | end
84 | 6'd44: begin
85 | w_r = 24'b 11111111_11111111_01001011;
86 | w_i = 24'b 11111111_11111111_01001011;
87 | next_valid = 1'b1;
88 | end
89 | 6'd45: begin
90 | w_r = 24'b 11111111_11111111_00101011;
91 | w_i = 24'b 11111111_11111111_01110010;
92 | next_valid = 1'b1;
93 | end
94 | 6'd46: begin
95 | w_r = 24'b 11111111_11111111_00010011;
96 | w_i = 24'b 11111111_11111111_10011110;
97 | next_valid = 1'b1;
98 | end
99 | 6'd47: begin
100 | w_r = 24'b 11111111_11111111_00000101;
101 | w_i = 24'b 11111111_11111111_11001110;
102 | next_valid = 1'b0;
103 | end
104 | default: begin
105 | w_r = 24'b 00000000_00000001_00000000;
106 | w_i = 24'b 00000000_00000000_00000000;
107 | next_valid = 1'b1;
108 | end
109 | endcase
110 | end
111 |
112 | always@(posedge clk or negedge rst_n)begin
113 | if(~rst_n)begin
114 | count <= 0;
115 | valid <= 0;
116 | end
117 | else if(in_valid)
118 | begin
119 | count <= next_count;
120 | valid <= in_valid;
121 | end
122 | else if (valid)
123 | begin
124 | count <= next_count;
125 | valid <= next_valid;
126 | end
127 | end
128 | endmodule
--------------------------------------------------------------------------------
/src/FFTtb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/10ps
2 | module FFTtb;
3 |
4 | reg signed [11:0] r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31;
5 | reg enable;
6 | reg clk;
7 | wire ret;
8 | MyTestbed Test(.r0(r0),
9 | .r1(r1),
10 | .r2(r2),
11 | .r3(r3),
12 | .r4(r4),
13 | .r5(r5),
14 | .r6(r6),
15 | .r7(r7),
16 | .r8(r8),
17 | .r9(r9),
18 | .r10(r10),
19 | .r11(r11),
20 | .r12(r12),
21 | .r13(r13),
22 | .r14(r14),
23 | .r15(r15),
24 | .r16(r16),
25 | .r17(r17),
26 | .r18(r18),
27 | .r19(r19),
28 | .r20(r20),
29 | .r21(r21),
30 | .r22(r22),
31 | .r23(r23),
32 | .r24(r24),
33 | .r25(r25),
34 | .r26(r26),
35 | .r27(r27),
36 | .r28(r28),
37 | .r29(r29),
38 | .r30(r30),
39 | .r31(r31),
40 | .i0(i0),
41 | .i1(i1),
42 | .i2(i2),
43 | .i3(i3),
44 | .i4(i4),
45 | .i5(i5),
46 | .i6(i6),
47 | .i7(i7),
48 | .i8(i8),
49 | .i9(i9),
50 | .i10(i10),
51 | .i11(i11),
52 | .i12(i12),
53 | .i13(i13),
54 | .i14(i14),
55 | .i15(i15),
56 | .i16(i16),
57 | .i17(i17),
58 | .i18(i18),
59 | .i19(i19),
60 | .i20(i20),
61 | .i21(i21),
62 | .i22(i22),
63 | .i23(i23),
64 | .i24(i24),
65 | .i25(i25),
66 | .i26(i26),
67 | .i27(i27),
68 | .i28(i28),
69 | .i29(i29),
70 | .i30(i30),
71 | .i31(i31),
72 | .enable(enable),
73 | .clk(clk),
74 | .ret(ret));
75 |
76 | integer i;
77 | parameter cycle = 10.0;
78 | always #(cycle/2.0) clk = ~clk;
79 | initial
80 | begin
81 | clk = 1;
82 | enable = 1;
83 | r0 = 0;
84 | r1 = -1700;
85 | r2 = -1605;
86 | r3 = 412;
87 | r4 = 1363;
88 | r5 = -115;
89 | r6 = -209;
90 | r7 = 277;
91 | r8 = 381;
92 | r9 = 736;
93 | r10 = -1086;
94 | r11 = 42;
95 | r12 = 1346;
96 | r13 = 1889;
97 | r14 = -978;
98 | r15 = 96;
99 | r16 = -227;
100 | r17 = -1409;
101 | r18 = 1979;
102 | r19 = -477;
103 | r20 = 299;
104 | r21 = -751;
105 | r22 = 1563;
106 | r23 = -968;
107 | r24 = -1552;
108 | r25 = -723;
109 | r26 = -484;
110 | r27 = -1781;
111 | r28 = 2043;
112 | r29 = -527;
113 | r30 = -701;
114 | r31 = 1502;
115 |
116 | i0 = -1884;
117 | i1 = 1674;
118 | i2 = 262;
119 | i3 = 1052;
120 | i4 = -6;
121 | i5 = 1818;
122 | i6 = -36;
123 | i7 = -1932;
124 | i8 = -203;
125 | i9 = -1591;
126 | i10 = -1760;
127 | i11 = 47;
128 | i12 = -1397;
129 | i13 = -145;
130 | i14 = -24;
131 | i15 = -743;
132 | i16 = 116;
133 | i17 = 1596;
134 | i18 = -98;
135 | i19 = -1501;
136 | i20 = 681;
137 | i21 = 1002;
138 | i22 = -1492;
139 | i23 = -1465;
140 | i24 = 121;
141 | i25 = 86;
142 | i26 = 393;
143 | i27 = -49;
144 | i28 = -1910;
145 | i29 = 621;
146 | i30 = 672;
147 | i31 = 2032;
148 | end
149 |
150 | always @(ret)
151 | begin
152 | if(ret==1)begin
153 | enable = 0;
154 | #10;
155 | enable = 1;
156 | r0 = 1536;
157 | r1 = 592;
158 | r2 = -1210;
159 | r3 = 1962;
160 | r4 = -205;
161 | r5 = 638;
162 | r6 = -93;
163 | r7 = -475;
164 | r8 = 1753;
165 | r9 = -2022;
166 | r10 = 709;
167 | r11 = -752;
168 | r12 = -949;
169 | r13 = 1926;
170 | r14 = 1124;
171 | r15 = 592;
172 | r16 = 556;
173 | r17 = -1268;
174 | r18 = 1717;
175 | r19 = -12;
176 | r20 = -1852;
177 | r21 = 1560;
178 | r22 = 1590;
179 | r23 = 93;
180 | r24 = -955;
181 | r25 = -1710;
182 | r26 = 1889;
183 | r27 = -1212;
184 | r28 = -286;
185 | r29 = 912;
186 | r30 = 1079;
187 | r31 = -605;
188 |
189 | i0 = -1427;
190 | i1 = -973;
191 | i2 = 1864;
192 | i3 = 1620;
193 | i4 = 488;
194 | i5 = -1410;
195 | i6 = 1042;
196 | i7 = 1644;
197 | i8 = -1037;
198 | i9 = 1093;
199 | i10 = 865;
200 | i11 = 46;
201 | i12 = 1805;
202 | i13 = -1718;
203 | i14 = 1519;
204 | i15 = 1587;
205 | i16 = 1748;
206 | i17 = -1915;
207 | i18 = -1195;
208 | i19 = -1887;
209 | i20 = -1765;
210 | i21 = 553;
211 | i22 = 970;
212 | i23 = 1382;
213 | i24 = -167;
214 | i25 = -1769;
215 | i26 = -950;
216 | i27 = -1066;
217 | i28 = -1922;
218 | i29 = -1630;
219 | i30 = -1256;
220 | i31 = -608;
221 | end
222 | end
223 |
224 | initial
225 | begin
226 | $dumpfile("main.vcd");
227 | $dumpvars(0, FFTtb);
228 | #2050;
229 | $finish;
230 |
231 | end
232 |
233 |
234 |
235 | endmodule
236 |
237 |
238 |
239 |
240 |
--------------------------------------------------------------------------------
/src/MyTestbed.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/10ps
2 |
3 | module MyTestbed(input signed [11:0] r0,
4 | input signed [11:0] r1,
5 | input signed [11:0] r2,
6 | input signed [11:0] r3,
7 | input signed [11:0] r4,
8 | input signed [11:0] r5,
9 | input signed [11:0] r6,
10 | input signed [11:0] r7,
11 | input signed [11:0] r8,
12 | input signed [11:0] r9,
13 | input signed [11:0] r10,
14 | input signed [11:0] r11,
15 | input signed [11:0] r12,
16 | input signed [11:0] r13,
17 | input signed [11:0] r14,
18 | input signed [11:0] r15,
19 | input signed [11:0] r16,
20 | input signed [11:0] r17,
21 | input signed [11:0] r18,
22 | input signed [11:0] r19,
23 | input signed [11:0] r20,
24 | input signed [11:0] r21,
25 | input signed [11:0] r22,
26 | input signed [11:0] r23,
27 | input signed [11:0] r24,
28 | input signed [11:0] r25,
29 | input signed [11:0] r26,
30 | input signed [11:0] r27,
31 | input signed [11:0] r28,
32 | input signed [11:0] r29,
33 | input signed [11:0] r30,
34 | input signed [11:0] r31,
35 | input signed [11:0] i0,
36 | input signed [11:0] i1,
37 | input signed [11:0] i2,
38 | input signed [11:0] i3,
39 | input signed [11:0] i4,
40 | input signed [11:0] i5,
41 | input signed [11:0] i6,
42 | input signed [11:0] i7,
43 | input signed [11:0] i8,
44 | input signed [11:0] i9,
45 | input signed [11:0] i10,
46 | input signed [11:0] i11,
47 | input signed [11:0] i12,
48 | input signed [11:0] i13,
49 | input signed [11:0] i14,
50 | input signed [11:0] i15,
51 | input signed [11:0] i16,
52 | input signed [11:0] i17,
53 | input signed [11:0] i18,
54 | input signed [11:0] i19,
55 | input signed [11:0] i20,
56 | input signed [11:0] i21,
57 | input signed [11:0] i22,
58 | input signed [11:0] i23,
59 | input signed [11:0] i24,
60 | input signed [11:0] i25,
61 | input signed [11:0] i26,
62 | input signed [11:0] i27,
63 | input signed [11:0] i28,
64 | input signed [11:0] i29,
65 | input signed [11:0] i30,
66 | input signed [11:0] i31,
67 | input enable,
68 | input clk,
69 | output ret);
70 |
71 | integer i, j, latency;
72 | integer fp_r, fp_i, int_r, int_i;
73 | integer flag;
74 | parameter FFT_size = 32;
75 | parameter IN_width = 12;
76 | parameter OUT_width = 16;
77 | parameter latency_limit = 68;
78 |
79 | parameter cycle = 10.0;
80 | //reg clk,
81 | reg rst_n, in_valid;
82 | wire out_valid;
83 | reg signed [IN_width-1:0] din_r, din_i;
84 | wire signed [OUT_width-1:0] dout_r, dout_i;
85 |
86 | //always #(cycle/2.0) clk = ~clk;
87 |
88 | always @(enable) begin
89 | if(enable==1) begin
90 | //clk = 0;
91 | rst_n = 1;
92 | in_valid = 0;
93 | latency = 0;
94 | flag = 0;
95 | //fp_r = $fopen("../Test_pattern/input/IN_real_pattern01.txt", "r");
96 | //fp_i = $fopen("../Test_pattern/input/IN_imag_pattern01.txt", "r");
97 |
98 | @(negedge clk);
99 | @(negedge clk) rst_n = 0;
100 | @(negedge clk) rst_n = 1;
101 | @(negedge clk);
102 | $display("Input");
103 | for(j=0;j