testbench_pkg.vhd 19.4 KB
Newer Older
Evangelia Gousiou's avatar
Evangelia Gousiou committed
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
--==============================================================================
-- CERN (BE-CO-HT)
-- TTL-RS485 pkg package
--==============================================================================

--==============================================================================
-- 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
--==============================================================================

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.wishbone_pkg.all;
use work.genram_pkg.all;
26
use work.print_pkg.all;
Evangelia Gousiou's avatar
Evangelia Gousiou committed
27 28 29 30 31 32 33 34 35


package testbench_pkg is

  --============================================================================
  -- Constant declarations
  --============================================================================
  
  -- Clock periods
Evangelia Gousiou's avatar
Evangelia Gousiou committed
36 37 38
  constant C_CLK_20_PER   : time := 50 ns;
  constant C_CLK_125_PER  : time :=  8 ns;
  constant C_RESET_WIDTH  : time := 200 ns;
Evangelia Gousiou's avatar
Evangelia Gousiou committed
39 40 41

  
  -- DUT configuration (generics):
Evangelia Gousiou's avatar
Evangelia Gousiou committed
42 43 44
  constant C_NR_CHANS     : integer := 6;
  constant C_NR_INV_CHANS : integer := 4;
  constant C_BOARD_ID     : std_logic_vector(31 downto 0) := x"54343835";
Evangelia Gousiou's avatar
Evangelia Gousiou committed
45 46

   -- Number of I2C masters and slaves for the I2C bus model
Evangelia Gousiou's avatar
Evangelia Gousiou committed
47 48 49
  constant C_NR_MASTERS : positive := 1;
  constant C_NR_SLAVES  : positive := 1;

50 51
  constant C_NO_RTM            : std_logic_vector(5 downto 0) := "000000";
  constant C_RTM_DB9           : std_logic_vector(5 downto 0) := "000101";
52 53
  constant C_INITIAL_TST_VALUE : std_logic_vector(31 downto 0) := x"FFFFFFF0";

54 55
  constant C_I2C_MASTER_SLV_ADDR: std_logic_vector(6 downto 0) := "1011110";

Evangelia Gousiou's avatar
Evangelia Gousiou committed
56 57

  -- DUT register map:
58
  constant C_BIDR      : std_logic_vector(31 downto 0) := x"00000000";
Evangelia Gousiou's avatar
Evangelia Gousiou committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

  constant C_SR       : std_logic_vector(31 downto 0) := x"00000004";
  constant C_ERR      : std_logic_vector(31 downto 0) := x"00000008";
  constant C_CR       : std_logic_vector(31 downto 0) := x"0000000C";

  constant C_CH1FPPCR : std_logic_vector(31 downto 0) := x"00000010";
  constant C_CH2FPPCR : std_logic_vector(31 downto 0) := x"00000014";
  constant C_CH3FPPCR : std_logic_vector(31 downto 0) := x"00000018";
  constant C_CH4FPPCR : std_logic_vector(31 downto 0) := x"0000001C";
  constant C_CH5FPPCR : std_logic_vector(31 downto 0) := x"00000020";
  constant C_CH6FPPCR : std_logic_vector(31 downto 0) := x"00000024";

  constant C_CH1RPPCR : std_logic_vector(31 downto 0) := x"00000028";
  constant C_CH2RPPCR : std_logic_vector(31 downto 0) := x"0000002C";
  constant C_CH3RPPCR : std_logic_vector(31 downto 0) := x"00000030";
  constant C_CH4RPPCR : std_logic_vector(31 downto 0) := x"00000034";
  constant C_CH5RPPCR : std_logic_vector(31 downto 0) := x"00000038";
  constant C_CH6RPPCR : std_logic_vector(31 downto 0) := x"0000003C";

78 79 80 81
  constant CH1LTSCYR : std_logic_vector(31 downto 0) := x"0000005C";
  constant CH1LTSTLR : std_logic_vector(31 downto 0) := x"00000060";


Evangelia Gousiou's avatar
Evangelia Gousiou committed
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
  type t_reg is
  record
    reg_addr : std_logic_vector(31 downto 0);
    reg_name : string(1 to 8);
  end record;

  type t_reg_table is array (natural range <>) of t_reg;

  constant c_REG_MAP : t_reg_table(15 downto 0) :=
    (0 => (reg_addr => C_BIDR,
           reg_name => "BIDR    "),
     1 => (reg_addr => C_SR,
           reg_name => "SR      "),
     2 => (reg_addr => C_ERR,
           reg_name => "ERR     "),
     3 => (reg_addr => C_CR,
           reg_name => "CR      "),
     4 => (reg_addr => C_CH1FPPCR,
           reg_name => "CH1FPPCR"),
     5 => (reg_addr => C_CH2FPPCR,
           reg_name => "CH3FPPCR"),
     6 => (reg_addr => C_CH3FPPCR,
           reg_name => "CH3FPPCR"),
     7 => (reg_addr => C_CH4FPPCR,
           reg_name => "CH4FPPCR"),
     8 => (reg_addr => C_CH5FPPCR,
           reg_name => "CH5FPPCR"),
     9 => (reg_addr => C_CH6FPPCR,
           reg_name => "CH6FPPCR"),
     10 => (reg_addr => C_CH1RPPCR,
           reg_name => "CH1RPPCR"),
     11 => (reg_addr => C_CH2RPPCR,
           reg_name => "CH3RPPCR"),
     12 => (reg_addr => C_CH3RPPCR,
           reg_name => "CH3RPPCR"),
     13 => (reg_addr => C_CH4RPPCR,
           reg_name => "CH4RPPCR"),
     14 => (reg_addr => C_CH5RPPCR,
           reg_name => "CH5RPPCR"),
     15 => (reg_addr => C_CH6RPPCR,
           reg_name => "CH6RPPCR"));

Evangelia Gousiou's avatar
Evangelia Gousiou committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145

  --============================================================================
  -- Types declarations
  --============================================================================
  type t_i2c_master_in is record
    i2c_master_start                  : std_logic;  
    i2c_master_rdwr                   : std_logic;
    i2c_master_slv_addr               : std_logic_vector(6 downto 0);
    i2c_master_reg_addr               : std_logic_vector(31 downto 0);
    i2c_master_send_val               : std_logic_vector(31 downto 0);
  end record;

  type t_i2c_master_out is record
    i2c_master_ready                  : std_logic;
    i2c_master_finish                 : std_logic;
    i2c_master_rcvd_val               : std_logic_vector(31 downto 0);
  end record;

  --============================================================================
  -- Components declarations
  --============================================================================
  component conv_ttl_rs485 is
146 147 148
  generic (g_simul         : boolean := FALSE;
		   g_rst_time		: positive := 10
		   ); 
Evangelia Gousiou's avatar
Evangelia Gousiou committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
  port
  (
    -- Clocks
    clk_20_i                : in  std_logic;
    clk_125_p_i             : in  std_logic;
    clk_125_n_i             : in  std_logic;

    -- I2C interface
    scl_i                   : in  std_logic;
    scl_o                   : out std_logic;
    scl_en_o                : out std_logic;
    sda_i                   : in  std_logic;
    sda_o                   : out std_logic;
    sda_en_o                : out std_logic;

    -- VME interface
    vme_sysreset_n_i        : in  std_logic;
    vme_ga_i                : in  std_logic_vector(4 downto 0);
    vme_gap_i               : in  std_logic;

    -- PCB version recognition
    pcbrev_i				: in std_logic_vector(5 downto 0);

    -- Channel enable
    global_oen_o            : out std_logic;
    ttl_oen_o               : out std_logic;
    inv_oen_o               : out std_logic;
    rs485_oen_o             : out std_logic;

    -- Front panel channels
    ttl_n_i                 : in  std_logic_vector(5 downto 0);
    ttl_o                   : out std_logic_vector(5 downto 0);
    inv_n_i                 : in  std_logic_vector(3 downto 0);
    inv_o                   : out std_logic_vector(3 downto 0);

    -- Rear panel channels
    rs485_n_i               : in  std_logic_vector(5 downto 0);
    rs485_fs_n_i            : in  std_logic_vector(5 downto 0);
    rs485_o                 : out std_logic_vector(5 downto 0);

    -- Rear input and output termination lines
    iterm_en_o              : out std_logic_vector(5 downto 0);
    oterm_en_o              : out std_logic_vector(5 downto 0);

    -- Channel leds
    led_front_n_o           : out std_logic_vector(5 downto 0);
    led_front_inv_n_o       : out std_logic_vector(3 downto 0);
    led_rear_n_o            : out std_logic_vector(5 downto 0);

    -- SPI interface to on-board flash chip
    flash_cs_n_o            : out std_logic;
    flash_sclk_o            : out std_logic;
    flash_mosi_o            : out std_logic;
    flash_miso_i            : in  std_logic;

    -- PLL DACs
    -- 20 MHz VCXO control
    dac20_din_o             : out std_logic;
    dac20_sclk_o            : out std_logic;
    dac20_sync_n_o          : out std_logic;
    -- 125 MHz clock generator control
    dac125_din_o            : out std_logic;
    dac125_sclk_o           : out std_logic;
    dac125_sync_n_o         : out std_logic;

    -- SFP lines
    sfp_los_i               : in    std_logic;
    sfp_present_i           : in    std_logic;
    sfp_rate_select_o       : out   std_logic;
    sfp_scl_b               : inout std_logic;
    sfp_sda_b               : inout std_logic;
    sfp_tx_disable_o        : out   std_logic;
    sfp_tx_fault_i          : in    std_logic;

    -- Thermometer data port
    thermometer_b           : inout std_logic;

    -- Switches
    sw_gp_n_i               : in   std_logic_vector(7 downto 0);
    sw_multicast_n_i        : in   std_logic_vector(3 downto 0);

    -- RTM lines
    rtmm_i                  : in  std_logic_vector(2 downto 0);
    rtmp_i                  : in  std_logic_vector(2 downto 0);

    -- Front panel bicolor LEDs
    led_ctrl0_o             : out std_logic;
    led_ctrl0_oen_o         : out std_logic;
    led_ctrl1_o             : out std_logic;
    led_ctrl1_oen_o         : out std_logic;
    led_gp_2_4_o            : out std_logic;
    led_gp_1_3_o            : out std_logic;
    led_oterm_wr_o          : out std_logic;
    led_iterm_syserror_o    : out std_logic;
    led_gf_syspw_o          : out std_logic;
    led_ttl_i2c_o           : out std_logic
  );
end component conv_ttl_rs485;

  -- procedure read_i2c (signal i2c_m_out  : in  t_i2c_master_out;
                      -- signal i2c_m_in   : out t_i2c_master_in;
                      -- signal slv_addr : in  std_logic_vector( 6 downto 0);
                      -- signal reg_addr : in  std_logic_vector(31 downto 0);
                      -- signal rcvd_val   : out std_logic_vector(31 downto 0));


Evangelia Gousiou's avatar
Evangelia Gousiou committed
255 256
  procedure generate_pulse (signal pulse_n_out : out std_logic;
                            nb_of_pulses       : in natural;
257 258
                            fp_or_rp           : in string (1 to 2);
                            signal rs485_fs_n  : out std_logic;
Evangelia Gousiou's avatar
Evangelia Gousiou committed
259 260
                            ns_on              : in time;
                            ns_off             : in time);
Evangelia Gousiou's avatar
Evangelia Gousiou committed
261

262 263 264

  procedure settings_config (constant glitch_filter_en : in std_logic;
                             constant ttl_out_bar_en   : in std_logic;
265
                             constant rtm_value        : in std_logic_vector(5 downto 0);
266 267 268
                             signal sw_gp_n  : out std_logic_vector(7 downto 0);
                             signal sw_other : out std_logic_vector(31 downto 0);
                             signal pcbrev   : out std_logic_vector(5 downto 0);
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
                             signal rtm      : out std_logic_vector(5 downto 0));

  procedure cnt_pulses (signal pulse_train : in std_logic;
                       signal nb_of_pulses_cnted  :  out natural;
                       nb_pulses_expected  : in integer);


  procedure write_i2c (signal i2c_m_in   : out t_i2c_master_in;
                       signal i2c_m_out  : in  t_i2c_master_out;
                       constant slv_addr : in  std_logic_vector( 6 downto 0);
                       constant reg_addr : in  std_logic_vector(31 downto 0);
                       constant reg_name : string(1 to 8);
                       constant send_val : in  std_logic_vector(31 downto 0);
                                err      : out natural);

284 285 286 287 288 289 290 291 292 293 294 295
  procedure read_i2c (signal   i2c_m_in    : out t_i2c_master_in;
                      signal   i2c_m_out   : in  t_i2c_master_out;
                      constant slv_addr    : in  std_logic_vector(6 downto 0);
                      constant reg_addr    : in  std_logic_vector(31 downto 0);
                      constant reg_name    : string(1 to 8);
                      signal   rcvd_val    : out std_logic_vector(31 downto 0);
                      constant exp_val     : in  std_logic_vector(31 downto 0);
                      constant eval_result : in boolean;
                               err         : out natural);

  -- procedure read_i2c_err (signal i2c_m_in  : out t_i2c_master_in;
                          -- signal i2c_m_out : in  t_i2c_master_out);
296

Evangelia Gousiou's avatar
Evangelia Gousiou committed
297 298
end testbench_pkg;
package body testbench_pkg is 
Evangelia Gousiou's avatar
Evangelia Gousiou committed
299
--==================================================================================================
Evangelia Gousiou's avatar
Evangelia Gousiou committed
300
--  Procedures
Evangelia Gousiou's avatar
Evangelia Gousiou committed
301
--==================================================================================================
302 303
  procedure settings_config (constant glitch_filter_en : in std_logic;
                             constant ttl_out_bar_en   : in std_logic;
304 305 306 307 308
                             constant rtm_value : in std_logic_vector(5 downto 0);
                             signal sw_gp_n     : out std_logic_vector(7 downto 0);
                             signal sw_other    : out std_logic_vector(31 downto 0);
                             signal pcbrev      : out std_logic_vector(5 downto 0);
                             signal rtm         : out std_logic_vector(5 downto 0)) is
Evangelia Gousiou's avatar
Evangelia Gousiou committed
309
  begin
Evangelia Gousiou's avatar
Evangelia Gousiou committed
310
    sw_gp_n(0)          <= not glitch_filter_en;
311
    if glitch_filter_en = '1' then
312
      print_now("- Glitch filter enabled");
313
    else
314
      print_now("- Glitch filter disabled");
315 316
    end if;

Evangelia Gousiou's avatar
Evangelia Gousiou committed
317
    sw_gp_n(7)          <= ttl_out_bar_en;
318
    if ttl_out_bar_en = '1' then
319 320 321 322 323 324 325
      print_now("- TTL output BAR enabled");
    else
      print_now("- TTL output BAR disabled");
    end if;

    if rtm_value = C_RTM_DB9 then
      print_now("- DB9 RTM plugged in");
326
    else
327
      print_now("- No particular RTM");
328 329
    end if;

Evangelia Gousiou's avatar
Evangelia Gousiou committed
330
    --print_now_s_std("RTMP & RTMM set to x", C_RTM);
331

332 333 334
    sw_gp_n(6 downto 1) <= (others => '0'); -- not used
    sw_other            <= (others => '0'); -- not used
    pcbrev              <= "111100";        -- not used
335 336 337
    rtm                 <= rtm_value;


Evangelia Gousiou's avatar
Evangelia Gousiou committed
338 339
  end procedure;

Evangelia Gousiou's avatar
Evangelia Gousiou committed
340
----------------------------------------------------------------------------------------------------
Evangelia Gousiou's avatar
Evangelia Gousiou committed
341 342
  procedure generate_pulse (signal pulse_n_out  : out std_logic;
                            nb_of_pulses : in natural;
343 344 345 346
                            fp_or_rp     : in string (1 to 2);
                            signal rs485_fs_n   : out std_logic;
                            ns_on        : in time;
                            ns_off       : in time) is
Evangelia Gousiou's avatar
Evangelia Gousiou committed
347 348 349 350

    variable numb_cnt : natural;
    begin
      numb_cnt := 0;
351

Evangelia Gousiou's avatar
Evangelia Gousiou committed
352
      while not(numb_cnt = nb_of_pulses) loop
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
        if fp_or_rp = "fp" then
          rs485_fs_n <= '0'; -- stays inactive

          pulse_n_out <= '1';
          wait for ns_off;
          pulse_n_out <= '0';
          wait for ns_on; 
          pulse_n_out <= '1';
        else
          pulse_n_out <= '1';
          rs485_fs_n <= '0';
          wait for ns_off;
          pulse_n_out <= '0';
          rs485_fs_n <= '1';
          wait for ns_on; 
          pulse_n_out <= '1';
          rs485_fs_n <= '0';
        end if;
Evangelia Gousiou's avatar
Evangelia Gousiou committed
371 372
        numb_cnt:= numb_cnt + 1;
      end loop;
373
      wait for 500ns; -- wait for all pulses to propagate to the output
Evangelia Gousiou's avatar
Evangelia Gousiou committed
374 375 376
  end procedure generate_pulse;


377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
----------------------------------------------------------------------------------------------------
  procedure cnt_pulses (signal pulse_train        : in std_logic;
                        signal nb_of_pulses_cnted : out integer;
                               nb_pulses_expected : in integer) is

  variable pulse_cnt : integer :=0;
  variable err_sum   : integer:=0;
  begin
    if rising_edge(pulse_train) then
      pulse_cnt := pulse_cnt +1;
    end if;

    nb_of_pulses_cnted <= pulse_cnt;

    if pulse_cnt = nb_pulses_expected then
      print_now_s_i("[OK] counted: ", pulse_cnt);
    else
      print_now_s_i("[ERR] counted: ", pulse_cnt);
    end if;

  end procedure cnt_pulses;

----------------------------------------------------------------------------------------------------

  procedure read_i2c (signal   i2c_m_in : out t_i2c_master_in;
                      signal   i2c_m_out: in  t_i2c_master_out;
                      constant slv_addr : in  std_logic_vector(6 downto 0);
                      constant reg_addr : in  std_logic_vector(31 downto 0);
                      constant reg_name : string(1 to 8);
                      signal   rcvd_val : out std_logic_vector(31 downto 0);
                      constant exp_val  : in  std_logic_vector(31 downto 0);
408
                      constant eval_result : in boolean;
409 410 411 412 413 414 415
                               err      : out natural) is
  variable err_cnt : natural := 0;
  begin
    print_now("---------------");
    print_now("read_i2c: start"); 
    i2c_m_in.i2c_master_start    <= '0';
    i2c_m_in.i2c_master_rdwr     <= '0'; --mst_fsm_op
416
    i2c_m_in.i2c_master_slv_addr <= C_I2C_MASTER_SLV_ADDR;
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
    i2c_m_in.i2c_master_reg_addr <= (others => '0');
    i2c_m_in.i2c_master_send_val <= (others => '1');
    wait for 1us;
    i2c_m_in.i2c_master_slv_addr  <= slv_addr;
    i2c_m_in.i2c_master_reg_addr  <= reg_addr;
    i2c_m_in.i2c_master_start     <= '1';
    i2c_m_in.i2c_master_rdwr      <= '1'; --0: write
    wait for C_CLK_20_PER;
    i2c_m_in.i2c_master_start     <= '0';
    wait until i2c_m_out.i2c_master_finish = '1';
    rcvd_val             <= i2c_m_out.i2c_master_rcvd_val;
    print_now_s_std_s_std("I2C value read from 0x", reg_addr(7 downto 0),
                          " is 0x",i2c_m_out.i2c_master_rcvd_val);
    wait until i2c_m_out.i2c_master_finish = '0';
    print_now("read_i2c: completed"); 
432 433 434 435 436 437 438 439 440 441
    if eval_result = TRUE then
      if i2c_m_out.i2c_master_rcvd_val = exp_val then
        print_now_s_s("[OK] Correct reading from reg ", reg_name, "; expected value matches read value");
      else
        print_now_s_std_s_std("[ERR]: Read value from " & reg_name & ": ", i2c_m_out.i2c_master_rcvd_val,
                              "; expected value: ",exp_val);
        err_cnt := err_cnt +1;
      end if;
    end if; 

442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
    err := err_cnt;
    print_now("---------------");
  end procedure read_i2c;

----------------------------------------------------------------------------------------------------
  procedure write_i2c (signal i2c_m_in   : out t_i2c_master_in;
                       signal i2c_m_out  : in  t_i2c_master_out;
                       constant slv_addr : in  std_logic_vector( 6 downto 0);
                       constant reg_addr : in  std_logic_vector(31 downto 0);
                       constant reg_name : string(1 to 8);
                       constant send_val : in  std_logic_vector(31 downto 0);
                                err      : out natural) is
  variable err_cnt : natural := 0;
  begin
    print_now("---------------");
    print_now("write_i2c: start"); 
    i2c_m_in.i2c_master_start    <= '0';
    i2c_m_in.i2c_master_rdwr     <= '0'; --mst_fsm_op
460
    i2c_m_in.i2c_master_slv_addr <= C_I2C_MASTER_SLV_ADDR;
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
    i2c_m_in.i2c_master_reg_addr <= (others => '0');
    i2c_m_in.i2c_master_send_val <= (others => '1');
    wait for 1us;
    i2c_m_in.i2c_master_slv_addr <= slv_addr;
    i2c_m_in.i2c_master_reg_addr <= reg_addr;
    i2c_m_in.i2c_master_send_val <= send_val;
    i2c_m_in.i2c_master_start    <= '1';
    i2c_m_in.i2c_master_rdwr     <= '0'; --0: write
    wait for C_CLK_20_PER;
    i2c_m_in.i2c_master_start    <= '0';
    wait until i2c_m_out.i2c_master_ready = '1';
    print_now_s_std_s("write_i2C: Value ", send_val, " written to reg " & reg_name);
    print_now("---------------");
    err := 0;

  end procedure write_i2c;


479 480 481
----------------------------------------------------------------------------------------------------


Evangelia Gousiou's avatar
Evangelia Gousiou committed
482

Evangelia Gousiou's avatar
Evangelia Gousiou committed
483 484 485 486 487
end;


-----------------------------------------------------------------------------------