Memory Handler VHDL Code
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity hndlr is
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 entity hndlr;
architecture behavioural of hndlr is
type states is (get_inputs, read_car_reg, latch_address, check_address, read_mem,
latch_data,
update_car_reg, free_up, free_down,
free_mem,
finished);
signal state, next_state: states;
signal last_address : std_logic_vector(11 downto 0);
signal address_reg : std_logic_vector(7 downto 0);
signal data_reg : std_logic_vector(7 downto 0);
signal car_id_reg : std_logic_vector(3 downto 0);
signal status, up, down, done_read, done_latch, free, freed,
reg_access, checked, reg_updated : std_logic;
alias up_down : std_logic is data_reg(2);
constant no_car: std_logic_vector(3 downto 0) := "0000";
begin
state_machine : process(state)
begin
wait until (clock'event) and (clock = '1');
case state is
when get_inputs => -- get current location data from cars
status <= '1';
mem_request <= '0';
done_read <= '0';
freed <= '0';
address_reg <= location_status;
car_id_reg <= car_id;
up <= '0';
down <= '0';
when read_car_reg => -- get last location data from car_register
reg_address <= car_id_reg;
reg_we <= '0';
if reg_ready = '0' then
reg_request <= '1';
reg_access <= '1';
elsif reg_ready = '0' then
reg_access <= '0';
end if;
when latch_address => -- latch last location data
last_address <= reg_data;
reg_request <= '0';
reg_access <='0';
when check_address => -- check if still at last address
if last_address(7 downto 0) = address_reg then
-- if same, goto get_inputs and get new data
status <='0';
elsif not(last_address(7 downto 0) =
address_reg) then
checked <= '1';
end if;
when read_mem => -- read current location status from memory map
mem_request <= '1';
checked <= '0';
mem_address <= address_reg;
write_en <= '0';
if (mem_ready = '1') then
done_read <= '1';
elsif (mem_ready = '0') then
done_read <= '0';
end if;
when latch_data => -- latch data from memory map
mem_request <= '0';
done_read <= '0';
data_reg <= read_data;
when update_car_reg => -- put new location in car_register
reg_we <= '1';
new_address(7 downto 0)
<= address_reg;
new_address(11 downto
8) <= data_reg(3 downto 0);
if reg_ready = '0' then
reg_request <= '1';
reg_updated <= '1';
elsif reg_ready = '0' then
reg_updated <= '0';
end if;
if up_down='1' then
up <= '1';
down <= '0';
end if;
if up_down = '0' then
down <= '1';
up <= '0';
end if;
when free_up => -- free previous location
mem_address <=
last_address(7 downto 0);
reg_request <= '0';
write_en <= '0';
data_reg(7 downto 0)
<= "00000000";
up <= '0';
when free_down => -- free previous location
mem_address <=
last_address(7 downto 0);
reg_request <= '0';
mem_request <= '0';
write_en <= '0';
data_reg(7 downto 0)
<= "00000000";
down <= '0';
when free_mem =>
mem_request <= '1';
write_en <= '1';
write_data <= data_reg;
if (mem_ready = '1') then
freed <= '1';
elsif (mem_ready = '0') then
freed <= '0';
end if;
when finished =>
mem_request <= '0';
freed <= '0';
write_en <= '0';
status <= '0';
end case;
end process state_machine;
next_state_is : process(clock)
begin
wait until (clock'event) and (clock = '1');
if state = finished and status ='0' then
next_state <= get_inputs;
end if;
if state = get_inputs and status = '1' then
next_state <= read_car_reg;
end if;
if state = read_car_reg and reg_access = '1' then
next_state <= latch_address;
end if;
if state = latch_address and reg_access = '0' then
next_state <= check_address;
end if;
if state = check_address and checked = '1' then
next_state <= read_mem;
elsif state = check_address and status = '0' then
next_state <= get_inputs;
end if;
if state = read_mem and done_read = '1' then
next_state <= latch_data;
elsif state = read_mem and done_read = '0' then
next_state <= read_mem;
end if;
if state = latch_data and done_latch = '1' then
next_state <= update_car_reg;
end if;
if state = update_car_reg and reg_updated = '1' and up='1' then
next_state <= free_up;
end if;
if state = update_car_reg and reg_updated = '1' and down='1' then
next_state <= free_down;
end if;
if (state = free_up or state = free_down) and free = '1' then
next_state <= free_mem;
end if;
if state = free_mem and freed = '1' then
next_state <= finished;
elsif state = free_mem and freed = '0' then
next_state <= free_mem;
end if;
end process next_state_is;
state_register : process(clock)
begin
if rising_edge(clock) then
state <= next_state;
end if;
end process state_register;
with state select
done_latch <=
'0' when get_inputs | read_car_reg |
latch_address | check_address | read_mem |
update_car_reg
| free_up | free_down | free_mem | finished,
'1' when latch_data;
with state select
free <=
'0' when get_inputs | read_car_reg |
latch_address | check_address | read_mem |
latch_data
| update_car_reg | free_mem | finished,
'1' when free_up | free_down;
end architecture behavioural;