Table of contents
Hours, minutes, seconds module
Binary to eight-segment digital tube display signal
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.