Beruflich Dokumente
Kultur Dokumente
conrolUnit.vhd
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use IEEE.numeric_std.all; use work.misc_package.all; entity controlUnit is port ( clk : in std_logic ; -- freq: 50MHz. time: 0.00000002 (20 ns) PIN_N2 toggles : in std_logic_vector(17 downto 0) ; -- toggle-switches 17 to 0 PIN_V2,PIN_V1,PIN_U4,PIN_U3,PIN_T7,PIN_P2,PIN_P1,PIN_N1,PIN_A13,PIN_B13,PIN_C13,PIN_AC13,PIN_AD13,PIN_AF14,PIN_AE14,PI N_P25,PIN_N26,PIN_N25 keys : in std_logic_vector(3 downto 0) ; -- keys 3 to 0 PIN_W26,PIN_P23,PIN_N23,PIN_G26 -- COMPASS PWMcompass : in std_logic ; -PIN_W25 -- DISTANCE SENSORS -- 1 is for front sensor , 2 if PWM_front : in std_logic trig_front : out std_logic PWM_right : in std_logic PWM_left : in std_logic
trig_right : out std_logic ; -- WHEELS r_en : out std_logic ; l_en : out std_logic ; r_PWM : out std_logic ; l_PWM : out std_logic ; r_ctrl1 : out std_logic ; r_ctrl2 : out std_logic ; l_ctrl1 : out std_logic ; l_ctrl2 : out std_logic ; -- CAMERA cam_trans : out std_logic ; cam_rec : in std_logic ; -- OUTPUT INDICATORS ss rl gl ); end entity controlUnit; architecture arc_controlUnit of controlUnit is
----PIN_L19 -----------
PIN_G25 PIN_K22 PIN_P18 -PIN_F23 PIN_F23 PIN_F26 PIN_F24 PIN_F25 PIN_J21 PIN_J20 PIN_J22 PIN_D25 PIN_N24 PIN_N20 8 seven-segments red leds green leds
-- FUNCTIONS -- stlv27seg function stlv27seg(stlv: std_logic_vector(3 downto 0)) return std_logic_vector is begin return digits(to_integer(ieee.numeric_std.unsigned(stlv))); end stlv27seg; -- returns stlv(6 to 0) representing the 7seg of this stlv -- int to stdlv function int2stlv(stlv: integer) return std_logic_vector is begin if(stlv<0) then return "000"; elsif(stlv>7) then return "111"; else return conv_std_logic_vector(stlv,3); end if; end int2stlv; -- fwSpeed function fwSpeed(dist_f: integer) return integer is begin if(dist_f>256) then return 6; elsif(dist_f>170) then return 6; elsif(dist_f>130) then return 6; elsif(dist_f>100) then return 5; elsif(dist_f>80) then return 4; elsif(dist_f>60) then return 3; elsif(dist_f>40) then return 2; else return 0; end if; end fwSpeed; --
function stlv237seg(stlv: std_logic_vector; max_index: integer range 0 to 11) return std_logic_vector begin if(max_index=7) then return stlv27seg(stlv(7 downto 4)) & stlv27seg(stlv(3 downto 0)); elsif(max_index=8) then return stlv27seg("000" & stlv(8)) & stlv27seg(stlv(7 downto 4)) & stlv27seg(stlv(3 downto elsif (max_index=9) then return stlv27seg("00" & stlv(9 downto 8)) & stlv27seg(stlv(7 downto 4)) & stlv27seg(stlv(3 downto elsif (max_index=10) then return stlv27seg("0" & stlv(10 downto 8)) & stlv27seg(stlv(7 downto 4)) & stlv27seg(stlv(3 downto elsif (max_index=11) then return stlv27seg(stlv(11 downto 8)) & stlv27seg(stlv(7 downto 4)) & stlv27seg(stlv(3 downto end if; end stlv237seg; -- returns (3 or 2)*stlv(6 to 0) representing the 7seg of this stlv -- the stlv is 3 downto 0. i don't write it because in quartus it makes problems) -- fix_angle function fix_angle(ang: integer) return integer is begin if(ang>=angle360) then return ang-angle360 ; elsif(ang<0) then return ang+angle360 ; else return ang ; end if; end fix_angle ; -- returns the angle in the right range [0,angle360] -- ang_ABSdiff function ang_ABSdiff(ang1: integer; ang2: integer) return integer is variable temp: integer ; begin if(ang1>=ang2) then temp:=ang1-ang2 ; else temp:=ang2-ang1 ; end if; if(temp>angle180) then return temp-angle180 ; else return temp ; end if ; end ang_ABSdiff ; -- returns absolute difference between 2 angles in range [0,angle180] -- ang_CCWdiff function ang_CCWdiff(ang1: integer; ang2: integer) return integer is variable temp: integer ; begin temp:=ang1-ang2 ; if(temp<0) then return temp+angle360 ; else return temp ; end if; end ang_CCWdiff ; -- returns diff ang1 from ang2 that ang1 sees when he looks CCW -- COMPONENTS component distanceSensor is port ( clk: in std_logic ; rst: in std_logic ; pwm: in std_logic ; trig: out std_logic ; result: out std_logic_vector(9 downto 0) ; -- each unit is 0.6834cm (0.002278 from max) done: out std_logic ); end component; -component compass is port ( clk: in std_logic; rst: in std_logic; pwm: in std_logic; result: out std_logic_vector(8 downto 0); -- each unit is ~0.8 degrees (0.00222 from max) done: out std_logic ); end component; -component wheel is port ( clk : in std_logic ; rst : in std_logic ; mode : in wheel_mode ; speed : in std_logic_vector(2 downto 0) ; en : out std_logic ; ctrl1 : out std_logic ; ctrl2 : out std_logic ; pwm : out std_logic ); end component; -component camera is PORT( clk : in std_logic; rst : in std_logic; eof_found : out std_logic; -- Send TXD : out std_logic; begin_send : in std_logic;
is
cur_send_state :out std_logic_vector(7 downto 0); -- Receive RXD : in std_logic; x_coord_data : out std_logic_vector(7 downto 0); x_coord_done : out std_logic ); end component; -- VARS -- general vars signal rst : std_logic; signal d_mode : drive_modes ; signal r_mode, prev_r_mode, next_mode : robot_modes ; -- distance vars signal ds_front_result, ds_right_result, ds_left_result : std_logic_vector(9 downto 0) ; signal done_ds_front, done_ds_right,done_ds_left : std_logic ; -- wheel vars signal wl_mode, wr_mode : wheel_mode ; signal wl_speed, wr_speed : std_logic_vector(2 downto 0) ; -- angle vars signal angle : std_logic_vector(8 downto 0) ; signal done_compass : std_logic ; signal last_angle_stlv : std_logic_vector(8 downto 0); -- camera vars signal x_coord,x_cord,cur_send_state : std_logic_vector(7 downto 0) ; signal debuga:std_logic_vector(7 downto 0); signal begin_send, cam_done, eof_found, nyancat : std_logic ; -- misc signal msg,prev_msg : std_logic_vector(55 downto 0); -- 10ms counter signal cnt10ms_ezer : integer range 0 to 500001; -- 500000 clk-s are 10ms signal cnt10ms : integer ; -- can count to 248 days (max value of integer is 2147483647)=>no need to make it cyclic -- timestamps vars (prefix: "ts_"). used to save times based on counter10ms signal ts_msgChanged : integer ; signal ts_r_modeChanged : integer ; signal ts_modeChanged : integer ; signal ts_sampleDistance : integer ; signal ts_lastFixed : integer ; signal ts_r_fix_start,ts_l_fix_start : integer ; -- sampling distance type samp5 is array (0 to 4) of integer; type samp100 is array (0 to 99) of integer; signal red_samp:samp100; type dists_samp_bla is array (0 to 2) of samp100; signal dists_samp:dists_samp_bla; -- vars for specific modes -- getNewDir signal newDirDist : integer ; signal new_d_mode : drive_modes ; begin -- PORT MAPS cmp : compass ds_front : distanceSensor ds_right : distanceSensor ds_left : distanceSensor right_wheel : wheel left_wheel : wheel cam : camera x_coord, cam_done);
PWMcompass ,angle, done_compass); PWM_front, trig_front ,ds_front_result ,done_ds_front); PWM_right, trig_right ,ds_right_result ,done_ds_right); PWM_left, nyancat ,ds_left_result ,done_ds_left); wr_mode, wr_speed, r_en, r_ctrl1, r_ctrl2, r_PWM); wl_mode, wl_speed, l_en, l_ctrl1, l_ctrl2, l_PWM); eof_found, cam_trans, begin_send, cur_send_state, cam_rec,
process (clk, toggles(0),keys(0)) is variable angle_init_samples_count : integer range 0 to 4 ; variable angle_init_sum : std_logic_vector(10 downto 0) ; variable last_angle, dist_f, dist_r, dist_l, destination_ang, cur_angle : integer ; variable red : integer; -- red object x position variable new_dir_indx : integer; variable break:boolean; begin -- toggle & key if (toggles(0) = '0' or keys(0)='0') then -- 0 of toggle is down (outer side of card) ----------------------RESET THINGS ------------------------ simple reset assignments rst <= '0' ; gl <= "111111111" ; rl <= "000000000000000000" ; -- timestamps reset ts_msgChanged <= 0 ; -- more reset assignments prev_msg <= blnk & blnk7 ; msg <= STARTING_word ; cnt10ms <= 0 ; cnt10ms_ezer <= 0 ; ts_sampleDistance <= 0 ; ts_l_fix_start <= 0 ; ts_r_fix_start <= 0 ; begin_send <= '0' ; break := false; for i in 0 to 99 loop dists_samp(0)(i)<=10000;
dists_samp(1)(i)<=10000; dists_samp(2)(i)<=10000; red_samp(i)<=0; end loop; -- reset for first r_mode (rot4newDir) prev_r_mode <= nulll ; r_mode <= getNewDir ; elsif rising_edge(clk) then rst <= '1'; begin_send <= '1' ; break := false; --------------------PRE MAIN-LOGIC ---------------------- front distance if(done_ds_front='1') then dist_f := conv_integer(ds_front_result) ; end if ; -- side distances if(done_ds_right='1') then dist_r := conv_integer(ds_right_result) ; end if ; if(done_ds_left='1') then dist_l := conv_integer(ds_left_result) ; end if ; -- angle if(done_compass='1') then cur_angle := conv_integer(angle) ; end if ; x_cord <= x_coord ; if(cam_done='1') then x_cord <= x_coord ; end if ; -- sample distance if(ts_sampleDistance+6<cnt10ms) then ts_sampleDistance<=cnt10ms; for i in 1 to 99 loop dists_samp(0)(i)<=dists_samp(0)(i-1); dists_samp(1)(i)<=dists_samp(1)(i-1); dists_samp(2)(i)<=dists_samp(2)(i-1); red_samp(i)<=red_samp(i-1); end loop; dists_samp(0)(0) <=dist_f; dists_samp(1)(0) <=dist_r; dists_samp(2)(0) <=dist_l; red_samp(0)<=conv_integer(x_cord); end if; -- disable wheel movement when last toggle in on (used for debugging) if(toggles(17)='0') then wr_mode <= rw_modes(drive_modes'pos(d_mode)) ; wl_mode <= lw_modes(drive_modes'pos(d_mode)) ; else wr_mode <= w_st; wl_mode <= w_st; end if; ---------------------------------------------------------------************************ MAIN-LOGIC ************************ -------------------------------------------------------------if(cnt10ms>200) then if(min_dist2keep>dist_f and r_mode/=wallGoBack and r_mode/=found_red) then next_mode<=r_mode; r_mode<=wallGoBack; elsif(conv_integer(x_cord)>0 and red_samp(2)>0) then r_mode<=found_red; end if; -- r_mode case r_mode is when wallGoBack => ---------------------------------if(r_mode/=prev_r_mode) then ts_modeChanged <= cnt10ms; prev_r_mode <= d_mode <= bw ; wl_speed <= "010"; wr_speed <= "010"; end if; if(min_dist2keep<dist_f) then r_mode<=next_mode; break:=true; end if; ----------------------------------
r_mode;
if(r_mode/=prev_r_mode) then ts_modeChanged <= cnt10ms; prev_r_mode <= r_mode; d_mode <= st ; end if; if(dist_f>dist_r and dist_f>dist_l) then new_d_mode<=fw; msg<=F_ch&F_ch&F_ch&F_ch&F_ch&F_ch&F_ch&F_ch; elsif(dist_r>dist_l) then new_dir_indx:=1;
else
end if; wl_speed <= "010"; wr_speed <= "010"; r_mode<=goNewDir; when goNewDir =>-----------------------------------------if(r_mode/=prev_r_mode) then ts_modeChanged <= cnt10ms; prev_r_mode <= r_mode; d_mode<=new_d_mode; if(new_d_mode=fw) then r_mode<=forward; end if; elsif(dists_samp(new_dir_indx)(1)>newDirDist and dists_samp(new_dir_indx) (1)<dists_samp(new_dir_indx)(0)) then ts_modeChanged <= cnt10ms ; r_mode <= forward ; elsif(ts_modeChanged+rotTime010/4<cnt10ms) then -- same cmds. just spares long "or" ts_modeChanged <= cnt10ms ; r_mode <= forward ; end if; when forward=> ------------------------------------------if(r_mode/=prev_r_mode) then ts_modeChanged <= cnt10ms; prev_r_mode <= r_mode; d_mode<=st; end if; if(ts_modeChanged+t_ds_acquisition>cnt10ms) then else d_mode<=fw; if(dist_f<dist_wall_stop) then -- or (dists_samp(1)(0)-dists_samp(1) (4)>112) or (dists_samp(2)(0)-dists_samp(2)(4)>112) d_mode<=st; r_mode<=getNewDir; elsif(dist_l<30) then wl_speed<=int2stlv(fwSpeed(dist_f)); wr_speed<=int2stlv(fwSpeed(dist_f)-3); elsif(dist_r<30) then wl_speed<=int2stlv(fwSpeed(dist_f)-3); wr_speed<=int2stlv(fwSpeed(dist_f)); elsif(dist_l<min_dist2keep) then wl_speed<=int2stlv(fwSpeed(dist_f)); wr_speed<=int2stlv(fwSpeed(dist_f)-1); elsif(dist_r<min_dist2keep) then wl_speed<=int2stlv(fwSpeed(dist_f)-1); wr_speed<=int2stlv(fwSpeed(dist_f)); elsif((dists_samp(1)(2)-dist_r>8 and dist_r<80) or (dist_r>256 and dist_l>256 and dist_l>dist_r) or ts_l_fix_start+7>=cnt10ms) then -- right goes down fast if(ts_l_fix_start+7<cnt10ms) then msg<=M_ch&M_ch&L_ch&L_ch&B_ch&O_ch&O_ch&M_ch; ts_l_fix_start<=cnt10ms; end if; wl_speed<=int2stlv(fwSpeed(dist_f)-1); wr_speed<=int2stlv(fwSpeed(dist_f)); elsif((dists_samp(2)(2)-dist_l>8 and dist_l<80) or (dist_r>256 and dist_l>256 and dist_l<dist_r) or ts_r_fix_start+7>=cnt10ms) then -- left goes down fast if(ts_r_fix_start+7<cnt10ms) then msg<=M_ch&M_ch&R_ch&R_ch&B_ch&O_ch&O_ch&M_ch; ts_r_fix_start<=cnt10ms; end if; wr_speed<=int2stlv(fwSpeed(dist_f)-1); wl_speed<=int2stlv(fwSpeed(dist_f)); else wl_speed<=int2stlv(fwSpeed(dist_f)); wr_speed<=int2stlv(fwSpeed(dist_f)); end if; end if; when found_red=> ----------------------------------------- -- middle is ~88 if(r_mode/=prev_r_mode) then ts_modeChanged <= cnt10ms; prev_r_mode <= r_mode; d_mode <= fw; end if; red:=conv_integer(x_cord); if(red=0 and red_samp(2)=0) then ts_modeChanged <= cnt10ms; r_mode <= forward ; elsif((dist_f<64 and red>72 and red<104) or dist_f<48) then wl_speed<=int2stlv(0); wr_speed<=int2stlv(0); elsif(dist_f<64 and red<=72) then
wl_speed<=int2stlv(0); wr_speed<=int2stlv(3); elsif(dist_f<64 and red>=106) then wl_speed<=int2stlv(3); wr_speed<=int2stlv(0); elsif(red>104 and red<62) then wl_speed<=int2stlv(fwSpeed(dist_f)); wr_speed<=int2stlv(fwSpeed(dist_f)); elsif(red<=72) then wl_speed<=int2stlv(fwSpeed(dist_f)-1); wr_speed<=int2stlv(fwSpeed(dist_f)); elsif(red>=104) then wl_speed<=int2stlv(fwSpeed(dist_f)); wr_speed<=int2stlv(fwSpeed(dist_f)-1); else end if; when others=> else end case; d_mode<=st; end if; ---------------------------------------------------------------******************** END OF MAIN-LOGIC ******************** ---------------------------------------------------------------------------------MISC -- cnt10ms update if(cnt10ms_ezer>=500000) then cnt10ms_ezer <= 0 ; cnt10ms <= cnt10ms + 1 ; else cnt10ms_ezer <= cnt10ms_ezer + 1 ; end if ; -- mode change timestamp update if(prev_msg /= msg) then ts_msgChanged <= cnt10ms ; prev_msg <= msg ; end if ; end if ; -- rising_edge clk end process ; --------------------OUTPUT INDICATION for the 8 7-segments ---------------------- NOTE: when some toggles are up at once, then the first line determine ss <= RESET_word & blnk3 when toggles(0) = '0' or keys(0)='0' -- "reset" on reset else R_ch & stlv237seg(ds_right_result,9) & L_ch & stlv237seg(ds_left_result,9) when toggles(1)='1' -- "r[right_d]L[left_d] on toggles(1) else F_ch & stlv237seg(ds_front_result,9) & A_ch & stlv237seg(angle,8) when toggles(2)='1' -- "f[front_d]A[angle] on toggles(2) else D_ch & EQUAL_ch & m_7segDM(drive_modes'pos(d_mode)) when toggles(3)='1' -- "d=[drive mode]]" on toggles(3) else C_ch & EQUAL_ch & stlv237seg(x_cord,7) & blnk4 when toggles(4)='1' -- "C=[x cord]" on toggles(4) else W_ch & EQUAL_ch & m_7segRM(drive_modes'pos(d_mode)) when toggles(5)='1' -- W=[drive mode]] ---------------------
on toggles(5)
-- no toggles: else msg when ts_msgChanged+msg_display_t>cnt10ms when msg changed recently(=d_mode_display_t*10ms) else W_ch & EQUAL_ch & m_7segRM(robot_modes'pos(r_mode)); -- W=[robot mode]] changed recently end architecture arc_controlUnit;
--Back to Top
work/misc.vhd
library IEEE; use IEEE.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use IEEE.numeric_std.all; package misc_package is -- wheel type wheel_mode is (w_st, w_fw, w_bw); type arr3 is ARRAY(0 to 2) of std_logic ; constant wheel_enable_mode : arr3 :=('0', '1', '1'); constant ctrl1_mode : arr3 :=('0', '0', '1'); constant ctrl2_mode : arr3 :=('0', '1', '0'); -- 7segment constant blnk : std_logic_vector(6 downto 0) := "1111111"; -- blank constant blnk2 : std_logic_vector(13 downto 0) := blnk & blnk ; constant blnk3 : std_logic_vector(20 downto 0) := blnk & blnk & blnk ; constant blnk4 : std_logic_vector(27 downto 0) := blnk & blnk & blnk & constant blnk5 : std_logic_vector(34 downto 0) := blnk & blnk & blnk & constant blnk6 : std_logic_vector(41 downto 0) := blnk & blnk & blnk & constant blnk7 : std_logic_vector(48 downto 0) := blnk & blnk & blnk & constant A_ch : std_logic_vector(6 downto 0) := "0001000"; constant B_ch : std_logic_vector(6 downto 0) := "0000011"; constant C_ch : std_logic_vector(6 downto 0) := "1000110"; constant D_ch : std_logic_vector(6 downto 0) := "0100001"; constant E_ch : std_logic_vector(6 downto 0) := "0000110"; constant F_ch : std_logic_vector(6 downto 0) := "0001110"; constant G_ch : std_logic_vector(6 downto 0) := "0010000"; constant H_ch : std_logic_vector(6 downto 0) := "0001001"; constant I_ch : std_logic_vector(6 downto 0) := "1111001"; constant J_ch : std_logic_vector(6 downto 0) := "1100001"; constant K_ch : std_logic_vector(6 downto 0) := "0001010"; constant L_ch : std_logic_vector(6 downto 0) := "1000111"; constant M_ch : std_logic_vector(6 downto 0) := "1001000"; constant N_ch : std_logic_vector(6 downto 0) := "1001000"; constant O_ch : std_logic_vector(6 downto 0) := "1000000"; constant P_ch : std_logic_vector(6 downto 0) := "0001100"; constant R_ch : std_logic_vector(6 downto 0) := "1001110"; constant S_ch : std_logic_vector(6 downto 0) := "0010010"; constant T_ch : std_logic_vector(6 downto 0) := "0000111"; constant U_ch : std_logic_vector(6 downto 0) := "1000001"; constant V_ch : std_logic_vector(6 downto 0) := U_ch ; constant W_ch : std_logic_vector(6 downto 0) := "0110110"; constant Y_ch : std_logic_vector(6 downto 0) := "0010001"; constant Z_ch : std_logic_vector(6 downto 0) := "0100100"; constant MINUS_ch : std_logic_vector(6 downto 0) := "0111111"; constant UNDERSCORE_ch : std_logic_vector(6 downto 0) := "1110111"; constant EQUAL_ch : std_logic_vector(6 downto 0) := "1110110"; constant OFF_word : std_logic_vector(20 downto 0) := O_ch & F_ch constant STOP_word : std_logic_vector(27 downto 0) := S_ch & T_ch constant RESET_word : std_logic_vector(34 downto 0) := R_ch & E_ch constant STARTING_word : std_logic_vector(55 downto 0) := S_ch & T_ch
; & blnk ; & blnk & blnk ; & blnk & blnk & blnk ;
; & P_ch ; & E_ch & T_ch ; & R_ch & T_ch & I_ch & H_ch & G_ch ;
type seg7_arr is ARRAY(0 to 15) of std_logic_vector(6 downto 0); constant digits : seg7_arr := (O_ch,I_ch,Z_ch,"0110000","0011001",S_ch,"0000010","1111000","0000000",G_ch,A_ch,B_ch,C_ch,D_ch,E_ch,F_ch); -- robot -- robot modes type robot_modes is (nulll, getNewDir, wallGoBack, goNewDir, forward, found_red) ; -- drive modes type drive_modes is (st, fw, bw, cw, ccw); -- wheels modes type w_modes is ARRAY(0 to 4) of wheel_mode; constant rw_modes : w_modes := (w_st, w_fw, w_bw, w_bw, w_fw) ; constant lw_modes : w_modes := (w_st, w_fw, w_bw, w_fw, w_bw) ; -- modes in 6 7seg type m7segDM is ARRAY(0 to 4) of std_logic_vector(41 downto 0); constant m_7segDM : m7segDM := (blnk2&S_ch&T_ch&O_ch&P_ch,F_ch&O_ch&W_ch&A_ch&R_ch&D_ch,B_ch&W_ch&blnk4,C_ch&W_ch&blnk4,blnk2&C_ch&C_ch&W_ch&blnk) ; type m7segRM is ARRAY(0 to 5) of std_logic_vector(41 downto 0); constant m_7segRM : m7segRM := (blnk2&N_ch&U_ch&L_ch&L_ch,N_ch&D_ch&blnk4,blnk2&W_ch&G_ch&O_ch&B_ch,blnk2&G_ch&N_ch&D_ch&blnk,blnk2&F_ch&O_ch&R_ch&W_ ch,blnk2&F_ch&O_ch&N_ch&D_ch) ; -- misc const constant min_dist2keep : integer :=20 ; constant dist_wall_stop : integer :=50 ; constant ang_derivation : integer :=24 ; constant msg_display_t : integer :=50 ; -- time that msg is displayed in units of 10ms constant angle360 : integer :=451 ; constant angle180 : integer :=225 ; constant max_dist : integer :=439 ; constant rotTime011 : integer :=360 ; -- 3.6 sec constant rotTime010 : integer :=530 ; -- 5.3 sec constant t_ds_acquisition : integer := 5 ; -- 50ms end misc_package; package body misc_package is end misc_package;
--Back to Top
wheel.vhd
-- data sheet link library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.misc_package.all; entity wheel is port ( clk : in std_logic ; -- freq: 50MHz. time: 0.00000002 rst : in std_logic ; mode : in wheel_mode ; speed : in std_logic_vector(2 downto 0) ; en : out std_logic ; ctrl1 : out std_logic ; ctrl2 : out std_logic ; pwm : out std_logic ); end entity wheel; architecture arc_wheel of wheel is signal current_mode : wheel_mode; signal en_PWM : std_logic; component PWMgenerator is port ( clk : in std_logic ; --freq: 50MHz. time: 0.00000002. rst : in std_logic ; en : in std_logic ; speed8 : in std_logic_vector(2 downto 0) ; pwm : out std_logic ); end component; begin wheel_pwm: PWMgenerator port map(clk, rst, en_PWM, speed, pwm) ; process(clk, rst) is begin if (rst = '0') then current_mode<=w_stop; -- en=ctrl1=ctrl2=0==> Stop (not Brake) elsif rising_edge(clk) then current_mode<=mode; end if; end process; en_PWM en ctrl1 ctrl2 <= <= <= <= wheel_enable_mode(wheel_mode'pos(current_mode)) ; wheel_enable_mode(wheel_mode'pos(current_mode)) ; ctrl1_mode(wheel_mode'pos(current_mode)) ; ctrl2_mode(wheel_mode'pos(current_mode)) ;
PWMgenerator.vhd
-- generates 4KHz PWM with duty cycle ranging from 10% to 90% depending on speed8 library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use IEEE.numeric_std.all; entity PWMgenerator is port ( clk : in std_logic; rst : in std_logic; en : in std_logic; speed8 : in std_logic_vector(2 downto 0); pwm : out std_logic ); end entity PWMgenerator;
architecture arc_PWMgenerator of PWMgenerator is -- signals & variables signal cnt : std_logic_vector(13 downto 0); -- for counting a cycle of 4KHz=12,500 clk-s begin process (clk, rst) is begin if (rst = '0') then cnt <= (others => '0'); pwm <= '0'; elsif rising_edge(clk) then if (cnt = 12500) then cnt <= (others => '0'); else cnt <= cnt + 1; end if; if(en='1') then if(cnt<1250+To_integer(IEEE.numeric_std.unsigned(speed8))*1429) then -- duty cycle is 10%+(current_speed/8)*80% pwm<='1'; else pwm<='0'; end if; else pwm<='0'; end if; end if; end process; end architecture arc_PWMgenerator; --Back to Top
distanceSensor.vhd
-- data sheet link library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; entity distanceSensor is port ( clk: in std_logic ; rst: in std_logic ; pwm: in std_logic ; trig: out std_logic ; result: out std_logic_vector(9 downto 0) ; done: out std_logic ); end entity distanceSensor; architecture signal signal begin -- trigger trig_proc: begin
-- freq: 50MHz, time: 0.00000002. -- the echo signal. max is 25ms -- should be 10us -- each unit is 0.6834cm (0.002278 from max)
arc_distanceSensor of distanceSensor is cnt : std_logic_vector(21 downto 0); -- for generating trigger q1, q2, q3, result_en : std_logic ; process process (clk, rst) is
if (rst = '0') then cnt <= (others => '0') ; trig <= '0' ; elsif rising_edge(clk) then if (cnt = 2499999) then cnt <=(others => '0') ; else cnt <= cnt + 1 ; end if ;
if (cnt < 500) then trig <= '1' ; else trig <= '0' ; end if; end if; end process trig_proc ; -- echo process echo_proc: process (clk, rst) is variable cnt1 : std_logic_vector(20 downto variable s4,s3,s2,s1 : std_logic_vector(20 variable samples_sum : std_logic_vector(22 begin if (rst = '0') then q1 <= '0' ; q2 <= '0' ; q3 <= '0' ; done <= '0' ; s1 := (others => '0') ; s2 := (others => '0') ; s3 := (others => '0') ; s4 := (others => '0') ; cnt1 := (others => '0') ; result <= (others => '0') ; elsif rising_edge(clk) then q1 <= pwm ; q2 <= q1 ; q3 <= q2 ; if (result_en = '1') then s4 := s3 ; s3 := s2 ; s2 := s1 ; s1 := cnt1 ; samples_sum := ("00" & s1)
0); -- for counting PWM downto 0); -- for saving prev samples downto 0);
end if ; done <= result_en; if (result_en = '1') then cnt1 := (others => '0') ;
elsif (q2 = '1') then cnt1 := cnt1 + 1 ; -- cnt1 is a number between 5,000 and 900,000 end if ;
compass.vhd
-- data sheet link -- data sheet: http://www.cs.uml.edu/~achanler/robotics/compass/compass.html library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; entity compass is port ( clk: in std_logic ; -- freq: 50MHz. time: 0.00000002. rst: in std_logic ; pwm: in std_logic ; -- the echo signal. max is 40ms result: out std_logic_vector(8 downto 0) ; -- each unit is ~0.8 degrees (0.00222 from max) done: out std_logic ); end entity compass ; architecture arc_compass of compass is signal q1, q2, q3, result_en : std_logic ; signal cnt : std_logic_vector(20 downto 0) ; -- for counting PWM begin process (clk, rst) is begin if (rst = '0') then q1 <= '0' ; q2 <= '0' ; q3 <= '0' ; done <= '0' ; cnt <= (others => '0') ; result <= (others => '0') ; elsif rising_edge(clk) then q1 <= pwm ; q2 <= q1 ; q3 <= q2 ; if (result_en = '1') then result <= cnt( 20 downto 12); -- result is number between ~12 and ~451 end if ; done <= result_en ; if (result_en = '1') then cnt <= (others => '0') ; elsif (q2 = '1') then cnt <= cnt + 1 ; -- cnt is a number between 50,000 and 1,850,000 end if ; end if ; end process; result_en <= q3 and (not q2); end architecture arc_compass; --Back to Top
Cam/rom22.vhd
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.misc_package.all; use IEEE.numeric_std.all; entity tests is end entity tests; architecture arc_tests of tests is begin process variable wm: wheel_mode; variable stdl4: std_logic_vector(3 downto 0); variable dig: std_logic_vector(6 downto 0); variable bla: integer range 0 to 8; begin wm:=w_bw; --report "The value of 'a' is " & integer'image(wheel_mode'pos(wm)); stdl4 := "1101" ; bla := 5; bla := bla - 6; report "bla is " & integer'image(bla); --dig := digits(to_integer(ieee.numeric_std.unsigned(stdl4))) ; --dig:=stlv27seg(stdl4); --report "The value of digits at '1101' is " & Std_Logic'image(dig(6)) & Std_Logic'image(dig(5)) & Std_Logic'image(dig(4)) & Std_Logic'image(dig(3)) & Std_Logic'image(dig(2)) & Std_Logic'image(dig(1)) & Std_Logic'image(dig(0)); wait; end process; end architecture arc_tests; --Back to Top
Cam/ReceiveLogic.vhd
library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; -- Description: Logic for receiving data from UART entity ReceiveLogic is port (clk : in std_logic; rst : in std_logic; RXD : in std_logic; receive_data : out std_logic_vector(7 downto 0); done : out std_logic ); end entity ReceiveLogic; architecture Behavioral of ReceiveLogic is type state_vector is (wait_for_start_bit, start_bit_skip, wait_for_middle_point, counts_for_8_bit); signal state : state_vector; signal bit_counter : std_logic_vector(3 downto 0); signal Sdata : std_logic_vector(7 downto 0); signal sample_cnt : std_logic_vector(7 downto 0); signal cnt : std_logic_vector(4 downto 0); signal q1, rxd_fall, sample_cnt_en : std_logic; signal shift_en : std_logic; signal eq_27 : std_logic; signal done_s : std_logic; begin rxd_fall <= (not rxd) and q1; eq_27 <= '1' when (cnt = 27) else '0'; process(clk, rst)is begin if (rst = '0') then Sdata <= (others => '0'); state <= wait_for_start_bit; bit_counter <= (others => '0'); cnt <= (others => '0'); sample_cnt <= (others => '0'); shift_en <= '0'; sample_cnt_en <= '0'; q1 <= '1'; done_s <= '0'; receive_data <= (others => '0'); elsif clk'event and clk = '0' then shift_en <= '0'; done_s <= bit_counter(3) and shift_en; if (done_s='1') then receive_data <= Sdata; end if; if (shift_en = '1') then Sdata <= RXD & Sdata(7 downto 1); end if; if (eq_27 = '1') then q1 <= rxd; cnt <= (others => '0'); if (sample_cnt_en = '1') then sample_cnt <= sample_cnt+1; else
sample_cnt <= (others => '0'); end if; case state is when wait_for_start_bit => sample_cnt_en <= '0'; if (rxd_fall = '1') then state <= start_bit_skip; end if; when start_bit_skip => sample_cnt_en <= '1'; if sample_cnt(3 downto 0) = x"f" then state <= wait_for_middle_point; end if; when wait_for_middle_point => sample_cnt_en <= '1'; if sample_cnt(1 downto 0) = "11" then state <= counts_for_8_bit; sample_cnt_en <= '0'; end if; when counts_for_8_bit => sample_cnt_en <= '1'; if (sample_cnt(3 downto 0) = x"0") then if (bit_counter <= 7) then shift_en <= '1'; bit_counter <= bit_counter+'1'; else bit_counter <= (others => '0'); sample_cnt_en <= '0'; state <= wait_for_start_bit; end if; end if; when others => state <= wait_for_start_bit; end case; else cnt <= cnt+1; end if; end if; end process; done<=done_s; end architecture Behavioral;
--Back to Top
Cam/divider.vhd
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- Description: Clock divider for UART transmit logic. -Generates 115200 baud rate entity divider is Port ( clk rst end divider; architecture arc_divider of divider is SIGNAL s_send_clk :std_logic; SIGNAL count : std_logic_vector(7 downto 0); begin process(clk,rst) begin if rst='0' then count<=(others=>'0'); s_send_clk<='0'; elsif clk'event and clk='1' then if count< 217 then count<=count+'1'; s_send_clk<=s_send_clk; else count<=(others=>'0'); s_send_clk<=NOT s_send_clk; end if; end if; end process; send_clk<= s_send_clk; end arc_divider;
--Back to Top
Cam/SendLogic.vhd
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- Description: Logic for sending data (from rom22.vhd) using UART -to the camera module entity SendLogic is Port ( clk : in std_logic; rst : in std_logic; data_load_req : out std_logic; TXD : out std_logic; eof_found : out std_logic; begin_send : in std_logic; cur_address : out std_logic_vector(7 downto 0); send_data : in std_logic_vector(7 downto 0); cur_state :out std_logic_vector(7 downto 0)); end SendLogic; architecture Behavioral of SendLogic is type state_vector is (start,wait_e,readData,WCheck, SendCounter,AddS,DataLoadS,StartBit,Timer,EOF); signal state : state_vector; signal Sadd : std_logic_vector(7 downto 0); signal counter : std_logic_vector(3 downto 0); signal Sdata : std_logic_vector(7 downto 0); ----------timer signal TimerCount : std_logic_vector(16 downto 0); signal startTimer : std_logic; signal endTimer : std_logic; signal flag : std_logic; begin process(clk,rst) begin if rst='0' then TXD<='1'; flag<='0'; data_load_req<='0'; state<=start; Sadd<=(others=>'1'); Sdata<=(OTHERS=>'0'); counter<=(OTHERS=>'0'); startTimer<='0'; elsif clk'event and clk='1' then case state is when start => flag<='0'; TXD<='1'; data_load_req<='0'; counter<=(OTHERS=>'0'); Sadd<=(others=>'0'); Sdata<=(others=>'0'); state<=wait_e; startTimer<='0'; when wait_e=>
flag<= '0'; TXD<='1'; data_load_req<='0'; counter<=(OTHERS=>'0'); Sadd<=Sadd; Sdata<=Sdata; state<=readData; if begin_send='0' then state<=wait_e; else state<=readData; end if; when readData => flag<= flag; TXD<='1'; data_load_req<='1'; Sadd<=Sadd; Sdata<=send_data; counter<=(OTHERS=>'0'); state<=DataLoadS; when DataLoadS => flag<= flag; TXD<='1'; Sadd<=Sadd; Sdata<=send_data; counter<=(OTHERS=>'0'); state<=WCheck; data_load_req<='1' ; when WCheck=> TXD<='1'; data_load_req<='0'; Sadd<=Sadd; Sdata<=send_data; if send_data=255 then --end of file FF HEX state<=EOF; Sadd<=x"0D"; flag<='0'; elsif send_data=x"00" then state<=Timer; Sadd<=Sadd+'1'; startTimer<='1'; flag<='1'; else state<=StartBit; flag<='0'; end if; when StartBit => flag<= flag; TXD<='0'; data_load_req<='0'; Sadd<=Sadd; Sdata<=Sdata; state<=SendCounter; when SendCounter =>
flag<= flag; if counter<=7 then Sdata<= Sdata(6 downto 0)& Sdata(7) ;--M2L TXD<=Sdata(7); counter<=counter + '1'; state<= Sendcounter; else Sdata<=Sdata; TXD<='1'; counter<=(others=>'0'); state<=AddS; end if; when AddS => Sdata<=Sdata; TXD<='1'; SAdd<=SAdd+'1'; state<=readData; when Timer => if endTimer='0' then state<=Timer; else state<=readData; startTimer<='0'; end if; when EOF => TXD<='1'; state<=EOF; when others=> TXD<='1'; data_load_req<='0' ; Sadd<=(others=>'0'); Sdata<=(others=>'0'); end case; end if; end process; cur_address<=Sadd; eof_found<=flag; ------------------------------------timer onesec PROCESS(clk,rst) begin if rst='0' then TimerCount<=(others=>'0'); endTimer <='0'; elsif clk'event and clk='1' then if startTimer='1' then if TimerCount<=50000 then ---186A0 one sec --if TimerCount<=2 then ---186A0 one sec TimerCount<=TimerCount+'1'; endTimer <='0'; else TimerCount<=(others=>'0'); endTimer <='1'; end if; --one sec
else TimerCount<=(others=>'0'); endTimer <='0'; end if; end if; end process; ---------------------------------with state select cur_state <= x"00" when start, x"01" when wait_e, x"02" when readData, x"03" when WCheck, x"04" when StartBit, x"05" when SendCounter, x"06" when AddS, x"07" when DataLoadS, x"08" when Timer, x"09" when EOF; end Behavioral;
--Back to Top
Cam/rom22.vhd
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- Description: ROM of initiailzation bytes to send to the camera module entity rom22 is Port ( clk : in std_logic; rst : in std_logic; add : in std_logic_vector(7 downto 0); data_load_req : in std_logic; data_out : out std_logic_vector(7 downto 0)); end rom22; architecture Behavioral of rom22 is function byte_swap (din : std_logic_vector) return std_logic_vector is variable temp : std_logic_vector(din'reverse_range); begin for i in din'range loop temp(i):=din(i); end loop; return temp; end function byte_swap; signal sq : std_logic_vector(7 downto 0); begin process(clk,rst) begin if rst='0' then sq <= (others=>'0'); elsif clk'event and clk='1' then if data_load_req='1' then case add is ----1 "RS" when x"00" => sq<=x"52"; --r when x"01" => sq<=x"53"; --s when x"02" => sq<=x"0D"; --CR when x"03" => --one sec sq<=x"00"; ------2 "OM 0 1" when x"04" => sq<=x"4F"; --O when x"05" => sq<=x"4D"; --M when x"06" => sq<=x"20"; --SPACE when x"07" => sq<=x"30"; --0 when x"08" => sq<=x"20"; --SPACE when x"09" => sq<=x"31"; --1 when x"0a" =>
----3
----4
----5
sq<=x"0D"; --CR when x"0b" => sq<=x"00"; --one sec "RM 3" when x"0c" => sq<=x"52"; --R when x"0d" => sq<=x"4D"; --M when x"0e" => --space sq<=x"20"; when x"0f" => sq<=x"33"; --3 when x"10" => sq<=x"0D"; --CR when x"11" => sq<=x"00"; --one sec "HR 1" when x"12" => sq<=x"48"; --H when x"13" => sq<=x"52"; --R when x"14" => sq<=x"20";--SPACE when x"15" => sq<=x"31";--1 when x"16" => sq<=x"0D"; --CR when x"17" => sq<=x"00"; --one sec "VW 1 60 174 254" when x"18" => sq<=x"56"; --V when x"19" => sq<=x"57"; --W when x"1a" => sq<=x"20"; --SPACE when x"1b" => sq<=x"31"; --1 when x"1c" => sq<=x"20"; --SPACE when x"1d" => sq<=x"30"; --0 when x"1e" => sq<=x"31"; --1 when x"1f" => sq<=x"20"; --SPACE when x"20" => sq<=x"31"; --1 when x"21" => sq<=x"37"; --7 when x"22" => sq<=x"34"; --4 when x"23" => sq<=x"20"; --SPACE when x"24" => sq<=x"32"; --2 when x"25" => sq<=x"35"; --5 when x"26" => sq<=x"34"; --4 when x"27" =>
----6
sq<=x"0D"; --CR when x"28" => sq<=x"00"; --one sec "CR 18 44" when x"29" => sq<=x"43"; --C when x"2a" => sq<=x"52"; --R when x"2b" => sq<=x"20";--SPACE when x"2c" => sq<=x"31";--1 when x"2d" => sq<=x"38";--8 when x"2e" => sq<=x"20"; --SPACE when x"2f" => sq<=x"34";--4 when x"30" => sq<=x"34";--4 when x"31" => sq<=x"0D"; --CR when x"32" => sq<=x"00"; --one sec when x"33" => sq<=x"54"; --T when x"34" => sq<=x"43"; --C when x"35" => sq<=x"20"; --SPACE when x"36" => sq<=x"31"; --1 when x"37" => sq<=x"30"; --0 when x"38" => sq<=x"30"; --0 when x"39" => sq<=x"20"; --SPACE when x"3a" => sq<=x"31"; --1 when x"3b" => sq<=x"35"; --5 when x"3c" => sq<=x"30"; --0 when x"3d" => sq<=x"20"; --SPACE when x"3e" => sq<=x"32"; --2 when x"3f" => sq<=x"30"; --0 when x"40" => sq<=x"20"; --SPACE when x"41" => sq<=x"36"; --6 when x"42" => sq<=x"30"; --0 when x"43" => sq<=x"20"; --SPACE when x"44" => sq<=x"32"; --2 when x"45" =>
sq<=x"30"; --0 when x"46" => sq<=x"20"; --SPACE when x"47" => sq<=x"36"; --6 when x"48" => sq<=x"30"; --0 when x"49" => sq<=x"0D"; --CR when x"4a" => sq<=x"00"; --one sec ------8 when x"4b" => sq<=x"ff"; when others=> null; end case; else sq<=sq; end if; end if; end process; data_out<=byte_swap(sq); end Behavioral;
--Back to Top
--
Cam/camera.vhd
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- Description: top-design for the camera logic. It is used for processing the received -data, parsing it and averaging the sampled x coordinates entity camera is PORT( clk : in std_logic; rst : in std_logic; eof_found : out std_logic; -- Send TXD : out std_logic; begin_send : in std_logic; cur_send_state :out std_logic_vector(7 downto 0); -- Receive RXD : in std_logic; x_coord_data : out std_logic_vector(7 downto 0); x_coord_done : out std_logic ); end camera; architecture arc_camera of camera is COMPONENT divider Port ( clk : in std_logic; rst : in std_logic; send_clk : out std_logic); END COMPONENT; COMPONENT SendLogic Port ( clk : in std_logic; rst : in std_logic; data_load_req : out std_logic; TXD : out std_logic; eof_found : out std_logic; begin_send : in std_logic; cur_address : out std_logic_vector(7 downto 0); send_data : in std_logic_vector(7 downto 0); cur_state :out std_logic_vector(7 downto 0)); END COMPONENT; --------RECIEVE COMPONENT ReceiveLogic PORT( clk : IN std_logic; rst : IN std_logic; RXD : IN std_logic; receive_data : OUT std_logic_vector(7 downto 0); done : out std_logic ); END COMPONENT; ---------ROM COMPONENT rom22 Port ( clk : in std_logic; rst : in std_logic;
add : in std_logic_vector(7 downto 0); data_load_req : in std_logic; data_out : out std_logic_vector(7 downto 0)); END COMPONENT; signal s_send_clk : std_logic; signal s_data_load_req : std_logic; signal s_cur_address : std_logic_vector(7 downto 0); signal s_send_data : std_logic_vector(7 downto 0); type state_vector is (wait_for_T,wait_for_data,wait_for_FF); signal state : state_vector; signal receive_data : std_logic_vector(7 downto 0); signal receive_done : std_logic; begin process (rst,clk) variable zero_count : std_logic_vector(2 downto 0); variable x_coord_sum : std_logic_vector(9 downto 0); variable sample1 : std_logic_vector(9 downto 0); variable sample2 : std_logic_vector(9 downto 0); variable sample3 : std_logic_vector(9 downto 0); variable sample4 : std_logic_vector(9 downto 0); begin if (rst='0') then state <= wait_for_T; x_coord_done <= '0'; elsif (clk'event and clk = '1') then -- Wait for 'T' character if (state=wait_for_T) then if (receive_done='1') and (receive_data=84) then state<=wait_for_data; end if; -- Wait for x coordinate elsif (state=wait_for_data) then if (receive_done='1') then --Samples for the averaging sample4 := sample3; sample3 := sample2; sample2 := sample1; sample1 := conv_std_logic_vector(conv_integer(receive_data),10); --Find zeroes in the outputs zero_count:=(others => '0'); if (sample1=0) then zero_count := zero_count + 1; end if; if (sample2=0) then zero_count := zero_count + 1; end if; if (sample3=0) then zero_count := zero_count + 1; end if;
if (sample4=0) then zero_count := zero_count + 1; end if; --Sum of samples x_coord_sum:=sample1+sample2+sample3+sample4; --If more than two zeros, the whole sample is considered zero if (zero_count>2) then x_coord_data <= conv_std_logic_vector(0,8); else -- Calculate average excluding zeros x_coord_data <= conv_std_logic_vector(((conv_integer(x_coord_sum)) / conv_integer((4-zero_count))),8); end if; -- Mark done x_coord_done <= '1'; state<=wait_for_FF; end if; -- Wait for 0xFF byte elsif (state=wait_for_FF) then if (receive_done='1') and (receive_data=255) then state<=wait_for_T; end if; end if; end if; end process; -- Clock for the transmit logic U_divider: divider PORT MAP( clk => clk , rst => rst , send_clk => s_send_clk ); -- Send logic U_SendLogic : SendLogic PORT MAP( clk =>s_send_clk , rst =>rst , data_load_req => s_data_load_req, TXD => TXD , eof_found => eof_found, begin_send => begin_send, cur_address => s_cur_address, send_data => s_send_data, cur_state => cur_send_state ); -- Receive logic U_ReceiveLogic : ReceiveLogic PORT MAP( clk => clk, rst => rst , RXD => RXD , receive_data => receive_data , done=> receive_done );
-- ROM for sending init data U_rom22 : rom22 PORT MAP( clk =>s_send_clk , rst => rst , add => s_cur_address , data_load_req => s_data_load_req, data_out => s_send_data ); end arc_camera;
--Back to Top