VHDL digital clock design and pin locking method

Table of contents

introduction

Course topics

Hours, minutes, seconds module

Frequency division module

Button debounce module

Time adjustment module

Buzzer alarm module

Scan signal output module

Binary to eight-segment digital tube display signal

Results display

summary


introduction

        Recently, the end of the Express Exam Week has been set up, and the tasks have followed. This semester I have to complete the FPGA course design. There are three topics. In order to make up for the regret of the mold welding board course, I chose the digital clock task this time. After two days of hard work and searching for information in various aspects, the course design was finally completed at two o'clock last Saturday night. I have a day off today and I haven’t blogged for a long time, so I’ll write an article to summarize it!

Course topics

 

 As you can see, you only need to complete the normal time display and adjust the hours, minutes and the buzzer sounds at a specific time.

Hours, minutes, seconds module

Without further ado, let’s start with the code.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity second is
port (clk,clr:in std_logic;
	  sec1,sec0:out  std_logic_vector(3 downto 0);
	co:out std_logic);
end second;
architecture sec of second is
SIGNAL cnt1,cnt0:std_logic_vector(3 downto 0);
begin
	process(clk)
	begin
	if(clr='1')then
	cnt0<="0000";
	cnt1<="0000";
	elsif(clk'event and clk='1')then
			if cnt1="0101" and cnt0="1001" then
				co<='1';
				cnt0<="0000";
				cnt1<="0000";
			elsif cnt0<"1001" then
				cnt0<=(cnt0+1);
			else 
			    cnt0<="0000";
				cnt1<=cnt1+1;
				co<='0';
			end if;
		end if;
	sec1<=cnt1;
	sec0<=cnt0;
	end process;
end sec;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity minute is
port (clk:in std_logic;
	  min1,min0:out std_logic_vector(3 downto 0);
	co:out std_logic);
end minute;
architecture min of minute is
SIGNAL cnt1,cnt0:std_logic_vector(3 downto 0);
begin
	process(clk)
	begin
	if(clk'event and clk='1')then
			if cnt1="0101" and cnt0="1001" then
				co<='1';
				cnt0<="0000";
				cnt1<="0000";
			elsif cnt0<"1001" then
				cnt0<=(cnt0+1);
			else 
			    cnt0<="0000";
				cnt1<=cnt1+1;
				co<='0';
			end if;
		end if;
	min1<=cnt1;
	min0<=cnt0;
	end process;
end min;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity hour is
port(clk,en:in std_logic;
h1,h0:out std_logic_vector(3 downto 0));
end hour;

architecture beha of hour is
signal cnt1,cnt0:std_logic_vector(3 downto 0);
begin
process(clk)
begin
if(clk'event and clk='1') then
if cnt1="0010" and cnt0="0011" then
cnt1<="0000";
cnt0<="0000";
elsif cnt0<"1001" then
cnt0<=cnt0+1;
else
cnt0<="0000";
cnt1<=cnt1+1;
end if;
end if;
h1<=cnt1;
h0<=cnt0;
end process;
end beha;

        The above are the codes for seconds, minutes, and hours. The principle is very simple. It is based on counting, and the seconds bit is incremented by one when the clock rises. When the low digit of the second reaches ten, a carry is carried to the high digit of the second. When the high digit of the second reaches six, a carry signal is sent to the minute position. In the same way, the high point of points and the low and high points of time are set. The difference is that the seconds are connected to the divided clock terminal, the seconds are connected to the carry signal, and the hours are connected to the minutes' carry signal.

Frequency division module

library ieee; 
use ieee.std_logic_1164.all;  

entity fenpin is   
port (clk:in std_logic; 
		clk1: out std_logic;
		clk500: out std_logic;
		clk1000: out std_logic;
		clk16:out std_logic;
		clk256: out std_logic);                     
end fenpin; 

architecture fen_arc of fenpin is 
begin  
process(clk)  
variable cnt1: integer range 0 to 24999999;
variable cnt500: integer range 0 to 49999;  
variable cnt1000: integer range 0 to 24999;
variable cnt16: integer range 0 to 1669999; 
variable cnt256: integer range 0 to 99999;     
variable x: std_logic;
variable y: std_logic;  
variable z: std_logic;
variable m: std_logic;   
variable n: std_logic;       
begin   
	if clk'event and clk = '1' then    
		if cnt1<24999999 then     
			cnt1:=cnt1+1;    
		else     
			cnt1:=0;     
			x:= not x;    
		end if;  
	end if; 	
	clk1<=x;
	
	if clk'event and clk = '1' then    
		if cnt500<49999 then     
			cnt500:=cnt500+1;    
		else     
			cnt500:=0;     
			y:= not y;    
		end if;  
	end if; 	
	clk500<=y;
	
	if clk'event and clk = '1' then    
		if cnt1000<24999 then     
			cnt1000:=cnt1000+1;    
		else     
			cnt1000:=0;     
			z:= not z;    
		end if;  
	end if; 	
	clk1000<=z;
	
	if clk'event and clk = '1' then    
		if cnt16<1669999 then     
			cnt16:=cnt16+1;    
		else     
			cnt16:=0;     
			m:= not m;    
		end if;  
	end if; 	
	clk16<=m;
	
	if clk'event and clk = '1' then    
		if cnt256<99999 then     
			cnt256:=cnt256+1;    
		else     
			cnt256:=0;     
			n:= not n;    
		end if;  
	end if; 	
	clk256<=n;
	
	
	
end process; 
end fen_arc;

        The places where a digital clock needs a clock signal are the seconds input terminal, the buzzer input terminal, the button debounce circuit, and the scan display circuit. As needed, divide the frequency into 1Hz, 500/1000Hz, 256Hz, and 16Hz. (Scanning seems to be 500Hz). The method of frequency division is also very simple. The purpose of frequency division can also be achieved by counting.

Button debounce module

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity debounce is
port( clk,din: in std_logic;
		dout: out std_logic);
end debounce;
architecture behav of debounce is
signal counter:integer range 0 to 50000000;
signal df_1,df_2,df,rst_n:std_logic;
constant timer:integer:=5000;
begin


process(clk)
begin
if clk'event and clk='1' then
df_1<=din;
df_2<=df_1;
end if;
df<=df_1 xor df_2;
rst_n<=df;
end process;

process(clk,rst_n)
begin
if rst_n='1' then
counter<=0;
elsif clk'event and clk='1' then
counter<=counter+1;
if counter=50000000 then  
counter<=0;
end if;
if counter>=timer then
dout<=din;
end if;
end if;
end process;
end behav;

Time adjustment module

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity ctrl is
port(clk:in std_logic;  --10HZ
key1,key2,key3:in std_logic;
led1,led2,led3:out std_logic);
end ctrl;
architecture a of ctrl is
begin
process (clk)
begin
if(clk'event and clk='1')then
if(key1='0')then
led1<='1';
elsif(key1='1')then
led1<='0';
end if;

if(key2='0')then
led2<='1';
elsif(key2='1')then
led2<='0';
end if;

if(key3='0')then
led3<='1';
elsif(key3='1')then
led3<='0';
end if;
end if;
end process;
end a;

Buzzer alarm module

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity xiang is
port(m1,m0,s1,s0:in std_logic_vector(3 downto 0);
  clk1,clk2:in std_logic;
    speaker:out std_logic);
end xiang;
architecture sss_arc of xiang is
  begin
  process(clk1,clk2,m1,m0,s1,s0)
  begin
    speaker <= '0';
if(m1="0101"and m0="1001"and s1="0101"and s0="1001")then
speaker<=clk2;--1024HZ
else 
  speaker <= '1';
end if;
if(m1="0101"and m0="1001")then 
  if(s1="0101" )then
   if(s0="0000" or s0="0010" or s0="0100" or s0="0110" or s0="1010")then
  speaker<=clk1;--512HZ
   end if;
  end if;
else
  speaker <= '1';
end if;
end process;
end sss_arc;

Scan signal output module

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity saomiao is
    port(
    clk500:in std_logic;--------------------------------时钟信号
    cnt1:buffer integer);
    end saomiao;

architecture one of saomiao is
begin
process(clk500)-------主要是让计算两个数码管的数值
begin
        if clk500'event and clk500 = '1' then
        if cnt1 = 5 then cnt1 <= 0;
        else
        cnt1 <= cnt1+1;
        end if;
        end if;
end process;
end one;
        

My main purpose here is to generate 0-5 scanning signals, and finally assign them to the scanning module of DigitalClock.vhd to achieve the purpose of scanning. The scanning module code is as follows:

case cn1 is
        when 0 => s <= h_1; q <="011111";------------cnt扫描信号,q位选信号,s数码管显示。
        when 1 => s <= h_0; q <="101111";

        when 2 => s <= min_1; q <="110111";
        when 3 => s <= min_0; q <="111011";

        when 4 => s <= sec_1; q <="111101";
        when 5 => s <= sec_0; q <="111110";
        when others => null;
        
    end case;   

Binary to eight-segment digital tube display signal

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity f2e is
    port(
    clk:in std_logic;
    high,low:in std_logic_vector(3 downto 0);--------------------------------时钟信号
    num1,num0:out std_logic_vector(7 downto 0));
end f2e;

architecture beh of f2e is
begin
    process(clk,high,low)
    begin
        case high is
            when ("0000")=> num1 <= "11000000";
            when ("0001")=> num1 <= "11111001";
            when ("0010")=> num1 <= "10100100";
            when ("0011")=> num1 <= "10110000";
            when ("0100")=> num1 <= "10011001";
            when ("0101")=> num1 <= "10010010";
            when ("0110")=> num1 <= "10000010";
            when ("0111")=> num1 <= "11111000";
            when ("1000")=> num1 <= "10000000";
            when ("1001")=> num1 <= "10010000";
            when others=> num1 <= null;
        end case;

        case low is
            when "0000"=> num0 <= "11000000";
            when "0001"=> num0 <= "11111001";
            when "0010"=> num0 <= "10100100";
            when "0011"=> num0 <= "10110000";
            when "0100"=> num0 <= "10011001";
            when "0101"=> num0 <= "10010010";
            when "0110"=> num0 <= "10000010";
            when "0111"=> num0 <= "11111000";
            when "1000"=> num0 <= "10000000";
            when "1001"=> num0 <= "10010000";
            when others=> num0 <= null;
        end case;
    end process;
end beh;

This code mainly converts the binary numbers output by the previous clock into the corresponding characters displayed by the eight-segment digital tube.

Results display

(woc, the wind at two o'clock in the middle of the night is so cold!)

summary

        The chip model used is Cyclone IV E EP4CE6F17C8. Finally, the digital clock display, time adjustment, and specific time alarm are realized. Complete course requirements. If you need the final project file or sof file, you can get it by private message.

Tips: Pin binding method - Pin Planner, just drag the corresponding pin in directly.

 

 

Guess you like

Origin blog.csdn.net/weixin_47666981/article/details/121728451