IC学习笔记:02.自动售货饮料-有限状态机-mealy型

第一步:看要求

编写一个自动售货机,功能如下:
1)共有三种纸币入口,分别支持10元,20元,50元;
2)货物售价为80元;
3)需要支持找钱功能(注意,找钱有四种种情况)。
RTL编码,完成testbench编码,用QuestaSim仿真波形通过。

答题

第一步画出状态转移图

有7种状态,状态图从s0到s7如下图
状态转移图

第二步:辨别情况,设置输入输出及s0~s7的状态

(1)输入与输出状态

设置投钱10元为:in10,
设置投钱20元为:in20,
设置投钱50元为:in50
设置出货为:out,
设置找钱10元为: return_10,
设置找钱20元为: return_20,
设置找钱30元为: return_30,
设置找钱40元为: return_40。

(2)s0~s7的状态定义如下

parameter [2:0] s0 = 3’b000,
s1 = 3’b001,
s2 = 3’b010,
s3 = 3’b011,
s4 = 3’b100,
s5 = 3’b101,
s6 = 3’b110,
s7 = 3’b111。

第三步:写RTL如下

module sell(
  output out,
  output return_10,
  output return_20,
  output return_30,
  output return_40,
  input  clk,
  input  reset,
  input  in10,
  input  in20,
  input  in50
  );
  parameter [2:0] s0 = 3'b000,
                  s1 = 3'b001,
                  s2 = 3'b010,
                  s3 = 3'b011,
                  s4 = 3'b100,
                  s5 = 3'b101,
                  s6 = 3'b110,
                  s7 = 3'b111;
  reg [2:0] curr_state;  //Temporary variables are defined
  reg [2:0] next_state;
//First segment: state transfer(state transitions are clock-dependent)
  always@(posedge clk, negedge reset)
    begin
      if (!reset)
        curr_state <= s0;
        else
          curr_state <= #1 next_state;
    end
//Second segment: transfer condition(condition are state-dependent)
  always@(curr_state, in10, in20, in50)
    begin
      case(curr_state) //curr_state have many conditions
        s0: begin
              if (in10)        next_state = s1;
              else if (in20)   next_state = s2;
              else if (in50)   next_state = s5;
              else             next_state = s0;
            end
        s1: begin
              if (in10)        next_state = s2;
              else if (in20)   next_state = s3;
              else if (in50)   next_state = s6;
              else             next_state = s1;
            end
        s2: begin
              if (in10)        next_state = s3;
              else if (in20)   next_state = s4;
              else if (in50)   next_state = s7;
              else             next_state = s2;
            end
        s3: begin
              if (in10)        next_state = s4;
              else if (in20)   next_state = s5;
              else if (in50)   next_state = s0;
              else             next_state = s3;
            end
        s4: begin
              if (in10)        next_state = s5;
              else if (in20)   next_state = s5;
              else if (in50)   next_state = s0;
              else             next_state = s4;
            end
        s5: begin
              if (in10)        next_state = s6;
              else if (in20)   next_state = s7;
              else if (in50)   next_state = s0;
              else             next_state = s5;
            end
        s6: begin
              if (in10)        next_state = s7;
              else if (in20)   next_state = s0;
              else if (in50)   next_state = s0;
              else             next_state = s6;
            end
        s7: begin
              if (in10)        next_state = s0;
              else if (in20)   next_state = s0;
              else if (in50)   next_state = s0;
              else             next_state = s7;
            end
            default:           next_state = s0;
      endcase
    end
//Third sement: state ouput 
//mealy type FSM
  assign out = ((curr_state == s7) & (in10 | in20 | in50)) ? 1 : 
               ((curr_state == s6) & (in20 | in50)) ? 1 : 
               ((curr_state == s5) & (in50)) ? 1 : 
               ((curr_state == s4) & (in50)) ? 1 : 
               ((curr_state == s3) & (in50)) ? 1 : 0;
  assign return_40 = ((curr_state == s7) & (in50)) ? 1 : 0;
  assign return_30 = ((curr_state == s6) & (in50)) ? 1 : 0;
  assign return_20 = ((curr_state == s5) & (in50)) ? 1 : 0;
  assign return_10 = ((curr_state == s7) & (in20)) ? 1 : 
                     ((curr_state == s4) & (in50)) ? 1 : 0; 
endmodule

第四步:写Testbench如下(这个可以自己随便写的)

module sell_tb();
  wire out;
  wire return_10;
  wire return_20;
  wire return_30;
  wire return_40;
  reg  in10;
  reg  in20;
  reg  in50;
  reg  clk;
  reg  reset;
  initial
    begin
      clk = 0;
      reset = 0;
      #20
      reset = 1;
    end
  always #20 clk = ~clk;
  initial
    begin
      in10 = 0;
      in20 = 0;
      in50 = 0;
      #100
      repeat (8) //after repeat 8 times was spend time of 8*20ns=160ns 
      begin
        @(posedge clk) in10 = 1;
        @(posedge clk) in20 = 0;
        @(posedge clk) in50 = 0;
      end
      #200
      repeat (4) 
      begin
        @(posedge clk) in10 = 0;
        @(posedge clk) in20 = 1;
        @(posedge clk) in50 = 0;
      end
      #200
      repeat (3) 
      begin
        @(posedge clk) in10 = 1;
        @(posedge clk) in20 = 1;
        @(posedge clk) in50 = 0;
      end
      #200
      repeat (2) 
      begin
        @(posedge clk) in10 = 0;
        @(posedge clk) in20 = 0;
        @(posedge clk) in50 = 1;
      end
      #200
      $finish;
    end
  sell u0_sell(
                  .out         (out),
                  .return_10   (return_10),
                  .return_20   (return_20),
                  .return_30   (return_30),
                  .return_40   (return_40),
                  .in10        (in10),
                  .in20        (in20),
                  .in50        (in50),
                  .clk         (clk),
                  .reset       (reset)
                  );
endmodule

观察波形,看看自己的tb输入和波形的情况

波形图如下
波形图

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值