演示如何使用switch/is來實現狀態機。
參考連接:
https://github.com/ucb-bar/chisel-tutorial/blob/release/src/main/scala/solutions/VendingMachineSwitch.scala
1. 引入Chisel3
2. 繼承自Module類
3. 定義輸入輸出接口
建立各項輸入輸出接口。
val nickel = Input(Bool())
a. 使用Bool()建立布爾型數,位寬爲1;
b. 使用UInt建立無符號整型數;
c. 使用Input/Output表示接口方向;
d. val 關鍵字代表定義的變量是所屬匿名Bundle子類的數據成員;
4. 內部鏈接
1) 建立5個狀態:val sIdle :: s5 :: s10 :: s15 :: sOk :: Nil = Enum(5)
2) 使用switch/is判斷邏輯嵌套實現狀態機;
如同when/elsewhen/otherwise判斷結構的實現方式,switch/is分別接收兩個參數列表,分別是判斷條件和要執行的call-by-name代碼塊。
5. 生成Verilog
能夠直接點運行符號運行。
也可使用sbt shell執行:
略
生成Verilog以下:
略
6. 測試
略
7. 附錄
VendingMachineSwitch.scala:
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 }
}
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
}
}
io.valid := (state === sOk)
}
object VendingMachineSwitchMain {
def main(args: Array[String]): Unit = {
chisel3.Driver.execute(Array("--target-dir", "generated/VendingMachineSwitch"), () => new VendingMachineSwitch)
}
}