joe 发表于 2021-9-1 10:30:18

chisel实现三状态的Mealy FSM

前面介绍了Moore和Mealy FSM,当用于边沿检测的时候,比如说,val risingEdge = din & (!RegNext(din))
只要这么一句就可以实现上升沿检测,如果用前面所说的Mealy FSM,只用zero和one两个状态以Mealy进行检测
处理则一般不会这么处理,除非有多个状态才会用Mealy FSM处理比较合适。所以下面我将状态由二个变为三个,
然后再用Moore FSM处理上升沿检测,如下图:

图中,puls状态只有一个周期,然后要么返回zero状态要么返回one状态,然后再等待输入为0.
import chisel3._
import chisel3.util._
class RisingEdge3state extends Module {
val io = IO(new Bundle {
    val din = Input(Bool())
    val risingEdge = Output(Bool())
})
//用util包中的Enum定义三个状态
val zero :: puls :: one :: Nil = Enum(3)
//状态寄存器
val stateReg = RegInit(zero)
//因为是Moore FSM,所以输出信号只与当前状态有关,与输入无关
//在zero状态,如果din为1则状态变到plus
//puls状态,如果din为1则状态变到one否则状态回到zero
switch(stateReg) {//各个is是串行执行的吗????看verilog:if(){}else if(){} else if(){} else{}的关系
    is(zero) {
      when(io.din) {
      stateReg := puls
      }
    }
    is(puls) {
      when(io.din) {
      stateReg := one
      } otherwise {
      //zero状态检测到了上升,但此周期ts之前居然又加到了0电平,说明是一个干扰
      //在用 din & !RegNext(din)这种语句检测时,只要检测到了1,下个周期ts之前加到0,输出还是不会变为1
      stateReg := zero
      }
    }
    is(one) {

      when(!io.din) { //如果电平不回到0,状态不需要改变回zero
      stateReg := zero
      }
    }
}
io.risingEdge := stateReg === puls//输出是不是puls状态
}
从代码中可以看到寄存器所对应的D触发器比二状态的Mealy FSM或直接din & !RegNext(din)版本需求量多一倍,
当然,状态转移逻辑也要复杂多了。

从时序图中可以看到Mealy输出紧紧跟随上升边沿,Moore输出在时钟tick之后上升。我们可以看到Moore输出是一个
时钟周期的宽度,而Mealy输出一般小于一个时钟周期。
从上面的例子可以发现Mealy FSM需要更少的状态和逻辑,并比Moore FSM反应更快。但是,在一个Mealy中,组合电路可能在更大规模需求上。
很多时候都是用FSM做通信,这个组合通路可能很长,其次,如果FSM的通信形成一个圆圈,会造成组合闭环,在同步电路设计中是错误的。
总结来说,Moore FSM在状态机间通信的组合是更好的选择,它们比Mealy FSM更稳定。使用Mealy FSM只是当关注在相同周期的反应下更为重要。

joe 发表于 2021-9-1 10:31:04

对应的verilog文件内容如下:
module RisingEdge3state(
input   clock,
input   reset,
input   io_din,
outputio_risingEdge
);
reg stateReg; // @
reg _RAND_0;
wire_T = 2'h0 == stateReg; // @
wire_T_1 = 2'h1 == stateReg; // @
wire_T_2 = 2'h2 == stateReg; // @
wire_T_3 = ~io_din; // @
assign io_risingEdge = stateReg == 2'h1; // @

always @(posedge clock) begin
    if (reset) begin
      stateReg <= 2'h0;
    end else if (_T) begin
      if (io_din) begin
      stateReg <= 2'h1;
      end
    end else if (_T_1) begin
      if (io_din) begin
      stateReg <= 2'h2;
      end else begin
      stateReg <= 2'h0;
      end
    end else if (_T_2) begin
      if (_T_3) begin
      stateReg <= 2'h0;
      end
    end
end
endmodule
页: [1]
查看完整版本: chisel实现三状态的Mealy FSM