I'm trying to split a state machine into several traits, so one trait per state. Each state has a substate machine, so the division would make the code more readable for me.
Actually I'm failing at the first when statement.
My actual Test Code looks like this:
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
}
}
When generating the verilog code it ignores the when for the toggling of the substate. So the verilog "always" with the assignments looks like this:
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
I tried it with the override and protected modifiers for the state and substate val's but it doesn't make a difference and I have no other idea how to get it working. Perhaps traits aren't the right constructs for that?
Good question. I think you are being bitten by order of evaluation during the construction of your classes. The traits get executed before the lazy vals are evaluated. There has been some interest in state machine construction that can be found by searching in the issues of the chisel3 repo, you should poke around there a little.
But for immediate consideration take a look at This executable example. This is the source, I think it might be close to what you are looking for.
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))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With