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;