# 【3】Generators contributed by AgainTW --- # 章節 * [【1】Scala 和 Chisel 語法簡記](https://hackmd.io/@nfUUgsYRTGy81y5d9AYOyg/BJdW9obUa) * [【2】組合電路、序向電路和 Control Flow](https://hackmd.io/@nfUUgsYRTGy81y5d9AYOyg/HyWJBxmUa) * [【3】Generators](https://hackmd.io/@nfUUgsYRTGy81y5d9AYOyg/SJZ7kz7L6) * [【4】高階函式與設計](https://hackmd.io/@nfUUgsYRTGy81y5d9AYOyg/rk0Ckf7Lp) * [【5】物件導向設計](https://hackmd.io/@nfUUgsYRTGy81y5d9AYOyg/B1hB1aTLT) * [【6】Generators: Types](https://hackmd.io/@nfUUgsYRTGy81y5d9AYOyg/SJ8tka6U6) * [【7】FIRRTL 簡介](https://hackmd.io/@nfUUgsYRTGy81y5d9AYOyg/HJOjkppIT) * [【8】Chisel 到 Verilog 的中間表示](https://hackmd.io/@nfUUgsYRTGy81y5d9AYOyg/r1URy6aIT) --- # Outline 1. Chisel 生成器如何取得其參數 2. Chisel 的條件分支 3. Implicits 4. Collections 5. 範例3: Mealy machine --- # 隨筆 * 位寬為零的 IO 會從產生的 Verilog 中修剪掉 * Scala Map() 的錯誤使用法: * 錯誤的索引呼叫 * 但使用 .get() 在錯誤呼叫時則會回傳 None ```scala= // 錯誤 val map = Map("a" -> 1) val a = map("a") println(a) val b = map("b") println(b) // 使用 .get() val map = Map("a" -> 1) val a = map.get("a") println(a) val b = map.get("b") println(b) ``` ```shell 1 // 報錯 Some(1) None ``` --- # Chisel 生成器如何取得其參數 ## Scala class 取得參數的語法 ```scala= class ParameterizedScalaObject(param1: Int, param2: String) { println(s"I have parameters: param1 = $param1 and param2 = $param2") } val obj1 = new ParameterizedScalaObject(4, "Hello") val obj2 = new ParameterizedScalaObject(4 + 2, "World") ``` ```shell I have parameters: param1 = 4 and param2 = Hello I have parameters: param1 = 6 and param2 = World ``` ## Chisel module 取得參數的語法 * require(): 這些是預闡述斷言,當構造的生成器僅適用於某些參數或某些參數相互排斥或無意義時,require() 非常有用。 ```scala= class ParameterizedWidthAdder(in0Width: Int, in1Width: Int, sumWidth: Int) extends Module { require(in0Width >= 0) require(in1Width >= 0) require(sumWidth >= 0) val io = IO(new Bundle { val in0 = Input(UInt(in0Width.W)) val in1 = Input(UInt(in1Width.W)) val sum = Output(UInt(sumWidth.W)) }) // a +& b includes the carry, a + b does not io.sum := io.in0 +& io.in1 } println(getVerilog(new ParameterizedWidthAdder(1, 4, 6))) ``` ```mips module ParameterizedWidthAdder( input clock, input reset, input io_in0, input [3:0] io_in1, output [5:0] io_sum ); wire [3:0] _GEN_0 = {{3'd0}, io_in0}; // @[cmd3.sc 11:20] wire [4:0] _T = _GEN_0 + io_in1; // @[cmd3.sc 11:20] assign io_sum = {{1'd0}, _T}; // @[cmd3.sc 11:20] endmodule ``` * chisel module 的輸入可以宣告預設值,或是宣告成```None``` * .isDefined 可以判斷輸入是否不為空,回傳值為 scala 的布林值 ```scala= class DelayBy1(resetValue: Option[UInt] = None) extends Module { val io = IO(new Bundle { val in = Input(UInt(16.W)) val out = Output(UInt(16.W)) }) val reg = if (resetValue.isDefined) { // resetValue = Some(number) RegInit(resetValue.get) } else { //resetValue = None Reg(UInt()) } reg := io.in io.out := reg } println(getVerilog(new DelayBy1)) println(getVerilog(new DelayBy1(Some(3.U)))) ``` ```mips module DelayBy1( input clock, input reset, input [15:0] io_in, output [15:0] io_out ); `ifdef RANDOMIZE_REG_INIT reg [31:0] _RAND_0; `endif // RANDOMIZE_REG_INIT reg [15:0] reg_; // @[cmd8.sc 9:12] assign io_out = reg_; // @[cmd8.sc 12:12] always @(posedge clock) begin reg_ <= io_in; // @[cmd8.sc 11:9] end endmodule ``` ```mips module DelayBy1( input clock, input reset, input [15:0] io_in, output [15:0] io_out ); `ifdef RANDOMIZE_REG_INIT reg [31:0] _RAND_0; `endif // RANDOMIZE_REG_INIT reg [15:0] reg_; // @[cmd8.sc 7:16] assign io_out = reg_; // @[cmd8.sc 12:12] always @(posedge clock) begin if (reset) begin // @[cmd8.sc 7:16] reg_ <= 16'h3; // @[cmd8.sc 7:16] end else begin reg_ <= io_in; // @[cmd8.sc 11:9] end end endmodule ``` --- # Chisel 的條件分支 ## scala 的條件分支 ### 單輸入分支 ```scala= // y is an integer variable defined somewhere else in the code val y = 7 /// ... val x = y match { case 0 => "zero" // One common syntax, preferred if fits in one line case 1 => // Another common syntax, preferred if does not fit in one line. "one" // Note the code block continues until the next case case 2 => { // Another syntax, but curly braces are not required "two" } case _ => "many" // _ is a wildcard that matches all values } println("y is " + x) ``` ```shell y is many ``` ### 多輸入分支 ```scala= def animalType(biggerThanBreadBox: Boolean, meanAsCanBe: Boolean): String = { (biggerThanBreadBox, meanAsCanBe) match { case (true, true) => "wolverine" case (true, false) => "elephant" case (false, true) => "shrew" case (false, false) => "puppy" } } println(animalType(true, true)) ``` ```shell wolverine ``` ### 單類型分支 ```scala= val sequence = Seq("a", 1, 0.0) sequence.foreach { x => x match { case s: String => println(s"$x is a String") case s: Int => println(s"$x is an Int") case s: Double => println(s"$x is a Double") case _ => println(s"$x is an unknown type!") } } ``` ```shell a is a String 1 is an Int 0.0 is a Double ``` ### 多類型分支 ```scala= val sequence = Seq("a", 1, 0.0) sequence.foreach { x => x match { case _: Int | _: Double => println(s"$x is a number!") case _ => println(s"$x is an unknown type!") } } ``` ```shell a is an unknown type! 1 is a number! 0.0 is a number! ``` ### 分支的限制: Erasure * 因為 Scala 運行在 JVM 上,JVM 不維護多態類型,因此會發生以下狀況 * 以下範例總是符合第一個 case 語句,因為 ```[String]```、```[Int]```和```[Double]```多態類型被刪除 * 並且 case 語句實際上僅符合 Seq ```scala= val sequence1 = Seq(Seq("a"), Seq(1), Seq(0.0)) sequence1.foreach { x => x match { case s: Seq[String] => println(s"$x is a String") case s: Seq[Int] => println(s"$x is an Int") case s: Seq[Double] => println(s"$x is a Double") } } val sequence2 = Seq(Seq(1), Seq("a"), Seq(0.0)) sequence2.foreach { x => x match { case s: Seq[String] => println(s"$x is a String") case s: Seq[Int] => println(s"$x is an Int") case s: Seq[Double] => println(s"$x is a Double") } } val sequence3 = Seq(Seq(1), Seq("a"), Seq(0.0)) sequence3.foreach { x => x match { case s: Seq[Int] => println(s"$x is an Int") case s: Seq[String] => println(s"$x is a String") case s: Seq[Double] => println(s"$x is a Double") } } val sequence4 = Seq(Seq("a"), Seq(1), Seq(0.0)) sequence3.foreach { x => x match { case s: Seq[Int] => println(s"$x is an Int") case s: Seq[String] => println(s"$x is a String") case s: Seq[Double] => println(s"$x is a Double") } } ``` ```shell List(a) is a String List(1) is a String List(0.0) is a String List(1) is a String List(a) is a String List(0.0) is a String List(1) is an Int List(a) is an Int List(0.0) is an Int List(a) is an Int List(1) is an Int List(0.0) is an Int ``` ## Chisel 的條件分支寫法 ### 使用 match * 我們可以得到和"Chisel module 取得參數的語法"那裡相同的結果 ```scala= class DelayBy1(resetValue: Option[UInt] = None) extends Module { val io = IO(new Bundle { val in = Input( UInt(16.W)) val out = Output(UInt(16.W)) }) val reg = resetValue match { case Some(r) => RegInit(r) case None => Reg(UInt()) } reg := io.in io.out := reg } println(getVerilog(new DelayBy1)) println(getVerilog(new DelayBy1(Some(3.U)))) ``` ```mips module DelayBy1( input clock, input reset, input [15:0] io_in, output [15:0] io_out ); `ifdef RANDOMIZE_REG_INIT reg [31:0] _RAND_0; `endif // RANDOMIZE_REG_INIT reg [15:0] reg_; // @[cmd18.sc 8:24] assign io_out = reg_; // @[cmd18.sc 11:10] always @(posedge clock) begin reg_ <= io_in; // @[cmd18.sc 10:7] end endmodule ``` ```mips module DelayBy1( input clock, input reset, input [15:0] io_in, output [15:0] io_out ); `ifdef RANDOMIZE_REG_INIT reg [31:0] _RAND_0; `endif // RANDOMIZE_REG_INIT reg [15:0] reg_; // @[cmd18.sc 7:28] assign io_out = reg_; // @[cmd18.sc 11:10] always @(posedge clock) begin if (reset) begin // @[cmd18.sc 7:28] reg_ <= 16'h3; // @[cmd18.sc 7:28] end else begin reg_ <= io_in; // @[cmd18.sc 10:7] end end endmodule ``` --- # Implicits * 基礎語法 * 變數隱式值宣告 * 函數的隱式輸入參數宣告 * 隱式參數可能的失敗時機 * 給定類型的兩個或多個隱式值在作用域中定義 * 如果編譯器找不到函數呼叫所需的隱式值 ```scala= object CatDog { implicit val numberOfCats: Int = 3 //implicit val numberOfDogs: Int = 5 def tooManyCats(nDogs: Int)(implicit nCats: Int): Boolean = nCats > nDogs val imp = tooManyCats(2) // Argument passed implicitly! val exp = tooManyCats(2)(1) // Argument passed explicitly! } CatDog.imp CatDog.exp ``` ```shell res24_1 : Boolean = true res24_2 : Boolean = false ``` ## Chisel 中隱式應用: 生成生成日誌(log) * trait: scala 的結構(struct)定義方式之一 * sealed: 密封。scala 的編譯器會去驗證並枚舉類別或是結構的繼承是否有缺失 * 因此使用 sealed trait 表示宣告一個類別,並且編譯器會去驗證他的宣告和繼承 * 2, 3 行宣告了兩個物件 * 前面有提到 require() 的使用,結合隱式可以用來生成生成日誌或是隱藏他 * log 已經提前定義了 * 加 s 則輸出"in0Width of 1 OK" * 不加 s 則會輸出"in0Width of $in0Width OK" ``` require( 目標判斷式 ) log(s"in0Width of $in0Width OK") ``` * 範例程式碼: ```scala= sealed trait Verbosity implicit case object Silent extends Verbosity case object Verbose extends Verbosity class ParameterizedWidthAdder(in0Width: Int, in1Width: Int, sumWidth: Int)(implicit verbosity: Verbosity) extends Module { def log(msg: => String): Unit = verbosity match { case Silent => case Verbose => println(msg) } require(in0Width >= 0) log(s"in0Width of $in0Width OK") require(in1Width >= 0) log(s"in1Width of $in1Width OK") require(sumWidth >= 0) log(s"sumWidth of $sumWidth OK") val io = IO(new Bundle { val in0 = Input(UInt(in0Width.W)) val in1 = Input(UInt(in1Width.W)) val sum = Output(UInt(sumWidth.W)) }) log("Made IO") io.sum := io.in0 + io.in1 log("Assigned output") } println(getVerilog(new ParameterizedWidthAdder(1, 4, 5))) println(getVerilog(new ParameterizedWidthAdder(1, 4, 5)(Verbose))) ``` ```mips Elaborating design... Done elaborating. module ParameterizedWidthAdder( input clock, input reset, input io_in0, input [3:0] io_in1, output [4:0] io_sum ); wire [3:0] _GEN_0 = {{3'd0}, io_in0}; // @[cmd28.sc 23:20] wire [3:0] _T_1 = _GEN_0 + io_in1; // @[cmd28.sc 23:20] assign io_sum = {{1'd0}, _T_1}; // @[cmd28.sc 23:20] endmodule ``` ```mips Elaborating design... in0Width of 1 OK in1Width of 4 OK sumWidth of 5 OK Made IO Assigned output Done elaborating. module ParameterizedWidthAdder( input clock, input reset, input io_in0, input [3:0] io_in1, output [4:0] io_sum ); wire [3:0] _GEN_0 = {{3'd0}, io_in0}; // @[cmd28.sc 23:20] wire [3:0] _T_1 = _GEN_0 + io_in1; // @[cmd28.sc 23:20] assign io_sum = {{1'd0}, _T_1}; // @[cmd28.sc 23:20] endmodule ``` ## 隱式轉換 * 隱式轉換用於減少樣板程式碼。更具體地說,它們用於自動將一個 Scala 物件轉換為另一個物件。 * 通常,隱式會使您的程式碼變得混亂,因此我們建議您將它們用作最後的手段。首先嘗試繼承、特徵或方法重載 ```scala= class Animal(val name: String, val species: String) class Human(val name: String) implicit def human2animal(h: Human): Animal = new Animal(h.name, "Homo sapiens") val me = new Human("Adam") println(me.species) ``` ```shell Homo sapiens defined class Animal defined class Human defined function human2animal me: Human = ammonite.$sess.cmd30$Helper$Human@75cf0cfc ``` --- # Collections ## 核心想法與範例1 ground truth 函式設計 * 想法1: 把輸入換成可以任意長度的 ```Seq[Int]``` * 想法2: 保存先前週期的值,使用1```var pseudoRegisters = List.fill(input.length)(0)```建立一個 list * 範例說明: * ```::```: [第一章有提到](https://hackmd.io/@nfUUgsYRTGy81y5d9AYOyg/BJdW9obUa) * ```list.indices```: 回傳 list 的所有下標 * 第 13 行的 accumulator 表回傳值 * ground truth 函式 因為不是 extends Module,所以僅能進行 chisel test,無法 getVerilog() ```scala= /** * A naive implementation of an FIR filter with an arbitrary number of taps. */ class ScalaFirFilter(taps: Seq[Int]) { var pseudoRegisters = List.fill(taps.length)(0) def poke(value: Int): Int = { pseudoRegisters = value :: pseudoRegisters.take(taps.length - 1) var accumulator = 0 for(i <- taps.indices) { accumulator += taps(i) * pseudoRegisters(i) } accumulator } } ``` ## 範例1: 單輸入 FIR * 可以根據輸入生成不同的電路 * 範例說明: * ```ArrayBuffer```: scala 的一種集合類型,允許使用 ```+=``` 運算子追加元素 * 使用時需要 ```import scala.collection.mutable.ArrayBuffer``` * 宣告方式大概是這樣 * ```val ints = ArrayBuffer[Int]()``` * ```val names = ArrayBuffer[String]()``` * 最後一個 scan 就是計算加總後的元素 ```scala= class MyManyElementFir(consts: Seq[Int], bitWidth: Int) extends Module { val io = IO(new Bundle { val in = Input(UInt(bitWidth.W)) val out = Output(UInt(bitWidth.W)) }) val regs = mutable.ArrayBuffer[UInt]() for(i <- 0 until consts.length) { if(i == 0) regs += io.in else regs += RegNext(regs(i - 1), 0.U) } val muls = mutable.ArrayBuffer[UInt]() for(i <- 0 until consts.length) { muls += regs(i) * consts(i).U } val scan = mutable.ArrayBuffer[UInt]() for(i <- 0 until consts.length) { if(i == 0) scan += muls(i) else scan += muls(i) + scan(i - 1) } io.out := scan.last } ``` * 輸入為```Seq(1, 1),4``` * 兩個輸入所以生成一個暫存器 ```scala println(getVerilog(new MyManyElementFir(Seq(1, 1),4))) ``` ```mips= module MyManyElementFir( input clock, input reset, input [3:0] io_in, output [3:0] io_out ); `ifdef RANDOMIZE_REG_INIT reg [31:0] _RAND_0; `endif // RANDOMIZE_REG_INIT reg [3:0] regs_1; // @[cmd18.sc 10:33] wire [4:0] muls_0 = io_in * 1'h1; // @[cmd18.sc 15:23] wire [4:0] muls_1 = regs_1 * 1'h1; // @[cmd18.sc 15:23] wire [4:0] scan_1 = muls_1 + muls_0; // @[cmd18.sc 21:28] assign io_out = scan_1[3:0]; // @[cmd18.sc 24:10] always @(posedge clock) begin if (reset) begin // @[cmd18.sc 10:33] regs_1 <= 4'h0; // @[cmd18.sc 10:33] end else begin regs_1 <= io_in; // @[cmd18.sc 10:33] end end endmodule ``` * 輸入為```Seq(1, 1, 1),8``` * 三個輸入所以生成兩個暫存器 ```scala println(getVerilog(new MyManyElementFir(Seq(1, 1, 1),8))) ``` ```mips= module MyManyElementFir( input clock, input reset, input [7:0] io_in, output [7:0] io_out ); `ifdef RANDOMIZE_REG_INIT reg [31:0] _RAND_0; reg [31:0] _RAND_1; `endif // RANDOMIZE_REG_INIT reg [7:0] regs_1; // @[cmd18.sc 10:33] reg [7:0] regs_2; // @[cmd18.sc 10:33] wire [8:0] muls_0 = io_in * 1'h1; // @[cmd18.sc 15:23] wire [8:0] muls_1 = regs_1 * 1'h1; // @[cmd18.sc 15:23] wire [8:0] muls_2 = regs_2 * 1'h1; // @[cmd18.sc 15:23] wire [8:0] scan_1 = muls_1 + muls_0; // @[cmd18.sc 21:28] wire [8:0] scan_2 = muls_2 + scan_1; // @[cmd18.sc 21:28] assign io_out = scan_2[7:0]; // @[cmd18.sc 24:10] always @(posedge clock) begin if (reset) begin // @[cmd18.sc 10:33] regs_1 <= 8'h0; // @[cmd18.sc 10:33] end else begin regs_1 <= io_in; // @[cmd18.sc 10:33] end if (reset) begin // @[cmd18.sc 10:33] regs_2 <= 8'h0; // @[cmd18.sc 10:33] end else begin regs_2 <= regs_1; // @[cmd18.sc 10:33] end end endmodule ``` ## 範例2: 多輸入 FIR * 範例說明: * 能實現多輸入是因為第五行的```val consts = Input(Vec(length, UInt(8.W)))```,能根據生成器輸入決定電路輸入 * 單輸入的係數是在生成電路後就固定,多輸入的再生成電路後還能根據輸入改變係數 * 剩下的部分跟單輸入的差不多 ```scala= class MyManyDynamicElementVecFir(length: Int) extends Module { val io = IO(new Bundle { val in = Input(UInt(8.W)) val out = Output(UInt(8.W)) val consts = Input(Vec(length, UInt(8.W))) }) // Reference solution val regs = RegInit(VecInit(Seq.fill(length - 1)(0.U(8.W)))) for(i <- 0 until length - 1) { if(i == 0) regs(i) := io.in else regs(i) := regs(i - 1) } val muls = Wire(Vec(length, UInt(8.W))) for(i <- 0 until length) { if(i == 0) muls(i) := io.in * io.consts(i) else muls(i) := regs(i - 1) * io.consts(i) } val scan = Wire(Vec(length, UInt(8.W))) for(i <- 0 until length) { if(i == 0) scan(i) := muls(i) else scan(i) := muls(i) + scan(i - 1) } io.out := scan(length - 1) } println(getVerilog(new MyManyDynamicElementVecFir(2))) ``` ```mips= module MyManyDynamicElementVecFir( input clock, input reset, input [7:0] io_in, output [7:0] io_out, input [7:0] io_consts_0, input [7:0] io_consts_1 ); `ifdef RANDOMIZE_REG_INIT reg [31:0] _RAND_0; `endif // RANDOMIZE_REG_INIT reg [7:0] regs_0; // @[cmd24.sc 9:21] wire [15:0] _T = io_in * io_consts_0; // @[cmd24.sc 17:35] wire [15:0] _T_1 = regs_0 * io_consts_1; // @[cmd24.sc 18:41] wire [7:0] muls_1 = _T_1[7:0]; // @[cmd24.sc 15:18 cmd24.sc 18:26] wire [7:0] muls_0 = _T[7:0]; // @[cmd24.sc 15:18 cmd24.sc 17:26] assign io_out = muls_1 + muls_0; // @[cmd24.sc 24:31] always @(posedge clock) begin if (reset) begin // @[cmd24.sc 9:21] regs_0 <= 8'h0; // @[cmd24.sc 9:21] end else begin regs_0 <= io_in; // @[cmd24.sc 11:26] end end endmodule ``` ## 範例3: 32 位元 RISC-V 暫存器 * 範例說明: * 單一寫入,多埠讀值 * addr 位寬設為 5.W 是因為 RV32I 暫存器數量為 32 * 第 18 行是因為 **RV32 規範 $0 的值恆為 0** * 所像是```addi $0 $18 1024```就是 nop 指令 ```scala= class RegisterFile(readPorts: Int) extends Module { require(readPorts >= 0) val io = IO(new Bundle { val wen = Input(Bool()) val waddr = Input(UInt(5.W)) val wdata = Input(UInt(32.W)) val raddr = Input(Vec(readPorts, UInt(5.W))) val rdata = Output(Vec(readPorts, UInt(32.W))) }) // A Register of a vector of UInts val reg = RegInit(VecInit(Seq.fill(32)(0.U(32.W)))) when (io.wen) { reg(io.waddr) := io.wdata } for (i <- 0 until readPorts) { when (io.raddr(i) === 0.U) { io.rdata(i) := 0.U } .otherwise { io.rdata(i) := reg(io.raddr(i)) } } } ``` * 生成 verilog code 後,就可以知道 HCL 的重要性 * 除了使用 HCL 外,晶片設計者也會使用(自製的)腳本語言完成 HDL 的基本撰寫 * 因為很長我就不調整縮排了 :::spoiler ```mips= module RegisterFile( input clock, input reset, input io_wen, input [4:0] io_waddr, input [31:0] io_wdata, input [4:0] io_raddr_0, input [4:0] io_raddr_1, output [31:0] io_rdata_0, output [31:0] io_rdata_1 ); `ifdef RANDOMIZE_REG_INIT reg [31:0] _RAND_0; reg [31:0] _RAND_1; reg [31:0] _RAND_2; reg [31:0] _RAND_3; reg [31:0] _RAND_4; reg [31:0] _RAND_5; reg [31:0] _RAND_6; reg [31:0] _RAND_7; reg [31:0] _RAND_8; reg [31:0] _RAND_9; reg [31:0] _RAND_10; reg [31:0] _RAND_11; reg [31:0] _RAND_12; reg [31:0] _RAND_13; reg [31:0] _RAND_14; reg [31:0] _RAND_15; reg [31:0] _RAND_16; reg [31:0] _RAND_17; reg [31:0] _RAND_18; reg [31:0] _RAND_19; reg [31:0] _RAND_20; reg [31:0] _RAND_21; reg [31:0] _RAND_22; reg [31:0] _RAND_23; reg [31:0] _RAND_24; reg [31:0] _RAND_25; reg [31:0] _RAND_26; reg [31:0] _RAND_27; reg [31:0] _RAND_28; reg [31:0] _RAND_29; reg [31:0] _RAND_30; reg [31:0] _RAND_31; `endif // RANDOMIZE_REG_INIT reg [31:0] reg_0; // @[cmd27.sc 12:22] reg [31:0] reg_1; // @[cmd27.sc 12:22] reg [31:0] reg_2; // @[cmd27.sc 12:22] reg [31:0] reg_3; // @[cmd27.sc 12:22] reg [31:0] reg_4; // @[cmd27.sc 12:22] reg [31:0] reg_5; // @[cmd27.sc 12:22] reg [31:0] reg_6; // @[cmd27.sc 12:22] reg [31:0] reg_7; // @[cmd27.sc 12:22] reg [31:0] reg_8; // @[cmd27.sc 12:22] reg [31:0] reg_9; // @[cmd27.sc 12:22] reg [31:0] reg_10; // @[cmd27.sc 12:22] reg [31:0] reg_11; // @[cmd27.sc 12:22] reg [31:0] reg_12; // @[cmd27.sc 12:22] reg [31:0] reg_13; // @[cmd27.sc 12:22] reg [31:0] reg_14; // @[cmd27.sc 12:22] reg [31:0] reg_15; // @[cmd27.sc 12:22] reg [31:0] reg_16; // @[cmd27.sc 12:22] reg [31:0] reg_17; // @[cmd27.sc 12:22] reg [31:0] reg_18; // @[cmd27.sc 12:22] reg [31:0] reg_19; // @[cmd27.sc 12:22] reg [31:0] reg_20; // @[cmd27.sc 12:22] reg [31:0] reg_21; // @[cmd27.sc 12:22] reg [31:0] reg_22; // @[cmd27.sc 12:22] reg [31:0] reg_23; // @[cmd27.sc 12:22] reg [31:0] reg_24; // @[cmd27.sc 12:22] reg [31:0] reg_25; // @[cmd27.sc 12:22] reg [31:0] reg_26; // @[cmd27.sc 12:22] reg [31:0] reg_27; // @[cmd27.sc 12:22] reg [31:0] reg_28; // @[cmd27.sc 12:22] reg [31:0] reg_29; // @[cmd27.sc 12:22] reg [31:0] reg_30; // @[cmd27.sc 12:22] reg [31:0] reg_31; // @[cmd27.sc 12:22] wire [31:0] _GEN_65 = 5'h1 == io_raddr_0 ? reg_1 : reg_0; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_66 = 5'h2 == io_raddr_0 ? reg_2 : _GEN_65; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_67 = 5'h3 == io_raddr_0 ? reg_3 : _GEN_66; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_68 = 5'h4 == io_raddr_0 ? reg_4 : _GEN_67; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_69 = 5'h5 == io_raddr_0 ? reg_5 : _GEN_68; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_70 = 5'h6 == io_raddr_0 ? reg_6 : _GEN_69; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_71 = 5'h7 == io_raddr_0 ? reg_7 : _GEN_70; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_72 = 5'h8 == io_raddr_0 ? reg_8 : _GEN_71; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_73 = 5'h9 == io_raddr_0 ? reg_9 : _GEN_72; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_74 = 5'ha == io_raddr_0 ? reg_10 : _GEN_73; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_75 = 5'hb == io_raddr_0 ? reg_11 : _GEN_74; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_76 = 5'hc == io_raddr_0 ? reg_12 : _GEN_75; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_77 = 5'hd == io_raddr_0 ? reg_13 : _GEN_76; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_78 = 5'he == io_raddr_0 ? reg_14 : _GEN_77; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_79 = 5'hf == io_raddr_0 ? reg_15 : _GEN_78; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_80 = 5'h10 == io_raddr_0 ? reg_16 : _GEN_79; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_81 = 5'h11 == io_raddr_0 ? reg_17 : _GEN_80; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_82 = 5'h12 == io_raddr_0 ? reg_18 : _GEN_81; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_83 = 5'h13 == io_raddr_0 ? reg_19 : _GEN_82; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_84 = 5'h14 == io_raddr_0 ? reg_20 : _GEN_83; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_85 = 5'h15 == io_raddr_0 ? reg_21 : _GEN_84; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_86 = 5'h16 == io_raddr_0 ? reg_22 : _GEN_85; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_87 = 5'h17 == io_raddr_0 ? reg_23 : _GEN_86; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_88 = 5'h18 == io_raddr_0 ? reg_24 : _GEN_87; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_89 = 5'h19 == io_raddr_0 ? reg_25 : _GEN_88; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_90 = 5'h1a == io_raddr_0 ? reg_26 : _GEN_89; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_91 = 5'h1b == io_raddr_0 ? reg_27 : _GEN_90; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_92 = 5'h1c == io_raddr_0 ? reg_28 : _GEN_91; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_93 = 5'h1d == io_raddr_0 ? reg_29 : _GEN_92; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_94 = 5'h1e == io_raddr_0 ? reg_30 : _GEN_93; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_95 = 5'h1f == io_raddr_0 ? reg_31 : _GEN_94; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_98 = 5'h1 == io_raddr_1 ? reg_1 : reg_0; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_99 = 5'h2 == io_raddr_1 ? reg_2 : _GEN_98; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_100 = 5'h3 == io_raddr_1 ? reg_3 : _GEN_99; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_101 = 5'h4 == io_raddr_1 ? reg_4 : _GEN_100; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_102 = 5'h5 == io_raddr_1 ? reg_5 : _GEN_101; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_103 = 5'h6 == io_raddr_1 ? reg_6 : _GEN_102; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_104 = 5'h7 == io_raddr_1 ? reg_7 : _GEN_103; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_105 = 5'h8 == io_raddr_1 ? reg_8 : _GEN_104; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_106 = 5'h9 == io_raddr_1 ? reg_9 : _GEN_105; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_107 = 5'ha == io_raddr_1 ? reg_10 : _GEN_106; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_108 = 5'hb == io_raddr_1 ? reg_11 : _GEN_107; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_109 = 5'hc == io_raddr_1 ? reg_12 : _GEN_108; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_110 = 5'hd == io_raddr_1 ? reg_13 : _GEN_109; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_111 = 5'he == io_raddr_1 ? reg_14 : _GEN_110; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_112 = 5'hf == io_raddr_1 ? reg_15 : _GEN_111; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_113 = 5'h10 == io_raddr_1 ? reg_16 : _GEN_112; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_114 = 5'h11 == io_raddr_1 ? reg_17 : _GEN_113; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_115 = 5'h12 == io_raddr_1 ? reg_18 : _GEN_114; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_116 = 5'h13 == io_raddr_1 ? reg_19 : _GEN_115; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_117 = 5'h14 == io_raddr_1 ? reg_20 : _GEN_116; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_118 = 5'h15 == io_raddr_1 ? reg_21 : _GEN_117; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_119 = 5'h16 == io_raddr_1 ? reg_22 : _GEN_118; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_120 = 5'h17 == io_raddr_1 ? reg_23 : _GEN_119; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_121 = 5'h18 == io_raddr_1 ? reg_24 : _GEN_120; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_122 = 5'h19 == io_raddr_1 ? reg_25 : _GEN_121; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_123 = 5'h1a == io_raddr_1 ? reg_26 : _GEN_122; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_124 = 5'h1b == io_raddr_1 ? reg_27 : _GEN_123; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_125 = 5'h1c == io_raddr_1 ? reg_28 : _GEN_124; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_126 = 5'h1d == io_raddr_1 ? reg_29 : _GEN_125; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_127 = 5'h1e == io_raddr_1 ? reg_30 : _GEN_126; // @[cmd27.sc 21:25 cmd27.sc 21:25] wire [31:0] _GEN_128 = 5'h1f == io_raddr_1 ? reg_31 : _GEN_127; // @[cmd27.sc 21:25 cmd27.sc 21:25] assign io_rdata_0 = io_raddr_0 == 5'h0 ? 32'h0 : _GEN_95; // @[cmd27.sc 18:36 cmd27.sc 19:25 cmd27.sc 21:25] assign io_rdata_1 = io_raddr_1 == 5'h0 ? 32'h0 : _GEN_128; // @[cmd27.sc 18:36 cmd27.sc 19:25 cmd27.sc 21:25] always @(posedge clock) begin if (reset) begin // @[cmd27.sc 12:22] reg_0 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h0 == io_waddr) begin // @[cmd27.sc 15:23] reg_0 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_1 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h1 == io_waddr) begin // @[cmd27.sc 15:23] reg_1 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_2 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h2 == io_waddr) begin // @[cmd27.sc 15:23] reg_2 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_3 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h3 == io_waddr) begin // @[cmd27.sc 15:23] reg_3 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_4 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h4 == io_waddr) begin // @[cmd27.sc 15:23] reg_4 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_5 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h5 == io_waddr) begin // @[cmd27.sc 15:23] reg_5 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_6 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h6 == io_waddr) begin // @[cmd27.sc 15:23] reg_6 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_7 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h7 == io_waddr) begin // @[cmd27.sc 15:23] reg_7 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_8 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h8 == io_waddr) begin // @[cmd27.sc 15:23] reg_8 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_9 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h9 == io_waddr) begin // @[cmd27.sc 15:23] reg_9 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_10 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'ha == io_waddr) begin // @[cmd27.sc 15:23] reg_10 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_11 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'hb == io_waddr) begin // @[cmd27.sc 15:23] reg_11 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_12 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'hc == io_waddr) begin // @[cmd27.sc 15:23] reg_12 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_13 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'hd == io_waddr) begin // @[cmd27.sc 15:23] reg_13 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_14 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'he == io_waddr) begin // @[cmd27.sc 15:23] reg_14 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_15 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'hf == io_waddr) begin // @[cmd27.sc 15:23] reg_15 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_16 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h10 == io_waddr) begin // @[cmd27.sc 15:23] reg_16 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_17 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h11 == io_waddr) begin // @[cmd27.sc 15:23] reg_17 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_18 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h12 == io_waddr) begin // @[cmd27.sc 15:23] reg_18 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_19 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h13 == io_waddr) begin // @[cmd27.sc 15:23] reg_19 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_20 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h14 == io_waddr) begin // @[cmd27.sc 15:23] reg_20 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_21 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h15 == io_waddr) begin // @[cmd27.sc 15:23] reg_21 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_22 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h16 == io_waddr) begin // @[cmd27.sc 15:23] reg_22 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_23 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h17 == io_waddr) begin // @[cmd27.sc 15:23] reg_23 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_24 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h18 == io_waddr) begin // @[cmd27.sc 15:23] reg_24 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_25 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h19 == io_waddr) begin // @[cmd27.sc 15:23] reg_25 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_26 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h1a == io_waddr) begin // @[cmd27.sc 15:23] reg_26 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_27 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h1b == io_waddr) begin // @[cmd27.sc 15:23] reg_27 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_28 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h1c == io_waddr) begin // @[cmd27.sc 15:23] reg_28 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_29 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h1d == io_waddr) begin // @[cmd27.sc 15:23] reg_29 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_30 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h1e == io_waddr) begin // @[cmd27.sc 15:23] reg_30 <= io_wdata; // @[cmd27.sc 15:23] end end if (reset) begin // @[cmd27.sc 12:22] reg_31 <= 32'h0; // @[cmd27.sc 12:22] end else if (io_wen) begin // @[cmd27.sc 14:19] if (5'h1f == io_waddr) begin // @[cmd27.sc 15:23] reg_31 <= io_wdata; // @[cmd27.sc 15:23] end end end endmodule ``` ::: --- # 範例 ## 範例1: Mealy machine * 定義一個物件 BinaryMealyParams,輸入 Module ```scala= // Mealy machine has case class BinaryMealyParams( // number of states nStates: Int, // initial state s0: Int, // function describing state transition stateTransition: (Int, Boolean) => Int, // function describing output output: (Int, Boolean) => Int ) { require(nStates >= 0) require(s0 < nStates && s0 >= 0) } class BinaryMealy(val mp: BinaryMealyParams) extends Module { val io = IO(new Bundle { val in = Input(Bool()) val out = Output(UInt()) }) val state = RegInit(UInt(), mp.s0.U) // output zero if no states io.out := 0.U for (i <- 0 until mp.nStates) { when (state === i.U) { when (io.in) { state := mp.stateTransition(i, true).U io.out := mp.output(i, true).U }.otherwise { state := mp.stateTransition(i, false).U io.out := mp.output(i, false).U } } } } ``` ```shell Elaborating design... Done elaborating. module BinaryMealy( input clock, input reset, input io_in, output io_out ); `ifdef RANDOMIZE_REG_INIT reg [31:0] _RAND_0; `endif // RANDOMIZE_REG_INIT reg [1:0] state; // @[cmd32.sc 21:22] wire _GEN_2 = state == 2'h0 & io_in; // @[cmd32.sc 26:26 cmd32.sc 24:10] wire _GEN_3 = io_in ? 1'h0 : 1'h1; // @[cmd32.sc 27:20 cmd32.sc 29:16 cmd32.sc 32:16] wire _GEN_5 = state == 2'h1 ? _GEN_3 : _GEN_2; // @[cmd32.sc 26:26] assign io_out = state == 2'h2 ? 1'h0 : _GEN_5; // @[cmd32.sc 26:26] always @(posedge clock) begin if (reset) begin // @[cmd32.sc 21:22] state <= 2'h2; // @[cmd32.sc 21:22] end else if (state == 2'h2) begin // @[cmd32.sc 26:26] state <= {{1'd0}, io_in}; end else if (state == 2'h1) begin // @[cmd32.sc 26:26] state <= {{1'd0}, io_in}; end else if (state == 2'h0) begin // @[cmd32.sc 26:26] state <= {{1'd0}, io_in}; end end endmodule ``` --- # 參考 * [Chisel-bootcamp](https://mybinder.org/v2/gh/freechipsproject/chisel-bootcamp/master)