地铁自动售票系统VHDL

更新时间:2023-06-09 08:43:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

数字系统课程设计---地铁售票模拟

一、 设计要求:

功能描述:用于模仿地铁售票的自动售票,完成地铁售票的核心控制功能。

功能要求:售票机有两个进币孔,一个是输入硬币,一个是输入纸币,硬币的识别范围是5

角和1 元的硬币,纸币的识别范围是1 元、2 元,5 元,10 元。乘客可以连续多次投入钱币。

乘客可以选择的种类为2 元和4 元,乘客一次只能选择一个出站口。购买车票时,乘客先选

择出站名,然后选择所需的票数,再进行投币,投入的钱币达到所需金额时,售票机自动出

票,并找出余额,本次交易结束,等待下一次的交易。在投币期间,乘客可以按取消键取消 本次操作,钱币自动退出。

功能描述:用于模仿地铁售票的自动售票,完成地铁售票的核心控制功能。

功能要求:售票机有两个进币孔,一个是输入硬币,一个是输入纸币,硬币的识别范围是5

角和1 元的硬币,纸币的识别范围是1 元、2 元,5 元,10 元。乘客可以连续多次投入钱币。

乘客可以选择的种类为2 元和4 元,乘客一次只能选择一个出站口。购

买车票时,乘客先选

择出站名,然后选择所需的票数,再进行投币,投入的钱币达到所需金额时,售票机自动出

票,并找出余额,本次交易结束,等待下一次的交易。在投币期间,乘客可以按取消键取消 本次操作,钱币自动退出。

二、 课题分析 1.

买车票时,乘客按“开始选择”按钮,接着选择出站口接着

选择购票数量(根据提示,一次购票数限制在3张以内);然后按“开始投币”按钮,投入钱币;当投入的钱币达到所需金额时,售票机自动出票,并找出余额。考虑到控制整个售票机的物理体积,余额将全部采用5角硬币的形式找出。 2.

选择出站口或投币过程中,乘客都可以按“取消”按钮取消

该次交易。选择出站口的过程中,若按“取消”,则售票机直接回到初始状态;投币过程中,若按“取消”,则售票机将乘客已经投入的钱币全部退出,再回到初始状态。

3. 客一次只能选择一个出站口,根据乘坐的站数确定票价。假

设乘客购票所在站到终点站共有15站。若乘坐1-8站,则票价为2元/张;若乘坐9-16站,则票价为4元/张。16个站用长度位4的二进制向量编码表示,即0001表示乘坐1站,0010表示乘坐2站,依次类推,1111表示乘坐15站(到终点站)。 4.

票机有2个进币端口。硬币口可识别5角和1元2种硬币,

拟用长度为2的一比特热位(one-hot)编码方式表示,即01表示5角,10表示1元。纸币口类似,用长度为4的一比特热位编码方式表示。乘客可以连续多次投入钱币,并且可以以任意顺序投入硬币和纸币。 5.

票机设有钱币“暂存杆”,其有3个状态:退币状态、等待状

态、进币状态,分别用00、01、10表示。退币状态下,“暂存杆”将乘客投入的钱币推出;等待状态下,投入的钱币被“暂存杆”挡住暂存;进币状态下,“暂存杆”将乘客投入的钱币推入售票机内部。

三、系统流程图:

四、 系统状态图

五、程序源代码及注释

library ieee;

use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;

entity subway is port( );

end subway;

architecture behave of subway is

begin

process(clk)

variable type_temp :std_logic;

--记录是否已选择出站口的变量 --记录是否已选择购票张数的变量

--记录票种的中间变量

type state_type is (initialize_state,select_state,insert_state,ticket_state,change_state);

--状态变量申明 --状态信号申明

clk

:in std_logic;

--系统时钟 --“开始选择”按钮 --“开始投币”按钮 --硬币入口 --纸币入口 --“取消”按钮 --出站口编号 --购票张数 --钱币“暂存杆” --购买的车票 --出票口 --找零口

select_start insert_start

:in std_logic; :in std_logic;

coin :in std_logic_vector(1 downto 0); note :in std_logic_vector(3 downto 0); cancel

:in std_logic;

ticket_stop :in std_logic_vector(3 downto 0);

ticket_account :in std_logic_vector(1 downto 0); money_gate :out std_logic_vector(1 downto 0); ticket_out ticket_gate

:out std_logic_vector(4 downto 0); :out std_logic;

change_gate :out std_logic

signal state:state_type;

variable account_temp :std_logic;

variable temp_type :std_logic_vector(4 downto 0);

variable temp_account :std_logic_vector(4 downto 0); --记录票数的中间变量 variable price :std_logic_vector(7 downto 0);

--记录单张票价的变量

variable number :std_logic_vector(1 downto 0); --记录票数的变量 --记录总票价的变量

variable total_price :std_logic_vector(7 downto 0);

variable total_insert :std_logic_vector(7 downto 0);-- 记录投入钱币总额的变量 variable change

:std_logic_vector(7 downto 0);

--记录应找零金额的变量

variable sign :std_logic; variable temp :std_logic;

--记录系统是否已经过初始化的变量 --记录投入钱币金额达到总票价的变量

begin

if (clk'event and clk='1') then

case state is

when initialize_state=>

if(sign='0')

then

--初始状态

--表示系统未经过初始化 --钱币“暂存杆”退出钱币 --购票记录清零 --出票口关闭 --找零口关闭 --票种记录清零 --票数记录清零

--单张票价记录清零 --购票张数记录清零 --票价总额记录清零 --投入钱币总额记录清零 --应找零金额记录清零 --记录已完成系统初始化

--时钟信号上升沿触发

money_gate<="00"; ticket_out<="00000"; ticket_gate<='0';

change_gate<='0'; temp_type:="00000";

temp_account:="00000"; type_temp:='0'; account_temp:='0'; price:="00000000"; number:="00";

total_price:="00000000"; total_insert:="00000000"; change:="00000000"; sign:='1'; temp:='0' ;

--投入达到总票价记录清零

--表示系统已经过初始化

else

money_gate<="01"; --钱币“暂存杆”归为等待状态

if (select_start='1') then --按下“开始选择”按钮

sign:='0';

--系统进入选择状态

state<=select_state;

--选择状态

--表示尚未选择出站口

end if;

when select_state=>

if(type_temp='0') then

if((ticket_stop>="0001")and(ticket_stop<="1000"))then

--乘坐站数不超过8站

--由于整个系统中涉及的最小金额为5角,为表示方便,有关金额的量统一以“角”为单位--即5角为“5”,1元为“10”,2元为“20”,5元为“50”,10元为“100”

price:="00010100";

--票价为2元

--用5位逻辑矢量表示票种和数量

--其中前2位表示票种:10000表示4元票,01000表示2元票 --后3位表示数量:10000表示3张,01000表示2张,00100表示1张 --二者相加即可同时表示购买的票种和张数信息

temp_type:="01000"; type_temp:='1';

--表示2元票 --记录已选择出站口

elsif((ticket_stop>="1001")and(ticket_stop<="1111"))then

--乘坐站数超过8站 --票价为4元 --表示4元票 --记录已选择出站口

price:="00101000"; temp_type:="10000"; type_temp:='1';

end if;

then

end if;

if((account_temp='0')and(type_temp='1'))

--表示已选择出站口但尚未选择购票张数

case ticket_account is

when "11"=>

--选择3张票

temp_account:="00100";--表示3张票 number:="11";

--购票张数为3

total_price:=price+price+price; --计算总票价 account_temp:='1'; --记录已选择购票张数

--选择2张票

when "10"=>

temp_account:="00010"; number:="10";

account_temp:='1';

--选择1张票

when "01"=>

temp_account:="00001"; number:="01"; total_price:=price; account_temp:='1'; null;

when others=>

end case;

then

end if;

if((type_temp='1')and(account_temp='1'))

--表示已选择出站口且已选择购票张数

--按下“开始投币”按钮 --系统进入投币状态

if(insert_start='1') then

state<=insert_state;

end if;

--按下“取消”按钮 --回到初始状态

end if;

if(cancel='1') then

state<=initialize_state;

end if;

--投币状态 --纸币识别 --1元纸币

when insert_state=>

case note is

when "0001"=>

total_insert:=total_insert+"00001010";

--重新计算投币总额

when "0010"=>

total_insert:=total_insert+"00010100";

--2元纸币

when "0100"=>

total_insert:=total_insert+"00110010";

--5元纸币

when "1000"=>

total_insert:=total_insert+"01100100";

--10元纸币

when others=>

null;

end case; case coin is

--硬币识别

when "01"=>

total_insert:=total_insert+"00000101";

--5角硬币

when "10"=>

total_insert:=total_insert+"00001010";

--1元硬币

when others=>

null;

end case;

if(cancel='1') then

--按下“取消”按钮 --回到初始状态

state<=initialize_state;

end if; if(temp='1')

then

--判断投入钱币金额达到总票价

money_gate<="10";

--钱币“暂存杆”将钱币推入售票机内,表示接受投币

state<=ticket_state; --系统进入出票状态

end if;

if(total_insert>=total_price) then

--判断投入总金额是否已达到票价总额

temp:='1'; --记录投入钱币金额达到总票价

end if;

--出票状态 --计算应找零金额

when ticket_state=>

if(number="11") then

change:=total_insert-price-price-price; elsif(number="10") then

change:=total_insert-price-price; elsif(number="01") then

change:=total_insert-price; end if;

end if;

end process;

end behave;

六、程序调试

ticket_out<=temp_type+temp_account; --计算输出车票 ticket_gate<='1';

--出票口打开 if(change>"00000000") then --判断是否还有找零

state<=change_state;

--系统进入找零状态

else

state<=initialize_state;

--找零完成,回到初始状态

end if;

when change_state=>

--找零状态

--找零口打开时,可控制每个时钟上升沿推出一个5角的硬币

if(change>"00000000") then change_gate<='1';

--找零口打开

change:=change-"00000101";--计算剩余应找零金额

else change_gate<='0';

--找零口关闭

state<=initialize_state;

--系统回到初始状态

end if;

end case;

编译可以通过,无错误或警告,如图所示:

七、波形仿真:

在创建的波形仿真文件中,添加所有输入输出端口,并添加程序中涉及的重要变量进行仿真。End Time设定为10.0us,时钟周期设定为100ns,模拟完成乘客5次购票的过程,以期测试系统的所有功能是否正常。全部的仿真波形截图如下:

下面将各次购票过程的波形仿真结果放大,逐一讨论检测。

1. (1)乘客按下“开始选择”按钮(select_start='1'),钱币“暂存杆”进入

等待状态(money_gate="01"),系统进入选择状态(state=select_state)。 (2)乘客选择出站口为第6站,系统得出单张票价price为20(2元);选择

购买数量为2张,系统得出票数number为2。进而得出总票价total_price为40(4元)。

(3)乘客按下“取消”按钮(cancel='1'),系统回到初始状态(state=

initialize_state),钱币“暂存杆”推出(此刻无暂存钱币,仅表示初始化过程中的一个动作),然后再归为等待状态;其余变量全部清零。 此段仿真主要验证了在选择状态时“取消”按钮的功能正常。系统全部恢复初

960.0ns

2.(1)乘客在约1.15us时按下“开始选择”按钮,系统进入选择状态。 (2)乘客选择出站口为第11站,系统得出票价为4元;选择购买3张,系统得

出票数为3张。进而得出总票价为12元。

(3)乘客按下“开始投币”按钮(insert_start='1'),系统进入投币状态

(state=insert_state)。

(4)乘客投入5元纸币(note="0100"),系统得出投入的总金额为5元

(total_insert为50);投入1元硬币(coin="10"),系统得出投入的总金额为6元(total_insert为60)。

(5)乘客按下“取消”按钮,系统回到初始状态,钱币“暂存杆”推出,退出乘

客投入的钱币,然后再归为等待状态;其余变量全部清零。

此段仿真主要验证了在投币状态时“取消”按钮的功能正常。系统全部恢复初始状态的时间在2.36us左右(如图)。

3.(1)乘客在约2.45us时按下“开始选择”按钮,系统进入选择状态。

(2)乘客选择出站口为第9站,系统得出票价为4元;选择购买3张,系统得出票数为3张。

进而得出总票价为12元。

(3)乘客按下“开始投币”按钮,系统进入投币状态。

(4)乘客投入10元纸币,系统得出投入的总金额为10元,再投入5元纸币,系统得出投入

的总金额为15元。

(5)系统判断投入的总金额已经达到票价总额(total_insert>=total_price)。

(6)系统进入出票状态(ticket_state):系统准备好4元的票3张(10100),出票口打开

(ticket_gate='1')出票。

(7)系统进入找零状态(change_state):找零口打开(change_gate='1')找零,每个时钟上

升沿时出一个5角硬币,变量change实时显示剩余应找零金额。 (8)找零完毕,找零口关闭;出票口关闭。系统回到初始状态。

此段仿真主要验证了连续投入单种介质钱币购票且找零的功能正常。系统全部恢复初始状态的时间在4.56us左右(如图)。

本文来源:https://www.bwwdw.com/article/9621.html

Top