出租车计费器 FPGA 实现
浙江理工大学 司兆龙
一 实验任务及要求
1. 能实现计费功能�计费标准为�按行驶里程收费�起步费为 6.00 元�并在车行 3 公
里后再按 1.2 元/公里�当计费器计费达到或超过一定收费 20 元时�每公里加收 50%的车费�
车停止或者暂停时不计费。
2. 实现模拟功能�能模拟汽车启动、停止、暂停、车速挡位等状态。
3. 设计动态扫描电路�将车费和路程显示出来�有两位小数。
4.用 VerilogHDL 语言设计实现所有模块。
5. 各计数器的计数状态用功能仿真的方法验证�并通过有关波形确认电路设计是否正
确。
6. 完成电路全部设计后�通过系统实验箱下载验证设计的正确性。
二 实验原理
设计出租车有启动键�停止键�暂停键和挡位键。启动键为脉冲触发信号�当其为一
个高电平脉冲时�表示汽车已启动�并根据车速的选择和基本车速发出响应频率的脉冲�计
费脉冲��以此实现路程和车费的计数�同时车费显示起步价�当停止键为高电平时�表示
汽车熄火�同时停止发出脉冲�车费路程计数清零�当暂停键为高电平时�表示汽车暂停并
发出脉冲�此时车费和路程计数保持暂停。挡位用来控制不同的汽车挡位�不同的挡位路程
计数速度不同。
出租车计费器分为两大模块�即控制模块和译码显示模块。控制模块实现了计费和路
程的计数�并且不同的挡位来控制车速。译码显示模块实现十进制数到 4 位十进制数的转换�
以及车费和路程的显示。
三 程序附录
控制模块程序
module taxi (money,distance,clk,start,stop,pause,speedup);
input clk ; //计费时钟
input start; //汽车启动
input stop; //汽车停止
input pause; //汽车暂停
input [1:0] speedup; //档位 4 档位
output [12:0] money; //车费
output [12:0] distance; //路程
reg [12:0] money ;
reg [12:0] distance;
reg [12:0] money_reg ; //车费寄存器
reg [12:0] distance_reg; //路程寄存器
reg [3:0] num; //控制车速的计数器
reg [12:0] dis; //千米计数器
reg d; //千米标志位
always@(posedge clk)
begin
if (stop) //车停�计费和路程清零
begin money_reg<='d0;
distance_reg<='d0;
dis<='d0;
num<='d0;
end
else if(start) //车启动�起步价 6 元
begin money_reg<='d600;
distance_reg<='d0;
dis<='d0;
num<='d0;
end
else
begin
if(!start&&!speedup&&!pause&&!stop) //1 档
begin
if (num=='d9)
begin num<='d0;
distance_reg<=distance_reg+1;
dis<=dis+1;
end
else
begin num<=num+1; end
end
else if (!start&&speedup=='b01&&!pause&&!stop) //2 档
begin
if (num=='d9)
begin num<='d0;
distance_reg<=distance_reg+2;
dis<=dis+2;
end
else
begin num<=num+1; end
end
else if (!start&&speedup=='b10&&!pause&&!stop) //3 档
begin
if (num=='d9)
begin num<='d0;
distance_reg<=distance_reg+5;
dis<=dis+5;
end
else
begin num<=num+1; end
end
else if (!start&&speedup=='b11&&!pause&&!stop) //4 档
begin
distance_reg<=distance_reg+2;
dis<=dis+2;
end
end
if (dis>='d100)
begin d<='d1; dis<='d0;end
else
begin d<='d0;end
if(distance_reg>='d300) //超过 3KM�则按照 1.2 元每 KM 计算
begin
if(money_reg<='d2000&&d=='d1)
begin money_reg<=money+'d120;end
else if(money_reg>='d2000&&d=='d1)
begin money_reg<=money+'d180;end //当车费达到 20 元以上时�
每千米加收 50%的车费
end
money<=money_reg;
distance<=distance_reg;
end
endmodule
显示模块程序
module deceder (scan,seg7,dp,clk20mhz,money_in,distance_in);
output[7:0] scan; //数码管地址选择信号
output[6:0] seg7; //7 段显示控制信号
output dp; //小数点
input clk20mhz; //系统时钟 20MHZ
input [12:0] money_in; //车费
input [12:0] distance_in; //路程
reg[7:0]scan;
reg[6:0]seg7;
reg dp;
reg clk1khz; //1KHZ 分频时钟�用于扫描数码管地址
reg[3:0] data;
reg[3:0] m_one,m_ten,m_hun,m_tho; //车费钱数的 4 位十进制表示
reg[3:0] d_one,d_ten,d_hun,d_tho; //路程的 4 位十进制表示
reg[15:0] count ;
reg[15:0]comb1;
reg[3:0]comb1_a,comb1_b,comb1_c,comb1_d;
reg[15:0] comb2;
reg[3:0]comb2_a,comb2_b,comb2_c,comb2_d;
reg[2:0] cnt;
//1khz 分频�用于扫描数码管地址
always@(posedge clk20mhz)
begin
if(count==1'd10000)
begin clk1khz<=~clk1khz;count<='d0;end
else
begin count<=count+1;end
//将车费转化为 4 位十进制数
if(comb1
m_hun<=comb1_c;
m_tho<=comb1_d;
end
else if (comb1>money_in)
begin
comb1_a<='b0000;
comb1_b<='b0000;
comb1_c<='b0000;
comb1_d<='b0000;
comb1<='d0;
end
//将路程转化为 4 位十进制数
if(comb2
d_one<=comb2_a;
d_ten<=comb2_b;
d_hun<=comb2_c;
d_tho<=comb2_d;
end
else if (comb2>distance_in)
begin
comb2_a<='b0000;
comb2_b<='b0000;
comb2_c<='b0000;
comb2_d<='b0000;
comb2<='d0;
end
end
// 数码管动态扫描
always@(posedge clk1khz)
begin
cnt=cnt+1;
end
always@(cnt)
begin
case(cnt)
'b000:begin data<=m_one;dp<='d0;scan<='b00000001;end
'b001:begin data<=m_ten;dp<='d0;scan<='b00000010;end
'b010:begin data<=m_hun;dp<='d1;scan<='b00000100;end
'b011:begin data<=m_tho;dp<='d0;scan<='b00001000;end
'b100:begin data<=d_one;dp<='d0;scan<='b00010000;end
'b101:begin data<=d_ten;dp<='d0;scan<='b00100000;end
'b110:begin data<=d_hun;dp<='d1;scan<='b01000000;end
'b111:begin data<=d_tho;dp<='d0;scan<='b10000000;end
default:begin data<='bx;dp<='bx;scan<='bx;end
endcase
end
//7 段译码
always@(data)
begin
case(data[3:0])
4'b0000:seg7[6:0]=7'b1111110;
4'b0001:seg7[6:0]=7'b0110000;
4'b0010:seg7[6:0]=7'b1101101;
4'b0011:seg7[6:0]=7'b1111001;
4'b0100:seg7[6:0]=7'b0110011;
4'b0101:seg7[6:0]=7'b1011011;
4'b0110:seg7[6:0]=7'b1011111;
4'b0111:seg7[6:0]=7'b1110000;
4'b1000:seg7[6:0]=7'b1111111;
4'b1001:seg7[6:0]=7'b1111011;
default:seg7[6:0]=7'b0000000;
endcase
end
endmodule
FPGA 犀利。