《EDA技术》课程设计报告
简述
随着数字电子技术的发展,频率测量成为一项越来越普遍的工作,因此测频计常受到人们的青睐。目前许多高精度的数字频率计都采用单片机加上外部的高速计数器来实现,然而单片机的时钟频率不高导致测频速度比较慢,并且在这种设计中,由于PCB版的集成度不高,导致PCB板走线长,因此难以提高计数器的工作频率。为了克服这种缺点,大大提高测量精度和速度,我们可以设计一种可编程逻辑器件来实现数字频率计。
EDA技术是以大规模可编程逻辑器件为设计载体,以硬件语言为系统逻辑描述的主要方式,以计算机、大规模可编程逻辑器件的开发软件及实验开发系统为设计工具,通过有关的开发软件,自动完成用软件设计的电子系统到硬件系统的设计,最终形成集成电子系统或专用集成芯片的一门新技术。其设计的灵活性使得EDA技术得以快速发展和广泛应用。以QUARTUSII软件为设计平台,采用VHDL语言实现数字频率计的整体设计。
EDA技术已经广泛应用于模拟与数字电路系统等许多领域。电子设计自动化是一种实现电子系统或电子产品自动化设计的技术,它与电子技术,微电子技术的发展密切相关,它吸收了计算机科学领域的大多数最新研究成果,以高性能的计算机作为工作平台,促进了工程发展。EDA的一个重要特征就是使用硬件描述语言(HDL)来完成的设计文件,VHDL语言是经IEEE确认的标准硬件语言,在电子设计领域受到了广泛的接受。
1. 设计概述
1.1设计原理
在电子技术中,频率是最基本的参数之一,并且与许多电参量的测量方案、测量结果都有十分密切的关系,因此,频率的测量就显得更为重要。测量频率的方法有多种,其中电子计数器测量频率具有精度高、使用方便、测量迅速,以及便于实现测量过程自动化等优点,是频率测量的重要手段之一。
数字式频率计的测量原理有两类:一是直接测频法,即在一定闸门时间内测量被测信号的脉冲个数;二是间接测频法即测周期法,如周期测频法。直接测频法适用于高频信号的频率测量,通常采用计数器、数据锁存器及控制电路实现,并通过改变计数器阀门的时间长短在达到不同的测量精度;间接测频法适用于低频信号的频率测量。
本设计中使用的就是直接测频法,即用计数器在计算1s内输入信号周期的个数,其测频范围为1Hz~9999Hz。
1.2原理框图
1.3 系统原理图
系统原理图仿真
分析说明:clk为1HZ,待测信号sig为10HZ
1.5 引脚图
2. 设计思路
频率测量的基本原理是计算每秒钟内待测信号的脉冲个数。这就要求测频控制信号发生器testpl的计数使能信号tsten能产生一个1秒脉宽的周期信号,并对频率计的每一计数器cnt10的使能端en进行同步控制。当tsten为高电平"1"时,允许计数;为低电平"0"时停止计数,并保持其计数结果。在停止计数期间,首先需要一个锁存信号load的上跳沿将计数器在前1 秒种的计数值锁存进16位锁存器reg16b中。锁存信号之后,必须有一个清零信号clr_cnt对计数器进行清零,为下1 秒的计数操作做准备。,然后由外部数码管控制器ledcom控制的7段译码器ymq译出,并稳定显示。
3.模块划分
3.1 测频控制信号发生器testpl模块:
输入端clk收到1Hz信号后,其输出端testen控制各个cnt10的使能,clr_cnt控制各个cnt10的清零,load控制锁存器内数据的输出。
仿真图如下:
3.2 十进制计数器cnt10模块:
有一时钟使能输入端en,用于锁定计数值。当高电平"1"时计数允许计数,低电平"0"时禁止计数。多位十进制计数器时,最低位的计数器的clk端输入被测信号,各计数器的进位输出端c10将信号输到下一位十进制计数器cnt10的输入端clk,最高位十进制计数器cnt10的进位输出端c10不处理。
仿真图如下:
3.3 16位锁存器reg16b模块:将已有16 位bcd码存在于此模块的输入口din[15..0],在信号load的上升沿后即被锁存到寄存器reg16b的内部,并由reg16b的输出端dout[15..0]输出,设置锁存器的好处是,数码管上显示的数据稳定,不会由于周期性的清零信号而不断闪烁。。
仿真图如下:
3.4 数码管控制器ledcom模块:两个输入端一个为datain[15..0],另一个为数码管显示选择的扫描频率输入端clk,输出端为数码管选择信号com[3..0]和对应显示的数码管的BCD码信号端dataout[3..0],数码管显示选择随扫描频率clk循环变化,实现稳定显示。
仿真图如下:
3.5 译码器ymq模块:输入端d_in[3..0]将接收BCD码信号,译码后输出端d_out[7..0]输出8为7段数码管信号,其中输出的第8位均为高电平"1"可以使四个数码管的小数点不显示。经译码器的处理输出后数码管显示相应的数值。
4.VHDL顶层文件:
library ieee;
use ieee.std_logic_1164.all;
entity lx is
port(clk: in std_logic;
led: out std_logic_vector(7 downto 0);
ledc: out std_logic_vector(2 downto 0));
end lx;
architecture art of lx is
--十进制计数器
component cnt10 --待调用的有时钟使能的十进制计数器端口定义
port(clk,clr,en: in std_logic;
q: out std_logic_vector(3 downto 0);
c10: out std_logic);
end component;
--16位锁存器
component reg16b --待调用的32位锁存器端口定义
port (load: in std_logic;
din: in std_logic_vector(15 downto 0);
dout: out std_logic_vector(15 downto 0));
end component;
--测频控制器
component testpl --待调用的测频控制信号发生器端口定义
port(clk:in std_logic;
tsten:out std_logic;
clr_cnt:out std_logic;
load:out std_logic);
end component;
--数码管选择器
component ledcom --待调用的数码管选择器端口定义
port(clk:in std_logic;
datain: in std_logic_vector(15 downto 0);
dataout: out std_logic_vector(3 downto 0);
sel: out std_logic_vector(2 downto 0));
end component;
--译码器
component ymq --待调用的译码器端口定义
port(d_in: in std_logic_vector(3 downto 0);
d_out: out std_logic_vector(7 downto 0));
end component;
signal clk1,clk2,clk3: std_logic;--clk1为1Hz信号,clk2为被测信号,clk3为数码管扫描信号
signal tsten,clr,load: std_logic;
signal c1,c2,c3,c4: std_logic;
signal qout,rout: std_logic_vector(15 downto 0);
signal datao: std_logic_vector(3 downto 0);
begin
u0:testpl port map(clk1,tsten,clr,load);
u1:cnt10 port map(clk2,clr,tsten,qout(3 downto 0),c1);
u2:cnt10 port map(c1,clr,tsten,qout(7 downto 4),c2);
u3:cnt10 port map(c2,clr,tsten,qout(11 downto 8),c3);
u4:cnt10 port map(c3,clr,tsten,qout(15 downto 12),c4);
u5:reg16b port map(load,qout(15 downto 0),rout);
u6:ledcom port map(clk3,rout,datao,ledc);
u8:ymq port map(datao,led);
end art;
5. 心得体会
这次课程设计中,我不仅复习巩固了课堂所学的理论知识,提高了对所学知识的综合应用能力,并从根本上了解了VHDL语言的一些基本用法,应用了原来不会或者不熟练的句型,如if句,case句等,也学会了一些基本功能的实现方法,如分频,状态控制等等,从另外一个角度重新审视了上学期完全从硬件角度出发的电路设计,明白了软硬件之间的交互。通过这个课题,对系统框图、逻辑流程图、状态转移图的设计有了一定的了解。也懂得了系统的前期设计对于后续的编程和调试的重要性。
本课题采用了自下而上的设计方法,根据系统对硬件的要求,画出系统控制流程图;然后根据控制流程图,分化模块,利用模块实现功能;最后进行仿真和调试。
每个成功的背后都要面对无数次的失败,这次课设也不例外。虽然遇到不少问题与困难,但通过老师以及同学的帮助,都一一得到顺利地解决。我想这必定会为将来的实践积累宝贵的经验和教训。
总之,这次课设我们都受益匪浅。整个过程氛围浓厚,本人也态度十分认真,积极向老师和同学求教并在此过程中收获良多,能够进一步了解和使用一门与硬件直接打交道的基本语言对我们将来的学习和工作都会十分有益。
6. 五个模块的程序源代码
6.1 测频控制信号发生器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity testpl is
port(clk:in std_logic;--1Hz信号
tsten:out std_logic;--计数器使能信号
clr_cnt:out std_logic;--计数器清零信号
load:out std_logic);--锁存器输出控制信号
end testpl;
architecture art of testpl is
signal div2clk:std_logic;
begin
process(clk)
begin
if clk'event and clk='1'then
div2clk<=not div2clk; --div2clk为2Hz
end if ;
end process;
process (clk ,div2clk)
begin
if( clk='0'and div2clk='0')then
clr_cnt<='1'; --当div2clk与clk同时为零时计数器清零
else clr_cnt<='0'; --当div2clk处于的高电平时计数器计数
end if;
end process;
load<=not div2clk; --锁存器输出与计数器使能信号反相
tsten<=div2clk;
end art;
有时钟使能的十进制计数器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cnt10 is
port(clk,clr,en: in std_logic; --clk:计数器时钟,clr:清零信号,en:计数使能信号
q: out std_logic_vector(3 downto 0);--q:4位计数结果输出
c10: out std_logic);--计数进位
end cnt10;
architecture art of cnt10 is
signal cqi: std_logic_vector(3 downto 0);
begin
process (clk,clr)
begin
if clr='1' then cqi<="0000"; --当输入的clr_cnt为低电平0时清零
elsif clk'event and clk='1' then
if en='1' then --当输入的tesen为高电平1时允许计数
if (cqi<9) then cqi<=cqi+1;
else cqi<="0000"; --等于9则计数器清零
end if; --当输入的tesen为低电平0时禁止计数,锁定计数值
end if;
end if;
end process;--产生进位
process(cqi)
begin
if cqi="1001" then c10<='1'; --当加的9时产生进位输出
else c10<='0';
end if;
end process;
q<=cqi;
end art;
16位锁存器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity reg16b is
port (load: in std_logic;--输出锁存控制信号
din: in std_logic_vector(15 downto 0);
dout: out std_logic_vector(15 downto 0));
end reg16b;
architecture art of reg16b is
begin
process(load,din)
begin
if load'event and load='1'then --load为高电平时teten为低电平,计数器禁止
dout<=din; --锁存输入的数据
end if;
end process;
end art;
6.4 数码管控制器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ledcom is
port(clk:in std_logic; --数码管扫描频率
datain: in std_logic_vector(15 downto 0);--锁存器输入的16位信号
dataout: out std_logic_vector(3 downto 0);--输出至译码器的4位信号
sel: buffer std_logic_vector(2 downto 0));--输出数码管选择信号
end ledcom;
architecture art of ledcom is
begin --sel同扫描频率clk循环变化
process(clk)
begin
if rising_edge(clk) then
if sel>=7 then
sel <="000";
else sel<=sel+1;
end if;
end if;
end process; --数码管选择
process(sel,datain)
begin
case sel is
when "000"=> dataout<=datain(3 downto 0);
when "001"=> dataout<=datain(7 downto 4);
when "010"=> dataout<=datain(11 downto 8);
when "011"=> dataout<=datain(15 downto 12);
when others =>NULL;
end case;
end process;
end art;
七段数码管的译码器
library IEEE;
use IEEE.std_logic_1164.all;
entity ymq is
port(
d_in: in std_logic_vector(3 downto 0); --数码管控制器输入四位信号
d_out: out std_logic_vector(6 downto 0)); --输出8位信号
end ymq; --第8位d_out[7]为逗号
architecture art of ymq is
begin
process(d_in)
begin
case d_in is --第8位为1高电平逗号不显示
when "0000" => d_out<="1111110"; --0
when "0001" => d_out<="0110000"; --1
when "0010" => d_out<="1101101"; --2
when "0011" => d_out<="1111001"; --3
when "0100" => d_out<="0110010"; --4
when "0101" => d_out<="1011011"; --5
when "0110" => d_out<="1011111"; --6
when "0111" => d_out<="1110000"; --7
when "1000" => d_out<="1111111"; --8
when "1001" => d_out<="1111011"; --9
when others =>NULL;
end case;
end process;
end art;
7. 参考文献
1、王小军 主编.《VHDL简明教程》.清华大学出版社,1997
2、潘松、王国栋 主编.《VHDL应用教程》电子科技大学出版社,2000
3、甘历 主编.《VHDL应用于开发实践》科学出版社,2003
4、刘爱荣 主编.《EDA技术与CPLD/FPGA开发应用简明教程》.清华大学出版社,2007