广州大学松田学院2009届本科生毕业设计
输入信号在锁存时钟信号上升沿时进行锁存。
锁存模块程序: library ieee;
use ieee.std_logic_1164.all; entity lock5 is --锁存模块 port(lock:in std_logic;
d6,d5,d4,d3,d2,d1,d0:in std_logic_vector(3 downto 0); --锁存输入信号 q6,q5,q4,q3,q2,q1,q0:out std_logic_vector(3 downto 0)); --锁存输出信号end lock5;
architecture a of lock5 is begin process(lock)
variable t6,t5,t4,t3,t2,t1,t0:std_logic_vector(3 downto 0); --锁存信号内部变量 begin
if lock'event and lock='1' then --在基准时钟上升沿进行锁存 t6:=d6; t5:=d5; t4:=d4; t3:=d3; t2:=d2; t1:=d1; t0:=d0;
end if; --否则,当锁存信号lock为0时,锁存输出信号 q6<=t6; q5<=t5; q4<=t4; q3<=t3; q2<=t2; q1<=t1;
12
广州大学松田学院2009届本科生毕业设计
q0<=t0; end process; end a;
4.3显示模块功能及程序
CPLD的引脚资源总是有限的。因此对于多个数码管显示,可以采用扫描方式来实现动态显示。实现方法是将频率计的4个数码管并联起来,用片选信号依次点亮,进行循环显示,即一个数码管显示之后另一个数码管马上显示,利用人眼的暂留特性,可以看到多个数码管同时显示的效果。程序所生成的显示模块框图如图4-3所示:
图4-3 显示模块框图
由图4-3可以看出,xuan[3..0]是动态扫描模块的位选端,dout[6..0],dot是输出端。此处只用到四个数码管进行动态扫描。
显示模块程序: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity saomiao is port(clk2:in std_logic;
q4,q3,q2,q1,dian:in std_logic_vector(3 downto 0);--高四位和小数点输入 xuan:out std_logic_vector(3 downto 0); --模四计数器 Dout:out std_logic_vector(6 downto 0); --7段译码输出
13
广州大学松田学院2009届本科生毕业设计
dot:out std_logic); --小数点输出 end saomiao;
architecture behav of saomiao is
Signal xuan2:std_logic_vector(2 downto 0); Signal Dout0:std_logic_vector(3 downto 0); begin
p1:process(clk2,xuan2) --模四计数器,数码管选位信号 begin
if clk2'event and clk2='1' then If xuan2>=\ xuan2<=\ else xuan2<=xuan2+1; end if; end if; End process p1;
p2:process(xuan2,q4,q3,q2,q1,dian,clk2) begin
If clk2'event and clk2='1' then Case xuan2 is
when \ --选择数码管1时,放q1和小数点进去
when \--选择数码管2时,放q2和小数点进去
when \--选择数码管3时,放q3和小数点进去
when \--选择数码管4时,放q4和小数点进去
when others =>dout0<=\ --当其他情况时,放1111和小数点0进去 End case; End if;
14
广州大学松田学院2009届本科生毕业设计
End process p2; P3:process (dout0) begin case dout0 is
when\--当信号dout0为0000时译码输出1000000到dout when\--当信号dout0为0001时译码输出1111001到dout when\--当信号dout0为0010时译码输出0100100到dout when\--当信号dout0为0011时译码输出0110000到dout when\--当信号dout0为0100时译码输出0011001到dout when\--当信号dout0为0101时译码输出0010010到dout when\--当信号dout0为0110时译码输出0000010到dout when\--当信号dout0为0111时译码输出1111000到dout when\--当信号dout0为1000时译码输出0000000到dout when\--当信号dout0为1001时译码输出0010000到dout when others =>dout<=\--当信号dout0为其他情况时译码输出1111111到dout end case; end process p3; End architecture behav ;
4.4分频模块功能及程序
从晶振时钟50MHz分出系统所需的几个时基信号。以下clk1是对输入时钟信号进行2分频,即每计到24999999个上升沿,输出信号翻转一次。clk2是对输入时钟信号进行10000分频,即每计到499个上升沿,输出信号翻转一次。根据系统需要,可以修改分频系数得到所需频率。clk1是作为系统基准时钟,clk2是作为显示扫描信号。程序所生成的分频模块框图如图4-4所示。
图4-4 分频模块框图
15
广州大学松田学院2009届本科生毕业设计
分频模块程序: library ieee;
use ieee.std_logic_1164.all; entity fdiv is
port(clk0:in std_logic; --输入系统时钟 clk1:out std_logic; --输出1hz时钟信号 clk2:out std_logic); --输出显示扫描时钟信号 end fdiv; architecture a of fdiv is begin p1:process(clk0)
variable cnt:integer range 0 to 24999999; --分频系数为24999999 variable ff:std_logic; begin
if clk0'event and clk0='1' then if cnt<24999999 then cnt:=cnt+1; else cnt:=0;
ff:=not ff; --反向 end if; end if; clk1<=ff; end process p1; p2:process(clk0)
variable cnn:integer range 0 to 499; --分频系数为499 variable dd:std_logic; begin
if clk0'event and clk0='1' then if cnn<499 then
16