--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:   10:56:50 03/05/2014
-- Design Name:   
-- Module Name:   C:/Dropbox/00_Praksa/PCIe_Bus_master_moj//tb_user_wrapper_for_pcie.vhd
-- Project Name:  PCIe_Bus_master_xil_vhdl
-- Target Device:  
-- Tool versions:  
-- Description:   
-- 
-- VHDL Test Bench Created by ISE for module: user_wrapper_for_pcie
-- 
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.math_real.all;
use std.textio.all;

 
ENTITY tb_user_wrapper_for_pcie IS
END tb_user_wrapper_for_pcie;
 
ARCHITECTURE behavior OF tb_user_wrapper_for_pcie IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT user_wrapper_for_pcie
    PORT(
         trn_clk : IN  std_logic;
         trn_reset_n : IN  std_logic;
         trn_lnk_up_n : IN  std_logic;
         trn_td : OUT  std_logic_vector(63 downto 0);
         trn_trem_n : OUT  std_logic_vector(7 downto 0);
         trn_tsof_n : OUT  std_logic;
         trn_teof_n : OUT  std_logic;
         trn_tsrc_rdy_n : OUT  std_logic;
         trn_tdst_rdy_n : IN  std_logic;
         trn_tsrc_dsc_n : OUT  std_logic;
         trn_terrfwd_n : OUT  std_logic;
         trn_tdst_dsc_n : IN  std_logic;
         trn_tbuf_av : IN  std_logic_vector(3 downto 0);
         trn_rd : IN  std_logic_vector(63 downto 0);
         trn_rrem_n : IN  std_logic_vector(7 downto 0);
         trn_rsof_n : IN  std_logic;
         trn_reof_n : IN  std_logic;
         trn_rsrc_rdy_n : IN  std_logic;
         trn_rsrc_dsc_n : IN  std_logic;
         trn_rdst_rdy_n : OUT  std_logic;
         trn_rerrfwd_n : IN  std_logic;
         trn_rnp_ok_n : OUT  std_logic;
         trn_rbar_hit_n : IN  std_logic_vector(6 downto 0);
         trn_rfc_nph_av : IN  std_logic_vector(7 downto 0);
         trn_rfc_npd_av : IN  std_logic_vector(11 downto 0);
         trn_rfc_ph_av : IN  std_logic_vector(7 downto 0);
         trn_rfc_pd_av : IN  std_logic_vector(11 downto 0);
         trn_rcpl_streaming_n : OUT  std_logic;
         cfg_do : IN  std_logic_vector(31 downto 0);
         cfg_di : OUT  std_logic_vector(31 downto 0);
         cfg_byte_en_n : OUT  std_logic_vector(3 downto 0);
         cfg_dwaddr : OUT  std_logic_vector(9 downto 0);
         cfg_rd_wr_done_n : IN  std_logic;
         cfg_wr_en_n : OUT  std_logic;
         cfg_rd_en_n : OUT  std_logic;
         cfg_err_cor_n : OUT  std_logic;
         cfg_err_ur_n : OUT  std_logic;
         cfg_err_cpl_rdy_n : IN  std_logic;
         cfg_err_ecrc_n : OUT  std_logic;
         cfg_err_cpl_timeout_n : OUT  std_logic;
         cfg_err_cpl_abort_n : OUT  std_logic;
         cfg_err_cpl_unexpect_n : OUT  std_logic;
         cfg_err_posted_n : OUT  std_logic;
         cfg_interrupt_n : OUT  std_logic;
         cfg_interrupt_rdy_n : IN  std_logic;
         cfg_interrupt_assert_n : OUT  std_logic;
         cfg_interrupt_di : OUT  std_logic_vector(7 downto 0);
         cfg_interrupt_do : IN  std_logic_vector(7 downto 0);
         cfg_interrupt_mmenable : IN  std_logic_vector(2 downto 0);
         cfg_interrupt_msienable : IN  std_logic;
         cfg_turnoff_ok_n : OUT  std_logic;
         cfg_to_turnoff_n : IN  std_logic;
         cfg_pm_wake_n : OUT  std_logic;
         cfg_pcie_link_state_n : IN  std_logic_vector(2 downto 0);
         cfg_trn_pending_n : OUT  std_logic;
         cfg_err_tlp_cpl_header : OUT  std_logic_vector(47 downto 0);
         cfg_bus_number : IN  std_logic_vector(7 downto 0);
         cfg_device_number : IN  std_logic_vector(4 downto 0);
         cfg_function_number : IN  std_logic_vector(2 downto 0);
         cfg_status : IN  std_logic_vector(15 downto 0);
         cfg_command : IN  std_logic_vector(15 downto 0);
         cfg_dstatus : IN  std_logic_vector(15 downto 0);
         cfg_dcommand : IN  std_logic_vector(15 downto 0);
         cfg_lstatus : IN  std_logic_vector(15 downto 0);
         cfg_lcommand : IN  std_logic_vector(15 downto 0)
        );
    END COMPONENT;
    
    
   --Inputs
   signal trn_clk : std_logic := '0';
   signal trn_reset_n : std_logic := '0';
   signal trn_lnk_up_n : std_logic := '0';
   signal trn_tdst_rdy_n : std_logic := '0';
   signal trn_tdst_dsc_n : std_logic := '0';
   signal trn_tbuf_av : std_logic_vector(3 downto 0) := (others => '0');
   signal trn_rd : std_logic_vector(63 downto 0) := (others => '0');
   signal trn_rrem_n : std_logic_vector(7 downto 0) := (others => '0');
   signal trn_rsof_n : std_logic := '0';
   signal trn_reof_n : std_logic := '0';
   signal trn_rsrc_rdy_n : std_logic := '0';
   signal trn_rsrc_dsc_n : std_logic := '0';
   signal trn_rerrfwd_n : std_logic := '0';
   signal trn_rbar_hit_n : std_logic_vector(6 downto 0) := (others => '0');
   signal trn_rfc_nph_av : std_logic_vector(7 downto 0) := (others => '0');
   signal trn_rfc_npd_av : std_logic_vector(11 downto 0) := (others => '0');
   signal trn_rfc_ph_av : std_logic_vector(7 downto 0) := (others => '0');
   signal trn_rfc_pd_av : std_logic_vector(11 downto 0) := (others => '0');
   signal cfg_do : std_logic_vector(31 downto 0) := (others => '0');
   signal cfg_rd_wr_done_n : std_logic := '0';
   signal cfg_err_cpl_rdy_n : std_logic := '0';
   signal cfg_interrupt_rdy_n : std_logic := '0';
   signal cfg_interrupt_do : std_logic_vector(7 downto 0) := (others => '0');
   signal cfg_interrupt_mmenable : std_logic_vector(2 downto 0) := (others => '0');
   signal cfg_interrupt_msienable : std_logic := '0';
   signal cfg_to_turnoff_n : std_logic := '0';
   signal cfg_pcie_link_state_n : std_logic_vector(2 downto 0) := (others => '0');
   signal cfg_bus_number : std_logic_vector(7 downto 0) := (others => '0');
   signal cfg_device_number : std_logic_vector(4 downto 0) := (others => '0');
   signal cfg_function_number : std_logic_vector(2 downto 0) := (others => '0');
   signal cfg_status : std_logic_vector(15 downto 0) := (others => '0');
   signal cfg_command : std_logic_vector(15 downto 0) := (others => '0');
   signal cfg_dstatus : std_logic_vector(15 downto 0) := (others => '0');
   signal cfg_dcommand : std_logic_vector(15 downto 0) := (others => '0');
   signal cfg_lstatus : std_logic_vector(15 downto 0) := (others => '0');
   signal cfg_lcommand : std_logic_vector(15 downto 0) := (others => '0');

 	--Outputs
   signal trn_td : std_logic_vector(63 downto 0);
   signal trn_trem_n : std_logic_vector(7 downto 0);
   signal trn_tsof_n : std_logic;
   signal trn_teof_n : std_logic;
   signal trn_tsrc_rdy_n : std_logic;
   signal trn_tsrc_dsc_n : std_logic;
   signal trn_terrfwd_n : std_logic;
   signal trn_rdst_rdy_n : std_logic;
   signal trn_rnp_ok_n : std_logic;
   signal trn_rcpl_streaming_n : std_logic;
   signal cfg_di : std_logic_vector(31 downto 0);
   signal cfg_byte_en_n : std_logic_vector(3 downto 0);
   signal cfg_dwaddr : std_logic_vector(9 downto 0);
   signal cfg_wr_en_n : std_logic;
   signal cfg_rd_en_n : std_logic;
   signal cfg_err_cor_n : std_logic;
   signal cfg_err_ur_n : std_logic;
   signal cfg_err_ecrc_n : std_logic;
   signal cfg_err_cpl_timeout_n : std_logic;
   signal cfg_err_cpl_abort_n : std_logic;
   signal cfg_err_cpl_unexpect_n : std_logic;
   signal cfg_err_posted_n : std_logic;
   signal cfg_interrupt_n : std_logic;
   signal cfg_interrupt_assert_n : std_logic;
   signal cfg_interrupt_di : std_logic_vector(7 downto 0);
   signal cfg_turnoff_ok_n : std_logic;
   signal cfg_pm_wake_n : std_logic;
   signal cfg_trn_pending_n : std_logic;
   signal cfg_err_tlp_cpl_header : std_logic_vector(47 downto 0);

-- Clock period definitions
constant clk_period : time := 10 ns;

file sim_in : text open read_mode is "tb_user_wrapper_for_pcie_TX.sim"; --FIXME

signal stop     : Boolean := true;
signal timeout  : Boolean := true;
signal sync     : std_logic := '1';
signal period   : integer := 20;
constant Tu     : time := 1 ns;

signal T  : time := 20 ns;
signal T2 : time := 10 ns;


--
--  converts character into std_logic
function to_std_logic(ch : character) return std_logic is
begin
case ch is
  when '0' => return '0';
  when '1' => return '1';
  when 'Z' => return 'Z';
  when 'X' => return 'X';
  when others => return 'U';
end case;
end to_std_logic;

--  converts character into std_logic
function to_std_logic_n(ch : character) return std_logic is
begin
case ch is
  when '0' => return '1';
  when '1' => return '0';
  when 'Z' => return 'Z';
  when 'X' => return 'X';
  when others => return 'U';
end case;
end to_std_logic_n;



--
--  converts a std_logic_vector int hex string
function hstr(slv : std_logic_vector) return string is
type vector_ptr is access std_logic_vector;
variable pslv : vector_ptr;
variable i, hexlen : integer;
variable ln : line;
variable s : std_logic;
variable fourbit : std_logic_vector(3 downto 0);

begin
hexlen  := (slv'LENGTH - 1) / 4;
i       := hexlen * 4;
pslv    := new std_logic_vector(i+3 downto 0);
ln      := new string(1 to hexlen+1);
s       := slv(slv'LEFT);
if s = '1' then s := '0'; end if;
pslv.all(pslv.all'LEFT downto slv'LENGTH) := (others => s);
pslv.all(slv'LENGTH-1 downto 0) := slv;
for j in ln.all'RANGE loop
  fourbit := pslv(i+3 downto i);
  case fourbit is
    when "0000" => ln.all(j) := '0';
    when "0001" => ln.all(j) := '1';
    when "0010" => ln.all(j) := '2';
    when "0011" => ln.all(j) := '3';
    when "0100" => ln.all(j) := '4';
    when "0101" => ln.all(j) := '5';
    when "0110" => ln.all(j) := '6';
    when "0111" => ln.all(j) := '7';
    when "1000" => ln.all(j) := '8';
    when "1001" => ln.all(j) := '9';
    when "1010" => ln.all(j) := 'A';
    when "1011" => ln.all(j) := 'B';
    when "1100" => ln.all(j) := 'C';
    when "1101" => ln.all(j) := 'D';
    when "1110" => ln.all(j) := 'E';
    when "1111" => ln.all(j) := 'F';
    when "ZZZZ" => ln.all(j) := 'z';
    when "UUUU" => ln.all(j) := 'u';
    when "XXXX" => ln.all(j) := 'x';
    when others => ln.all(j) := '?';
  end case;
  i := i-4;
end loop;
deallocate(pslv);
return ln.all;
end hstr;

procedure read_vector(variable ln  : inout line;
                      variable sig : inout std_logic_vector) is
type vector_ptr is access std_logic_vector;
variable i   : integer;
variable ch  : character;
variable str : line;
variable slv1, slv2 : vector_ptr;
begin
  read(ln, i);
  if (i > 0) then
    sig := conv_std_logic_vector(i, sig'LENGTH);
    return;
  end if;
  if ln.all'LENGTH < 2 then
    sig := conv_std_logic_vector(0, sig'LENGTH);
    return;
  end if;
  if ln.all(1) /= 'x' and ln.all(1) /= 'X' then return; end if;
  read(ln, ch);
  ch := ln.all(1);
  i := ln.all'LENGTH;
  for k in ln.all'RANGE loop
    ch := ln.all(k);
    if (ch < '0' or ch > '9') and
       (ch < 'A' or ch > 'F') and
       (ch < 'a' or ch > 'f') and
   (ch /= 'z') and (ch /= 'Z') and
   (ch /= 'u') and (ch /= 'U') and
   (ch /= 'X') and (ch /= 'X') then
      i := k-1;
      exit;
    end if;
  end loop;
  slv1 := new std_logic_vector(sig'LENGTH-1 downto 0);
  str := new string(1 to i);
  read(ln, str.all);
  i := i*4;
  slv2 := new std_logic_vector(i-1 downto 0);
  for j in str.all'RANGE loop
    i := i-4;
    case str.all(j) is
      when '0' => slv2.all(i+3 downto i) := "0000";
      when '1' => slv2.all(i+3 downto i) := "0001";
      when '2' => slv2.all(i+3 downto i) := "0010";
      when '3' => slv2.all(i+3 downto i) := "0011";
      when '4' => slv2.all(i+3 downto i) := "0100";
      when '5' => slv2.all(i+3 downto i) := "0101";
      when '6' => slv2.all(i+3 downto i) := "0110";
      when '7' => slv2.all(i+3 downto i) := "0111";
      when '8' => slv2.all(i+3 downto i) := "1000";
      when '9' => slv2.all(i+3 downto i) := "1001";
      when 'A' => slv2.all(i+3 downto i) := "1010";
      when 'B' => slv2.all(i+3 downto i) := "1011";
      when 'C' => slv2.all(i+3 downto i) := "1100";
      when 'D' => slv2.all(i+3 downto i) := "1101";
      when 'E' => slv2.all(i+3 downto i) := "1110";
      when 'F' => slv2.all(i+3 downto i) := "1111";
      when 'a' => slv2.all(i+3 downto i) := "1010";
      when 'b' => slv2.all(i+3 downto i) := "1011";
      when 'c' => slv2.all(i+3 downto i) := "1100";
      when 'd' => slv2.all(i+3 downto i) := "1101";
      when 'e' => slv2.all(i+3 downto i) := "1110";
      when 'f' => slv2.all(i+3 downto i) := "1111";
      when 'z' => slv2.all(i+3 downto i) := "ZZZZ";
      when 'u' => slv2.all(i+3 downto i) := "UUUU";
      when 'x' => slv2.all(i+3 downto i) := "XXXX";
      when others => null;
    end case;
  end loop;
  deallocate(str);
  i := slv1'LEFT;
  if slv2.all'LEFT < i then i := slv2.all'LEFT; end if;
  slv1.all(i downto 0) := slv2.all(i downto 0);
  if slv1.all'LEFT > i then
    if slv1.all(i) = '1' then
      slv1.all(slv1'LEFT downto i+1) := (others => '0');
    else
      slv1.all(slv1'LEFT downto i+1) := (others => slv1.all(i));
    end if;
  end if;
  sig := slv1.all;
  deallocate(slv1);
  deallocate(slv2);
  return;
end read_vector;


procedure readreal(variable ln : inout line; variable val : inout real) is
variable i : integer;
begin
  read(ln, i);
  val := 0.0;
  if ln.all'LENGTH > 0 then
    if ln.all(1) = '.' and ln.all'LENGTH > 1 then
      read(ln, val);
    end if;
  end if;
  val := val + real(i);
end readreal;
 
BEGIN
 
	-- Instantiate the Unit Under Test (UUT)
   uut: user_wrapper_for_pcie PORT MAP (
          trn_clk => trn_clk,
          trn_reset_n => trn_reset_n,
          trn_lnk_up_n => trn_lnk_up_n,
          trn_td => trn_td,
          trn_trem_n => trn_trem_n,
          trn_tsof_n => trn_tsof_n,
          trn_teof_n => trn_teof_n,
          trn_tsrc_rdy_n => trn_tsrc_rdy_n,
          trn_tdst_rdy_n => trn_tdst_rdy_n,
          trn_tsrc_dsc_n => trn_tsrc_dsc_n,
          trn_terrfwd_n => trn_terrfwd_n,
          trn_tdst_dsc_n => trn_tdst_dsc_n,
          trn_tbuf_av => trn_tbuf_av,
          trn_rd => trn_rd,
          trn_rrem_n => trn_rrem_n,
          trn_rsof_n => trn_rsof_n,
          trn_reof_n => trn_reof_n,
          trn_rsrc_rdy_n => trn_rsrc_rdy_n,
          trn_rsrc_dsc_n => trn_rsrc_dsc_n,
          trn_rdst_rdy_n => trn_rdst_rdy_n,
          trn_rerrfwd_n => trn_rerrfwd_n,
          trn_rnp_ok_n => trn_rnp_ok_n,
          trn_rbar_hit_n => trn_rbar_hit_n,
          trn_rfc_nph_av => trn_rfc_nph_av,
          trn_rfc_npd_av => trn_rfc_npd_av,
          trn_rfc_ph_av => trn_rfc_ph_av,
          trn_rfc_pd_av => trn_rfc_pd_av,
          trn_rcpl_streaming_n => trn_rcpl_streaming_n,
          cfg_do => cfg_do,
          cfg_di => cfg_di,
          cfg_byte_en_n => cfg_byte_en_n,
          cfg_dwaddr => cfg_dwaddr,
          cfg_rd_wr_done_n => cfg_rd_wr_done_n,
          cfg_wr_en_n => cfg_wr_en_n,
          cfg_rd_en_n => cfg_rd_en_n,
          cfg_err_cor_n => cfg_err_cor_n,
          cfg_err_ur_n => cfg_err_ur_n,
          cfg_err_cpl_rdy_n => cfg_err_cpl_rdy_n,
          cfg_err_ecrc_n => cfg_err_ecrc_n,
          cfg_err_cpl_timeout_n => cfg_err_cpl_timeout_n,
          cfg_err_cpl_abort_n => cfg_err_cpl_abort_n,
          cfg_err_cpl_unexpect_n => cfg_err_cpl_unexpect_n,
          cfg_err_posted_n => cfg_err_posted_n,
          cfg_interrupt_n => cfg_interrupt_n,
          cfg_interrupt_rdy_n => cfg_interrupt_rdy_n,
          cfg_interrupt_assert_n => cfg_interrupt_assert_n,
          cfg_interrupt_di => cfg_interrupt_di,
          cfg_interrupt_do => cfg_interrupt_do,
          cfg_interrupt_mmenable => cfg_interrupt_mmenable,
          cfg_interrupt_msienable => cfg_interrupt_msienable,
          cfg_turnoff_ok_n => cfg_turnoff_ok_n,
          cfg_to_turnoff_n => cfg_to_turnoff_n,
          cfg_pm_wake_n => cfg_pm_wake_n,
          cfg_pcie_link_state_n => cfg_pcie_link_state_n,
          cfg_trn_pending_n => cfg_trn_pending_n,
          cfg_err_tlp_cpl_header => cfg_err_tlp_cpl_header,
          cfg_bus_number => cfg_bus_number,
          cfg_device_number => cfg_device_number,
          cfg_function_number => cfg_function_number,
          cfg_status => cfg_status,
          cfg_command => cfg_command,
          cfg_dstatus => cfg_dstatus,
          cfg_dcommand => cfg_dcommand,
          cfg_lstatus => cfg_lstatus,
          cfg_lcommand => cfg_lcommand
        );

   -- Clock process definitions
   gen_clk: trn_clk <= not(trn_clk) after T2;
  timeout <= false after 500000 ns;

testbench: process (sync, trn_clk) --FIXME
    variable start : boolean := true;
    variable command : string(8 downto 1);
    variable ln, hex, ln2 : line;
    variable ch : character;
    variable int1, int2 : integer;
    variable arg1, arg2, arg3, arg4 : real;
    variable nxt : integer;
    variable Tm, Sync_delay, delay : time;
    variable QW  : std_logic_vector (63 downto 0);
    variable DW  : std_logic_vector(31 downto 0);
    variable rx_FMT_TYPE   : std_logic_vector(7 downto 0);
    variable rx_len     : integer;
    variable rx_rid_tag : std_logic_vector(23 downto 0);
    variable DW_BE      : std_logic_vector(7 downto 0);
    variable rrem      : std_logic_vector(7 downto 0);
  begin
    cfg_bus_number<=x"01";
    cfg_device_number<="00000";
    cfg_function_number<="000";
    trn_tdst_dsc_n<='1';
  
    if not endfile(sim_in) then
      if start then
        Tm := T;
        start := false;
      end if;
      if sync = '1' then
        -- view_opb <= '1', '0' after 1 ns;    -- REMOVE
        delay := 0 fs;
        readline(sim_in, ln);
        Command := (others => ' ');
        if ln.all'LENGTH > 0 then
          for i in Command'RANGE loop
            read(ln, Command(i));
            exit when Command(i) = ' ' or ln.all'LENGTH = 0;
          end loop;
        end if;
        case Command is
            when "clock   " =>
                delay := trn_clk'LAST_ACTIVE;
                if delay > 0 fs then
                  delay := Tm - trn_clk'LAST_EVENT;
                else
                  delay := T2 - delay;
                end if;
                read(ln, nxt);
                Tm := nxt * Tu;
                if trn_clk = '0' then
                  T <= Tm;
                  T2 <= Tm/2;
                else
                  T <= Tm after T2;
                  T2 <= Tm/2 after T2;
                end if;
            when "reset   " =>
                readreal(ln, arg1);
                readreal(ln, arg2);
                if arg1 > 0.0 then
                  trn_reset_n <= '0' after arg1*Tm, '1' after arg2*Tm;
                else
                  trn_reset_n <= '0', '1' after arg2*Tm;
                end if;
                trn_rsrc_rdy_n<='1';
                trn_rsof_n<='1';
                trn_reof_n<='1';
                trn_rd <= (others=>'0');
                trn_rrem_n<=(others=>'1');
                trn_rbar_hit_n<="1111111";
            when "delay   " =>
                readreal(ln, arg1);
                delay := arg1 * Tm;
            when "stop    " =>
                if ln.all'LENGTH > 0 then readreal(ln,arg1); else arg1:=0.0; end if;
                if (arg1 > 0.0) then
                  stop <= false after arg1*Tm;
                else
                  stop <= false;
                end if;
            when "sync    " =>
                if trn_clk'LAST_VALUE = '0' then
                  delay := Tm - trn_clk'LAST_EVENT;
                else
                  delay := T2 - trn_clk'LAST_EVENT;
                end if;
            when "data_nul" =>  --trn_rd all 0
                trn_rd <= (others=>'0');
            when "core_rdy" =>  --asserts trn_rsrc_rdy_n
                trn_rsrc_rdy_n <= '0'; 
            when "cor_nrdy" =>  --deasserts trn_rsrc_rdy_n
                trn_rsrc_rdy_n <= '1'; 
            when "rsof    " =>  --asserts/deasserts trn_rsof_n
                trn_rsof_n <= '0', '1' after 10.01 ns;
            when "reof    " =>  --asserts/deasserts trn_reof_n
                trn_reof_n <= '0', '1' after 10.01 ns;      
            when "rx_QW   " =>  --Data QW
                read_vector(ln, QW);
                trn_rd <= QW;
            when "rx_DW1  " =>  --Data DW (63 downto 32)
                read_vector(ln, DW);
                trn_rd(63 downto 32) <= DW;
            when "rx_DW2  " =>  --Data DW (31 downto 0)
                read_vector(ln, DW);
                trn_rd(31 downto 0) <= DW;   
            when "rx_adr32" =>  --address DW for 32 bit addressing
                read_vector(ln, DW);
                trn_rd(63 downto 34) <= DW(29 downto 0);
            when "rx_adr64" =>  --address QW for 64 bit addressing
                read_vector(ln, QW);
                trn_rd(63 downto 2) <= QW(61 downto 0);                 
            when "rx_FMTYP" =>  --rx FMT and TYPE (header)
                read_vector(ln, rx_FMT_TYPE);
                trn_rd(62 downto 56) <= rx_FMT_TYPE(6 downto 0);                
            when "rx_len  " =>  --rx length in DW (header)
                read(ln, rx_len);
                trn_rd(41 downto 32) <= conv_std_logic_vector(rx_len, 10);             
            when "rx_idtag" =>  --rx Requester ID and Tag (header)
                read_vector(ln, rx_rid_tag);
                trn_rd(31 downto 8) <= rx_rid_tag;             
            when "rx_DW_BE" =>  --Last and 1st DW Byte Enable
                read_vector(ln, DW_BE);
                trn_rd(7 downto 0) <= DW_BE;             
            when "rrem    " =>  --receive data remainder (on trn_rrem_n)
                read_vector(ln, rrem);
                trn_rrem_n <= rrem; 
            when "rbar_hit" =>  --receive data remainder (on trn_rrem_n)
                read(ln, int1);
                if conv_std_logic_vector(int1,3)="000" then
                    trn_rbar_hit_n<="1111110";
                elsif conv_std_logic_vector(int1,3)="001" then
                    trn_rbar_hit_n<="1111101";
                elsif  conv_std_logic_vector(int1,3)="111" then --trn_rbar_reset
                    trn_rbar_hit_n<="1111111";
                end if;
            when "read    " =>  
                sync_delay := trn_clk'LAST_EVENT;
                if trn_clk'LAST_VALUE = '1' then
                  sync_delay := T2 - sync_delay;
                elsif sync_delay > 0 fs then
                  sync_delay := T2 - sync_delay;
                else
                  sync_delay := 0 fs;
                end if;
                delay := sync_delay + Tm;
            when others => null;
        end case;
        sync <= '0';
      else
        if delay > 0 fs then
          sync <= '1' after delay;
        else
          sync <= '1';
        end if;
      end if;
    elsif sync = '1' then
      sync <= '0';

    end if;
  end process;
  
  assert stop report "Simulation completed" severity failure;
  assert timeout report "Simulation timeouted" severity failure;
END;
