基于verilog语言的出租车计费器Word文件下载.docx
《基于verilog语言的出租车计费器Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于verilog语言的出租车计费器Word文件下载.docx(16页珍藏版)》请在冰点文库上搜索。
![基于verilog语言的出租车计费器Word文件下载.docx](https://file1.bingdoc.com/fileroot1/2023-5/11/281bacf3-8de5-4150-8928-94e4cb73a456/281bacf3-8de5-4150-8928-94e4cb73a4561.gif)
本系统采用层次化、模块化的设计方法,设计顺序为自下向上。
首先实现系统框图中的各子模块,然后由顶层模块调用各子模块来完成整个系统。
为了便于显示,这里的路程、时间和费用计数器均用十六进制表示。
3.1分频模块:
3.1.1计数器的分频模块:
计数器的分频模块具体框图:
此模块的功能是对总的时钟进行分频,分出的频率是让计数器用的,因为总的时钟是50M的。
设计该模块的时候用了一个32位的计数器,当计数器计到25_000000的时候产生时钟。
在仿真的时候为了方便观察设计了一个8分频的电路。
当下载的时候用的是2HZ的时钟。
计数器的分频模块VerilogHDL源代码:
modulediv(clk_50M,clk,reset);
//端口的定义
inputclk_50M,reset;
//总的时钟是50M
outputclk;
//分频后输的时钟
regclk;
reg[31:
0]count;
//32位的计数器
always@(posedgeclk_50Mornegedgereset)//异步复位
begin
if(!
reset)
begin
clk<
='
d0;
count=32'
end
elseif(count==32'
d25_000000)//判断计时器记到了25_000000吗
count<
=32'
//计到25_000000计数器清零
=~clk;
//输出的时钟取反
end//endbegin
elsecount<
=count+1'
d1;
//没计到25_000000计数器加一
end//endalways
endmodule//结束分频模块
仿真的结果:
从波形可以看出当reset为低电平的时候clk为零,当为高电平的时候clk的高电平占了clk_50M的八个周期,低电平也占了clk_50M的八个周期。
3.1.2数码管的分频模块:
具体框图:
此模块的功能是对总的时钟进行分频,分出的频率是让数码管用的,因为总的时钟是50M的。
设计该模块的时候用了一个32位的计数器,当计数器计到50_000的时候产生时钟。
数码管的分频模块VerilogHDL源代码:
modulediv1(clk_50M,clk1,reset);
outputclk1;
regclk1;
clk1<
d50_000)//判断计时器记到了50_000吗
//计到50_000计数器清零
=~clk1;
//没计到50_000计数器加一
3.2计程模块:
计程模块的框图:
此模块的功能是计算出租车行驶的路程。
在出租车启动并行驶的过程中(即复位/启动信号reset为1,行驶/停止信号start为1),当时钟clk是上升沿的时候,系统即对路程计数器distance的里程计数器进行加计数,当路程超过三公里时,系统将输出标志正脉冲distance_enable。
计程模块的VerilogHDL源代码:
moduledistancemokuai(clk,start,reset,distance,distance_enable);
//端口的定义
inputclk,start,reset;
output[7:
0]distance;
//输出的公里
reg[7:
outputdistance_enable;
//控制计费的公里信号
regdistance_enable;
always@(posedgeclkornegedgereset)//异步复位
reset)//低电平复位
distance<
=8'
end
elseif(start)//start高电平有效
if(distance[3:
0]==9)//判断distance的低四位计到了9没有
begin
distance[3:
0]<
=4'
//计到9清零
if(distance[7:
4]==9)//判断distance的高四位计到了9没有
distance[7:
4]<
elsedistance[7:
=distance[7:
4]+1'
//distance的高四位没有计到9的时候加一
end
elsedistance[3:
=distance[3:
0]+1'
//distance的低四位没有计到9的时候加一
end//endstart
//*产生distance_enable信号*//
always@(posedgeclkornegedgereset)
if(!
distance_enable<
=1'
//复位
else
if(distance>
8'
d2)//大于公里三的时候
distance_enable<
//输出distance_enable信号
endmodule//结束计程模块
计程模块的仿真结果:
从波形图可以看出在时钟的控制下,当reset为高电平且start为高电平的时候distance开始计数,当计到大于三的时候输出了distancedistance_enable为高电平。
3.3计时模块:
计时模块的框图:
此模块用于计算停车等待的时间。
在出租车行进中,如果车辆停止等待,计数器则在1Hz信号clk的上升沿进行加计数,每60次产生进位脉冲使分钟计数器位进行加计数,当累计等待时间超过2(不包括2分钟)分钟时,输出标志time_enable正脉冲信号。
计时模块的VerilogHDL源代码:
moduletimemokuai(clk,reset,start,s,m,time_enable);
inputclk,reset,start;
0]s;
//输出的秒
0]m;
//输出的分
outputtime_enable;
//输出的控制计费的信号
wiretime_enable;
reset)//低电平有效
begin//复位
s<
m<
elseif(!
start)//start信号低电平有效
if(s[3:
0]==9)//秒的低四位是9
begin
s[3:
//清零
if(s[7:
4]==5)//秒的高四位是5
s[7:
//清零
if(m[3:
0]==9)//分的低四位是9
begin
m[3:
if(m[7:
4]==9)//分的高四位是9
m[7:
elsem[7:
=m[7:
//分的高四位不是9加一
elsem[3:
=m[3:
//分的低四位不是9加一
elses[7:
=s[7:
//秒的高四位不是5加一
elses[3:
=s[3:
//秒的低四位不是9加一
end//endalways
assigntime_enable=((m[7:
0]>
d2)&
&
(s[7:
0]==8'
d0))?
1'
d1:
//产生time_enable信号。
endmodule//结束计时模块
计时模块的仿真结果:
两分钟之内(包括两分钟)的仿真结果如下所示:
从波形图可以看出在clk的控制下当start为低电平reset为高电平的时候时间计数,time_enable为低电平。
两分钟之外(不包括两分钟)的仿真结果如下所示:
从波形图可以看出在clk的控制下当start为低电平reset为高电平的时候时间计数,当时间大于二分钟的时候,time_enable为输出高电平。
3.4控制模块:
控制模块的框图:
控制模块用于为计费模块提供时钟,当start高电平的时候选择公里计费,输出的时钟信号为distance_enable,当start低电平的时候选择时间计费,输出的时钟信号为time_enable,
控制模块的VerilogHDL源代码:
modulecontrol(start,distance_enable,time_enable,select_clk);
inputstart,distance_enable,time_enable;
outputselect_clk;
//输出选择的时钟信号
wireselect_clk;
//*当start高电平的时候选择公里计费,输出的时钟信号
为distance_enable,当start低电平的时候选择时间计费,输出的时钟信号为time_enable*//
assignselect_clk=start?
distance_enable:
time_enable;
endmodule//结束控制模块
控制模块的仿真结果:
(1)公里计费的仿真结果如下所示:
从波形图可以看出当start为高电平的时候输出的信号是distance_enable。
(2)时间计费的仿真结果如下所示:
从波形图可以看出当start为低电平的时候输出的信号是time_enable。
3.5计费模块:
计费模块的框图:
费用计数器模块用于出租车启动后,根据行驶路程和等待时间计算费用。
当出租车停车时,时钟select_clk用于将费用计数器复位为起步价6.0元;
当车处于行驶状态且满3公里时,select_clk信号选择distans_enable,此后路程每满1公里,费用计数器加1元;
当出租车处于停止等待状态且时钟满2分钟时,select_clk信号选择time_enable信号,时间每满1分钟,费用计数器加1元。
计费模块的VerilogHDL源代码如下所示:
modulefeemokuai(select_clk,reset,fee,clk);
inputselect_clk,reset,clk;
output[7:
0]fee;
//输出的费用
fee<
=8’d6;
//起步为六元
elseif(select_clk==1’d1)
if(fee[3:
0]==4'
d9)//费用的低四位是不是计到了9
fee[3:
if(fee[7:
4]==4'
d9)//费用的高四位是不是计到了9
fee[7:
//计到9清零
elsefee[7:
=fee[7:
//费用的高四位没有计到9加1
elsefee[3:
=fee[3:
//费用的低四位没有计到9加1
end//endbegin
endmodule//结束计费模块
计费模块的仿真结果:
3.6数码管显示模块:
3.6.1数码管显示模块的框图:
数码管有两种显示方式动态显示与静态显示,由于在本文中用到了八个数码管所以选择了动态显示,在时钟的控制下,当reset为高电平的时候把费用,公里,时间译码输出。
3.6.2数码管显示的VerilogHDL源代码:
modulescan_led(clk1,dig,seg,distance,s,m,fee);
inputclk1;
input[7:
0]distance,fee;
//输入的公里,费用。
0]s;
//输入的秒
0]m;
//输入的分。
0]dig;
//译码结果
0]seg;
//数码管的选择。
0]r_dig;
//译码结果输出寄存器
0]r_seg;
//数码管的选择寄存器。
reg[3:
0]disp_dat;
reg[3:
0]a;
assigndig=r_dig;
assignseg=r_seg;
always@(posedgeclk1)
a<
=a+1'
//数码管的选择
case(a)
4'
d0:
disp_dat=distance[7:
4];
//公里的高四位用第一个数码管显示。
disp_dat=distance[3:
0];
//公里的低四位用第二个数码管显示。
d2:
disp_dat=m[7:
//时间分的高四位用第三个数码管显示。
d3:
disp_dat=m[3:
//时间分的低四位用第四个数码管显示
d4:
disp_dat=s[7:
//时间秒的高四位用第五个数码管显示。
d5:
disp_dat=s[3:
//时间秒的低四位用第六个数码管显示。
d6:
disp_dat=fee[7:
//费用的高四位用第七个数码管显示。
d7:
disp_dat=fee[3:
//费用的低四位用第八个数码管显示。
default:
disp_dat=4'
b1010;
endcase
case(a)
r_dig=8'
b01111111;
//选择第一个数码管
b10111111;
//选择第二个数码管
b11011111;
//选择第三个数码管
b11101111;
//选择第四个数码管
b11110111;
//选择第五个数码管
b11111011;
//选择第六个数码管
b11111101;
//选择第七个数码管
b11111110;
//选择第八个数码管
b11111111;
//*译码结果*//
always@(disp_dat)
case(disp_dat)
4'
h0:
r_seg=8'
hc0;
//显示0
h1:
hf9;
//显示1
h2:
ha4;
//显示2
h3:
hb0;
//显示3
h4:
h99;
//显示4
h5:
h92;
//显示5
h6:
h82;
//显示6
h7:
hf8;
//显示7
h8:
h80;
//显示8
h9:
h90;
//显示9
default:
hbf;
endmodule//结束译码模块
3.7顶层模块:
各模块设计仿真实现后,可分别创建成元件符号。
顶层就是将各分模块用VerilogHDL语言或者是图形方法连接起来,便可实现系统电路。
3.7.1顶层模块的VerilogHDL源代码:
moduletaximeter(clk_50M,reset,start,seg,dig);
inputclk_50M,reset,start;
//总的时钟信号,复位信号,开始信号
0]seg,dig;
//数码管的输出
wire[7:
0]distance;
//公里
//秒
//分
wire[7:
//费用
wireclk;
//计数时钟
wiredistance_enable;
//公里控制费用的信号
//时间控制费用的信号
wireselect_clk;
//控制信号
wireclk1;
//数码管显示的时钟
//*模块的调用*//
divu0(.clk_50M(clk_50M),.clk(clk),.reset(reset));
//调用计数分频模块
div1u1(.clk_50M(clk_50M),.clk1(clk1),.reset(reset));
//调用数码管显示分频模块
Distancemokuaiu2(.clk(clk),.start(start),.reset(reset),
.distance(distance),.distance_enable(distance_enable));
//调用计程模块
timemokuaiu4(.clk(clk),.reset(reset),.start(start),.s(s),.m(m),
.time_enable(time_enable));
//调用计时模块
controlu3(.start(start),.distance_enable(distance_enable),
.time_enable(time_enable),.select_clk(select_clk));
//调用控制模块
feemokuaiu5(.reset(reset),.fee(fee),.select_clk(select_clk),
.clk(clk));
//调用计费模块
scan_ledU6(.clk1(clk1),.dig(dig),.seg(seg),.distance(distance),
.s(s),.m(m),.fee(fee));
//调用数码管显示模块
endmodule//结束顶层模块
四、测试部分
测试VerilogHDL源代码:
`timescale1ns/100ps//时间的