当前位置:   article > 正文

【附源码】基于fpga的自动售货机(三段式状态机)_fpga自动售货机代码

fpga自动售货机代码

目录

1、VL38 自动贩售机1

题目介绍

思路分析

代码实现

仿真文件

2、VL39 自动贩售机2

题目介绍:

题目分析

代码实现

仿真文件

3、状态机基本知识


1、VL38 自动贩售机1

题目介绍

        设计一个自动贩售机,输入货币有三种,为0.5/1/2元,饮料价格是1.5元,要求进行找零,找零只会支付0.5元。

ps:

        1、投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号

        2、注意rst为低电平复位

信号示意图:

波形示意图:

思路分析

代码实现

  1. module seller1(
  2. input wire clk ,
  3. input wire rst ,
  4. input wire d1 , //0.5元
  5. input wire d2 , //1.0元
  6. input wire d3 , //2.0元
  7. output reg out1, //饮料
  8. output reg [1:0]out2 //零钱
  9. );
  10. //*************code***********//
  11. parameter [2:0] s0 = 3'b000,
  12. s1 = 3'b001,
  13. s2 = 3'b010,
  14. s3 = 3'b011,
  15. s4 = 3'b100,
  16. s5 = 3'b101,
  17. s6 = 3'b110;
  18. reg [2:0] curr_state;
  19. reg [2:0] next_state;
  20. //第一段 状态转移
  21. always @(posedge clk or negedge rst)begin
  22. if(!rst)
  23. curr_state <= s0;
  24. else
  25. curr_state <= next_state;
  26. end
  27. //第二段 转移状况
  28. always @(*)begin
  29. case(curr_state)
  30. s0:begin
  31. if(d1) next_state = s1;
  32. else if(d2) next_state = s2;
  33. else if(d3) next_state = s3;
  34. else next_state = next_state; //为什么保持原值next_state,而不是s0?
  35. end
  36. s1:begin
  37. if(d1) next_state = s2;
  38. else if(d2) next_state = s4;
  39. else if(d3) next_state = s5;
  40. else next_state = next_state;
  41. end
  42. s2:begin
  43. if(d1) next_state = s4;
  44. else if(d2) next_state = s3;
  45. else if(d3) next_state = s6;
  46. else next_state = next_state;
  47. end
  48. s3,s4,s5,s6:begin next_state = s0;end
  49. default: begin next_state = s0;end
  50. endcase
  51. end
  52. //第三段 状态输出 moore FSM
  53. always @(posedge clk or negedge rst)begin //为什么用时序电路,而不是组合电路?
  54. if(!rst)
  55. out1 <= 0;
  56. else if(
  57. next_state == s3 ||
  58. next_state == s4 ||
  59. next_state == s5 ||
  60. next_state == s6
  61. )
  62. out1 <= 1; //出货标志
  63. else
  64. out1 <= 0;
  65. end
  66. always @(posedge clk or negedge rst)begin //为什么用时序电路,而不是组合电路?
  67. if(!rst)
  68. out2 <= 0;
  69. else if(next_state == s3)
  70. out2 <= 2'd1; //找零5毛的数量
  71. else if(next_state == s5)
  72. out2 <= 2'd2;
  73. else if(next_state == s6)
  74. out2 <= 2'd3;
  75. else
  76. out2 <= 2'b0;
  77. end
  78. //*************code***********//
  79. endmodule

针对代码中的问题“为什么保持原值next_state,而不是s0?”

答:如下图所示,如果保持s0,因为是组合逻辑,且输入信号d1为半个时钟周期,那么就会导致next_state在s1和s0之间翻转,而不是保持正确的状态s1。

 参考这个回答:

仿真文件

仿真图:

仿真代码:

  1. module tb_seller1;
  2. reg clk;
  3. reg rst;
  4. reg d1,d2,d3;
  5. wire out1;
  6. wire [1:0] out2;
  7. //1、初始化
  8. initial begin
  9. clk = 0;
  10. rst = 0;
  11. d1 = 0;
  12. d2 = 0;
  13. d3 = 0;
  14. end
  15. //2、产生激励
  16. always #5 clk = ~clk;
  17. initial begin
  18. #10;
  19. rst = 1'b1;
  20. #20;
  21. @(posedge clk); {d1,d2,d3}=3'b100; //0.5
  22. @(posedge clk); {d1,d2,d3}=3'b000;
  23. #50;
  24. @(posedge clk); {d1,d2,d3}=3'b010; //1.5
  25. @(posedge clk); {d1,d2,d3}=3'b000;
  26. #30;
  27. @(posedge clk); {d1,d2,d3}=3'b100; //0.5
  28. @(posedge clk); {d1,d2,d3}=3'b000;
  29. #60;
  30. @(posedge clk); {d1,d2,d3}=3'b100; //1
  31. @(posedge clk); {d1,d2,d3}=3'b000;
  32. #50;
  33. @(posedge clk); {d1,d2,d3}=3'b001; //3
  34. @(posedge clk); {d1,d2,d3}=3'b000;
  35. #50;
  36. @(posedge clk); {d1,d2,d3}=3'b001; //2
  37. @(posedge clk); {d1,d2,d3}=3'b000;
  38. #30;
  39. @(posedge clk); {d1,d2,d3}=3'b100; //0.5
  40. @(posedge clk); {d1,d2,d3}=3'b000;
  41. #60;
  42. @(posedge clk); {d1,d2,d3}=3'b001; //2.5
  43. @(posedge clk); {d1,d2,d3}=3'b000;
  44. #50;
  45. @(posedge clk); {d1,d2,d3}=3'b010; //1
  46. @(posedge clk); {d1,d2,d3}=3'b000;
  47. #60;
  48. @(posedge clk); {d1,d2,d3}=3'b010; //2
  49. @(posedge clk); {d1,d2,d3}=3'b000;
  50. end
  51. //3、仿真暂停
  52. initial begin
  53. #1000
  54. $finish();
  55. end
  56. //4、实例化
  57. seller1 u1_seller1(
  58. .clk(clk),
  59. .rst(rst),
  60. .d1 (d1), //0.5元
  61. .d2 (d2), //1.0元
  62. .d3 (d3), //2.0元
  63. .out1(out1), //饮料
  64. .out2(out2) //零钱
  65. );
  66. endmodule

2、VL39 自动贩售机2

题目介绍:

        设计一个自动贩售机,输入货币有两种,为0.5/1元,饮料价格是1.5/2.5元,要求进行找零,找零只会支付0.5元。

ps:

        1、投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号

        2、此题忽略出饮料后才能切换饮料的问题

        注意rst为低电平复位

波形示意图:

题目分析

代码实现

  1. module seller2(
  2. input wire clk ,
  3. input wire rst ,
  4. input wire d1 , //0.5元
  5. input wire d2 , //1.0元
  6. input wire sel , //0选择1.5元、1选择2.5元
  7. output reg out1, //饮料1(1.5元)
  8. output reg out2, //饮料2(2.5元)
  9. output reg [1:0]out3 //零钱
  10. );
  11. //*************code***********//
  12. parameter [2:0] s0 = 3'b000,
  13. s1 = 3'b001,
  14. s2 = 3'b010,
  15. s3 = 3'b011,
  16. s4 = 3'b100,
  17. s5 = 3'b101,
  18. s6 = 3'b110;
  19. reg [2:0] curr_state;
  20. reg [2:0] next_state;
  21. //第一段 状态转移
  22. always @(posedge clk or negedge rst)begin
  23. if(!rst)
  24. curr_state <= s0;
  25. else
  26. curr_state <= next_state;
  27. end
  28. //第二段 转移状况
  29. always @(*)begin
  30. case(curr_state)
  31. s0: begin
  32. if(d1) next_state = s1;
  33. else if(d2) next_state = s2;
  34. else next_state = next_state;
  35. end
  36. s1: begin
  37. if(d1) next_state = s2;
  38. else if(d2) next_state = s3;
  39. else next_state = next_state;
  40. end
  41. s2: begin
  42. if(d1) next_state = s3;
  43. else if(d2) next_state = s4;
  44. else next_state = next_state;
  45. end
  46. s3: begin
  47. if(!sel) //选择饮料是1.5元还是2元
  48. begin next_state = s0; end
  49. else begin
  50. if(d1) next_state = s4;
  51. else if(d2) next_state = s5;
  52. else next_state = next_state;
  53. end
  54. end
  55. s4: begin
  56. if(!sel)
  57. begin next_state = s0; end
  58. else begin
  59. if(d1) next_state = s5;
  60. else if(d2) next_state = s6;
  61. else next_state = next_state;
  62. end
  63. end
  64. s5: begin next_state = s0; end
  65. s6: begin next_state = s0; end
  66. default: begin next_state = s0;end
  67. endcase
  68. end
  69. /********* 第三段 状态输出 moore FSM ************/
  70. //出货标志
  71. always @(posedge clk or negedge rst)begin
  72. if(!rst)begin
  73. out1 <= 0;
  74. out2 <= 0;
  75. end
  76. else if(sel==0 && (next_state == s3 || next_state == s4) )
  77. out1 <= 1; //饮料1
  78. else if(sel==1 && (next_state == s5 || next_state == s6) )
  79. out2 <= 1; //饮料2
  80. else begin
  81. out1 <= 0;
  82. out2 <= 0;
  83. end
  84. end
  85. //找零数量
  86. always @(posedge clk or negedge rst)begin
  87. if(!rst)
  88. out3 <= 0;
  89. else if(sel==0 && (next_state == s4) )
  90. out3 <= 2'd1; //饮料1
  91. else if(sel==1 && (next_state == s6) )
  92. out3 <= 2'd1; //饮料2
  93. else
  94. out3 <= 2'b0;
  95. end
  96. //*************code***********//
  97. endmodule

仿真文件

仿真图如下:

3、状态机基本知识

 


以上是mealy和moore型状态机的实现区别,注意在代码里理解!

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

闽ICP备14008679号