一、【设计目的】
学习并掌握Quartus II 开发系统的基本操作。
掌握用Quartus II进行文本输入法进行电路设计、编译和仿真方法。
掌握CPLD/FPGA的开发流程。
掌握EDA实验开发系统的使用。
掌握状态机的原理。
掌握简单状态机的VHDL设计方法
掌握计数器的设计方法。
掌握带有复位和和时钟使能的10进制计数器的原理。
掌握通用计数器的设计方法。
学习使用VHDL进行时序逻辑电路的设计。
学习利用真值表编写VHDL程序。
学习掌握7段数码显示译码器设计的原理。
掌握VHDL语言方式设计7段数码显示译码器。
学习掌握8位数码管动态扫描显示电路的原理。
掌握VHDL语言设计8位数码管动态扫描显示电路
学习VHDL语言设计较复杂的电路方法。
二、【设计任务】
设计要求
用VHDL语言设计一个状态机,要求具有以下状态和功能中的四种或者四种以上:
A.复位功能
B.8、10或者16进制加法计数
C.8、10或者16进制减法计数
D.数码管以任何方式闪动
E.8个LED灯以任何方式闪动
F.蜂鸣器发声或者播放一段音乐
G.并用两位数码管将结果显示出来
本次设计选用的功能状态为:
A.复位功能
B.十进制加法计数
C.十进制减法计数
D.数码管闪动
E.8个led灯闪动
F.并用两位数码管将结果显示出来
功能实现说明
Clk为50MHz的时钟信号输入;rst为复位控制按键(低电平有效);en(0-2)通过三个按键分别控制3种状态(低电平有效)。
1.当en(0)=`0`时,启动加法计数并将结果动态显示到两位数码管上,同时另外的两位数码管的6段以相反方向按顺序闪烁
2.当en(1)=`0`时,启动减法计数并将结果动态显示到两位数码管上,同时另外的两位数码管的6段以相反方向按顺序闪烁,闪烁方向与加法的相反;
3.当en(2)=`0`时,启动LED闪烁功能,LED灯按顺序逐个流水闪动;
4.当rst=`0`时,复位清零;
三、【设计代码】
library IEEE;
use IEEE.STD_LOGIC_11.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-----------------------------------------------------------------------------
ENTITY cnt16 IS
PORT (
clk : IN std_logic; --50MHz时钟信号输入
rst : IN std_logic; ---复位功能输入
en : IN std_logic_vector(2 DOWNTO 0); ---状态选择输入
led8 : OUT std_logic_vector(7 DOWNTO 0); --各段数据输出
com8 : OUT std_logic_vector(7 DOWNTO 0)); ---各位数据输出
END cnt16;
-----------------------*****对各个信号进行定义****-------------------------------------
ARCHITECTURE arch OF cnt16 IS
signal cnt : std_logic_vector(25 downto 0 );
signal data : std_logic_vector(3 downto 0);
signal led8_xhdl : std_logic_vector(7 downto 0);
signal com8_xhdl : std_logic_vector(7 downto 0);
signal coud1 : std_logic_vector(3 downto 0);
signal coud2 : std_logic_vector(3 downto 0);
signal s1 : std_logic;
signal s2 : std_logic;
signal s3 : std_logic;
signal coud : std_logic_vector(3 downto 0);
signal first : std_logic_vector(3 downto 0); --0000
signal second : std_logic_vector(3 downto 0); --0000 0000 0000 1001
signal jinwei: std_logic;
-------------------------------------------------------------------------------------------------------------
begin
led8<=led8_xhdl;
com8<=com8_xhdl;
----------------------- *****状态控制部分*************---------------------------------------------
process(en)
begin
if en="110"then ----状态控制,低电平有效
s1<='1';
s2<='0';
s3<='0';
else if en="101"then
s2<='1';
s1<='0';
s3<='0';
else if en="011"then
s3<='1';
s1<='0';
s2<='0';
end if;
end if;
end if;
end process;
-----------------------------------------------------------------------------------------------------
--------------------------**********时钟分频部分********----------------------------------
process(clk,rst)
begin
if(rst='0')then
cnt<="00000000000000000000000000";
elsif(clk'event and clk='1')then
cnt<=cnt+1; -----来一个时钟信号cnt加1
end if;
end process;
----------------------------------------------------------------------------
------------------------------------------*****-加减计数器的个位-*******-------------------------------
process(cnt(24),rst,s1,s2)
begin
if(rst='0')then
first<="0000";
jinwei<='0';
elsif(cnt(24)'event and cnt(24)='1')then ---每隔(1/50)*48=0.96s计数一次
if (s1='1')then
if(first="1001")then ---10进制计数
first<="0000";
jinwei<='1';
else
jinwei<='0';
first<=first+1; ---加法计数
end if;
else if(s2='1')then
if(first="0000")then
first<="1001";
jinwei<='1';
else
jinwei<='0';
first<=first-1; ---减法计数
end if;
end if;
end if;
end if;
end process;
-------------------------------------------------------------------------------
------------------------------------*********-加减计数器的十位*******--------------------------
process(jinwei,rst,s1,s2)
begin
if(rst='0')then
second<="0000";
elsif(jinwei'event and jinwei='1')then ---每来1个位产生的进位信号则十位加(减)1
if (s1='1')then
if(second="1001")then
second<="0000";
else
second<=second+1;
end if;
else if(s2='1')then
if(second="0000")then
second<="1001";
else
second<=second-1;
end if;
end if;
end if;
end if;
end process;
-----------------------------------------------------------------------------------------------------
-------------------------------------------*****闪动数码管的计数***---------------------------------------
process(cnt(23),rst,s1,s2)
begin
if(rst='0')then
coud<="0000";
else if(cnt(23)'event and cnt(23)='1')then ----每隔(1/50)*46=0.92s计数一次
if(s1='1')then
if(coud="0101")then
coud<="0000";
else
coud<=coud+1;
end if;
else if(s2='1')then
if(coud="0000")then
coud<="0101";
else
coud<=coud-1;
end if;
end if;
end if;
end if;
end if;
end process;
---------------------------------------------------------------------------------------
-----------------------------------***码变换****---------------------------------------------
process(coud,rst)
begin
case coud is
when"0000" => coud1<="1010";coud2<="1010";
when"0001" => coud1<="1011";coud2<="1111";
when"0010" => coud1<="1100";coud2<="1110";
when"0011" => coud1<="1101";coud2<="1101";
when"0100" => coud1<="1110";coud2<="1100";
when"0101" => coud1<="1111";coud2<="1011";
when others => coud1<="0000";coud2<="0000";
end case;
end process;
-----------------------------------------------------------------------------------------
---****************显示部分***************--
process(rst,s1,s2,s3,cnt(17 downto 16),cnt(25 downto 23))
begin
if(rst='0')then
com8_xhdl<="11110000";
led8_xhdl <= "00000000";
else if s1='1'or s2='1'then ----计数以及数码管闪动部分的扫描
case cnt(17 downto 16) is
when"10" => com8_xhdl<="11111110";data<=first;
when"01" => com8_xhdl<="11111101";data<=second;
when"00" => com8_xhdl<="01111111";data<=coud1;
when"11" => com8_xhdl<="10111111";data<=coud2;
end case;
case data is
WHEN "0000" =>led8_xhdl <= "00111111"; --0
WHEN "0001" =>led8_xhdl <= "00000110"; --1
WHEN "0010" =>led8_xhdl <= "01011011"; --2
WHEN "0011" =>led8_xhdl <= "01001111"; --3
WHEN "0100" =>led8_xhdl <= "01100110"; --4
WHEN "0101" =>led8_xhdl <= "01101101"; --5
WHEN "0110" =>led8_xhdl <= "01111101"; --6
WHEN "0111" =>led8_xhdl <= "00000111"; --7
WHEN "1000" =>led8_xhdl <= "01111111"; --8
WHEN "1001" =>led8_xhdl <= "01101111"; --9
WHEN "1010" =>led8_xhdl <= "00000001";
WHEN "1011" =>led8_xhdl <= "00000010";
WHEN "1100" =>led8_xhdl <= "00000100";
WHEN "1101" =>led8_xhdl <= "00001000";
WHEN "1110" =>led8_xhdl <= "00010000";
WHEN "1111" =>led8_xhdl <= "00100000";
WHEN OTHERS =>led8_xhdl <= "00000011";
END CASE;
else if s3='1'then ----8个LED灯闪动的扫描,闪动周期为0.92s-1s
case cnt(25 downto 23) is
when"000" => com8_xhdl<="11111110";led8_xhdl<="10000000" ;
when"001" => com8_xhdl<="11111101";led8_xhdl<="10000000" ;
when"010" => com8_xhdl<="11111011";led8_xhdl<="10000000" ;
when"011" => com8_xhdl<="11110111";led8_xhdl<="10000000" ;
when"100" => com8_xhdl<="11101111";led8_xhdl<="10000000" ;
when"101" => com8_xhdl<="11011111";led8_xhdl<="10000000" ;
when"110" => com8_xhdl<="10111111";led8_xhdl<="10000000" ;
when"111" => com8_xhdl<="01111111";led8_xhdl<="10000000" ;
end case;
end if;
end if;
end if;
end process;
end arch;下载本文