Top Level VHDL Code

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity elevchip is

    port (
        clock, reset_not, cs_req_not, int_req, up_req : in std_logic;
        req_floor : in std_logic_vector(5 downto 0);
        req_car_id : in std_logic_vector(3 downto 0);
        elev_busy, hsync, vsync : out std_logic;
        rgb : out std_logic_vector(2 downto 0)
    );

end elevchip;

architecture mixed of elevchip is

-- constants

-- components/modules
component ramm
port(    write_data_A,
        write_data_B,
        write_data_C,
        write_data_D : in std_logic_vector(7 downto 0);
        address_A,
        address_B,
        address_C,
        address_D : in std_logic_vector(7 downto 0);
        mem_request_A,
        mem_request_B,
        mem_request_C,
        mem_request_D : in std_logic;
        we_A, we_B, we_C, we_D, clock     : in std_logic;

        read_data_A,
        read_data_B,
        read_data_C,
        read_data_D : out std_logic_vector(7 downto 0);
        mem_ready_A,
        mem_ready_B,
        mem_ready_C,
        mem_ready_D : out std_logic);
end component;

component vgadisp
    port (
        clock : in std_logic;
        data : in std_logic_vector(7 downto 0);
        address : out std_logic_vector(7 downto 0);
        dtreq : out std_logic;
        hsync, vsync : out std_logic;
        rgb : out std_logic_vector(2 downto 0)
    );
end component;

component car_router
    port (
        clock, reset, r_req, u_not_d, dtack : in std_logic;
        start_loc : in std_logic_vector(7 downto 0);
        dest_flr : in std_logic_vector(5 downto 0);
        req_car : in std_logic_vector(3 downto 0);
        rdata : in std_logic_vector(7 downto 0);
        busy, we, dtreq : out std_logic;
        address : out std_logic_vector(7 downto 0);
        wdata : out std_logic_vector(7 downto 0)
    );
end component;

component car_sel
    PORT (
        kick_off, clock, internal, up, reg_ready, mem_ready : IN std_logic;       
        slow_clock : in std_logic;
        floor_req : IN std_logic_vector(5 downto 0);
        car_id : IN std_logic_vector(3 downto 0);
        reg_out : in std_logic_vector(11 downto 0);
        mem_out : in std_logic_vector(7 downto 0);
        reg_addr, car_to_move : out std_logic_vector(3 downto 0);
        reg_in : out std_logic_vector(11 downto 0);
        reg_we, reg_request, mem_we, mem_request, path, ready : out std_logic;
        request_location : out std_logic_vector(5 downto 0);
        mem_in, current_location : out std_logic_vector(7 downto 0);
        mem_addr : out std_logic_vector(7 downto 0)
    );
end component;

component car_drv
    PORT (
        reset, clock, slow_clock : IN std_logic;
        car_id : IN std_logic_vector(3 downto 0);
        data_in : IN std_logic_vector(7 downto 0);            
        location : OUT std_logic_vector(7 downto 0);
        busy : out std_logic;
        move_car : OUT std_logic_vector(3 downto 0)
    );
end component;

component car_reg
    port(    write_data_A, write_data_B : in std_logic_vector(11 downto 0);
            address_A, address_B, address_C : in std_logic_vector(3 downto 0);
            request_A, request_B, request_C : in std_logic;
            we_A, we_B, clock     : in std_logic;

            read_data_A, read_data_B, read_data_C: out std_logic_vector(11 downto 0);
            ready_A, ready_B, ready_C : out std_logic);
end component;

component hndlr
    port(   
            reg_data : in std_logic_vector(11 downto 0);
            location_status : in std_logic_vector(7 downto 0);
            read_data : in std_logic_vector(7 downto 0);
            car_id : in std_logic_vector(3 downto 0);
            clock, mem_ready, reg_ready : in std_logic;

            new_address : out std_logic_vector(11 downto 0);
            write_data : out std_logic_vector(7 downto 0);
            mem_address : out std_logic_vector(7 downto 0);
            reg_address : out std_logic_vector(3 downto 0);
            write_en, mem_request, reg_request, reg_we : out std_logic);
end component;

-- signals
signal slow_clock : std_logic;
signal cs_req, reset : std_logic;
signal vga_rdata, vga_wdata, vga_addr : std_logic_vector(7 downto 0);
signal vga_memreq, vga_memrdy, vga_we: std_logic;

signal crout_rdata, crout_wdata, crout_addr : std_logic_vector(7 downto 0);
signal crout_carid : std_logic_vector(3 downto 0);
signal crout_req, crout_memrdy, crout_busy, crout_we, crout_memreq : std_logic;

signal mh_rdata, mh_wdata, mh_addr : std_logic_vector(7 downto 0);
signal mh_we, mh_memreq, mh_memrdy : std_logic;
signal mh_next_loc, mh_reg_data : std_logic_vector(11 downto 0);
signal mh_reg_addr : std_logic_vector(3 downto 0);
signal mh_reg_req, mh_reg_we, mh_reg_rdy : std_logic;

signal cs_rdata, cs_wdata, cs_addr, cs_start : std_logic_vector(7 downto 0);
signal cs_we, cs_memreq, cs_memrdy, cs_path : std_logic;
signal cs_next_loc, cs_reg_data : std_logic_vector(11 downto 0);
signal cs_reg_addr : std_logic_vector(3 downto 0);
signal cs_reg_req, cs_reg_we, cs_reg_rdy, cs_ready : std_logic;
signal cs_end : std_logic_vector(5 downto 0);

signal cd_req, cd_busy : std_logic;
signal movecar_req, car_moved : std_logic_vector(3 downto 0);
signal move_loc, next_loc : std_logic_vector(7 downto 0);

signal sim_reg_addr : std_logic_vector(3 downto 0);
signal sim_reg_data : std_logic_vector(11 downto 0);
signal sim_reg_req, sim_reg_rdy : std_logic;

begin

    -- since VGA and simulator are read only, the write inputs are dummy signals
    vga_wdata <= "00000000";
    vga_we <= '0';

    cs_req <= not cs_req_not;
    reset <= not reset_not;
   
    crout_req <= cs_ready and (not crout_busy) and (not cs_path);
    elev_busy <= crout_busy or (not cs_ready);

    rm : ramm
        port map (
            write_data_A => cs_wdata,
            write_data_B => mh_wdata,
            write_data_C => crout_wdata,
            write_data_D => vga_wdata,
            address_A => cs_addr,
            address_B => mh_addr,
            address_C => crout_addr,
            address_D => vga_addr,
            mem_request_A => cs_memreq,
            mem_request_B => mh_memreq,
            mem_request_C => crout_memreq,
            mem_request_D => vga_memreq,
            we_A => cs_we,
            we_B => mh_we,
            we_C => crout_we,
            we_D => vga_we,
            clock => clock,
            read_data_A => cs_rdata,
            read_data_B => mh_rdata,
            read_data_C => crout_rdata,
            read_data_D => vga_rdata,
            mem_ready_A => cs_memrdy,
            mem_ready_B => mh_memrdy,
            mem_ready_C => crout_memrdy,
            mem_ready_D => vga_memrdy
        );

    vga : vgadisp
        port map (
            clock => clock, data => vga_rdata, address => vga_addr,
            dtreq => vga_memreq,
            hsync => hsync, vsync => vsync,
            rgb => rgb
        );

    crout : car_router
        port map (
            clock => slow_clock, reset => reset, r_req => crout_req,
            u_not_d => up_req, dtack => crout_memrdy,
            start_loc => cs_start, dest_flr => cs_end,
            req_car => crout_carid,
            rdata => crout_rdata, busy => crout_busy, we => crout_we,
            dtreq => crout_memreq,
            address => crout_addr,
            wdata => crout_wdata
        );

    cs : car_sel
        port map (
            kick_off => cs_req, clock => clock, internal => int_req, up => up_req,
            reg_ready => cs_reg_rdy, mem_ready => cs_memrdy, slow_clock => slow_clock,
            floor_req => req_floor, car_id => req_car_id,
            reg_out => cs_reg_data, mem_out => cs_rdata,
            reg_addr => cs_reg_addr, car_to_move => crout_carid,
            reg_in => cs_next_loc, reg_we => cs_reg_we, path => cs_path,
            reg_request => cs_reg_req, mem_we => cs_we, mem_request => cs_memreq,
            ready => cs_ready, mem_in => cs_wdata, current_location => cs_start,
            request_location => cs_end, mem_addr => cs_addr
        );

    cd : car_drv
        port map (
            reset => cd_req, clock => clock, slow_clock => slow_clock,
            car_id => movecar_req, data_in => next_loc,
            location => move_loc, busy => cd_busy, move_car => car_moved
        );

    cr : car_reg
        port map (
            write_data_A => mh_next_loc, write_data_B => cs_next_loc,
            address_A => mh_reg_addr, address_B => cs_reg_addr, address_C => sim_reg_addr,
            request_A => mh_reg_req, request_B => cs_reg_req, request_C => sim_reg_req,
            we_A => mh_reg_we, we_B => cs_reg_we, clock => clock,
            read_data_A => mh_reg_data, read_data_B => cs_reg_data, read_data_C => sim_reg_data,
            ready_A => mh_reg_rdy, ready_B => cs_reg_rdy, ready_C => sim_reg_rdy
        );

    mh : hndlr
        port map (   
                reg_data => mh_reg_data, location_status => move_loc,
                read_data => mh_rdata, car_id => car_moved, clock => slow_clock,
                mem_ready => mh_memrdy, reg_ready => mh_reg_rdy,
                new_address => mh_next_loc, write_data => mh_wdata,
                mem_address => mh_addr, reg_address => mh_reg_addr,
                write_en => mh_we, mem_request => mh_memreq,
                reg_request => mh_reg_req, reg_we => mh_reg_we
        );

    -- generate slow clock (clock/2) (easily divisible by more if desired)
    clock_divider: PROCESS (clock) IS
    VARIABLE c:natural RANGE 0 TO 1;
    BEGIN
        WAIT UNTIL rising_edge(clock);
        IF reset ='1' THEN
            c := 0;
            slow_clock <= '0';
        ELSE
            c := (c + 1);
            IF c=0 THEN    
                slow_clock <= not slow_clock;
            END IF;
        END IF;
    END PROCESS clock_divider;

    -- simulate the relatively slow progress of an elevator car by dividing the
    -- clock down by an outrageously high number and scanning the car registers for
    -- an elevator's next
    -- (normally the signals used below would be IO pins on the chip, but we have
    -- no physical elevator, so this is a kind of "diagnostic mode")
    elev_sim: PROCESS (clock) IS
    VARIABLE delcnt:natural RANGE 0 TO 1000000; -- arbitrarily large counter
    VARIABLE scancar : std_logic_vector(3 downto 0);
    BEGIN
        WAIT UNTIL rising_edge(clock);
        IF reset ='1' THEN
            delcnt := 0;
            scancar := "0001";
        ELSIF delcnt = 1 THEN   
            sim_reg_req <= '0';
            cd_req <= '0';
            if sim_reg_rdy = '0' then
                delcnt := (delcnt + 1);
            end if;
        ELSIF delcnt = 2 THEN   
            sim_reg_addr <= scancar;
            sim_reg_req <= '1';
            if sim_reg_rdy = '1' and cd_busy = '0' then
                delcnt := (delcnt + 1);
            end if;
        ELSIF delcnt = 3 THEN   
            movecar_req <= scancar;
            case sim_reg_data(11 downto 8) is
                when "1000" =>
                    next_loc <= sim_reg_data(7 downto 0) + 1;
                when "1010" =>
                    next_loc <= sim_reg_data(7 downto 0) - 1;
                when "1100" =>
                    next_loc <= sim_reg_data(7 downto 0) - 64;
                when "1110" =>
                    next_loc <= sim_reg_data(7 downto 0) + 64;
                when others =>
                    next_loc <= sim_reg_data(7 downto 0);
            end case;
            cd_req <= '1';
            sim_reg_req <= '0';
            if scancar < "0001" or scancar > "0110" then
                scancar := "0001";
            else
                scancar := scancar + 1;
            end if;
            delcnt := (delcnt + 1);
        ELSE
            sim_reg_req <= '0';
            cd_req <= '0';
            delcnt := (delcnt + 1);
        END IF;
    END PROCESS elev_sim;

end mixed;