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

Subversion Repositories astron_wb_fft

[/] [astron_wb_fft/] [trunk/] [fft_r2_pipe.vhd] - Blame information for rev 3

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

Line No. Rev Author Line
1 2 danv
--------------------------------------------------------------------------------
2
--
3 3 danv
-- Copyright 2020
4 2 danv
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6 3 danv
-- 
7
-- Licensed under the Apache License, Version 2.0 (the "License");
8
-- you may not use this file except in compliance with the License.
9
-- You may obtain a copy of the License at
10
-- 
11
--     http://www.apache.org/licenses/LICENSE-2.0
12
-- 
13
-- Unless required by applicable law or agreed to in writing, software
14
-- distributed under the License is distributed on an "AS IS" BASIS,
15
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
-- See the License for the specific language governing permissions and
17
-- limitations under the License.
18 2 danv
--
19
--------------------------------------------------------------------------------  --
20
-- Purpose:  Complex Pipelined Fast Fourier Transform
21
-- 
22
-- Description: The fft_r2_pipe unit performs a complex pipelined FFT on the incoming data stream.
23
--              The implementation is pipelined which means that at every stage only one 
24
--              multiplier is used to perform all N/2 twiddle multiplications. 
25
--              
26
--              There are two optional features: 
27
--              
28
--              * Reordering: When enabled the output bins of the FFT are re-ordered in 
29
--                            in such a way that the bins represent the frequencies in an 
30
--                            incrementing way. 
31
--              
32
--              * Separation: When enabled the fft_r2_pipe can be used to process two real streams.
33
--                            The first real stream (A) presented on the real input, the second 
34
--                            real stream (B) presented on the imaginary input. 
35
--                            The separation unit processes outputs the spectrum of A and B in 
36
--                            an alternating way: A(0), B(0), A(1), B(1).... etc
37
--
38
--
39
-- Remarks: When g_fft.nof_chan is used the spectrums at the output will be interleaved
40
--          per spectrum and NOT per sample. So in case g_fft.nof_chan = 1 there will be
41
--          two multiplexed channels at the input (c0t0 means channel 0, timestamp 0) :
42
--         
43
--          c0t0 c1t0s c0t1 c1t1 c0t2 c1t2 ... c0t15 c1t15 
44
--
45
--          At the output will find: 
46
--
47
--          c0f0 c0f1 c0f2 ... c0f15 c1f0 c1f1 c1f2 ... c1f15  (c0f0 means channel 0, frequency bin 0)
48
--
49
--           
50
 
51
library ieee, common_pkg_lib, common_components_lib,  common_requantize_lib, rTwoSDF_lib;
52
use IEEE.std_logic_1164.all;
53
use common_pkg_lib.common_pkg.all;
54
use rTwoSDF_lib.rTwoSDFPkg.all;
55
use work.fft_pkg.all;
56
 
57
entity fft_r2_pipe is
58
  generic (
59
    g_fft      : t_fft := c_fft;                   -- generics for the FFT
60
    g_pipeline : t_fft_pipeline := c_fft_pipeline; -- generics for pipelining in each stage, defined in rTwoSDF_lib.rTwoSDFPkg
61
    g_dont_flip_channels : boolean := false        -- generic to prevent re-ordering of the channels
62
  );
63
  port (
64
    clk      : in  std_logic;
65
    rst      : in  std_logic := '0';
66
    in_re    : in  std_logic_vector(g_fft.in_dat_w-1 downto 0);
67
    in_im    : in  std_logic_vector(g_fft.in_dat_w-1 downto 0);
68
    in_val   : in  std_logic := '1';
69
    out_re   : out std_logic_vector(g_fft.out_dat_w-1 downto 0);
70
    out_im   : out std_logic_vector(g_fft.out_dat_w-1 downto 0);
71
    out_val  : out std_logic
72
  );
73
end entity fft_r2_pipe;
74
 
75
architecture str of fft_r2_pipe is
76
 
77
  constant c_pipeline_remove_lsb : natural := 0;
78
 
79
  constant c_nof_stages         : natural := ceil_log2(g_fft.nof_points);
80
  constant c_stage_offset       : natural := true_log2(g_fft.wb_factor);                         -- Stage offset is required for twiddle generation in wideband fft
81
  constant c_in_scale_w         : natural := g_fft.stage_dat_w - g_fft.in_dat_w - sel_a_b(g_fft.guard_enable, g_fft.guard_w, 0);
82
  constant c_out_scale_w        : integer := g_fft.stage_dat_w - g_fft.out_dat_w - g_fft.out_gain_w;  -- Estimate number of LSBs to throw throw away when > 0 or insert when < 0
83
 
84
  -- number the stage instances from c_nof_stages:1
85
  -- . the data input for the first stage has index c_nof_stages
86
  -- . the data output of the last stage has index 0
87
  type t_data_arr is array(c_nof_stages downto 0) of std_logic_vector(g_fft.stage_dat_w-1 downto 0);
88
 
89
  signal data_re      : t_data_arr;
90
  signal data_im      : t_data_arr;
91
  signal data_val     : std_logic_vector(c_nof_stages downto 0):= (others=>'0');
92
 
93
  signal out_cplx     : std_logic_vector(c_nof_complex*g_fft.stage_dat_w-1 downto 0);
94
  signal in_cplx      : std_logic_vector(c_nof_complex*g_fft.stage_dat_w-1 downto 0);
95
  signal raw_out_re   : std_logic_vector(g_fft.stage_dat_w-1 downto 0);
96
  signal raw_out_im   : std_logic_vector(g_fft.stage_dat_w-1 downto 0);
97
  signal raw_out_val  : std_logic;
98
 
99
begin
100
 
101
  -- Inputs
102
  data_re( c_nof_stages) <= scale_and_resize_svec(in_re, c_in_scale_w, g_fft.stage_dat_w);
103
  data_im( c_nof_stages) <= scale_and_resize_svec(in_im, c_in_scale_w, g_fft.stage_dat_w);
104
  data_val(c_nof_stages) <= in_val;
105
 
106
  ------------------------------------------------------------------------------
107
  -- pipelined FFT stages
108
  ------------------------------------------------------------------------------
109
  gen_fft: for stage in c_nof_stages downto 1 generate
110
    u_stage : entity rTwoSDF_lib.rTwoSDFStage
111
    generic map (
112
      g_nof_chan       => g_fft.nof_chan,
113
      g_stage          => stage,
114
      g_stage_offset   => c_stage_offset,
115
      g_twiddle_offset => g_fft.twiddle_offset,
116
      g_scale_enable   => sel_a_b(stage <= g_fft.guard_w, FALSE, TRUE),
117
      g_pipeline       => g_pipeline
118
    )
119
    port map (
120
      clk       => clk,
121
      rst       => rst,
122
      in_re     => data_re(stage),
123
      in_im     => data_im(stage),
124
      in_val    => data_val(stage),
125
      out_re    => data_re(stage-1),
126
      out_im    => data_im(stage-1),
127
      out_val   => data_val(stage-1)
128
    );
129
  end generate;
130
 
131
  ------------------------------------------------------------------------------
132
  -- Optional output reorder and separation
133
  ------------------------------------------------------------------------------
134
  gen_reorder_and_separate : if(g_fft.use_separate or g_fft.use_reorder) generate
135
    in_cplx <= data_im(0) & data_re(0);
136
 
137
    u_reorder_sep : entity work.fft_reorder_sepa_pipe
138
    generic map (
139
      g_bit_flip    => g_fft.use_reorder,
140
      g_fft_shift   => g_fft.use_fft_shift,
141
      g_separate    => g_fft.use_separate,
142
      g_dont_flip_channels => g_dont_flip_channels,
143
      g_nof_points  => g_fft.nof_points,
144
      g_nof_chan    => g_fft.nof_chan
145
    )
146
    port map (
147
      clk     => clk,
148
      rst     => rst,
149
      in_dat  => in_cplx,
150
      in_val  => data_val(0),
151
      out_dat => out_cplx,
152
      out_val => raw_out_val
153
    );
154
 
155
    raw_out_re <= out_cplx(  g_fft.stage_dat_w-1 downto 0);
156
    raw_out_im <= out_cplx(2*g_fft.stage_dat_w-1 downto g_fft.stage_dat_w);
157
 
158
  end generate;
159
 
160
  no_reorder_no_generate : if(g_fft.use_separate=false and g_fft.use_reorder=false) generate
161
    raw_out_re  <= data_re(0);
162
    raw_out_im  <= data_im(0);
163
    raw_out_val <= data_val(0);
164
  end generate;
165
 
166
  ------------------------------------------------------------------------------
167
  -- pipelined FFT output requantization
168
  ------------------------------------------------------------------------------
169
  u_requantize_re : entity common_requantize_lib.common_requantize
170
  generic map (
171
    g_representation      => "SIGNED",
172
    g_lsb_w               => c_out_scale_w,
173
    g_lsb_round           => TRUE,
174
    g_lsb_round_clip      => FALSE,
175
    g_msb_clip            => FALSE,
176
    g_msb_clip_symmetric  => FALSE,
177
    g_pipeline_remove_lsb => c_pipeline_remove_lsb,
178
    g_pipeline_remove_msb => 0,
179
    g_in_dat_w            => g_fft.stage_dat_w,
180
    g_out_dat_w           => g_fft.out_dat_w
181
  )
182
  port map (
183
    clk        => clk,
184
    in_dat     => raw_out_re,
185
    out_dat    => out_re,
186
    out_ovr    => open
187
  );
188
 
189
  u_requantize_im : entity common_requantize_lib.common_requantize
190
  generic map (
191
    g_representation      => "SIGNED",
192
    g_lsb_w               => c_out_scale_w,
193
    g_lsb_round           => TRUE,
194
    g_lsb_round_clip      => FALSE,
195
    g_msb_clip            => FALSE,
196
    g_msb_clip_symmetric  => FALSE,
197
    g_pipeline_remove_lsb => c_pipeline_remove_lsb,
198
    g_pipeline_remove_msb => 0,
199
    g_in_dat_w            => g_fft.stage_dat_w,
200
    g_out_dat_w           => g_fft.out_dat_w
201
  )
202
  port map (
203
    clk        => clk,
204
    in_dat     => raw_out_im,
205
    out_dat    => out_im,
206
    out_ovr    => open
207
  );
208
 
209
  -- Valid Output
210
  u_out_val : entity common_components_lib.common_pipeline_sl
211
  generic map (
212
    g_pipeline => c_pipeline_remove_lsb
213
  )
214
  port map (
215
    rst     => rst,
216
    clk     => clk,
217
    in_dat  => raw_out_val,
218
    out_dat => out_val
219
  );
220
 
221
end str;
222
 

powered by: WebSVN 2.1.0

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