摘要: 文中介绍了一种基于FPGA的数字秒表设计方法。采用VHDL硬件描述语言, 运用ModelSim等EDA仿真工具。该设计具有外围电路少、集成度高、可靠性强等优点。最后经实验验证, 该数字秒表计时准确, 输入信号能准确控制秒表运行。系统所采用的自上而下的模块化设计方法, 对于其他复杂的系统设计也有很强的借鉴意义。
数字集成电路作为当今信息时代的基石, 不仅在信息处理、工业控制等生产领域得到普及应用, 并且在人们的日常生活中也是随处可见, 极大的改变了人们的生活方式。面对如此巨大的市场, 要求数字集成电路的设计周期尽可能短、实验成本尽可能低, 最好能在实验室直接验证设计的准确性和可行性, 因而出现了现场可编程逻辑门阵列FPGA。对于芯片设计而言, FPGA的易用性不仅使得设计更加简单、快捷, 并且节省了反复流片验证的巨额成本。对于某些小批量应用的场合, 甚至可以直接利用FPGA实现, 无需再去订制专门的数字芯片。
文中着重介绍了一种基于FPGA利用VHDL硬件描述语言的数字秒表设计方法, 在设计过程中使用基于VHDL的EDA工具ModelSim对各个模块仿真验证, 并给出了完整的源程序和仿真结果。
1 总体功能结构设计
一个完整的数字秒表应具有计时、相应的控制以及计时结果显示功能, 总体的功能结构如图1所示。黑色线框内是计数模块、使能转化模块和显示译码模块, 左边是输入控制信号, 右边是显
示计时结果的数码显示管, 用六位BCD七段数码管显示读数, 显示格式如图2, 计时范围为: 1小时,精度为0.01s。
输入时钟信号由32MHz的石英晶振提供, 考虑到设计指标要求秒表精度为0.01秒, 计数脉冲的时
钟输入就应该是频率为100Hz的脉冲, 所以先要设计一个320000分频器, 分频器的输出可作计数器的输入; 其次计数模块设计应综合考虑秒表的计时范围(1小时) 和显示输出(6位输出), 6位输出中有两位是六进制输出, 其余四位是十进制输出,所以可通过设计4个模10计数器和2个模6计数器来实现, 其中较低位的进位输出就是高位的计数输入端。
控制模块应包括开始计时/停止计时、复位两个按钮, 即电路设计经常用到的使能端和清零端,这两个控制端口直接接到计数器的清零和史能端即可实现复位、开始计时/停止计时; 但是外围使能输入需要经过使能转换电路后, 才可变为计数器可用的使能控制信号。因此在输入使能信号和计数器使能输入之间需设计一个信号转换模块。
显示计数结果的模块实现较为简单, 只需将六位计数结果通过七段译码电路接到输出即可点亮数码管, 无需时序控制, 直接用组合逻辑电路就可以实现。数码管显示可以采用扫描显示, 用一个频率1KHz的信号扫描一个多路选择器, 实现对六位已经锁存的计数结果的扫描输出。
2 各功能模块设计
2.1 分频器模块
分频器的功能是提供标准时钟控制信号以精确控制计数器的开闭, 提供的标准信号是32MHz,根据设计精度0.01s的要求, 输出信号是100Hz, 所以该分频器实现的功能是320000 分频, 具体的
VHDL源程序:
process (clk)
begin
if (clk'event and clk='1') then
if (q=159999) then
q<=0;
count_temp<=not count_temp;
else
q<=q+1;
end if;
end if;
end process;
2.2 计数模块
该计数器要实现最大计数值为59分59秒99的计数, 而且为了数码管显示方便, 该模块必须通过计数器的级联来实现, 即首先分别设计一个模6计数器和一个模10计数器, 然后将他们级联, 其中调用4次模10计数器、2次模6计数器, 这样可以比直接设计模100 的计数器和模60的计数器节省资源。级联时低位的计数进位输出接高位的计数输入端, 如图3所示。再考虑到控制模块的要求, 每个计数器有三个输入端: 时钟、使能和清零, 两个输出端: 计数输出和进位输出, 采用同步使能异步清零的设计方法, 每个计数器的使能和清零端都与外围的使能和清零端相联。
该模块的源程序以及ModelSim仿真输出结果如下:
模6计数器的VHDL源程序如下:
process (clear,clk)
begin
if (clear='1') then
tmp<=" 0000" ;
carryout<='0';
elsif (clk'event and clk='1') then
if (rst='0') then
if (tmp=" 0101") then
carryout<='1';
tmp<=" 0000" ;
else
tmp<=tmp+1;
carryout<='0';
end if;
end if;
end if;
模10计数器的VHDL源程序与模6计数器类似,为节省篇幅, 不再给出。
2.3 使能信号转换模块
数字秒表输入的开始和停止信号是单个脉冲信号, 而计数器要持续计数所需的使能信号是持续的高电平, 所以需要通过使能控制电路实现使能信号的转换。该模块的VHDL源程序以及Model-Sim仿真输出结果如下:
该模块源程序:
process (enablein)
begin
if (enablein'event and enablein='1') then
temp<= not temp;
end if ;
end process;
2.4 译码显示模块
由上面的设计可知, 计数器输出为二进制码,不能直接点亮数码管, 要想将计数结果通过数码管显示必须再设计一个七段译码电路, 以便将计数结果输出。通过分析可知该译码器是一个4输入, 7输出元件, 其真值表如表1所示:
根据以上真值表可写出译码电路VHDL源程序如下:
process (datainput)
begin
case datainput is
when " 0000" =>dataoutput<=" 0000010" ;
when " 0001" =>dataoutput<=" 1001111" ;
when " 0010" =>dataoutput<=" 0010001" ;
when " 0011" =>dataoutput<=" 0000101" ;
when " 0100" =>dataoutput<=" 1001100" ;
when " 0101" =>dataoutput<=" 0100100" ;
when " 0110" =>dataoutput<=" 0100000" ;
when " 0111" =>dataoutput<=" 0001111" ;
when " 1000" =>dataoutput<=" 0000000" ;
when " 1001" =>dataoutput<=" 0000100" ;
when others=>dataoutput<=" 1111111" ;
end case;
end process;
3 功能验证以及下载实现
完成以上各个子模块的设计后, 该数字秒表的模块设计就基本完成了, 剩下的工作就是通过一个顶层文件将各个子模块连接起来。在顶层文件中可以将以上各个子模块看作一个个黑匣子,只将其输入输出端对应相连就可以了。下面是该顶层文件的VHDL源程序:
architecture Behavioral of topfile is
signal clk:std_logic:='0';
signal enableout:std_logic:='0';
signal data0,data1,data2,
data3,data4,data5:std_logic_vector (3
downto 0) :=" 0000" ;
component abc
port (clk:in std_logic;
dout:out std_logic) ;
end component;
component enable
port (enablein:in std_logic;
enableout:out std_logic) ;
end component;
component highlevel
port (rst,clk,clear:in std_logic;
output1,output2,output3,
output4,output5,output6:out
std_logic_vector (3 downto 0) ;
carryout:out std_logic) ;
end component;
component yima
port (datainput:in std_logic_vector (3 downto 0) ;
dataoutput: out std_logic_vector (6 downto 0)) ;
end component;
begin
u0:abc port map (clkin,clk) ;
u1:enable port map (enablein,enableout) ;
u2:highlevel port map ( enableout,clk,clear,data0,data1,
data2,data3,data4,data5) ;
u3:yima port map (data0,dataout0) ;
u4:yima port map (data1,dataout1) ;
u5:yima port map (data2,dataout2) ;
u6:yima port map (data3,dataout3) ;
u7:yima port map (data4,dataout4) ;
u8:yima port map (data5,dataout5) ;
end Behavioral;
由于各个子模块都已经经过验证无误, 并且顶层文件中不涉及复杂的时序关系, 相当于只是将各个模块用导线连接起来, 只要各个端口的连接对应正确即可, 所以不需写专门的test bench进行验证。完成以上设计后, 即可进行逻辑综合,综合无误后进行管脚适配, 生成.bit文件然后下载到实验板上测试。经过反复多次测试, 以上设计完全满足了预期的设计指标, 开始/停止按键和清零按键都能准确的控制秒表的运行, 七段显示数码管也能够准确的显示计时结果。通过与标准秒表对比, 该设计的计时误差在0.03s以内, 而这其中也包括实验板上晶振由于长期使用所带来的误差。
4 结束语
本文所介绍数字秒表设计方法, 采用了当下最流行的EDA设计手段。在Xinlinx FPGA开发环境下, 采用至上而下的模块化设计方法, 使得系统开发速度快、成本低、系统性能大幅度提升。通过实验验证, 本文设计的数字秒表计时准确、性能稳定, 可以很容易嵌入其他复杂的数字系统,充当计时模块。
利用EDA设计工具, 结合基于FPGA的可编程实验板, 轻松实现电子芯片的设计, 现场观察实验结果, 大大缩短了产品的设计周期和调试周期,提高了设计的可靠性和成功率, 体现了逻辑器件在数字设计中优越性。
评论
查看更多