-- ======================================================
--   Message Interface Behavioral (Simulation) model
-- ======================================================
--
--  Module      : SIM_MSG
--  Date        : 07/02/2002
--  Author      : L. Bacquart - ALSE
--
-- ==============================================================
--
--  Ver     Modified By      Date      Changes
--  ---     -----------      ----      -------
--  1.0     L. Bacquart    07-02-02    First Written
--  1.1     R. Williams    08-05-02    Syntax change made to all
--                                     instanciated components,
--                                     (changed '0' to GND)
--                                     for compatibility with
--                                     ModelSim5.5b.
--
-- ==============================================================


library IEEE;
  use IEEE.std_logic_1164.all;
  use IEEE.numeric_std.all;

-- pragma translate_off
  use std.textio.all;
  use IEEE.std_logic_textio.all;
-- pragma translate_on

entity SIM_MSG is
  port (
    ADSTRB : out std_logic;
    AD     : out std_logic;
    RDWR   : out std_logic;
    DONE   : in  std_logic;
    AD_BUS : inout std_logic_vector(3 downto 0);
    MFF    : out std_logic;
    MACK   : out std_logic;
    MCLK   : in  std_logic;
    MDAT   : out std_logic;
    --
    START  : in  boolean;                         -- transaction -> start operation
    OP     : in  std_logic;                       -- 1/read - 0/write
    ADDR   : in  std_logic_vector(7 downto 0);    -- address
    DIN    : in  std_logic_vector(7 downto 0);    -- write data
    DOUT   : out std_logic_vector(7 downto 0);    -- read data
    READY  : out boolean                          -- 0/busy - 1/finished
  );
end SIM_MSG;


-- pragma translate_off

architecture Behave of SIM_MSG is

begin

process
  variable L : line;
  variable DATA : std_logic_vector(7 downto 0);
begin
  --
  ADSTRB <= '1';
  AD     <= '1';
  RDWR   <= '1';
  AD_BUS <= (others=>'Z');
  --
  MFF    <= '1';
  MACK   <= '1';
  MDAT   <= '1';

  wait on START'transaction;
  READY <= FALSE;

  if OP='1' then
    -- READ operation

    -- write address top nibble
    wait for 20 ns;
    AD     <= '1';
    RDWR   <= '0';
    AD_BUS <= ADDR(7 downto 4);
    ADSTRB <= '1';
    wait for 20 ns;
    ADSTRB <= '0';
    wait for 100 ns;
    ADSTRB <= '1';
    wait for 20 ns;

    -- write address bottom nibble
    AD     <= '1';
    RDWR   <= '0';
    AD_BUS <= ADDR(3 downto 0);
    ADSTRB <= '1';
    wait for 20 ns;
    ADSTRB <= '0';
    wait for 100 ns;
    ADSTRB <= '1';
    wait for 20 ns;

    -- read top data nibble
    AD     <= '0';
    RDWR   <= '1';
    AD_BUS <= (others=>'Z');
    ADSTRB <= '1';
    wait for 20 ns;
    ADSTRB <= '0';
    wait for 100 ns;
    DATA(7 downto 4) := AD_BUS;
    ADSTRB <= '1';
    wait for 20 ns;

    -- read bottom data nibble
    AD     <= '0';
    RDWR   <= '1';
    AD_BUS <= (others=>'Z');
    ADSTRB <= '1';
    wait for 20 ns;
    ADSTRB <= '0';
    wait for 100 ns;
    DATA(3 downto 0) := AD_BUS;
    ADSTRB <= '1';
    wait for 20 ns;

    -- report
    wait for 100 ns;
    write(L, string'("READ on HSB"));
    write(L, string'("- address "));
    hwrite(L, ADDR);
    write(L, string'("- data "));
    hwrite(L, DATA);
    writeline(output, L);
  else
    -- WRITE operation

    -- write address top nibble
    wait for 20 ns;
    AD     <= '1';
    RDWR   <= '0';
    AD_BUS <= ADDR(7 downto 4);
    ADSTRB <= '1';
    wait for 20 ns;
    ADSTRB <= '0';
    wait for 100 ns;
    ADSTRB <= '1';
    wait for 20 ns;

    -- write address bottom nibble
    AD     <= '1';
    RDWR   <= '0';
    AD_BUS <= ADDR(3 downto 0);
    ADSTRB <= '1';
    wait for 20 ns;
    ADSTRB <= '0';
    wait for 100 ns;
    ADSTRB <= '1';
    wait for 20 ns;

    -- write top data nibble
    AD     <= '0';
    RDWR   <= '0';
    AD_BUS <= DIN(7 downto 4);
    ADSTRB <= '1';
    wait for 20 ns;
    ADSTRB <= '0';
    wait for 100 ns;
    ADSTRB <= '1';
    wait for 20 ns;

    -- read bottom data nibble
    AD     <= '0';
    RDWR   <= '0';
    AD_BUS <= DIN(3 downto 0);
    ADSTRB <= '1';
    wait for 20 ns;
    ADSTRB <= '0';
    wait for 100 ns;
    ADSTRB <= '1';
    wait for 20 ns;

    -- report
    wait for 100 ns;
    write(L, string'("WRITE on HSB"));
    write(L, string'("- address "));
    hwrite(L, ADDR);
    write(L, string'("- data "));
    hwrite(L, DIN);
    writeline(output, L);
  end if;

  READY <= TRUE;
end process;

end Behave;

-- pragma translate_on

