《基于verilog语言的出租车计费器.docx》由会员分享,可在线阅读,更多相关《基于verilog语言的出租车计费器.docx(16页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上基于verilog语言的出租车计费器 院别:_计算机与通信工程学院_专业名称:_电子信息工程_班级学号:_学生姓名:_指导教师:_陈海宴_随着出租车行业的发展,对出租车计费器的要求也越来越高。最近几年出租车行业发展迅速,在全国有几千家出租车公司。因此出租车计费器市场是庞大的。而出租车计费器成为不可缺少的一部分。信息社会的现代电子产品,性能越来越高,复杂度越来越大,更新步伐也越来越快。实现这种进步的主要原因就是微电子技术和电子技术的发展。而电子技术的发展后者的核心就是电子设计自动化技术。EDA是指以计算机为工作平台,融合了应用电子技术、计算机技术、智能化技术的最新成果而
2、开发出的电子CAD通用软件包,它根据硬件描述语言HDL完成的设计文件,自动完成逻辑编译、化简、分割、综合、优化、布局布线及仿真,直至完成对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。没有EDA技术的支持,想要完成超大规模集成电路的设计制造是不可想象的;反过来,生产制造技术的不断进步又必将对EDA技术提出新的要求。本文采用verilog语言来设计实现出租车计费系统,经过ModelSim和Quartus仿真将其实例化。如果将该设计再结合到实际应用中,那么,只需改变设计中计费要求,就可以应用到出租车上。另外,如果再任意输入该出租车计价器的计费标准,那么,它的适用范围可能就更广泛了。一、 设计
3、要求 (1) 行程3公里内(包括3公里),且等待累计时间2分钟内(包括2分钟),起步费为6.0元;(2)3公里外(不包括3公里)以每公里1.0元,等待累计时间2分钟外(不包括2分钟)以每分钟以1.0元计费。(3)能显示行驶公里数、等待累计时间和最后的总费用。本计费器的显示范围为099元,计价分辨率为1元;计程器显示范围为099公里,分辨率为1公里;计时器的显示范围是分钟的显示范围是099, 辨率为1分钟。秒的显示范围是059。分辨率为1秒。二 、工作原理 出租车的一般计费过程为:出租车载客后,启动计费器,整个系统开始运行,里程计数器和时间计数器从0开始计数,费用计数器从6开始计算。再根据行驶里
4、程或停止等待的时间按以上的标准计费。若在行驶状态,则计程器开始加计数,当路程超过三公里后,计费器以每公里1元累加。若出租车停止等待状态,则计时器开始加计数,当时间超过两分钟后,计费器以每分钟1元累加。出租车到达目的地停止后,停止计费器,显示总费用。根据出租车计费器的工作过程,本系统采用分层次、分模块的方式设计,其本系统组成框图如下所示。其中行驶路程计数模块、等待时间计数模块和计费模块,用来统计路程、等待时间和总费用,控制模块是用来控制计费模块,数码管显示模块用来显示行驶的公里数、等待累计时间和总费用等信息。系统框图如下所示:三、各模块的设计本系统采用层次化、模块化的设计方法,设计顺序为自下向上
5、。首先实现系统框图中的各子模块,然后由顶层模块调用各子模块来完成整个系统。为了便于显示,这里的路程、时间和费用计数器均用十六进制表示。3.1分频模块:3.1.1计数器的分频模块:计数器的分频模块具体框图: 此模块的功能是对总的时钟进行分频,分出的频率是让计数器用的,因为总的时钟是50M的。设计该模块的时候用了一个32位的计数器,当计数器计到25_的时候产生时钟。在仿真的时候为了方便观察设计了一个8分频的电路。当下载的时候用的是2HZ的时钟 。计数器的分频模块VerilogHDL源代码:module div(clk_50M,clk,reset);/ 端口的定义input clk_50M,rese
6、t;/ 总的时钟是50Moutput clk;/分频后输的时钟 reg clk;reg 31:0 count;/32位的计数器always (posedge clk_50M or negedge reset)/异步复位begin if(!reset) begin clk=d0; count=32d0;endelse if(count=32d25_)/ 判断计时器记到了25_吗 begin count=32d0;/计到25_计数器清零 clk=clk;/输出的时钟取反 end/end begin else count=count+1d1;/ 没计到25_计数器加一end/end alwaysen
7、dmodule / 结束分频模块仿真的结果: 从波形可以看出当reset为低电平的时候clk为零,当为高电平的时候clk的高电平占了clk_50M的八个周期,低电平也占了clk_50M的八个周期。3.1 .2数码管的分频模块:具体框图: 此模块的功能是对总的时钟进行分频,分出的频率是让数码管用的,因为总的时钟是50M的。设计该模块的时候用了一个32位的计数器,当计数器计到50_000的时候产生时钟。在仿真的时候为了方便观察设计了一个8分频的电路。数码管的分频模块VerilogHDL源代码:module div1(clk_50M,clk1,reset);/ 端口的定义input clk_50M,
8、reset;/ 总的时钟是50Moutput clk1;/分频后输的时钟 reg clk1;reg 31:0 count;/32位的计数器always (posedge clk_50M or negedge reset)/异步复位begin if(!reset) begin clk1=d0; count=32d0;endelse if(count=32d50_000)/ 判断计时器记到了50_000吗 begin count=32d0;/计到50_000计数器清零 clk1=clk1;/输出的时钟取反 end/end begin else count=count+1d1;/ 没计到50_000
9、计数器加一end/end alwaysendmodule / 结束分频模块3.2 计程模块:计程模块的框图:此模块的功能是计算出租车行驶的路程。在出租车启动并行驶的过程中(即复位/启动信号reset为1,行驶/停止信号start为1),当时钟clk是上升沿的时候,系统即对路程计数器distance的里程计数器进行加计数,当路程超过三公里时,系统将输出标志正脉冲distance_enable。计程模块的VerilogHDL源代码:module distancemokuai(clk,start,reset,distance,distance_enable);/端口的定义input clk,star
10、t,reset;output 7:0 distance;/ 输出的公里reg 7:0 distance;output distance_enable;/ 控制计费的公里信号reg distance_enable;always(posedge clk or negedge reset)/异步复位begin if(!reset)/低电平复位 begin distance=8d0; end else if(start)/ start 高电平有效 begin if(distance3:0=9)/判断distance的低四位计到了9没有 begin distance3:0=4d0;/计到9清零 if(d
11、istance7:4=9) /判断distance的高四位计到了9没有 distance7:4=4d0;/计到9清零 else distance7:4= distance7:4+1d1;/ distance的高四位没有计到9的时候加一 end else distance3:0=distance3:0+1d1;/ distance的低四位没有计到9的时候加一 end/end startend/end always/*产生distance_enable信号*/always(posedge clk or negedge reset)beginif(!reset)begin distance_enab
12、le8d2)/ 大于公里三的时候 begin distance_enable=1d1;/输出distance_enable信号 endend/end alwaysendmodule/结束计程模块计程模块的仿真结果:从波形图可以看出在时钟的控制下,当reset为高电平且start为高电平的时候distance开始计数,当计到大于三的时候输出了distancedistance_enable为高电平。3.3计时模块:计时模块的框图:此模块用于计算停车等待的时间。在出租车行进中,如果车辆停止等待,计数器则在1Hz信号clk的上升沿进行加计数,每60次产生进位脉冲使分钟计数器位进行加计数,当累计等待时间
13、超过2(不包括2分钟)分钟时,输出标志time_enable正脉冲信号。计时模块的VerilogHDL源代码:module timemokuai(clk,reset,start,s,m,time_enable);/ 端口的定义input clk,reset,start;output 7:0 s;/输出的秒output 7:0 m;/输出的分output time_enable;/输出的控制计费的信号reg 7:0 s;reg 7:0 m;wire time_enable; always(posedge clk or negedge reset)/异步复位beginif(!reset)/低电平有
14、效begin /复位s=8d0;m=8d0;endelse if(!start)/start 信号低电平有效beginif(s3:0=9)/ 秒的低四位是9 begin s3:0=4d0;/清零 if(s7:4=5) / 秒的高四位是5 begin s7:4=4d0; /清零 if(m3:0=9) / 分的低四位是9 begin m3:0=4d0; /清零 if(m7:4=9) / 分的高四位是9 m7:4=4d0; /清零 else m7:4=m7:4+1d1; / 分的高四位不是9加一endelse m3:0=m3:0+1d1; /分的低四位不是9加一endelse s7:4=s7:4+1
15、d1; / 秒的高四位不是5加一endelse s3:08d2)&(s7:0=8d0)?1d1:1d0;/产生time_enable信号。endmodule/结束计时模块计时模块的仿真结果:两分钟之内(包括两分钟)的仿真结果如下所示:从波形图可以看出在clk的控制下当start为低电平reset为高电平的时候时间计数,time_enable为低电平。两分钟之外(不包括两分钟)的仿真结果如下所示:从波形图可以看出在clk的控制下当start为低电平reset为高电平的时候时间计数,当时间大于二分钟的时候,time_enable为输出高电平。3.4控制模块:控制模块的框图:控制模块用于为计费模块提
16、供时钟,当start高电平的时候选择公里计费,输出的时钟信号为distance_enable,当start低电平的时候选择时间计费,输出的时钟信号为time_enable,控制模块的VerilogHDL源代码:module control(start,distance_enable,time_enable,select_clk);input start,distance_enable,time_enable;output select_clk;/输出选择的时钟信号wire select_clk;/*当start高电平的时候选择公里计费,输出的时钟信号为distance_enable,当star
17、t低电平的时候选择时间计费,输出的时钟信号为time_enable*/assign select_clk=start?distance_enable:time_enable; endmodule/结束控制模块控制模块的仿真结果:(1)公里计费的仿真结果如下所示:从波形图可以看出当start为高电平的时候输出的信号是distance_enable。(2)时间计费的仿真结果如下所示:从波形图可以看出当start为低电平的时候输出的信号是time_enable。3.5 计费模块:计费模块的框图:费用计数器模块用于出租车启动后,根据行驶路程和等待时间计算费用。当出租车停车时,时钟select_clk用
18、于将费用计数器复位为起步价6.0元;当车处于行驶状态且满3公里时,select_clk信号选择distans_enable,此后路程每满1公里,费用计数器加1元;当出租车处于停止等待状态且时钟满2分钟时,select_clk信号选择time_enable信号,时间每满1分钟,费用计数器加1元。 计费模块的VerilogHDL源代码如下所示:module feemokuai(select_clk,reset,fee,clk);input select_clk,reset,clk;output7:0 fee; /输出的费用reg 7:0 fee;always(posedge clk or nege
19、dge reset)/异步复位begin if(!reset)/低电平有效 begin fee=8d6;/起步为六元 end else if(select_clk=1d1) begin if(fee3:0=4d9)/费用的低四位是不是计到了9 begin fee3:0=4d0;/计到9清零 if(fee7:4=4d9)/ 费用的高四位是不是计到了9fee7:4=4d0; /计到9清零 else fee7:4=fee7:4+1d1;/ 费用的高四位没有计到9加1endelse fee3:0=fee3:0+1d1;/ 费用的低四位没有计到9加1end/end beginend/end always
20、endmodule /结束计费模块计费模块的仿真结果:3.6 数码管显示模块:3.6.1 数码管显示模块的框图:数码管有两种显示方式动态显示与静态显示,由于在本文中用到了八个数码管所以选择了动态显示,在时钟的控制下,当reset为高电平的时候把费用,公里,时间译码输出。3.6.2 数码管显示的VerilogHDL源代码:module scan_led(clk1,dig,seg,distance,s,m,fee);input clk1;input7:0 distance,fee;/输入的公里,费用。input7:0 s;/输入的秒input7:0 m; / 输入的分。output7:0 dig;
21、 / 译码结果output7:0 seg; / 数码管的选择。reg 7:0 r_dig;/ 译码结果输出寄存器reg 7:0 r_seg; /数码管的选择寄存器。reg 3:0 disp_dat;reg3:0 a;assign dig=r_dig;assign seg=r_seg;always(posedge clk1)begin a=a+1d1; /数码管的选择endalways(posedge clk1)begincase(a) 4d0: disp_dat=distance7:4;/公里的高四位用第一个数码管显示。4d1: disp_dat=distance3:0;/公里的低四位用第二个
22、数码管显示。4d2: disp_dat=m7:4; /时间分的高四位用第三个数码管显示。4d3: disp_dat=m3:0; /时间分的低四位用第四个数码管显示4d4: disp_dat=s7:4; /时间秒的高四位用第五个数码管显示。4d5: disp_dat=s3:0; /时间秒的低四位用第六个数码管显示。4d6: disp_dat=fee7:4;/费用的高四位用第七个数码管显示。4d7: disp_dat=fee3:0; /费用的低四位用第八个数码管显示。default: disp_dat=4b1010;endcasecase(a)4d0:r_dig=8b; / 选择第一个数码管4d1
23、:r_dig=8b; / 选择第二个数码管4d2:r_dig=8b; / 选择第三个数码管4d3:r_dig=8b; / 选择第四个数码管4d4:r_dig=8b; / 选择第五个数码管4d5:r_dig=8b; / 选择第六个数码管4d6:r_dig=8b; / 选择第七个数码管4d7:r_dig=8b; / 选择第八个数码管default:r_dig=8b;endcaseend/ *译码结果*/always(disp_dat)begin case(disp_dat) 4h0: r_seg=8hc0;/ 显示0 4h1: r_seg=8hf9;/ 显示1 4h2: r_seg=8ha4;/
24、显示2 4h3: r_seg=8hb0;/ 显示3 4h4: r_seg=8h99;/ 显示4 4h5: r_seg=8h92;/ 显示5 4h6: r_seg=8h82;/ 显示6 4h7: r_seg=8hf8;/ 显示7 4h8: r_seg=8h80;/ 显示8 4h9: r_seg=8h90;/ 显示9 default: r_seg=8hbf;endcaseendendmodule/结束译码模块3.7 顶层模块:各模块设计仿真实现后,可分别创建成元件符号。顶层就是将各分模块用Verilog HDL语言或者是图形方法连接起来,便可实现系统电路。3.7.1 顶层模块的VerilogHDL
25、源代码:module taximeter(clk_50M,reset,start,seg,dig);/端口的定义input clk_50M,reset,start;/总的时钟信号,复位信号,开始信号output7:0 seg,dig;/数码管的输出wire 7:0distance;/公里wire 7:0 s;/秒wire 7:0 m;/分wire7:0 fee;/费用wire clk; /计数时钟wire distance_enable;/公里控制费用的信号wire time_enable; /时间控制费用的信号wire select_clk; /控制信号wire clk1; /数码管显示的时
26、钟/*模块的调用*/div u0(.clk_50M(clk_50M),.clk(clk),.reset(reset);/调用计数分频模块div1 u1(.clk_50M(clk_50M),.clk1(clk1),.reset(reset);/调用数码管显示分频模块Distancemokuai u2(.clk(clk),.start(start),.reset(reset),.distance(distance),.distance_enable(distance_enable); /调用计程模块timemokuai u4(.clk(clk),.reset(reset),.start(start
27、),.s(s),.m(m),.time_enable(time_enable); /调用计时模块control u3(.start(start),.distance_enable(distance_enable),.time_enable(time_enable),.select_clk(select_clk); /调用控制模块feemokuai u5(.reset(reset),.fee(fee),.select_clk(select_clk),.clk(clk); /调用计费模块scan_led U6(.clk1(clk1),.dig(dig),.seg(seg),.distance(di
28、stance),.s(s),.m(m),.fee(fee);/调用数码管显示模块endmodule/结束顶层模块四、测试部分 测试VerilogHDL源代码:timescale 1ns/100ps/时间的单位与时间的精度module taximeter_tb;/验证的模块名字reg clk_50M,reset,start;/输入wire7:0 distance;/输出的公里wire 7:0 s;/输出的秒wire 7:0 m;/输出的分wire 7:0 fee;/输出的费用always #10 clk_50M=clk_50M;/时钟的周期是20nsinitial /激励设定begin rese
29、t=0; clk_50M=0; #1000 reset=1; start=1; #10000 start=0; # $finish;/结束仿真end initial/实施监控 begin $monitor($time,clk_50M=%d,reset=%d,start=%d,distance=%d,s=%d, fee=%d,m=%d,n ,clk_50M,reset,start,distance,s,m,fee); end /调用被测试的模块/div u0(.clk_50M(clk_50M),.clk(clk),.reset(reset); /调用计数分频模块div1 u1(.clk_50M(
30、clk_50M),.clk1(clk1),.reset(reset); /调用数码管分频模块distancemokuai u2(.clk(clk),.start(start),.reset(reset),.distance(distance),.distance_enable(distance_enable); /调用计程模块timemokuai u4(.clk(clk),.reset(reset),.start(start),.s(s),.m(m),.time_enable(time_enable); /调用计时模块control u3(.start(start),.distance_ena
31、ble(distance_enable),.time_enable(time_enable),.select_clk(select_clk); /调用控制模块Feemokuai u5(.reset(reset),.fee(fee),.select_clk(select_clk),.clk(clk);/调用计费模块endmodule/结束测试模块系统仿真:初步设计完成后,即可将分模块和顶层模块进行仿真测试,同时可根据设计要求加入测试输入条件。仿真后得到的相应输出结果如与预先的结果不相符,则应修改设计,直到相符为止。没有译码的仿真结果如下所示: (a)为行驶中未停时的系统电路仿真结果:(b)为行驶
32、中停止时(在两分钟之内)的系统电路仿真结果:(c)为行驶中停止时(在两分钟之外)的系统电路仿真结果:从(a)可以看出当reset为1时,费用计数器为6元,系统启动,start=1表示出租车行驶, distance_enable每产生一个脉冲,路程计数器加1;路程3公里内,费用保持6不变,超过3公里,费用计数器进行加计数,每增加1公里费用加1元,此时等待时间计数器不变。而根据 (b) ,(c)的仿真波形可知,当reset为1时,系统启动,start=0表示出租车处于停止等待状态,此时等待时间计数器计数,在2分钟等待时间内,费用计数器不变;等待时间超过2分钟后,每增加1分钟,费用计数器增加1元,此时路程计数器保持不变。专心-专注-专业