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;