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 5

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

powered by: WebSVN 2.1.0

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