OpenCores
URL https://opencores.org/ocsvn/fft2_size/fft2_size/trunk

Subversion Repositories fft2_size

[/] [fft2_size/] [fft_int/] [butterfly.sv] - Blame information for rev 12

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 Papayaved
`ifndef _butterfly_
2
`define _butterfly_
3
`include "W_int32.sv"
4
 
5
// Delay 3, 4
6
module butterfly #(parameter DATA_WIDTH = 32, W_WIDTH = 32, POW = 3)(
7
        input clk,
8
        input sync, // y
9
        input signed [DATA_WIDTH-1:0] sink_Re, sink_Im,
10
        output reg signed [DATA_WIDTH:0] source_Re, source_Im
11
);
12
        reg [POW-1:0] cnt;
13
 
14
        always_ff @(posedge clk)
15
                if (sync)
16
                        cnt <= '0;
17
                else
18
                        cnt <= cnt + 1'b1;
19
 
20
        generate
21
                if (POW == 1) // delay 3
22
                        begin :gen1
23
                                wire x_yn;
24
                                reg signed [DATA_WIDTH-1:0] Re_reg[2], Im_reg[2];
25
                                reg signed [DATA_WIDTH:0] new_x_Re, new_x_Im;
26
 
27
                                assign x_yn = cnt[0];
28
 
29
                                // W = 1
30
                                always_ff @(posedge clk) begin
31
                                        Re_reg[0] <= sink_Re;
32
                                        Im_reg[0] <= sink_Im;
33
                                        Re_reg[1] <= Re_reg[0];
34
                                        Im_reg[1] <= Im_reg[0];
35
                                end
36
 
37
                                always_ff @(posedge clk)
38
                                        if (x_yn == 1'b1)
39
                                                begin
40
                                                        new_x_Re <= Re_reg[0] + Re_reg[1]; // x + y
41
                                                        new_x_Im <= Im_reg[0] + Im_reg[1];
42
                                                        source_Re <= Re_reg[0] - Re_reg[1]; // x - y
43
                                                        source_Im <= Im_reg[0] - Im_reg[1];
44
                                                end
45
                                        else
46
                                                begin
47
                                                        source_Re <= new_x_Re;
48
                                                        source_Im <= new_x_Im;
49
                                                end
50
                        end
51
                else if (POW == 2) // delay 3
52
                        begin :gen2
53
                                wire x_yn, k;
54
                                reg signed [DATA_WIDTH-1:0] Re_reg, Im_reg;
55
                                reg signed [DATA_WIDTH-1:0] wy_Re, wy_Im;
56
                                reg signed [DATA_WIDTH:0] new_x_Re, new_x_Im;
57
 
58
                                assign x_yn = cnt[0];
59
                                assign k = cnt[1];
60
 
61
                                always_ff @(posedge clk) begin
62
                                        Re_reg <= sink_Re;
63
                                        Im_reg <= sink_Im;
64
                                end
65
 
66
                                always_ff @(posedge clk)
67
                                        if (x_yn == 1'b0)
68
                                                case (k)
69
                                                        1'b0: // 1
70
                                                                begin
71
                                                                        wy_Re <= Re_reg;
72
                                                                        wy_Im <= Im_reg;
73
                                                                end
74
                                                        1'b1: // -j: -j * (a + j*b) = b - j*a
75
                                                                begin
76
                                                                        wy_Re <= Im_reg;
77
                                                                        wy_Im <= DATA_WIDTH'('sh0) - Re_reg;
78
                                                                end
79
                                                endcase
80
 
81
                                always_ff @(posedge clk)
82
                                        if (x_yn == 1'b1)
83
                                                begin
84
                                                        new_x_Re <= Re_reg + wy_Re; // x + w*y
85
                                                        new_x_Im <= Im_reg + wy_Im;
86
                                                        source_Re <= Re_reg - wy_Re; // x - w*y
87
                                                        source_Im <= Im_reg - wy_Im;
88
                                                end
89
                                        else
90
                                                begin
91
                                                        source_Re <= new_x_Re;
92
                                                        source_Im <= new_x_Im;
93
                                                end
94
                        end
95
                else // delay 4
96
                        begin :gen3
97
                                reg x_yn;
98
                                wire [POW-2:0] k;
99
                                reg signed [DATA_WIDTH-1:0] Re_reg[2], Im_reg[2];
100
                                wire signed [W_WIDTH-1:0] W_Re, W_Im;
101
                                reg signed [W_WIDTH + DATA_WIDTH:0] wy_Re, wy_Im;
102
                                wire signed [DATA_WIDTH-1:0] wy_Re_tr, wy_Im_tr;
103
                                reg signed [DATA_WIDTH:0] new_x_Re, new_x_Im;
104
 
105
                                always_ff @(posedge clk)
106
                                        begin
107
                                                Re_reg[0] <= sink_Re;
108
                                                Im_reg[0] <= sink_Im;
109
                                                Re_reg[1] <= Re_reg[0];
110
                                                Im_reg[1] <= Im_reg[0];
111
                                                x_yn <= cnt[0];
112
                                        end
113
 
114
                                assign k = cnt[POW-1:1];
115
 
116
                                W_int32 #(.POW(POW), .W_WIDTH(W_WIDTH)) W_inst(.clk, .k, .W_Re, .W_Im);
117
 
118
                                // w * y = (wr + wi * j) * (yr + yi * j) = wr * yr  - wi * yi + j * (wi * yr + wr * yi)
119
                                always_ff @(posedge clk)
120
                                        if (x_yn == 1'b0)
121
                                                begin
122
                                                        wy_Re <= W_Re * Re_reg[1] - W_Im * Im_reg[1];
123
                                                        wy_Im <= W_Re * Im_reg[1] + W_Im * Re_reg[1];
124
                                                end
125
 
126
                                assign wy_Re_tr = wy_Re[(W_WIDTH-2)+:DATA_WIDTH];
127
                                assign wy_Im_tr = wy_Im[(W_WIDTH-2)+:DATA_WIDTH];
128
 
129
                                always_ff @(posedge clk)
130
                                        if (x_yn == 1'b1)
131
                                                begin
132
                                                        new_x_Re <= Re_reg[1] + wy_Re_tr; // x
133
                                                        new_x_Im <= Im_reg[1] + wy_Im_tr;
134
                                                        source_Re <= Re_reg[1] - wy_Re_tr; // y
135
                                                        source_Im <= Im_reg[1] - wy_Im_tr;
136
                                                end
137
                                        else
138
                                                begin
139
                                                        source_Re <= new_x_Re;
140
                                                        source_Im <= new_x_Im;
141
                                                end
142
                        end
143
        endgenerate
144
endmodule :butterfly
145
 
146
`endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.