基于FPGA的出租车计价器设计(Verilog、basys3、含数码管模块、EDA设计与实践课程)

版权声明:本文为博主原创文章,转载请注明作者和出处。

文章目录

  • 前言
  • 一、系统功能及设计要求
    • 1.系统功能
    • 2.设计要求
  • 二、系统设计方案、Verilog源程序与仿真结果分析
    • 1.计数分频模块div
    • 2.计程模块distancecount
    • 3.计时模块timecount
    • 4.控制模块control
    • 5.计费模块fee
    • 6.数码管显像模块smg_ip_model
    • 7.顶层模块taximeter
  • 三、约束与综合
    • 1.原理图
    • 2.引脚配置图
  • 四、系统硬件测试
  • 总结


前言

本文章是总结EDA设计与实践课程的成果,设计题目为出租车计价器


以下是本篇文章正文内容

一、系统功能及设计要求

1.系统功能

出租车启动和停驶由司机控制。启动后显示里程,用四位数字显示,精确到1公里;停止后显示金额,四位显示,格式为XXXX,精确到1元。
功能
1、当行程小于基本里程时,显示起步价,基本里程设3公里,起步价设5元。
2、当行程大于基本里程时,每多行一公里,在起步价上加2元;不足一公里按一公里收费。
3、当出租车等待时,由司机按下等候键,每等待一分钟加1元,不足一分钟的按一分钟计算。
4、此处用脉冲信号模拟轮胎的转数,设每计一个脉冲汽车前进100米。

2.设计要求

系统设计一个频率为1Hz的基本脉冲,该脉冲用于等待计时和轮胎转数。
一个该脉冲表征1s;用于计轮胎转数时,计10个记为1公里。用于等待计时时,计60个记为1分钟。
设计拨动开关A 用于控制和表征模拟出租车的钥匙(插入钥匙和拔出钥匙)。
拨动开关B 用于控制和表征模拟客人的上下车行为(预备上车和即将下车)。
拨动开关C 用于控制和表征模拟出租车行驶状态(行驶或等待)。
一个四位七段数码管用于分时分状态表示里程数或总计价。

二、系统设计方案、Verilog源程序与仿真结果分析

本系统采用层次化、模块化的设计方法,设计顺序为自下向上。首先实现系统框图中的各子模块,然后由顶层模块调用各子模块来完成整个系统。

1.计数分频模块div

输入:基准时钟100MHz,频率信号CLK_100M,重置信号reset
输出:1Hz频率时钟信号CLK
module div(input clk_100M,input reset,output reg clk);reg [31:0] count;always@(posedge clk_100M , negedge reset)beginif(!reset)beginclk<=1'd0;count=32'd0;endelse if(count==32'd50_000000)begincount<=32'd0;clk<=!clk;endelsecount<=count+1'd1;end         
endmodule

clk_100M为主频,当reset为1时,div模块工作,此处为了仿真采取六分频,clk_100M触发6个周期,clk输出1个周期。
在这里插入图片描述

2.计程模块distancecount

输入:1HZ频率时钟信号CLK,模块使能信号work,计程开始信号start,计程重置信号reset
输出:16位二进制里程计数值distance,里程使能输出distance_enable
module distanceCount(input clk,input work,input start,input reset,output reg [15:0] distance,output reg distance_enable);  always@(posedge clk or negedge reset)beginif(!reset)begindistance<=16'd0;endelse if(start&&work)beginif(distance[3:0]==9)begindistance[3:0]<=4'd0;if(distance[7:4]==9)begindistance[7:4]<=4'd0;if(distance[11:8]==9)begindistance[11:8]<=4'd0;if(distance[15:12]==9)distance[15:12]<=4'd0;elsedistance[15:12]<=distance[15:12]+1'd1;end        else    distance[11:8]<=distance[11:8]+1'd1;end            elsedistance[7:4]<=distance[7:4]+1'd1;endelsedistance[3:0]<=distance[3:0]+1'd1;endend//产生distance_enable信号always@(posedge clk or negedge reset)beginif(!reset)begindistance_enable<=1'd0;endelseif(distance>=16'd2)begindistance_enable<=1'd1;endend                                     
endmodule

当reset为1时,distancecount模块工作。当work为0时,车无顾客,不论start为0还是为1,即不论此时车停止还是行驶,distance里程均为0,distance_enable也为0;当work为1时,车有顾客,start为0时车停止,distance里程不增即为0,start为1时车行驶,distance里程增加;当distance大于3公里时,distance_enable为1,代表此时里程增加就要计费。
在这里插入图片描述

3.计时模块timecount

输入:1HZ频率时钟信号CLK,计时开始信号start,计时重置信号reset
输出:8位二进制计时秒输出s,8位二进制计时分输出m,计时使能输出time_enable
module timeCount(input clk,input reset,input start,output reg [7:0] s,output reg [7:0] m,output wire time_enable);always@(posedge clk or negedge reset)beginif(!reset)begins<=8'd0;m<=8'd0;endelse if(!start)beginif(s[3:0]==9)begins[3:0]<=4'd0;if(s[7:4]==5)begins[7:4]<=4'd0;if(m[3:0]==9)beginm[3:0]<=4'd0;if(m[7:4]==5)m[7:4]<=4'd0;elsem[7:4]<=m[7:4]+1'd1;endelsem[3:0]<=m[3:0]+1'd1;endelses[7:4]<=s[7:4]+1'd1;endelses[3:0]<=s[3:0]+1'd1;endendassign time_enable=((m[7:0]>=8'd1)&&(s[7:0]==8'd0))?1'd1:1'd0;
endmodule

当reset为1时,timecount模块工作。Start为1时,不计算等待时间。当start为0时,计算等待时间。每过一秒,s增加1,当s计到60时清零,m进1,同时time_enable产生一个脉冲,代表一分钟增一次等待费用。
在这里插入图片描述
在这里插入图片描述

4.控制模块control

输入:控制开始信号start,计程使能信号distance_enable,计时使能信号time_enable
输出:选择脉冲信号select_clk
module control(input start,input distance_enable,input time_enable,output wire select_clk);assign select_clk=start?distance_enable:time_enable;
endmodule

当start为0时,select_clk的值为time_enable的值;当start为1时,select_clk的值为distance_enable的值。
在这里插入图片描述

5.计费模块fee

输入:计费工作信号work,计费使能信号start,选择脉冲信号select_clk,计费重置信号reset,1HZ频率时钟工作信号CLK
输出:16位二进制费用输出fee
module fee(input work,input start,input select_clk,input reset,input clk,output reg [15:0] fee);reg [3:0]cnt=0;always@(posedge clk or negedge reset or negedge work)beginif(!reset&&!work)fee<=16'd5;else if(select_clk==1'd1&&start==0&&work==1)beginif(fee[3:0]==4'd9)beginfee[3:0]<=4'd0;if(fee[7:4]==4'd9)beginfee[7:4]<=4'd0;if(fee[11:8]==4'd9)beginfee[11:8]<=4'd0;if(fee[15:12]==4'd9)fee[15:12]<=4'd0;elsefee[15:12]<=fee[15:12]+1'd1;endelsefee[11:8]<=fee[11:8]+1'd1;endelse fee[7:4]<=fee[7:4]+1'd1;endelse fee[3:0]<=fee[3:0]+1'd1;endelse if(select_clk==1'd1&&start==1&&work===1)begincnt<=cnt+1;if(cnt==11)begincnt<=0;repeat(2)beginif(fee[3:0]==4'd9)beginfee[3:0]=4'd0;if(fee[7:4]==4'd9)beginfee[7:4]=4'd0;if(fee[11:8]==4'd9)beginfee[11:8]=4'd0;if(fee[15:12]==4'd9)fee[15:12]=4'd0;elsefee[15:12]=fee[15:12]+1'd1;endelsefee[11:8]=fee[11:8]+1'd1;endelse fee[7:4]=fee[7:4]+1'd1;endelse fee[3:0]=fee[3:0]+1'd1;      endendendend
endmodule

当reset为1时,fee模块工作。Select_clk为1代表计费使能。work为0时无顾客,费用一直为起步价5,当work为1时,有顾客开始计价。当start为0时,车停止,代表此时等待计费,每等一分钟,费用加1;当start为1时,车行驶,代表此时行驶计费,每行驶1公里,费用加2。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.数码管显像模块smg_ip_model

输入:1HZ频率时钟工作信号CLK,显像工作信号work,显像使能信号start,显像重置信号reset,16位二进制费用输入fee,16位二进制里程输入dis
输出:4位数码管位选信号sm_wei,8位数码管段选信号sm_duan
module smg_ip_model(input clk,input work,input start,input reset,input [15:0] fee,input [15:0] dis,output [3:0] sm_wei,output [7:0] sm_duan);//分频integer clk_cnt;reg clk_400Hz;always@(posedge clk, negedge reset)beginif(!reset)beginclk_400Hz<=1'd0;clk_cnt=32'd0;endelse if(clk_cnt==32'd1000)beginclk_cnt<=32'b0;clk_400Hz<=!clk_400Hz;endelseclk_cnt<=clk_cnt+1'd1;//位控制endreg [3:0] wei_ctrl = 4'b1110;always@(posedge clk_400Hz)wei_ctrl<={wei_ctrl[2:0],wei_ctrl[3]};//段控制reg [3:0] duan_ctrl;always@(wei_ctrl)beginif(work)case(wei_ctrl) 4'b1110:duan_ctrl=dis[3:0];4'b1101:duan_ctrl=dis[7:4];4'b1011:duan_ctrl=dis[11:8];4'b0111:duan_ctrl=dis[15:12];default:duan_ctrl=4'hf;endcaseelse if(!work)case(wei_ctrl) 4'b1110:duan_ctrl=fee[3:0];4'b1101:duan_ctrl=fee[7:4];4'b1011:duan_ctrl=fee[11:8];4'b0111:duan_ctrl=fee[15:12];default:duan_ctrl=4'hf;endcaseend//解码reg [7:0]duan;always@(duan_ctrl)case(duan_ctrl)4'h0:duan=8'b1100_0000;4'h1:duan=8'b1111_1001;4'h2:duan=8'b1010_0100;4'h3:duan=8'b1011_0000;4'h4:duan=8'b1001_1001;4'h5:duan=8'b1001_0010;4'h6:duan=8'b1000_0010;4'h7:duan=8'b1111_1000;4'h8:duan=8'b1000_0000;4'h9:duan=8'b1001_0000;default:duan=8'b1100_0000;endcaseassign sm_wei=wei_ctrl;assign sm_duan=duan;endmodule

当reset为1时,smg_ip_model模块工作。sm_wei在e、d、b、7间循环,即是在1110、1101、1011、0111间循环,循环选中数码管。work为1时,数码管显示里程数,dis为7,即为f8,而且显示在e选中的个位数码管上,其他位的数码管均显示0,即为c0。
在这里插入图片描述

7.顶层模块taximeter

输入:100MHZ频率时钟工作信号CLK_100M,模块复位信号reset,模块工作信号start,模块使能信号work
输出:4位数码管位选信号sm_wei,8位数码管段选信号sm_duan
module taximeter(clk_100M, reset,start,sm_wei,sm_duan,work);input clk_100M,reset,start,work;output [3:0] sm_wei;output [7:0] sm_duan;wire [15:0]distance;wire [7:0] s;wire [7:0] m;wire [15:0] fee;wire clk;wire distance_enable;wire time_enable;wire select_clk;reg clk_car;reg [31:0] count;always@(posedge clk , negedge reset)beginif(!reset)beginclk_car<=1'd0;count=32'd0;endelse if(count==32'd5)begincount<=32'd0;clk_car<=!clk_car;endelsecount<=count+1'd1;end div u0(.clk_100M(clk_100M),.clk(clk),.reset(reset));distanceCount u2(.work(work),.clk(clk_car),.start(start),.reset(reset),.distance(distance),.distance_enable(distance_enable));timeCount u4(.clk(clk),.reset(reset),.start(start),.s(s),.m(m),  .time_enable(time_enable));control u3(.start(start),.distance_enable(distance_enable),.time_enable(time_enable),.select_clk(select_clk));fee u5(.work(work),.start(start),.reset(reset),.fee(fee),.select_clk(select_clk),.clk(clk));smg_ip_model u6(.work(work),.start(start),.fee(fee),.reset(reset),.clk(clk_100M),.dis(distance),.sm_wei(sm_wei),.sm_duan(sm_duan));endmodule

当reset为1时,taximeter模块工作。work为0时,无顾客,distance里程、fee费用一直为0。work为1时,有顾客,当start为1是,汽车行驶,distance里程加1,费用为起步价5,当distance大于3时,每公里2元。当start为0时,汽车停止行驶,开始等待计费,每等待1分钟,费用加1元,此时distance不变化。最后work为0,顾客下车,distance里程和fee费用都不再变化。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、约束与综合

1.原理图

在这里插入图片描述
在这里插入图片描述

2.引脚配置图

W7,W6,U8,V8,U5,V5,U7,V7:八段数码管显示0-7
W4,V4,U4,U2:四个片选信号
W5:clk时钟
reset:车钥匙,1为启动汽车
start:油门,1汽车行驶,0汽车停止
work:代表顾客,1代表接客,0代表接待结束

在这里插入图片描述

四、系统硬件测试

启动油门,显示起步价5元。
在这里插入图片描述
顾客上车,汽车行驶,里程开始增加。
在这里插入图片描述
在这里插入图片描述
若此时下车,费用为起步价5元。
在这里插入图片描述
行驶至5公里时,价格为9元。
在这里插入图片描述
在这里插入图片描述
当汽车停止行驶,每等待1分钟,价格加1,顾客下车显示价格。
在这里插入图片描述
在这里插入图片描述


总结

以上就是本文章所有内容,详细总结了出租车计价器设计的全过程。

版权声明:本文为博主原创文章,转载请注明作者和出处。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部