VHDL实现交通灯程序

1、交通灯控制器设计

状态转换图:

各个状态的时间:

数码管显示原理图:

程序的模块分类:

源代码:

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_unsigned.all;
USE IEEE.STD_LOGIC_ARITH.ALL;

--io define--
entity traffic_Light is
	 port(
		 sysclk : in STD_LOGIC;  --ipput->system clock
		 reset : in STD_LOGIC;   --reset signal  -> 0 to reset ,1 :normal
		 enable : in STD_LOGIC;  --enable signal -> 1 to enable,0 to disable
		 led : out std_logic_vector ( 5 downto 0);  --ledcontrol
		 DIG_S,SEG : out std_logic_vector(7 downto 0)   --seg,bitselect and segselect
	     );
end traffic_Light;

architecture rtl of traffic_Light is		

	signal clk : std_logic;		--1khz   0.001s
	signal clk1 : std_logic;	--1hz    1s
	signal cnt : std_logic_vector ( 15 downto 0);  --counter      16bit 
	signal cnt1 : std_logic_vector ( 11 downto 0); --counter 1    12bit
	signal count : std_logic_vector ( 1 downto 0);

	signal i:integer:=0;   --creat a interger varibale i and init 0
	signal abshi,abge,cdshi,cdge:integer;  --ab oriential time,include shi ge
	signal abshi1,abge1,cdshi1,cdge1:std_logic_vector (7 downto 0);  --control IO

	type state_type is (s0, s1, s2, s3);   --define the all of states
	signal state   : state_type:=s0;       --init statas is s0
	signal y_ab,r_ab,g_cd,y_cd:INTEGER RANGE 0 TO 35; --
	signal g_ab:INTEGER:=30;    --intial ab oriental green_lignt is 30 seconds
	signal r_cd:INTEGER:=35;	--intial cd oriental red_light is 35  seconds
begin
----div the system clock module--
process( sysclk ,reset )   --process sentiment is sysclk and reset
begin
	if reset='0' then
		cnt <= "0000000000000000";   --reset enable ,initial the cnt 
		clk <= '1';					 
	elsif ( sysclk'event and sysclk = '1') then   --if system rise edge
		cnt <= cnt + 1;    --cnt++
		if (cnt = "0000000000001101") then--0110000110101000=25000  50000 is a cycle
		                                  --0000000000000101=5      5Mhz = 0.0000002s    
		cnt <= "0000000000000000";
			clk <= NOT clk ;    -- 25000 times invert the clk
		end if ;	
	end if;
end process ;
--div the clk  -- > clk1 --
--the clk is 1k Hz 0.001s,--
--create clk1 1  the frequency is 1s --
process  (clk ,reset)
begin
	if reset='0' then
		cnt1 <= "000000000000";
		clk1 <= '0';
	elsif ( clk'event and clk = '1') then  -- 1khz  0.001s extcute 
	                                       -- 50Mhz 0.0000002s extcute ,
		cnt1 <= cnt1 + 1;
		if (cnt1 = "0101") then--000111110100=500  1k->0.5s   5M->0.0001s=0.1ms
			cnt1 <= "000000000000" ;   --one cycle is Tclk * 500*2 
			                           --5MHz  cycle = 0.0000002 *1000 = 0.0002s = 0.2ms
			clk1 <= NOT clk1 ; --the clk cycle is 1s
		end if ;
	end if;
end process ;
	
--the clk1 is 1s--  need 70 one cycle = 0.2 * 70 = 14 ms
process (clk1, reset)
begin
		if reset = '0' then
			state <= s0;g_ab<=30;r_cd<=35;  --this is a reset process
		elsif (clk1='1' AND clk1'EVENT ) then  --respond clk rise edge
			if enable = '1' then                --makesure enable,vaild is 1
				case state is
					when s0=>       --the first process 
						if g_ab=0 then   --ab oriental green_light On
							state <= s1;y_ab<=4;abshi<=0;abge<=5;
						else
							--g_ab will deduct 1
							state <= s0;g_ab<=g_ab-1;
							--seg display--ab oriental including ge shi
							abshi<=g_ab/10;abge<=g_ab rem 10;
						end if;	
						r_cd<=r_cd-1;cdshi<=r_cd/10;cdge<=r_cd rem 10;		
					when s1=>
						if y_ab=0 then  --if y_ab duduct to 0,yellow_light timeout
							state <= s2; --enter satate s2
							r_ab<=34;g_cd<=29; --initial the ab oriental value
							abshi<=3;abge<=5;  --initial the seg display
							cdshi<=3;cdge<=0;
						else
							state <= s1;   --enter state s1
							y_ab<=y_ab-1;  --sub y_ab
							abshi<=y_ab/10;abge<=y_ab rem 10;  --refresh ab seg
							r_cd<=r_cd-1;cdshi<=r_cd/10;cdge<=r_cd rem 10; --refresh cd seg
						end if;
						
					when s2=>
						if g_cd=0  then
							state <= s3;y_cd<=4;cdshi<=0;cdge<=5;
						else
							state <= s2;g_cd<=g_cd-1;cdshi<=g_cd/10;cdge<=g_cd rem 10;
						end if;
						r_ab<=r_ab-1;abshi<=r_ab/10;abge<=r_ab rem 10;
					when s3 =>
						if y_cd=0  then
							state <= s0;g_ab<=29;r_cd<=34;cdshi<=3;cdge<=5;abshi<=3;abge<=0;
						else
							state <= s3;y_cd<=y_cd-1;cdshi<=y_cd/10;cdge<=y_cd rem 10;r_ab<=r_ab-1;abshi<=r_ab/10;abge<=r_ab rem 10;
						end if;
						
				end case;
			end if;
		end if;
end process;
process (state)
begin
		case state is
			when s0 =>
				led <= "011110";--100001
			when s1 =>
				led <= "101110";--010001
			when s2 =>
				led <= "110011";--001100
			when s3 =>
				led <= "110101";--001010
		end case;
		if (abshi=0) then 
			if abge<=3 then
				if clk1 = '0' then
					led(5)<='1';led(4)<='1';led(3)<='1';
				end if;
			end if;
		end if;
		if (cdshi=0) then 
			if cdge<=3 then
				if clk1 = '0' then
					led(2)<='1';led(1)<='1';led(0)<='1';
				end if;
			end if;
		end if;
end process;
--seg display--
--the proces is conver the interget to vector for the purpose of controling the IO
process(cdge,cdshi,abge,abshi)
begin
		case cdge is
			when 0 => cdge1<="11000000";--00111111
			when 1 => cdge1<="11111001";--00000110
			when 2 => cdge1<="10100100";--01001011
			when 3 => cdge1<="10110000";--01001111
			when 4 => cdge1<="10011001";--01100110 	
			when 5 => cdge1<="10010010";--01101101
			when 6 => cdge1<="10000011";--01111100	
			when 7 => cdge1<="11011000";--00100111	
			when 8 => cdge1<="10000000";--01111111
			when 9 => cdge1<="10011000";--01100111	
			when others => cdge1<="11111111";
		end case;
		case cdshi is
			when 0 => cdshi1<="11000000";--00111111
			when 1 => cdshi1<="11111001";--00000110
			when 2 => cdshi1<="10100100";--01001011
			when 3 => cdshi1<="10110000";--01001111
			when 4 => cdshi1<="10011001";--01100110 	
			when 5 => cdshi1<="10010010";--01101101
			when 6 => cdshi1<="10000011";--01111100	
			when 7 => cdshi1<="11011000";--00100111	
			when 8 => cdshi1<="10000000";--01111111
			when 9 => cdshi1<="10011000";--01100111	
			when others => cdshi1<="11111111";
		end case;
		case abge is
			when 0 => abge1<="11000000";--00111111
			when 1 => abge1<="11111001";--00000110
			when 2 => abge1<="10100100";--01001011
			when 3 => abge1<="10110000";--01001111
			when 4 => abge1<="10011001";--01100110 	
			when 5 => abge1<="10010010";--01101101
			when 6 => abge1<="10000011";--01111100	
			when 7 => abge1<="11011000";--00100111	
			when 8 => abge1<="10000000";--01111111
			when 9 => abge1<="10011000";--01100111	
			when others => abge1<="11111111";
		end case;
		case abshi is
			when 0 => abshi1<="11000000";--00111111
			when 1 => abshi1<="11111001";--00000110
			when 2 => abshi1<="10100100";--01001011
			when 3 => abshi1<="10110000";--01001111
			when 4 => abshi1<="10011001";--01100110 	
			when 5 => abshi1<="10010010";--01101101
			when 6 => abshi1<="10000011";--01111100	
			when 7 => abshi1<="11011000";--00100111	
			when 8 => abshi1<="10000000";--01111111
			when 9 => abshi1<="10011000";--01100111	
			when others => abshi1<="11111111";
		end case;	
end process;


--resfresh the seg--
--every 0.001 s excute--
process(clk,i)
begin
		if clk'event and clk='1' then
		DIG_S<="11111111";  --this is bit select,close all of seg  
			DIG_S(i)<='0';
			case (i) is
				when 0 => SEG<= cdge1;
				when 1 => SEG<= cdshi1;
				when 2 => SEG<="11111111";	
				when 3 => SEG<="11111111";
				when 4 => SEG<= abge1;
				when 5 => SEG<= abshi1;
				when 6 => SEG<="11111111";	
				when 7 => SEG<="11111111";	
				when others => SEG<="11111111";
			end case;
			i<=i+1;
			if i=8 then i<=0;end if;
		end if;
end process;
end rtl;

全部源代码下载:https://download.csdn.net/download/qq_36243942/11133915


发布了91 篇原创文章 · 获赞 247 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/qq_36243942/article/details/89441651