-- VHDL Entity vme_firmware.vmebus.symbol
--
-- Created:
--          by - st79.UNKNOWN (TE2MOZAMBIQUE)
--          at - 16:21:45 25/08/2004
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2003.2 (Build 28)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY exemplar;
USE exemplar.exemplar_1164.all;

ENTITY vmebus IS
   PORT( 
      amin      : IN     STD_LOGIC_vector (5 DOWNTO 0);
      adr       : INOUT  STD_LOGIC_vector (31 DOWNTO 0) := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
      data      : INOUT  STD_LOGIC_vector (31 DOWNTO 0) := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
      mode      : IN     STD_LOGIC_vector (1 DOWNTO 0);                                         -- 1 - byte, 2-two byte, 3- quad byte
      burst     : IN     std_logic;                                                             -- 1 run burst mode
      burst_cnt : IN     STD_LOGIC_vector (7 DOWNTO 0);                                         -- burst count
      not_r_w   : IN     std_logic;
      go        : IN     std_logic;
      sysclk    : IN     std_logic;
      am        : OUT    STD_LOGIC_vector (5 DOWNTO 0)  := "ZZZZZZ";
      abus      : INOUT  STD_LOGIC_vector (31 DOWNTO 1) := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
      dbus      : INOUT  STD_LOGIC_vector (31 DOWNTO 0) := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
      not_as    : OUT    STD_LOGIC;
      not_ds0   : OUT    STD_LOGIC;
      not_ds1   : OUT    STD_LOGIC;
      not_lword : OUT    STD_LOGIC;
      not_write : OUT    STD_LOGIC;
      not_dtack : IN     STD_LOGIC
   );

-- Declarations

END vmebus ;



library ieee;
use ieee.std_logic_1164.all;
--library exemplar;
--use exemplar.exemplar_1164.all;


architecture operate_vmebus of vmebus is

type bus_state is
	(pre_ad, ad_on, ad_off);

signal ad_state : bus_state := pre_ad;
signal xburst_cnt : std_logic_vector(7 downto 0);

constant single_byte: STD_LOGIC_vector := "01";
constant double_byte: STD_LOGIC_vector := "10";
constant quad_byte: STD_LOGIC_vector := "11";
constant adr_ds_delay : time := 35 ns; -- shud be 35?
constant ds_end_delay : time := 5 ns;  -- should be 5
constant as_end_delay : time := 5 ns;
constant lword_end_delay : time := 5 ns;
constant adr_end_delay : time := 5 ns;	-- shud be 5
constant adr_ad_delay : time := 35 ns; -- shud be 35?
constant ds_off_delay : time := 40 ns;

begin
proc_op:			-- optional label
process --(go,not_dtack,data,adr,mode,not_r_w)
-- declarations
begin
  case ad_state is
  when pre_ad =>
  not_as <= '1';
  not_write <= '1';
  not_ds0 <= '1';
  not_ds1 <= '1';
  not_lword <= '1';
  wait until (go='1');
  xburst_cnt <= burst_cnt;
  abus <= adr(31 downto 1);
  am <= amin;
  ad_state <= ad_on;
  when  ad_on =>
    if (not_r_w='1') then -- read
	not_write <= '1';
     case mode is
      when single_byte =>
         not_lword <= '1';
	    not_as <= TRANSPORT '0' after adr_ad_delay;
	    case adr(0) is
	    when '0' =>
	      not_ds1 <= TRANSPORT '0' after adr_ds_delay;
	      not_ds0 <= TRANSPORT '1' after adr_ds_delay;
	    when '1' =>
	      not_ds1 <= TRANSPORT '1' after adr_ds_delay;
	      not_ds0 <= TRANSPORT '0' after adr_ds_delay;
	    when others =>
	    end case;
      when double_byte =>
         not_lword <= '1';
	    not_as <= TRANSPORT '0' after adr_ad_delay;
	    not_ds1 <= TRANSPORT '0' after adr_ds_delay;
	    not_ds0 <= TRANSPORT '0' after adr_ds_delay;
      when quad_byte =>
          not_lword <= '0';
	    not_as <= TRANSPORT '0' after adr_ad_delay;
	    not_ds1 <= TRANSPORT '0' after adr_ds_delay;
	    not_ds0 <= TRANSPORT '0' after adr_ds_delay;
	 when others =>
     end case;
  else -- write
  	not_write <= '0';
   	dbus <= data; 
   	case mode is
      when single_byte =>
         not_lword <= '1';
	    not_as <= TRANSPORT '0' after adr_ad_delay;
	    case adr(0) is
	    when '0' =>
	      not_ds1 <= TRANSPORT '0' after adr_ds_delay;
	      not_ds0 <= TRANSPORT '1' after adr_ds_delay;
	    when '1' =>
	      not_ds1 <= TRANSPORT '1' after adr_ds_delay;
	      not_ds0 <= TRANSPORT '0' after adr_ds_delay;
	    when others =>
	    end case;
      when double_byte =>
         not_lword <= '1';
	    not_as <= TRANSPORT '0' after adr_ad_delay;
	    not_ds1 <= TRANSPORT '0' after adr_ds_delay;
	    not_ds0 <= TRANSPORT '0' after adr_ds_delay;
      when quad_byte =>
          not_lword <= '0';
	    not_as <= TRANSPORT '0' after adr_ad_delay;
	    not_ds1 <= TRANSPORT '0' after adr_ds_delay;
	    not_ds0 <= TRANSPORT '0' after adr_ds_delay;
	 when others =>
     end case;
 end if;
 wait until (not_dtack='0');
 abus <= "1111111111111111111111111111111";  -- 1's better than X, prevents lots of undef warnings
 not_lword <= '1'; -- see above
 not_ds1 <= TRANSPORT '1' after ds_end_delay;
 not_ds0 <= TRANSPORT '1' after ds_end_delay;
 dbus <= TRANSPORT "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after ds_end_delay;
if (burst='1') then
   wait for ds_off_delay;
   xburst_cnt <= xburst_cnt +"11111111";
   if (xburst_cnt="00000000") then
      ad_state <= ad_off;
   else
     ad_state <= ad_on;
   end if;
else
   ad_state <= ad_off;
end if;
when ad_off =>
   not_as <= TRANSPORT '1' after as_end_delay;
   not_lword <= TRANSPORT '1' after lword_end_delay;
   abus <= TRANSPORT "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after adr_end_delay;
   am <= TRANSPORT "ZZZZZZ"  after adr_end_delay;
  -- wait until(not_dtack='1');
 --  wait until(go='0');
 if not_dtack = 'Z' then
 	ad_state <= pre_ad;
else
	ad_state <= ad_off;
end if;
end case;
wait for 1 ns;
end process;


  
end operate_vmebus;
