基于VHDL的出租车计费器设计论文.doc
基于VHDL的出租车计费器设计摘 要近年来,随着人们生活水平的提高,出租车已经成为人们出行必不可少的交通工具之一。而出租车计费器是出租车上的一个重要仪器,它是乘客与司机双方的公平交易准则。在出租车的需求量不断加大的情况下,对出租车计费器系统的稳定性,灵活性的要求增加,具有良好性能的计费器对于司机和乘客都是很有必要的。本文设计了一个基于VHDL的出租车计费器系统,该系统分为计费和显示两大模块。计费模块是实现系统功能的核心,根据输入信号,将里程、计费和等候时间以BCD码形式显示出来,显示模块将其译码轮流扫描显示。本设计首先在Quartus软件中,用VHDL语言对各个模块进行设计,其次画出顶层原理图,然后对顶层文件进行仿真测试,最后将仿真成功的设计文件下载到EDA实验箱进行验证。验证结果具有计时、计里程、计费等功能。关键词:出租车计费器;VHDL;Quartus ;设计Design of Taximeter Based on VHDLAbstractWith the development of people's living standard,taxi has become an important transportation in recent years.And taxi meter is an important instrument in taxi,it is the fair trade standards in bothpassengers and drivers.In the situation that the demand of taxi is increasing continuously and the requirements of taxi meter system's stability and flexibility are increase,the taxi meter which have a good performance is very necessary for drivers and passengers.This paper designs a taxi meter based on VHDL,the taxi meter system is divided into two modules:charge control and display control.The charge control module is the core to realize the function of the system,according to the input signal,display the mileage,charge and waiting time by BCD code.The display module will be scan and display decoding alternately.Firstly,using VHDL language compile the various parts in Quartussoftware,and draw the top diagram.Then the simulation test.Finally,the success of simulation program will be downloaded into the EDA experiment box.The validation result comply with the design requirements,there are many functions,as record the time,mileage and charge.Key woords:taximeter; VHDL; Quartus; design 21 / 25目 录中文摘要英文摘要1 引言11.1 设计背景11.2 VHDL简介11.3 Quartus简介32 出租车计费器的设计32.1 系统设计要求32.2 设计思路42.3 出租车计费器系统工作流程图43 出租车计费器的实现53.1 出租车计费器的顶层原理图53.2 系统各功能模块的实现53.2.1 模块taxi:charge_control63.2.2 模块display:display_control64 出租车计费器系统仿真与分析74.1 顶层实体的仿真波形74.2 计费模块的仿真波形84.3 显示模块的仿真波形94.4 管脚锁定94.5 显示结果的几种情况105 总结11参考文献12致13附录141 引言1.1 设计背景出租车行业在我国八十年代初开始兴起,因为其方便快捷的特点受到人们的欢迎。尤其是近几年里,人们物质生活水平得到提高以与生活节奏加快了,很多城市的出租车行业迅速发展,出租车已经成为人们出行的普遍选择之一。而出租车计费器是出租车重要的仪器之一,它能够规出租车市场,减小乘客与司机之间发生纠纷的可能性。要想加强出租车行业的管理,提高服务的质量就必须要有一种功能齐全,准确计量,简单又易用的出租车计费器。因为出租车计费器计数是连续累加的,所以它可以显示出任一时刻乘客应付的费用。我国最初所使用的计费器只有一种功能,即计量。我国第一家生产计费器的是起重机厂,早期的计费器就是个里程表,因为它们都是用的机械齿轮结构,只能实现最简单的计程功能。如今我国有上百家企业生产出租车计费器,这些企业主要分布在,和等地。随着时代的发展,第一代计费器已经不能满足人们的需求,科学技术的发展使第二代计费器应运而生。它实现了半机械半电子化的设计,采用的是手摇计算机与机械结构相结合的方式,它不仅能实现计程的功能,同时还能完成计价的工作,给计费器的使用者带来了方便。而大规模集成电路的发展又给计费器带来了新的变化,产生了第三代计费器,即全电子化的计费器。它的功能变得更多,同时也在不断完善的过程之中。在改进和完善的过程中,产生了很多实用的附加功能,给人们带来了更多的方便。例如:(1)LED显示功能。在计费器中添加数码管,让计费器多屏显示的功能得以实现;(2)永久时钟功能。将日历时钟芯片运用到计费器当中,即使是在非营运的状态下,计费器上的时钟也可以永久显示;(3)存储功能。计费器可长时间存储多项营运数据,以便于需要的时候查询1。1.2 VHDL简介硬件描述语言已经有几十年的发展历史,并且在系统的仿真、验证和设计、综合等方面得到成功的应用。目前常用的硬件描述语言有VHDL、 Verilog HDL 、ABEL等234。VHDL则起源于20世纪70年代末和80年代初,美国国防部提出的VHSIC计划,目标是为下一代集成电路的生产、实践阶段性的工艺极限和完成10万门级以上的电路设计而建立一种新的描述方法5。VHDL的英文全称为Very-High-Speed Integrated Circuit Hardware Description Language,是IEEE标准化的硬件描述语言,并且已经成为系统描述的国际公认标准,得到众多EDA公司的支持。VHDL具有很多的优点使它能够被大多数人认可,被广泛应用在逻辑电路的设计方面,并且成为了标准化的硬件描述语言,其优点如下:(1)功能强大和设计灵活。一个简洁的使用VHDL语言编写的程序就可以描述一个复杂的逻辑电路,因为VHDL拥有强大的语言结构6。VHDL多层次的设计描述功能可以有效地控制设计的实现,支持设计库和可重复使用的元件生成,还支持多种设计方式,如层次化设计、模块化设计和同步、异步和随机电路设计。(2)与具体器件无关。用VHDL设计硬件电路时不用先确定设计要用到哪种器件,也不用特别熟悉器件的部结构,这样可以使设计人员专注于进行系统设计。设计完成后,可以根据消耗的资源选择合适的器件,而不造成资源的浪费。(3)很强的移植能力。VHDL由很多不同的工具支持,同一个设计的程序可以在包括综合工具、仿真工具、系统平台等工具中使用。(4)强大的硬件描述能力。VHDL可以描述系统级电路和门级电路,而且描述方式多样,可以采用行为描述、寄存器传输描述或者结构描述,也可以用其混合描述方式。同时,VHDL可以准确地建立硬件电路模型,因为它支持惯性延迟和传输延迟。VHDL的数据类型很丰富,支持标准定义的数据类型,当标准定义的数据类型不能满足用户的需求时,用户可以自己定义的所需要的数据类型,增加了设计的自由度。(5)语法规,易于共享。当把用VHDL编写的代码文件看作是程序时,它可以作为设计人员之间的交流容;当把它看作是文档时,可以作为签约双方的合同文本。VHDL易于共享的特点,使得大规模的协作开发容易实现。同时,这些特点也促进了VHDL的发展和完善。综上所述,VHDL有很多其他的硬件描述语言所不具备的优点。但是,VHDL仍然存在一些缺点,主要是3个方面。(1)要求设计者对硬件电路知识甚至是芯片结构方面的知识了解较多。应该摆脱一般的高级语言程序设计思路,因为在电路世界里的事件很多是并行发生的,并且硬件电路系统部的模块可以是互相独立的,也可以是互为因果的,所以,在用VHDL设计硬件电路时应摆脱一般的高级语言程序设计思路。在设计电路时,应先构思电路,然后才能描述。(2)不能进行太抽象的系统描述。因为EDA工具无法综合抽象性太强的系统,故用VHDL描述系统电路时不能太抽象。目前的VHDL很难综合实际的硬件电路,只能适用于系统建模。(3)不能描述模拟电路。对于模拟电路而言,VHDL并不是一种理想的硬件描述语言。但可以预见,未来硬件描述语言的发展方向是模拟电路和数模混合电路的描述方式。1.3 Quartus简介Quartus II 是Altera公司的综合性PLD开发软件,可以采用多种输入方式,如VHDL、Verilog HDL、AHDL(Altera Hardware Description Language)与电路图等。它支持一些比较成熟的模块,如LPM/MegaFunction宏功能模块库等,设计者可以直接调用这些模块,从而使设计的复杂性降低了,设计的速度也加快了。Quartus II 带有综合器和仿真器,可以完成从设计输入到硬件配置的完整PLD设计流程,减少了设计者的工作量。Quartus II 是一种综合性的开发平台,在Quartus II 中可以进行系统级设计嵌入式的软件开发和可编程逻辑的设计。Quartus II 越来越受到数字系统设计者的欢迎,是因为 Quartus II 拥有强大的设计能力和直观易用的接口,可以在多种平台上使用,如XP、Linux以与Unix等,具有完善的用户图形界面设计方式,运行速度快,功能集中,易学易用等特点78。2 出租车计费器的设计2.1 系统设计要求系统设计要求为:(1)起步价为8.00元,起步公里为3公里;(2)超过3公里,每公里按1.00元收费;(3)单程行驶里程超过20公里,每公里租价加收50%;(4)等候时间累计1分钟,则每分钟折算1公里里程价。要求显示里程、计费与等候时间。乘客上车后,按下启动键,开始计费,除非同一乘客往返乘车,否则按下单程键,这样当行驶里程超过20公里时,每公里收费1.5元。2.2 设计思路根据系统的功能要求,分为2个模块来实现,分别是计费模块,显示模块。计费模块是实现系统功能的核心,里面有分为分频、计时、公里计数、计费等部分。分频部分是把外部提供的300Hz进行分频得到系统工作需要的工作脉冲,计费部分包括两个容,一个是正常行驶的里程数所产生的费用,另一个是车行中途暂停的时间所产生的费用。然后将里程、计费和等候时间以BCD码形式显示出来,显示模块将其译码轮流扫描显示。2.3 出租车计费器系统工作流程图对出租车计费器系统的功能要求进行分析,得到如下工作流程图:图1 工作流程图出租车载客后,启动计费器,整个系统开始工作,进入初始化状态,即计程从0开始,计费从8开始。再根据stop信号判断行驶还是暂停。若是行驶状态,计费器开始进行里程计数,当里程超过3公里时,计费器开始累加,按1.00元每公里计算,计程器则继续,否则计费器不变。当里程超过20公里,按1.50每公里进行累加。若是暂停状态,计费器开始进行等候时间计数,当等候时间累计1分钟,则每分钟折算1公里里程价。最后将等候时间、里程、计费都显示出来。3 出租车计费器的实现3.1 出租车计费器的顶层原理图图2 顶层原理图原理图中输入部分分别是clk:系统时钟信号;mile:公里脉冲信号;single:单程键;start:计费器启动信号;stop:等待信号。输出部分为七段译码show和位选码sel,show显示出来的是等候时间、里程和计费。描述系统顶层实体的VHDL程序见附录。3.2 系统各功能模块的实现3.2.1 模块taxi:charge_control图3 计费模块设计计费模块的难点在于小数计算,由计费规则知,单程行驶里程超过20公里,每公里租价加收50%,即每公里租价1.5元。20公里是临界值,在此以后,计费以1.5元累加,需要对计数进行讨论,因为个位为8或9都可能导致进位。等候时间累计1分钟,则每分钟折算1公里里程价,所以,等候和行驶都可使计费增加。为此,设计2个时钟脉冲,公里脉冲和等候脉冲,根据汽车行驶还是等候选择计费脉冲。描述计费模块的VHDL程序见附录。3.2.2 模块display:display_control图4 显示模块显示模块用来将计费模块输出译码,然后轮流扫描数码管。如图5,出租车计费器共有8个数码管,带一个使能端,高电平有效。图5 七段数码管与向量元素对应表1 七段数码管段位码十进制数字段位码000111111100000110201011011301100111401100110501101101601111101700100111801111111901101111灭00000000描述显示模块的VHDL程序见附录。4 出租车计费器系统仿真与分析4.1 顶层实体的仿真波形图6 系统顶层实体仿真波形图之一图7 系统顶层实体仿真波形图之二由图7可知001(表示c1)对应11101111(表示9.),100(表示k0)对应01100110(表示4),其余均对应00111111(表示0),即显示为行驶4公里,费用为9.0元。4.2 计费模块的仿真波形图8(a)图8(b)图8(c)图8均为计费模块的仿真波形图,由图8(a)可看出汽车是单程行驶,图8(b)可看出汽车在中途暂停了一段时间,在图8(c)中可直观地看出汽车行驶了75公里,等候时间为4分钟,应付的费用为113.5元。4.3 显示模块的仿真波形图9 显示模块仿真波形图将计费模块输出译码,然后轮流扫描数码管,显示各个数据,等候时间4分钟,里程75公里,计费113.5元。4.4 管脚锁定在验证出租车计费器系统的功能之前,需要清楚实验箱与各个信号之间的对应关系,参照资料得出本设计中各引脚的对应情况如下:图10 管脚锁定管脚锁定后将顶层文件下载到EDA实验箱芯片中,验证计费器的功能。4.5 显示结果的几种情况图11 验证结果1图11表示汽车行驶21公里,应付费26.5元,符合设计要求。图12 验证结果2图12表示汽车行驶25公里,在行驶20公里之后的一段时间停留4分钟,应付费38.5元,符合设计要求。5 总结本设计采用VHDL硬件描述语言,通过Quartus开发平台设计了出租车计费器系统,经过编译仿真基本无误,在此次设计中我主要做了以下工作:1对所选题目进行仔细的审阅,理顺思路,了解熟悉设计的基本思路,掌握整个设计工作的框架;2学习设计所需要用到的Quartus软件,做到熟练掌握软件的各种仿真功能;3学习VHDL硬件描述语言,做到能读懂VHDL程序,并能够编写本设计所需要的程序;4用软件对程序进行编译和仿真,观察波形,符合设计的要求后,准备硬件下载工作;5在实验室把程序下载到实验板上,经过数码管显示结果符合设计要求,完成整个设计工作部分的实验环节。出租车计费器系统的设计已经全部完成,能够按照预期的效果显示等候时间、里程和车费数目。车行驶或暂停按其各自的计费规则进行计费,车费总数为两项之和,若停止则车费清零,等待下一次计费的开始9。在出租车计费器系统的两个模块计费模块、显示模块中,计费模块是实现系统功能的核心,里面又分为分频、计时、公里计数、计费等部分;显示模块将显示等候时间,里程和费用。各模块成功编译运行后,再将它们组合到一起,完成完整的出租车系统的设计10。通过这次的论文设计,我对VHDL编程语言有了更深层次的了解,对Quartus软件的应用更加的熟练,加强了我的动手能力,使我在理论学习和编程练习方面都有了较大的收获。参考文献1 蓉.基于VHDL语言的出租车自动计费器的设计J.科技风,2008,24:42-462 侯伯亨,顾新.VHDL硬件描述语言与数字逻辑电路设计(修订版)M.:电子科技大学,2005:3-93 孟庆海,洲.VHDL基础与经典实例开发M.:交通大学,2008,4:1-54 王行,衍.EDA技术入门与提高M.:电子科技大学,2005:17-325 周彩宝等.VHDL语言与其应用J.计算机工程,1998,10:17-206 冰等.VHDL在计算机组成原理实验中的应用研究J.价值工程,2011,30(27):56-597 黄正瑾等编著.CPLD系统设计技术入门与应用M.:电子工业,2002:13-238 爱荣等编著. EDA技术与CPLD/FPGA开发应用简明教程M. :清华大学,2007:45-569 席砺莼等.基于VHDL语言的出租车计费系统设计J.现代电子技术,2003,3:57-6110 高健等.基于Verilog HDL出租车计费系统的研制J.实验室研究与探索, 2004,10:34-37致 在这次毕业设计的设计过程中,得到了很多人的帮助。首先要感我的指导老师初侠老师,在课程设计上给予我的指导,提供给我的支持和帮助,让我能把系统做得更加完善。在完成毕业论文的过程中,我学到了许多新的知识,也巩固了一些已经学过的知识,弥补了以前的不足之处,锻炼了我的动手能力,使我的设计能力得到提高。其次,我要感帮助过我的同学们,他们也为我解决了不少难题,同时也感学院为我提供了良好的做毕业设计的环境。最后,要感各位老师抽出时间对本文进行评阅。附 录顶层实体的VHDL编程:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity taximeter isport(clk : in std_logic;-输入300Hz时钟 start : in std_logic;-计费器启动 stop : in std_logic;-等待信号 mile : in std_logic;-公里脉冲信号 single : in std_logic;-单程键 sel : out std_logic_vector(2 downto 0);-位选 show : out std_logic_vector(7 downto 0);-7段数码管译码输出end taximeter;architecture structural of taximeter is component taxi port(clk : in std_logic; start : in std_logic; stop : in std_logic; mile : in std_logic; single : in std_logic; char0 : out std_logic_vector(3 downto 0);-计费输出小数点位 char1 : out std_logic_vector(3 downto 0);-计费输出个位 char2 : out std_logic_vector(3 downto 0);-计费输出十位 char3 : out std_logic_vector(3 downto 0);-计费输出百位 min0 : out std_logic_vector(3 downto 0);-等待时间输出个位 min1 : out std_logic_vector(3 downto 0);-等待时间输出十位 km0 : out std_logic_vector(3 downto 0);-行驶公里输出个位 km1 : out std_logic_vector(3 downto 0);-行驶公里输出十位 end component; component display port(clk : in std_logic; char0 : in std_logic_vector(3 downto 0); char1 : in std_logic_vector(3 downto 0); char2 : in std_logic_vector(3 downto 0); char3 : in std_logic_vector(3 downto 0); min0 : in std_logic_vector(3 downto 0); min1 : in std_logic_vector(3 downto 0); km0 : in std_logic_vector(3 downto 0); km1 : in std_logic_vector(3 downto 0); sel : out std_logic_vector(2 downto 0); show : out std_logic_vector(7 downto 0); end component; signal char0 : std_logic_vector(3 downto 0); signal char1 : std_logic_vector(3 downto 0);signal char2 : std_logic_vector(3 downto 0);signal char3 : std_logic_vector(3 downto 0);signal min0 : std_logic_vector(3 downto 0);signal min1 : std_logic_vector(3 downto 0);signal km0 : std_logic_vector(3 downto 0);signal km1 : std_logic_vector(3 downto 0);begin charge_control:taxi port map(clk => clk, start => start, stop => stop, mile => mile,single => single, char0 => char0, char1 => char1, char2 => char2, char3 => char3, min0 => min0, min1 => min1, km0 => km0, km1 => km1);display_control:displayport map(clk => clk,char0 => char0, char1 => char1, char2 => char2, char3 => char3, min0 => min0, min1 => min1, km0 => km0, km1 => km1, sel => sel, show => show);end structural;计费模块的VHDL编程:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity taxi isport(clk : in std_logic;-输入300Hz时钟 start : in std_logic;-计费器启动 stop : in std_logic;-等待信号 mile : in std_logic;-公里脉冲信号 single : in std_logic;-单程键 char0 : out std_logic_vector(3 downto 0);-计费输出小数点位 char1 : out std_logic_vector(3 downto 0);-计费输出个位 char2 : out std_logic_vector(3 downto 0);-计费输出十位 char3 : out std_logic_vector(3 downto 0);-计费输出百位 min0 : out std_logic_vector(3 downto 0);-等待时间输出 min1 : out std_logic_vector(3 downto 0);-等待时间输出 km0 : out std_logic_vector(3 downto 0);-行驶公里输出 km1 : out std_logic_vector(3 downto 0);-行驶公里输出end taxi;architecture behave of taxi isconstant n : integer := 30;signal f_mile1 : std_logic;-延迟时间signal f_mile2 : std_logic;-延迟时间signal f_mile_r : std_logic;-延迟时间signal start_r : std_logic;-延迟时间signal clk1hz : std_logic;-分频所得1Hz时钟signal q : integer range 0 to n-1;-分频器signal sec : integer range 0 to 59;signal c3,c2,c1,c0 : std_logic_vector(3 downto 0);-计费寄存器signal k0 : std_logic_vector(3 downto 0);-公里寄存器signal k1 : std_logic_vector(3 downto 0);-公里寄存器signal m1 : std_logic_vector(3 downto 0);-等待时间寄存器signal m0 : std_logic_vector(3 downto 0);-等待时间寄存器signal en0 : std_logic;-路程大于3公里,使能有效signal en1 : std_logic;-单程且大于20公里,使能有效signal f_wait : std_logic;-等待时间,1脉冲/分钟signal f : std_logic;-计费时钟begin-输出显示min0 <= m0;min1 <= m1;km0 <= k0;km1 <= k1;char0 <= c0;char1 <= c1;char2 <= c2;char3 <= c3;-分频进程-u1:process(clk)beginif rising_edge(clk) thenif q=299 thenq<=0;elseq<=q+1;end if;end if;end process;clk1hz <= '0' when q<integer(n/2) else '1'-等待计时进程-u2:process(clk1hz,start)beginif start='0' thenf_wait<='0'elsif rising_edge(clk1hz) thenif stop='1' thenif sec=59 then sec<=0; f_wait<='1' if m0="1001" then m0<="0000"if m1="0101" then m1<="0000" else m1<=m1+'1' end if;else m0<=m0+'1'end if;else f_wait<='0' sec<=sec+1;end if;else f_wait<='0'end if;end if;end process;-延迟信号,检测上升沿-u3:process(clk1hz)begin if rising_edge(clk1hz) then f_mile2 <= f_mile1; f_mile1 <= mile; start_r <= start; end if;end process;f_mile_r<= f_mile1 and not(f_mile2);-选择不同的计费时钟-f<= f_wait when stop='1' else f_mile_r when en0='1' else'0'-公里计数进程-u4:process(start,f_mile_r)begin if start='0' then k0<="0000" k1<="0000" en0<='0'en1<='0'elsif rising_edge(f_mile_r) thenif k0="1001" thenk0<="0000"if k1="1001" then k1<="0000"else k1<=k1+'1'end if;elsek0<=k0+'1'end if; -大于3公里,使能有效if k0="0011" then en0<='1'end if; -单程且大于20公里,使能有效if k1="0001" and k0="1001" and single='1' then en1<='1'end if;end if;end process;-计费进程-u5:process(start,f,start_r)beginif start='1