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

Subversion Repositories astron_wb_fft

[/] [astron_wb_fft/] [trunk/] [fft_wide_unit_control.vhd] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3
-- Copyright (C) 2009
4
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6
--
7
-- This program is free software: you can redistribute it and/or modify
8
-- it under the terms of the GNU General Public License as published by
9
-- the Free Software Foundation, either version 3 of the License, or
10
-- (at your option) any later version.
11
--
12
-- This program is distributed in the hope that it will be useful,
13
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
-- GNU General Public License for more details.
16
--
17
-- You should have received a copy of the GNU General Public License
18
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
-------------------------------------------------------------------------------
21
-- Purpose: Composition of the SOSI output streams for the fft_wide_unit. 
22
--
23
-- Description: This unit monitors the in_val signal. Based on the assertion of the 
24
--              in_val signal it will compose the output sosi streams. The packet-
25
--              size equals g_fft.nof_points/g_fft.wb_factor. 
26
--              Both the incoming bsn and err fields are written to a fifo. When 
27
--              the output is composed the bsn and err field will be read from the 
28
--              fifo's. 
29
--              Incoming syncs will be detected and the bsn that accompanies the sync
30
--              will be stored. When the bsn that is read from the fifo is the same 
31
--              as the stored one, the sync will be asserted to the output. 
32
--
33
-- Remarks:    .The sync interval must be larger that the total amount of pipeline
34
--              stages in the FFT. In other words: the fft_wide_unit_control unit 
35
--              is not capable of handling more than one sync pulse at a time. 
36
--              
37
--
38
 
39
library IEEE, common_pkg_lib, common_ram_lib, common_fifo_lib, dp_pkg_lib;
40
use IEEE.std_logic_1164.ALL;
41
use IEEE.numeric_std.ALL;
42
use common_pkg_lib.common_pkg.ALL;
43
use common_ram_lib.common_ram_pkg.ALL;
44
use dp_pkg_lib.dp_stream_pkg.ALL;
45
use work.fft_pkg.ALL;
46
 
47
entity fft_wide_unit_control is
48
  generic (
49
    g_fft      : t_fft   := c_fft;
50
    g_nof_ffts : natural := 1
51
  );
52
  port (
53
    rst          : in  std_logic := '0';
54
    clk          : in  std_logic;
55
    in_re_arr    : in  t_fft_slv_arr(g_nof_ffts*g_fft.wb_factor-1 downto 0);
56
    in_im_arr    : in  t_fft_slv_arr(g_nof_ffts*g_fft.wb_factor-1 downto 0);
57
    in_val       : in  std_logic;
58
    ctrl_sosi    : in  t_dp_sosi;                                            -- Inputrecord for tapping off the sync, bsn and err.              
59
    out_sosi_arr : out t_dp_sosi_arr(g_nof_ffts*g_fft.wb_factor-1 downto 0)  -- Streaming output interface    
60
  );
61
end fft_wide_unit_control;
62
 
63
architecture rtl of fft_wide_unit_control is
64
 
65
  constant c_pipe_data       : natural := 3;                                -- Delay depth for the data 
66
  constant c_pipe_ctrl       : natural := c_pipe_data-1;                    -- Delay depth for the control signals
67
  constant c_packet_size     : natural := (2**g_fft.nof_chan)*g_fft.nof_points/g_fft.wb_factor; -- Definition of the packet size
68
  constant c_ctrl_fifo_depth : natural := 16;                               -- Depth of the bsn and err fifo.  
69
 
70
  type t_fft_slv_arr2 is array (integer range <>) of t_fft_slv_arr(g_nof_ffts*g_fft.wb_factor-1 downto 0);
71
  type state_type     is (s_idle, s_run, s_hold);
72
 
73
  type reg_type is record
74
    out_sosi_arr   : t_dp_sosi_arr(g_nof_ffts*g_fft.wb_factor-1 downto 0); -- Register that holds the streaming interface          
75
    in_re_arr2_dly : t_fft_slv_arr2(c_pipe_data              -1 downto 0); -- Input registers for the real data 
76
    in_im_arr2_dly : t_fft_slv_arr2(c_pipe_data              -1 downto 0); -- Input registers for the imag data  
77
    val_dly        : std_logic_vector(c_pipe_ctrl            -1 downto 0); -- Delay-register for the valid signal
78
    sop_dly        : std_logic_vector(c_pipe_ctrl            -1 downto 0); -- Delay-register for the sop signal
79
    eop_dly        : std_logic_vector(c_pipe_ctrl            -1 downto 0); -- Delay-register for the eop signal
80
    sync_detected  : std_logic;                                            -- Register used to detect and pass the sync pulse.
81
    packet_cnt     : integer;                                              -- Counter to create the packets. 
82
    state          : state_type;                                           -- The state machine. 
83
  end record;
84
 
85
  signal r, rin   : reg_type;
86
  signal bsn      : std_logic_vector(c_dp_stream_bsn_w  -1 downto 0);
87
  signal sync_bsn : std_logic_vector(c_dp_stream_bsn_w  -1 downto 0);
88
  signal err      : std_logic_vector(c_dp_stream_error_w-1 downto 0);
89
  signal rd_req   : std_logic;
90
  signal rd_req_i : std_logic;
91
  signal rd_dat_i : std_logic_vector(c_dp_stream_bsn_w  -1 downto 0);
92
  signal rd_val_i : std_logic;
93
 
94
begin
95
 
96
  ---------------------------------------------------------------
97
  -- INPUT FIFO FOR BSN
98
  ---------------------------------------------------------------
99
  u_bsn_fifo : entity common_fifo_lib.common_fifo_sc
100
  generic map (
101
    g_use_lut   => TRUE,   -- Make this FIFO in logic, since it's only 4 words deep. 
102
    g_reset     => FALSE,
103
    g_init      => FALSE,
104
    g_dat_w     => c_dp_stream_bsn_w,
105
    g_nof_words => c_ctrl_fifo_depth
106
  )
107
  port map (
108
    rst     => rst,
109
    clk     => clk,
110
    wr_dat  => ctrl_sosi.bsn,
111
    wr_req  => ctrl_sosi.sop,
112
    wr_ful  => open ,
113
    rd_dat  => bsn,
114
    rd_req  => r.sop_dly(0),
115
    rd_emp  => open ,
116
    rd_val  => open ,
117
    usedw   => open
118
  );
119
 
120
  ---------------------------------------------------------------
121
  -- INPUT FIFO FOR ERR
122
  ---------------------------------------------------------------
123
  u_error_fifo : entity common_fifo_lib.common_fifo_sc
124
  generic map (
125
    g_use_lut   => TRUE,   -- Make this FIFO in logic, since it's only 4 words deep. 
126
    g_reset     => FALSE,
127
    g_init      => FALSE,
128
    g_dat_w     => c_dp_stream_error_w,
129
    g_nof_words => c_ctrl_fifo_depth
130
  )
131
  port map (
132
    rst     => rst,
133
    clk     => clk,
134
    wr_dat  => ctrl_sosi.err,
135
    wr_req  => ctrl_sosi.sop,
136
    wr_ful  => open ,
137
    rd_dat  => err,
138
    rd_req  => r.sop_dly(1),
139
    rd_emp  => open ,
140
    rd_val  => open ,
141
    usedw   => open
142
  );
143
 
144
  ---------------------------------------------------------------
145
  -- FIFO FOR SYNC-BSN
146
  ---------------------------------------------------------------
147
  u_sync_bsn_fifo : entity common_fifo_lib.common_fifo_sc
148
  generic map (
149
    g_use_lut   => TRUE,   -- Make this FIFO in logic, since it's only 4 words deep. 
150
    g_reset     => FALSE,
151
    g_init      => FALSE,
152
    g_dat_w     => c_dp_stream_bsn_w,
153
    g_nof_words => 2
154
  )
155
  port map (
156
    rst     => rst,
157
    clk     => clk,
158
    wr_dat  => ctrl_sosi.bsn,
159
    wr_req  => ctrl_sosi.sync,
160
    wr_ful  => open ,
161
    rd_dat  => rd_dat_i,
162
    rd_req  => rd_req_i,
163
    rd_emp  => open,
164
    rd_val  => rd_val_i,
165
    usedw   => open
166
  );
167
 
168
  ---------------------------------------------------------------
169
  -- CREATE READ-AHEAD FIFO INTERFACE FOR SYNC-BSN
170
  ---------------------------------------------------------------
171
  u_fifo_adapter : entity common_fifo_lib.common_fifo_rd
172
  generic map (
173
    g_dat_w => c_dp_stream_bsn_w
174
  )
175
  port map(
176
    rst        => rst,
177
    clk        => clk,
178
    -- ST sink: RL = 1
179
    fifo_req   => rd_req_i,
180
    fifo_dat   => rd_dat_i,
181
    fifo_val   => rd_val_i,
182
    -- ST source: RL = 0
183
    rd_req     => rd_req,
184
    rd_dat     => sync_bsn,
185
    rd_val     => open
186
  );
187
 
188
  rd_req <= r.out_sosi_arr(0).sync; --  (r.sync_detected and not(rd_emp)) or r.rd_first; 
189
 
190
  ---------------------------------------------------------------
191
  -- PROCESS THAT COMPOSES THE SOSI OUTPUT ARRAYS
192
  ---------------------------------------------------------------
193
  comb : process(r, rst, ctrl_sosi, in_re_arr, in_im_arr, in_val, sync_bsn, bsn, err)
194
    variable v : reg_type;
195
  begin
196
 
197
    v := r;
198
 
199
    v.val_dly(0)  := '0';              -- Some defaults, before entering the state machine.              
200
    v.sop_dly(0)  := '0';
201
    v.eop_dly(0)  := '0';
202
 
203
    for I in g_nof_ffts*g_fft.wb_factor-1 downto 0 loop
204
      v.out_sosi_arr(I).sync  := '0';
205
    end loop;
206
 
207
    v.in_re_arr2_dly(0) := in_re_arr;  -- Latch the data into the input registers. 
208
    v.in_im_arr2_dly(0) := in_im_arr;  -- Latch the data into the input registers. 
209
 
210
    v.in_re_arr2_dly(c_pipe_data-1 downto 1) := r.in_re_arr2_dly(c_pipe_data-2 downto 0); -- Shift the delay registers
211
    v.in_im_arr2_dly(c_pipe_data-1 downto 1) := r.in_im_arr2_dly(c_pipe_data-2 downto 0); -- Shift the delay registers
212
    v.val_dly(c_pipe_ctrl-1 downto 1)        := r.val_dly(c_pipe_ctrl-2 downto 0);        -- Shift the delay registers
213
    v.sop_dly(c_pipe_ctrl-1 downto 1)        := r.sop_dly(c_pipe_ctrl-2 downto 0);        -- Shift the delay registers
214
    v.eop_dly(c_pipe_ctrl-1 downto 1)        := r.eop_dly(c_pipe_ctrl-2 downto 0);        -- Shift the delay registers
215
 
216
    for I in g_nof_ffts*g_fft.wb_factor-1 downto 0 loop
217
      v.out_sosi_arr(I).sop   := r.sop_dly(c_pipe_ctrl-1);  -- Assign the output of the shiftregisters to the "real" signals
218
      v.out_sosi_arr(I).eop   := r.eop_dly(c_pipe_ctrl-1);  -- Assign the output of the shiftregisters to the "real" signals
219
      v.out_sosi_arr(I).valid := r.val_dly(c_pipe_ctrl-1);  -- Assign the output of the shiftregisters to the "real" signals
220
      v.out_sosi_arr(I).bsn   := bsn;                       -- The bsn is read from the FIFO
221
      v.out_sosi_arr(I).err   := err;                       -- The err is read from the FIFO
222
      v.out_sosi_arr(I).re    := RESIZE_SVEC(r.in_re_arr2_dly(c_pipe_data-1)(I), c_dp_stream_dsp_data_w); -- Data input is latched-in 
223
      v.out_sosi_arr(I).im    := RESIZE_SVEC(r.in_im_arr2_dly(c_pipe_data-1)(I), c_dp_stream_dsp_data_w); -- Data input is latched-in 
224
    end loop;
225
 
226
    if(ctrl_sosi.sync = '1') then                           -- Check which bsn accompanies the sync
227
      v.sync_detected := '1';
228
    end if;
229
 
230
    if(sync_bsn = bsn and r.sop_dly(1) = '1' and r.sync_detected = '1') then -- When the next bsn equals the stored bsn 
231
      for I in g_fft.wb_factor-1 downto 0 loop                                 -- a sync pulse will be generated that 
232
        v.out_sosi_arr(I).sync  := '1';                                        -- preceeds the sop
233
      end loop;
234
      v.sync_detected := '0';
235
    end if;
236
 
237
    case r.state is
238
            when s_idle =>
239
                if(in_val = '1') then                       -- Wait for the first data to arrive
240
                  v.packet_cnt := 0;                        -- Reset the packet counter
241
                        v.state      := s_run;
242
                end if;
243
 
244
            when s_run =>
245
              v.val_dly(0) := '1';                        -- Assert the valid signal (Stream starts)
246
              v.packet_cnt := r.packet_cnt + 1;           -- Increment the packet-counter when in s_run-state
247
 
248
        if(r.packet_cnt = 0) then                   -- First sample marks
249
          v.sop_dly(0) :='1';                       -- the start of a packet
250
        elsif(r.packet_cnt = c_packet_size-1) then  -- Last address marks  
251
          v.eop_dly(0) :='1';                       -- the end of a packet
252
          v.packet_cnt := 0;                        -- Reset the counter
253
        end if;
254
 
255
        if(in_val = '0') then                       -- If there is no more data:
256
          v.state := s_hold;                        -- go wait in the s_hold state
257
        end if;
258
 
259
      when s_hold =>
260
        if(in_val = '1') then                       -- Wait until new valid data arrives
261
          v.state := s_run;
262
        end if;
263
 
264
            when others =>
265
              v.state := s_idle;
266
 
267
          end case;
268
 
269
    if(rst = '1') then
270
      v.out_sosi_arr  := (others => c_dp_sosi_rst);
271
      v.val_dly       := (others => '0');
272
      v.sop_dly       := (others => '0');
273
      v.eop_dly       := (others => '0');
274
      v.sync_detected := '0';
275
      v.packet_cnt    := 0;
276
      v.state         := s_idle;
277
    end if;
278
 
279
    rin <= v;
280
 
281
  end process comb;
282
 
283
  regs : process(clk)
284
  begin
285
    if rising_edge(clk) then
286
      r <= rin;
287
    end if;
288
  end process;
289
 
290
  -- Connect to the outside world  
291
  gen_output : for I in g_nof_ffts*g_fft.wb_factor-1 downto 0 generate
292
    out_sosi_arr(I) <= r.out_sosi_arr(I);
293
  end generate;
294
 
295
end rtl;
296
 
297
 

powered by: WebSVN 2.1.0

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