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 4

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

powered by: WebSVN 2.1.0

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