MAIN CONTROLLER
Authors: Anthony Eshpeter & Andrew Dunmore
Description: This program controls all interaction between components. It communicates with the computer via the UART and determines what will be done: the sending of signals or the receiving of signals. It also controls the calculations to be done: position and velocity.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library lpm;
use lpm.lpm_components.ALL;
entity main_controller is
generic( address_width : positive := 5;
datain_width : positive := 6;
dataout_width : positive := 8;
pos_width : positive := 13 );
port( clk : in std_logic; -- Global controls
detected_data, timeout : in std_logic; -- From Detector
posx, posy, posz : in std_logic_vector(pos_width-1 downto 0); -- From Pos Alu
data_in : in std_logic_vector(datain_width-1 downto 0); -- From UART
data_rec, ready_to_send : in std_logic; -- From UART
data_ack, data_send : out std_logic; -- To UART
data_out : out std_logic_vector(dataout_width-1 downto 0); -- To UART
e_go1, e_go2, e_go3, e_go4 : buffer std_logic; -- To emitter
d_go : out std_logic; -- To detector
mic_address : out std_logic_vector(address_width-1 downto 0); -- To Mic Decoders
data_ack_d, dumpdata : out std_logic;
state_bin : out std_logic_vector(7 downto 0));
end main_controller;
architecture behavioural of main_controller is
TYPE STATE_TYPE IS ( waiting,datainUart,init,load_address,detect_mics,ram_load,ram_enable,mic_cnt_go,return_mics,
return_init,hold_data_sent,data_present,hold_data_present,emit_sp1,get_data1,emit_sp2,get_data2,
emit_sp3,get_data3,emit_sp4,get_data4,send1,hold1,send2,hold2,send3,hold3,send4,hold4,send5,hold5,
timeout1,timeout2,hold_TO2);
SIGNAL state: STATE_TYPE;
signal mic_address_select : std_logic_vector(0 downto 0);
signal data_out_select : std_logic_vector(1 downto 0);
signal mic_count_enable, mic_count_clear : std_logic;
signal mic_count : std_logic_vector(address_width-1 downto 0);
signal ram_out : std_logic_vector(address_width-1 downto 0);
signal ram_write_enable: std_logic;
signal ram_in_select : std_logic_vector(0 downto 0);
signal ram_in : std_logic_vector(address_width-1 downto 0);
signal ram_index_comparable:std_logic_vector(datain_width-1 downto 0);
signal ram_index_enable, ram_index_clear : std_logic;
signal ram_index : std_logic_vector(address_width-1 downto 0);
signal data_from_UART_load : std_logic;
signal data_from_UART : std_logic_vector( datain_width-1 downto 0);
signal mic_address_mux_in : std_logic_2D(1 downto 0, address_width-1 downto 0 );
signal ram_in_mux_in : std_logic_2D( 1 downto 0, address_width-1 downto 0 );
signal output_mux_in : std_logic_2D( dataout_width-2 downto 0, dataout_width-1 downto 0 );
signal output_select : std_logic_vector(2 downto 0);
signal byte1, byte2, byte3, byte4, byte5: std_logic_vector(dataout_width-1 downto 0);
signal error_byte, pad_ram_index : std_logic_vector( dataout_width-1 downto 0);
begin
PROCESS (clk)
BEGIN
IF clk'EVENT AND clk = '1' THEN
CASE state IS
WHEN waiting =>
IF data_rec = '1' THEN
state <= datainUart;
else
state <= waiting;
END IF;
WHEN datainUart =>
if data_from_UART(5) = '1' then
state <= init;
else
state <= data_present;
end if;
WHEN init =>
state <= load_address;
WHEN load_address =>
state <= detect_mics;
WHEN detect_mics =>
if detected_data = '1' then
state <= ram_load;
elsif timeout = '1' then
state <= mic_cnt_go;
end if;
WHEN ram_load =>
state <= ram_enable;
WHEN ram_enable =>
state <= mic_cnt_go;
WHEN mic_cnt_go =>
if mic_count = "11111" then
state <= return_mics;
else
state <= load_address;
end if;
WHEN return_mics =>
if ready_to_send = '1' then
state <= return_init;
else
state <= return_mics;
end if;
WHEN return_init =>
if ready_to_send = '0' then
state <= hold_data_sent;
else
state <= return_init;
end if;
WHEN hold_data_sent =>
if ready_to_send = '1' then
state <= waiting;
else
state <= hold_data_sent;
end if;
WHEN data_present =>
if data_from_UART = conv_std_logic_vector(0,datain_width) then
state <= timeout1;
else
state <= hold_data_present;
end if;
WHEN hold_data_present =>
if data_from_UART <= ram_index_comparable then
state <= emit_sp1;
else
state <= timeout1;
end if;
WHEN emit_sp1 =>
if timeout = '1' then
state <= timeout1;
elsif detected_data = '1' then
state <= get_data1;
end if;
WHEN get_data1 =>
if detected_data = '1' then
state <= emit_sp2;
else
state <= get_data1;
end if;
WHEN timeout1 =>
if ready_to_send = '1' then
state <= timeout2;
else
state <= timeout1;
end if;
WHEN emit_sp2 =>
if timeout = '1' then
state <= timeout1;
elsif detected_data = '1' then
state <= get_data2;
end if;
WHEN get_data2 =>
if detected_data = '1' then
state <= emit_sp3;
else
state <= get_data2;
end if;
WHEN emit_sp3 =>
if timeout = '1' then
state <= timeout1;
elsif detected_data = '1' then
state <= get_data3;
end if;
WHEN get_data3 =>
if detected_data = '1' then
state <= emit_sp4;
else
state <= get_data3;
end if;
WHEN emit_sp4 =>
if timeout = '1' then
state <= timeout1;
elsif detected_data = '1' then
state <= get_data4;
end if;
WHEN get_data4 =>
if ready_to_send = '1' then
state <= send1;
else
state <= get_data4;
end if;
WHEN send1 =>
if ready_to_send = '0' then
state <= hold1;
else
state <= send1;
end if;
WHEN hold1 =>
if ready_to_send = '1' then
state <= send2;
else
state <= hold1;
end if;
WHEN send2 =>
if ready_to_send = '0' then
state <= hold2;
else
state <= send2;
end if;
WHEN hold2 =>
if ready_to_send = '1' then
state <= send3;
else
state <= hold2;
end if;
WHEN send3 =>
if ready_to_send = '0' then
state <= hold3;
else
state <= send3;
end if;
WHEN hold3 =>
if ready_to_send = '1' then
state <= send4;
else
state <= hold3;
end if;
WHEN send4 =>
if ready_to_send = '0' then
state <= hold4;
else
state <= send4;
end if;
WHEN hold4 =>
if ready_to_send = '1' then
state <= send5;
else
state <= hold4;
end if;
WHEN send5 =>
if ready_to_send = '0' then
state <= hold5;
else
state <= send5;
end if;
WHEN hold5 =>
if ready_to_send = '1' then
state <= waiting;
else
state <= hold5;
end if;
WHEN timeout2 =>
if ready_to_send = '0' then
state <= hold_TO2;
else
state <= timeout2;
end if;
WHEN hold_TO2 =>
if ready_to_send = '1' then
state <= waiting;
else
state <= hold_TO2;
end if;
WHEN others =>
state <= waiting;
END CASE;
END IF;
END PROCESS;
d_go <= e_go1 or e_go2 or e_go3 or e_go4;
ram_index_comparable(address_width) <= '0';
ram_index_comparable(address_width-1 downto 0) <= ram_index;
with state select
state_bin <= "00000000" when waiting,
"00000001" when datainUart,
"00000010" when init,
"00000011" when load_address,
"00000100" when detect_mics,
"00000101" when ram_load,
"00000110" when ram_enable,
"00000111" when mic_cnt_go,
"00001000" when return_mics,
"00001000" when return_init,
"00001000" when hold_data_sent,
"00001001" when data_present,
"00001001" when hold_data_present,
"00001010" when emit_sp1,
"00001011" when get_data1,
"00001100" when timeout1,
"00001101" when emit_sp2,
"00001110" when get_data2,
"00001111" when emit_sp3,
"00010000" when get_data3,
"00010001" when emit_sp4,
"00010010" when get_data4,
"00010011" when send1,
"00010100" when hold1,
"00010101" when send2,
"00010110" when hold2,
"00010111" when send3,
"00011000" when timeout2,
"00011000" when hold_TO2,
"00011001" when hold3,
"00011010" when send4,
"00011011" when hold4,
"00011100" when send5,
"00011101" when hold5,
"00011111" when others;
WITH state SELECT
e_go1 <= '1' WHEN detect_mics,
'1' when emit_sp1,
'0' WHEN others;
WITH state SELECT
e_go2 <= '1' WHEN emit_sp2,
'0' WHEN others;
WITH state SELECT
e_go3 <= '1' WHEN emit_sp3,
'0' WHEN others;
WITH state SELECT
e_go4 <= '1' WHEN emit_sp4,
'0' WHEN others;
WITH state SELECT
dumpdata <= '1' when get_data1,
'1' when get_data2,
'1' when get_data3,
'1' when get_data4,
'0' when others;
WITH state SELECT
data_send <= '1' when return_init,
'1' when timeout2,
'1' when send1,
'1' when send2,
'1' when send3,
'1' when send4,
'1' when send5,
'0' when others;
WITH state SELECT
output_select <= "001" when return_mics,
"001" when return_init,
"001" when hold_data_sent,
"000" when timeout1,
"000" when timeout2,
"000" when hold_TO2,
"010" when send1,
"010" when hold1,
"011" when send2,
"011" when hold2,
"100" when send3,
"100" when hold3,
"101" when send4,
"101" when hold4,
"110" when send5,
"110" when hold5,
(others => '0') when others;
WITH state SELECT
data_ack <= '1' when init,
'1' when data_present,
'0' when others;
WITH state SELECT
data_ack_d <= '1' when init,
'1' when mic_cnt_go,
'1' when data_present,
'1' when get_data1,
'1' when get_data2,
'1' when get_data3,
'1' when get_data4,
'0' when others;
WITH state SELECT
mic_address_select <= "0" when load_address,
"0" when detect_mics,
"1" when emit_sp1,
"1" when get_data1,
"1" when emit_sp2,
"1" when get_data2,
"1" when emit_sp3,
"1" when get_data3,
"1" when emit_sp4,
(others => '1') when others;
with state SELECT
mic_count_enable <= '1' when mic_cnt_go,
'0' when others;
with state SELECT
mic_count_clear <= '1' when init,
'0' when others;
with state SELECT
ram_index_enable <= '1' when ram_enable,
'0' when others;
with state SELECT
ram_index_clear <= '1' when init,
'0' when others;
with state SELECT
ram_write_enable <= '1' when ram_load,
'1' when ram_enable,
'0' when others;
with state SELECT
ram_in_select <= "0" when ram_load,
"0" when ram_enable,
(others => '1') when others;
with state SELECT
data_from_UART_load <= '1' when datainUart,
'0' when others;
error_byte <= "10000000";
pad_ram_index(address_width-1 downto 0) <= ram_index;
pad_ram_index(7 downto 5) <= "000";
-- allocating data to tranfer bytes
byte1(7) <= '0';
byte1(6 downto 0) <= posx(pos_width-1 downto pos_width-7);
byte2(7 downto 2) <= posx(pos_width-8 downto 0);
byte2(1 downto 0) <= posy(pos_width-1 downto pos_width-2);
byte3(7 downto 0) <= posy(pos_width-3 downto pos_width-10);
byte4(7 downto 5) <= posy(pos_width-11 downto 0);
byte4(4 downto 0) <= posz(pos_width-1 downto pos_width-5);
byte5(7 downto 0) <= posz(pos_width-6 downto 0);
mic_count_counter : component lpm_counter -- counts the number of mics in the sensor array
generic map( LPM_WIDTH => 6 )
port map( clock => clk,
cnt_en => mic_count_enable,
sclr => mic_count_clear,
q => mic_count );
ram_index_counter : component lpm_counter -- ram index counter
generic map( LPM_WIDTH => address_width )
port map( clock => clk,
cnt_en => ram_index_enable,
sclr => ram_index_clear,
q => ram_index );
input_register: component lpm_ff -- register where data entering system is loaded into
generic map( LPM_WIDTH => datain_width )
port map( clock => clk,
sload => data_from_UART_load,
data => data_in,
q => data_from_UART );
mic_mux : FOR i IN 4 downto 0 GENERATE
mic_address_mux_in(0,i) <= mic_count(i);
mic_address_mux_in(1,i) <= ram_out(i);
END GENERATE mic_mux;
mic_address_mux : component lpm_mux -- selecting value to send to emitter (mic count or RAM out)
generic map( LPM_WIDTH => address_width,
LPM_SIZE => 2,
LPM_WIDTHS => 1 )
port map( data => mic_address_mux_in,
sel => mic_address_select,
result => mic_address );
ram_mux : FOR i IN 4 downto 0 GENERATE
ram_in_mux_in(0,i) <= ram_index(i);
ram_in_mux_in(1,i) <= data_from_UART(i);
END GENERATE ram_mux;
ram_in_mux : component lpm_mux -- selecting input value to RAM (from UART or from RAM index)
generic map( LPM_WIDTH => address_width,
LPM_SIZE => 2,
LPM_WIDTHS => 1 )
port map( data => ram_in_mux_in,
sel => ram_in_select,
result => ram_in );
out_mux : FOR i IN 7 downto 0 GENERATE
output_mux_in(0,i) <= error_byte(i);
output_mux_in(1,i) <= pad_ram_index(i);
output_mux_in(2,i) <= byte1(i);
output_mux_in(3,i) <= byte2(i);
output_mux_in(4,i) <= byte3(i);
output_mux_in(5,i) <= byte4(i);
output_mux_in(6,i) <= byte5(i);
END GENERATE out_mux;
output_mux : component lpm_mux -- selecting value to return to computer (ie: x,y,z,error)
generic map( LPM_WIDTH => dataout_width,
LPM_SIZE => 7,
LPM_WIDTHS => 3 )
port map( data => output_mux_in,
sel => output_select,
result => data_out );
the_ram: component lpm_ram_dq -- setting up the RAM to store input data values in
generic map( LPM_WIDTH => address_width,
LPM_WIDTHAD => address_width )
port map( data => mic_count(address_width-1 downto 0),
address => ram_in,
we => ram_write_enable,
inclock => clk,
outclock => clk,
q => ram_out );
end architecture behavioural;