大三下学期的实验,没有录制视频,贴出代码,仅供参考:
它具有计时功能。此秒表有两个按键(reset, start)按下reset键后,秒表清零,按下start键后,开始计时, 再次按下start键后, 停止计时, 用FPGA开发板上的两个七段数码管显示时间(以秒为单位),计时由0 到 59 循环。还有一个按键(select),用于轮流切换两个七段数码管分别显示百分之一秒,秒,分钟。
1、按键消抖模块:
library IEEE;
USEIEEE.std_logic_1164.all;
ENTITY key_delayIS
port( clk_key_delay_in:instd_logic;
reset_key_delay_in: in std_logic;
start_key_delay_in: in std_logic;
select_key_delay_in: in std_logic;
start_key_delay_out: out std_logic;
select_key_delay_out:outstd_logic--最后一行不能加分号
);
END key_delay;
architectureb_key_delay of key_delay is
type state is (s0,s1,s2);--状态机类型
type state1 is (s0,s1,s2);--状态机类型
signal current:state;
signal current1:state;
begin
process(reset_key_delay_in,clk_key_delay_in,start_key_delay_in)
begin
if(reset_key_delay_in ='1') then
start_key_delay_out<='0';
current <= s0;
elsif(clk_key_delay_in'eventand clk_key_delay_in='1')then
case current is
when s0 =>
start_key_delay_out<='0';
if(start_key_delay_in='1')then
current<= s1;
else
current<= s0;
endif;
when s1 =>
start_key_delay_out<='0';
if(start_key_delay_in='1')then
current<= s2;
else
current<= s0;
endif;
when s2 =>
--start_key_delay_out<='1';此处输出高电平
if(start_key_delay_in='1')then
current<= s2;
else
start_key_delay_out<='1';--此处输出单脉冲
current<= s0;
endif;
when others=>
current<= s0;
start_key_delay_out<='0';
end case;
end if;
end process;
process(reset_key_delay_in,clk_key_delay_in,select_key_delay_in)
begin
if(reset_key_delay_in ='1') then
select_key_delay_out<='0';
current1 <= s0;
elsif(clk_key_delay_in'event and clk_key_delay_in='1')then
case current1 is
when s0 =>
select_key_delay_out<='0';
if(select_key_delay_in='1')then
current1<= s1;
else
current1<= s0;
endif;
when s1 =>
select_key_delay_out<='0';
if(select_key_delay_in='1')then
current1<= s2;
else
current1<= s0;
end if;
when s2 =>
select_key_delay_out<='1';
if(select_key_delay_in='1')then
current1<= s2;
else
current1<= s0;
endif;
when others=>
current1<= s0;
select_key_delay_out<='0';
end case;
end if;
end process;
end;
2、计时和数据选择模块:
library IEEE;
USEIEEE.std_logic_1164.all;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY count IS
port( clk_count_in :in std_logic;
reset_count_in :in std_logic;
start_count_in :in std_logic; --控制计时的开始
select_seg_in :in std_logic; --控制输出的数据
count1ms_out :out std_logic; --1ms使能时钟输出,用于按键检测
data1_out :out std_logic_vector(3 downto 0); --输出的第1位
data2_out :out std_logic_vector(3 downto 0); --输出的第2位
data3_out :out std_logic_vector(3 downto 0); --输出的第3位
data4_out :out std_logic_vector(3 downto 0) --输出的第4位
);
end count;
architectureb_count of count is
signal count_1ms :std_logic_vector(15 downto 0); --50_000
signal count_10ms :std_logic_vector(4 downto 0); --10
signal count_1s :INTEGER RANGE 99 downto 0 ; --100
signal count_1min :INTEGER RANGE 59 downto 0 ; --60
signal count_1h :INTEGER RANGE 59 downto 0 ; --60
signal count2_1s :std_logic_vector(3 downto 0);
signal count2_1min:std_logic_vector(3downto 0);
signal count2_1h :std_logic_vector(3 downto 0);
signal count3_1s :std_logic_vector(3 downto 0);
signal count3_1min:std_logic_vector(3downto 0);
signal count3_1h :std_logic_vector(3 downto 0);
signal signal_1ms :std_logic;
signal signal_10ms :std_logic;
signal signal_1s :std_logic;
signal signal_1min :std_logic;
signal signal_start :std_logic;
type state is (s0,s1,s2,s3);--状态机类型
signal current:state;
begin
process(start_count_in,reset_count_in)
begin
if(reset_count_in='1')then
signal_start<= '0';
elsif(start_count_in'eventand start_count_in ='0')then--检测到下降沿才开始响应
if signal_start ='0' then
signal_start<='1';
else
signal_start<='0';
end if;
end if;
end process;
process (clk_count_in,reset_count_in)--1ms计时
begin
if(reset_count_in='1')then
count_1ms <= (others =>'0');
signal_1ms <='0';
elsif(clk_count_in'eventand clk_count_in='1')then
if count_1ms =49_999 then
signal_1ms <= '1';
count_1ms <= (others =>'0');
else
signal_1ms <= '0'; --signal_1ms的高电平持续了一个周期的clk_count_in
count_1ms <= count_1ms+1;
end if;
end if;
end process;
count1ms_out <= signal_1ms; --1ms使能输出
process(signal_1ms,reset_count_in)--10ms计时
begin
if(reset_count_in='1')then
count_10ms <= (others =>'0');
signal_10ms <='0';
elsif(signal_1ms'event andsignal_1ms='1')then
if(signal_start= '0')then
if count_10ms= 9 then
signal_10ms <= '1';
count_10ms <= (others =>'0');
else
signal_10ms <= '0'; --signal_10ms的高电平持续了一个周期的signal_1ms,即持续了1ms
count_10ms <= count_10ms+1;
end if;
end if;
end if;
end process;
process(signal_10ms,reset_count_in)--1s计时,990ms
begin
if(reset_count_in='1')then
count_1s <= 0;
count2_1s <="0000";
count3_1s <="0000";
signal_1s <='0';
elsif(signal_10ms'event andsignal_10ms='1')then
if count_1s = 99then
signal_1s<='1';
count_1s <= 0;
else
signal_1s <= '0'; --signal_1s的高电平持续了一个周期的signal_10ms,即持续了10ms
count_1s <= count_1s+1;
end if;
if count2_1s ="1001" then --9
count2_1s<="0000";
if count3_1s= "1001" then --9
count3_1s<="0000";
else
count3_1s<= count3_1s+1;
end if;
else
count2_1s<= count2_1s+1;
end if;
end if;
end process;
process(signal_1s,reset_count_in)--1min计时 59s
begin
if(reset_count_in='1')then
count_1min <= 0;
count2_1min<="0000";
count3_1min<="0000";
signal_1min <='0';
elsif(signal_1s'event andsignal_1s='1')then
if count_1min = 59then
signal_1min <= '1';
count_1min <= 0;
else
signal_1min <= '0'; --signal_1min的高电平持续了一个周期的signal_1s,即持续了1s
count_1min <= count_1min+1;
end if;
if count2_1min ="1001" then --9
count2_1min<="0000";
ifcount3_1min = "0101" then --5
count3_1min<="0000";
else
count3_1min<= count3_1min+1;
end if;
else
count2_1min<= count2_1min+1;
end if;
end if;
end process;
process(signal_1min,reset_count_in)--1h计时
begin
if(reset_count_in='1')then
count_1h <= 0;
count2_1h<="1000";
count3_1h<="0101";
elsif(signal_1min'event andsignal_1min='1')then
if count_1h = 59then
count_1h <= 0;
else
count_1h <= count_1h+1;
end if;
if count2_1h ="1001" then --9
count2_1h<="0000";
if count3_1h= "0101" then --5
count3_1h<="0000";
else
count3_1h<= count3_1h+1;
end if;
else
count2_1h <= count2_1h+1;
end if;
end if;
end process;
process (select_seg_in)
begin
if(select_seg_in'event andselect_seg_in='0')then
case current is
when s0 =>
current<= s1;
when s1 =>
current<= s2;
when s2 =>
current<= s3;
when s3 =>
current<= s0;
when others=>
current<= s0;
end case;
end if;
end process;
process(clk_count_in,reset_count_in)--1min计时
begin
if(reset_count_in='1')then--按键按下为高电平
data1_out <="1111";
data2_out <="1111";
data3_out <="1111";
data4_out <="1111";
elsif(clk_count_in'eventand clk_count_in='1')then
case current is
when s0 =>--此状态4个数码管都显示,显示秒和分
data1_out<=count2_1min; --0~9
data2_out<=count3_1min; --0~5
data3_out<=count2_1h; --0~9
data4_out<=count3_1h; --0~5
when s1=>--此状态2个数码管都显示,显示百分毫秒
data1_out<=count2_1s; --0~9
data2_out<=count3_1s; --0~9
data3_out<="1111";
data4_out<="1111";
when s2 => --此状态2个数码管都显示,显示秒
data1_out<=count2_1min; --0~9
data2_out<=count3_1min; --0~5
data3_out<="1111";
data4_out<="1111";
when s3 =>--此状态2个数码管都显示,显示分
data1_out<=count2_1h; --0~9
data2_out<=count3_1h; --0~5
data3_out<="1111";
data4_out<="1111";
when others=> --全灭
data1_out<="1111";
data2_out<="1111";
data3_out<="1111";
data4_out<="1111";
end case;
end if;
end process;
end;
3、数码管驱动模块:
library IEEE;
USEIEEE.std_logic_1164.all;
USEieee.std_logic_signed.all;
ENTITY seg IS
port( clk_seg_in :in std_logic;
reset_seg_in :in std_logic;
data1_in :in std_logic_vector(3 downto0);
data2_in :in std_logic_vector(3 downto0);
data3_in :in std_logic_vector(3 downto0);
data4_in :in std_logic_vector(3 downto0);
wei :out std_logic_vector(3downto 0); --位选
duan :outstd_logic_vector(7 downto 0) --段选
);
end seg;
architectureb_seg of seg is
signal CNT4:std_logic_vector(1 downto 0);
begin
process(clk_seg_in,reset_seg_in)--扫描显示进程
begin
if(reset_seg_in='1')then --按键按下为高电平
CNT4 <= (others =>'0');
elsif(clk_seg_in'event andclk_seg_in='1')then
if CNT4 ="11" THEN
CNT4 <="00";
else
CNT4 <=CNT4 + 1;
end if;
end if;
end process;
process(CNT4,reset_seg_in)
variable data:std_logic_vector(3downto 0);
begin
if(reset_seg_in='1')then --按键按下为高电平
wei <= (others =>'1');
data := (others =>'1');
else
case CNT4 is
when"00" => data := data1_in; wei <= "1110";
when"01" => data := data2_in; wei <= "1101";
when"10" => data := data3_in; wei <= "1011";
when"11" => data := data4_in; wei <= "0111";
when others=> wei <= "1111";
end case;
end if;
case data is
when"0000" => duan <= "00000011"; --0
when"0001" => duan <= "10011111"; --1
when"0010" => duan <= "00100101"; --2
when"0011" => duan <= "00001101"; --3
when"0100" => duan <= "10011001"; --4
when"0101" => duan <= "01001001"; --5
when"0110" => duan <= "01000001"; --6
when"0111" => duan <= "00011111"; --7
when"1000" => duan <= "00000001"; --8
when"1001" => duan <= "00001001"; --9
WHEN OTHERS =>duan <= "11111111"; --熄灭
end case;
end process;
end;
5、顶层模块:
library IEEE;
USEIEEE.std_logic_1164.all;
ENTITYMiaoBiao_top IS
PORT ( clk :instd_logic;
reset :in std_logic;
start :in std_logic;
selectt :in std_logic;
seg_wei :out std_logic_vector(3 downto 0);
seg_duan :out std_logic_vector(7 downto 0)
);
ENDMiaoBiao_top;
architecture aof MiaoBiao_top is
component key_delay --声明消抖模块
port( clk_key_delay_in :instd_logic;
reset_key_delay_in :in std_logic;
start_key_delay_in :in std_logic;
select_key_delay_in :in std_logic;
start_key_delay_out :out std_logic;
select_key_delay_out :out std_logic--最后一行不能加分号
);
end component;
component count --计数器
port( clk_count_in :in std_logic;
reset_count_in :in std_logic;
start_count_in :in std_logic; --控制计时的开始
select_seg_in :in std_logic; --控制输出的数据
count1ms_out :out std_logic; --1ms使能时钟输出,用于按键检测,和数码管动态扫描
data1_out :out std_logic_vector(3 downto 0); --输出的第1位
data2_out :out std_logic_vector(3 downto 0); --输出的第2位
data3_out :out std_logic_vector(3 downto 0); --输出的第3位
data4_out :out std_logic_vector(3 downto 0) --输出的第4位
);
end component;
component seg --数码管显示
port( clk_seg_in :in std_logic;
reset_seg_in :in std_logic;
data1_in :in std_logic_vector(3 downto 0);
data2_in :in std_logic_vector(3 downto0);
data3_in :in std_logic_vector(3 downto0);
data4_in :in std_logic_vector(3 downto0);
wei: out std_logic_vector(3downto 0); --位选
duan: outstd_logic_vector(7 downto 0) --段选
);
end component;
signal start_signal :std_logic;
signal select_signal :std_logic;
signal count1ms_signal :std_logic;
signal data1_signal :std_logic_vector(3 downto 0);
signal data2_signal :std_logic_vector(3 downto 0);
signal data3_signal :std_logic_vector(3 downto 0);
signal data4_signal :std_logic_vector(3 downto 0);
begin
u1:key_delay port map ( count1ms_signal,
reset,
start,
selectt,
start_signal,
select_signal
);
u2:count port map ( clk,
reset,
start_signal,
select_signal,
count1ms_signal,
data1_signal,
data2_signal,
data3_signal,
data4_signal
);
u3:seg port map ( count1ms_signal,
reset,
data1_signal,
data2_signal,
data3_signal,
data4_signal,
seg_wei,
seg_duan
);
end;
FPGA开发板截图:
(1)初始状态
(2)百分之一秒:
(3)秒:
(4)分钟:
上图显示的时间为58:00:41
58分00秒41百分之一秒。