请教大神VHDL FPGA设计多功能电子表

2024-12-28 13:05:45
推荐回答(1个)
回答1:

数字秒表电路的设计
一、设计要求

设计用于体育比赛的数字秒表,要求:
⑴计时器能显示 0.01s的时间。
m ⑵计时器的最长计时时间为 24h。

总体框图如图2所示

二、模块及模块的功能

⑴ 100进制计数器模块BAI见图2 .1, 输出值为 0.01s和0.1s。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity bai is
port( clr ,clk: in std_logic;
bai1,bai0:out std_logic_vector(3 downto 0);
c0: out std_logic);
end bai;
architecture bai_arc of bai is
begin
process(clk, clr)
variable cnt0,cnt1:std_logic_vector(3 downto 0);
begin
if clr ='0'then
cnt0:="0000";
cnt1:="0000";
elsif clk'event and clk='1' then
if cnt0 ="1000"and cnt1 ="1001"then
cnt0:="1001";
c0<='1';
elsif cnt0 <"1001" then
cnt0:=cnt0+1;
else cnt0:="0000";
if cnt1 <"1001" then
cnt1:=cnt1+1;
else
cnt1:="0000";
c0<='0';
end if;
end if;
end if;
bai1<=cnt1;
bai0<=cnt0;
end process;
end bai_arc;

⑵ 60进制计数器模块MIAO见图2.2,用于对秒和分的计数。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity miao is
port(clr,clk,en:in std_logic;
sec1,sec0:out std_logic_vector(3 downto 0);
c0:out std_logic);
end miao;
architecture miao_arc of miao is
begin
process(clk,clr)
variable cnt0,cnt1:std_logic_vector(3 downto 0);
begin
if clr='0'then
cnt0:="0000";
cnt1:="0000";
elsif clk'event and clk='1'then
if en='1'then
if cnt1="0101" and cnt0="1000"then
cnt0:="1001"; c0<='1';
elsif cnt0<"1001"then
cnt0:=cnt0+1;
else cnt0:="0000";
if cnt1<"0101"then
cnt1:=cnt1+1;
else
cnt1:="0000";
c0<='0';
end if;
end if;
end if;
end if;
sec1<=cnt1;
sec0<=cnt0;
end process;
end miao_arc;

⑶ 24进制计数器模块HOU见图2 .3, 计数输出为小时的数值。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity hou is
port(en,clk,clr:in std_logic;
h1,h0:out std_logic_vector(3 downto 0));
end hou;
architecture hour_arc of hou is
begin
process(clk)
variable cnt0,cnt1:std_logic_vector(3 downto 0);
begin
if clr='0'then
cnt0:="0000";
cnt1:="0000";
elsif clk'event and clk='1'then
if en='1'then
if cnt0="0011" and cnt1="0010"then
cnt0:="0000"; cnt1:="0000";
elsif cnt0<"1001"then
cnt0:=cnt0+1;
else
cnt0:="0000";
cnt1:=cnt1+1;
end if;
end if;
end if;
h1<=cnt1;
h0<=cnt0;
end process;
end hour_arc;
⑷同步消除抖动模块 DOU见图2.4。

library ieee;
use ieee.std_logic_1164.all;
entity dou is
port(din,clk:in std_logic;
dout:out std_logic);
end dou;
architecture dou_arc of dou is
signal x,y:std_logic;
begin
process(clk)
begin
if clk'event and clk='1'then
x<=din;
y<=x;
end if;
dout<=x and(not y);
end process;
end dou_arc;
⑸启停控制模块 AAB见图2.5。秒表的启停是通过控制送给计数器的时钟来实现的,当按下启停键后,输出端Q的状态发生反转。Q为‘1'时,时钟可通过与门,秒表计时;Q为‘0'时,时钟被屏蔽,计数器得不到时钟,停止计数。

library ieee;
use ieee.std_logic_1164.all;
entity aab is
port(a,clk,clr:in std_logic;
q:out std_logic);
end aab;
architecture aab_arc of aab is
begin
process(clk)
variable tmp:std_logic;
begin
if clr='0'then tmp:='0';
elsif clk'event and clk='1'then
if a='1'then
tmp:=not tmp;
end if;
end if;
q<=tmp;
end process;
end aab_arc;
⑹产生数码管的片选信号模块 SEL见图2.6 。

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

entity sel is
port(clk:in std_logic;
q:out std_logic_vector(2 downto 0));
end sel;

architecture sel_arc of sel is
begin
process(clk)
variable cnt:std_logic_vector(2 downto 0);
begin
if clk'event and clk='1'then
cnt:=cnt+1;
end if;
q<=cnt;
end process;
end sel_arc;
⑺模块 BBC见图2.7,此模块对应不同的片选信号,输出不同的要显示的数据。

library ieee;
use ieee.std_logic_1164.all;
entity bbc is
port(bai1,bai0,sec1,sec0,min1,min0,h1,h0:in std_logic_vector(3 downto 0);
sel:in std_logic_vector(2 downto 0);
q: out std_logic_vector(3 downto 0));
end bbc;
architecture bbb_arc of bbc is
begin
process(sel)
begin
case sel is
when "000"=>q<=bai0;
when "001"=>q<=bai1;
when "010"=>q<=sec0;
when "011"=>q<=sec1;
when "100"=>q<=min0;
when "101"=>q<=min1;
when "110"=>q<=h0;
when "111"=>q<=h1;
when others=>q<="111";
end case;
end process;
end bbb_arc;
⑻ 模块 CH见图2.8,该模块为4线—七段译码器。

library ieee;
use ieee.std_logic_1164.all;

entity disp is
port(d:in std_logic_vector(3 downto 0);
q:out std_logic_vector(6 downto 0));
end disp;

architecture disp_arc of disp is
begin
process(d)
begin
case d is
when "0000"=>q<="0111111";
when "0001"=>q<="0000110";
when "0010"=>q<="1011011";
when "0011"=>q<="1001111";
when "0100"=>q<="1100110";
when "0101"=>q<="1101101";
when "0110"=>q<="1111101";
when "0111"=>q<="0100111";
when "1000"=>q<="1111111";
when "1001"=>q<="1101111";
when others=>q<="0000000";
end case;
end process;