risc-v中文社区

 找回密码
 立即注册
查看: 1152|回复: 3

[原创] chisel实现Moore状态机

  [复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-8-29 08:36:09 | 显示全部楼层 |阅读模式
有限状态机(FSM finite-state machine)是数字电路中的基本模块,一个FSM可以被描述为一些状态states和条件.一个FSM有一个初始状态,就是在RESET时被
确定的状态。FSMs也被称为同步时序电路。
FSM的实现包括三个部分:
1)一个具有现在状态的寄存器
2)组合逻辑 它根据现在状态和输入计算下个状态
3)组合逻辑能够计算FSM的输出
当输出只取决于当前状态时称为Moore状态机,当输出不仅取决于当前状态,还同时取决于当前输入称为Mealy状态机.
下图是一个简单的FSM图:

根据上图写对应的chisel代码如下:
import chisel3._
import chisel3.util._
class SimpleFSM extends Module{
  val io = IO(new Bundle {
    val badEvent = Input(Bool())
    val clear = Input(Bool())
    val ringBell = Output(Bool())
  })
  //状态
  val green :: orange :: red ::Nil = Enum(3)  //chisel3.util.Enum(n:Int)产生[0,n)每个值(UInt)都是唯一的seq
  //状态寄存器
  val stateReg = RegInit(green) //用chisel类型初始化RegInit寄存器
  //下个状态逻辑判断
  switch(stateReg) {
    is (green) {
      when (io.badEvent) {
        stateReg := orange
      }
    }
    is (orange) {
      when (io.badEvent) {
        stateReg := red
      } .elsewhen(io.clear) {
        stateReg := green
      }
    }
    is (red) {
      when (io.clear) {
        stateReg := green
      }
    }
  }
  //输出组合逻辑
  io.ringBell := stateReg === red
}
注意:我们并没有引入next_state作为寄存器输入。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-8-29 08:37:20 | 显示全部楼层
计数器、状态机、FIFO是常用三大基础,都需要用chisel实现它们。
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-8-29 08:56:52 | 显示全部楼层
生成的verilog文件内容如下:
module SimpleFSM(
  input   clock,
  input   reset,
  input   io_badEvent,
  input   io_clear,
  output  io_ringBell
);
  reg [1:0] stateReg; // @[SimpleFSM.scala 14:25]
  reg [31:0] _RAND_0;
  wire  _T = 2'h0 == stateReg; // @[Conditional.scala 37:30]
  wire  _T_1 = 2'h1 == stateReg; // @[Conditional.scala 37:30]
  wire  _T_2 = 2'h2 == stateReg; // @[Conditional.scala 37:30]
  assign io_ringBell = stateReg == 2'h2; // @[SimpleFSM.scala 36:15]
`ifdef RANDOMIZE_GARBAGE_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_INVALID_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_MEM_INIT
`define RANDOMIZE
`endif
`ifndef RANDOM
`define RANDOM $random
`endif
`ifdef RANDOMIZE_MEM_INIT
  integer initvar;
`endif
`ifndef SYNTHESIS
initial begin
  `ifdef RANDOMIZE
    `ifdef INIT_RANDOM
      `INIT_RANDOM
    `endif
    `ifndef VERILATOR
      `ifdef RANDOMIZE_DELAY
        #`RANDOMIZE_DELAY begin end
      `else
        #0.002 begin end
      `endif
    `endif
  `ifdef RANDOMIZE_REG_INIT
  _RAND_0 = {1{`RANDOM}};
  stateReg = _RAND_0[1:0];
  `endif // RANDOMIZE_REG_INIT
  `endif // RANDOMIZE
end // initial
`endif // SYNTHESIS
  always @(posedge clock) begin
    if (reset) begin
      stateReg <= 2'h0;
    end else if (_T) begin
      if (io_badEvent) begin
        stateReg <= 2'h1;
      end
    end else if (_T_1) begin
      if (io_badEvent) begin
        stateReg <= 2'h2;
      end else if (io_clear) begin
        stateReg <= 2'h0;
      end
    end else if (_T_2) begin
      if (io_clear) begin
        stateReg <= 2'h0;
      end
    end
  end
endmodule
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-8-29 08:58:37 | 显示全部楼层
简化形式如下:
module SimpleFSM(
  input   clock,
  input   reset,
  input   io_badEvent,
  input   io_clear,
  output  io_ringBell
);
  reg [1:0] stateReg; // @[SimpleFSM.scala 14:25]
  reg [31:0] _RAND_0;
  wire  _T = 2'h0 == stateReg; // @[Conditional.scala 37:30]
  wire  _T_1 = 2'h1 == stateReg; // @[Conditional.scala 37:30]
  wire  _T_2 = 2'h2 == stateReg; // @[Conditional.scala 37:30]
  assign io_ringBell = stateReg == 2'h2; // @[SimpleFSM.scala 36:15]
  always @(posedge clock) begin
    if (reset) begin
      stateReg <= 2'h0;
    end else if (_T) begin
      if (io_badEvent) begin
        stateReg <= 2'h1;
      end
    end else if (_T_1) begin
      if (io_badEvent) begin
        stateReg <= 2'h2;
      end else if (io_clear) begin
        stateReg <= 2'h0;
      end
    end else if (_T_2) begin
      if (io_clear) begin
        stateReg <= 2'h0;
      end
    end
  end
endmodule
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-4-29 05:00 , Processed in 0.018259 second(s), 18 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表