zoukankan      html  css  js  c++  java
  • 我的EDA课程设计 Verilog HDL 自动售票机的实现

    ·设计目标: 

    本设计完成基于Verilog HDL的自动售票系统,综合软件用Quartus II8.1。

    本自动售票系统可以完成1元、2元、3元、4元四种票的自动售出,货币种类可以是1元、5元、10元、50元、100元,能自动找零和显示

    ·总体设计: 

    共有四个主要模块和一个顶层模块:四个模块分别是主控模块、统计模块、出票模块和找零模块;顶层模块负责各模块间的连接,组成一个可用的自动售票系统。

    总体结构如下:

    image

    ·各模块设计: 

    统计模块

    根据各种货币输入,统计出总钱数提供给主控模块。每次售票完成后总钱数自动归零(主控模块提供售票完成信号,计数清零)

    代码如下:

     1:  //统?计?钱?数?模?块?
     2:   module count (    rst,                        //复?位?高?有??
     3:                  clr,
     4:                  ci1,ci5,ci10,ci50,ci100,    //1元?、?元?、?元?、?元?、?元?输?入?
     5:                  cout                        //统?计?出?的?总?钱?数?
     6:               );
     7:   
     8:  input rst;
     9:  input clr;                        //清?零?信?号?
    10:   input ci1,ci5,ci10,ci50,ci100;    //高?脉?冲?有??
    11:   output [7:0] cout;
    12:   
    13:  reg [2:0] q1,q5,q10,q50,q100;
    14:   
    15:  assign cout = q1 + 5*q5 + 10*q10 + 50*q50 + 100*q100;
    16:   
    17:  //一?元?计?数?
    18:   always @ (posedge rst or posedge clr or posedge ci1)
    19:  begin
    20:      if(rst==1)    q1 <= 0;
    21:      else if(clr==1)    q1 <= 0;
    22:      else
    23:      begin
    24:          q1 = q1 + 1;
    25:      end
    26:  end
    27:   
    28:  //5元?计?数?
    29:   always @ (posedge rst or posedge clr or posedge ci5)
    30:  begin
    31:      if(rst==1)    q5 <= 0;
    32:      else if(clr==1)    q5 <= 0;
    33:      else
    34:      begin
    35:          q5 = q5 + 1;
    36:      end
    37:  end
    38:   
    39:  //10元?计?数?
    40:   always @ (posedge rst or posedge clr or posedge ci10)
    41:  begin
    42:      if(rst==1)    q10 <= 0;
    43:      else if(clr==1)    q10 <= 0;
    44:      else
    45:      begin
    46:          q10 = q10 + 1;
    47:      end
    48:  end
    49:   
    50:  //50元?计?数?
    51:   always @ (posedge rst or posedge clr or posedge ci50)
    52:  begin
    53:      if(rst==1)    q50 <= 0;
    54:      else if(clr==1)    q50 <= 0;
    55:      else
    56:      begin
    57:          q50 = q50 + 1;
    58:      end
    59:  end
    60:   
    61:  //100元?计?数?
    62:   always @ (posedge rst or posedge clr or posedge ci100)
    63:  begin
    64:      if(rst==1)    q100 <= 0;
    65:      else if(clr==1)    q100 <= 0;
    66:      else
    67:      begin
    68:          q100 = q100 + 1;
    69:      end
    70:  end
    71:   
    72:  endmodule

    模块先统计各种金额的货币数,然后用并行赋值(assign赋值语句)统计出总钱数输出。

    仿真波形如下:

    clip_image008

    由仿真波形:

    初始时,cout为0,即总钱数为0,经过货币输入脉冲后能准确记录输出钱的总数。清零脉冲后,cout可归零,只需把主控模块的完成脉冲加到此,则完成一次售票后,本模块可以自动归零,准备接受下一次投币。

    主控模块: 

     完成总体控制和各种控制信号。

    程序代码如下:

     1:  // 主?控?模?块?,?完?成?自?动?售?票?逻?辑?计?算?及?产?生?各?种?控?制?信?号?
     2:   module contrl (    rst,clk,                    //复?位?高?有?? 时?钟?
     3:                  get,cancel,
     4:                  sel,                        //票?类?别?,?
     5:                  count,                        //票?数?
     6:                  money,                        //总?钱?数?
     7:                  mout,                        //找?零?钱?数?
     8:                  finish,                        //出?钱?信?号?
     9:                  finishp                        //出?票?信?号?
    10:              );
    11:   
    12:  input rst;
    13:  input clk;                    //时?钟?,?
    14:   input get,cancel;
    15:  input [1:0] sel,count;
    16:  input [7:0] money;
    17:  output reg [7:0] mout;
    18:  output reg finish,finishp;                //完?成?脉?冲?
    19:   
    20:   
    21:   always @ (posedge rst or posedge clk)
    22:  begin
    23:      if(rst==1)
    24:      begin
    25:          mout <= 0;
    26:          finish <= 0;
    27:          finishp <= 0;
    28:      end
    29:      else
    30:      begin
    31:          if((get == 1)&&(money >= sel*count + count))
    32:          begin
    33:              finish <= 1;
    34:              finishp <= 1;
    35:              mout = money - sel*count - count;
    36:          end
    37:          else if((cancel == 1)||((get == 1)&&(money < sel*count + count)))
    38:          begin
    39:              finishp <= 0;
    40:              finish <= 1;
    41:              mout = money;
    42:          end
    43:          else 
    44:          begin
    45:              finishp <= 0;
    46:              finish <= 0;
    47:          end
    48:      end
    49:  end
    50:   
    51:  endmodule
    52:   

    本模块为主控制模块,产生各种控制信号并完成购票后余额的计算,控制其他模块一致完成自动售票。

    仿真结果:

    clip_image010

    get cancel分别为确认买票,和取消买票信号,高脉冲有效,由仿真图:买4元一张的票3张,总钱数50,仿真结果 输出完成信号脉冲和出票信号脉冲,并输出找零总数38元,正确。

    出票模块: 

    根据所需票和主控模块传来的出票信号输出相应的票。

    代码如下:

     1:  //出?票?模?块?
     2:   module chupiao (    rst,clk,            //复?位?高?有??
     3:                      en,                    //使?能?
     4:                      sel,                //票?类?别?
     5:                      count,                //票?数?
     6:                      co1,co2,co3,co4        //各?种?票?输?出?
     7:                   );
     8:   
     9:  input rst,clk;
    10:  input en;                        //
    11:   input [1:0] sel,count;    //高?脉?冲?有??
    12:   output co1,co2,co3,co4;
    13:   
    14:  reg [3:0] q;
    15:   
    16:  reg [1:0] qsel;
    17:  reg [2:0] qcount;
    18:   
    19:  assign co1 = q[0];
    20:  assign co2 = q[1];
    21:  assign co3 = q[2];
    22:  assign co4 = q[3];
    23:   
    24:  always @ (posedge rst or posedge en or posedge clk)
    25:  begin
    26:      if(rst==1)    q <= 0;
    27:      else if(en==1)
    28:      begin
    29:          q <= 0;
    30:          qsel <= sel;
    31:          qcount <= count * 2;
    32:      end
    33:      else
    34:      begin
    35:          if(qsel==0)
    36:          begin
    37:              if(qcount != 0)
    38:              begin
    39:                  q[0] = ~q[0];
    40:                  qcount <= qcount - 1;
    41:              end
    42:          end
    43:          else if(qsel==1)
    44:          begin
    45:              if(qcount != 0)
    46:              begin
    47:                  q[1] = ~q[1];
    48:                  qcount <= qcount - 1;
    49:              end
    50:          end
    51:          else if(qsel==2)
    52:          begin
    53:              if(qcount != 0)
    54:              begin
    55:                  q[2] = ~q[2];
    56:                  qcount <= qcount - 1;
    57:              end
    58:          end
    59:          else
    60:          begin
    61:              if(qcount != 0)
    62:              begin
    63:                  q[3] <= ~q[3];
    64:                  qcount <= qcount - 1;
    65:              end
    66:          end
    67:      end
    68:  end
    69:   
    70:  endmodule

    本模块接收主控模块产生的finishp作为使能信号,根据所选票及票数输出相应的票,输出票为脉冲(一个脉冲代表一张票)。

    仿真结果如下:

    clip_image012

    co1-co4是对应票输出,每脉冲一张票。要买3张4元每张的票:仿真结果输出三个co4的脉冲,正确。

    找零模块: 

     

    根据主控模块送来的需找零钱数或是需退回钱数输出相应票额。

    根据找零钱数计算并输出相应的票额,一个时钟周期为输出一次(一个时钟周期长度为一张对应面额的钱)。

    找零模块: 

    根据主控模块送来的需找零钱数或是需退回钱数输出相应票额。

    各信号

    根据找零钱数计算并输出相应的票额,一个时钟周期为输出一次。

     1:  // 找?零?模?块?,?完?成?找?零?功?能?
     2:   module zhao (    rst,clk,                    //复?位?高?有?? 时?钟?                    
     3:   
     4:      //使?能?
     5:                  money,    //找?零?钱?数?
     6:                  cak1,cak5,cak10,cak50    //找?零?1 5 10 50 元?
     7:               );
     8:   
     9:  input rst;
    10:  input clk;                    //
    11:   input [7:0] money;
    12:  output cak1,cak5,cak10,cak50;
    13:   
    14:  reg [3:0] qout;
    15:   
    16:  reg [2:0] q1,q5,q10,q50;
    17:   
    18:  assign cak1 = qout[0];
    19:  assign cak5 = qout[1];
    20:  assign cak10 = qout[2];
    21:  assign cak50 = qout[3];
    22:   
    23:  always @ (posedge rst or posedge clk)///negedge
    24:   begin
    25:      if(rst==1)    qout <= 0;
    26:      else if(money!=0)
    27:      begin
    28:          qout <= 0;
    29:          q50 = money / 50;
    30:          q10 = (money - q50*50)/10;
    31:          q5 = (money - q10*10 - q50*50)/5;
    32:          q1 = money - q5*5 -q10*10 -q50*50;
    33:      end
    34:      else
    35:      begin
    36:          if(q50 != 0)
    37:          begin
    38:              qout[3] <= 1;
    39:              q50 <= q50 - 1;
    40:          end
    41:          else if(q10 != 0)
    42:          begin
    43:              qout[3] = 0;
    44:              qout[2] = 1;    
    45:              q10= q10 -1;
    46:          end
    47:          else if(q5!=0)
    48:          begin
    49:              qout[3:2] = 0;
    50:              qout[1] = 1;
    51:              q5 = q5 - 1;
    52:          end        
    53:          else if(q1 != 0)
    54:          begin
    55:              qout[3:1] = 0;
    56:              qout[0] = 1;
    57:              q1 = q1 - 1;
    58:          end
    59:          else
    60:          begin
    61:               qout <= 0;
    62:          end
    63:      end
    64:  end
    65:   
    66:  endmodule

    本模块接收主控模块的找零总数,并根据其值进行找零操作。

    仿真结果如下:

    clip_image013

    要找零28元,如仿真图:找回10元两张,5元一张,1元三张,结果正确。

    顶层模块:

    本设计顶层模块亦用Verilog HDL语言实现,完成各模块间输入出信号的连接,用元件例化组成一个完整的自动售票系统。

    代码如下:

     1:  module piao (   rst,clk,                //复?位?、?时?钟?信?号?输?入?
     2:                  get,cancel,
     3:                  sel,count,    
     4:                  ci1,ci5,ci10,ci50,ci100,//1元?、?元?、?元?、?元?、?元?输?入?
     5:                  co1,co2,co3,co4,        //出?票?
     6:                  cak1,cak5,cak10,cak50,    //找?零?
     7:                  cout                    //找?零?显?示?
     8:               );
     9:  input rst,clk;
    10:  input get,cancel;                //确?认?、?取?消?买?票?信?号?高?脉?冲?有??
    11:  input ci1,ci5,ci10,ci50,ci100;    //高?脉?冲?有??
    12:  input [1:0] count,sel;
    13:   
    14:  output co1,co2,co3,co4;            //高?脉?冲?有??
    15:  output cak1,cak5,cak10,cak50;    //高?脉?冲?有??
    16:  output [7:0] cout;
    17:   
    18:  wire [7:0] mcount;            //总?钱?数?
    19:  wire finish;
    20:  wire finishp;
    21:  wire [7:0] a;
    22:   
    23:  assign cout = a;
    24:   
    25:  count  u1 (rst,finish,ci1,ci5,ci10,ci50,ci100,mcount);
    26:  contrl u2 (rst,clk,get,cancel,sel,count,mcount,a,finish,finishp);
    27:  chupiao u3 (rst,clk,finishp,sel,count,co1,co2,co3,co4);
    28:  zhao u4 (rst,clk,a,cak1,cak5,cak10,cak50);
    29:   
    30:  endmodule

    程序完成各信号的连接,通过各个信号把各模块实例化并正确连接,完成自动售票功能。

    ·仿真结果:

    (仿真结果即是顶层模块仿真结果):

    当取消买票时,当退回投币金额,且不输出票,如下图,仿真正确

    clip_image016

    sel=3,count=3买3张4元一张的票,ci100一个输入脉冲(即输入100元)

    有结果可以看出,找零50+10*3+5+1*3;cout:88 找零88元

    结果正确

    clip_image018

    ·总结:

    本系统可以完成自动售票逻辑,售票完成后不需手动复位,售票完成后自动进入等待下一次售票,通过主控模块输出完成的控制信号(finish),让统计模块清零,其他模块完成后即可进行下一次售票的操作。

    Verilog HDL语言以类C的灵活而被广泛使用,通过这个课程设计的完成,加深的对verilog的学习和对硬件描述语言的认识。

    工程项目文件夹:下载

    作者:给我一杯酒
    出处:http://Engin.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,转载保留此段文字并且注明出处;谢谢。

  • 相关阅读:
    常用数字处理小技巧
    C# 绘制统计图(柱状图, 折线图, 扇形图) zhuan
    谈谈防 SQL 注入式攻击策略
    ASP.NET2.0小技巧--内部控件权限的实现
    宝刀不老: Cookie
    IP地址与子网掩码总结
    ASP.NET 2.0下实现匿名用户向注册用户的迁移(上) zhuan
    [翻译].net 2.0(c#)下简单的FTP应用程序 zhuan
    ASP.NET2.0自动搜索文件组成导航系统
    正则表达式实现资料验证的技术总结
  • 原文地址:https://www.cnblogs.com/Engin/p/1936124.html
Copyright © 2011-2022 走看看