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

Subversion Repositories astron_r2sdf_fft

[/] [astron_r2sdf_fft/] [trunk/] [rTwoSDF.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
--------------------------------------------------------------------------------
2
--
3 3 danv
-- Copyright 2020
4
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6
-- 
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
 
21
-- Purpose: Pipelined radix 2 FFT
22
-- Description: ASTRON-RP-755
23
-- Remarks: doc/readme.txt
24
 
25
 
26 4 danv
library ieee, common_pkg_lib, astron_requantize_lib;
27 2 danv
use IEEE.std_logic_1164.all;
28
use common_pkg_lib.common_pkg.all;
29
use work.twiddlesPkg.all;
30
use work.rTwoSDFPkg.all;
31
 
32
entity rTwoSDF is
33
  generic (
34
    -- generics for the FFT    
35
    g_nof_chan    : natural := 0;     -- Exponent of nr of subbands (0 means 1 subband)
36
    g_use_reorder : boolean := true;
37
    g_in_dat_w    : natural := 8;     -- number of input bits
38
    g_out_dat_w   : natural := 14;    -- number of output bits
39
    g_stage_dat_w : natural := 18;    -- number of bits used between the stages
40
    g_guard_w     : natural := 2;     -- guard bits are used to avoid overflow in single FFT stage.   
41
    g_nof_points  : natural := 1024;  -- N point FFT
42
    -- generics for rTwoSDFStage
43
    g_pipeline    : t_fft_pipeline := c_fft_pipeline
44
  );
45
  port (
46
    clk      : in  std_logic;
47
    rst      : in  std_logic := '0';
48
    in_re    : in  std_logic_vector(g_in_dat_w-1 downto 0);
49
    in_im    : in  std_logic_vector(g_in_dat_w-1 downto 0);
50
    in_val   : in  std_logic := '1';
51
    out_re   : out std_logic_vector(g_out_dat_w-1 downto 0);
52
    out_im   : out std_logic_vector(g_out_dat_w-1 downto 0);
53
    out_val  : out std_logic
54
  );
55
end entity rTwoSDF;
56
 
57
architecture str of rTwoSDF is
58
 
59
  constant c_nof_stages         : natural := ceil_log2(g_nof_points);
60
  constant c_stage_offset       : natural := 0;                               -- In "normal" pipelined fft operation the stage offset is 0
61
  constant c_twiddle_offset     : natural := 0;                               -- In "normal" pipelined fft operation the twiddle offset is 0
62
 
63
  -- Round last stage output to g_out_dat_w if g_out_dat_w < g_stage_dat_w else resize to g_out_dat_w
64
  constant c_out_scale_w        : integer := g_stage_dat_w - g_out_dat_w;     -- Estimate number of LSBs to round throw away when > 0 or insert when < 0
65
 
66
  -- Scale the input to make optimal use of the g_stage_dat_w of the stages, using a margin of g_guard_w to account for factor > 2 gain of the first stage
67
  constant c_in_scale_w         : natural := g_stage_dat_w - g_guard_w - g_in_dat_w; -- use type natural instead of integer to implicitly ensure that the g_stage_dat_w >= g_input_dat_w
68
 
69
  -- number the stage instances from c_nof_stages:1
70
  -- . the data input for the first stage has index c_nof_stages
71
  -- . the data output of the last stage has index 0
72
  type t_data_arr is array(c_nof_stages downto 0) of std_logic_vector(g_stage_dat_w-1 downto 0);
73
 
74
  signal data_re      : t_data_arr;
75
  signal data_im      : t_data_arr;
76
  signal data_val     : std_logic_vector(c_nof_stages downto 0):= (others=>'0');
77
 
78
  signal out_cplx     : std_logic_vector(2*g_stage_dat_w-1 downto 0);
79
  signal raw_out_cplx : std_logic_vector(2*g_stage_dat_w-1 downto 0);
80
  signal raw_out_re   : std_logic_vector(g_stage_dat_w-1 downto 0);
81
  signal raw_out_im   : std_logic_vector(g_stage_dat_w-1 downto 0);
82
  signal raw_out_val  : std_logic;
83
 
84
begin
85
 
86
  -- Inputs
87
  data_re( c_nof_stages) <= scale_and_resize_svec(in_re, c_in_scale_w, g_stage_dat_w);
88
  data_im( c_nof_stages) <= scale_and_resize_svec(in_im, c_in_scale_w, g_stage_dat_w);
89
  data_val(c_nof_stages) <= in_val;
90
 
91
  ------------------------------------------------------------------------------
92
  -- pipelined FFT stages
93
  ------------------------------------------------------------------------------
94
 
95
  gen_fft: for stage in c_nof_stages downto 1 generate
96
    u_stage : entity work.rTwoSDFStage
97
    generic map (
98
      g_nof_chan       => g_nof_chan,
99
      g_stage          => stage,
100
      g_stage_offset   => c_stage_offset,
101
      g_twiddle_offset => c_twiddle_offset,
102
      g_scale_enable   => sel_a_b(stage <= g_guard_w, FALSE, TRUE),  -- On average all stages have a gain factor of 2 therefore each stage needs to round 1 bit except for the last g_guard_w nof stages due to the input c_in_scale_w
103
      g_pipeline       => g_pipeline
104
    )
105
    port map (
106
      clk       => clk,
107
      rst       => rst,
108
      in_re     => data_re(stage),
109
      in_im     => data_im(stage),
110
      in_val    => data_val(stage),
111
      out_re    => data_re(stage-1),
112
      out_im    => data_im(stage-1),
113
      out_val   => data_val(stage-1)
114
    );
115
  end generate;
116
 
117
  ------------------------------------------------------------------------------
118
  -- Optional output reorder
119
  ------------------------------------------------------------------------------
120
 
121
  no_reorder : if g_use_reorder=false generate
122
    raw_out_re  <= data_re(0);
123
    raw_out_im  <= data_im(0);
124
    raw_out_val <= data_val(0);
125
  end generate;
126
 
127
  gen_reorder : if g_use_reorder=true generate
128
    raw_out_cplx <= data_im(0) & data_re(0);
129
 
130
    raw_out_re <= out_cplx(  g_stage_dat_w-1 downto 0);
131
    raw_out_im <= out_cplx(2*g_stage_dat_w-1 downto g_stage_dat_w);
132
 
133
    u_cplx: entity work.rTwoOrder
134
    generic map (
135
      g_nof_points => g_nof_points,
136
      g_nof_chan   => g_nof_chan
137
    )
138
    port map (
139
      clk     => clk,
140
      rst     => rst,
141
      in_dat  => raw_out_cplx,
142
      in_val  => data_val(0),
143
      out_dat => out_cplx,
144
      out_val => raw_out_val
145
    );
146
  end generate;
147
 
148
  ------------------------------------------------------------------------------
149
  -- pipelined FFT output requantization
150
  ------------------------------------------------------------------------------
151 4 danv
  u_requantize_re : entity astron_requantize_lib.common_requantize
152 2 danv
  generic map (
153
    g_representation      => "SIGNED",
154
    g_lsb_w               => c_out_scale_w,
155
    g_lsb_round           => TRUE,
156
    g_lsb_round_clip      => FALSE,
157
    g_msb_clip            => FALSE,
158
    g_msb_clip_symmetric  => FALSE,
159
    g_pipeline_remove_lsb => 0,
160
    g_pipeline_remove_msb => 0,
161
    g_in_dat_w            => g_stage_dat_w,
162
    g_out_dat_w           => g_out_dat_w
163
  )
164
  port map (
165
    clk        => clk,
166
    clken      => '1',
167
    in_dat     => raw_out_re,
168
    out_dat    => out_re,
169
    out_ovr    => open
170
  );
171
 
172 4 danv
  u_requantize_im : entity astron_requantize_lib.common_requantize
173 2 danv
  generic map (
174
    g_representation      => "SIGNED",
175
    g_lsb_w               => c_out_scale_w,
176
    g_lsb_round           => TRUE,
177
    g_lsb_round_clip      => FALSE,
178
    g_msb_clip            => FALSE,
179
    g_msb_clip_symmetric  => FALSE,
180
    g_pipeline_remove_lsb => 0,
181
    g_pipeline_remove_msb => 0,
182
    g_in_dat_w            => g_stage_dat_w,
183
    g_out_dat_w           => g_out_dat_w
184
  )
185
  port map (
186
    clk        => clk,
187
    clken      => '1',
188
    in_dat     => raw_out_im,
189
    out_dat    => out_im,
190
    out_ovr    => open
191
  );
192
 
193
  -- Valid Output
194
  out_val <= raw_out_val;
195
 
196
end str;

powered by: WebSVN 2.1.0

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