推荐答案
测试一下
题目
设计一个自动售货机系统,卖soda水的,只能投进三种硬币,要正确的找回钱
参考答案与知识点
参考答案
设计一个自动售货机,卖 soda 水,只接受三种硬币(例如 0.5元、1元、2元),需要正确的找零。系统采用有限状态机(FSM)实现,时钟驱动。
1. 模块划分:
- 投币检测模块:同步采样、消抖,识别硬币面值并产生脉冲。
- 状态机控制模块:核心 FSM,记录已投金额,控制输出。
- 找零计算模块:根据当前投币总额与 soda 价格,计算找零硬币个数。
- 输出模块:出水信号、找零脉冲序列。
2. 状态定义:
- IDLE:初始态,等待投币。
- SUM_0.5、SUM_1、SUM_1.5…… 根据当前累计金额定义状态。假设 soda 价格 = 2元,最大投币上限设为 5元(防止金额过大)。
- 状态转换:每来一个硬币脉冲,从当前状态转移到(当前金额+硬币面值)对应的状态。
- 当累计金额 >= 2元时,进入 OUTPUT 状态,输出 soda 并计算找零。
3. 找零逻辑:
- 若总金额 = 2元,不找零。
- 若 >2元,差值 = 总金额 - 2元。按硬币面值从大到小贪婪找零(例如 2、1、0.5)。输出找零脉冲序列,每个脉冲代表一个硬币。
- 找零完成后回到 IDLE,同时将已投金额清零。
4. 易错点:
- 投币检测要防抖,同一硬币只产生一个脉冲。
- 状态转移时注意组合逻辑与时序逻辑分离,避免竞争。
- 找零硬币数量可能很多(大面值优先),输出脉冲需分时产生,不能在同一时钟沿全部输出。建议用移位寄存器或计数器控制找零脉冲间隔。
- 若投币总额超过最大状态值,应有溢出处理(例如拒绝投币或退回多投部分)。
5. 实现提示:
- 用 parameter 定义硬币面值和 soda 价格。
- 两个 always 块:一个组合逻辑计算下一状态和输出,一个时序逻辑更新状态。
- 找零部分可设计为状态机子状态:IDLE -> 找零中(每次输出一个硬币脉冲)-> 完成。
6. 扩展:支持同时投多个硬币(并行投币),需增加并口检测和累加逻辑。
涉及知识点
- 有限状态机(FSM)设计
- 同步投币检测与消抖
- 贪婪找零算法
- 时序逻辑与组合逻辑分离
- 状态溢出处理
- 脉冲分时输出控制