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

Subversion Repositories astron_mm

[/] [astron_mm/] [trunk/] [tb_mm_file.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
-- Author:
22
--   D. van der Schuur  May 2012  Original with manual file IO using an editor.
23
--   E. Kooistra        Feb 2017  Added purpose and description
24
--                                Added external control by p_mm_stimuli and
25
--                                p_sim_stimuli
26
-- Purpose: Testbench for MM and simulation control via file io
27
-- Description:
28
--   This testbench verifies mm_file and mm_file_pkg.
29
--   1) p_mm_stimuli
30
--     The p_mm_stimuli uses mmf_mm_bus_wr() and mmf_mm_bus_rd() to access a MM
31
--     slave register instance of common_reg_r_w_dc via mm_file using a MM slave
32
--     .ctrl and .stat file. The p_mm_stimuli verifies the W/R accesses.
33
--   2) p_sim_stimuli
34
--     The p_sim_stimuli waits for get_now and then it uses mmf_sim_get_now() to
35
--     read the simulator status via mmf_poll_sim_ctrl_file() using a sim.ctrl
36
--     and sim.stat file. The p_sim_stimuli does not verify read rd_now value,
37
--     but it does print it.
38
-- Usage:
39
--   > as 5
40
--   > run -all
41
--   The tb is self stopping and self checking. 
42
--   For example observe mm_mosi, mm_miso, rd_now and out_reg_arr in wave window.
43
 
44 4 danv
LIBRARY IEEE, common_pkg_lib, astron_ram_lib;
45 2 danv
USE IEEE.std_logic_1164.ALL;
46
USE IEEE.numeric_std.ALL;
47
USE common_pkg_lib.common_pkg.ALL;
48 4 danv
USE astron_ram_lib.common_ram_pkg.ALL;
49 2 danv
USE common_pkg_lib.common_str_pkg.ALL;
50
USE common_pkg_lib.tb_common_pkg.ALL;
51
USE work.mm_file_pkg.ALL;
52
 
53
ENTITY tb_mm_file IS
54
  GENERIC (
55
    g_tb_index           : NATURAL := 0;
56
    g_mm_nof_accesses    : NATURAL := 100;
57
    g_mm_timeout         : TIME := 0 ns;--100 ns;   -- default 0 ns for full speed MM, use > 0 to define number of mm_clk without MM access after which the MM file IO is paused
58
    g_mm_pause           : TIME := 1000 ns;  -- defines the time for which MM file IO is paused to reduce the file IO rate when the MM slave is idle
59
    g_timeout_gap        : INTEGER := -1;--4;    -- no gap when < 0, else force MM access gap after g_timeout_gap wr or rd strobes
60
    g_cross_clock_domain : BOOLEAN := FALSE --TRUE
61
  );
62
END tb_mm_file;
63
 
64
ARCHITECTURE tb OF tb_mm_file IS
65
 
66
  CONSTANT c_mm_clk_period            : TIME := c_mmf_mm_clk_period;  -- = 100 ps;
67
  CONSTANT c_mm_nof_dat               : NATURAL := smallest(c_mem_reg_init_w/c_32, g_mm_nof_accesses);
68
  CONSTANT c_mm_rd_latency            : NATURAL := 2;
69
 
70
  CONSTANT c_cross_nof_mm_clk         : NATURAL := sel_a_b(g_cross_clock_domain, 100, 0);  -- > 2*24 see common_reg_cross_domain, factor 2 for W/R
71
 
72
  -- Determine node mm_file prefix based on --unb --gn (similar as done in mmf_unb_file_prefix())
73
  CONSTANT c_unb_nr                   : NATURAL := 3;  --unb
74
  CONSTANT c_pn_nr                    : NATURAL := 1;  --gn = 0:7
75
  CONSTANT c_node_type                : STRING(1 TO 2):= sel_a_b(c_pn_nr<4, "FN", "BN");
76
  CONSTANT c_node_nr                  : NATURAL := sel_a_b(c_node_type="BN", c_pn_nr-4, c_pn_nr);
77
 
78
  -- Use local mmfiles/ subdirectory in mm project build directory
79
  CONSTANT c_sim_file_pathname        : STRING := mmf_slave_prefix("TB", g_tb_index) & "sim";
80
  CONSTANT c_reg_r_w_dc_file_pathname : STRING := mmf_slave_prefix("TB", g_tb_index, "UNB", c_unb_nr, c_node_type, c_node_nr) & "REG_R_W_DC";
81
 
82
  --TYPE t_c_mem IS RECORD
83
  --  latency   : NATURAL;    -- read latency
84
  --  adr_w     : NATURAL;
85
  --  dat_w     : NATURAL;
86
  --  nof_dat   : NATURAL;    -- optional, nof dat words <= 2**adr_w
87
  --  init_sl   : STD_LOGIC;  -- optional, init all dat words to std_logic '0', '1' or 'X'
88
  --  --init_file : STRING;     -- "UNUSED", unconstrained length can not be in record
89
  --END RECORD;
90
  CONSTANT c_mem_reg            : t_c_mem := (c_mm_rd_latency, ceil_log2(c_mm_nof_dat), c_32, c_mm_nof_dat, '0');
91
 
92
  SIGNAL tb_state           : STRING(1 TO 5) := "Init ";
93
  SIGNAL tb_end             : STD_LOGIC := '0';
94
  SIGNAL mm_clk             : STD_LOGIC := '0';
95
  SIGNAL mm_rst             : STD_LOGIC;
96
 
97
  SIGNAL get_now            : STD_LOGIC := '0';
98
  SIGNAL rd_now             : STRING(1 TO 16);  -- sufficient to fit TIME NOW in ns as a string
99
 
100
  SIGNAL mm_mosi            : t_mem_mosi;
101
  SIGNAL mm_miso            : t_mem_miso;
102
  SIGNAL file_wr_data       : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0);
103
  SIGNAL file_rd_data       : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0);
104
 
105
  SIGNAL reg_wr_arr         : STD_LOGIC_VECTOR(     c_mem_reg.nof_dat-1 DOWNTO 0);
106
  SIGNAL reg_rd_arr         : STD_LOGIC_VECTOR(     c_mem_reg.nof_dat-1 DOWNTO 0);
107
  SIGNAL in_new             : STD_LOGIC := '1';
108
  SIGNAL in_reg             : STD_LOGIC_VECTOR(c_32*c_mem_reg.nof_dat-1 DOWNTO 0);
109
  SIGNAL out_reg            : STD_LOGIC_VECTOR(c_32*c_mem_reg.nof_dat-1 DOWNTO 0);
110
  SIGNAL out_new            : STD_LOGIC;    -- Pulses '1' when new data has been written.
111
 
112
  SIGNAL out_reg_arr        : t_slv_32_arr(c_mem_reg.nof_dat-1 DOWNTO 0);
113
 
114
BEGIN
115
 
116
  mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2;
117
  mm_rst <= '1', '0' AFTER c_mm_clk_period*10;
118
 
119
  -- DUT mm access files 'c_reg_r_w_dc_file_pathname'.ctrl and 'c_reg_r_w_dc_file_pathname'.stat
120
  p_mm_stimuli : PROCESS
121
    VARIABLE v_addr : NATURAL;
122
  BEGIN
123
    proc_common_wait_until_low(mm_clk, mm_rst);
124
    proc_common_wait_some_cycles(mm_clk, 3);
125
 
126
    -- Write all nof_dat once
127
    tb_state <= "Write";
128
    FOR I IN 0 TO c_mm_nof_dat-1 LOOP
129
      IF I=g_timeout_gap THEN
130
        WAIT FOR 2*c_mmf_mm_timeout;
131
      END IF;
132
      file_wr_data <= TO_UVEC(I, c_32);
133
      mmf_mm_bus_wr(c_reg_r_w_dc_file_pathname, I, I, mm_clk);
134
    END LOOP;
135
 
136
    proc_common_wait_some_cycles(mm_clk, c_cross_nof_mm_clk);
137
 
138
    -- Read all nof_dat once
139
    tb_state <= "Read ";
140
    FOR I IN 0 TO c_mm_nof_dat-1 LOOP
141
      IF I=g_timeout_gap THEN
142
        WAIT FOR 2*c_mmf_mm_timeout;
143
      END IF;
144
      mmf_mm_bus_rd(c_reg_r_w_dc_file_pathname, c_mem_reg.latency, I, file_rd_data, mm_clk);
145
      ASSERT I=TO_UINT(file_rd_data) REPORT "Read data is wrong." SEVERITY ERROR;
146
    END LOOP;
147
 
148
    -- Write/Read
149
    tb_state <= "Both ";
150
    FOR I IN 0 TO g_mm_nof_accesses-1 LOOP
151
      IF I=g_timeout_gap THEN
152
        WAIT FOR 2*c_mmf_mm_timeout;
153
      END IF;
154
      file_wr_data <= TO_UVEC(I, c_32);
155
      v_addr := I MOD c_mm_nof_dat;
156
      mmf_mm_bus_wr(c_reg_r_w_dc_file_pathname, v_addr, I, mm_clk);
157
      proc_common_wait_some_cycles(mm_clk, c_cross_nof_mm_clk);
158
      mmf_mm_bus_rd(c_reg_r_w_dc_file_pathname, c_mem_reg.latency, v_addr, file_rd_data, mm_clk);
159
      ASSERT TO_UINT(file_wr_data)=TO_UINT(file_rd_data) REPORT "Write/read data is wrong." SEVERITY ERROR;
160
    END LOOP;
161
 
162
    proc_common_gen_pulse(mm_clk, get_now);
163
    tb_state <= "End  ";
164
 
165
    proc_common_wait_some_cycles(mm_clk, g_mm_nof_accesses);
166
    tb_end <= '1';
167
    WAIT;
168
  END PROCESS;
169
 
170
  u_mm_file : ENTITY work.mm_file
171
  GENERIC MAP(
172
    g_file_prefix   => c_reg_r_w_dc_file_pathname,
173
    g_mm_rd_latency => c_mem_reg.latency,  -- the mm_file g_mm_rd_latency must be >= the MM slave read latency
174
    g_mm_timeout    => g_mm_timeout,
175
    g_mm_pause      => g_mm_pause
176
  )
177
  PORT MAP (
178
    mm_rst        => mm_rst,
179
    mm_clk        => mm_clk,
180
 
181
    mm_master_out => mm_mosi,
182
    mm_master_in  => mm_miso
183
  );
184
 
185
  -- Target MM reg
186
  u_reg_r_w_dc : ENTITY work.common_reg_r_w_dc
187
  GENERIC MAP (
188
    g_cross_clock_domain => g_cross_clock_domain,
189
    g_in_new_latency     => 0,
190
    g_readback           => FALSE,
191
    g_reg                => c_mem_reg
192
    --g_init_reg           => STD_LOGIC_VECTOR(c_mem_reg_init_w-1 DOWNTO 0) := (OTHERS => '0')
193
  )
194
  PORT MAP (
195
    -- Clocks and reset
196
    mm_rst      => mm_rst,
197
    mm_clk      => mm_clk,
198
    st_rst      => mm_rst,
199
    st_clk      => mm_clk,
200
 
201
    -- Memory Mapped Slave in mm_clk domain
202
    sla_in      => mm_mosi,
203
    sla_out     => mm_miso,
204
 
205
    -- MM registers in st_clk domain
206
    reg_wr_arr  => reg_wr_arr,
207
    reg_rd_arr  => reg_rd_arr,
208
    in_new      => in_new,
209
    in_reg      => in_reg,
210
    out_reg     => out_reg,
211
    out_new     => out_new
212
  );
213
 
214
  in_reg <= out_reg;
215
 
216
  p_wire : PROCESS(out_reg)
217
  BEGIN
218
    FOR I IN c_mem_reg.nof_dat-1 DOWNTO 0 LOOP
219
      out_reg_arr(I) <= out_reg((I+1)*c_32-1 DOWNTO I*c_32);
220
    END LOOP;
221
  END PROCESS;
222
 
223
  -- Also verify simulation status access
224
  mmf_poll_sim_ctrl_file(mm_clk, c_sim_file_pathname & ".ctrl", c_sim_file_pathname & ".stat");
225
 
226
  p_sim_stimuli : PROCESS
227
  BEGIN
228
    proc_common_wait_until_low(mm_clk, mm_rst);
229
    proc_common_wait_some_cycles(mm_clk, 10);
230
 
231
    proc_common_wait_until_hi_lo(mm_clk, get_now);
232
    mmf_sim_get_now(c_sim_file_pathname, rd_now, mm_clk);
233
    WAIT;
234
  END PROCESS;
235
 
236
END tb;

powered by: WebSVN 2.1.0

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