概述
本设计基于超高速硬件描述语言VHDL在Altera公司的实验箱主控板上编程实现,主要由状态机完成对彩灯的控制,并有分频模块分别控制彩灯的循环及数码管的扫描计时,完成彩灯的自动循环、手动控制、清零、及定时功能。
设计任务
1.基本功能:
- 由两位以上输入控制端控制节日彩灯输出花样。
- 输出对应8位彩灯,用LED发光二极管代替。
- 花样可以是:循环左移、循环右移、从中间向两边、从两边往中间等。
- 一位复位信号对流水彩灯进行清零控制。
2.扩展功能:
- 增加手动/自动控制端,手动控制时,由输入控制端控制输出彩灯花样,自动时,按预设花样循环输出。
- 时控功能:在设定时间段自动亮,其他时间自动灭。
- 一位复位信号对计数器进行清零控制。
设计方案
模块设计
1.分频模块
输入1kHz,用于数码管的扫描,又将它分频为1Hz和5Hz两部分,1Hz的用于数码管秒的计时,5Hz的用于彩灯的循环。其中clk_s是1kHz的输入时钟,clk_l是分频为5Hz的输出时钟,clk_c是分频为1Hz的输出时钟。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity fdiv is
port(
clk_s:in std_logic;
clk_l,clk_c:out std_logic
);
end fdiv;
architecture tmp of fdiv is
signal cnt1:integer range 0 to 100;
signal cnt2:integer range 0 to 500;
signal ct,st:std_logic;
begin
clk_l<=st;clk_c<=ct;
process(clk_s)
begin
if clk_s'event and clk_s='1' then
if cnt1<99 then cnt1<=cnt1+1;
else cnt1<=0;st<=not st;
end if;
if cnt2<499 then cnt2<=cnt2+1;
else cnt2<=0;ct<=not ct;
end if;
end if;
end process;
end;
2.计数模块
计数器不仅可以用来进行数字计数,用于数码管计时,还可以用来控制有限状态机的转换,进行彩灯的循环花样显示,本设计中单独的计数小模块用于数码管计时三分钟,秒的部分为60进制,分钟部分从0到2,总共计时三分钟,这部分可以修改,只是为了减少拍视屏时间及验证时间,将时间定时为三分钟。其中clk是输入1Hz的分频时钟,ret是计数器清零复位端,cnt1,cnt2,cnt3,cnt4是计数器输出的时间,cnt1:0至9,cnt2:0至5,60秒计数,cnt3使它永远保持为10,在数码管中固定显示为“-”,用于将分钟与秒分隔开,cnt4:0至2,分钟计数。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity count is
port(
clk:in std_logic;
cnt1,cnt2,cnt3,cnt4:out std_logic_vector(3 downto 0)
);
end count;
architecture tmp of count is
signal temp1,temp2,temp3,temp4:std_logic_vector(3 downto 0);
signal c,c1:std_logic;
begin
cnt1<=temp1;cnt2<=temp2;cnt3<=temp3;cnt4<=temp4;
process(clk)
begin
if clk'event and clk='1' then
temp3<="1010";
if temp1<"1001" then
temp1<=temp1+1;c<='0';
else
temp1<="0000";c<='1';
end if;
end if;
end process;
process(c)
begin
if c'event and c='1' then
if temp2<"0101" then
temp2<=temp2+1;c1<='0';
else
temp2<="0000";c1<='1';
end if;
end if;
end process;
process(c1)
begin
if c1'event and c1='1' then
if temp4<"0010" then
temp4<=temp4+1;
else
temp4<="0000";
end if;
end if;
end process;
end;
3.数码管显示模块
用数码管显示时钟并定时控制彩灯的亮灭,可以分为译码部分和扫描部分,译码模块是实现4位二进制计数结果与对应数码管各段编码的转换;扫描子模块则通过扫描信号依次选中数码管,并决定该数码管显示的数字。其中clk_s是1kHz的输入时钟,data1,data2,data3,data4是从计数器输出的二进制时间,dig是数码管的位选端,seg是数码管的段选端。
process(clk_s)
begin
if clk_s'event and clk_s='1' then
cnt<=cnt+1;
end if;
end process;
process(cnt)
begin
case cnt is
when "00"=>dig<="000"</