自动售卖机状态机设计精解

设计状态机时有一个很好用的问题:

"当前输入消失以后,我还需要记住什么信息?"

实现自动售卖机功能,A饮料5元钱,B饮料10元钱,售卖机可接收投币5元钱和10元钱,每次投币只可买一种饮料,考虑找零的情况。

电路的接口如下图所示。sel信号会先于din信号有效,且在购买一种饮料时值不变。

  • sel为选择信号,用来选择购买饮料的种类,sel=0,表示购买A饮料,sel=1,表示购买B饮料;

  • din表示投币输入,din=0表示未投币,din=1表示投币5元,din=2表示投币10元,不会出现din=3的情况;

  • drinks_out表示饮料输出,drinks_out=0表示没有饮料输出,drinks_out=1表示输出A饮料,drinks_out=2表示输出B饮料,不出现drinks_out =3的情况,输出有效仅保持一个时钟周期;

  • change_out表示找零输出,change_out=0表示没有找零,change_out=1表示找零5元,输出有效仅保持一个时钟周期。

    `timescale 1ns/1ns

    module sale(
    input clk,
    input rst_n,
    input sel,
    input [1:0] din,

    复制代码
      output reg  [1:0]   drinks_out,
      output reg          change_out

    );

    reg state;

    localparam S_ZERO = 1'b0; // 当前余额0元
    localparam S_FIVE = 1'b1; // 当前余额5元

    always @(posedge clk or negedge rst_n) begin

    复制代码
      if (!rst_n) begin
    
          state      <= S_ZERO;
          drinks_out <= 2'd0;
          change_out <= 1'b0;
    
      end
    
      else begin
    
          // 输出只保持一个时钟周期
          drinks_out <= 2'd0;
          change_out <= 1'b0;
    
          case(state)
    
              //============================
              // 当前没有余额
              //============================
              S_ZERO: begin
    
                  // 购买A饮料:5元
                  if (sel == 1'b0) begin
    
                      // 投5元
                      if (din == 2'd1) begin
    
                          drinks_out <= 2'd1;
    
                      end
    
                      // 投10元
                      else if (din == 2'd2) begin
    
                          drinks_out <= 2'd1;
                          change_out <= 1'b1;
    
                      end
    
                  end
    
    
                  // 购买B饮料:10元
                  else begin
    
                      // 投5元
                      if (din == 2'd1) begin
    
                          // 钱不够,记住已经有5元
                          state <= S_FIVE;
    
                      end
    
                      // 投10元
                      else if (din == 2'd2) begin
    
                          drinks_out <= 2'd2;
    
                      end
    
                  end
    
              end
    
    
              //============================
              // 已经投入5元
              // 这里实际上只可能是在购买B饮料
              //============================
              S_FIVE: begin
    
                  // 再投入5元
                  if (din == 2'd1) begin
    
                      // 5 + 5 = 10
                      drinks_out <= 2'd2;
    
                      state <= S_ZERO;
    
                  end
    
    
                  // 再投入10元
                  else if (din == 2'd2) begin
    
                      // 5 + 10 = 15
                      // 买B饮料10元,找5元
                      drinks_out <= 2'd2;
                      change_out <= 1'b1;
    
                      state <= S_ZERO;
    
                  end
    
              end
    
    
              default: begin
                  state <= S_ZERO;
              end
    
          endcase
    
      end

    end

    endmodule

相关推荐
HQB20261 天前
屹晶微电子 EG1130|2‑24V 输入 / 最高 28V 输出 内置 MOS 异步升压 DC‑DC|SOT23‑6|摄像头 / 车充 / 电池充电电源
嵌入式硬件·硬件工程
HQB20261 天前
屹晶微电子 EG1195|10‑120V/10A+ 外置 MOS 异步降压控制器|ESOP‑8|电动车转换器 / 快充 / 工业电源
嵌入式硬件·硬件工程
海雅达手持终端PDA2 天前
工业手持终端的“去手机化”演进:看海雅达如何以“同轴扫摄”终结工程妥协,重塑工业PDA新范式
android·物联网·智能手机·硬件工程·能源·制造·iot
2501_922639582 天前
率能半导体 SS6840单通道H桥驱动芯片:42V/7A,覆盖打印机、办公自动化、机器人、工业缝纫机四大应用场景
stm32·单片机·嵌入式硬件·硬件工程
ACP广源盛139246256733 天前
6 盘位存储扩展方案选型笔记:YLB3116 @ACP评估记录
笔记·硬件架构·硬件工程·国产芯片
Industio_触觉智能3 天前
瑞芯微工业ADC采集实战-上|AD7616&RK3506 FlexBus高速并行采集落地
嵌入式硬件·硬件架构·硬件工程·adc·瑞芯微·rk3506·flexbus
恒锐丰科技林技术员3 天前
CL5012A 升压型双节锂电池充电芯片方案解析
经验分享·嵌入式硬件·硬件工程
yqj2344 天前
ESP32 S3-智能语音
硬件工程
半导体憨包4 天前
共源共栅(Cascode)功率器件:让 SiC / GaN “兼容“你的硅栅驱动
嵌入式硬件·生成对抗网络·硬件工程·半导体·dc-dc·半导体芯片
2501_922639584 天前
率能半导体 SS6811H双通道H桥驱动芯片:38V/1.6A,覆盖舞台灯光、安防相机、办公自动化、游戏机、机器人五大应用场景
单片机·嵌入式硬件·硬件工程