空调机状态机verilog

该文章为汇总文章Verilog学习代码总结的状态机——空调机部分。

该状态机为moore型时序电路。
采用三段式设计方式。

题目要求

设计一个空调机的控制机。温度传感器控制两个输入端temp_high和temp_low, 如果室内温度较高,则temp_high为’1’, 同时temp_low为’0’; 如果室内温度较低,则temp_high为’0’, 同时temp_ low为’1’; 如果室内温度正常,则temp_high为’0’, 同时temp_low为’0’。 根据输入端temp_high和temp_ _low的值来判断当前的状态是: 1.too_hot (太热) ; 2. too_cold (太冷) ; 3.just_right (正好),然后决定输出端heat和cool的值是’1’还是’0’,从而控制是制冷还是制热。

要求:

1.画出有限状态机,标明状态转换条件;

2.写出程序代码,标注说明和解释;

3.写出验证程序,对设计进行全面的验证。


状态转移图

在这里插入图片描述

源代码

module air(clk,rst,temp_high,temp_low,heat,cool);
  input clk,rst,temp_high,temp_low;
  output heat,cool;
  reg heat,cool;
  reg [1:0] cur_state,next_state;
  //定义三个状态
  parameter TOO_HIGH = 2'b10,
            JUST_RIGHT = 2'b00,
            TOO_LOW = 2'b01;

  //时序  设置当前状态为预设的下一状态或初始
  always @(posedge clk or posedge rst) begin
    if(rst)begin
      //重设置零
      cur_state <= JUST_RIGHT;
      next_state <= JUST_RIGHT;
    end else begin
      cur_state <= next_state;
    end
  end

  //根据当前状态决定输出
  always @(cur_state) begin
    case (cur_state)
      TOO_HIGH: begin
        {heat,cool} = 2'b01;
      end 
      JUST_RIGHT: begin
        {heat,cool} = 2'b00;
      end 
      TOO_LOW: begin
        {heat,cool} = 2'b10;
      end 
      default: begin
        {heat,cool} = 2'b00;
      end 
    endcase
  end

  //根据输入决定下一预设状态
  always @(cur_state or temp_high or temp_low) begin
    case (cur_state)
      TOO_HIGH: begin
        next_state = (temp_high == 1)?TOO_HIGH:JUST_RIGHT;
      end
      JUST_RIGHT: begin
        if (temp_high == 1 && temp_low == 0) begin
          next_state = TOO_HIGH;
        end else if (temp_high == 0 && temp_low == 1) begin
          next_state = TOO_LOW;
        end else begin
          next_state = JUST_RIGHT;
        end
      end 
      TOO_LOW: begin
        next_state = (temp_low == 1)?TOO_LOW:JUST_RIGHT;
      end 
      default: begin
        next_state = JUST_RIGHT;
      end 
    endcase
  end
endmodule

测试代码

`timescale 1ns/1ns
module tb_air;
reg clk,rst,temp_high,temp_low;
wire heat,cool;
parameter PERIOD = 10;
parameter CHANGE_PERIOD = 4*PERIOD;

//初始化各值
initial begin
    clk = 1'b0;
    rst = 1'b0;
    temp_high = 1'b0;
    temp_low = 1'b0;
end

//设定时钟周期
initial 
  forever #(PERIOD/2) clk = ~clk;

//重置模块
initial begin
  #PERIOD rst = 1;
  #PERIOD rst = 0;
end

initial begin
  //测试JUST_RIGHT状态下输入改变
  #CHANGE_PERIOD {temp_high,temp_low} = 2'b11;
  #CHANGE_PERIOD {temp_high,temp_low} = 2'b00;
  #CHANGE_PERIOD {temp_high,temp_low} = 2'b01;
  //转入TOO_LOW,测试TOO_LOW状态下输入改变
  #CHANGE_PERIOD {temp_high,temp_low} = 2'b01;
  #CHANGE_PERIOD {temp_high,temp_low} = 2'b11;
  #CHANGE_PERIOD {temp_high,temp_low} = 2'b10;
  //重新转入JUST_RIGHT
  #CHANGE_PERIOD {temp_high,temp_low} = 2'b10;
  //转入TOO_HIGH,测试TOO_HIGH状态下输入改变
  #CHANGE_PERIOD {temp_high,temp_low} = 2'b11;
  #CHANGE_PERIOD {temp_high,temp_low} = 2'b10;
  #CHANGE_PERIOD {temp_high,temp_low} = 2'b00;
  #CHANGE_PERIOD $finish;
end

//实例化模块
air i1(clk,rst,temp_high,temp_low,heat,cool);

endmodule //tb_air 

模拟仿真

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44856695/article/details/106142631