如何在 Chisel 中将状态机拆分为多个 类 或特征?

How to Split a State Machine in multiple Classes or Traits in Chisel?

我正在尝试将状态机拆分为多个特征,因此每个状态一个特征。 每个状态都有一个子状态机,所以除法会使代码对我来说更具可读性。

实际上我在第一个 when 语句时失败了。

我的实际测试代码如下所示:

class A extends Module with B{
    val io = IO(
        new Bundle{
            val state = Output(UInt(2.W))
            val substate = Output(UInt(2.W))
        }
    )

    lazy val state = RegInit(0.U(2.W))
    lazy val substate = RegInit(0.U(2.W))
    io.state := state
    io.substate := substate
}

trait B{
    def state : UInt
    def substate : UInt

    when(state === 0.U){
        state := 1.U
        substate := ~substate
    }
}

生成 verilog 代码时,它会忽略切换子状态的时间。 所以带有分配的verilog“总是”看起来像这样:

  assign _T_7 = state == 2'h0; // @[traittest.scala 25:16:@9.4]
  assign _T_11 = ~ substate; // @[traittest.scala 27:21:@13.6]
  always @(posedge clock) begin
    if (reset) begin
      state <= 2'h0;
    end else begin
      if (_T_7) begin
        state <= 2'h1;
      end
    end
    if (reset) begin
      substate <= 2'h0;
    end else begin
      substate <= _T_11;
    end
  end

我尝试使用状态和子状态 val 的 override 和 protected 修饰符进行尝试,但没有任何区别,而且我不知道如何让它工作。也许特征不是正确的构造?

好问题。我认为您在 类 的构建过程中被评估顺序所困扰。在评估惰性值之前执行特征。通过搜索 chisel3 repo 的问题可以找到对状态机构造的一些兴趣,你应该在那里四处看看。

但要立即考虑,请查看 This executable example。这是来源,我认为它可能接近您要查找的内容。

import chisel3._
import chisel3.stage.ChiselStage
import chiseltest._
import chiseltest.experimental.ChiselTestShell

trait State {
  def state: UInt
  def substate: UInt
}

class A extends Module with State {
    val io = IO(
        new Bundle{
            val state = Output(UInt(2.W))
            val substate = Output(UInt(2.W))
        }
    )

    val state = RegInit(0.U(2.W))
    val substate = RegInit(0.U(2.W))
  
    new B(state, substate)
    new C(state, substate)
  
    io.state := state
    io.substate := substate
}

class B(val state: UInt, val substate: UInt) extends State {
    when(state === 0.U){
        state := 1.U
        substate := ~substate
    }
}

class C(val state: UInt, val substate: UInt) extends State {
    when(state === 1.U){
        state := 2.U
        substate := substate + 1.U
    }
}

println((new ChiselStage()).emitVerilog(new A))