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

Subversion Repositories astron_diagnostics

[/] [astron_diagnostics/] [trunk/] [mms_diag_block_gen.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
-- Purpose: Block generator for multiple parallel SOSI streams
22
-- Description:
23
-- . The mms_diag_block_gen provides a MM slave interface to an array of
24
--   g_nof_streams diag_block_gen instances.
25
-- . The waveform data is stored in RAM and can be pre-load with data from a
26
--   file g_file_name_prefix. The stream index to the select the actual file
27
--   is default I, but can be set via g_file_index_arr(I). The g_file_index_arr
28
--   makes the relation between the instance index and file index flexible.
29
 
30
-- . g_use_usr_input and g_use_bg
31
--   When g_use_usr_input=FALSE the BG works standalone.
32
--   When g_use_bg=FALSE then only the user input is used.
33
--   When both g_use_usr_input=TRUE and g_use_bg=TRUE then default the user
34
--   input is passed on when the BG is disabled. The dynamic selection between
35
--   user input an BG output is done between blocks by the dp_mux using xon.
36
--
37
-- . g_use_bg_buffer_ram
38
--   When g_use_bg_buffer_ram=TRUE then each stream has a BG buffer RAM that
39
--   can be accessed via the ram_bg_data MM port. Else when
40
--   g_use_bg_buffer_ram= FALSE then the RAM is not implemented (to save
41
--   RAM resources) and instead the RAM read address is used as data in the
42
--   generated data block. Hence the data will then depend on mem_low_adrs,
43
--   mem_high_adrs and samples_per_packet, so typically it will output the
44
--   counter data (0:samples_per_packet-1) and the samedata foreach block.
45
--
46
-- . g_use_tx_seq
47
--   When g_use_tx_seq=TRUE then the diag_mms_tx_seq is instantiated. If the
48
--   tx_seq is enabled then the data field is overwitten with tx seq counter
49
--   or pseudo random data. The tx seq uses the valid as request for tx seq
50
--   data, so it preserves the output valid, sop, eop framing. For more info
51
--   on the tx_seq see mms_diag_tx_seq. If g_use_usr_input=FALSE and g_use_bg
52
--   =FALSE and g_use_tx_seq=TRUE then only the tx_seq is instantiated and
53
--   without input (c_use_tx_seq_input).
54
--
55
-- Block diagram:
56
--
57
--         g_use_bg
58
--         g_use_bg_buffer_ram
59
--          .
60
--          .  g_use_usr_input                     g_use_tx_seq
61
--          .   .     g_usr_bypass_xonoff               .
62
--          .   .      .                                .
63
--          .   .      .                                .
64
--          .   .      .                                .
65
--          .   .      ___     __ dp_mux                .
66
--          .   .     |dp |   |  \                      .
67
--          .  usr----|xon|-->|0  \                     .
68
--          .         |off|   |    \                    .
69
--          .         |___|   |     |----------------->|\ 
70
--          .                 |    /    |              | |---> out
71
--         BG ctrl----------->|1  /     \--> TX seq -->|/
72
--         BG data            |__/             |
73
--            ||                               |
74
--            ||                               |
75
--     MM ====================================================
76
--    
77
--   The dp_mux is only there if both the usr input and the BG are used.
78
--
79
-- Remark:
80
-- . The diag_block_gen does not support back pressure, but it does support
81
--   XON/XOFF flow control at block level via out_siso.xon.
82
-- . Default input *_mosi = c_mem_mosi_rst to support using the BG with default
83
--   control and memory settings and no MM interface
84
-- . The BG does support xon flow control.
85
-- . If the user input already supports xon then g_usr_bypass_xonoff can be
86
--   set to TRUE. However if g_usr_bypass_xonoff=FALSE then this is fine to
87
--   because an extra dp_xonoff stage merely causes the stream to resume one
88
--   block later when xon goes active (see test bench tb_dp_xonoff). The
89
--   diag_block_gen BG does already support xon.
90
-- . A nice new feature would be to support BG data width > 32b, similar as in
91
--   the DB mms_diag_data_buffer.vhd.
92
-- . A nice new feature would be to support a BG burst of N blocks.
93
 
94
 
95 4 danv
LIBRARY IEEE, common_pkg_lib, astron_ram_lib, dp_pkg_lib, dp_components_lib, astron_multiplexer_lib, astron_mm_lib;
96 2 danv
USE IEEE.STD_LOGIC_1164.ALL;
97
USE IEEE.NUMERIC_STD.ALL;
98
USE common_pkg_lib.common_pkg.ALL;
99 4 danv
USE astron_ram_lib.common_ram_pkg.ALL;
100 2 danv
USE dp_pkg_lib.dp_stream_pkg.ALL;
101
USE work.diag_pkg.ALL;
102 4 danv
--USE technology_lib.technology_select_pkg.ALL;
103 2 danv
 
104
ENTITY mms_diag_block_gen IS
105
  GENERIC (
106 4 danv
    g_technology         : NATURAL := 0;
107 2 danv
    -- Generate configurations
108
    g_use_usr_input      : BOOLEAN := FALSE;
109
    g_use_bg             : BOOLEAN := TRUE;
110
    g_use_tx_seq         : BOOLEAN := FALSE;
111
    -- General
112
    g_nof_streams        : POSITIVE := 1;
113
    -- BG settings
114
    g_use_bg_buffer_ram  : BOOLEAN := TRUE;
115
    g_buf_dat_w          : POSITIVE := 32;
116
    g_buf_addr_w         : POSITIVE := 7;                -- Waveform buffer size 2**g_buf_addr_w nof samples
117
    g_file_index_arr     : t_nat_natural_arr := array_init(0, 128, 1);  -- default use the instance index as file index 0, 1, 2, 3, 4 ...
118
    g_file_name_prefix   : STRING := "data/bf_in_data";  -- Path to the hex files that contain the initial data for the memories. The sequence number and ".hex" are added within the entity.
119
    g_diag_block_gen_rst : t_diag_block_gen := c_diag_block_gen_rst;
120
    -- User input multiplexer option
121
    g_usr_bypass_xonoff  : BOOLEAN := FALSE;
122
    -- Tx_seq
123
    g_seq_dat_w          : NATURAL := 32;  -- >= 1, test sequence data width. Choose g_seq_dat_w <= g_buf_dat_w
124
    -- LOFAR Lofar style block sync that is active from SOP to EOP
125
    g_blk_sync           : BOOLEAN := FALSE
126
  );
127
  PORT (
128
    -- System
129
    mm_rst           : IN  STD_LOGIC;                     -- reset synchronous with mm_clk
130
    mm_clk           : IN  STD_LOGIC;                     -- memory-mapped bus clock
131
    dp_rst           : IN  STD_LOGIC;                     -- reset synchronous with st_clk
132
    dp_clk           : IN  STD_LOGIC;                     -- streaming clock domain clock
133
    en_sync          : IN  STD_LOGIC := '1';              -- block generator enable sync pulse in ST dp_clk domain
134
    -- MM interface
135
    reg_bg_ctrl_mosi : IN  t_mem_mosi := c_mem_mosi_rst;  -- BG control register (one for all streams)
136
    reg_bg_ctrl_miso : OUT t_mem_miso;
137
    ram_bg_data_mosi : IN  t_mem_mosi := c_mem_mosi_rst;  -- BG buffer RAM (one per stream)
138
    ram_bg_data_miso : OUT t_mem_miso;
139
    reg_tx_seq_mosi  : IN  t_mem_mosi := c_mem_mosi_rst;  -- Tx seq control (one per stream because c_reg_tx_seq_broadcast=FALSE)
140
    reg_tx_seq_miso  : OUT t_mem_miso;
141
    -- ST interface
142
    usr_siso_arr     : OUT t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);  -- connect when g_use_usr_input=TRUE, else leave not connected 
143
    usr_sosi_arr     : IN  t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst);
144
    out_siso_arr     : IN  t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy);  -- Default xon='1'
145
    out_sosi_arr     : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0)  -- Output SOSI that contains the waveform data
146
  );
147
END mms_diag_block_gen;
148
 
149
ARCHITECTURE rtl OF mms_diag_block_gen IS
150
 
151
  CONSTANT c_buf                  : t_c_mem  := (latency  => 1,
152
                                                 adr_w    => g_buf_addr_w,
153
                                                 dat_w    => g_buf_dat_w,
154
                                                 nof_dat  => 2**g_buf_addr_w,
155
                                                 init_sl  => '0');
156
 
157
  CONSTANT c_post_buf_file        : STRING := ".hex";
158
 
159
  CONSTANT c_use_mux              : BOOLEAN := g_use_usr_input AND g_use_bg;
160
  CONSTANT c_use_tx_seq_input     : BOOLEAN := g_use_usr_input OR g_use_bg;
161
  CONSTANT c_mux_nof_input        : NATURAL := 2;   -- fixed
162
 
163
  CONSTANT c_reg_tx_seq_broadcast : BOOLEAN := FALSE;  -- fixed use dedicated MM register per stream
164
 
165
  TYPE t_buf_dat_arr IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(g_buf_dat_w -1 DOWNTO 0);
166
  TYPE t_buf_adr_arr IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(g_buf_addr_w-1 DOWNTO 0);
167
 
168
  SIGNAL st_addr_arr           : t_buf_adr_arr(g_nof_streams    -1 DOWNTO 0);
169
  SIGNAL st_rd_arr             : STD_LOGIC_VECTOR(g_nof_streams -1 DOWNTO 0);
170
  SIGNAL st_rdval_arr          : STD_LOGIC_VECTOR(g_nof_streams -1 DOWNTO 0);
171
  SIGNAL st_rddata_arr         : t_buf_dat_arr(g_nof_streams    -1 DOWNTO 0);
172
  SIGNAL ram_bg_data_mosi_arr  : t_mem_mosi_arr(g_nof_streams   -1 DOWNTO 0);
173
  SIGNAL ram_bg_data_miso_arr  : t_mem_miso_arr(g_nof_streams   -1 DOWNTO 0);
174
  SIGNAL bg_ctrl               : t_diag_block_gen;
175
 
176
  SIGNAL mux_ctrl              : NATURAL RANGE 0 TO c_mux_nof_input-1;
177
  SIGNAL mux_snk_out_2arr_2    : t_dp_siso_2arr_2(g_nof_streams-1 DOWNTO 0);  -- [g_nof_streams-1:0][c_mux_nof_input-1:0] = [1:0]
178
  SIGNAL mux_snk_in_2arr_2     : t_dp_sosi_2arr_2(g_nof_streams-1 DOWNTO 0);  -- [g_nof_streams-1:0][c_mux_nof_input-1:0] = [1:0]
179
 
180
  SIGNAL usr_xflow_src_in_arr  : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);  -- optionally use dp_xonoff to add siso.xon flow control to use input when g_usr_bypass_xonoff=FALSE
181
  SIGNAL usr_xflow_src_out_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
182
 
183
  SIGNAL bg_src_in_arr         : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);  -- BG has siso.xon flow control but no siso.ready flow control
184
  SIGNAL bg_src_out_arr        : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
185
 
186
  SIGNAL mux_src_in_arr        : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
187
  SIGNAL mux_src_out_arr       : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
188
 
189
BEGIN
190
 
191
  -----------------------------------------------------------------------------
192
  -- BG
193
  -----------------------------------------------------------------------------
194
 
195
  no_bg : IF g_use_bg=FALSE GENERATE
196
    reg_bg_ctrl_miso <= c_mem_miso_rst;
197
    ram_bg_data_miso <= c_mem_miso_rst;
198
 
199
    bg_src_out_arr <= (OTHERS=>c_dp_sosi_rst);
200
  END GENERATE;
201
 
202
  gen_bg : IF g_use_bg=TRUE GENERATE
203
    mux_ctrl <= 0 WHEN bg_ctrl.enable='0' ELSE 1;
204
 
205
    u_bg_ctrl : ENTITY work.diag_block_gen_reg
206
    GENERIC MAP(
207
      g_cross_clock_domain => TRUE,   -- use FALSE when mm_clk and st_clk are the same, else use TRUE to cross the clock domain
208
      g_diag_block_gen_rst => g_diag_block_gen_rst
209
    )
210
    PORT MAP (
211
      mm_rst  => mm_rst,                   -- Clocks and reset
212
      mm_clk  => mm_clk,
213
      dp_rst  => dp_rst,
214
      dp_clk  => dp_clk,
215
      mm_mosi => reg_bg_ctrl_mosi,
216
      mm_miso => reg_bg_ctrl_miso,
217
      bg_ctrl => bg_ctrl
218
    );
219
 
220
    -- Combine the internal array of mm interfaces for the bg_data to one array that is connected to the port of the MM bus
221 4 danv
    u_mem_mux_bg_data : ENTITY astron_mm_lib.common_mem_mux
222 2 danv
    GENERIC MAP (
223
      g_nof_mosi    => g_nof_streams,
224
      g_mult_addr_w => g_buf_addr_w
225
    )
226
    PORT MAP (
227
      mosi     => ram_bg_data_mosi,
228
      miso     => ram_bg_data_miso,
229
      mosi_arr => ram_bg_data_mosi_arr,
230
      miso_arr => ram_bg_data_miso_arr
231
    );
232
 
233
    gen_streams : FOR I IN 0 TO g_nof_streams-1 GENERATE
234
      no_buffer_ram : IF g_use_bg_buffer_ram=FALSE GENERATE
235
        ram_bg_data_miso_arr(I) <= c_mem_miso_rst;
236
 
237
        -- Use read address as read data with read latency 1 similar as for u_buffer_ram
238
        st_rdval_arr(I)  <=             st_rd_arr(I)                 WHEN rising_edge(dp_clk);
239
        st_rddata_arr(I) <= RESIZE_UVEC(st_addr_arr(I), g_buf_dat_w) WHEN rising_edge(dp_clk);
240
      END GENERATE;
241
 
242
      gen_buffer_ram : IF g_use_bg_buffer_ram=TRUE GENERATE
243 4 danv
        u_buffer_ram : ENTITY astron_ram_lib.common_ram_crw_crw
244 2 danv
        GENERIC MAP (
245
          g_technology => g_technology,
246
          g_ram        => c_buf,
247
          -- Sequence number and ".hex" extension are added to the relative path in case a ram file is provided. 
248
          g_init_file  => sel_a_b(g_file_name_prefix = "UNUSED", g_file_name_prefix, g_file_name_prefix & "_" & NATURAL'IMAGE(g_file_index_arr(I)) & c_post_buf_file)
249
        )
250
        PORT MAP (
251
          -- MM side
252
          rst_a     => mm_rst,
253
          clk_a     => mm_clk,
254
          wr_en_a   => ram_bg_data_mosi_arr(I).wr,
255
          wr_dat_a  => ram_bg_data_mosi_arr(I).wrdata(c_buf.dat_w -1 DOWNTO 0),
256
          adr_a     => ram_bg_data_mosi_arr(I).address(c_buf.adr_w-1 DOWNTO 0),
257
          rd_en_a   => ram_bg_data_mosi_arr(I).rd,
258
          rd_dat_a  => ram_bg_data_miso_arr(I).rddata(c_buf.dat_w -1 DOWNTO 0),
259
          rd_val_a  => ram_bg_data_miso_arr(I).rdval,
260
          -- Waveform side
261
          rst_b     => dp_rst,
262
          clk_b     => dp_clk,
263
          wr_en_b   => '0',
264
          wr_dat_b  => (OTHERS =>'0'),
265
          adr_b     => st_addr_arr(I),
266
          rd_en_b   => st_rd_arr(I),
267
          rd_dat_b  => st_rddata_arr(I),
268
          rd_val_b  => st_rdval_arr(I)
269
        );
270
      END GENERATE;
271
 
272
      u_diag_block_gen : ENTITY work.diag_block_gen
273
      GENERIC MAP (
274
        g_blk_sync   => g_blk_sync,
275
        g_buf_dat_w  => g_buf_dat_w,
276
        g_buf_addr_w => g_buf_addr_w
277
      )
278
      PORT MAP (
279
        rst        => dp_rst,
280
        clk        => dp_clk,
281
        buf_addr   => st_addr_arr(I),
282
        buf_rden   => st_rd_arr(I),
283
        buf_rddat  => st_rddata_arr(I),
284
        buf_rdval  => st_rdval_arr(I),
285
        ctrl       => bg_ctrl,
286
        en_sync    => en_sync,
287
        out_siso   => bg_src_in_arr(I),
288
        out_sosi   => bg_src_out_arr(I)
289
      );
290
    END GENERATE;
291
  END GENERATE;
292
 
293
 
294
  ---------------------------------------------------------------------------
295
  -- No multiplexer, so only one input or no input at all
296
  ---------------------------------------------------------------------------
297
  no_dp_mux : IF c_use_mux=FALSE GENERATE  -- so g_use_usr_input and g_use_bg are not both TRUE
298
    -- default pass on flow control
299
    usr_siso_arr  <= mux_src_in_arr;
300
    bg_src_in_arr <= mux_src_in_arr;
301
 
302
    -- User input only, BG only or no input
303
    mux_src_out_arr <= usr_sosi_arr             WHEN g_use_usr_input=TRUE ELSE
304
                       bg_src_out_arr           WHEN g_use_bg=TRUE        ELSE
305
                      (OTHERS=>c_dp_sosi_rst);
306
  END GENERATE;
307
 
308
 
309
  -----------------------------------------------------------------------------
310
  -- Multiplex user input and BG
311
  -----------------------------------------------------------------------------
312
  gen_dp_mux : IF c_use_mux=TRUE GENERATE  -- so g_use_usr_input and g_use_bg are both TRUE
313
    gen_streams : FOR I IN 0 TO g_nof_streams-1 GENERATE
314
      -- Add user xon flow control if the user input does not already support it
315
      u_dp_xonoff : ENTITY dp_components_lib.dp_xonoff
316
      GENERIC MAP (
317
        g_bypass => g_usr_bypass_xonoff  -- if the user input already has xon flow control then bypass using g_usr_bypass_xonoff=TRUE
318
      )
319
      PORT MAP (
320
        rst           => dp_rst,
321
        clk           => dp_clk,
322
        -- Frame in
323
        in_siso       => usr_siso_arr(I),
324
        in_sosi       => usr_sosi_arr(I),
325
        -- Frame out
326
        out_siso      => usr_xflow_src_in_arr(I),  -- flush control via out_siso.xon
327
        out_sosi      => usr_xflow_src_out_arr(I)
328
      );
329
 
330
      -- Multiplex the inputs:
331
      -- . [0] = usr input
332
      -- . [1] = BG
333
      usr_xflow_src_in_arr(I) <= mux_snk_out_2arr_2(I)(0);
334
      bg_src_in_arr(I)        <= mux_snk_out_2arr_2(I)(1);
335
 
336
      mux_snk_in_2arr_2(I)(0) <= usr_xflow_src_out_arr(I);
337
      mux_snk_in_2arr_2(I)(1) <= bg_src_out_arr(I);
338
 
339 4 danv
      u_dp_mux : ENTITY astron_multiplexer_lib.dp_mux
340 2 danv
      GENERIC MAP (
341
        g_technology        => g_technology,
342
        -- MUX
343
        g_mode              => 4,                                 -- g_mode=4 for framed input select via sel_ctrl
344
        g_nof_input         => c_mux_nof_input,                   -- >= 1
345
        g_append_channel_lo => FALSE,
346
        g_sel_ctrl_invert   => TRUE,  -- Use default FALSE when stream array IO are indexed (0 TO g_nof_input-1), else use TRUE when indexed (g_nof_input-1 DOWNTO 0)
347
        -- Input FIFO
348
        g_use_fifo          => FALSE,
349
        g_fifo_size         => array_init(1024, c_mux_nof_input),  -- must match g_nof_input, even when g_use_fifo=FALSE
350
        g_fifo_fill         => array_init(   0, c_mux_nof_input)   -- must match g_nof_input, even when g_use_fifo=FALSE
351
      )
352
      PORT MAP (
353
        rst         => dp_rst,
354
        clk         => dp_clk,
355
        -- Control
356
        sel_ctrl    => mux_ctrl,  -- 0 = usr, 1 = BG
357
        -- ST sinks
358
        snk_out_arr => mux_snk_out_2arr_2(I),  -- [c_mux_nof_input-1:0]
359
        snk_in_arr  => mux_snk_in_2arr_2(I),   -- [c_mux_nof_input-1:0]
360
        -- ST source
361
        src_in      => mux_src_in_arr(I),
362
        src_out     => mux_src_out_arr(I)
363
      );
364
    END GENERATE;
365
  END GENERATE;
366
 
367
  no_tx_seq : IF g_use_tx_seq=FALSE GENERATE
368
    reg_tx_seq_miso <= c_mem_miso_rst;
369
 
370
    mux_src_in_arr <= out_siso_arr;
371
    out_sosi_arr   <= mux_src_out_arr;
372
  END GENERATE;
373
 
374
  gen_tx_seq : IF g_use_tx_seq=TRUE GENERATE
375
    u_mms_diag_tx_seq : ENTITY work.mms_diag_tx_seq
376
    GENERIC MAP (
377
      g_use_usr_input => c_use_tx_seq_input,
378
      g_mm_broadcast  => c_reg_tx_seq_broadcast,
379
      g_nof_streams   => g_nof_streams,
380
      g_seq_dat_w     => g_seq_dat_w
381
    )
382
    PORT MAP (
383
      -- Clocks and reset
384
      mm_rst         => mm_rst,
385
      mm_clk         => mm_clk,
386
      dp_rst         => dp_rst,
387
      dp_clk         => dp_clk,
388
 
389
      -- MM interface
390
      reg_mosi       => reg_tx_seq_mosi,
391
      reg_miso       => reg_tx_seq_miso,
392
 
393
      -- DP streaming interface
394
      usr_snk_out_arr => mux_src_in_arr,  -- connect when g_use_usr_input=TRUE, else leave not connected
395
      usr_snk_in_arr  => mux_src_out_arr,
396
      tx_src_out_arr  => out_sosi_arr,
397
      tx_src_in_arr   => out_siso_arr
398
    );
399
  END GENERATE;
400
 
401
END rtl;

powered by: WebSVN 2.1.0

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