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

powered by: WebSVN 2.1.0

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