如何在 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))
我正在尝试将状态机拆分为多个特征,因此每个状态一个特征。 每个状态都有一个子状态机,所以除法会使代码对我来说更具可读性。
实际上我在第一个 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))