FSM을 이번에는 when문이 아니라, switch문으로 구현하는 차이점 뿐이다.
즉 간단하다.
// See LICENSE.txt for license details.
package problems
import chisel3.iotesters.PeekPokeTester
class VendingMachineSwitchTests(c: VendingMachineSwitch) extends PeekPokeTester(c) {
var money = 0
var isValid = false
for (t <- 0 until 20) {
val coin = rnd.nextInt(3)*5
val isNickel = coin == 5
val isDime = coin == 10
// Advance circuit
poke(c.io.nickel, if (isNickel) 1 else 0)
poke(c.io.dime, if (isDime) 1 else 0)
step(1)
// Advance model
money = if (isValid) 0 else money + coin
isValid = money >= 20
// Compare
expect(c.io.valid, if (isValid) 1 else 0)
}
}
내부적으로 money 변수를 유지하고, 20 이상인지의 여부를 정답으로 생성하여
Chisel 모듈의 답과 비교하는 간단한 테스트코드이다.
// See LICENSE.txt for license details.
package problems
import chisel3._
import chisel3.util._
// Problem:
//
// Implement a vending machine using a 'switch' statement.
// 'nickel' is a 5 cent coin
// 'dime' is 10 cent coin
// 'sOk' is reached when there are coins totalling 20 cents or more in the machine.
// The vending machine should return to the 'sIdle' state from the 'sOk' state.
//
class VendingMachineSwitch extends Module {
val io = IO(new Bundle {
val nickel = Input(Bool())
val dime = Input(Bool())
val valid = Output(Bool())
})
val sIdle :: s5 :: s10 :: s15 :: sOk :: Nil = Enum(5)
val state = RegInit(sIdle)
switch (state) {
is (sIdle) {
when (io.nickel) { state := s5 }
when (io.dime) { state := s10 }
}
// Implement below ----------
is (s5){
when(io.nickel){ state := s10}
when(io.dime){ state := s15}
}
is (s10){
when(io.nickel){ state := s15}
when(io.dime){ state := sOk}
}
is (s15){
when(io.nickel){ state := sOk}
when(io.dime){ state := sOk}
}
is (sOk){
when(io.nickel){ state := sIdle}
when(io.dime){ state := sIdle}
}
// Implement above ----------
}
io.valid := (state === sOk)
}
// See LICENSE.txt for license details.
package problems
import chisel3._
import chisel3.util._
// Problem:
//
// Implement a vending machine using a 'switch' statement.
// 'nickel' is a 5 cent coin
// 'dime' is 10 cent coin
// 'sOk' is reached when there are coins totalling 20 cents or more in the machine.
// The vending machine should return to the 'sIdle' state from the 'sOk' state.
//
class VendingMachineSwitch extends Module {
val io = IO(new Bundle {
val nickel = Input(Bool())
val dime = Input(Bool())
val valid = Output(Bool())
})
val sIdle :: s5 :: s10 :: s15 :: sOk :: Nil = Enum(5)
val state = RegInit(sIdle)
switch (state) {
is (sIdle) {
when (io.nickel) { state := s5 }
when (io.dime) { state := s10 }
}
// Implement below ----------
is (s5){
when(io.nickel){ state := s10}
when(io.dime){ state := s15}
}
is (s10){
when(io.nickel){ state := s15}
when(io.dime){ state := sOk}
}
is (s15){
when(io.nickel){ state := sOk}
when(io.dime){ state := sOk}
}
is (sOk){
state := sIdle
}
// Implement above ----------
}
io.valid := (state === sOk)
}
고쳤고, 통과했다.
... // default values here
switch ( myState ) {
is( state1 ) {
... // some logic here
}
is( state2 ) {
... // some logic here
}
}