Car Selector VHDL Code

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

PACKAGE types IS
    CONSTANT max_car: std_logic_vector:= "0110";
    CONSTANT busy_status: std_logic_vector:= "1001";
    CONSTANT ADDR_WIDTH: integer:= 4;
    CONSTANT DATA_WIDTH: integer:= 12;

    SUBTYPE saddr IS std_logic_vector(3 DOWNTO 0);
    SUBTYPE laddr IS std_logic_vector(11 DOWNTO 0);
    SUBTYPE maddr IS std_logic_vector(5 DOWNTO 0);
    SUBTYPE lbit IS std_logic_vector(1 DOWNTO 0);
    subtype memaddr IS std_logic_vector(7 DOWNTO 0);

    TYPE state_type IS (initialize, get_mm_addr, get_mm_data, compare_mm_data,
        change_mm_addr, write_stop, read_data, compare_data, check_distance,
        change_addr, check_done, write_data);

END types;

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL;
USE work.types.ALL;
LIBRARY lpm;
USE lpm.lpm_components.ALL;

ENTITY car_sel IS
    PORT(
        clock, internal, up, reg_ready, mem_ready             : IN std_logic;        
        slow_clock                                             : IN std_logic;
        floor_req                                             : IN maddr;       
        car_id                                                 : IN saddr;
        reg_out                                                 : IN laddr;
        mem_out                                                 : IN memaddr;   
        kick_off                                             : IN std_logic;
        reg_addr, car_to_move                                 : OUT saddr;
        reg_in                                                 : OUT laddr;
        reg_we, reg_request, mem_we, mem_request             : OUT std_logic;
        mem_in                                                 : OUT memaddr;
        request_location                                     : OUT maddr;
        current_location                                     : OUT std_logic_vector(7 DOWNTO 0);
        ready                                                 : OUT std_logic;
        path                                                 : OUT std_logic;
        mem_addr                                             : OUT memaddr
    );
END ENTITY;

ARCHITECTURE behaviour OF car_sel IS

SIGNAL state, next_state                             : state_type;
SIGNAL car_data, mem_reg, data_reg                     : laddr;
SIGNAL car_local, difference, dist                     : maddr;
SIGNAL request_latch, tmp_location                     : maddr;
SIGNAL car_addr, car_addr_latch, reg_status             : saddr;
SIGNAL car_status, move_car                             : saddr;
SIGNAL found                                         : std_logic;
SIGNAL done, calc_dist                                 : std_logic;
SIGNAL done_latch                                      : std_logic;
SIGNAL internal_latch, done_shaft                     : std_logic;
SIGNAL found_path : std_logic;
SIGNAL shaft, shafted                                 : lbit;
SIGNAL mm_addr                                         : memaddr;
SIGNAL mm_data                                         : memaddr;

------------------------------------------------------------------------------
BEGIN

car_select: PROCESS (slow_clock) IS
BEGIN

WAIT UNTIL rising_edge(slow_clock);

CASE state IS
    WHEN initialize =>
        reg_request <= '0';
        found_path <= '0';
        reg_we <= '0';
        ready <= '0';
        done_shaft <= '0';
        IF internal = '1' THEN
            move_car <= car_id;
            car_addr_latch <= car_id;
        ELSE
            car_addr_latch <= "0001";
        END IF;
        difference <= "111111";
        shaft <= "00";
        done_latch <= '0';
        next_state <= get_mm_addr;
    WHEN get_mm_addr =>
        mem_request <= '1';
        mem_addr <= shaft & floor_req;
        mem_we <= '0';
        IF mem_ready = '1' THEN
            next_state <= get_mm_data;
        ELSE
            next_state <= get_mm_addr;
        END IF;
    WHEN get_mm_data =>
        mm_data <= mem_out;
        next_state <= compare_mm_data;
    WHEN compare_mm_data =>
        IF (mm_data(3) = '1' AND mm_data(2) = '0' AND mm_data(1) = up) THEN
            move_car <= mm_data(7 DOWNTO 4);
            mem_addr <= mm_data(7 DOWNTO 4);
            next_state <= write_stop;
        ELSIF (done_shaft = '1') THEN
            reg_addr <= car_addr_latch;
            reg_request <= '1';
            next_state <= read_data;
        ELSE
            next_state <= change_mm_addr;
        END IF;
    WHEN change_mm_addr =>
        IF (shaft + 1) = "11" THEN
            done_shaft <= '1';
        END IF;
        shaft <= shaft + 1;
        next_state <= get_mm_addr;
    WHEN write_stop =>
        mem_we <= '1';
        mem_in <= mm_data(7 DOWNTO 1) & '1';
        mem_request <= '0';
        car_addr_latch <= move_car;
        found_path <= '1';
        reg_addr <= car_addr_latch;
        reg_request <= '1';
        next_state <= read_data;
    WHEN read_data =>
        IF reg_ready = '0' THEN
            mem_request <= '0';
            reg_request <= '1';
            mem_reg <= reg_out;
            car_status <= reg_out(11 DOWNTO 8);
            car_local <= reg_out(5 DOWNTO 0);
            shafted <= reg_out(7 DOWNTO 6);
            next_state <= compare_data;
        ELSE
            next_state <= read_data;
        END IF;
    WHEN compare_data =>
        IF internal = '1' or found_path = '1' THEN
            tmp_location <= car_local;
            done_latch <= '1';
            found <= '1';
            next_state <= write_data;
        ELSIF (car_status = "0000") THEN
            found <= '1';
            car_status(3) <= '1';
            car_status(1) <= up;
            calc_dist <= '1';
            IF (request_latch > car_local) THEN
                dist <= (request_latch - car_local);
            ELSE
                dist <= (car_local - request_latch);
            END IF;
            next_state <= check_distance;
        ELSIF (car_status /= "0000") THEN
            found <= '0';
            car_status <= reg_out(11 DOWNTO 8);
            next_state <= change_addr;
        END IF;
    WHEN check_distance =>
        IF((dist < difference) AND calc_dist = '1') THEN
            difference <= dist;
            move_car <= car_addr;
            data_reg <= reg_out;
            tmp_location <= car_local;
        END IF;
        next_state <= change_addr;
    WHEN change_addr =>
        IF ((car_addr_latch + 1) > max_car) THEN
            car_addr_latch <= "0001";
        ELSE
            car_addr_latch <= car_addr_latch + 1;
        END IF;
        next_state <= check_done;
    WHEN check_done =>
        IF(calc_dist = '1' AND move_car /= "0000" AND car_addr = max_car) THEN
            done_latch <= '1';
            next_state <= write_data;
        ELSE
            next_state <= read_data;
        END IF;
    WHEN write_data =>
        IF found = '1' THEN
            car_to_move <= move_car;
            reg_we <= found;
            reg_in <= car_status & data_reg(7 DOWNTO 0);
            request_location <= request_latch;
            current_location <= shafted & tmp_location;
            path <= found_path;
            ready <= '1';
            reg_request <= '0';
        ELSIF found = '0' THEN
            next_state <= initialize;
        END IF;
END CASE;
END PROCESS car_select;


latch: PROCESS(clock) IS
BEGIN
    WAIT UNTIL rising_edge(clock);
    done <= done_latch;
END PROCESS latch;

input_latch: PROCESS(clock, internal) IS
BEGIN
    WAIT UNTIL rising_edge(clock);
    request_latch <= floor_req;
END PROCESS input_latch;

addr_latch: PROCESS(clock, car_addr_latch) IS
BEGIN
    WAIT UNTIL rising_edge(clock);
    car_addr <= car_addr_latch;
END PROCESS addr_latch;

state_register: PROCESS(clock, kick_off)
BEGIN
    IF kick_off = '1' THEN
        state <= initialize;   
    ELSIF rising_edge(clock) THEN
        state <= next_state;
    END IF;
END PROCESS state_register;

END behaviour;