题目
请设计一个区别两种特定时序的有限状态机FSM:该有限状态机有一个输入w和一个输出z。当w是4个连续的0或4个连续的1时,输出z=1,否则z=0,时序允许重叠。即:若w是连续的5个1时,则在第4个和第5个时钟之后,z均为1。
chisel
main.scala
import chisel3._
import chisel3.util._
class FSM extends Module{
val io = IO(new Bundle{
val in = Input(UInt(1.W))
val out = Output(UInt(1.W))
})
//很奇怪,必须要多一个状态 否则无法识别s9
val s1 :: s2 :: s3 :: s4 :: s5 :: s6 :: s7 :: s8 :: s9 ::nano = Enum(10)
val stage = RegInit(s1)
//这里原本设计是Reg类型,但是会有一拍的延迟,所以后面改为Wire类型
val outReg = Wire(UInt(1.W))
outReg := 0.U
//友情提醒,switch is 中不能直接给IO赋值
//否则报错。改道用When就可以可以直接给IO赋值
switch(stage){
is(s1){
when(io.in === 0.U){
stage := s2
}.otherwise{
stage := s6
}
}
is(s2){
when(io.in === 0.U){
stage := s3
outReg := 0.U
}.otherwise{
stage := s6
outReg := 0.U
}
}
is(s3){
when(io.in === 0.U){
stage := s4
}.otherwise{
stage := s6
}
}
is(s4){
when(io.in === 0.U){
stage := s5
}.otherwise{
stage := s6
}
}
is(s5){
when(io.in === 0.U){
stage := s5
outReg := 1.U
}.otherwise{
stage := s6
}
}
is(s6){
when(io.in === 0.U){
stage := s2
outReg := 0.U
}.otherwise{
stage := s7
outReg := 0.U
}
}
is(s7){
when(io.in === 0.U){
stage := s2
}.otherwise{
stage := s8
}
}
is(s8){
when(io.in === 0.U){
stage := s2
}.otherwise{
stage := s9
}
}
is(s9){
when(io.in === 0.U){
stage := s2
}.otherwise{
stage := s9
outReg := 1.U
}
}
}
io.out := outReg
}
object MyFSM extends App{
emitVerilog (new FSM(),Array("--target-dir","generate") )
}
test.scala
import chisel3._
import chiseltest._
import scala.util.Random
import org.scalatest.flatspec.AnyFlatSpec
class FSM_Test extends AnyFlatSpec with ChiselScalatestTester{
"Waveform" should "pass" in {
test (new FSM).withAnnotations(Seq(WriteVcdAnnotation)){//WriteVcdAnnotation
dut=>
//val in_a_tb = Random.nextInt(40)
val in_tb = Seq(1.U,0.U,1.U,1.U,1.U,1.U,1.U,1.U,1.U,0.U,0.U,0.U,0.U,0.U,0.U,0.U,0.U)
for(i <- 0 until 17){
println("in_tb = ",in_tb(i))
dut.io.in.poke(in_tb(i))
dut.clock.step()
print("FSM output = ",dut.io.out.peek().toString)
}
}
}
}
波形图