基于Verilog的洗衣机代码实现100/50时钟周期等待功能问题
洗衣机Verilog指定周期等待逻辑实现方案
核心实现思路
你当前的写法问题在于时序逻辑的always块中,无法在同一个时钟沿的处理分支内直接实现多周期等待,需要新增计数器和状态跳转判断逻辑,具体思路如下:
- 新增1个7位宽的计数器寄存器
cnt,最大可计数到127,满足100/50周期的计数需求 - 原有2位状态位
{state1, state0}对应4个工作状态:00=进水、01=加洗涤剂、10=洗涤、11=脱水,idle状态统一设为2'b00即可,不要赋值x(x值仅可用于仿真,不可综合) - 进入洗涤状态后启动计数,计数满100个周期自动跳转到脱水状态,清空计数器重新计数
- 进入脱水状态后启动计数,计数满50个周期自动跳回idle状态
- 等待计数期间所有输出信号保持当前状态不变,仅计数器递增
修改后完整代码
module Washing_Machine( input clk, input power, input water_full, input detergent_full, input spin_dry, output reg wash_ongoing, output reg spindry_ongoing, output reg state0, output reg state1 ); // 新增内部计数器,7位宽支持最大127计数,满足100/50周期需求 reg [6:0] cnt; always @ (posedge clk) begin if(power == 1'b0) begin wash_ongoing <= 1'b0; spindry_ongoing <= 1'b0; state0 <= 1'b0; state1 <= 1'b0; cnt <= 7'd0; end else begin case({state1, state0}) // 00:进水状态 2'b00: begin cnt <= 7'd0; wash_ongoing <= 1'b0; spindry_ongoing <= 1'b0; // 进水完成跳转到加洗涤剂状态 if(water_full == 1'b1) begin state0 <= 1'b1; state1 <= 1'b0; end // 直接选择脱水模式跳转到脱水状态 else if(spin_dry == 1'b1) begin state0 <= 1'b1; state1 <= 1'b1; spindry_ongoing <= 1'b1; end end // 01:加洗涤剂状态 2'b01: begin cnt <= 7'd0; wash_ongoing <= 1'b0; spindry_ongoing <= 1'b0; // 洗涤剂加完成跳转到洗涤状态 if(detergent_full == 1'b1) begin state0 <= 1'b0; state1 <= 1'b1; wash_ongoing <= 1'b1; end end // 10:洗涤状态,等待100周期 2'b10: begin // 计数未满100,计数器递增,输出保持不变 if(cnt < 7'd99) begin cnt <= cnt + 7'd1; end // 计数满100,跳转到脱水状态 else begin cnt <= 7'd0; wash_ongoing <= 1'b0; spindry_ongoing <= 1'b1; state0 <= 1'b1; state1 <= 1'b1; end end // 11:脱水状态,等待50周期 2'b11: begin // 计数未满50,计数器递增,输出保持不变 if(cnt < 7'd49) begin cnt <= cnt + 7'd1; end // 计数满50,跳回idle状态 else begin cnt <= 7'd0; spindry_ongoing <= 1'b0; state0 <= 1'b0; state1 <= 1'b0; end end endcase end end endmodule
关键逻辑说明
- 计数器从0开始计数,数到99对应100个时钟周期(0~99共100个值),数到49对应50个时钟周期,符合需求
- 等待计数期间,除了计数器递增外,所有输出信号、状态位都保持不变,满足等待期间输出稳定的要求
- 调整了状态跳转逻辑,不再直接根据输入组合跳转,而是以当前状态作为跳转判断核心,符合时序状态机的设计规范
- 所有赋值使用非阻塞赋值
<=,符合时序逻辑的编码规范,避免仿真和综合结果不一致
内容的提问来源于stack exchange,提问作者vi_4005
相关产品推荐
相关产品推荐

