目录
1.设计目标与原理说明 ................................................1
1.1 地铁售票系统设计目标 ........................................ 1
1.2 原理说明 .................................................... 1
1.2.1 流程图说明 ............................................. 1
1.2.2 状态转移图 ............................................. 2
1.2.3 系统设计图 ............................................. 3
2 程序代码及仿真 ................................................... 3
select_area .................................... 4
2.1 模块 1:module
2.2 模块 2:module count_money ................................... 6
2.3 模块 3: module out_tick ...................................... 8
2.4 模块 4:module back_money .................................... 9
3 总结与体会 ...................................................... 10
4 测试程序代码 .................................................... 11
4.1 模块一测试程序 select_area_vlg_tst ..............................11
4.2 模块二测试程序 count_money_vlg_tst ........................... 13
4.3 模块三测试程序 out_tick_vlg_tst ................................ 14
4.4 模块四测试程序 back_money_vlg_tst ............................ 16
基于 FPGA 的地铁售票系统 Verilog 程序设计
1.设计目标与原理说明
1.1 地铁售票系统设计目标
地铁售票系统的 verilog HDL 程序设计必须满足以下目标:
1. 能够设置乘车区间,根据票数计算出所需金额;
2. 能够识别投入的金额总数;
3. 能够自动进行余额结算;
4. 能够正确出票。
1.2 原理说明
1.2.1 流程图说明
在程序设计中,采用模块化的设计,顶层模块为 Subway_tick,下面有选择
乘车区间模块 Select_area、识别投入金额模块 Count_money、余额结算模块
back_money 和出票模块 Out_tick。
根据设计思想得到了如下的流程图 1:
否
开始
监测车站输入信号和复位
信号
是否是车站输入
信号发生变化
是
设置区间并计算所需购票
金额
1
识别投入的钞票总数
投入金额是否大于
等于购票所需金额
是
否
出票
找零
结束
图 1 地铁售票系统流程图
1.2.2 状态转移图
若将开始令为空闲状态 Idle,将选则乘车区间令为状态 Select,将识别钞票
令为 Count 状态,出票令为 out_tic 状态,找出零钱设为 back_m 状态,则根据相
关的参量画出其状态转移图 2:
2
图 2 状态转移图
1.2.3 系统设计图
找零模块
出票模块
比较模块
乘车区间模块
计算金额
识别钱币模块
图 3 系统设计图
2 程序代码及仿真
使用 Quartus Ⅱ11.0 版本编写程序,在 Modelsim10.0 版本下仿真,并得出
相应的仿真波形。
3
2.1 模块 1:module
select_area
module select_area(train_station,//站点名称输入:火车站
nan_men,//站点名称输入:南门
zhong_lou,//站点名称输入:钟楼
official_house,//站点名称输入:政务厅
xiao_zhai,//站点名称输入:小寨
muta_zhai,//站点名称输入:木塔寨
qu_jiang,//站点名称输入:曲江新区
clk,//时钟信号
rst,//复位信号
tick_number1,//购票数量 1 输入信号
tick_number2,
tick_number3,
tick_number4,//购票数量 4 输入信号
tick_number5,
tick_number6,
tick_number7,
tick_number8,
tick_number9,
tick_money//所需金额总数
);
//设定 7 站:火车站——南门——钟楼——省政务大厅——小寨——木塔寨
//——曲江,每一站之间票价 1 元
input
input
train_station,nan_men,zhong_lou,official_house,
xiao_zhai,muta_zhai,qu_jiang,clk,rst;
tick_number1,tick_number2,tick_number3,tick_number4,
tick_number5,tick_number6,tick_number7,tick_number8,
tick_number9;
output[6:0]
tick_money;//一共 7 站,最高票价为 6 元,15 张票最高
//位 90 元,故需要 7 为二进制
output end_station;
reg[2:0] end_station;//终点站变量
reg[3:0] tick_number;
reg[5:0] flag1=0;//标志变量
reg[8:0] flag2=0;
//以火车站为出发站,确定终点站的 always 块
always @(posedge nan_men , posedge zhong_lou,posedge official_house ,
posedge xiao_zhai , posedge muta_zhai , posedge qu_jiang ,posedge rst )
//购票站名电平变化时进入选择乘车区间
begin
end_station<=0;
4
end_station<=0;
if(rst)
else
begin
flag1<={nan_men,zhong_lou,official_house,
xiao_zhai,muta_zhai,qu_jiang};
case (flag1[5:0])
6'b000001 : end_station<=6;
6'b000010 : end_station<=5;
6'b000100 : end_station<=4;
6'b001000 : end_station<=3;
6'b010000 : end_station<=2;
6'b100000 : end_station<=1;
default :
endcase
end_station<=0;
//当外部输入票数信号时//进入
end
end
//确定总票数的 always 块
always @(posedge tick_number1,posedge tick_number2,
posedge tick_number3,posedge tick_number4,
posedge tick_number5,posedge tick_number6,
posedge tick_number7,posedge tick_number8,
posedge tick_number9,posedge rst)
计算票数程序
begin
tick_number<=0;
if(rst) tick_number<=0;//当复位信号有效,票数清零
else
begin
flag2<={tick_number1,tick_number2,tick_number3,
tick_number4,tick_number5,tick_number6,
tick_number7,tick_number8,tick_number9};
case (flag2[8:0])
9'b000000001 : tick_number<=9;
9'b000000010 : tick_number<=8;
9'b000000100 : tick_number<=7;
9'b000001000 : tick_number<=6;
9'b000010000 : tick_number<=5;
9'b000100000 : tick_number<=4;
9'b001000000 : tick_number<=3;
9'b010000000 : tick_number<=2;
9'b100000000 : tick_number<=1;
default : tick_number<=0;
endcase
end
5
end
// 确定总金额
assign
tick_money =end_station*tick_number;//购票所需金额有单价和数
//目乘积确定
Endmodule
图 4 选择乘车区间模块仿真图
仿真分析:在上图 4 中,可以看到火车站 train_station 为出发站,故电平一
直为 1,当 qu_jiang 曲江站随机变化被选中时,选择 4 张票 tick_number4 随机变
化,得到了仿真的所需金额 tick_money 波形。
在第一段内,qu_jiang=1,tick_number4=1,就是说 train_staion 为出发站,
q_jiang 为终点站,之间票价为 6 元,一共买 4 张票,结果总票价为 24 元,这与
波形显示的“0011000”恰好吻合。
2.2 模块 2:module count_money
module
count_money( rst,//复位信号
clk,//时钟
money_1,
money_5,
money_10,
money_20, //1 元 5 元 10 元 20 币元输入信号
cout //统计出的总钱数
);
//时钟信号
input rst;
input clk;
input money_1,money_5,money_10,money_20;
output [6:0] cout;//5 位可最大统计 255 元,可满足实际需求
reg [2:0] num_1,num_5,num_10,num_20;//1,5,10,20 币数量两边
//高脉冲有效
6
assign cout = num_1 + 5*num_5 + 10*num_10 + 20*num_20;
//一元计数 always 模块
always @ (posedge rst or posedge money_1)
begin
if(rst==1)
else num_1 = num_1 + 1;//当 money_1 输入信号变化时,1 元币数目加 1
num_1 <= 0;//复位信号有效,钱币数为 0
//5 元计数 always 模块
always @ (posedge rst or posedge money_5)
num_5 <= 0;
num_5 = num_5 + 1;//当 money_5 输入信号变化时,5 元币数目加 1
end
begin
if(rst==1)
else
end
begin
end
//10 元计数 always 模块
always @ (posedge rst or posedge money_10)
begin
if(rst==1)
else num_10 = num_10 + 1;//当 money_10 变化时,10 元币数目加 1
end
num_10 <= 0;
//20 元计数 always 模块
always @ (posedge rst or posedge money_20)
if(rst==1)
else
num_20 <= 0;
num_20 =num_20 + 1;//当 money_20 变化时,20 元币数目加 1
endmodule
仿真分析:一共四种钞票类型,money_1,money_5,money_10,money_20,在
图 5 识别投入钞票总额的仿真图
7