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

Subversion Repositories astron_statistics

[/] [astron_statistics/] [trunk/] [st_sst.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) 2011
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
 
22
LIBRARY IEEE, common_pkg_lib, common_ram_lib, common_counter_lib, mm_lib, technology_lib, dp_pkg_lib;
23
USE IEEE.std_logic_1164.ALL;
24
USE common_pkg_lib.common_pkg.ALL;
25
USE common_ram_lib.common_ram_pkg.ALL;
26
USE mm_lib.common_field_pkg.ALL;
27
USE dp_pkg_lib.dp_stream_pkg.ALL;
28
USE technology_lib.technology_select_pkg.ALL;
29
 
30
-- Purpose:
31
--   Store the (auto)power statistics of a complex input stream with
32
--   blocks of nof_stat multiplexed subbands into a MM register.
33
-- Description:                                                          
34
--
35
--   When the treshold register is set to 0 the statistics will be auto-
36
--   correlations.
37
--   In case the treshold register is set to a non-zero value, it allows
38
--   to create a sample & hold function for the a-input of the multiplier.
39
--   The a-input of the multiplier is updated every "treshold" clockcycle.
40
--   Thereby cross statistics can be created.  
41
--  
42
--   After each sync the MM register gets updated with the (auto) power statistics
43
--   of the previous sync interval. The length of the sync interval determines
44
--   the nof accumlations per statistic, hence the integration time. See st_calc
45
--   for more details.
46
-- Remarks:
47
-- . The in_sync is assumed to be a pulse an interpreted directly.
48
-- . The MM register is single page RAM to save memory resources. Therefore
49
--   just after the sync its contents is undefined when it gets written, but
50
--   after that its contents remains stable for the rest of the sync interval.
51
--   Therefore it is not necessary to use a dual page register that swaps at
52
--   the sync. 
53
-- . The minimum g_nof_stat = 8. Lower values lead to simulation errors. This is
54
--   due to the read latency of 2 of the accumulation memory in the st_calc entity. 
55
 
56
ENTITY st_sst IS
57
  GENERIC (
58
    g_technology    : NATURAL := c_tech_select_default;
59
    g_nof_stat      : NATURAL := 512;   -- nof accumulators
60
    g_xst_enable    : BOOLEAN := FALSE; -- when set to true, an extra memory is instantiated to hold the imaginary part of the cross-correlation results
61
    g_in_data_w     : NATURAL := 18;    -- width o dth edata to be accumulated
62
    g_stat_data_w   : NATURAL := 54;    -- statistics accumulator width
63
    g_stat_data_sz  : NATURAL := 2      -- statistics word width >= statistics accumulator width and fit in a power of 2 multiple 32b MM words
64
  );
65
  PORT (
66
    mm_rst          : IN  STD_LOGIC;
67
    mm_clk          : IN  STD_LOGIC;
68
    dp_rst          : IN  STD_LOGIC;
69
    dp_clk          : IN  STD_LOGIC;
70
 
71
    -- Streaming    
72
    in_complex      : IN  t_dp_sosi;   -- Complex input data
73
 
74
    -- Memory Mapped
75
    ram_st_sst_mosi : IN  t_mem_mosi;
76
    ram_st_sst_miso : OUT t_mem_miso;
77
    reg_st_sst_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
78
    reg_st_sst_miso : OUT t_mem_miso := c_mem_miso_rst
79
  );
80
END st_sst;
81
 
82
 
83
ARCHITECTURE str OF st_sst IS
84
 
85
  CONSTANT c_nof_stat_w   : NATURAL := ceil_log2(g_nof_stat);
86
  CONSTANT c_nof_word     : NATURAL := g_stat_data_sz*g_nof_stat;
87
  CONSTANT c_nof_word_w   : NATURAL := ceil_log2(c_nof_word);
88
  CONSTANT g_stat_word_w  : NATURAL := g_stat_data_sz*c_word_w;
89
  CONSTANT zeros          : STD_LOGIC_VECTOR(c_nof_stat_w-1 DOWNTO 0) := (OTHERS => '0');
90
 
91
  -- Statistics register
92
  CONSTANT c_mm_ram       : t_c_mem := (latency  => 1,
93
                                        adr_w    => c_nof_word_w,
94
                                        dat_w    => c_word_w,
95
                                        nof_dat  => c_nof_word,
96
                                        init_sl  => '0');           -- MM side : sla_in, sla_out
97
  CONSTANT c_stat_ram     : t_c_mem := (latency  => 1,
98
                                        adr_w    => c_nof_stat_w,
99
                                        dat_w    => g_stat_word_w,
100
                                        nof_dat  => g_nof_stat,
101
                                        init_sl  => '0');           -- ST side : stat_mosi
102
 
103
  CONSTANT c_field_arr : t_common_field_arr(0 DOWNTO 0) := (0=> ( field_name_pad("treshold"), "RW", c_nof_stat_w, field_default(0) ));
104
 
105
  SIGNAL mm_fields_out : STD_LOGIC_VECTOR(field_slv_out_len(c_field_arr)-1 DOWNTO 0);
106
  SIGNAL treshold      : STD_LOGIC_VECTOR(c_nof_stat_w-1 DOWNTO 0);
107
 
108
  TYPE reg_type IS RECORD
109
    in_sosi_reg : t_dp_sosi;
110
    in_a_re     : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO 0);
111
    in_a_im     : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO 0);
112
  END RECORD;
113
 
114
  SIGNAL r, rin       : reg_type;
115
  SIGNAL in_sync      : STD_LOGIC;
116
  SIGNAL stat_data_re : STD_LOGIC_VECTOR(g_stat_data_w-1 DOWNTO 0);
117
  SIGNAL stat_data_im : STD_LOGIC_VECTOR(g_stat_data_w-1 DOWNTO 0);
118
 
119
  SIGNAL wrdata_re    : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);
120
  SIGNAL wrdata_im    : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);
121
 
122
  SIGNAL stat_mosi    : t_mem_mosi;
123
  SIGNAL count        : STD_LOGIC_VECTOR(c_nof_stat_w-1 DOWNTO 0);
124
 
125
  SIGNAL ram_st_sst_mosi_arr : t_mem_mosi_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
126
  SIGNAL ram_st_sst_miso_arr : t_mem_miso_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);
127
 
128
BEGIN
129
 
130
  ------------------------------------------------------------------------------
131
  -- Register map for the treshold register
132
  ------------------------------------------------------------------------------
133
  register_map : ENTITY mm_lib.mm_fields
134
  GENERIC MAP(
135
    g_cross_clock_domain => TRUE,
136
    g_field_arr          => c_field_arr
137
  )
138
  PORT MAP (
139
    mm_rst  => mm_rst,
140
    mm_clk  => mm_clk,
141
 
142
    mm_mosi => reg_st_sst_mosi,
143
    mm_miso => reg_st_sst_miso,
144
 
145
    slv_rst => dp_rst,
146
    slv_clk => dp_clk,
147
 
148
    slv_out => mm_fields_out
149
  );
150
 
151
  treshold <= mm_fields_out(field_hi(c_field_arr, "treshold") DOWNTO field_lo(c_field_arr, "treshold"));
152
 
153
  ------------------------------------------------------------------------------
154
  -- Input registers and preparation of the input data for the multiplier. 
155
  ------------------------------------------------------------------------------
156
  comb : PROCESS(r, dp_rst, in_complex, count, treshold)
157
    VARIABLE v : reg_type;
158
  BEGIN
159
    v               := r;
160
    v.in_sosi_reg   := in_complex;
161
 
162
    IF(count = zeros OR treshold = zeros) THEN
163
      v.in_a_re  := in_complex.re(g_in_data_w-1 DOWNTO 0);
164
      v.in_a_im  := in_complex.im(g_in_data_w-1 DOWNTO 0);
165
    END IF;
166
 
167
    IF(dp_rst = '1') THEN
168
      v.in_a_re := (OTHERS => '0');
169
      v.in_a_im := (OTHERS => '0');
170
    END IF;
171
 
172
    rin             <= v;
173
 
174
  END PROCESS comb;
175
 
176
  regs : PROCESS(dp_clk)
177
  BEGIN
178
    IF rising_edge(dp_clk) THEN
179
      r <= rin;
180
    END IF;
181
  END PROCESS;
182
 
183
  ------------------------------------------------------------------------------
184
  -- Counter used to detect when treshold is reached in order to load new 
185
  -- input vlaues for the multiplier. 
186
  ------------------------------------------------------------------------------
187
  treshold_cnt : ENTITY common_counter_lib.common_counter
188
  GENERIC MAP(
189
    g_latency   => 1,
190
    g_init      => 0,
191
    g_width     => c_nof_stat_w,
192
    g_max       => 0,
193
    g_step_size => 1
194
  )
195
  PORT MAP (
196
    rst     => dp_rst,
197
    clk     => dp_clk,
198
    cnt_clr => in_complex.eop,
199
    cnt_en  => in_complex.valid,
200
    cnt_max => treshold,
201
    count   => count
202
  );
203
 
204
  in_sync <= in_complex.sync;
205
 
206
  st_calc : ENTITY work.st_calc
207
  GENERIC MAP (
208
    g_technology   => g_technology,
209
    g_nof_mux      => 1,
210
    g_nof_stat     => g_nof_stat,
211
    g_in_dat_w     => g_in_data_w,
212
    g_out_dat_w    => g_stat_data_w,
213
    g_out_adr_w    => c_nof_stat_w,
214
    g_complex      => g_xst_enable
215
  )
216
  PORT MAP (
217
    rst            => dp_rst,
218
    clk            => dp_clk,
219
    in_ar          => r.in_a_re,
220
    in_ai          => r.in_a_im,
221
    in_br          => r.in_sosi_reg.re(g_in_data_w-1 DOWNTO 0),
222
    in_bi          => r.in_sosi_reg.im(g_in_data_w-1 DOWNTO 0),
223
    in_val         => r.in_sosi_reg.valid,
224
    in_sync        => in_sync,
225
    out_adr        => stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0),
226
    out_re         => stat_data_re,
227
    out_im         => stat_data_im,
228
    out_val        => stat_mosi.wr,
229
    out_val_m      => OPEN
230
  );
231
 
232
  wrdata_re <= RESIZE_MEM_UDATA(stat_data_re);
233
  wrdata_im <= RESIZE_MEM_UDATA(stat_data_im);
234
 
235
  stat_reg_re : ENTITY common_ram_lib.common_ram_crw_crw_ratio
236
  GENERIC MAP (
237
    g_technology => g_technology,
238
    g_ram_a      => c_mm_ram,
239
    g_ram_b      => c_stat_ram,
240
    g_init_file  => "UNUSED"
241
  )
242
  PORT MAP (
243
    rst_a     => mm_rst,
244
    clk_a     => mm_clk,
245
 
246
    rst_b     => dp_rst,
247
    clk_b     => dp_clk,
248
 
249
    wr_en_a   => ram_st_sst_mosi_arr(0).wr,  -- only for diagnostic purposes, typically statistics are read only
250
    wr_dat_a  => ram_st_sst_mosi_arr(0).wrdata(c_mm_ram.dat_w-1 DOWNTO 0),
251
    adr_a     => ram_st_sst_mosi_arr(0).address(c_mm_ram.adr_w-1 DOWNTO 0),
252
    rd_en_a   => ram_st_sst_mosi_arr(0).rd,
253
    rd_dat_a  => ram_st_sst_miso_arr(0).rddata(c_mm_ram.dat_w-1 DOWNTO 0),
254
    rd_val_a  => ram_st_sst_miso_arr(0).rdval,
255
 
256
    wr_en_b   => stat_mosi.wr,
257
    wr_dat_b  => wrdata_re(c_stat_ram.dat_w-1 DOWNTO 0),
258
    adr_b     => stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0),
259
    rd_en_b   => '0',
260
    rd_dat_b  => OPEN,
261
    rd_val_b  => OPEN
262
  );
263
 
264
  gen_re: IF g_xst_enable=FALSE GENERATE
265
    ram_st_sst_mosi_arr(0) <= ram_st_sst_mosi;
266
    ram_st_sst_miso        <= ram_st_sst_miso_arr(0);
267
  END GENERATE;
268
 
269
  gen_im: IF g_xst_enable=TRUE GENERATE
270
    ---------------------------------------------------------------
271
    -- COMBINE MEMORY MAPPED INTERFACES
272
    ---------------------------------------------------------------
273
    -- Combine the internal array of mm interfaces for both real
274
    -- and imaginary part. 
275
    u_mem_mux_select : entity mm_lib.common_mem_mux
276
    generic map (
277
      g_nof_mosi    => c_nof_complex,
278
      g_mult_addr_w => c_nof_word_w
279
    )
280
    port map (
281
      mosi     => ram_st_sst_mosi,
282
      miso     => ram_st_sst_miso,
283
      mosi_arr => ram_st_sst_mosi_arr,
284
      miso_arr => ram_st_sst_miso_arr
285
    );
286
 
287
    stat_reg_im : ENTITY common_ram_lib.common_ram_crw_crw_ratio
288
    GENERIC MAP (
289
      g_technology => g_technology,
290
      g_ram_a      => c_mm_ram,
291
      g_ram_b      => c_stat_ram,
292
      g_init_file  => "UNUSED"
293
    )
294
    PORT MAP (
295
      rst_a     => mm_rst,
296
      clk_a     => mm_clk,
297
 
298
      rst_b     => dp_rst,
299
      clk_b     => dp_clk,
300
 
301
      wr_en_a   => ram_st_sst_mosi_arr(1).wr,  -- only for diagnostic purposes, typically statistics are read only
302
      wr_dat_a  => ram_st_sst_mosi_arr(1).wrdata(c_mm_ram.dat_w-1 DOWNTO 0),
303
      adr_a     => ram_st_sst_mosi_arr(1).address(c_mm_ram.adr_w-1 DOWNTO 0),
304
      rd_en_a   => ram_st_sst_mosi_arr(1).rd,
305
      rd_dat_a  => ram_st_sst_miso_arr(1).rddata(c_mm_ram.dat_w-1 DOWNTO 0),
306
      rd_val_a  => ram_st_sst_miso_arr(1).rdval,
307
 
308
      wr_en_b   => stat_mosi.wr,
309
      wr_dat_b  => wrdata_im(c_stat_ram.dat_w-1 DOWNTO 0),
310
      adr_b     => stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0),
311
      rd_en_b   => '0',
312
      rd_dat_b  => OPEN,
313
      rd_val_b  => OPEN
314
    );
315
 
316
  END GENERATE;
317
 
318
END str;

powered by: WebSVN 2.1.0

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