EDA课程设计基于VHDL数字电压表设计.doc
广西工学院课程设计任务书课题名称 数字电压表设计 系 别 信息与计算科学系 专 业 电子信息科学与技术 班 级 学 号 姓 名 指导教师 韦艳霞 教研室主任 李政林 系 主 任 李栋龙 2012年 9月 13日基于FPGA的数字电压表的设计目录摘 要电子设计自动化(electronic design automation,EDA)是近几年迅速发展起来的将计算机软件、硬件、微电子技术交叉运用的现代电子设计技术。其中EDA设计语言中的VHDL语言是一种快速的电路设计工具,功能涵盖了电路描述、电路综合、电路仿真等三大电路设计内容。本电压表的电路设计正是用VHDL语言完成的。此次设计主要应用的软件是美国ALTERA公司自行设计的一种CAE软件工具,即MAX+PLUS 。本次所设计的电压表的测量范围是05V,精度为0.01V。此电压表的设计特点为:通过软件编程下载到硬件实现,设计周期短,开发效率高。关键词:电子设计自动化(EDA);FPGA;VHDL;A/D采集;数字电压表AbstractThe design of digital system is becoming faster, bulkier ,smaller and lighter than before. Electronic design automation is in the last few years quickly develop, it makes use of software , hardware ,micro-electronics technology to form a course of electronic design. Among them , the VHDL language of EDA is a kind of tool of fast circuit design , the function covered the circuit describe , the circuit synthesize , the circuit imitate the true etc . The circuit of the design that use VHDL language to complete . The this time design is primarily the applied software is MAX PLUS which is made by the United States ALTERA company.This systems range is -5v to +5v and precision is 0.01v.Characteristics of this electric voltage watch is :Pass the software program to download the hardware o realize , design the period is short ,development the efficiency is high. Key words: Electronic Design Automation (EDA);FPGA;VHDL;A/D Acquisition digital voltage一、绪 论1、研究目的及意义数字电压表(Digital Voltmeter)简称DVM,是大学物理教学和实验中的重要仪表,其数字化是指将连续的模拟电压量转换成不连续、离散的数字量并加以显示。传统的实验用模拟电压表功能单一、精度低、体积大,且存在读数时的视差,长时间连续使用易引起视觉疲劳,使用中存在诸多不便。而目前数字万用表的内部核心多是模数转换器,其精度很大程度上限制了整个表的准确度,可靠性较差。传统的数字电压表设汁通常以大规模ASIC(专用集成电路)为核心器件,并辅以少量中规模集成电路及显示器件构成。ASIC完成从模拟量的输入到数字量的输出,是数字电压表的心脏。这种电压表的设计简单、精确度高,但是这种设计方法由于采用了ASIC器件使得它欠缺灵活性,其系统功能固定,难以更新扩展。后来发展起来的用微处理器(单片机)控制通用A/D转换器件的数字电压表的设计的灵活性明显提高,系统功能的扩展变得简单,但是由于微处理器的引脚数量有限,其控制转换速度和灵活性还是不能满足日益发展的电子工业的需求。而应用EDA(电子设汁自动化)技术及FPGA(现场可编程门阵列),其集成度高、速度快、性能十分可靠、用户可自由编程且编程语言通俗易懂、系统功能扩展非常方便。采用FPGA芯片控制通用A/D转换器可使速度、灵活性大大优于由微处理器和通用A/D转换器构成的数字电压表。本设计的A/D转换器件选用ADC0809对模拟电压采样,以一片高性能FPGA芯片为控制核心,以软件实现了诸多硬件功能,对电压信号的转换结果进行准确实时的运算处理并送出显示。系统的主要功能都集成在一块芯片上,大大减少了系统的分立元件数量,降低了功耗,增加了可靠性,较好地实现了电压的精准测量。二、设计要求设计一个数字电压表,利用8位A/D转换器,将连续的模拟电信号转换成离散的数字电信号,并加以显示,要求其量程为0-5V,分辨率约为0.02V,三位数码管显示,其中一位为整数,两位为小数,能正确显示小数点。三、设计过程1数字电压表的基本原理 数字电压表整体设计框图,如图4.9.1所示,数字电压表系统由A/D转换控制模块、数据转换模块、动态扫描与译码模块三部分构成。A/D转换控制模块控制外部A/D转换器,动态扫描与译码模块向外部数码管显示电路输出数据。 A/D转换器负责采集模拟电压,转换成8位数字信号送入FPGA的A/D转换控制模块,A/D转换控制模块负责A/D转换的启动、地址锁存、输入通道选择、数据读取等工作,数据转换模块将8位二进制数据转换成16位十进制BCD 1码送入动态扫描与译码模块,最后通过数码管显示当前电压值。2A/D转换控制模块 (1)A/D转换器 作为A/D转换器的ADC0809,片内有8路模拟开关,分辨率为8位,转换时间约100us,含锁存控制的8路多路开关,输出由三态缓冲器控制,单5V电源供电。 分辨率是指A/D转换器能分辨的最小模拟输入量,通常用能转换成的数字量的位数来表示,如8位、10位、12位、16位等。位数越高,分辨率越高。例如,对于8位A/D转换器,当输入电压满刻度为5V时,其输出数字量的变化范围为028-1,转换电路对输入模拟电压的分辨能力为5V/(28-1)19.6mV。 量程是指A/D转换器所能转换的输入电压范围。 如图4.9.2所示为ADC0809芯片的封装引脚图,由图可知芯片有28只引脚,采用双列直插式的封装。 各引脚功能如下:IN7IN08路模拟信号输入通道。ADC0809对输入的模拟量要求主要为:信号单极性,电压范围05V。 ADDA、ADDB、ADDC3位地址线。ADDA为低位地址,ADDC为高位地址,组成3位二进制码000111,分别选中IN0IN7。 2ALE地址锁存允许信号,高电平时允许ADDA、ADDB、ADDC所示当前通道被选中,上升沿时将通道地址锁存至地址锁存器中。 START启动转换信号。START上升沿时,所有内部寄存器清0;START下降沿时,开始进行A/D转换。在A/D转换期间,START保持低电平。 EOCA/D转换结束信号。EOC=0,正在进行转换;EOC=1,A/D转换完毕,常用作中断申请信号。 OE输出允许信号,高电平有效,用来打开三态输出锁存器。OE=0,输出数据线呈高阻态;OE=1,输出转换得到的数据。 CLOCK外部时钟脉冲输入端。ADC0809内部没有时钟电路,所需时钟信号由外界提供,要求频率范围10KHz1.5MHz。 D7D0数据输出线。为三态缓冲输出形式。 Vcc单5V电源。 GND接地。 如图4.9.3所示,为ADC0809工作时序图。IN0IN7是模拟信号的输入端,通过ADDC、ADDB、ADDA地址选择信号来选择模拟信号具体从哪个端口输入,当ALE产生上升沿,地址信号就存入地址寄存器,下降沿时则开始A/D转换;EOC为低电平时表示A/D转换进行中,高电平时表示A/D转换结束;OE位低电平时,输出数据线高阻态,当 3OE出现高电平,则打开三态输出锁存器,输出八位数据D7D0。 (2)A/D转换控制模块 A/D转换控制模块的功能是进行时序控制,控制A/D转换器件对模拟信号采样,转换为数字信号。 如图4.9.4所示为A/D控制模块状态转换关系。在上电瞬间,A/D转换控制模块处于st0的初始状态;进入st1状态后,选择模拟信号的输入通道,启动采样;在st2状态中进行A/D转换,当eoc=1时进入st3状态;st3状态表示A/D转换完成,允许转换好的数据输出;进入st4状态,如果lock出现上升沿,转换好的数据送入锁存器。图4.9.4 状态转换关系图 设计程序如下:LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY adc IS port (din : IN STD_LOGIC_VECTOR(7 DOWNTO 0); clk, eoc : IN STD_LOGIC; 4 ale, start, oe, adda : OUT STD_LOGIC; dout : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); END adc; ARCHITECTURE behave OF adc IS TYPE states IS (st0, st1, st2, st3, st4); SIGNAL c_state, n_state : states ; SIGNAL temp : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL lock : STD_LOGIC; BEGIN adda <= '1' dout <= temp; COM1: PROCESS(c_state, eoc) BEGIN CASE c_state IS WHEN st0 => ale<='0' start <= '0' lock <= '0' oe <= '0' n_state <= st1; WHEN st1 => ale<='1' start <= '1' lock <= '0' oe <= '0' n_state <= st2; WHEN st2 => ale <= '0' start <= '0' lock <= '0' oe <= '0' IF (eoc = '1') THEN n_state <= st3; ELSE n_state <= st2; END IF; WHEN st3 => ale <= '0' start <= '0' lock <= '0' oe <='1' n_state <= st4; WHEN st4 => ale <= '0' start <= '0' lock <= '1' oe <= '1' n_state <= st0; WHEN OTHERS => n_state <= st0; END CASE; 5 END PROCESS COM1; COM2 : PROCESS(clk) BEGIN IF (clk'EVENT AND clk = '1') THEN c_state <= n_state; END IF; END PROCESS COM2; LATCH1 : PROCESS(lock) BEGIN IF (lock'EVENT AND lock = '1') THEN temp <= din; END IF; END PROCESS LATCH1; END behave; 以上程序中,使用了ale、start、oe和eoc等端口控制ADC0809器件的工作时序,根据A/D转换的状态转换关系,将一个完整的采样过程分为st0、st1、st2、st3、st4五个状态,由两个主控进程和一个辅助进程控制,构成Moore型状态机。 A/D转换控制模块的波形仿真图如图4.9.5所示,上电瞬间,c_state处于st0初始状态,时序控制信号start、oe、ale输出为0;第一个clk脉冲,状态转换为st1,start置1,此时内部寄存器清零,oe=0,ale=1,对模拟启动采样;第2个clk脉冲,进入st2状态,start产生下降沿开始A/D转换,oe=0,ale=0,此时若eoc=1,表示A/D转换完成,可以进入st3状态;第3个clk脉冲,进入st3状态,statrt=0,ale=0,oe置高电平,打开三态输出锁存器,允许转换数据输出;第4个clk脉冲,进入st4状态,转换数据被稳定的锁存在锁存器中。 对照波形仿真图,我们看到dout端口的信号输出均发生在st4状态,仿真结果满足时序要求,输出结果正确,设计合理。 在MAXPLUS平台上实现的A/D转换控制模块的符号如图4.9.6所示。 输入端口有数据输入端din7.0,时钟信号端clk,A/D转换结束信号端eoc;输出端口有地址锁存允许信号端ale,转换启动信号端start,输出允许信号端oe,模拟信号通道地址端adda。 3数据转换模块 ADC0809是8位模数转换器,它的输出状态共有256种,若信号为05V电压范围,则每两个状态的电压差值为5/(256-1),约为0.0196V。本设计用查表命令来得到电压值,如表4-9-1所示为待转换数值与实际电压值的对应表。程序如下: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; ENTITY bcd2 IS PORT(datain : IN STD_LOGIC_VECTOR(7 DOWNTO 0); q1, q2, q3, q4 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); END bcd2; ARCHITECTURE behave OF bcd2 IS SIGNAL data0, data1 : STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL sum1, sum2, sum3, sum4: STD_LOGIC_VECTOR(4 DOWNTO 0); SIGNAL c1, c2, c3 : STD_LOGIC_VECTOR(4 DOWNTO 0); 8 BEGIN data1 <="0000000000000000" WHEN datain(7 DOWNTO 4)="0000" ELSE "0000001100010100" WHEN datain(7 DOWNTO 4)="0001" ELSE "0000011000100111" WHEN datain(7 DOWNTO 4)="0010" ELSE "0000100101000001" WHEN datain(7 DOWNTO 4)="0011" ELSE "0001001001010101" WHEN datain(7 DOWNTO 4)="0100" ELSE "0001010101101001" WHEN datain(7 DOWNTO 4)="0101" ELSE "0001100010000010" WHEN datain(7 DOWNTO 4)="0110" ELSE "0010000110010110" WHEN datain(7 DOWNTO 4)="0111" ELSE "0010010100010000" WHEN datain(7 DOWNTO 4)="1000" ELSE "0010100000100100" WHEN datain(7 DOWNTO 4)="1001" ELSE "0011000100110111" WHEN datain(7 DOWNTO 4)="1010" ELSE "0011010001010001" WHEN datain(7 DOWNTO 4)="1011" ELSE "0011011101100101" WHEN datain(7 DOWNTO 4)="1100" ELSE "0100000001111000" WHEN datain(7 DOWNTO 4)="1101" ELSE "0100001110010010" WHEN datain(7 DOWNTO 4)="1110" ELSE "0100011100000110" WHEN datain(7 DOWNTO 4)="1111" ELSE "0000000000000000" data0 <="0000000000000000" WHEN datain(3 DOWNTO 0)="0000" ELSE "0000000000100000" WHEN datain(3 DOWNTO 0)="0001" ELSE "0000000000111001" WHEN datain(3 DOWNTO 0)="0010" ELSE "0000000001011001" WHEN datain(3 DOWNTO 0)="0011" ELSE "0000000001111000" WHEN datain(3 DOWNTO 0)="0100" ELSE "0000000010011000" WHEN datain(3 DOWNTO 0)="0101" ELSE "0000000100011000" WHEN datain(3 DOWNTO 0)="0110" ELSE "0000000100110111" WHEN datain(3 DOWNTO 0)="0111" ELSE "0000000101010111" WHEN datain(3 DOWNTO 0)="1000" ELSE "0000000101110110" WHEN datain(3 DOWNTO 0)="1001" ELSE "0000000110010110" WHEN datain(3 DOWNTO 0)="1010" ELSE "0000001000010110" WHEN datain(3 DOWNTO 0)="1011" ELSE "0000001000110101" WHEN datain(3 DOWNTO 0)="1100" ELSE "0000001001010101" WHEN datain(3 DOWNTO 0)="1101" ELSE "0000001001110101" WHEN datain(3 DOWNTO 0)="1110" ELSE "0000001010000100" WHEN datain(3 DOWNTO 0)="1111" ELSE "0000000000000000" sum1 <=('0'&data1(3 DOWNTO 0) + ('0'&data0(3 DOWNTO 0); c1 <= "00000" WHEN sum1 < "01010" ELSE "00001" sum2 <=('0'&data1(7 DOWNTO 4) + ('0'&data0(7 DOWNTO 4)+ c1; c2 <= "00000" WHEN sum2 < "01010" ELSE "00001" sum3 <=('0'&data1(11 DOWNTO 8) + ('0'&data0(11 DOWNTO 8)+ c2; c3 <= "00000" WHEN sum3 < "01010" ELSE "00001" sum4 <=('0'&data1(15 DOWNTO 12) + ('0'&data0(15 DOWNTO 12)+ c3; q1 <= sum1(3 downto 0) WHEN sum1 < "01010" ELSE sum1 + "00110" q2 <= sum2(3 downto 0) WHEN sum2 < "01010" ELSE sum2 + "00110" q3 <= sum3(3 downto 0) WHEN sum3 < "01010" ELSE sum3 + "00110" q4 <= sum4(3 downto 0) WHEN sum4 < "01010" ELSE sum4 + "00110" END behave; 以上程序主要功能为接收来自于A/D转换控制模块的8位数据信号datain7.0,将这8位数据分为高4位datain7.4和低4位datain3.0,利用查表法分别给出高4位对应电压值和低4位对应电压值,这些电压值用16位BCD码data1和data0表示,作BCD码加法得到16位BCD码表示的电压值,这组数据以四组4位BCD码的形式送入下一级。 10如图4.9.7所示为数据转换模块的波形仿真图,我们假设输入信号datain7.0=“10010100B”,经过仿真,输出q1=“0010B”、q2=“0000B”、q3=“1001B”、q4=“0010B”,即8位二进制输入信号所对应的电压值大小为2.902V,对照表4-9-1可知满足查表法中待转换数据与电压值的对应关系。 数据转换处理模块的符号如图4.9.8所示。 输入端口为来自A/D控制转换模块数据信号datain7.0;输出端口为16位BCD码的低四位q13.0,次低四位q23.0,次高四位q33.0,高四位q43.0。 4显示译码模块 本模块的任务是把来自数据转换模块的BCD码转换成能被数码管识别的字型编码。 (1)动态扫描模块 程序如下: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; 11USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; ENTITY segdisp IS PORT(q1, q2, q3 : IN STD_LOGIC_VECTOR(3 downto 0); clk : IN STD_LOGIC; dpout : OUT STD_LOGIC; selout : OUT STD_LOGIC_VECTOR(2 DOWNTO 0); segout : OUT STD_LOGIC_VECTOR(6 DOWNTO 0); END segdisp; ARCHITECTURE behave OF segdisp IS COMPONENT encoder PORT(din : IN STD_LOGIC_VECTOR(3 DOWNTO 0); sout : OUT STD_LOGIC_VECTOR(6 DOWNTO 0); END COMPONENT; SIGNAL sel : STD_LOGIC_VECTOR(2 DOWNTO 0); SIGNAL b_din : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL b_sout : STD_LOGIC_VECTOR(6 DOWNTO 0); BEGIN p1:PROCESS(clk) BEGIN IF (clk'EVENT and clk = '1') THEN IF sel = "101" THEN sel <= "111" ELSE sel <= sel - 1; END IF; END IF; END PROCESS p1; 12 selout <= sel; p2:PROCESS(q1, q2, q3, sel) BEGIN CASE sel IS WHEN "101" => b_din <= q3; dpout <= '1' WHEN "110" => b_din <= q2; dpout <= '0' WHEN "111" => b_din <= q1; dpout <= '0' WHEN OTHERS => NULL; END CASE; END PROCESS p2; U0: encoder PORT MAP(din => b_din,sout => b_sout); segout <= b_sout; END behave; 8位二进制数在数据转换模块中已经转换成了16位的BCD码,最后4位BCD码为小数部分估算值,可以忽略不计,所以本程序接收来自数据转换模块高位的三组BCD码q12.0,q22.0,q32.0,利用位选信号selout,选通外部的三位数码管,从左往右依次显示带小数点的整数位,以及两位小数。 (2)译码模块 在动态扫描程序中用到了7段式数码显示译码器的元件例化语句,其实体元件程序如下: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY encoder IS PORT(din : IN std_logic_vector(3 downto 0); sout : OUT std_logic_vector(6 downto 0); END encoder; ARCHITECTURE behave OF encoder IS 13BEGIN sout <= "0111111" WHEN din="0000" ELSE "0000110" WHEN din="0001" ELSE "1011011" WHEN din="0010" ELSE "1001111" WHEN din="0011" ELSE "1100110" WHEN din="0100" ELSE "1101101" WHEN din="0101" ELSE "1111101" WHEN din="0110" ELSE "0000111" WHEN din="0111" ELSE "1111111" WHEN din="1000" ELSE "1101111" WHEN din="1001" ELSE "1110111" WHEN din="1010" ELSE "1111100" WHEN din="1011" ELSE "0111001" WHEN din="1100" ELSE "1011110" WHEN din="1101" ELSE "1111001" WHEN din="1110" ELSE "1110001" WHEN din="1111" ELSE "0000000" END behave; 以上程序,将输入端口din3.0接收的4位BCD转换成7段式数码管的字形编码形式,可显示十六进制数。 显示译码模块仿真波形如图4.9.9所示。clk提供扫描时钟,利用人眼视觉暂留现象,实现动态扫描,所以要求clk频率较高;q1、q2、q3输入四位BCD码,selout输出位选信号,segout输出段选信号,dpout为小数点输出,能正确显示2.90的字形。 输入端口有接收来自数据转换模块16位BCD码次低4位的q13.0,次高4位的q23.0,高4位的q33.0,时钟信号端clk;输出端口有小数点输出端口dpout,位选信号端selout2.0,段选信号端segout3.0。 5顶层设计 数字电压表的顶层设计,包含了A/D控制模块、数据转换模块和动态显示模块三部分,顶层设计原理图如图4.9.11所示。 图4.9.11 顶层设计原理图 数字电压表顶层模块的仿真波形图如图4.9.12所示。图中赋予输入信号din7.0=“01000110B”,设置时钟信号和必要的控制信号,经过仿真,输出位选 16码selout2.0为101、110、111,即八位数码管中的高三位,段选码segout6.0在输出时间上与位选码一一对应,输出显示电压值为1.37,满足查找法电压值计算结果,能正确显示数值字形,仿真结果符合数字电压表的设计要求。 三、参考文献1 潘松,EDA技术实用教程M,北京:科学出版社,2003, 1-152 谭敏,综述EDA技术,<<合肥学院学报(自然科学版)>>,2003, 10-453 王宝友,EDA技术标准化现状,<<北京联合大学学报(自然科学版)>>,2002, 112-117 4, 卢毅,VHDL与数字设计,北京:科学出版社,2001, 132-1345, 徐志军,大规模可编程逻辑器件及其应用,成都:电子科技大学出版社,2000, 24-536, Stefan Sjoholm,用VHDL设计电子线路,北京:清华大学出版社,2000, 76-1007, 赵雅兴,FPGA原理、设计与应用,天津:天津大学出版社,1999, 89-1298,林敏.VHDL数字系统设计与高层次综合M.北京:电子工业出版社,2001. 12-34 9,包本刚 基于FPGA器件的FIR滤波器的设计期刊论文-湖南科技学院学报,2005, 1110,齐洪喜,路颖。VHDL电路设计使用教程M。北京:清华大学出版社,2004,16-23四、致 谢从这次的课程设计中,我受益匪浅。电压表的设计,用EDA仿真工具Quartus II 8.0,用vhdl语言设计,这些对于我们初学者来说,并不是件容易的事情,但是同时巩固了我们对知识的深刻理解。为以后的FPGA设计打下了坚实的基础。所以,总的来说,过程是困难的,不容易的,结果却是很满意的,获得了很宝贵的知识和经验!本文设计的VHDL语言程序已在Quartus II 8.0工具软件上进行了编译、仿真和调试。经过实验验证,本设计是正确的,其电压显示值误差没有超过量化台阶上限(0.02V)。在本文完成之际,这里面每一个页面的显示,每一行语句的调试,每一段文本的输入之中都有我辛勤的汗水。设计的时间虽然短暂,我却从中学到了很多的东西。在此我谨向我的指导老师以及在设计过程中给予我很大帮助的老师、同学致以最诚挚的谢意!