burst_ctrl_tb.vhd 14.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
 --==============================================================================
-- CERN (BE-CO-HT)
-- Testbench for CONV-BURST_CTRL design
--==============================================================================
--
-- author: Denia Bouhired (denia.bouhired@cern.ch)
--
-- date of creation: 20-09-2016
--
-- version: 1.0
--
-- description:
--    Simulation testbench for the new burst mode module to run in as part of the
--    CONV-TTL-BLO common gateware.
--      
--
-- dependencies:
--    None.
--
--==============================================================================
-- GNU LESSER GENERAL PUBLIC LICENSE
--==============================================================================
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version. This source is distributed in the hope that it
-- will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details. You should have
-- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--==============================================================================
-- last changes:
--    20-09-2016   Denia Bouhired     File created

--==============================================================================
-- TODO: -
--==============================================================================

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use std.textio.all;


47
use work.gencores_pkg.all;
48 49
--use work.wishbone_pkg.all;

50
use work.conv_common_gw_pkg.all;
51 52 53 54 55 56 57 58 59 60

entity testbench is
end entity testbench;

architecture behav of testbench is


  -- Clock periods
  constant c_clk_20_per   : time := 50 ns;
  constant random_intervals : boolean := false;
61
  constant c_pgen_pwidth: natural := 5;
62
  constant c_pgen_duty_cycle_div : natural := 2;
63 64 65 66 67 68 69 70 71
  constant pwidth_sel : std_logic := '0';
  constant gf_en_n :std_logic:= '0';
  constant test_pgen : boolean:=false;
  -- constant g_temp_decre_step_in: t_temp_decre_step := (0,0,0,0,0,0,0,0,2500,731,220,250,40,85,50,125);
  constant g_temp_decre_step_in: t_temp_decre_step := (0, 0, 769, 31, 104, 14, 82, 0 ,0, 0, 0, 0, 0, 0, 0, 0);
  -- constant g_1_pulse_temp_rise_in :unsigned (19 downto 0) := x"17700";
  constant g_1_pulse_temp_rise_in :unsigned (19 downto 0) :=x"01388";
  	
  type t_time_array is array (2 downto 0) of integer;  
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
  
  component conv_pulse_gen is
  generic
  (
    -- This generic enables elaboration of the fixed pulse width logic
    g_with_fixed_pwidth : boolean;

    -- Pulse width, in number of clk_i cycles
    -- Default pulse width (20 MHz clock): 1.2 us
    -- Minimum allowable pulse width (20 MHz clock): 1 us
    -- Maximum allowable pulse width (20 MHz clock): 2 us
    g_pwidth : natural range 2 to 40 := 24;

    -- Duty cycle divider: D = 1/g_duty_cycle_div
    g_duty_cycle_div : natural := 5
  );
  port
  (
    -- Clock and active-low reset inputs
    clk_i         : in  std_logic;
    rst_n_i       : in  std_logic;

    -- Glitch filter enable input
    -- '1' - Glitch filter disabled (glitch-sensitive, no output jitter)
    -- '0' - Glitch filter enabled (glitch-insensitive, with output jitter)
    gf_en_n_i     : in  std_logic;

    -- Enable input, pulse generation is enabled when '1'
    en_i          : in  std_logic;

    -- Trigger input, has to be '1' to assure pulse output with delay no greater
    -- than internal gate delays.
    trig_a_i      : in  std_logic;
105 106
    trig_r_edge_p_i       : in std_logic; --synced 1 cycle-long r edge output
    trig_f_edge_p_i       : in std_logic; --synced 1 cycle-long f edge output
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

    -- Pulse error output, pulses high for one clock cycle when a pulse arrives
    -- within a pulse period
    pulse_err_p_o : out std_logic;

    -- Pulse output, active-high
    -- latency:
    --    glitch filter disabled: none
    --    glitch filter enabled: glitch filter length + 5 clk_i cycles
    pulse_o       : out std_logic;
	
	pulse_r_edge_p_o       : out std_logic; --synced 1 cycle-long r edge output
	pulse_f_edge_p_o       : out std_logic
  );
end component conv_pulse_gen;  
122 123 124 125 126
  
  component conv_dyn_burst_ctrl is
	generic
	(
		g_pwidth : natural range 2 to 40 	:= 5; 
127
		g_temp_decre_step : t_temp_decre_step := (0, 0, 769, 31, 104, 14, 82, 0 ,0, 0, 0, 0, 0, 0, 0,0);
128
		g_1_pulse_temp_rise			:in unsigned (19		downto 0);
129
		g_max_temp			:in unsigned (39 downto 0) 
130 131 132 133 134 135 136 137 138 139
	);
	port
	(
    -- Clock and active-low reset inputs
    clk_i        	: in  std_logic;
    rst_n_i      	: in  std_logic;
	
	-- Enable input, pulse generation is enabled when '1'
    en_i         	 	: in  std_logic;
	pulse_burst_i 		: in std_logic;
140 141
	pulse_r_edge_p_i	: in std_logic;
	pulse_f_edge_p_i	: in std_logic;
142
	temp_rise_o			:out unsigned (39 downto 0);
143 144 145 146 147 148 149 150 151 152 153 154 155
	pulse_burst_o		: out std_logic;
	
	-- Burst error output, pulses high for one clock cycle when a pulse arrives
    -- within a burst rejection phase
    burst_err_p_o : out std_logic	
	
	);
  end component conv_dyn_burst_ctrl;
  
  
  -- Signal declarations
  
  signal clk_20			: std_logic;
156
  signal rst_n			: std_logic;
157 158
  
  signal en				: std_logic;
159 160 161
  signal burst_train_d0	: std_logic;
  signal burst_train_d1	: std_logic;
  -- signal burst_train_d2	: std_logic;
162
  signal burst_train	: std_logic;
163 164
  signal burst_train_f_edge	: std_logic;
  signal burst_train_r_edge	: std_logic;
165 166
  signal burst_train_redge_in	: std_logic;
  signal burst_train_fedge_in	: std_logic;
167 168
  signal burst_train_regulated_dyn : std_logic;
  signal rand_num 		: integer := 0;
169 170 171
  signal pulse_outp_err_p :std_logic;
  signal burst_outp_err_p :std_logic;
  signal pulse_outp :std_logic;
172
  
173 174 175 176 177 178 179 180 181 182
  signal pgen_pwidth : integer;
  signal pgen_duty_cycle_div : integer;
  signal temp_rise : unsigned (39 downto 0);
  
  signal pnumber : integer;
  signal period_array_lg : t_time_array;
  signal period_array_sh : t_time_array;
  signal pwidth_array_lg : t_time_array;
  signal pwidth_array_sh : t_time_array;
  
183 184 185
	signal t_start : TIME := NOW;
	signal t_sim1 :TIME := 0 ns;
	signal t_sim2 :TIME := 0 ns;
186 187 188 189 190
	signal t_sim3 :TIME := 0 ns;
	
    
	

191 192 193 194 195 196
  --==============================================================================
--  architecture begin
--==============================================================================

  begin
  
197
-- ===========================================================================
198 199
  --Instantiate the DUT: Burst controller averaged over 1000 pulses
  --============================================================================
200

201 202 203 204 205
  
   -- burst_train_dyn <= burst_train;
    --============================================================================
  -- Instantiate the DUT: Dynamic
  --============================================================================
206 207

				
208 209 210 211 212 213 214 215 216 217
    cmp_pulse_gen_sh : conv_pulse_gen
    generic map
    (
      g_with_fixed_pwidth => true,
      g_pwidth            => c_pgen_pwidth,
      g_duty_cycle_div    => c_pgen_duty_cycle_div
    )
    port map
    (
      clk_i         => clk_20,
218
      rst_n_i       => rst_n,
219

220
      gf_en_n_i     => gf_en_n,
221 222 223

      en_i          => '1',

224 225 226
      trig_a_i      => burst_train_d1,
      trig_r_edge_p_i       => burst_train_redge_in,
      trig_f_edge_p_i       => burst_train_fedge_in,
227 228 229 230 231 232 233
      pulse_err_p_o => pulse_outp_err_p,

      pulse_o       => pulse_outp,
      pulse_r_edge_p_o       => burst_train_r_edge ,
      pulse_f_edge_p_o       => burst_train_f_edge

    );
234 235 236



237
  cmp_dut : conv_dyn_burst_ctrl
238 239
  generic map
  (
240
  g_pwidth 					=> c_pgen_pwidth, --
241 242
  g_temp_decre_step		=> g_temp_decre_step_in,
  g_1_pulse_temp_rise		=> g_1_pulse_temp_rise_in,
243 244
  g_max_temp			=> x"00000F4240" --10^6
  -- g_max_temp			=> x"02540BE400" --10^10
245 246 247
  )
  port map(
  clk_i			=> clk_20,
248
  rst_n_i		=>  rst_n,
249
  
250
  en_i				=> '1',
251
  pulse_burst_i		=> pulse_outp,
252 253
  pulse_r_edge_p_i	=> burst_train_r_edge,
  pulse_f_edge_p_i	=> burst_train_f_edge,
254
  temp_rise_o		=> temp_rise,
255
  pulse_burst_o		=> burst_train_regulated_dyn,
256
  burst_err_p_o		=> burst_outp_err_p
257 258 259 260
  
  );
  
  
261 262 263 264 265 266 267 268 269
    cmp_sync_ffs : gc_sync_ffs
    port map
    (
      clk_i    => clk_20,
      rst_n_i  => rst_n,
      data_i   => burst_train_d1,
      ppulse_o => burst_train_redge_in,
      npulse_o => burst_train_fedge_in
    );
270 271 272 273 274 275 276
   --============================================================================
-- Generate clock signals
--============================================================================
  p_clk_20 : process
  begin
    clk_20 <= '1';
    wait for c_clk_20_per/2;
277 278
    clk_20 <= '0';
    wait for c_clk_20_per/2;
279 280 281 282 283 284 285
  end process p_clk_20;
  --============================================================================ 
  -- Random number generator
   --============================================================================
 p_ran_gen : process 
    variable seed1, seed2: positive := 1;               -- seed values for random generator
    variable rand: real;   -- random real-number value in range 0 to 1.0  
286
    variable range_of_rand : real := 1000.0;    -- the range of random values created will be 0 to +10000.
287 288 289 290 291 292 293 294 295 296 297 298
begin

    uniform(seed1, seed2, rand);   -- generate random number
    rand_num <= integer(rand*range_of_rand);  -- rescale to 0..1000, convert integer part 
    wait for 1000 ns;
end process p_ran_gen;


  
  process 
  begin
 
299
	rst_n <= '1';
300
	wait for 2500 ns;
301
	rst_n <= '0';
302
	wait for 2000 ns;
303
	rst_n <= '1';
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
	wait;
  end process;  
  
  process 
  begin
	en <= '0';
	wait for 5000 ns;
	en <= '1';
	wait;
  end process; 
  
  
  --============================================================================
  -- Pulse stimuli
  --============================================================================
  
320 321 322 323 324 325 326 327
   -- cmp_sync_input : gc_sync_ffs
   -- generic map
   -- (
     -- g_sync_edge => "positive"
   -- )
   -- port map
   -- (
     -- clk_i    => clk_20,
328
     -- rst_n_i  => rst_n,
329 330 331 332
     -- data_i   => burst_train,
     -- npulse_o => burst_train_f_edge,
     -- ppulse_o => burst_train_r_edge
   -- );
333
  
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
  period_array_lg  <= (8000 , 9600 , 20000 );
  pwidth_array_lg  <= (2000 , 500 , 1200 );
  period_array_sh  <= (450 , 500 , 1000 );
  pwidth_array_sh  <= (400 , 100 , 250 );
  
  -- p_sel_params : process
  -- variable interval	: time;
    -- begin

    -- -- if rst_n = '1' and en = '1' then
	-- --for gf_en_n in 
		-- if pwidth_sel = '1' then
			-- for pwidth_index in 2 downto 0 loop
				-- for period_index in  2 downto 0  loop
					-- pnumber <= 0;
						-- while pnumber < 9 loop
							-- -- if random_intervals then
								-- -- interval := rand_num * 1 ns;
								-- -- if interval < 250 ns then
									-- -- interval := 250 ns;
								-- -- end if;
							-- -- else
								-- interval := (period_array_lg(period_index) - pwidth_array_lg(pwidth_index))*1ns;
							-- -- end if;
							-- burst_train <= '0';
							-- wait for interval;
							-- burst_train <= '1';
							-- wait for pwidth_array_lg(pwidth_index)*1ns;-- changes pulse width
							-- burst_train <= '0';
							-- pnumber <= pnumber + 1;
						-- end loop;
					-- wait for 0.1 ms;
				-- end loop;
					-- wait for 0.2 ms;
			-- end loop; 
					-- wait for 0.5 ms;
		-- else
			-- for pwidth_index in  2 downto 0 loop
				-- for period_index in  2 downto 0  loop
				    -- pnumber<=0;
					-- while pnumber < 9 loop
							-- -- if random_intervals then
								-- -- interval := rand_num * 1 ns;
								-- -- if interval < 250 ns then
									-- -- interval := 250 ns;
								-- -- end if;
							-- -- else
								-- interval := (period_array_sh(period_index) - pwidth_array_sh(pwidth_index))*1ns;
							-- -- end if;
							-- burst_train <= '0';
							-- wait for interval;
							-- burst_train <= '1';
							-- wait for pwidth_array_sh(pwidth_index)*1ns;-- changes pulse width
							-- burst_train <= '0';
						    -- pnumber <= pnumber+1;
						-- end loop;
					-- wait for 0.01 ms;
				-- end loop;
					-- wait for 0.02 ms;
			-- end loop; 
					-- wait for 0.05 ms;
		-- -- end if;
	-- end if;

  -- end process p_sel_params;


401
  
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418
  p_delay : process (clk_20)
  begin
    if rising_edge(clk_20) then
      if (rst_n = '0') then
	  burst_train_d0 <= '0';
      
	  burst_train_d1 <= '0';  
      else
        burst_train_d0 <= burst_train; 
        burst_train_d1 <= burst_train_d0; 
      end if;
	end if;
  end process p_delay;
  
  
  
 p_stim_burst1 : process
419
    variable interval	: time;-- := 1000 ns;
420
	variable period1		: time :=  250  ns;--changes pulse frequency
421
	variable period2		: time := 2000 ns;--changes pulse frequency
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
	variable period3		: time := 450 ns;--changes pulse frequency
	variable pwidth		: time := 100 ns;
  begin 

 
	  while t_sim1 < 10000 us loop 
	  
		t_sim1 <=  NOW - t_start;
		if random_intervals then
			interval := rand_num * 1 ns;
			if interval < 250 ns then
				interval := 250 ns;
			end if;
		else
			interval := period1 - pwidth;
437
		end if;
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
		burst_train <= '0';
		wait for interval;
		burst_train <= '1';
		wait for pwidth;-- changes pulse width
		burst_train <= '0';
	  end loop;  
   
	   while t_sim2 < 10000 us loop
		t_sim2 <=  NOW - t_sim1;
		if random_intervals then
			interval := rand_num * 1 ns;
		else
			interval := period2 - pwidth;
		end if;
		burst_train <= '0';
		wait for interval;
		burst_train <= '1';
		wait for pwidth;
		burst_train <= '0';
	  end loop; 
  
   burst_train <= '0';
   wait for 5 ms;
   while t_sim3 < 30000 us loop
	t_sim3 <=  NOW - t_sim1;
    interval := period3 - pwidth;
464 465 466
	burst_train <= '0';
	wait for interval;
	burst_train <= '1';
467
	wait for pwidth;-- changes pulse width
468 469
	burst_train <= '0';
  end loop;  
470

471
  end process p_stim_burst1;
472 473 474
  
  
  -- p_write_output : process (temp_rise_counter)
475
  -- file F 	 : text open write_mode is "C:\Users\debouhir\work\CONV-TTL-BLO\conv-ttl-blo\conv-ttl-blo-gw\sim\Release\temp_rise_counter.txt";
476 477
  -- variable L : line;
  -- begin
478 479 480
	-- write (L, NOW, left, 30);
	-- write (L, to_integer((temp_rise_counter (19 downto 0))), left, 50);
	-- write (L, to_integer((temp_rise_counter (39 downto 20))), left, 50);
481 482 483 484 485 486 487 488 489 490 491 492 493
	-- writeline (F, L);
  -- end process p_write_output;
  
  end architecture behav;
--==============================================================================
--  architecture end
--==============================================================================