summaryrefslogtreecommitdiff
path: root/src/test/scala/cookbook/FSM.scala
blob: 9cc0ef2a2a3e82365dc8808ee5556f92f0a39ab7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// See LICENSE for license details.

package cookbook

import chisel3._
import chisel3.util._

/* ### How do I create a finite state machine?
 *
 * Use Chisel Enum to construct the states and switch & is to construct the FSM
 * control logic
 */
class DetectTwoOnes extends Module {
  val io = IO(new Bundle {
    val in = Input(Bool())
    val out = Output(Bool())
  })

  val sNone :: sOne1 :: sTwo1s :: Nil = Enum(3)
  val state = RegInit(sNone)

  io.out := (state === sTwo1s)

  switch (state) {
    is (sNone) {
      when (io.in) {
        state := sOne1
      }
    }
    is (sOne1) {
      when (io.in) {
        state := sTwo1s
      } .otherwise {
        state := sNone
      }
    }
    is (sTwo1s) {
      when (!io.in) {
        state := sNone
      }
    }
  }
}

class DetectTwoOnesTester extends CookbookTester(10) {

  val dut = Module(new DetectTwoOnes)

  // Inputs and expected results
  val inputs: Vec[Bool] = Vec(false.B, true.B, false.B, true.B, true.B, true.B, false.B, true.B, true.B, false.B)
  val expected: Vec[Bool] = Vec(false.B, false.B, false.B, false.B, false.B, true.B, true.B, false.B, false.B, true.B)

  dut.io.in := inputs(cycle)
  assert(dut.io.out === expected(cycle))
}

class FSMSpec extends CookbookSpec {
  "DetectTwoOnes" should "work" in {
    assertTesterPasses { new DetectTwoOnesTester }
  }
}