抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

这是一个简易的1khz输入频率的电子钟。简易数字钟电路分两个层次:
(1)顶层:由一个时计数模块(24进制)和分、秒计数模块(60进制)、
分频器、动态扫描模块组成顶层的原理图CLOCK.BDF;
(2)底层:设计24进制、60进制技术模块、动态扫描模块、分频器模块。

1.先设计底层的24进制和60进制模块

60进制模块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity counter_60 is
Port ( clk : in STD_LOGIC; -- 时钟信号(1Hz)
reset : in STD_LOGIC; -- 异步复位
count : out STD_LOGIC_VECTOR(7 downto 0); -- 计数值(BCD码表示)
carry : out STD_LOGIC -- 进位信号
);
end counter_60;

architecture Behavioral of counter_60 is
signal cnt : integer range 0 to 59 := 0;
begin
process(clk, reset)
begin
if reset = '1' then
cnt <= 0;
carry <= '0';
elsif rising_edge(clk) then
if cnt = 59 then
cnt <= 0;
carry <= '1';
else
cnt <= cnt + 1;
carry <= '0';
end if;
end if;
end process;

-- 将二进制计数值转换为BCD码
count <= std_logic_vector(to_unsigned(cnt / 10, 4) & to_unsigned(cnt mod 10, 4));
end Behavioral;

24 进制模块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity counter_24 is
Port ( clk : in STD_LOGIC; -- 时钟信号(来自分钟计数器的进位)
reset : in STD_LOGIC; -- 异步复位
count : out STD_LOGIC_VECTOR(7 downto 0); -- 计数值(BCD码表示)
carry : out STD_LOGIC -- 进位信号
);
end counter_24;

architecture Behavioral of counter_24 is
signal cnt : integer range 0 to 23 := 0;
begin
process(clk, reset)
begin
if reset = '1' then
cnt <= 0;
carry <= '0';
elsif rising_edge(clk) then
if cnt = 23 then
cnt <= 0;
carry <= '1';
else
cnt <= cnt + 1;
carry <= '0';
end if;
end if;
end process;

-- 将二进制计数值转换为BCD码
count <= std_logic_vector(to_unsigned(cnt / 10, 4) & to_unsigned(cnt mod 10, 4));
end Behavioral;

2.设计 1Khz->1Hz 的分频模块

分频器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity freq_divider is
Port ( clk_in : in STD_LOGIC; -- 输入时钟
reset : in STD_LOGIC; -- 异步复位
clk_out : out STD_LOGIC -- 输出时钟
);
end freq_divider;

architecture Behavioral of freq_divider is
constant N : integer := 1000; -- 分频系数
signal count : integer range 0 to N/2-1 := 0;
signal clk_div : STD_LOGIC := '0';
begin
process(clk_in, reset)
begin
if reset = '1' then
count <= 0;
clk_div <= '0';
elsif rising_edge(clk_in) then
if count = N/2-1 then
count <= 0;
clk_div <= not clk_div;
else
count <= count + 1;
end if;
end if;
end process;

clk_out <= clk_div;
end Behavioral;

3.设计动态扫描模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity dynamic_scan is
Port (
clk_scan : in STD_LOGIC; -- 扫描时钟
reset : in STD_LOGIC; -- 异步复位
digits : in STD_LOGIC_VECTOR(23 downto 0); -- 输入6位BCD数字
seg : out STD_LOGIC_VECTOR(6 downto 0); -- 段选信号
sel : out STD_LOGIC_VECTOR(2 downto 0) -- 位选信号
);
end dynamic_scan;

architecture Behavioral of dynamic_scan is
signal scan_count : unsigned(2 downto 0) := (others => '0'); -- 扫描计数器
signal current_digit : STD_LOGIC_VECTOR(3 downto 0); -- 当前显示的BCD
begin

-- 扫描计数器
process(clk_scan, reset)
begin
if reset = '1' then
scan_count <= (others => '0');
elsif rising_edge(clk_scan) then
if scan_count = 7 then
scan_count <= (others => '0');
else
scan_count <= scan_count + 1;
end if;
end if;
end process;

-- 位选信号
sel <= std_logic_vector(scan_count);

-- 当前显示内容选择
process(scan_count, digits)
constant DASH : STD_LOGIC_VECTOR(3 downto 0) := "1010"; -- 定义破折号
begin
case to_integer(scan_count) is
when 0 =>
current_digit <= digits(7 downto 4); -- 第一位数字
when 1 =>
current_digit <= digits(3 downto 0); -- 第二位数字
when 2 =>
current_digit <= DASH; -- 第三位破折号
when 6 =>
current_digit <= digits(15 downto 12); -- 第四位数字
when 7 =>
current_digit <= digits(11 downto 8); -- 第五位数字
when 5 =>
current_digit <= DASH; -- 第六位破折号
when 3 =>
current_digit <= digits(23 downto 20); -- 第七位数字
when 4 =>
current_digit <= digits(19 downto 16); -- 第八位数字
when others =>
current_digit <= "0000"; -- 默认关闭
end case;
end process;

-- 数字到段选信号译码
process(current_digit)
begin
case current_digit is
when "0000" => seg <= "0111111"; -- 显示 0
when "0001" => seg <= "0000110"; -- 显示 1
when "0010" => seg <= "1011011"; -- 显示 2
when "0011" => seg <= "1001111"; -- 显示 3
when "0100" => seg <= "1100110"; -- 显示 4
when "0101" => seg <= "1101101"; -- 显示 5
when "0110" => seg <= "1111101"; -- 显示 6
when "0111" => seg <= "0000111"; -- 显示 7
when "1000" => seg <= "1111111"; -- 显示 8
when "1001" => seg <= "1101111"; -- 显示 9
when "1010" => seg <= "1000000"; -- 显示破折号
when others => seg <= "0000000"; -- 默认关闭
end case;
end process;

end Behavioral;

4.编译模块,获得组件;使用原理图调用上述模块,设计电子钟的顶层模块

顶层模块设计图
顶层模块设计图—本地

实验结果:

实验结果
实验结果-本地

评论