电子实习2基于FPGA多功能数字钟设计.doc
江苏科技大学南徐学院 Jiangsu university of science and technology nanxu college电子实习2基于FPGA多功能数字钟设计姓 名:学 号:.班 级:.指导教师:提交日期:2012 年 3 月摘 要本文介绍了利用EDA技术自顶向下的设计方法,提出了一个多功能数字钟的设计方案,采用VerlogHDL语言设计了数字钟系统的各个模块,在QuartusII开发平台下进行了编译、仿真、下载,实现了基本计时显示和设置、调整时间、闹钟和秒表功能。VHDL是Very High Speed Integrated Circuit Hardware Description Language的缩写,意思是超高速集成电路硬件描述语言。对于复杂的数字系统的设计,它有独特的作用。它的硬件描述能力强,能轻易的描述出硬件的结构和功能。这种语言的应用至少意味着两种重大的改变:电路的设计竟然可以通过文字描述的方式完成;电子电路可以当作文件一样来存储。随着现代技术的发展,这种语言的效益与作用日益明显,每年均能够以超过30%的速度快速成长。本文介绍一种基于FPGA的数字时钟设计方法,简要介绍了VHDL语言的一些基本语法和概念后,进一步应用VHDL,在MAX+plusII 的环境下设计一个电子钟,最后通过仿真出时序图实现预定功能。电子钟的时间显示用到了七段数码管(或称七段显示器)的电路设计,内部的时间控制输出则用到了各种设计,包括:时钟分频模块、计时模块、按键模块和显示模块四个部分。目 录1 引言12 总体方案设计 X2.1 项目设计要点2.2 方案论述2.3 软件介绍2.4 芯片介绍3 单元电路设计3.1 分频模块设计3.2 计时功能模块设计3.3 计数模块3.4 译码显示模块3.5 整点报时模块4 系统功能及功能仿真4.1 系统功能4.2功能仿真各个模块的仿真波形5 心得体会6 参考文献附录:完整实验程序引言VHDL语言是一种标准化的硬件描述语言。设计者可以通过它编写代码,然后用模拟器验证其功能,再将设计代码综合成门级电路,最后下载到可编程逻辑器件(CPLD,FPGA)中来实现一个设计。由于VHDL语言具有支持大规模设计和再利用已有设计等优点1,因此使用VHDL语言来设计数字钟。本设计采用的VHDL是一种全方位的硬件描述语言,具有极强的描述能力,能支持系统行为级、寄存器传输级和逻辑门级这三个不同层次的设计;支持结构、数据流、行为三种描述形式的混合描述,覆盖面广,抽象能力强,因此在实际应用中越来越广泛。ASIC是专用的系统集成电路,是一种带有逻辑处理的加速处理器;而FPGA是特殊的ASIC芯片,与其它的ASIC芯片相比,它具有设计开发周期短、设计制造成本低、开发工具先进、标准产品无需测试、质量稳定以及可实时在线检测等优点。在控制系统中,键盘是常用的输入设备,系统应当根据键盘的输入来完成相应的功能。因此,按键信息输入是与软件结构密切相关的过程。根据键盘结构的不同,采用不同的编码方法,但无论有无编码以及采用什么样的编码,最后都要转换成为相应的键值,以实现按键功能程序的转移。1钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。诸如定时自动报警、定时启闭电路、定时开关烘箱、通断动力设备,甚至各种定时电气的自动启用等,所有这些都是以钟表数字化为基础的。因此研究数字钟以及扩大其应用有着非常现实的意义。2.总体方案设计2.1项目设计要点 (1)以数字形式显示时、分、秒; (2)小时记数为24小时进制 (3)分秒进制为60进制 (4)扩展功能:定时闹钟、整点报时2.2 方案论述 系统组成框图,如下图所示: 主体电路电路的两种工作状态如下图所示:1.为正常时钟模块2.设置时间模块控制按键用来选择是正常计数还是调整时间并决定调整时、分、秒; 置数按键按下时,表示相应的调整块要加一;基准时钟是1HZ;计数器是对1HZ的频率计数;动态显示模块是对计数器的计数进行译码,送到数码管进行显示 。2.3 软件介绍本设计采用Quartus II软件编写所需程序。Quartus II 是Altera公司的综合性PLD开发软件,支持原理图、VHDL、VerilogHDL以及AHDL(Altera Hardware Description Language)等多种设计输入形式,内嵌自有的综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD设计流程。 Quartus II可以在XP、Linux以及Unix上使用,除了可以使用Tcl脚本完成设计流程外,提供了完善的用户图形界面设计方式。具有运行速度快,界面统一,功能集中,易学易用等特点。 Quartus II支持Altera的IP核,包含了LPM/MegaFunction宏功能模块库,使用户可以充分利用成熟的模块,简化了设计的复杂性、加快了设计速度。对第三方EDA工具的良好支持也使用户可以在设计流程的各个阶段使用熟悉的第三方EDA工具。 此外,Quartus II 通过和DSP Builder工具与Matlab/Simulink相结合,可以方便地实现各种DSP应用系统;支持Altera的片上可编程系统(SOPC)开发,集系统级设计、嵌入式软件开发、可编程逻辑设计于一体,是一种综合性的开发平台。 Maxplus II 作为Altera的上一代PLD设计软件,由于其出色的易用性而得到了广泛的应用。目前Altera已经停止了对Maxplus II 的更新支持,Quartus II 与之相比不仅仅是支持器件类型的丰富和图形界面的改变。Altera在Quartus II 中包含了许多诸如SignalTap II、Chip Editor和RTL Viewer的设计辅助工具,集成了SOPC和HardCopy设计流程,并且继承了Maxplus II 友好的图形界面及简便的使用方法。 Altera Quartus II 作为一种可编程逻辑的设计环境, 由于其强大的设计能力和直观易用的接口,越来越受到数字系统设计者的欢迎。Altera的Quartus II可编程逻辑软件属于第四代PLD开发平台。该平台支持一个工作组环境下的设计要求,其中包括支持基于Internet的协作设计。Quartus平台与Cadence、ExemplarLogic、 Mentor Graphics、Synopsis和Simplicity等EDA供应商的开发工具相兼容。改进了软件的LogicLock模块设计功能,增添 了FastFit编译选项,推进了网络编辑性能,而且提升了调试能力。支持MAX7000/MAX3000等乘积项器件2.4 芯片介绍FPGA是现场可编程门阵列(Field Programmable Gate Array)的简称,与之相应的CPLD是复杂可编程逻辑器件(Complex Programmable Logic Device)的简称,两者的功能基本相同,只是实现原理略有不同,有时可以忽略这两者的区别,统称为可编程逻辑器件或CPLD/PGFA。CPLD/PGFA几乎能完成任何数字器件的功能,上至高性能CPU,下至简单的74电路。它如同一张白纸或是一堆积木,工程师可以通过传统的原理图输入或硬件描述语言自由的设计一个数字系统。通过软件仿真可以事先验证设计的正确性,在PCB完成以后,利用CPLD/FPGA的在线修改功能,随时修改设计而不必改动硬件电路。使用CPLD/FPGA开发数字电路,可以大大缩短设计时间,减少PCB面积,提高系统的可靠性。这些优点使得CPLD/FPGA技术在20世纪90年代以后得到飞速的发展,同时也大大推动了EDA软件和硬件描述语言HDL的进步。3FPGA具有掩膜可编程门阵列的通用结构,它由逻辑功能块排成阵列,并由可编程的互连资源连接这些逻辑功能块来实现不同的设计。FPGA一般由3种可编程电路和一个用于存放编程数据的静态存储器SRAM组成。这3种可编程电路是:可编程逻辑模块(CLB-Configurable Logic Block)、输入/输出模块(IOB-I/O Block)和互连资源(IRInterconnect Resource)。可编程逻辑模块CLB是实现逻辑功能的基本单元,它们通常规则的排列成一个阵列,散布于整个芯片;可编程输入/输出模块(IOB)主要完成芯片上的逻辑与外部封装脚的接口,它通常排列在芯片的四周;可编程互连资源包括各种长度的连接线段和一些可编程连接开关,它们将各个CLB之间或CLB、IOB之间以及IOB之间连接起来,构成特定功能的电路。3 单元电路设计3.1 分频模块设计系统需要1Hz的频率来驱动计时器,而实验箱上可提供多种不同的频率,如系统时钟20MHz和SW7提供的可选择频率,请根据需要自行选择频率,并进行分频,形成1Hz频率。实验程序分频模块PROCESS(CLK) VARIABLE CNT: INTEGER RANGE 0 TO 12000000; BEGIN IF(CLK'EVENT AND CLK='1') THEN IF(CNT=12000000) THEN CNT:=0; CLKIN1<=NOT CLKIN1; ELSE CNT:=CNT+1; END IF; END IF; END PROCESS;PROCESS(CLK) VARIABLE CNT: INTEGER RANGE 0 TO 12000; BEGIN IF(CLK'EVENT AND CLK='1') THEN IF(CNT=12000) THEN CNT:=0; CLKIN2<=NOT CLKIN2; ELSE CNT:=CNT+1; END IF; END IF; END PROCESS;3.2 计时功能模块设计计时模块需对时、分、秒进行计数,其中小时位为24进制,分钟和秒钟位为60进制。可以用一段程序对时、分、秒进行连续计数,也可以对时、分、秒的高位和低位分别计数。注意,如果采用连续计数方式,因为每位显示时有高位和低位之分,所以需将十进制数据用BCD码进行转换后,才能输出到七段数码管上显示。实验程序process(clk) variable cnt: integer range 0 to 6000000; begin if(clk'event and clk='1') then if(jiezou='0') then if(cnt=3000000) then cnt:=0; clk1<=not clk1; else cnt:=cnt+1; end if; else if(cnt=6000000) then cnt:=0; clk1<=not clk1; else cnt:=cnt+1; end if; end if; end if; end process; process(clk1,KAIGUAN) begin if(clk1'event and clk1='1') then IF(KAIGUAN='1') THEN temp<=0; end if; if(KAIGUAN='0') THEN if(temp=25) then temp<=0; else temp<=temp+1; end if; end if; end if; end process; process(temp) begin case temp is when 0=>liushui<="00000000" when 1=>liushui<="01000000" when 2=>liushui<="00100000" when 3=>liushui<="00010000" when 4=>liushui<="00001000" when 5=>liushui<="00000100" when 6=>liushui<="00000010" when 7=>liushui<="00000000" when 8=>liushui<="00000001" when 9=>liushui<="00000010" when 10=>liushui<="00000100" when 11=>liushui<="00001000" when 12=>liushui<="00010000" when 13=>liushui<="00100000" when 14=>liushui<="01000000" when 15=>liushui<="10000000" when 16=>liushui<="00011000" when 17=>liushui<="00100100" when 18=>liushui<="01000010" when 19=>liushui<="10000001" when 20=>liushui<="00000000" when 21=>liushui<="10000001" when 22=>liushui<="01000010" when 23=>liushui<="00100100" when 24=>liushui<="00011000" when 25=>liushui<="00000000" end case; end process; PROCESS(CLKIN1,MODE,TIAOFEN,TIAOSHI) BEGIN IF(CLKIN1'EVENT AND CLKIN1='1') THEN CO1<='0'CO2<='0' IF(MODE='1') THEN IF(SEC0="1001") THEN SEC0<="0000" IF(SEC1="0101") THEN SEC1<="0000" ELSE SEC1<=SEC1+1; END IF; ELSE SEC0<=SEC0+1; END IF; IF(SEC1="0101" AND SEC0="1000") THEN CO1<='1' ELSE CO1<='0' END IF; IF(CO1='1') THEN IF(MIN0="1001") THEN MIN0<="0000" IF(MIN1="0101") THEN MIN1<="0000" ELSE MIN1<=MIN1+1; END IF; ELSE MIN0<=MIN0+1; END IF; END IF; IF(MIN1="0101" AND MIN0="1001") THEN CO2<='1' ELSE CO2<='0' END IF; IF(CO1='1' AND CO2='1') THEN IF(HOUR0="1001") THEN HOUR0<="0000" IF(HOUR1="0010") THEN HOUR1<="0000" ELSE HOUR1<=HOUR1+1; END IF; ELSE HOUR0<=HOUR0+1; END IF; IF(HOUR1="0010" AND HOUR0="0011") THEN HOUR1<="0000" HOUR0<="0000" END IF; END IF; ELSIF(MODE='0' AND TIAOFEN='0') THEN IF(MIN0="1001") THEN MIN0<="0000" IF(MIN1="0101") THEN MIN1<="0000" ELSE MIN1<=MIN1+1; END IF; ELSE MIN0<=MIN0+1; END IF; ELSIF(MODE='0' AND TIAOSHI='0') THEN IF(HOUR0="1001") THEN HOUR0<="0000" IF(HOUR1="0010") THEN HOUR1<="0000" ELSE HOUR1<=HOUR1+1; END IF; ELSE HOUR0<=HOUR0+1; END IF; IF(HOUR1="0010" AND HOUR0="0011") THEN HOUR1<="0000" HOUR0<="0000" END IF; END IF; END IF; END PROCESS; PROCESS(CLKIN2,SEL) BEGIN IF(CLKIN2'EVENT AND CLKIN2='1') THEN IF(SEL="111") THEN SEL<="000" ELSE SEL<=SEL+1; END IF; END IF;3.3 计数模块1.秒计数模块该模块框图如图4.9所示。模块主要完成秒向分的进位,产生脉冲信号。图3.9 秒模块逻辑框图核心程序如下:ENTITY second ISPORT(clk_1s : IN STD_LOGIC;os : OUT STD_LOGIC);END second;ARCHITECTURE sec_architecture OF second ISBEGINk1:process(clk_1s)variable count:integer range 0 to 100:=0;beginif rising_edge(clk_1s) thenif count=59 thenos<='1'count:=0;elseos<='0'count:=count+1;end if;end if;end process k1;3.4 译码显示模块该模块完成对计数器编码信息的译码工作,驱动数码管则显示相应的数字。模块组件如4.14所示。图3.14译码显示模块组件核心程序如下:ENTITY drive IS PORT (clk:in std_logic;addr : IN STD_LOGIC_vector(3 downto 0); led : OUT STD_LOGIC_vector(7 downto 0); END drive; ARCHITECTURE behave OF drive IS SIGNAL sel:STD_LOGIC_vector(3 downto 0); BEGIN process(clk)begin sel<=addr; case sel is when "0000"=>led<="11000000" when "0001"=>led<="11111001" when "0010"=>led<="10100100" when "0011"=>led<="10110000" when "0100"=>led<="10011001" when "0101"=>led<="10010010" when "0110"=>led<="10000010" when "0111"=>led<="11111000" when "1000"=>led<="10000000" when "1001"=>led<="10010000" when others=>led<="10111111" end case; end process; end behave;3.5 整点报时模块该模块能够完成整点时的报时功能。即将至整点时,前四秒低音,最后一秒高音。该模块在十二点三十分的时候,蜂鸣器响起音乐,持续一分钟。模块组件如图4.17所示。图3.17 整点报时模块组件1.整点报时核心程序如下:if rising_edge(clk05s) thenif cnt=119 thencnt:=0;elsecnt:=cnt+1;end if;if mh="0101" and ml="1001" and(cnt=117 or cnt=115 or cnt=113 or cnt=111) then c<='0'else c<='1'end if;if mh="0000" and ml="0000" and (cnt=119 or cnt=0 or cnt=1)then d<='0'else d<='1'end if;end if;end process;a<=clk1k and not(d);b<=clk05s and not(c);speaker<=a or b;4 系统功能及仿真计数功能 该模块的仿真波形如图4.10所示。图3.10 秒计数模块波形仿真译码功能该模块的仿真波形如图3.15所示。图3.15 译码显示波形仿真5.小结与体会通过本次的数字钟设计过程中,让我更进一步地熟悉有关数字电路的知识和具体应用。学会了利用QuarterII软件进行原理图的绘制,硬件描述语言VHDL的编写,程序的仿真等工作。并能根据仿真结果分析设计的存在的问题和缺陷,从而进行程序的调试和完善。参考文献:1EDA技术与VHDL。2 王紫婷,吴蓉 ,张彩珍,EDA技术与应用,兰州大学出版社,20033 潘松,黄继业,EDA技术实用教程,北京科学出版社,20064 王开军,姜宇柏,面向CPLD/FPGA的VHDL设计,机械工业出版社,20075 毕满清,电子技术实验与课程设计,机械工业出版社,20056 吕思忠,数子电路实验与课程设计,哈尔滨工业大学出版社,20017 谢自美,电子线路设计、实验、测试,华中理工大学出版社,2003附录:完整实验程序 1)主程序模块:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity szz isport(clk:in std_logic; md1:in std_logic; md2:in std_logic_vector(1 downto 0); speak:out std_logic; h1,h2,m1,m2,s1,s2:out std_logic_vector(3 downto 0);end szz;architecture one of szz issignal hou1:std_logic_vector(3 downto 0);signal hou2:std_logic_vector(3 downto 0);signal min1:std_logic_vector(3 downto 0);signal min2:std_logic_vector(3 downto 0);signal seth1:std_logic_vector(3 downto 0);signal seth2:std_logic_vector(3 downto 0);signal setm1:std_logic_vector(3 downto 0);signal setm2:std_logic_vector(3 downto 0);signal sec1:std_logic_vector(3 downto 0);signal sec2:std_logic_vector(3 downto 0);begin-小时十位h110:process(clk,hou2,min1,min2,sec1,sec2,md1,md2)beginif clk'event and clk='1' thenif (hou1="0010" and hou2="0011")and(min1="0101" and min2="1001") and (sec1="0101" and sec2="1001") thenhou1<="0000"elsif hou1="0010"and hou2="0011"and md1='0' and md2="01" then-当时间为23点且处于校时状态时hou1<="0000"elsif (hou2="1001"and(min1="0101" and min2="1001") and (sec1="0101" and sec2="1001")or (hou2="1001"and md1='0' and md2="01") thenhou1<=hou1+1;end if;end if;end process h110;-小时个位h220:process(clk,min1,min2,sec1,sec2,md1,md2,hou1)beginif clk'event and clk='1' thenif (hou1="0010" and hou2="0011")and(min1="0101" and min2="1001") and (sec1="0101" and sec2="1001") thenhou2<="0000"elsif hou2="1001"and(min1="0101" and min2="1001") and (sec1="0101" and sec2="1001") thenhou2<="0000"elsif (hou2="1001"and md1='0' and md2="01")or (hou1="0010"and hou2="0011") thenhou2<="0000"-md<='1'elsif (min1="0101" and min2="1001") and (sec1="0101" and sec2="1001")or (md1='0' and md2="01") thenhou2<=hou2+1;-speak<=clk;end if;end if;end process h220;-分钟十位m110:process(clk,min2,sec1,sec2,md1,md2)beginif clk'event and clk='1' thenif (min1="0101" and min2="1001") and (sec1="0101" and sec2="1001") then min1<="0000"elsif min1="0101"and min2="1001"and (md1='0' and md2="00")thenmin1<="0000"elsif (min2="1001"and (sec1="0101" and sec2="1001") or (min2="1001"and md1='0' and md2="00")thenmin1<=min1+1;end if;end if;-end if;end process m110;-分钟个位m220:process(clk,sec1,sec2,md1,md2)beginif clk'event and clk='1' thenif min2="1001"and (sec1="0101" and sec2="1001")thenmin2<="0000"elsif m