EDA Course Design (Digital System Design)--Digital Combination Lock

Table of contents

1. Pay attention

2. Possible problems

3. Title description

4. Realize preliminary preparation

5. Implement the code

6. Pin settings

7. Partial verification


1. Pay attention

This blog is written according to my own course design report, so please do not plagiarize, it is only used to provide you with implementation ideas and some experience, I hope you can understand the key codes based on what I wrote, and master the grammar of VHDL language more proficiently , rules and processes, learn how to realize all functions by yourself;

2. Possible problems

1. For students who will not install quartusII 9.0, you can refer to the previous blog: EDA course design (digital system design)--quartusII 9.0 installation and altera usb-blaster driver identification failure solution

2. If you don’t know how to use the onboard LED lights, 8-segment digital tubes, and clk signals, you can refer to the resources downloaded in the previous blog. In the directory: Digital System Design Experiment\Experiment, EDA-I Portable Digital System Experiment and Design Platform Instructions.pdf file;

3. Title description

Complete the design of a simple combination lock, realize the setting and unlocking of 6-digit combination.

1) Use 6 keys to enter the password, K0-K5, respectively represent the number keys 0-5, and use the 6 digital tubes on the right to display;

2) The initial value of the password is 555555; unlocking method: xxxxxx (x represents the number of the password, and the number of digits is equal to 6 digits); after power on, the initial display: "PP------"; enter a number and it will be on the rightmost number tube display, the previous numbers are moved to the left by one digital tube. If the input is correct, it will display "--OPEN--", if the input is wrong, it will display "--EEEE--".

3) Design a re-input button K6, when the input is incomplete or wrong (not up to 3 times), the input will be resumed, and "PP------" will be displayed after pressing

4) The working clock is 1khz; if you enter the wrong password three times in a row, it will be locked, and only restart the circuit; if you make two mistakes in a row, the alarm light will be turned on.

5) Use key k7 to set the password, setting method: the old password, input twice, it will be displayed as "OP------" before input, and prompt to enter the new password after correct: "NP------", Enter 2 times in a row. All the above errors display "--EEEE--", you can press K7 to restore the settings, or K6.

4. Realize preliminary preparation

According to the description of the topic, we can divide the general design into two main parts, the first part is unlocking, and the second part is resetting the password;

After figuring out the function you want to achieve, the following is the process of designing the program, because most of VHDL is executed in parallel, but I am used to writing sequential code, so I made many logical mistakes when writing the program, such as When assigning values ​​to some signals, I originally wanted to change them one by one, but because they are executed in parallel, they are always assigned together, so the digital tube can only display the same content, and I cannot get the result I want. I will think later After a long time, I also referred to some other people’s articles. After repeated tests, I found that the state transition can achieve the function I want, so I finally decided to use a similar state transition method to achieve the effect I want. To achieve this topic The requirements are not clear in a few words, the process is very painful, but you should not choose to put it badly because of some difficulties, you should understand the structure of VHDL, try to understand the knowledge in the book and the reference code, so that you can To achieve the purpose of all functions, which should also be the purpose of the course design;

The following is my own mind map for this topic. This picture was made after I realized all the password locks. It is a later thing. It is mainly put here for everyone to understand the following code and understand the train of thought;

5. Implement the code

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity seg is
	port(
		clk : in std_logic;
		key0,key1,key2,key3,key4,key5,key6,key7 : in std_logic;
		led_warning : out std_logic_vector(7 downto 0);
		smg_led : out std_logic_vector(7 downto 0);--数码管8段led
		smg_code : out std_logic_vector(7 downto 0)--8个数码管
);
end entity seg;
architecture display of seg is
	type smg_led_array is array (7 downto 0) of std_logic_vector(7 downto 0);
	signal smg_leds : smg_led_array;
	signal smg_index : integer range 0 to 7 :=0;
	
	type smg_code_array is array (0 to 9) of std_logic_vector(7 downto 0);
	signal smg_codes : smg_code_array;				--存放字符
	
	signal password : std_logic_vector(17 downto 0);
	signal password_code:std_logic_vector(17 downto 0) :="101101101101101101";
	
	type smg_int_array is array (7 downto 0) of integer;
	signal smg_int : smg_int_array :=(7,7,6,6,6,6,6,6);	--存放字符对应的数字
	
	signal counter,count : std_logic_vector(1 downto 0) := "00";
	signal i : std_logic_vector(2 downto 0) := "000"; 
	signal state : std_logic_vector(3 downto 0) := "0000";
	signal k0,k1,k2,k3,k4,k5,k6,k7 :  std_logic;
	
begin
	smg_codes(0)<="00111111";--0					--字符对应的数字数组
	smg_codes(1)<="00000110";--1
	smg_codes(2)<="01011011";--2
	smg_codes(3)<="01001111";--3
	smg_codes(4)<="01100110";--4
	smg_codes(5)<="01101101";--5
	smg_codes(6)<="01000000";--'-'
	smg_codes(7)<="01110011";--'P'
	smg_codes(8)<="01111001";--'E'
	smg_codes(9)<="00110111";--'N'
	--动态扫描数码管的进程
	smg_saomiao:process(clk)
	begin
		if clk'event and clk='1' then 
			smg_led<=smg_leds(smg_index);--shu_ma_guan_shu_chu
			smg_code <= not(conv_std_logic_vector(2**smg_index,8));
			if smg_index=7 then smg_index<=0;
			else smg_index<=smg_index+1;
			end if;
		end if;
	end process;
	--数码管显示进程
	smg_show:process(clk)
	begin
		smg_leds(7) <= smg_codes(smg_int(7));
		smg_leds(6) <= smg_codes(smg_int(6));
		smg_leds(5) <= smg_codes(smg_int(5));
		smg_leds(4) <= smg_codes(smg_int(4));
		smg_leds(3) <= smg_codes(smg_int(3));
		smg_leds(2) <= smg_codes(smg_int(2));
		smg_leds(1) <= smg_codes(smg_int(1));
		smg_leds(0) <= smg_codes(smg_int(0));
	end process;
	--处理按键的进程
	handle_key:process(clk,state,key0,key1,key2,key3,key4,key5,key6,key7)
	variable int_temp : smg_int_array ;
	begin
		if clk'event and clk='1' then						--统一时钟信号		k0<=key0;k1<=key1;k2<=key2;k3<=key3;k4<=key4;k5<=key5;k6<=key6;k7<=key7;
			--state0:										--状态0:初始化
			if state="0000" then
			int_temp:=(7,7,6,6,6,6,6,6);
			state<="0001";								--进入状态1
			i<="000";
			password<="000000000000000000";
			end if;
			--state0										--状态0结束
			--state1:										--状态1:确定密码
			if state="0001" then
				if i="110" then
					i<="000";
					if password=password_code then 		--密码正确
						led_warning<="00000000";
						counter<="00";
						state<="0010";					--进入状态2
						int_temp:=(6,6,0,7,8,9,6,6);		--显示“--OPEN--”
					else --mi_ma_false;
						counter<=counter+"01";
						--password<="000000000000000000";
						if counter="01" then 
							led_warning<="11111111"; 	--报警
							state<="0010";				--进入状态2
							int_temp:=(6,6,8,8,8,8,6,6);	--显示“--EEEE--”
						elsif counter="10" then 			--密码错误三次
							state<="1000";				--进入死锁状态
							int_temp:=(8,8,8,8,8,8,8,8);	--显示“EEEEEEEE”
						else 
							led_warning<="00000000";
							state<="0010";				--进入状态2
							int_temp:=(6,6,8,8,8,8,6,6);	--显示“--EEEE--”
						end if;
					end if;
				else 
					--判断是哪个key
					if (k0='0')and(key0='1') then			--key0
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="000";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),0);
					end if;
					if (k1='0')and(key1='1') then 			--key1
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="001";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),1);
					end if;
					if (k2='0')and(key2='1')then			--key2
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="010";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),2);
					end if;
					if (k3='0')and(key3='1') then 			--key3
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="011";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),3);
					end if;
					if (k4='0')and(key4='1') then 			--key4
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="100";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),4);
					end if;
					if (k5='0')and(key5='1') then			--key5
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="101";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),5);
					end if;
					if (k6='0')and(key6='1') then 			--key6
						state<="0000";					--回到状态0
						counter<="00";					--计数器清0
					end if;
					if (k7='0')and(key7='1') then
						state<="0011";					--进入状态3
					end if;
				end if;
			end if;
			--state1										--判断按键状态结束
			--state2:		--恢复状态,按key6重新输入,按key7进入重置密码
			if state="0010" then 
				password<="000000000000000000";
				if (k6='0')and(key6='1') then
					state<="0000";						--回到状态0
				end if;
				if (k7='0')and(key7='1') then
					state<="0011";						--进入状态3
				end if;
			end if;
			--state2										--状态2结束		
			--state3:									--状态3:重置密码中间态
			if state="0011" then
				int_temp:=(0,7,6,6,6,6,6,6);				显示“OP-----”
				state<="0100";							--进入状态4
				i<="000";
				password<="000000000000000000";
			end if;
			--state3										--状态3结束
			--state4:										--状态4:确认旧密码
			if state="0100" then
				if i="110" then
					i<="000";
					count<=count+"01";
					if password=password_code then --mi_ma_true
						counter<=counter+"01";
						count<="00";
						led_warning<="00000000";
						if counter="01" then			--连续两次输入正确旧密码
							counter<="00";
							int_temp:=(9,7,6,6,6,6,6,6);	--显示“NP------”
							state<="0110";				--进入状态6
						else 
							state<="0011";			--正确一次,回到状态3
						end if;
					else 
						if count="01" then 				--连续两次错误
							state<="1000";				--进入死锁状态
							int_temp:=(8,8,8,8,8,8,8,8);	--显示“EEEEEEEE”
						else 
							led_warning<="11111111";	--报警
							state<="0101";		--输入错误旧密码,进入状态5
							int_temp:=(6,6,8,8,8,8,6,6);	--显示“--EEEE--”
							i<="000";
						end if;
					end if;
				else 
					--判断key
					if (k0='0')and(key0='1') then 			--key0
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="000";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),0);
					end if;
					if (k1='0')and(key1='1') then 			--key1
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="001";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),1);
					end if;
					if (k2='0')and(key2='1')then 			--key2
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="010";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),2);
					end if;
					if (k3='0')and(key3='1') then			--key3
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="011";		int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),3);
					end if;
					if (k4='0')and(key4='1') then 			--key4
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="100";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),4);
					end if;
					if (k5='0')and(key5='1') then 			--key5
						i<=i+"001";
						password(17 downto 3)<=password(14 downto 0);
						password(2 downto 0)<="101";		int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),5);
					end if;
				end if;
			end if;
			--state4										--状态4结束
			--state5:	--状态5:确认旧密码中间态,按key6或key7回到状态3
			if state="0101" then 
				if (k6='0')and(key6='1') then			
					state<="0011";						--回到状态3
				end if;
				if (k7='0')and(key7='1') then
					state<="0011";						--回到状态3
				end if;
			end if;
			--state5										--状态5结束
			--state6:								--状态6:设置新密码中间态
			if state = "0110" then 
				state<="0111";							--进入状态7
				i<="000";
			end if;
			--state6										--状态6结束
			--state7:										--状态7:设置新密码
			if state="0111" then 
				if i="110" then
					state<="0000";				--成功设置新密码,回到状态0
					int_temp:=(7,7,6,6,6,6,6,6);			--显示“PP--------”
				else
					--判断key
					if (k0='0')and(key0='1') then			--key0
						i<=i+"001";
					password_code(17 downto 3)<=password_code(14 downto 0);
						password_code(2 downto 0)<="000";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),0);
					end if;
					if (k1='0')and(key1='1') then 			--key1
						i<=i+"001";
					password_code(17 downto 3)<=password_code(14 downto 0);
						password_code(2 downto 0)<="001";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),1);
					end if;
					if (k2='0')and(key2='1')then 			--key2
						i<=i+"001";
					password_code(17 downto 3)<=password_code(14 downto 0);
						password_code(2 downto 0)<="010";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),2);
					end if;
					if (k3='0')and(key3='1') then 			--key3
						i<=i+"001";
					password_code(17 downto 3)<=password_code(14 downto 0);
						password_code(2 downto 0)<="011";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),3);
					end if;
					if (k4='0')and(key4='1') then 			--key4
						i<=i+"001";
					password_code(17 downto 3)<=password_code(14 downto 0);
						password_code(2 downto 0)<="100";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),4);
					end if;
					if (k5='0')and(key5='1') then 			--key5
						i<=i+"001";
					password_code(17 downto 3)<=password_code(14 downto 0);
						password_code(2 downto 0)<="101";
	int_temp:=(int_temp(6),int_temp(5),int_temp(4),int_temp(3),int_temp(2),int_temp(1),int_temp(0),5);
					end if;
				end if;
			end if;
			--state7										--状态7结束
		end if;
		--把中间结果赋值给数码管对应字符的数字数组
		smg_int<=int_temp;
	end process;
end architecture display;

6. Pin settings

According to the requirements of the topic, the onboard resources to be used include the clock signal clk: pin128 (1khz); 8 digital tubes: pin135, pin133, pin132, pin131, pin130, pin121, pin120, pin119; the 8-segment LED lights of the digital tube: pin144, pin143, pin142, pin141, pin140, pin138, pin137, pin136; 8 keys: K7: pin43, K6: pin42, K5: pin41, K4: pin39, K3: pin38, K2: pin37, K1: pin36, K0: pin35; 8 alarm led lights: pin95, pin92, pin91, pin90, pin89, pin88, pin87, pin86. 

7. Partial verification

1. Initial display:

 2. Open the lock:

3. Reset password:

 4. Enter a new password:

Guess you like

Origin blog.csdn.net/qq_63306482/article/details/128559197