-- Model Name : Bus Arbiter Model -- Author : Zainalabedin Navabi -- Last Updated : 09 / 15 / 1996 -- This document is © copyrighted by the Author.

    PACKAGE waiting IS
      TYPE wait_array IS ARRAY (NATURAL RANGE <>) OF NATURAL;
    END waiting;
    --
    USE WORK.waiting.ALL;  
    ENTITY arbitrator IS
      GENERIC (wait_states : wait_array := (0, 1, 2, 3); 
               clock_period : TIME := 1 US);
      PORT (request : IN BIT_VECTOR (3 DOWNTO 0); 
            grant : BUFFER BIT_VECTOR (3 DOWNTO 0); clock : IN BIT);
    END arbitrator;
    --
    ARCHITECTURE behavioral OF arbitrator IS
    BEGIN
      wait_cycle: PROCESS 
      BEGIN
        IF clock = '0' THEN
          WAIT FOR 20 NS;
          FOR i IN request'RANGE LOOP
            IF request(i) = '1' THEN
              IF grant = "0000" THEN 
                WAIT FOR wait_states (i) * clock_period;
                grant (i) <= '1', '0' AFTER clock_period;
              END IF;
            END IF; 
          END LOOP;
        END IF;
        WAIT ON clock;
      END PROCESS wait_cycle;
    END behavioral;
    --
    







    ENTITY arbtest IS END arbtest;
    --
    ARCHITECTURE io OF arbtest IS
      USE WORK.waiting.ALL;
      CONSTANT source_delays : wait_array := (12, 10, 9, 14);
      SIGNAL clk : BIT;
      SIGNAL r, g : BIT_VECTOR (3 DOWNTO 0);
      CONSTANT t : TIME := 1 US;
    BEGIN
      arb : ENTITY WORK.arbitrator (behavioral)
        GENERIC MAP (wait_states => (3 => 0, 2 => 1, 1 => 2, 0 => 3), clock_period =
    > t)
        PORT MAP (r, g, clk);
      clk <= NOT clk AFTER t / 2 WHEN NOW < 40 US ELSE clk;
      sources : FOR i IN  r'RANGE GENERATE
        PROCESS
        BEGIN
          WAIT FOR source_delays (i) * 1 US;
          r(i) <= '1';
          WAIT UNTIL g(i) = '1';
          WAIT UNTIL clk = '0';
          r(i) <= '0';
        END PROCESS;
      END GENERATE;
    --r <= (r1, r2, r3, r4);
    --(g1, g2, g3, g4) <= g;
    END io;