当前位置:   article > 正文

基于FPGA的自动售货机_自动售货机fpga

自动售货机fpga

一、自动售货机的功能

       自动售货机中有价值为1元,3.5元,5元的三种饮料,能识别的金额为0.5元,1元,5元,10元。在购买饮料时,当输入金额小于饮料价值时,LED灯100ms闪烁;输入金额与饮料价值相等时,LED灯常亮;输入金额大于饮料价值时,显示多出的钱数,LED灯2s闪烁。饮料与输入金额须在数码管显示,饮料选择与金额输入可通过按键或者拨码开关进行。

二、具体实现方法  

  这个自动售货机采用top-down思想,主要分为5个模块,分别是:消抖模块、计算模块、状态机控制模块、led模块、显示模块;

  这个自动售货机根据·功能分析,它的输入有:系统时钟、复位信号、[2:0]drink(表示所选货物,拨码开关控制 分别为1元,3.5元,5元)、四种钱币的信号(0.5元,1元,5元,10元 由按键控制);它的输出有:数码管的位选和段选(sel[3:0],seg[7:0])和一个led的控制信号;

各个模块的实现方法

(1)、top模块

 本模块的实现主要是各个端口的例化,想要清晰的的实现本模块,画图是最简单的方式,所以,这个自动售货机的结构图如下:watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA57Sr572X5YWw5LiO5rW35qOg55qE6L6j6bih5a6k5Y-L,size_20,color_FFFFFF,t_70,g_se,x_16

 根据上图所示,本模块的代码为:

  1. module top(
  2. input clk, //系统时钟
  3. input rst, //复位信号
  4. input [2:0] drink,//货物
  5. input money_one, //0.5
  6. input money_two, //1
  7. input money_three, //5
  8. input money_four, //10
  9. output wire [3:0] sel,//数码管位选
  10. output wire [7:0] seg,//数码管段选
  11. output wire led
  12. );
  13. wire [7:0] money_1;
  14. wire [7:0] money_2;
  15. wire [2:0] flag;
  16. wire [11:0] money_in;
  17. wire [11:0] money_drink;
  18. wire [11:0] money_out;
  19. wire [2:0] ctrl;
  20. //消抖部分
  21. xiaodou s0(
  22. .clk(clk),
  23. .rst(rst),
  24. .key_in(money_one),
  25. .key_flag(key1)
  26. );
  27. xiaodou s1(
  28. .clk(clk),
  29. .rst(rst),
  30. .key_in(money_two),
  31. .key_flag(key2)
  32. );
  33. xiaodou s2(
  34. .clk(clk),
  35. .rst(rst),
  36. .key_in(money_three),
  37. .key_flag(key3)
  38. );
  39. xiaodou s3(
  40. .clk(clk),
  41. .rst(rst),
  42. .key_in(money_four),
  43. .key_flag(key4)
  44. );
  45. //计算部分
  46. money s4(
  47. .clk(clk),
  48. .rst(rst),
  49. .key1(key1),
  50. .key2(key2),
  51. .key3(key3),
  52. .key4(key4),
  53. .drink(drink),
  54. .money_1(money_1),
  55. .money_2(money_2),
  56. .flag(flag),
  57. .money_in(money_in),
  58. .money_drink(money_drink),
  59. .money_out(money_out)
  60. );
  61. //状态机
  62. zhaungtai s5(
  63. .clk(clk),
  64. .rst(rst),
  65. .flag(flag),
  66. .ctrl(ctrl)
  67. );
  68. //数码管显示部分
  69. xianshi s6(
  70. .clk(clk),
  71. .rst(rst),
  72. .ctrl(ctrl),
  73. .date1(money_drink),
  74. .date2(money_in),
  75. .date3(money_out),
  76. .sel(sel),
  77. .seg(seg)
  78. );
  79. //led灯控制部分
  80. led s7(
  81. .clk(clk),
  82. .rst(rst),
  83. .flag(flag),
  84. .money_1(money_1),
  85. .money_2(money_2),
  86. .led(led)
  87. );
  88. endmodule

(2)、消抖模块

        本模块的主要功能是对四个有按键输入的信号进行消抖,并输出一个脉冲信号;本模块的实现方法与上个文章的实现方法一致,在此不再赘述;

(3)、计算模块

        本模块的主要功能是计算所选的饮料的价格、输入铅笔的价格和所要找零的钱数并将其转化为BCD码(方便在数码管上显示);

        本模块的的输入有:系统时钟、复位信号、drink[2:0]、四个消抖后的钱币信号;输出有: money_1所选货物的价格(二进制)、money_2/所支付的钱数(二进制)flag状态机状态转化信号、money_in所支付的钱数(BCD)、 money_drink所选货物的价格(BCD)、 money_out 找零的钱数(BCD)。

本模块的实现困难之处是在数据转化为BCD码上,对于本模块我采用了三种实现方法:

        money_drink转化为BCD码:

这个信号的实现较为简单、直接通过一个译码器来实现:

  1. always@(posedge clk or negedge rst) begin
  2. if(rst==0)
  3. money_1<=0;
  4. else begin
  5. case(drink)
  6. 3'd000:begin money_1<='d0 ;money_drink<=12'b0000_0000_0000; end
  7. 3'd001:begin money_1<='d10;money_drink<=12'b0000_0001_0000; end
  8. 3'd010:begin money_1<='d35;money_drink<=12'b0000_0011_0101; end
  9. 3'd011:begin money_1<='d45;money_drink<=12'b0000_0100_0101; end
  10. 3'd100:begin money_1<='d50;money_drink<=12'b0000_0101_0000; end
  11. 3'd101:begin money_1<='d60;money_drink<=12'b0000_0110_0000; end
  12. 3'd110:begin money_1<='d85;money_drink<=12'b0000_1000_0101; end
  13. 3'd111:begin money_1<='d95;money_drink<=12'b0000_1001_0101; end
  14. endcase
  15. end
  16. end

        money_in转化为BCD码:

这个信号的处理采用直接赋值的方式,直接对数据的[3:0]、[7:4]进行赋值来实现;

  1. always@(posedge clk or negedge rst)begin
  2. if(!rst) begin
  3. money_in<=12'd0;
  4. money_2<='d0;
  5. end
  6. else if(money_in[3:0]>4'b1001)begin
  7. money_in[3:0]<=money_in[3:0]-4'b1010;
  8. money_in[7:4]<=money_in[7:4]+1'b1;
  9. end
  10. else if(money_in[7:4]>4'b1001)begin
  11. money_in[7:4]<=money_in[3:0]-4'b1010;
  12. money_in[11:8]<=money_in[7:0]+1'b1;
  13. end
  14. else if(key1) begin
  15. money_in[3:0]<=money_in[3:0]+4'b0101;
  16. money_2<=money_2+'d5;
  17. end
  18. else if(key2) begin
  19. money_in[7:4]<=money_in[7:4]+4'b0001;
  20. money_2<=money_2+'d10;
  21. end
  22. else if(key3) begin
  23. money_in[7:4]<=money_in[7:4]+4'b0101;
  24. money_2<=money_2+'d50;
  25. end
  26. else if(key4) begin
  27. money_in[11:8]<=money_in[11:8]+4'b0001;
  28. money_2<=money_2+'d100;
  29. end
  30. else
  31. money_in<=money_in;
  32. end

      money_out转化为BCD码 :

对这个部分的操作是一个比较通用的方法:由于BCD码只对0到9的数据有效,所以当我们这个数据:x

10=<x<20时, 给数据的[7:4]加1,[3:0]赋一个x-10;

20=<x<30时, 给数据的[7:4]加2,[3:0]赋一个x-20;

...以此类推;

  1. always@(posedge clk or negedge rst) begin
  2. if(rst==0)
  3. money_3<=0;
  4. else if(money_2>=money_1&&flag[2]==0)
  5. money_3<=money_2-money_1;
  6. else
  7. money_3<=money_3;
  8. end
  9. always@(posedge clk or negedge rst) begin
  10. if(rst==0)
  11. money_out<=0;
  12. else if(money_out[3:0]>4'b1001)begin
  13. money_out[3:0]<=money_out[3:0]-4'b1010;
  14. money_out[7:4]<=money_out[7:4]+1'b1;
  15. end
  16. else if(money_out[7:4]>4'b1001)begin
  17. money_out[7:4]<=money_out[3:0]-4'b1010;
  18. money_out[11:8]<=money_out[7:0]+1'b1;
  19. end
  20. else if(money_3>='d90&&flag[2]==0) begin
  21. money_out[7:4]<=money_out[7:4]+4'b1001;
  22. money_out[3:0]<=money_3-'d90;
  23. end
  24. else if(money_3>='d80&&flag[2]==0) begin
  25. money_out[7:4]<=money_out[7:4]+4'b1000;
  26. money_out[3:0]<=money_3-'d80;
  27. end
  28. else if(money_3>='d70&&flag[2]==0) begin
  29. money_out[7:4]<=money_out[7:4]+4'b0111;
  30. money_out[3:0]<=money_3-'d70;
  31. end
  32. else if(money_3>='d60&&flag[2]==0) begin
  33. money_out[7:4]<=money_out[7:4]+4'b0110;
  34. money_out[3:0]<=money_3-'d60;
  35. end
  36. else if(money_3>='d50&&flag[2]==0) begin
  37. money_out[7:4]<=money_out[7:4]+4'b0101;
  38. money_out[3:0]<=money_3-'d50;
  39. end
  40. else if(money_3>='d40&&flag[2]==0) begin
  41. money_out[7:4]<=money_out[7:4]+4'b0100;
  42. money_out[3:0]<=money_3-'d40;
  43. end
  44. else if(money_3>='d30&&flag[2]==0) begin
  45. money_out[7:4]<=money_out[7:4]+4'b0011;
  46. money_out[3:0]<=money_3-'d30;
  47. end
  48. else if(money_3>='d20&&flag[2]==0) begin
  49. money_out[7:4]<=money_out[7:4]+4'b0010;
  50. money_out[3:0]<=money_3-'d20;
  51. end
  52. else if(money_3>='d10&&flag[2]==0) begin
  53. money_out[7:4]<=money_out[7:4]+4'b0001;
  54. money_out[3:0]<=money_3-'d10;
  55. end

本模块还有一个对状态机进行控制的转换信号:

由于key1,key2,key3,key4这四个信号都是脉冲信号,要将对其首先判断;

本模块的完整代码为

  1. module money(
  2. input clk,
  3. input rst,
  4. input key1, //消抖后的信号
  5. input key2, //消抖后的信号
  6. input key3, //消抖后的信号
  7. input key4, //消抖后的信号
  8. input [2:0] drink,//货物
  9. output reg [7:0] money_1, //所选货物的价格(二进制)
  10. output reg [7:0] money_2, //所支付的钱数(二进制)
  11. output reg[2:0] flag, //状态机状态转化信号
  12. output reg[11:0] money_in, //所支付的钱数(BCD)
  13. output reg[11:0] money_drink, //所选货物的价格(BCD)
  14. output reg[11:0] money_out //找零的钱数(BCD)
  15. );
  16. reg [7:0] money_3; //找零的钱数(二进制)
  17. //所负的总钱数并转化为bcd码
  18. always@(posedge clk or negedge rst)begin
  19. if(!rst) begin
  20. money_in<=12'd0;
  21. money_2<='d0;
  22. end
  23. else if(money_in[3:0]>4'b1001)begin
  24. money_in[3:0]<=money_in[3:0]-4'b1010;
  25. money_in[7:4]<=money_in[7:4]+1'b1;
  26. end
  27. else if(money_in[7:4]>4'b1001)begin
  28. money_in[7:4]<=money_in[3:0]-4'b1010;
  29. money_in[11:8]<=money_in[7:0]+1'b1;
  30. end
  31. else if(key1) begin
  32. money_in[3:0]<=money_in[3:0]+4'b0101;
  33. money_2<=money_2+'d5;
  34. end
  35. else if(key2) begin
  36. money_in[7:4]<=money_in[7:4]+4'b0001;
  37. money_2<=money_2+'d10;
  38. end
  39. else if(key3) begin
  40. money_in[7:4]<=money_in[7:4]+4'b0101;
  41. money_2<=money_2+'d50;
  42. end
  43. else if(key4) begin
  44. money_in[11:8]<=money_in[11:8]+4'b0001;
  45. money_2<=money_2+'d100;
  46. end
  47. else
  48. money_in<=money_in;
  49. end
  50. //所选饮料的钱数并将其转化为bcd码
  51. always@(posedge clk or negedge rst) begin
  52. if(rst==0)
  53. money_1<=0;
  54. else begin
  55. case(drink)
  56. 3'd000:begin money_1<='d0 ;money_drink<=12'b0000_0000_0000; end
  57. 3'd001:begin money_1<='d10;money_drink<=12'b0000_0001_0000; end
  58. 3'd010:begin money_1<='d35;money_drink<=12'b0000_0011_0101; end
  59. 3'd011:begin money_1<='d45;money_drink<=12'b0000_0100_0101; end
  60. 3'd100:begin money_1<='d50;money_drink<=12'b0000_0101_0000; end
  61. 3'd101:begin money_1<='d60;money_drink<=12'b0000_0110_0000; end
  62. 3'd110:begin money_1<='d85;money_drink<=12'b0000_1000_0101; end
  63. 3'd111:begin money_1<='d95;money_drink<=12'b0000_1001_0101; end
  64. endcase
  65. end
  66. end
  67. //计算所要找的钱并将其转化为BCD码
  68. always@(posedge clk or negedge rst) begin
  69. if(rst==0)
  70. money_3<=0;
  71. else if(money_2>=money_1&&flag[2]==0)
  72. money_3<=money_2-money_1;
  73. else
  74. money_3<=money_3;
  75. end
  76. always@(posedge clk or negedge rst) begin
  77. if(rst==0)
  78. money_out<=0;
  79. else if(money_out[3:0]>4'b1001)begin
  80. money_out[3:0]<=money_out[3:0]-4'b1010;
  81. money_out[7:4]<=money_out[7:4]+1'b1;
  82. end
  83. else if(money_out[7:4]>4'b1001)begin
  84. money_out[7:4]<=money_out[3:0]-4'b1010;
  85. money_out[11:8]<=money_out[7:0]+1'b1;
  86. end
  87. else if(money_3>='d90&&flag[2]==0) begin
  88. money_out[7:4]<=money_out[7:4]+4'b1001;
  89. money_out[3:0]<=money_3-'d90;
  90. end
  91. else if(money_3>='d80&&flag[2]==0) begin
  92. money_out[7:4]<=money_out[7:4]+4'b1000;
  93. money_out[3:0]<=money_3-'d80;
  94. end
  95. else if(money_3>='d70&&flag[2]==0) begin
  96. money_out[7:4]<=money_out[7:4]+4'b0111;
  97. money_out[3:0]<=money_3-'d70;
  98. end
  99. else if(money_3>='d60&&flag[2]==0) begin
  100. money_out[7:4]<=money_out[7:4]+4'b0110;
  101. money_out[3:0]<=money_3-'d60;
  102. end
  103. else if(money_3>='d50&&flag[2]==0) begin
  104. money_out[7:4]<=money_out[7:4]+4'b0101;
  105. money_out[3:0]<=money_3-'d50;
  106. end
  107. else if(money_3>='d40&&flag[2]==0) begin
  108. money_out[7:4]<=money_out[7:4]+4'b0100;
  109. money_out[3:0]<=money_3-'d40;
  110. end
  111. else if(money_3>='d30&&flag[2]==0) begin
  112. money_out[7:4]<=money_out[7:4]+4'b0011;
  113. money_out[3:0]<=money_3-'d30;
  114. end
  115. else if(money_3>='d20&&flag[2]==0) begin
  116. money_out[7:4]<=money_out[7:4]+4'b0010;
  117. money_out[3:0]<=money_3-'d20;
  118. end
  119. else if(money_3>='d10&&flag[2]==0) begin
  120. money_out[7:4]<=money_out[7:4]+4'b0001;
  121. money_out[3:0]<=money_3-'d10;
  122. end
  123. end
  124. //状态机状态转化信号
  125. always@(posedge clk or negedge rst) begin
  126. if(rst==0)
  127. flag<=0;
  128. else if({key1,key2,key3,key4}>0&&flag[0]<=1)
  129. flag[1]<=1;
  130. else if(money_3>0&&flag[1]<=1)
  131. flag[2]<=1;
  132. else if(drink>0)
  133. flag[0]<=1;
  134. else
  135. flag<=0;
  136. end
  137. endmodule

(4)、状态机模块

        本模块的主要功能是控制各个状态的转换,将会有一下状态:IDLE,选货,付钱,找钱;本模块的的输入有:系统时钟、复位信号、flag信号;输出有:一个控制信号来控制数码管的显示;

状态机的工作为:当有人选货时也就是drink>0时flag[0]=1,进入选货状态;当有钱币投入时,也就是{key1,key2,key3,key4}>0(flag[1]=1),进入付钱状态;当所支付的钱数大于等于所选货的钱数时(我在这里加了一个并且本状态至少保持1s,原因是如果一次性所支付的钱数大于或者等于货物的价格时,数码管上只会显示一个时钟周期(20ns)的所支付钱数,时间太短,我们肉眼无法察觉),进入找钱状态;当进入找钱状态五秒后回到IDLE;

状态机的状态转移图为:

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA57Sr572X5YWw5LiO5rW35qOg55qE6L6j6bih5a6k5Y-L,size_20,color_FFFFFF,t_70,g_se,x_16

 本模块的代码为:

  1. module zhaungtai(
  2. input clk,
  3. input rst,
  4. input [2:0] flag,
  5. output reg [2:0] ctrl
  6. );
  7. localparam
  8. IDLE = 4'b0001,
  9. XUANHUO = 4'b0010,
  10. FUQIAN = 4'b0100,
  11. ZHAOQIAN = 4'b1000;
  12. reg [3:0] c_stats;
  13. reg [3:0] n_stats;
  14. reg en_1;
  15. reg en_2;
  16. localparam TIME_1S='d49_999_999;
  17. /* localparam TIME_1S='d4; */
  18. reg [25:0] cnt_1s;
  19. reg [25:0] cnt_1s2;
  20. reg [2:0] cnt_1;
  21. //三段式状态机
  22. always@(posedge clk or negedge rst) begin
  23. if(rst==0)
  24. c_stats<= IDLE;
  25. else
  26. c_stats<= n_stats;
  27. end
  28. always@(*)begin
  29. case(c_stats)
  30. IDLE: begin
  31. if(flag[0])
  32. n_stats<=XUANHUO;
  33. else
  34. n_stats<=IDLE;
  35. end
  36. XUANHUO: begin
  37. if(flag[1])
  38. n_stats<=FUQIAN;
  39. else
  40. n_stats<=XUANHUO;
  41. end
  42. FUQIAN: begin
  43. if(flag[2]&&cnt_1s2==TIME_1S)
  44. n_stats<=ZHAOQIAN;
  45. else
  46. n_stats<=FUQIAN;
  47. end
  48. ZHAOQIAN: begin
  49. if(cnt_1=='d5)
  50. n_stats<=IDLE;
  51. else
  52. n_stats<=ZHAOQIAN;
  53. end
  54. endcase
  55. end
  56. always@(posedge clk or negedge rst) begin
  57. if(rst==0) begin
  58. ctrl<=0;
  59. en_1<=0;
  60. en_2<=0;
  61. end
  62. else if(c_stats==IDLE) begin
  63. ctrl<=3'b000;
  64. en_1<=0;
  65. en_2<=0;
  66. end
  67. else if(c_stats==ZHAOQIAN) begin
  68. ctrl<=3'b100;
  69. en_1<=1;
  70. en_2<=0;
  71. end
  72. else if(c_stats==FUQIAN) begin
  73. ctrl<=3'b010;
  74. en_1<=0;
  75. en_2<=1;
  76. end
  77. else if(c_stats==XUANHUO) begin
  78. ctrl<=3'b001;
  79. en_1<=0;
  80. en_2<=0;
  81. end
  82. end
  83. //
  84. always@(posedge clk or negedge rst) begin
  85. if(rst==0)
  86. cnt_1s<='d0;
  87. else if(cnt_1s == TIME_1S)
  88. cnt_1s<='d0;
  89. else if(en_1==1)
  90. cnt_1s<= cnt_1s + 1'd1;
  91. end
  92. always@(posedge clk or negedge rst) begin
  93. if(rst==0)
  94. cnt_1<=0;
  95. else if(cnt_1=='d4)
  96. cnt_1<=0;
  97. else if(cnt_1s==TIME_1S)
  98. cnt_1<=cnt_1+1'd1;
  99. else
  100. cnt_1<=cnt_1;
  101. end
  102. always@(posedge clk or negedge rst) begin
  103. if(rst==0)
  104. cnt_1s2<='d0;
  105. else if(cnt_1s2 == TIME_1S)
  106. cnt_1s2<='d0;
  107. else if(en_2==1)
  108. cnt_1s2<= cnt_1s2 + 1'd1;
  109. end
  110. endmodule

(5)、led模块

        本模块的主要功能是实现当输入金额小于饮料价值时,LED灯100ms闪烁;输入金额与饮料价值相等时,LED灯常亮;输入金额大于饮料价值时,显示多出的钱数,LED灯2s闪烁。

        本模块的的输入有:系统时钟、复位信号、flag信号、money_1、money_2;输出:led信号;

        本模块实现较为简单,具体代码如下:

  1. module led(
  2. input clk,
  3. input rst,
  4. input [2:0] flag, //状态转化信号
  5. input [7:0] money_1,//所选货物的价格(二进制)
  6. input [7:0] money_2,//所支付的钱数(二进制)
  7. output reg led
  8. );
  9. localparam
  10. TIME_1S ='d49_999_999,
  11. TIME_100MS ='d4999_999;
  12. reg [22:0] cnt_100ms;
  13. reg [25:0] cnt_1s;
  14. always@(posedge clk or negedge rst)begin
  15. if(rst==0)
  16. cnt_1s<=0;
  17. else if(cnt_1s==TIME_1S)
  18. cnt_1s<=0;
  19. else
  20. cnt_1s<=cnt_1s+1'd1;
  21. end
  22. always@(posedge clk or negedge rst)begin
  23. if(rst==0)
  24. cnt_100ms<=0;
  25. else if(cnt_100ms==TIME_100MS)
  26. cnt_100ms<=0;
  27. else
  28. cnt_100ms<=cnt_100ms+1'd1;
  29. end
  30. always@(posedge clk or negedge rst)begin
  31. if(rst==0)
  32. led<=0;
  33. else if(money_1>money_2 && cnt_100ms==TIME_100MS)
  34. led<=~led;
  35. else if(money_1==money_2 && flag>0)
  36. led<=1;
  37. else if(money_1<money_2 && cnt_1s==TIME_1S)
  38. led<=~led;
  39. end
  40. endmodule

(6)、显示模块

        本模块的主要功能是将此状态下所要展示的数据显示在数码管上;本模块的的输入有:系统时钟、复位信号、ctrl信号、date1,date2,date3;输出:数码管的段选和位选;

        看到这里,我们一直所没有注意到问题:无论是产品的价格和所支付的钱数亦或是所要找零的钱数都会出现浮点数,我们的解决办法是给所有数据乘以10,在数据的第二位让其小数点常亮,也就是当动态扫描到sel[1]时;seg[7]为0;其余位置seg[7]都为1;

        本模块的代码为:

  1. module xianshi(
  2. input clk,
  3. input rst,
  4. input [2:0] ctrl,
  5. input [11:0] date1,//数据信号
  6. input [11:0] date2,//数据信号
  7. input [11:0] date3,//数据信号
  8. output reg [3:0] sel, // 数码管位选(选择当前要显示的数码管)
  9. output reg [7:0] seg // 数码管段选(选择当前要显示的内容)
  10. );
  11. reg [14:0] cnt_1; //分频记数的计数器
  12. reg clk_out; //分频后的时钟信号
  13. /* reg [3:0] sel_r; //表示那个数码管亮 */
  14. reg [3:0] date_tmp;
  15. reg [11:0] disp_data;
  16. localparam TIME='d24999;
  17. /* localparam TIME='d4; */
  18. always@(posedge clk or negedge rst) begin
  19. if(rst==0)
  20. disp_data<=0;
  21. else
  22. case(ctrl)
  23. 3'b001:disp_data<=date1;
  24. 3'b010:disp_data<=date2;
  25. 3'b100:disp_data<=date3;
  26. default:disp_data<=0;
  27. endcase
  28. end
  29. //cnt_1的记数模块
  30. always@(posedge clk or negedge rst) begin
  31. if(rst==0)
  32. cnt_1 <= 15'd0;
  33. else if(cnt_1 ==TIME)
  34. cnt_1 <= 15'd0;
  35. else
  36. cnt_1 <= cnt_1+1'd1;
  37. end
  38. //时钟分频模块
  39. always@(posedge clk or negedge rst) begin
  40. if(rst==0)
  41. clk_out<=1'b0;
  42. else if(cnt_1== TIME)
  43. clk_out<=~clk_out;
  44. else
  45. clk_out<=clk_out;
  46. end
  47. //移位寄存器
  48. always@(posedge clk_out or negedge rst) begin
  49. if(rst==0)
  50. sel<=4'b1110;
  51. else
  52. sel[2:0]<={sel[1:0],sel[2]};
  53. /* if(rst==0)
  54. sel_r<=4'b0001;
  55. else
  56. sel_r<={sel_r[2:0],sel_r[3]}; */
  57. end
  58. //四选一多路器
  59. always@(*) begin
  60. case(sel)
  61. 4'b1110 : date_tmp <= disp_data[3:0];
  62. 4'b1101 : date_tmp <= disp_data[7:4];
  63. 4'b1011 : date_tmp <= disp_data[11:8];
  64. default:date_tmp<=4'b0000;
  65. endcase
  66. end
  67. //字典(译码器)
  68. always@(*) begin
  69. if(sel[2:0]==3'b101)begin
  70. case(date_tmp)
  71. 4'h0:seg<=8'b01000000;
  72. 4'h1:seg<=8'b01111001;
  73. 4'h2:seg<=8'b00100100;
  74. 4'h3:seg<=8'b00110000;
  75. 4'h4:seg<=8'b00011001;
  76. 4'h5:seg<=8'b00010010;
  77. 4'h6:seg<=8'b00000010;
  78. 4'h7:seg<=8'b01111000;
  79. 4'h8:seg<=8'b00000000;
  80. 4'h9:seg<=8'b00010000;
  81. endcase
  82. end
  83. else begin
  84. case(date_tmp)
  85. 4'h0:seg<=8'b11000000;
  86. 4'h1:seg<=8'b11111001;
  87. 4'h2:seg<=8'b10100100;
  88. 4'h3:seg<=8'b10110000;
  89. 4'h4:seg<=8'b10011001;
  90. 4'h5:seg<=8'b10010010;
  91. 4'h6:seg<=8'b10000010;
  92. 4'h7:seg<=8'b11111000;
  93. 4'h8:seg<=8'b10000000;
  94. 4'h9:seg<=8'b10010000;
  95. endcase
  96. end
  97. end
  98. endmodule

 

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/762663
推荐阅读
相关标签
  

闽ICP备14008679号