--==============================================================================
-- CERN (BE-CO-HT)
-- Testbench for CONV-TTL-BLO design
--==============================================================================
--
-- author: Theodor Stana (t.stana@cern.ch)
--
-- date of creation: 2014-02-18
--
-- version: 1.0
--
-- description:
--    Design-wide simulation testbench for the CONV-TTL-BLO gateware. Currently
--    simulated features include:
--      - pulse triggering
--      - I2C master for reading register contents
--
-- 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:
--    2014-02-18   Theodor Stana     File created
--==============================================================================
-- TODO: -
--==============================================================================

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


entity testbench is
end entity testbench;


architecture behav of testbench is

  --============================================================================
  -- Type declarations
  --============================================================================
  type t_state_i2c_mst is
    (
      IDLE,
      I2C_ADDR, I2C_ADDR_ACK,

      WB_ADDR_B0, WB_ADDR_B0_ACK,
      WB_ADDR_B1, WB_ADDR_B1_ACK,

      ST_OP,

      RD_RESTART, RD_RESTART_ACK,
      RD, RD_ACK,

      WR, WR_ACK,

      STO,

      SUCCESS,
      ERR
    );


  --============================================================================
  -- Constant declarations
  --============================================================================
  -- Clock periods
  constant c_clk_20_per   : time := 50 ns;
  constant c_clk_125_per  : time :=  8 ns;

  -- Number of I2C masters and slaves for the I2C bus model
  constant c_nr_masters : positive := 1;
  constant c_nr_slaves  : positive := 1;

  --============================================================================
  -- Component declarations
  --============================================================================
  component conv_ttl_blo is
    generic
    (
      g_nr_ttl_chan : natural := 6;
      g_nr_inv_chan : natural := 4;
      g_sim         : boolean := false
    );
    port
    (
      -- Clocks
      -- 20 MHz from VCXO
      clk_20_vcxo_i           : in  std_logic;
      -- 125 MHz from clock generator
      fpga_clk_p_i           : in  std_logic;
      fpga_clk_n_i           : in  std_logic;
  
      -- 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_multicast_2_0_o    : out std_logic;
      led_multicast_3_1_o    : out std_logic;
      led_wr_gmt_ttl_ttln_o  : out std_logic;
      led_wr_link_syserror_o : out std_logic;
      led_wr_ok_syspw_o      : out std_logic;
      led_wr_ownaddr_i2c_o   : out std_logic;
  
      -- I/Os for pulses
      pulse_front_led_n_o    : out std_logic_vector(g_nr_ttl_chan downto 1);
      pulse_rear_led_n_o     : out std_logic_vector(g_nr_ttl_chan downto 1);
      fpga_input_ttl_n_i     : in  std_logic_vector(g_nr_ttl_chan downto 1);
      fpga_out_ttl_o         : out std_logic_vector(g_nr_ttl_chan downto 1);
      fpga_blo_in_i          : in  std_logic_vector(g_nr_ttl_chan downto 1);
      fpga_trig_blo_o        : out std_logic_vector(g_nr_ttl_chan downto 1);
      inv_in_n_i             : in  std_logic_vector(g_nr_inv_chan downto 1);
      inv_out_o              : out std_logic_vector(g_nr_inv_chan downto 1);
  
      -- Output enable lines
      fpga_oe_o              : out std_logic;
      fpga_blo_oe_o          : out std_logic;
      fpga_trig_ttl_oe_o     : out std_logic;
      fpga_inv_oe_o          : out std_logic;
  
      --TTL/INV_TTL_N
      ttl_switch_n_i         : in  std_logic;
  
      extra_switch_n_i       : in  std_logic_vector(7 downto 1);
  
      -- Lines for the i2c_slave
      scl_i                  : in  std_logic;
      scl_o                  : out std_logic;
      scl_oe_o               : out std_logic;
      sda_i                  : in  std_logic;
      sda_o                  : out std_logic;
      sda_oe_o               : out std_logic;
      fpga_ga_i              : in  std_logic_vector(4 downto 0);
      fpga_gap_i             : in  std_logic;
  
      -- Flash memory lines
      fpga_prom_cclk_o       : out std_logic;
      fpga_prom_cso_b_n_o    : out std_logic;
      fpga_prom_mosi_o       : out std_logic;
      fpga_prom_miso_i       : in  std_logic;
  
      -- Blocking power supply reset line
      mr_n_o                 : out std_logic;
  
      -- Thermometer line
      thermometer_b          : inout std_logic;
  
      -- PLL DACs
      -- DAC1: 20 MHz VCXO control
      fpga_plldac1_din_o     : out std_logic;
      fpga_plldac1_sclk_o    : out std_logic;
      fpga_plldac1_sync_n_o  : out std_logic;
      -- DAC2: 125 MHz clock generator control
      fpga_plldac2_din_o     : out std_logic;
      fpga_plldac2_sclk_o    : out std_logic;
      fpga_plldac2_sync_n_o  : out std_logic;
  
      -- SFP lines
      fpga_sfp_los_i         : in    std_logic;
      fpga_sfp_mod_def0_i    : in    std_logic;
      fpga_sfp_rate_select_o : out   std_logic;
      fpga_sfp_mod_def1_b    : inout std_logic;
      fpga_sfp_mod_def2_b    : inout std_logic;
      fpga_sfp_tx_disable_o  : out   std_logic;
      fpga_sfp_tx_fault_i    : in    std_logic;
  
      -- RTM identifiers, should match with the expected values
      fpga_rtmm_n_i          : in std_logic_vector(2 downto 0);
      fpga_rtmp_n_i          : in std_logic_vector(2 downto 0)
    );
  end component conv_ttl_blo;

  -- I2C bus model
  component i2c_bus_model is
    generic
    (
      g_nr_masters : positive := 1;
      g_nr_slaves  : positive := 1
    );
    port
    (
      -- Input ports from master lines
      mscl_i : in  std_logic_vector(g_nr_masters-1 downto 0);
      msda_i : in  std_logic_vector(g_nr_masters-1 downto 0);

      -- Input ports from slave lines
      sscl_i : in  std_logic_vector(g_nr_slaves-1 downto 0);
      ssda_i : in  std_logic_vector(g_nr_slaves-1 downto 0);

      -- SCL and SDA line outputs
      scl_o  : out std_logic;
      sda_o  : out std_logic
    );
  end component i2c_bus_model;

  -- I2C master
  component i2c_master_byte_ctrl is
    port
    (
      clk    : in std_logic;
      rst    : in std_logic; -- synchronous active high reset (WISHBONE compatible)
      nReset : in std_logic;	-- asynchornous active low reset (FPGA compatible)
      ena    : in std_logic; -- core enable signal

      clk_cnt : in unsigned(15 downto 0);	-- 4x SCL

      -- input signals
      start,
      stop,
      read,
      write,
      ack_in : std_logic;
      din    : in std_logic_vector(7 downto 0);

      -- output signals
      cmd_ack  : out std_logic; -- command done
      ack_out  : out std_logic;
      i2c_busy : out std_logic; -- arbitration lost
      i2c_al   : out std_logic; -- i2c bus busy
      dout     : out std_logic_vector(7 downto 0);

      -- i2c lines
      scl_i   : in std_logic;  -- i2c clock line input
      scl_o   : out std_logic; -- i2c clock line output
      scl_oen : out std_logic; -- i2c clock line output enable, active low
      sda_i   : in std_logic;  -- i2c data line input
      sda_o   : out std_logic; -- i2c data line output
      sda_oen : out std_logic  -- i2c data line output enable, active low
    );
  end component i2c_master_byte_ctrl;

  --============================================================================
  -- Signal declarations
  --============================================================================
  signal clk_20, clk_125              : std_logic;
  signal clk_125_p, clk_125_n         : std_logic;
  signal rst_n, rst                   : std_logic;

  signal pulse_led_front_n            : std_logic_vector(6 downto 1);
  signal pulse_led_front              : std_logic_vector(6 downto 1);
  signal pulse_led_rear_n             : std_logic_vector(6 downto 1);
  signal pulse_led_rear               : std_logic_vector(6 downto 1);
  signal ttl_inp_n, ttl_outp          : std_logic_vector(6 downto 1);
  signal ttl_pulse                    : std_logic_vector(6 downto 1);
  signal inv_pulse                    : std_logic_vector(6 downto 1);
  signal blo_inp, blo_outp            : std_logic_vector(6 downto 1);
  signal blo_pulse                    : std_logic_vector(6 downto 1);
  signal oe, blo_oe, ttl_oe, inv_oe   : std_logic;
  signal ttl_switch_n                 : std_logic;
  signal switches_n                   : std_logic_vector(7 downto 1);

  -- I2C signals
  signal state_i2c_mst                : t_state_i2c_mst;

  signal mst_fsm_op                   : std_logic;
  signal mst_fsm_start                : std_logic;
  signal stim_cnt                     : unsigned(31 downto 0);

  signal cnt                          : unsigned(2 downto 0);
  signal buf_byte_cnt                 : integer;
  signal once                         : boolean;

  signal byte_cnt                     : unsigned(1 downto 0);
  signal rcvd                         : std_logic_vector(31 downto 0);
  signal send                         : std_logic_vector(31 downto 0);
  signal send_val                     : std_logic_vector(31 downto 0);
  signal wrote                        : std_logic;
  signal slv_addr                     : std_logic_vector(6 downto 0);
  signal adr                          : std_logic_vector(31 downto 0);

  signal mst_sta                      : std_logic;
  signal mst_sto                      : std_logic;
  signal mst_rd                       : std_logic;
  signal mst_wr                       : std_logic;
  signal mst_ack                      : std_logic;
  signal mst_dat_in                   : std_logic_vector(7 downto 0);
  signal mst_dat_out                  : std_logic_vector(7 downto 0);
  signal mst_cmd_ack                  : std_logic;
  signal ack_fr_slv                   : std_logic;

  signal mscl, msda                   : std_logic_vector(c_nr_masters-1 downto 0);
  signal sscl, ssda                   : std_logic_vector(c_nr_slaves-1 downto 0);
  signal scl, sda                     : std_logic;

  signal scl_fr_mst                   : std_logic;
  signal scl_en_mst                   : std_logic;
  signal sda_fr_mst                   : std_logic;
  signal sda_en_mst                   : std_logic;

  signal scl_fr_slv                   : std_logic;
  signal scl_en_slv                   : std_logic;
  signal sda_fr_slv                   : std_logic;
  signal sda_en_slv                   : std_logic;

  signal t                            : boolean;

--==============================================================================
--  architecture begin
--==============================================================================
begin

  --============================================================================
  -- Generate clock signals
  --============================================================================
  p_clk_20 : process
  begin
    clk_20 <= '0';
    wait for c_clk_20_per/2;
    clk_20 <= '1';
    wait for c_clk_20_per/2;
  end process;

  p_clk_125 : process
  begin
    clk_125 <= '0';
    wait for c_clk_125_per/2;
    clk_125 <= '1';
    wait for c_clk_125_per/2;
  end process;

  clk_125_p <= clk_125;
  clk_125_n <= not clk_125;

  --============================================================================
  -- Instantiate the DUT
  --============================================================================
  cmp_dut : conv_ttl_blo
    generic map
    (
      g_nr_ttl_chan => 6,
      g_nr_inv_chan => 4,
      g_sim         => true
    )
    port map
    (
      -- Clocks
      -- 20 MHz from VCXO
      clk_20_vcxo_i          => clk_20,
      -- 125 MHz from clock generator
      fpga_clk_p_i           => clk_125_p,
      fpga_clk_n_i           => clk_125_n,

      -- LEDs
      led_ctrl0_o            => open,
      led_ctrl0_oen_o        => open,
      led_ctrl1_o            => open,
      led_ctrl1_oen_o        => open,
      led_multicast_2_0_o    => open,
      led_multicast_3_1_o    => open,
      led_wr_gmt_ttl_ttln_o  => open,
      led_wr_link_syserror_o => open,
      led_wr_ok_syspw_o      => open,
      led_wr_ownaddr_i2c_o   => open,

      -- I/Os for pulses
      pulse_front_led_n_o    => pulse_led_front_n,
      pulse_rear_led_n_o     => pulse_led_rear_n,
      fpga_input_ttl_n_i     => ttl_inp_n,
      fpga_out_ttl_o         => ttl_outp,
      fpga_blo_in_i          => blo_inp,
      fpga_trig_blo_o        => blo_outp,
      inv_in_n_i             => (others => '1'),
      inv_out_o              => open,

      -- Output enable lines
      fpga_oe_o              => oe,
      fpga_blo_oe_o          => blo_oe,
      fpga_trig_ttl_oe_o     => ttl_oe,
      fpga_inv_oe_o          => inv_oe,

      --TTL/INV_TTL_N
      ttl_switch_n_i         => ttl_switch_n,

      extra_switch_n_i       => switches_n,

      -- Lines for the i2c_slave
      scl_i                  => scl,
      scl_o                  => scl_fr_slv,
      scl_oe_o               => scl_en_slv,
      sda_i                  => sda,
      sda_o                  => sda_fr_slv,
      sda_oe_o               => sda_en_slv,
      fpga_ga_i              => "11110",
      fpga_gap_i             => '0',

      -- Flash memory lines
      fpga_prom_cclk_o       => open,
      fpga_prom_cso_b_n_o    => open,
      fpga_prom_mosi_o       => open,
      fpga_prom_miso_i       => 'Z',

      -- Blocking power supply reset line
      mr_n_o                 => rst_n,

      -- Thermometer line
      thermometer_b          => open,

      -- PLL DACs
      -- DAC1: 20 MHz VCXO control
      fpga_plldac1_din_o     => open,
      fpga_plldac1_sclk_o    => open,
      fpga_plldac1_sync_n_o  => open,
      -- DAC2: 125 MHz clock generator control
      fpga_plldac2_din_o     => open,
      fpga_plldac2_sclk_o    => open,
      fpga_plldac2_sync_n_o  => open,

      -- SFP lines
      fpga_sfp_los_i         => '1',
      fpga_sfp_mod_def0_i    => '1',
      fpga_sfp_rate_select_o => open,
      fpga_sfp_mod_def1_b    => open,
      fpga_sfp_mod_def2_b    => open,
      fpga_sfp_tx_disable_o  => open,
      fpga_sfp_tx_fault_i    => '1',

      -- RTM identifiers, should match with the expected values
      fpga_rtmm_n_i          => (others => '0'),
      fpga_rtmp_n_i          => (others => '0')
    );

  -- Tri-state buffers on the I2C lines
  sscl(0) <= scl_fr_slv when (scl_en_slv = '1') else
             '1';
  ssda(0) <= sda_fr_slv when (sda_en_slv = '1') else
             '1';

  -- Active-high reset
  rst <= not rst_n;

  --============================================================================
  -- Pulse outputs assignment based on OE signals
  --============================================================================
  ttl_pulse <= ttl_outp when (oe = '1') and (ttl_oe = '1') else (others => '0');
  blo_pulse <= blo_outp when (oe = '1') and (blo_oe = '1') else (others => '0');
  inv_pulse <= blo_outp when (oe = '1') and (inv_oe = '1') else (others => '0');

  --============================================================================
  -- Switches
  --============================================================================
  -- TTL
  ttl_switch_n <= '0';
  -- GF
  switches_n(1) <= '0';
  -- other
  switches_n(7 downto 2) <= (others => '1');

  --============================================================================
  -- Pulse LEDs
  --============================================================================
  pulse_led_front <= not pulse_led_front_n;
  pulse_led_rear  <= not pulse_led_rear_n;

  --============================================================================
  -- Pulse stimuli
  --============================================================================
  blo_inp(6) <= '0';
  ttl_inp_n(5 downto 1) <= (others => '1');
  gen_pulse_chain : for i in 6 downto 2 generate
    blo_inp(i-1) <= blo_outp(i);
  end generate gen_pulse_chain;

  p_stim_pulse : process
  begin
    ttl_inp_n(6) <= '1';
    wait until t = true;
    while (t = true) loop
      wait for 240 us;
      ttl_inp_n(6) <= '0';
      wait for 500 ns;
      ttl_inp_n(6) <= '1';
      if ttl_outp(6) /= '1' then
        assert false report "ttl_outp not '1'" severity warning;
      end if;
      if blo_outp(6) /= '1' then
        assert false report "blo_outp not '1'" severity warning;
      end if;
    end loop;
  end process p_stim_pulse;

  process
  begin
    t <= true;
    wait for 2 ms;
    t <= false;
    wait for 500 ms;
    t <= true;
    wait for 10 ms;
    t <= false;
    wait;
  end process;

  --============================================================================
  -- I2C master
  --============================================================================
  ------------------------------------------------------------------------------
  -- First, the component instantiation
  ------------------------------------------------------------------------------
  cmp_master : i2c_master_byte_ctrl
    port map
    (
      clk      => clk_20,
      rst      => rst,
      nReset   => rst_n,
      ena      => '1',

      clk_cnt  => x"0027",

      -- input signals
      start    => mst_sta,
      stop     => mst_sto,
      read     => mst_rd,
      write    => mst_wr,
      ack_in   => mst_ack,
      din      => mst_dat_in,

      -- output signals
      cmd_ack  => mst_cmd_ack,
      ack_out  => ack_fr_slv,
      i2c_busy => open,
      i2c_al   => open,
      dout     => mst_dat_out,

      -- i2c lines
      scl_i    => scl,
      scl_o    => scl_fr_mst,
      scl_oen  => scl_en_mst,
      sda_i    => sda,
      sda_o    => sda_fr_mst,
      sda_oen  => sda_en_mst
    );

  -- Then, the tri-state_i2c_mst buffers on the line
  mscl(0) <= scl_fr_mst when (scl_en_mst = '0') else
             '1';
  msda(0) <= sda_fr_mst when (sda_en_mst = '0') else
             '1';

  ------------------------------------------------------------------------------
  -- Bus model instantiation and connection to master and slaves
  ------------------------------------------------------------------------------
  cmp_i2c_bus : i2c_bus_model
    generic map
    (
      g_nr_masters => c_nr_masters,
      g_nr_slaves  => c_nr_slaves
    )
    port map
    (
      mscl_i => mscl,
      msda_i => msda,
      sscl_i => sscl,
      ssda_i => ssda,
      scl_o  => scl,
      sda_o  => sda
    );

  ------------------------------------------------------------------------------
  -- This FSM controls the signals to the master component to implement the I2C
  -- protocol defined together with ELMA. The FSM is controlled by the
  -- stimuli process below
  ------------------------------------------------------------------------------
  p_mst_fsm : process (clk_20) is
  begin
    if rising_edge(clk_20) then
      if (rst_n = '0') then
        state_i2c_mst      <= IDLE;
        mst_sta    <= '0';
        mst_wr     <= '0';
        mst_sto    <= '0';
        mst_rd     <= '0';
        mst_dat_in <= (others => '0');
        mst_ack    <= '0';
        cnt        <= (others => '0');
        once       <= true;
        byte_cnt   <= (others => '0');
        rcvd       <= (others => '0');
        send       <= (others => '0');
      else
        case state_i2c_mst is

          when IDLE =>
            if (mst_fsm_start = '1') then
              state_i2c_mst <= I2C_ADDR;
              send  <= std_logic_vector(send_val);
            end if;

          when I2C_ADDR =>
            mst_sta   <= '1';
            mst_wr    <= '1';
            mst_dat_in <= slv_addr & '0';
            if (mst_cmd_ack = '1') then
              mst_sta <= '0';
              mst_wr  <= '0';
              state_i2c_mst   <= I2C_ADDR_ACK;
            end if;

          when I2C_ADDR_ACK =>
            cnt <= cnt + 1;
            if (cnt = 7) then
              if (ack_fr_slv = '0') then
                state_i2c_mst <= WB_ADDR_B0;
              else
                state_i2c_mst <= ERR;
              end if;
            end if;

          when WB_ADDR_B0 =>
            mst_wr <= '1';
            mst_dat_in <= adr(15 downto 8);
            if (mst_cmd_ack = '1') then
              mst_wr <= '0';
              state_i2c_mst  <= WB_ADDR_B0_ACK;
            end if;

          when WB_ADDR_B0_ACK =>
            cnt <= cnt + 1;
            if (cnt = 7) then
              if (ack_fr_slv = '0') then
                state_i2c_mst <= WB_ADDR_B1;
              else
                state_i2c_mst <= ERR;
              end if;
            end if;

          when WB_ADDR_B1 =>
            mst_wr <= '1';
            mst_dat_in <= adr(7 downto 0);
            if (mst_cmd_ack = '1') then
              mst_wr <= '0';
              state_i2c_mst  <= WB_ADDR_B1_ACK;
            end if;

          when WB_ADDR_B1_ACK =>
            cnt <= cnt + 1;
            if (cnt = 7) then
              if (ack_fr_slv = '0') then
                state_i2c_mst <= ST_OP;
              else
                state_i2c_mst <= ERR;
              end if;
            end if;

          when ST_OP =>
            if (mst_fsm_op = '1') then
              state_i2c_mst <= RD_RESTART;
            else
              state_i2c_mst <= WR;
            end if;

          when RD_RESTART =>
            mst_wr <= '1';
            mst_dat_in <= slv_addr & '1';
            mst_sta <= '1';
            if (mst_cmd_ack = '1') then
              mst_sta <= '0';
              mst_wr  <= '0';
              state_i2c_mst <= RD_RESTART_ACK;
            end if;

          when RD_RESTART_ACK =>
            cnt <= cnt + 1;
            if (cnt = 7) then
              if (ack_fr_slv = '0') then
                state_i2c_mst <= RD;
              else
                state_i2c_mst <= ERR;
              end if;
            end if;

          when RD =>
            mst_rd <= '1';
            mst_ack <= '0';
            if (byte_cnt = 3) then
              mst_ack <= '1';
            end if;
            if (mst_cmd_ack = '1') then
              mst_rd <= '0';
              byte_cnt <= byte_cnt + 1;
              rcvd     <= mst_dat_out & rcvd(31 downto 8);
              mst_ack  <= '0';
              state_i2c_mst    <= RD;
              if (byte_cnt = 3) then
                state_i2c_mst  <= STO;
              end if;
            end if;

          when RD_ACK =>
            cnt <= cnt + 1;
            if (cnt = 7) then
              byte_cnt <= byte_cnt + 1;
              rcvd     <= mst_dat_out & rcvd(31 downto 8);
              mst_ack  <= '0';
              state_i2c_mst <= RD;
              if (byte_cnt = 3) then
                state_i2c_mst  <= STO;
              end if;
            end if;

          when WR =>
            mst_wr <= '1';
            mst_dat_in <= send(7 downto 0);
            if (mst_cmd_ack = '1') then
              mst_wr <= '0';
              state_i2c_mst  <= WR_ACK;
            end if;

          when WR_ACK =>
            cnt <= cnt + 1;
            if (cnt = 7) then
              if (ack_fr_slv = '0') then
                byte_cnt <= byte_cnt + 1;
                send     <= x"00" & send(31 downto 8);
                state_i2c_mst    <= WR;
                if (byte_cnt = 3) then
                  state_i2c_mst  <= STO;
                end if;
              else
                state_i2c_mst <= ERR;
              end if;
            end if;

          when STO =>
            mst_sto <= '1';
            if (mst_cmd_ack = '1') then
              mst_sto <= '0';
              state_i2c_mst   <= IDLE;
            end if;

          when ERR =>
            if (once) then
              report("Error!");
              once <= false;
            end if;

          when others =>
            state_i2c_mst <= ERR;

        end case;
      end if;
    end if;
  end process p_mst_fsm;

  ------------------------------------------------------------------------------
  -- Process to "stimulate" the master FSM above
  ------------------------------------------------------------------------------
  p_stim_mst_fsm : process (rst_n, t, state_i2c_mst)
  begin
    if (rst_n = '0') then
      mst_fsm_start <= '0';
      mst_fsm_op    <= '0';
      slv_addr      <= "1011110";
      adr           <= (others => '0');
      buf_byte_cnt  <= 0;
    elsif (not t) and (state_i2c_mst = IDLE) then
      mst_fsm_start <= '1';
      mst_fsm_op    <= '1';
      buf_byte_cnt  <= buf_byte_cnt + 1;
      case buf_byte_cnt is
        when 0 =>
          adr(11 downto 0) <= x"030";
        when 1 =>
          adr(11 downto 0) <= x"034";
        when 2 =>
          adr(11 downto 0) <= x"038";
        when 3 =>
          adr(11 downto 0) <= x"02c";
          buf_byte_cnt     <= 0;
        when others =>
          buf_byte_cnt <= 0;
      end case;
    else
      mst_fsm_start <= '0';
    end if;
  end process p_stim_mst_fsm;

end architecture behav;
--==============================================================================
--  architecture end
--==============================================================================
