我的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/
本文版权归作者和博客园共有,欢迎转载,转载保留此段文字并且注明出处;谢谢。

posted @ 2011-01-15 10:20  给我一杯酒  阅读(7578)  评论(18编辑  收藏  举报