• 241.00 KB
  • 2022-04-22 11:26:18 发布

出租车计费系统结构设计

  • 35页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'出租车计费系统结构设计第一章绪论目前,现代电子产品几科渗透了社会的各个领域,产品的性能越来越强,复杂程度越来越高,更新步伐越来越快。其中专用集成电路设计技术的日趋进步和完善,推动了数字系统的迅速发展。而电子产品技术发展的代表就是电子设计自动化设计(ElectronicDesignAutomation)。本设计采用的VHDL是硬件描述语言的一种,VHDL不仅可以作为系统模拟的建模工具,而且可以作为电路系统的设计工具,可以利用软件工具将VHDL源码自动地转化为文体方式表达的基本逻辑元件连接图。并且具有很强的电路描述和建模能力,能从多个层次对数字系统进行建模和描述,从而大大简化了硬件设计任务,提高了设计效率和可靠性。本论文采用ISP器件和VHDL语言开发出一套出租车计费系统,该计费系统的可靠性高、成本低、通用性强;该系统在不改变硬件电路的前提下,具有可以重构系统的功能,采用完全相同电路结构,只要根需求在VHDL程序中设置各参数,就可以适应不同计费标准的需要,还可根据需求增加其他功能。1.1选题背景本节将从FPGA嵌入式应用开发技术与计费器技术发展的客观实际出发,通过对该技术发展状况的了解,以及课题本身的需要,指出研究基于FPGA芯片设计出租车计费系统的必要性。1.1.1课题相关技术发展EDA技术已有30年的发展历程,大致可分为三个阶段。70年代为计算机辅助设计(CAD)阶段,人们开始用计算机辅助进行IC版图编辑、PCB布局布线,取代了手工操作。80年代为计算机辅助工程(CAE)阶段。与CAD相比,CAE除了有纯粹的图形绘制功能外,又增加了电路功能设计和结构设计,并且通过电气连接网络表将两者结合在一起,实现了工程设计。CAE的主要功能是:原理图输入,逻辑仿真,电路分析,自动布局布线,PCB后分析。90年代为电子系统设计自动化(EDA)阶段。25 现在数字设计依靠手工已经无法满足设计要求,设计工作需要在计算机上采用EDA技术完成。EDA技术以计算机硬件和系统软件为基本工作平台,采用EDA通用支撑软件和应用软件包,在计算机上帮助电子设计工程师完成电路的功能设计、逻辑设计、性能设计、时序测试直至PCB的自动设计等。在EDA软件的支持下、设计者完成对系统功能的描述,由计算机软件进行处理得到设计结果。利用EDA设计工具,设计者可以预知设计结果,减少设计的盲目性,极大地提高设计的效率。EDA技术包括电子电路设计的各个领域:即从低频电路到高频电路、从线性电路到非线性电路、从模拟电路到数字电路、从分立电路到集成电路的全部设计过程,涉及电子工程师进行产品开发的全过程,以及电子产品生产的全过程中期望由计算机提供的各种辅助工作。EDA技术中现代数字系统的都是采用“自顶向下”的设计方法,从系统设计入手,在顶层进行功能方框图的划分和结构设计;在方框图一级进行仿真,纠错,并用硬件描述语言对高层次的系统行为进行描述;在功能一级进行验证,然后用逻辑综合优化工具生成具体的门级逻辑电路的网表,其对应的物理实现级可以是印刷电路板或专用集成电路。“Top→down”设计方法有利于在早期发现产品结构设计中的错误,提高设计的一次成功率。用硬件描述语言进行电路与系统的设计是当前EDA技术的一个重要特征。硬件描述语言突出优点是:语言的公开可利用性;设计与工艺的无关性;宽范围的描述能力;便于组织大规模系统的设计;便于设计的复用和继承等。与原理图输入设计方法相比较,硬件描述语言更适合规模日益增大的电子系统。硬件描述语言使得设计者在比较抽象的层次上描述设计的结构和内部特征,是进行逻辑综合优化的重要工具。目前最常用的IEEE标准硬件描述语言有VHDL和Verilog-HDL。不难理解,EDA技术发展到现在已不是某一学科的分支,或某种新的技能技术,它应该是一门综合学科。它融合多学科于一体,又渗透于各学科之中。它打破了软件和硬件间的壁垒,使计算机的软件技术与硬件实现、设计效率和产品性能合二为一,它代表了电子设计技术和应用技术的发展方向。1.1.2课题研究的必要性出租车计费器是出租车中最重要的工具,具有良好性能的计费器无论是对出租车司机还是乘客来说都是很必要的。因此,出租车计费器的研究也是十分有应用价值的。传统国内外出租车计费器多数由单片机实现,升级繁琐,成本高,硬件电路复杂,容易在运营过程中产生干扰,影响系统的使用;并且由于分立器件多,必然造成电源功耗大,芯片易发热,影响芯片的使用寿命。基于FPGA25 的出租车计费器不仅可以解决电子系统小型化、低功耗、高可靠性等问题,而且其开发周期短、开发软件投入少、芯片价格不断降低,所以基于FPGA的出租车计费器已成首选。随着城市旅游业的发展,出租车行业已成为城市的窗口,象征着一个城市的文明程度。现在各大中城市出租车行业都已普及自动计费器,所以计费器技术的发展已成定局。而部分小城市尚未普及,但随着城市建设日益加快,象征着城市面貌的出租车行业也将加速发展,计费器的普及也是毫无疑问的,所以未来汽车计费器的市场还是十分有潜力的。1.2课题研究内容本课题主要研究在EDA工具软件平台上,利用硬件描述语言VHDL语言设计出租车计费系统,以QuartusII软件作为开发平台,设计了出租车计费器系统程序并进行了程序仿真。使其实现计费,预置起步费以及模拟汽车启动、停止、暂停等功能,并能动态扫描显示车费和里程。25 第二章FPGA简介第二章FPGA简介2.1FPGA概述FPGA(FieldProgrammableGateArray),即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。FPGA几乎能完成任何数字器件的功能,工程师可以通过传统的原理图输入法或者用硬件描述语言来设计一个数字系统。通过软件仿真验证设计的正确性,可以根据需要随时修改设计而不用改变硬件电路,大大的缩短了设计时间,同时提高了系统的可靠性。这些优点使得FPGA技术在20世纪90年代后得到了高速的发展,同时也大大的推动了EDA软件和硬件描述语言HDL的进步。2.2FPGA基本结构FPGA具有掩膜可编程门阵列的通用结构,它由逻辑功能块排成阵列组成,并由可编程的互联资源连接这些逻辑功能块来实现不同的设计。FPGA一般由三种可编程电路和一个用于存放编程数据的静态存储器SRAM组成。这三种可编程电路是:可编程逻辑块(ConfigurableLogicBlock,CLB)、输入/输出模块(I/OBlock,IOB)和互联资源(InterconnectResource,IR)。可编程逻辑块(CLB)是实现逻辑功能的基本单元,它们通常规则地排列成一个阵列,散布于整个芯片;可编程输入/输出模块(IOB)主要完成芯片上的逻辑与外部封装脚的接口,它通常排列在芯片的四周;可编程互连资源(IR)包括各种长度的连线线段和一些可编程连接开关,它们将各个CLB之间或CLB、IOB之间以及IOB之间连接起来,构成特定功能的电路。FPGA的功能由逻辑结构的配置数据决定。工作时,这些配置数据存放在片内的SRAM或熔丝图上。基于SRAM的FPGA器件,在工作前需要从芯片外部加载配置数据,配置数据可以存储在片外的EPROM或其他存储体上。用户可以控制加载过程,在现场修改器件的逻辑功能,即所谓的现场编程。FPGA结构的主要优点有:(1)FPGA中除了极少的几个引脚以外,大部分引脚都可编程的IOB相连,且均可根据需要设置成输入端或输出端。(2)每个CLB中都包含组合逻辑电路和存储电路两部分,可以设置成规模不大的组合逻辑电路或时序逻辑电路。25 第二章FPGA简介(3)在CLB之间配备了丰富的连线资源。这些互联资源包括不同类型的金属线、可编程的开关矩阵和可编程的连接点,从而使CLB更易设计成各种应用型电路。FPGA存在的主要缺点有:(1)信号传输延迟时间不是确定的且速度慢(2)由于FPGA中的编程数据存储器是一个静态随机存储器,断电时数据将随之丢失,因此,每次开始工作时都要重新装载编程数据,并需要配备保存编程数据的EPROM。(3)FPGA的编程数据不便于保密。2.3FPGA系统设计流程一般来说,一个较大的完整的项目应该采用层次化的描述方法:分为几个较大的模块,定义好各功能模块间的接口,然后各个模块再细分去具体实现,这就是自顶向下的设计方法。目前,这种高层次的设计方法已被广泛采用。高层次设计只是定义系统的行为特征,可以不涉及实现工艺,因此还可以在厂家综合库的支持下,利用综合优化工具将高层次描述转化成针对某种工艺优化的网络表,使工艺转化变得容易。FPGA/CPLD系统设计的流程如图2-1所示:图形输入/HDL文体编辑综合FPGA/CPLD适配时序与功能门级仿真FPGA/CPLD编程下载FPGA/CPLD器件和电路系统图2-1应用于FPGA/CPLD的开发流程图2.3.1设计输入(原理图/HDL文体编辑)图形输入通常包括原理图输入、状态图输入和波形力输入三种常用方法。其中以原理图输入为主,在原理图编辑绘制完成后,原理图编辑器将对输入的图形文件进行排错,之后再将其编译成适用于逻辑综合的网表文件。HDL25 第二章FPGA简介文本输入与传统的计算机软件语言编辑输入基本一致。就是将使用了某种硬件描述语言的电路设计文本,如VHDL或Verilog的源程序,进行编辑输入。应用HDL的文本输入方法克服了上述原理图输入法存在的所有弊端,为EDA技术的应用和发展打开了一个广阔的天地。目前有些EDA输入工具可以把图形的直观与HDL的优势结合起来。如,在原理图输入方式中,连接用VHDL描述的各个电路模块,直观地表示系统的总体框架,再用自动HDL生成工具生成相应的VHDL或Verilog程序。但总体上看,纯粹的HDL输入设计仍然是最基本、最有效和最通用的输入方法。2.3.2综合当输入的HDL文件在EDA工具中检测无误后,首先面临的是逻辑综合,在综合之后,HDL综合器一般都可以生成一种或多种文件格式网表文件,在这种网表文件中用各自的格式描述电路的结构。整个综合过程就是将设计者在EDA平台上编辑输入的HDL文本、原理图或状态图形描述,依据给定的硬件结构组件和约束控制条件进行编译、优化、转换和综合,最终获得门级电路甚至更底层的电路描述网表文件。由此可见,综合器工作前,必须给定最后实现的硬件结构参数,它的功能就是将软件描述与给定的硬件结构用某种网表文件的方式对应起来,成为相应的映射关系。2.3.3适配适配器也称为结构综合器,它的功能是将由综合器产生的网表文件配置于指定的目标器件中,使之产生最终的下载文件,适配器将综合后的网表文件针对某一具体的目标器件进行逻辑映射操作,其中包括底层器件配置、逻辑分割、逻辑优化、逻辑布局布线操作。适配完成后可以利用适配所产生的仿真文件作精确的时序仿真,同时产生可用于编程的文件。2.3.4时序仿真与功能仿真在编程下载前必须利用EDA工具对适配生成的结果进行模拟测试,就是所谓的仿真。有两种不同级别的仿真测试:(1)时序仿真,就是接近真实器件运行特性的仿真,仿真文件中已包含了器件硬件特性参数,因而,仿真精度高。综合后所得的EDIF等网表文件通常作为FPGA适配器的输入文件,产生的仿真网表文件中包含了精确的硬件延迟信息。(2)功能仿真,是直接对VHDL25 第二章FPGA简介、原理图描述或其他描述形式的逻辑功能进行测试模拟,以了解其实现的功能是否满足原设计的要求,仿真过程不涉及任何具体器件的硬件特性。通常的做法是,首先进行功能仿真,等确认设计文件所表达的功能满足设计者原有意图时,即逻辑功能满足要求后,再进行综合,适配和时序仿真,以便把握设计项目在硬件条件下的运行情况。2.3.5编程下载把适配后生成的下载或配置文件,通过编程器或编程电缆向FPGA或CPLD下载,以便进行硬件调试和验证。通常,将对CPLD的下载称为编程,对FPGA中的SRAM进行直接下载的方式称为配置,但对于反熔丝结构和Flash结构的FPGA的下载和对FPGA的专用配置ROM的下载仍称为编程。2.3.6硬件测试最后是将含有载入了设计的FPGA或CPLD的硬件系统进行统一测试,以便最终验证设计项目在目标系统上的实际工作情况,以排除错误,改进设计。25 第三章总体设计方案第三章总体设计方案3.1设计要求本设计要实现出租车计费功能,起步费为6.00元,并在车行2km后按1.9元/km增加。当计费达到或超过一定收费(如20元)时,每千米加收50%的车费,当夜间行驶时,每千米加收50%的车费,车停止计费结束。实现预置起步费,每千米收费。现场模拟汽车启动,停止,暂停的状态。动态扫描电路,将车费和路程显示出来,并有两位小数。3.2设计原理计费系统结构框图如图3-1所示:车轮传感器计数器A车轮脉冲clk计数器B车轮脉冲clk计数器C10m脉冲oclk2计数器D100m脉冲oclk1译码/动态扫描电路计费数据行驶路程数据里程显示收费显示图3-1出租车计费系统结构框图(1)车轮每转一圈送出一个脉冲,车轮直径以520mm为例,车轮周长为1634mm,即每送一个车轮脉冲,汽车行驶1634mm。计数器A和计数器B分别对车轮传感器送来的车轮脉冲clk进行计数分频,汽车每行驶10m,计数器A输出一个“10m脉冲信号oclk2”,汽车每行驶100m,计数器B输出一个“100m脉冲信号oclk1”。(2)计数器C:对输入的10m脉冲oclk2进行累加,输出实际公里数据给动态扫描模块。25 第三章总体设计方案(3)计数器D:一方面对输入的100m脉冲oclk1进行累加,另一方面在开始时输出起步费数据,而当超出起步价时就自动在起步价的基础上每增加一个100m脉冲就增加相应的费用,而当总计费值达到或超过一定的收费时或者是夜间行车时,能按新的收费标准进行收费。(4)译码/动态扫描电路模块将路程与费用的数值译码后用动态扫描的方式驱动8只数码管,即所连接的数码管共用一个数据端,由片选信号依次选择输出,轮流显示。(5)数码管显示将千米数和计费金额均用4位LED数码管显示(2位整数,2位小数)。将图3-1中所示计数器A,计数器B,计数器C,计数器D,译码动态扫描作为底层模块分别用VHDL设计,顶层再用元件例化法(或原理图法)将底层装配在1块FPGA芯片中,配合外围的车轮传感器、7段数码管显示器,构成出租车计费器整个应用系统。25 第四章单元电路设计第四章单元电路设计4.1分频模块由于里程计数是每10m计数一次,计费是每100m计数一次,所以要对车轮传感器送来的车轮脉冲clk进行计数分频,分频系数分别为6和60。分频电路的逻辑框图如4-1所示。图4-1分频电路模块该电路的VHDL程序如下:LIBRARYieee;USEieee.std_logic_1164.all;USEieee.std_logic_unsigned.all;USEieee.std_logic_arith.ALL;ENTITYspeedIS--实体取名speedPORT(--端口描述clk,start:INstd_logic;--clk车轮脉冲,start启动暂停开关oclk1,oclk2:OUTstd_logic--oclk1100m脉冲,oclk210m脉冲);ENDspeed;ARCHITECTUREbehaveOFspeedIS--结构体名称behaveSIGNALmode1:std_logic_vector(5downto0);--mode1,mode2为分频系数SIGNALmode2:std_logic_vector(5downto0);SIGNALtemp1:std_logic_vector(5downto0);--temp1,temp2为6位,记录计数值SIGNALtemp2:std_logic_vector(5downto0);BEGINmode1<="111100";--分频系数为60mode2<="000110";--分频系数为6PROCESS(start,clk)BEGIN25 第四章单元电路设计IFrising_edge(clk)THEN--若clk的上升沿来到,则IFstart="1"THEN--若有start=‘1’,则IFtemp1=(mode1)then--若temp=(mode1),则temp1<=(OTHERS=>"0");--temp1=“000000”ELSE--否则temp1<=temp1+"1";--加1计数ENDIF;IFtemp2=(mode2)thentemp2<=(OTHERS=>"0");ELSEtemp2<=temp2+"1";ENDIF;ENDIF;ENDIF;ENDPROCESS;oclk1<="1"WHEN(temp1=mode1)ELSE"0";--当temp1=mode1时oclk<=’1’,否则=0oclk2<="1"WHEN(temp2=mode2)ELSE"0";ENDbehave;程序说明:当启动暂停键为启动状态(高电平)时,模块发出相应频率的脉冲驱动里程计数模块和计费模块进行计数;当处于暂停状态,暂停发出脉冲,此时里程计数模块和计费模块相应地停止计数。仿真结果及分析:当start=1时,开始计数到有6个车轮脉冲时,送出一个10moclk2脉冲(如图4-2),计数到60个车轮脉冲时,送出一个100moclk脉冲(如图4-3),而在start=0时,计数暂停直到start=1才继续计数。仿真结果满足设计要求。图4-210moclk2脉冲输出25 第四章单元电路设计图4-3100moclk1输出4.2里程计数模块由分频模块发出的脉冲作为计数脉冲,并将计数动态显示出来,每来一个脉冲,里程值加0.01(每收到一个脉冲代表运行了0.01公里)。逻辑框图如图4-4所示。图4-4里程计数模块该模块的VHDL程序如下:LIBRARYieee;USEieee.std_logic_1164.all;USEieee.std_logic_unsigned.all;USEieee.std_logic_unsigned.all;ENTITYcdu99ISPORT(clk,reset:INstd_logic;--clk10m输入脉冲,reset复位count1:OUTstd_logic_vector(3downto0);--里程数值的百分位count2:OUTstd_logic_vector(3downto0);--里程数值的十分位count3:OUTstd_logic_vector(3downto0);--里程数值的个位count4:OUTstd_logic_vector(3downto0));--里程数值的十位ENDcdu99;25 第四章单元电路设计ARCHITECTUREaaOFcdu99ISBEGINPROCESS(clk,reset)VARIABLEmm:std_logic_vector(15downto0);BEGINIFreset="1"THEN--复位时,显示为0mm:="0000000000000000";ELSIFclk"eventandclk="1"THENIFmm(3downto0)="1001"THEN--十六进制转换成十进制mm:=mm+7;ELSEmm:=mm+1;ENDIF;IFmm(7downto4)="1010"THENmm:=mm+"01100000";ENDIF;IFmm(11downto8)="1010"THENmm:=mm+"011000000000";ENDIF;ENDIF;count1<=mm(3downto0);count2<=mm(7downto4);count3<=mm(11downto8);count4<=mm(15downto12);ENDPROCESS;ENDaa;程序说明:此模块就是起了个计数的作用,当有一个10m脉冲送过来时,count1就是加1,而当count1计数到9时,其进位信号又被当作count2的计数脉冲进行十分位的计数,依此类推,前一位的进位信号作为下一位的计数脉冲进行计数。值得注意的是这个程序中要将计数值从十六进制转换成十进制,即在十六进制的数上加7或6,同时产生了相应的进位信号。此里程模块的计数范围为0km~99.99km。仿真结果及分析:如图4-5所示,当reset=0时,里程模块百分位开始计数,每来一个脉冲,百分位即加1,当百分位等于9时,可以看到向十分位进位。进位情况如图4-6,图4-7。当reset=1时,所有数值清0,完成复位功能,如图4-8所示。仿真结果完全符合设计要求。25 第四章单元电路设计图4-5百分位开始计数图4-6十分位进位图4-7个位向十位进位图4-8复位4.3计费模块由分频模块发出的100m计数脉冲作为计费模块的计数脉冲。计费模块的初值为6,当里程超过2公里后,才接受分频模块发出的脉冲的驱动,每来一个脉冲其数值加0.19,当收费超过20时其数值加0.29;当在夜间行驶里,收费20以内每来一个脉冲数值加0.29,收费超过20时每来一个脉冲数值加0.38。逻辑框图如图4-9所示。25 第四章单元电路设计图4-9计费模块该模块的VHDL程序如下:LIBRARYieee;USEieee.std_logic_1164.all;USEieee.std_logic_arith.all;USEieee.std_logic_unsigned.all;ENTITYcount99ISPORT(clk,reset,night:INstd_logic;--clk100m输入脉冲,reset复位,night夜间行驶输入judge2:INstd_logic_vector(3downto0);--里程个位judge3:INstd_logic_vector(3downto0);--里程十位count1:OUTstd_logic_vector(3downto0);--计费百分位count2:OUTstd_logic_vector(3downto0);--计费十分位count3:OUTstd_logic_vector(3downto0);--计费个位count4:OUTstd_logic_vector(3downto0));--计费十位ENDcount99;ARCHITECTUREaaOFcount99ISSIGNALen:std_logic;SIGNALmoney:std_logic_vector(7downto0);SIGNALmcount:std_logic_vector(15downto0);BEGINmoney<="00111000"WHEN(((mcount(15)="1")or(mcount(14)="1")or(mcount(13)="1"))and(night="1"))ELSE--夜间行驶且费用超过20,加0.38"00101001"WHEN((mcount(15)="1")or(mcount(14)="1")or(mcount(13)="1")or(night="1"))ELSE"00011001";--计费20以内,加0.1925 第四章单元电路设计en<="0"WHENjudge3="0000"andjudge2(3downto1)="000"ELSE"1";--里程超过2公里,接受100m输入脉冲驱动PROCESS(clk,reset)VARIABLEmm:std_logic_vector(15downto0);BEGINIFreset="1"THENmm:="0000011000000000";--复位,计费显示为起步费6.00ELSIFclk"eventandclk="1"THENIFen="1"THENmm:=mm+money;--里程超过2公里IF(mm(1)="1"or(mm(3downto1)="000")or(mm(3downto2)="11"))THENmm:=mm+6;ENDIF;--十六进制转换成十进制IFmm(7)="1"and(not(mm(6downto5)="00"))THENmm:=mm+"01100000";ENDIF;IFmm(11)="1"and(not(mm(10downto9)="00"))THENmm:=mm+"011000000000";ENDIF;ENDIF;ENDIF;count1<=mm(3downto0);count2<=mm(7downto4);count3<=mm(11downto8);count4<=mm(15downto12);mcount<=mm;ENDPROCESS;ENDaa;程序说明:此程序在不同的计费模式下转换时需要注意转换条件的设置,不能有遗漏也不能有重复的情况。由于此模块计数在脉冲上升沿时不是每次加一,而是加一个特定的数,所以十六进制转换为十进制时需要仔细判断。计费范围0~99.99。25 第四章单元电路设计仿真结果及分析:设计的起步费为6,即里程在两公里以内时,都只是算起步费,如图4-10所示。当2公里后,白天行驶时,每来一个脉冲都在起步费6的基础上加0.19,如图4-11所示。当总计费超过20时,每来一个脉冲都在原来的基础上加0.29,如图4-12所示。而当夜间行车两公里后,每公里车费也在白天的基础上增加50%,即每来一个脉冲加0.29,如图4-13所示。当夜间行车,计费超过20时,每来一个脉冲加0.38,如图4-14所示。一次计费结束,要进入下一次计费时,只要按下复位开关,使reset=1就可预置起步费,重新开始下一次计费,如图4-15所示。可以发现,仿真结果完全符合设计要求。图4-10起步费图4-11两公里后图4-12计费超过2025 第四章单元电路设计图4-13夜间两公里后图4-14夜间计费超过20图4-15复位起步费64.4动态扫描模块动态扫描模块中其实还包括了一个译码子模块,将里程与费用的数值通过译码器译为7段数码编码后用动态扫描的方式分别驱动各4只数码管的字段和小数点。逻辑框图如图4-16所示。25 第四章单元电路设计图4-16动态扫描模块该模块的VHDL程序如下:LIBRARYieee;USEieee.std_logic_1164.all;USEieee.std_logic_unsigned.all;ENTITYscanISPORT(clk:INstd_logic;p8:INstd_logic_vector(3downto0);p7:INstd_logic_vector(3downto0);p6:INstd_logic_vector(3downto0);p5:INstd_logic_vector(3downto0);p4:INstd_logic_vector(3downto0);p3:INstd_logic_vector(3downto0);p2:INstd_logic_vector(3downto0);p1:INstd_logic_vector(3downto0);choice:OUTstd_logic_vector(7downto0);--显示位置选择data:OUTstd_logic_vector(7downto0));--当前位置数值ENDscan;ARCHITECTUREaOFscanISSIGNALcount:std_logic_vector(2downto0);SIGNALtemp:std_logic_vector(3downto0);SIGNALchoicein,datain:std_logic_vector(7downto0);25 第四章单元电路设计BEGINclk1_label:PROCESS(clk)BEGINIFclk"eventandclk="1"THEN--计数周期为8,即扫描周期count<=count+1;ENDIF;ENDPROCESSclk1_label;clk2_label:PROCESS(clk)BEGINIFclk"eventandclk="0"THENchoice<=choicein;data(7downto1)<=datain(7downto1);IF(count="0110"orcount="0010")THENdata(0)<="1";ELSEdata(0)<="0";ENDIF;ENDIF;ENDPROCESSclk2_label;choicein<="00000001"WHENcount="000"ELSE--显示位置的切换"00000010"WHENcount="001"ELSE"00000100"WHENcount="010"ELSE"00001000"WHENcount="011"ELSE"00010000"WHENcount="100"ELSE"00100000"WHENcount="101"ELSE"01000000"WHENcount="110"ELSE"10000000";temp<=p1WHENcount="000"ELSE--显示数值的选择p2WHENcount="001"ELSEp3WHENcount="010"ELSEp4WHENcount="011"ELSEp5WHENcount="100"ELSEp6WHENcount="101"ELSE25 第四章单元电路设计p7WHENcount="110"ELSEp8;WITHtempSELECTdatain<="11111100"WHEN"0000",--计数转换成相应的数码显示信号"01100000"WHEN"0001","11011010"WHEN"0010","11110010"WHEN"0011","01100110"WHEN"0100","10110110"WHEN"0101","10111110"WHEN"0110","11100000"WHEN"0111","11111110"WHEN"1000","11110110"WHEN"1001","11101110"WHEN"1010","00111110"WHEN"1011","10011100"WHEN"1100","01111010"WHEN"1101","10011110"WHEN"1110","10001110"WHENOTHERS;ENDa;程序说明:动态扫描电路将计数器输出的8421BCD码转换为数码管所需的逻辑状态,并且输出数码管的片选信号和位选信号。所谓动态扫描显示方式就是利用了人眼的视觉暂留效应,把八个数码管按顺序进行点亮,当点亮的频率(即扫描频率)不大时,我们看到的是数码管一个个的点亮,然而,当点亮频率足够大时,我们看到的不再是一个一个的点亮,而是全部同时显示(点亮),与传统方式得到的视觉效果完全一样。因此我们只要给数码管这样一个扫描频率,那么就可以实现两个以上的数码管同时点亮。一般每位显示的时间为1~10ms。仿真结果及分析:扫描结果如图4-17所示,扫描周期为8,依次按顺序扫描8个数码管。仿真结果完全符合设计。25 第四章单元电路设计图4-17动态扫描4.5顶层模块用元件例化语句来写本设计的顶层文件。元件例化就是引入一种连接关系,将预先设计好的设计实体定义为一个元件,然后利用特定的语句将此元件与当前的设计实体中的指定端口相连接,从而为当前设计实体引入一个新的低一级的设计层次。在这里,当前设计实体相当于一个较大的电路系统,所定义的例化元件相当于一个要插在这个电路系统板上的芯片,而当前设计实体中指定的端口则相当于这块电路板上准备接受此芯片的一个插座。元件例化是使VHDL设计实体构成自上而下层次化设计的一种重要途径。元件例化语句由两部分组成,前一部分是对一个现成的设计实体定义为一个元件,第二部分则是此元件与当前设计实体中的连接说明。该模块VHDL程序:LIBRARYieee;USEieee.std_logic_1164.all;ENTITYprojectISPORT(clkin:INstd_logic;--脉冲输入resin:INstd_logic;--复位输入stain:INstd_logic;--启动暂停输入nigin:INstd_logic;--夜间行驶输入chout:OUTstd_logic_vector(7downto0);--显示位置选择daout:OUTstd_logic_vector(7downto0));--当前位置数值END;ARCHITECTUREoneOFprojectISCOMPONENTspeed--分频模块PORT(clk,start:INstd_logic;oclk1,oclk2:OUTstd_logic);25 第四章单元电路设计ENDCOMPONENT;COMPONENTcdu99--里程计数模块PORT(clk,reset:INstd_logic;count1:OUTstd_logic_vector(3downto0);count2:OUTstd_logic_vector(3downto0);count3:OUTstd_logic_vector(3downto0);count4:OUTstd_logic_vector(3downto0));ENDCOMPONENT;COMPONENTcount99--计费模块PORT(clk,reset,night:INstd_logic;judge2:INstd_logic_vector(3downto0);judge3:INstd_logic_vector(3downto0);count1:OUTstd_logic_vector(3downto0);count2:OUTstd_logic_vector(3downto0);count3:OUTstd_logic_vector(3downto0);count4:OUTstd_logic_vector(3downto0));ENDCOMPONENT;COMPONENTscan--动态扫描模块PORT(clk:INstd_logic;p8:INstd_logic_vector(3downto0);p7:INstd_logic_vector(3downto0);p6:INstd_logic_vector(3downto0);p5:INstd_logic_vector(3downto0);p4:INstd_logic_vector(3downto0);p3:INstd_logic_vector(3downto0);p2:INstd_logic_vector(3downto0);p1:INstd_logic_vector(3downto0);choice:OUTstd_logic_vector(7downto0);data:OUTstd_logic_vector(7downto0));ENDCOMPONENT;SIGNALclk10,clk100:std_logic;SIGNALcou1,cou2,cou3,cou4,cou11,cou22,cou33,cou44:std_logic_vector(3downto0);BEGINu1:speedPORTMAP(clk=>clkin,start=>stain,oclk1=>clk100,oclk2=>clk10);u2:cdu99PORTMAP(clk=>clk10,reset=>resin,count1=>cou1,count2=>cou2,count3=>cou3,count4=>cou4);u3:count99PORTMAP(clk=>clk100,reset=>resin,night=>nigin,judge2=>cou3,judge3=>cou4,count1=>cou11,count2=>cou22,count3=>cou33,count4=>cou44);u4:scanPORTMAP(clk=>clkin,p8=>cou4,p7=>cou3,p6=>cou2,25 第四章单元电路设计p5=>cou1,p4=>cou44,p3=>cou33,p2=>cou22,p1=>cou11,choice=>chout,data=>daout);END;25 结论结论出租车计费系统的设计已全部完成,能按预期的效果进行模拟汽车启动,停止,暂停的状态等功能,并设计动态扫描电路显示车费。车暂停不计费,车费保持不变。若停止则车费清零,等待下一次计费的开始。在出租车计费系统的5个模块中,重点在于里程计数模块、计费模块、动态扫描模块。里程计数模块和计费模块主要是把里程和车费转化为4位十进制;动态扫描模块是将里程和车费显示出来。各模块完成后,用顶层模块将它们组合成完整的出租车计费系统。在此次设计过程中,更进一步地熟悉了有关数字电路的知识和具体应用。学会了用VHDL硬件描述语言的编写程序以及QuartusII软件的使用。并能根据仿真结果来分析设计存在的问题及缺陷,从而能进行程序的调试和完善。总的来说,通过本次设计更进一步的增加了动手能力,对出租车计费系统的原理也有了更透彻的理解。本设计虽然能初步的实现预期效果,但在实际应用中仍存在一些不足。比如每公里的单价不能显示、计数里程范围不够大、时间不能显示、不能打印发票等。这些都需要在以后的学习中更进一步的进行完善。本设计采用硬件描述语言和FPGA芯片相结合,从中可以EDA技术的发展在一定程度上实现了硬件设计的软件化。体现了VHDL覆盖面广,描述能力强,使用方便、便于修改、是一个多层次的硬件描述语言等特点。相信随着电子技术的发展,出租车计费器的功能会更加的多样化,满足人们的各种需要。25 参考文献参考文献[1]潘松.VHDL实用教程[M].成都:电子科技大学出版社,2000.[2]江国强.EDA技术与应用[M].北京:电子工业出版社,2004.[3]董丽海.基于VHDL语言的出租车计费系统设计.《现代电子技术》.2000年第3期总第146期.[4]潘松,黄继业.EDA技术实用教程[M].(第三版).北京:科学出版社,2006.[5]何小艇.电子系统设计[M].(第三版).浙江:浙江大学出版社,2004[6]王振营,李满,杨君.ProtelDXP2004电路设计与制版实用教程[M]北京:中国铁道出版社,2006.[7]林愿.基于CPLD/FPGA的出租车计费器的设计实现[J].湖南工程学院,电气与信息工程系,2007.[8]王新,付子义.EDA技术与虚拟实验[M].江苏:中国矿业大学出版社,2007.[9]黄智伟.FPGA系统设计与实践[M].北京:电子工业出版社,2005.35 致谢致谢在本课题的整个研究设计过程中,我得到了很多老师和同学的帮助,借此机会向他们表达我最诚挚的谢意。首先,我要感谢的是我的导师喻嵘老师。在本次的毕业论文的研究设计中,喻老师给了我很多指导与帮助。当我们遇到问题时,喻老师总是能耐心的给我们讲解。在论文的整体设计和技术方案上,她还给了我很多建议,使我确立了论文的正确方向和设计思想,从而保证了整个课题的顺序完成。在此我向她表达我最真诚的谢意!其次,我要感谢学校给我提供了良好的环境,先进的实验设备和资源丰富的图书馆,使我能够顺利的完成此次毕业论文的设计。同时班上的同学也给了我很多建议和帮助。在此我也向他们表示感谢!最后,我要感谢电子系所有老师,是你们将自己宝贵的财富无私地奉献给了我们,让我们能在学业上有所成绩,是你们的谆谆教导让我们知道如何与人相处,是你们的帮助才能让我完成了学业!谢谢你们!35 附录附录LIBRARYieee;USEieee.std_logic_1164.all;ENTITYprojectISPORT(clkin:INstd_logic;--脉冲输入resin:INstd_logic;--复位输入stain:INstd_logic;--启动暂停输入nigin:INstd_logic;--夜间行驶输入chout:OUTstd_logic_vector(7downto0);--显示位置选择daout:OUTstd_logic_vector(7downto0));--当前位置数值END;ARCHITECTUREoneOFprojectISCOMPONENTspeed--分频模块PORT(clk,start:INstd_logic;oclk1,oclk2:OUTstd_logic);ENDCOMPONENT;COMPONENTcdu99--里程计数模块PORT(clk,reset:INstd_logic;count1:OUTstd_logic_vector(3downto0);count2:OUTstd_logic_vector(3downto0);count3:OUTstd_logic_vector(3downto0);count4:OUTstd_logic_vector(3downto0));ENDCOMPONENT;COMPONENTcount99--计费模块PORT(clk,reset,night:INstd_logic;judge2:INstd_logic_vector(3downto0);judge3:INstd_logic_vector(3downto0);count1:OUTstd_logic_vector(3downto0);count2:OUTstd_logic_vector(3downto0);count3:OUTstd_logic_vector(3downto0);35 附录count4:OUTstd_logic_vector(3downto0));ENDCOMPONENT;COMPONENTscan--动态扫描模块PORT(clk:INstd_logic;p8:INstd_logic_vector(3downto0);p7:INstd_logic_vector(3downto0);p6:INstd_logic_vector(3downto0);p5:INstd_logic_vector(3downto0);p4:INstd_logic_vector(3downto0);p3:INstd_logic_vector(3downto0);p2:INstd_logic_vector(3downto0);p1:INstd_logic_vector(3downto0);choice:OUTstd_logic_vector(7downto0);data:OUTstd_logic_vector(7downto0));ENDCOMPONENT;SIGNALclk10,clk100:std_logic;SIGNALcou1,cou2,cou3,cou4,cou11,cou22,cou33,cou44:std_logic_vector(3downto0);BEGINu1:speedPORTMAP(clk=>clkin,start=>stain,oclk1=>clk100,oclk2=>clk10);u2:cdu99PORTMAP(clk=>clk10,reset=>resin,count1=>cou1,count2=>cou2,count3=>cou3,count4=>cou4);u3:count99PORTMAP(clk=>clk100,reset=>resin,night=>nigin,judge2=>cou3,judge3=>cou4,count1=>cou11,count2=>cou22,count3=>cou33,count4=>cou44);u4:scanPORTMAP(clk=>clkin,p8=>cou4,p7=>cou3,p6=>cou2,p5=>cou1,p4=>cou44,p3=>cou33,p2=>cou22,p1=>cou11,choice=>chout,data=>daout);END;LIBRARYieee;USEieee.std_logic_1164.all;USEieee.std_logic_unsigned.all;35 附录USEieee.std_logic_arith.ALL;ENTITYspeedIS--实体取名speedPORT(--端口描述clk,start:INstd_logic;--clk车轮脉冲,start启动暂停开关oclk1,oclk2:OUTstd_logic--oclk1100m脉冲,oclk210m脉冲);ENDspeed;ARCHITECTUREbehaveOFspeedIS--结构体名称behaveSIGNALmode1:std_logic_vector(5downto0);--mode1,mode2为分频系数SIGNALmode2:std_logic_vector(5downto0);SIGNALtemp1:std_logic_vector(5downto0);--temp1,temp2为6位,记录计数值SIGNALtemp2:std_logic_vector(5downto0);BEGINmode1<="111100";--分频系数为60mode2<="000110";--分频系数为6PROCESS(start,clk)BEGINIFrising_edge(clk)THEN--若clk的上升沿来到,则IFstart="1"THEN--若有start=‘1’,则IFtemp1=(mode1)then--若temp=(mode1),则temp1<=(OTHERS=>"0");--temp1=“000000”ELSE--否则temp1<=temp1+"1";--加1计数ENDIF;IFtemp2=(mode2)thentemp2<=(OTHERS=>"0");ELSEtemp2<=temp2+"1";ENDIF;ENDIF;ENDIF;ENDPROCESS;oclk1<="1"WHEN(temp1=mode1)ELSE"0";--当temp1=mode1时oclk<=’1’35 附录,否则=0oclk2<="1"WHEN(temp2=mode2)ELSE"0";ENDbehave;LIBRARYieee;USEieee.std_logic_1164.all;USEieee.std_logic_unsigned.all;USEieee.std_logic_unsigned.all;ENTITYcdu99ISPORT(clk,reset:INstd_logic;--clk10m输入脉冲,reset复位count1:OUTstd_logic_vector(3downto0);--里程数值的百分位count2:OUTstd_logic_vector(3downto0);--里程数值的十分位count3:OUTstd_logic_vector(3downto0);--里程数值的个位count4:OUTstd_logic_vector(3downto0));--里程数值的十位ENDcdu99;ARCHITECTUREaaOFcdu99ISBEGINPROCESS(clk,reset)VARIABLEmm:std_logic_vector(15downto0);BEGINIFreset="1"THEN--复位时,显示为0mm:="0000000000000000";ELSIFclk"eventandclk="1"THENIFmm(3downto0)="1001"THEN--十六进制转换成十进制mm:=mm+7;ELSEmm:=mm+1;ENDIF;IFmm(7downto4)="1010"THENmm:=mm+"01100000";ENDIF;IFmm(11downto8)="1010"THENmm:=mm+"011000000000";ENDIF;ENDIF;count1<=mm(3downto0);count2<=mm(7downto4);count3<=mm(11downto8);count4<=mm(15downto12);35 附录ENDPROCESS;ENDaa;LIBRARYieee;USEieee.std_logic_1164.all;USEieee.std_logic_arith.all;USEieee.std_logic_unsigned.all;ENTITYcount99ISPORT(clk,reset,night:INstd_logic;--clk100m输入脉冲,reset复位,night夜间行驶输入judge2:INstd_logic_vector(3downto0);--里程个位judge3:INstd_logic_vector(3downto0);--里程十位count1:OUTstd_logic_vector(3downto0);--计费百分位count2:OUTstd_logic_vector(3downto0);--计费十分位count3:OUTstd_logic_vector(3downto0);--计费个位count4:OUTstd_logic_vector(3downto0));--计费十位ENDcount99;ARCHITECTUREaaOFcount99ISSIGNALen:std_logic;SIGNALmoney:std_logic_vector(7downto0);SIGNALmcount:std_logic_vector(15downto0);BEGINmoney<="00111000"WHEN(((mcount(15)="1")or(mcount(14)="1")or(mcount(13)="1"))and(night="1"))ELSE--夜间行驶且费用超过20,加0.38"00101001"WHEN((mcount(15)="1")or(mcount(14)="1")or(mcount(13)="1")or(night="1"))ELSE--费用超过20或者夜间行驶,加0.29"00011001";--计费20以内,加0.19en<="0"WHENjudge3="0000"andjudge2(3downto1)="000"ELSE"1";--里程超过2公里,接受100m输入脉冲驱动PROCESS(clk,reset)VARIABLEmm:std_logic_vector(15downto0);BEGINIFreset="1"THEN35 附录mm:="0000011000000000";--复位,计费显示为起步费6.00ELSIFclk"eventandclk="1"THENIFen="1"THENmm:=mm+money;--里程超过2公里IF(mm(1)="1"or(mm(3downto1)="000")or(mm(3downto2)="11"))THENmm:=mm+6;ENDIF;--十六进制转换成十进制IFmm(7)="1"and(not(mm(6downto5)="00"))THENmm:=mm+"01100000";ENDIF;IFmm(11)="1"and(not(mm(10downto9)="00"))THENmm:=mm+"011000000000";ENDIF;ENDIF;ENDIF;count1<=mm(3downto0);count2<=mm(7downto4);count3<=mm(11downto8);count4<=mm(15downto12);mcount<=mm;ENDPROCESS;ENDaa;LIBRARYieee;USEieee.std_logic_1164.all;USEieee.std_logic_unsigned.all;ENTITYscanISPORT(clk:INstd_logic;p8:INstd_logic_vector(3downto0);p7:INstd_logic_vector(3downto0);p6:INstd_logic_vector(3downto0);p5:INstd_logic_vector(3downto0);p4:INstd_logic_vector(3downto0);p3:INstd_logic_vector(3downto0);p2:INstd_logic_vector(3downto0);p1:INstd_logic_vector(3downto0);choice:OUTstd_logic_vector(7downto0);--显示位置选择35 附录data:OUTstd_logic_vector(7downto0));--当前位置数值ENDscan;ARCHITECTUREaOFscanISSIGNALcount:std_logic_vector(2downto0);SIGNALtemp:std_logic_vector(3downto0);SIGNALchoicein,datain:std_logic_vector(7downto0);BEGINclk1_label:PROCESS(clk)BEGINIFclk"eventandclk="1"THEN--计数周期为8,即扫描周期count<=count+1;ENDIF;ENDPROCESSclk1_label;clk2_label:PROCESS(clk)BEGINIFclk"eventandclk="0"THENchoice<=choicein;data(7downto1)<=datain(7downto1);IF(count="0110"orcount="0010")THENdata(0)<="1";ELSEdata(0)<="0";ENDIF;ENDIF;ENDPROCESSclk2_label;choicein<="00000001"WHENcount="000"ELSE--显示位置的切换"00000010"WHENcount="001"ELSE"00000100"WHENcount="010"ELSE"00001000"WHENcount="011"ELSE"00010000"WHENcount="100"ELSE"00100000"WHENcount="101"ELSE"01000000"WHENcount="110"ELSE"10000000";35 附录temp<=p1WHENcount="000"ELSE--显示数值的选择p2WHENcount="001"ELSEp3WHENcount="010"ELSEp4WHENcount="011"ELSEp5WHENcount="100"ELSEp6WHENcount="101"ELSEp7WHENcount="110"ELSEp8;WITHtempSELECTdatain<="11111100"WHEN"0000",--计数转换成相应的数码显示信号"01100000"WHEN"0001","11011010"WHEN"0010","11110010"WHEN"0011","01100110"WHEN"0100","10110110"WHEN"0101","10111110"WHEN"0110","11100000"WHEN"0111","11111110"WHEN"1000","11110110"WHEN"1001","11101110"WHEN"1010","00111110"WHEN"1011","10011100"WHEN"1100","01111010"WHEN"1101","10011110"WHEN"1110","10001110"WHENOTHERS;ENDa;35'