从chisel代码到vivado上板测试

chisel代码及测试

本次设计中需要计算两个8bit输入的负二分之一次方乘积,并输出其8bit量化的输出结果。
O u t p u t = i n p u t 0 − 1 / 2 ∗ i n p u t 1 − 1 / 2 ∗ 256 Output= input0^{-1/2}*input1^{-1/2} * 256 Output=input01/2input11/2256
设计chisel代码及测试如下。

chisel代码

整体思想是用Python预先计算了一下,生成了部分查找表,由于当input0, input1较大时,输出均被量化为1,2等较小的数字,故不需要生成全部的查找表,使用条件判断加查找表相结合的方式即可。

package FAM
import chisel3._  
import chisel3.util._  
import os.read

import chisel3._

/* 输入起始节点和目的节点的度,计算得到他们乘积的-1/2次方
// 假设节点度最高256位,8bit
// 这里为实现整数的运算,将起始节点度与目的节点度的-1/2次方的乘积 * 256再取整
// 使用查找表完成乘法后的计算
*/

class SqrtInv(val Degree_Data_width: Int = 8) extends Module {
    val io = IO(new Bundle {
        val start_point_degree = Input(UInt(Degree_Data_width.W))
        val end_point_degree = Input(UInt(Degree_Data_width.W))
        val start = Input(Bool())
        val done = Output(Bool())
        val out = Output(UInt((Degree_Data_width).W))
    })

    // 初始化状态机。共四个状态:空闲状态、输入节点乘法计算,查找表,输出
    val state = RegInit(0.U(2.W))
    val idle :: multiply :: lut :: done :: Nil = Enum(4)

    // 计算乘积
    val mulResult = RegInit(0.U((2*Degree_Data_width).W))
    val result = RegInit(0.U(8.W))

    // 初始化LUT
        val LUT_array = Array(
        1.U -> 255.U(8.W),
        2.U -> 181.U(8.W),
        3.U -> 148.U(8.W),
        4.U -> 128.U(8.W),
        5.U -> 114.U(8.W),
        6.U -> 105.U(8.W),
        7.U -> 97.U(8.W),
        8.U -> 91.U(8.W),
        9.U -> 85.U(8.W),
        10.U -> 81.U(8.W),
        11.U -> 77.U(8.W),
        12.U -> 74.U(8.W),
        13.U -> 71.U(8.W),
        14.U -> 68.U(8.W),
        15.U -> 66.U(8.W),
        16.U -> 64.U(8.W),
        17.U -> 62.U(8.W),
        18.U -> 60.U(8.W),
        19.U -> 59.U(8.W),
        20.U -> 57.U(8.W),
        21.U -> 56.U(8.W),
        22.U -> 55.U(8.W),
        23.U -> 53.U(8.W),
        24.U -> 52.U(8.W),
        25.U -> 51.U(8.W),
        26.U -> 50.U(8.W),
        27.U -> 49.U(8.W),
        28.U -> 48.U(8.W),
        29.U -> 48.U(8.W),
        30.U -> 47.U(8.W),
        31.U -> 46.U(8.W),
        32.U -> 45.U(8.W),
        33.U -> 45.U(8.W),
        34.U -> 44.U(8.W),
        35.U -> 43.U(8.W),
        36.U -> 43.U(8.W),
        37.U -> 42.U(8.W),
        38.U -> 42.U(8.W),
        39.U -> 41.U(8.W),
        40.U -> 40.U(8.W),
        41.U -> 40.U(8.W),
        42.U -> 40.U(8.W),
        43.U -> 39.U(8.W),
        44.U -> 39.U(8.W),
        45.U -> 38.U(8.W),
        46.U -> 38.U(8.W),
        47.U -> 37.U(8.W),
        48.U -> 37.U(8.W),
        49.U -> 37.U(8.W),
        50.U -> 36.U(8.W),
        51.U -> 36.U(8.W),
        52.U -> 36.U(8.W),
        53.U -> 35.U(8.W),
        54.U -> 35.U(8.W),
        55.U -> 35.U(8.W),
        56.U -> 34.U(8.W),
        57.U -> 34.U(8.W),
        58.U -> 34.U(8.W),
        59.U -> 33.U(8.W),
        60.U -> 33.U(8.W),
        61.U -> 33.U(8.W),
        62.U -> 33.U(8.W),
        63.U -> 32.U(8.W),
        64.U -> 32.U(8.W),
        65.U -> 32.U(8.W),
        66.U -> 32.U(8.W),
        67.U -> 31.U(8.W),
        68.U -> 31.U(8.W),
        69.U -> 31.U(8.W),
        70.U -> 31.U(8.W),
        71.U -> 30.U(8.W),
        72.U -> 30.U(8.W),
        73.U -> 30.U(8.W),
        74.U -> 30.U(8.W),
        75.U -> 30.U(8.W),
        76.U -> 29.U(8.W),
        77.U -> 29.U(8.W),
        78.U -> 29.U(8.W),
        79.U -> 29.U(8.W),
        80.U -> 29.U(8.W),
        81.U -> 28.U(8.W),
        82.U -> 28.U(8.W),
        83.U -> 28.U(8.W),
        84.U -> 28.U(8.W),
        85.U -> 28.U(8.W),
        86.U -> 28.U(8.W),
        87.U -> 27.U(8.W),
        88.U -> 27.U(8.W),
        89.U -> 27.U(8.W),
        90.U -> 27.U(8.W),
        91.U -> 27.U(8.W),
        92.U -> 27.U(8.W),
        93.U -> 27.U(8.W),
        94.U -> 26.U(8.W),
        95.U -> 26.U(8.W),
        96.U -> 26.U(8.W),
        97.U -> 26.U(8.W),
        98.U -> 26.U(8.W),
        99.U -> 26.U(8.W),
        100.U -> 26.U(8.W),
        101.U -> 25.U(8.W),
        102.U -> 25.U(8.W),
        103.U -> 25.U(8.W),
        104.U -> 25.U(8.W),
        105.U -> 25.U(8.W),
        106.U -> 25.U(8.W),
        107.U -> 25.U(8.W),
        108.U -> 25.U(8.W),
        109.U -> 25.U(8.W),
        110.U -> 24.U(8.W),
        111.U -> 24.U(8.W),
        112.U -> 24.U(8.W),
        113.U -> 24.U(8.W),
        114.U -> 24.U(8.W),
        115.U -> 24.U(8.W),
        116.U -> 24.U(8.W),
        117.U -> 24.U(8.W),
        118.U -> 24.U(8.W),
        119.U -> 23.U(8.W),
        120.U -> 23.U(8.W),
        121.U -> 23.U(8.W),
        122.U -> 23.U(8.W),
        123.U -> 23.U(8.W),
        124.U -> 23.U(8.W),
        125.U -> 23.U(8.W),
        126.U -> 23.U(8.W),
        127.U -> 23.U(8.W),
        128.U -> 23.U(8.W),
        129.U -> 23.U(8.W),
        130.U -> 22.U(8.W),
        131.U -> 22.U(8.W),
        132.U -> 22.U(8.W),
        133.U -> 22.U(8.W),
        134.U -> 22.U(8.W),
        135.U -> 22.U(8.W),
        136.U -> 22.U(8.W),
        137.U -> 22.U(8.W),
        138.U -> 22.U(8.W),
        139.U -> 22.U(8.W),
        140.U -> 22.U(8.W),
        141.U -> 22.U(8.W),
        142.U -> 21.U(8.W),
        143.U -> 21.U(8.W),
        144.U -> 21.U(8.W),
        145.U -> 21.U(8.W),
        146.U -> 21.U(8.W),
        147.U -> 21.U(8.W),
        148.U -> 21.U(8.W),
        149.U -> 21.U(8.W),
        150.U -> 21.U(8.W),
        151.U -> 21.U(8.W),
        152.U -> 21.U(8.W),
        153.U -> 21.U(8.W),
        154.U -> 21.U(8.W),
        155.U -> 21.U(8.W),
        156.U -> 20.U(8.W),
        157.U -> 20.U(8.W),
        158.U -> 20.U(8.W),
        159.U -> 20.U(8.W),
        160.U -> 20.U(8.W),
        161.U -> 20.U(8.W),
        162.U -> 20.U(8.W),
        163.U -> 20.U(8.W),
        164.U -> 20.U(8.W),
        165.U -> 20.U(8.W),
        166.U -> 20.U(8.W),
        167.U -> 20.U(8.W),
        168.U -> 20.U(8.W),
        169.U -> 20.U(8.W),
        170.U -> 20.U(8.W),
        171.U -> 20.U(8.W),
        172.U -> 20.U(8.W),
        173.U -> 19.U(8.W),
        174.U -> 19.U(8.W),
        175.U -> 19.U(8.W),
        176.U -> 19.U(8.W),
        177.U -> 19.U(8.W),
        178.U -> 19.U(8.W),
        179.U -> 19.U(8.W),
        180.U -> 19.U(8.W),
        181.U -> 19.U(8.W),
        182.U -> 19.U(8.W),
        183.U -> 19.U(8.W),
        184.U -> 19.U(8.W),
        185.U -> 19.U(8.W),
        186.U -> 19.U(8.W),
        187.U -> 19.U(8.W),
        188.U -> 19.U(8.W),
        189.U -> 19.U(8.W),
        190.U -> 19.U(8.W),
        191.U -> 19.U(8.W),
        192.U -> 18.U(8.W),
        193.U -> 18.U(8.W),
        194.U -> 18.U(8.W),
        195.U -> 18.U(8.W),
        196.U -> 18.U(8.W),
        197.U -> 18.U(8.W),
        198.U -> 18.U(8.W),
        199.U -> 18.U(8.W),
        200.U -> 18.U(8.W),
        201.U -> 18.U(8.W),
        202.U -> 18.U(8.W),
        203.U -> 18.U(8.W),
        204.U -> 18.U(8.W),
        205.U -> 18.U(8.W),
        206.U -> 18.U(8.W),
        207.U -> 18.U(8.W),
        208.U -> 18.U(8.W),
        209.U -> 18.U(8.W),
        210.U -> 18.U(8.W),
        211.U -> 18.U(8.W),
        212.U -> 18.U(8.W),
        213.U -> 18.U(8.W),
        214.U -> 17.U(8.W),
        215.U -> 17.U(8.W),
        216.U -> 17.U(8.W),
        217.U -> 17.U(8.W),
        218.U -> 17.U(8.W),
        219.U -> 17.U(8.W),
        220.U -> 17.U(8.W),
        221.U -> 17.U(8.W),
        222.U -> 17.U(8.W),
        223.U -> 17.U(8.W),
        224.U -> 17.U(8.W),
        225.U -> 17.U(8.W),
        226.U -> 17.U(8.W),
        227.U -> 17.U(8.W),
        228.U -> 17.U(8.W),
        229.U -> 17.U(8.W),
        230.U -> 17.U(8.W),
        231.U -> 17.U(8.W),
        232.U -> 17.U(8.W),
        233.U -> 17.U(8.W),
        234.U -> 17.U(8.W),
        235.U -> 17.U(8.W),
        236.U -> 17.U(8.W),
        237.U -> 17.U(8.W),
        238.U -> 17.U(8.W),
        239.U -> 17.U(8.W),
        240.U -> 17.U(8.W),
        241.U -> 16.U(8.W),
        242.U -> 16.U(8.W),
        243.U -> 16.U(8.W),
        244.U -> 16.U(8.W),
        245.U -> 16.U(8.W),
        246.U -> 16.U(8.W),
        247.U -> 16.U(8.W),
        248.U -> 16.U(8.W),
        249.U -> 16.U(8.W),
        250.U -> 16.U(8.W),
        251.U -> 16.U(8.W),
        252.U -> 16.U(8.W),
        253.U -> 16.U(8.W),
        254.U -> 16.U(8.W),
        255.U -> 16.U(8.W),
        256.U -> 16.U(8.W),
        257.U -> 16.U(8.W),
        258.U -> 16.U(8.W),
        259.U -> 16.U(8.W),
        260.U -> 16.U(8.W),
        261.U -> 16.U(8.W),
        262.U -> 16.U(8.W),
        263.U -> 16.U(8.W),
        264.U -> 16.U(8.W),
        265.U -> 16.U(8.W),
        266.U -> 16.U(8.W),
        267.U -> 16.U(8.W),
        268.U -> 16.U(8.W),
        269.U -> 16.U(8.W),
        270.U -> 16.U(8.W),
        271.U -> 16.U(8.W),
        272.U -> 16.U(8.W)
    )


    // 状态机执行
    switch(state) {
        is(idle) {
            when(io.start) {
                state := multiply
            }
        }

        is(multiply) {
            mulResult := io.start_point_degree * io.end_point_degree
            state := lut
        }

        is(lut) {
            // 使用输入值作为索引来查找结果
            // 接受选择信号、一个默认值,一个选择表。如果匹配成功,则按照匹配值输出,否则按默认值输出
            // 观察计算结果,前面数值变化相对频繁,而后面数值变化不大,这里将整个过程进行分类。变化相对频繁的地方使用查找表进行查找,
            // 而没那么频繁的使用条件判断所属区间进行处理
            when(mulResult < 273.U) {           // 查找表所属区间,即LUT_depth
                result := MuxLookup(mulResult, 0.U, LUT_array)
            }
            .elsewhen(mulResult < 312.U) {      // 15
                result := 15.U
            }
            .elsewhen(mulResult < 360.U) {      // 14
                result := 14.U
            }
            .elsewhen(mulResult < 420.U) {      // 13
                result := 13.U
            }
            .elsewhen(mulResult < 496.U) {      // 12
                result := 12.U
            }
            .elsewhen(mulResult < 595.U) {      // 11
                result := 11.U
            }
            .elsewhen(mulResult < 727.U) {      // 10
                result := 10.U
            }
            .elsewhen(mulResult < 908.U) {      // 9
                result := 9.U
            }
            .elsewhen(mulResult < 1166.U) {     // 8
                result := 8.U
            }
            .elsewhen(mulResult < 1552.U) {     // 7
                result := 7.U
            }
            .elsewhen(mulResult < 2167.U) {     // 6
                result := 6.U
            }
            .elsewhen(mulResult < 3237.U) {     // 5
                result := 5.U
            }
            .elsewhen(mulResult < 5350.U) {     // 4
                result := 4.U
            }
            .elsewhen(mulResult < 10487.U) {    // 3
                result := 3.U
            }
            .elsewhen(mulResult < 29128.U) {    // 2
                result := 2.U
            }
            .otherwise {                        // 1                         
                result := 1.U
            }
            
            
            state := done
        }

        is(done) {
            state := idle
        }
    }

    io.done := (state === done)
    io.out := result

}

// 实例化模块并运行测试,同时生成Verilog代码
object SqrtInv extends App {
    (new chisel3.stage.ChiselStage).emitVerilog(new SqrtInv(), Array("--target-dir", "./verilog/FAM"))
}

chisel测试代码

类似UVM那套验证方法,软件做一套,硬件做一套,然后用断言来验证。

import scala.util.Random
import org.scalatest._
import chiseltest._
import chisel3._
import FAM.SqrtInv

// 乘累加器的测试类  

  
class SqrtInvTest extends FreeSpec with ChiselScalatestTester {
    "SqrtInv should pass" in {

        test(new SqrtInv)
        .withAnnotations(Seq(WriteVcdAnnotation))  // generate the .vcd waveform file as output
        { c =>
            println("Start Testing")
            for (i <- 0 until 10) {
                val a = Random.nextInt(256)  // 生成0到255之间的随机数  
                val b = Random.nextInt(256) 
                
                c.io.start_point_degree.poke(a.U)   // 将随机数a作为无符号数输入  
                c.io.end_point_degree.poke(b.U)     // 将随机数b作为无符号数输入
                c.io.start.poke(true.B)  
                c.clock.step(2)

                while (c.io.done.peekBoolean() === false) {
                    c.clock.step(1)
                }

                val expectedResult = math.round(256/math.sqrt(a * b))     // 计算预期乘积  
                val actualResult = c.io.out.peek().litValue.toLong // 获取实际乘积   
                /* 
                    c: 这是测试环境中MAC模块的实例。
                    c.io.result: 这是指向模块输出端口result的引用。
                    peek(): 这是一个Chisel测试方法,用于在不推进时钟的情况下读取端口的当前值。
                    litValue: 这是一个方法,用于从Chisel的Data类型中提取实际的Scala值(在这个例子中是BigInt) 
                */
                
                println(s"Iteration: $i, A: $a, B: $b, Expected Result: $expectedResult, Actual Result: $actualResult")  
                assert(actualResult === expectedResult, s"Product is incorrect at iteration $i!\n Start_point_degree is $a, end point degree is $b.\n Expected: $expectedResult, Actual: $actualResult")  
         
            }
        }
    }
}

chisel测试结果

运行命令行sbt "testOnly SqrtInvTest"
测试结果如下

(base) wzm@wzm-Predator-PHN16-71:~/Graduation_Design/task/main/GCN try/chisel-examples/hello-world$ sbt "testOnly SqrtInvTest"
[info] welcome to sbt 1.9.7 (Ubuntu Java 17.0.13)
[info] loading settings for project hello-world-build-build from metals.sbt ...
[info] loading project definition from /home/wzm/Graduation_Design/task/main/GCN try/chisel-examples/hello-world/project/project
[info] loading settings for project hello-world-build from metals.sbt ...
[info] loading project definition from /home/wzm/Graduation_Design/task/main/GCN try/chisel-examples/hello-world/project
[success] Generated .bloop/hello-world-build.json
[success] Total time: 1 s, completed 2025年1月4日 下午5:09:53
[info] loading settings for project hello-world from build.sbt ...
[info] set current project to hello-world (in build file:/home/wzm/Graduation_Design/task/main/GCN%20try/chisel-examples/hello-world/)
Start Testing
Iteration: 0, A: 211, B: 169, Expected Result: 1, Actual Result: 1
Iteration: 1, A: 92, B: 242, Expected Result: 2, Actual Result: 2
Iteration: 2, A: 65, B: 251, Expected Result: 2, Actual Result: 2
Iteration: 3, A: 38, B: 87, Expected Result: 4, Actual Result: 4
Iteration: 4, A: 129, B: 204, Expected Result: 2, Actual Result: 2
Iteration: 5, A: 156, B: 201, Expected Result: 1, Actual Result: 1
Iteration: 6, A: 172, B: 210, Expected Result: 1, Actual Result: 1
Iteration: 7, A: 194, B: 22, Expected Result: 4, Actual Result: 4
Iteration: 8, A: 97, B: 189, Expected Result: 2, Actual Result: 2
Iteration: 9, A: 47, B: 23, Expected Result: 8, Actual Result: 8
[info] SqrtInvTest:
[info] - SqrtInv should pass
[info] Run completed in 1 second, 497 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 2 s, completed 2025年1月4日 下午5:09:55

测试通过

生成Verilog文件

运行命令行sbt run得到Verilog代码(非常长,可以不看)

module SqrtInv(
  input        clock,
  input        reset,
  input  [7:0] io_start_point_degree,
  input  [7:0] io_end_point_degree,
  input        io_start,
  output       io_done,
  output [7:0] io_out
);
`ifdef RANDOMIZE_REG_INIT
  reg [31:0] _RAND_0;
  reg [31:0] _RAND_1;
  reg [31:0] _RAND_2;
`endif // RANDOMIZE_REG_INIT
  reg [1:0] state; // @[SqrtInv.scala 24:24]
  reg [15:0] mulResult; // @[SqrtInv.scala 28:28]
  reg [7:0] result; // @[SqrtInv.scala 29:25]
  wire [15:0] _mulResult_T = io_start_point_degree * io_end_point_degree; // @[SqrtInv.scala 317:48]
  wire [7:0] _result_T_1 = 16'h1 == mulResult ? 8'hff : 8'h0; // @[Mux.scala 81:58]
  wire [7:0] _result_T_3 = 16'h2 == mulResult ? 8'hb5 : _result_T_1; // @[Mux.scala 81:58]
  wire [7:0] _result_T_5 = 16'h3 == mulResult ? 8'h94 : _result_T_3; // @[Mux.scala 81:58]
  wire [7:0] _result_T_7 = 16'h4 == mulResult ? 8'h80 : _result_T_5; // @[Mux.scala 81:58]
  wire [7:0] _result_T_9 = 16'h5 == mulResult ? 8'h72 : _result_T_7; // @[Mux.scala 81:58]
  wire [7:0] _result_T_11 = 16'h6 == mulResult ? 8'h69 : _result_T_9; // @[Mux.scala 81:58]
  wire [7:0] _result_T_13 = 16'h7 == mulResult ? 8'h61 : _result_T_11; // @[Mux.scala 81:58]
  wire [7:0] _result_T_15 = 16'h8 == mulResult ? 8'h5b : _result_T_13; // @[Mux.scala 81:58]
  wire [7:0] _result_T_17 = 16'h9 == mulResult ? 8'h55 : _result_T_15; // @[Mux.scala 81:58]
  wire [7:0] _result_T_19 = 16'ha == mulResult ? 8'h51 : _result_T_17; // @[Mux.scala 81:58]
  wire [7:0] _result_T_21 = 16'hb == mulResult ? 8'h4d : _result_T_19; // @[Mux.scala 81:58]
  wire [7:0] _result_T_23 = 16'hc == mulResult ? 8'h4a : _result_T_21; // @[Mux.scala 81:58]
  wire [7:0] _result_T_25 = 16'hd == mulResult ? 8'h47 : _result_T_23; // @[Mux.scala 81:58]
  wire [7:0] _result_T_27 = 16'he == mulResult ? 8'h44 : _result_T_25; // @[Mux.scala 81:58]
  wire [7:0] _result_T_29 = 16'hf == mulResult ? 8'h42 : _result_T_27; // @[Mux.scala 81:58]
  wire [7:0] _result_T_31 = 16'h10 == mulResult ? 8'h40 : _result_T_29; // @[Mux.scala 81:58]
  wire [7:0] _result_T_33 = 16'h11 == mulResult ? 8'h3e : _result_T_31; // @[Mux.scala 81:58]
  wire [7:0] _result_T_35 = 16'h12 == mulResult ? 8'h3c : _result_T_33; // @[Mux.scala 81:58]
  wire [7:0] _result_T_37 = 16'h13 == mulResult ? 8'h3b : _result_T_35; // @[Mux.scala 81:58]
  wire [7:0] _result_T_39 = 16'h14 == mulResult ? 8'h39 : _result_T_37; // @[Mux.scala 81:58]
  wire [7:0] _result_T_41 = 16'h15 == mulResult ? 8'h38 : _result_T_39; // @[Mux.scala 81:58]
  wire [7:0] _result_T_43 = 16'h16 == mulResult ? 8'h37 : _result_T_41; // @[Mux.scala 81:58]
  wire [7:0] _result_T_45 = 16'h17 == mulResult ? 8'h35 : _result_T_43; // @[Mux.scala 81:58]
  wire [7:0] _result_T_47 = 16'h18 == mulResult ? 8'h34 : _result_T_45; // @[Mux.scala 81:58]
  wire [7:0] _result_T_49 = 16'h19 == mulResult ? 8'h33 : _result_T_47; // @[Mux.scala 81:58]
  wire [7:0] _result_T_51 = 16'h1a == mulResult ? 8'h32 : _result_T_49; // @[Mux.scala 81:58]
  wire [7:0] _result_T_53 = 16'h1b == mulResult ? 8'h31 : _result_T_51; // @[Mux.scala 81:58]
  wire [7:0] _result_T_55 = 16'h1c == mulResult ? 8'h30 : _result_T_53; // @[Mux.scala 81:58]
  wire [7:0] _result_T_57 = 16'h1d == mulResult ? 8'h30 : _result_T_55; // @[Mux.scala 81:58]
  wire [7:0] _result_T_59 = 16'h1e == mulResult ? 8'h2f : _result_T_57; // @[Mux.scala 81:58]
  wire [7:0] _result_T_61 = 16'h1f == mulResult ? 8'h2e : _result_T_59; // @[Mux.scala 81:58]
  wire [7:0] _result_T_63 = 16'h20 == mulResult ? 8'h2d : _result_T_61; // @[Mux.scala 81:58]
  wire [7:0] _result_T_65 = 16'h21 == mulResult ? 8'h2d : _result_T_63; // @[Mux.scala 81:58]
  wire [7:0] _result_T_67 = 16'h22 == mulResult ? 8'h2c : _result_T_65; // @[Mux.scala 81:58]
  wire [7:0] _result_T_69 = 16'h23 == mulResult ? 8'h2b : _result_T_67; // @[Mux.scala 81:58]
  wire [7:0] _result_T_71 = 16'h24 == mulResult ? 8'h2b : _result_T_69; // @[Mux.scala 81:58]
  wire [7:0] _result_T_73 = 16'h25 == mulResult ? 8'h2a : _result_T_71; // @[Mux.scala 81:58]
  wire [7:0] _result_T_75 = 16'h26 == mulResult ? 8'h2a : _result_T_73; // @[Mux.scala 81:58]
  wire [7:0] _result_T_77 = 16'h27 == mulResult ? 8'h29 : _result_T_75; // @[Mux.scala 81:58]
  wire [7:0] _result_T_79 = 16'h28 == mulResult ? 8'h28 : _result_T_77; // @[Mux.scala 81:58]
  wire [7:0] _result_T_81 = 16'h29 == mulResult ? 8'h28 : _result_T_79; // @[Mux.scala 81:58]
  wire [7:0] _result_T_83 = 16'h2a == mulResult ? 8'h28 : _result_T_81; // @[Mux.scala 81:58]
  wire [7:0] _result_T_85 = 16'h2b == mulResult ? 8'h27 : _result_T_83; // @[Mux.scala 81:58]
  wire [7:0] _result_T_87 = 16'h2c == mulResult ? 8'h27 : _result_T_85; // @[Mux.scala 81:58]
  wire [7:0] _result_T_89 = 16'h2d == mulResult ? 8'h26 : _result_T_87; // @[Mux.scala 81:58]
  wire [7:0] _result_T_91 = 16'h2e == mulResult ? 8'h26 : _result_T_89; // @[Mux.scala 81:58]
  wire [7:0] _result_T_93 = 16'h2f == mulResult ? 8'h25 : _result_T_91; // @[Mux.scala 81:58]
  wire [7:0] _result_T_95 = 16'h30 == mulResult ? 8'h25 : _result_T_93; // @[Mux.scala 81:58]
  wire [7:0] _result_T_97 = 16'h31 == mulResult ? 8'h25 : _result_T_95; // @[Mux.scala 81:58]
  wire [7:0] _result_T_99 = 16'h32 == mulResult ? 8'h24 : _result_T_97; // @[Mux.scala 81:58]
  wire [7:0] _result_T_101 = 16'h33 == mulResult ? 8'h24 : _result_T_99; // @[Mux.scala 81:58]
  wire [7:0] _result_T_103 = 16'h34 == mulResult ? 8'h24 : _result_T_101; // @[Mux.scala 81:58]
  wire [7:0] _result_T_105 = 16'h35 == mulResult ? 8'h23 : _result_T_103; // @[Mux.scala 81:58]
  wire [7:0] _result_T_107 = 16'h36 == mulResult ? 8'h23 : _result_T_105; // @[Mux.scala 81:58]
  wire [7:0] _result_T_109 = 16'h37 == mulResult ? 8'h23 : _result_T_107; // @[Mux.scala 81:58]
  wire [7:0] _result_T_111 = 16'h38 == mulResult ? 8'h22 : _result_T_109; // @[Mux.scala 81:58]
  wire [7:0] _result_T_113 = 16'h39 == mulResult ? 8'h22 : _result_T_111; // @[Mux.scala 81:58]
  wire [7:0] _result_T_115 = 16'h3a == mulResult ? 8'h22 : _result_T_113; // @[Mux.scala 81:58]
  wire [7:0] _result_T_117 = 16'h3b == mulResult ? 8'h21 : _result_T_115; // @[Mux.scala 81:58]
  wire [7:0] _result_T_119 = 16'h3c == mulResult ? 8'h21 : _result_T_117; // @[Mux.scala 81:58]
  wire [7:0] _result_T_121 = 16'h3d == mulResult ? 8'h21 : _result_T_119; // @[Mux.scala 81:58]
  wire [7:0] _result_T_123 = 16'h3e == mulResult ? 8'h21 : _result_T_121; // @[Mux.scala 81:58]
  wire [7:0] _result_T_125 = 16'h3f == mulResult ? 8'h20 : _result_T_123; // @[Mux.scala 81:58]
  wire [7:0] _result_T_127 = 16'h40 == mulResult ? 8'h20 : _result_T_125; // @[Mux.scala 81:58]
  wire [7:0] _result_T_129 = 16'h41 == mulResult ? 8'h20 : _result_T_127; // @[Mux.scala 81:58]
  wire [7:0] _result_T_131 = 16'h42 == mulResult ? 8'h20 : _result_T_129; // @[Mux.scala 81:58]
  wire [7:0] _result_T_133 = 16'h43 == mulResult ? 8'h1f : _result_T_131; // @[Mux.scala 81:58]
  wire [7:0] _result_T_135 = 16'h44 == mulResult ? 8'h1f : _result_T_133; // @[Mux.scala 81:58]
  wire [7:0] _result_T_137 = 16'h45 == mulResult ? 8'h1f : _result_T_135; // @[Mux.scala 81:58]
  wire [7:0] _result_T_139 = 16'h46 == mulResult ? 8'h1f : _result_T_137; // @[Mux.scala 81:58]
  wire [7:0] _result_T_141 = 16'h47 == mulResult ? 8'h1e : _result_T_139; // @[Mux.scala 81:58]
  wire [7:0] _result_T_143 = 16'h48 == mulResult ? 8'h1e : _result_T_141; // @[Mux.scala 81:58]
  wire [7:0] _result_T_145 = 16'h49 == mulResult ? 8'h1e : _result_T_143; // @[Mux.scala 81:58]
  wire [7:0] _result_T_147 = 16'h4a == mulResult ? 8'h1e : _result_T_145; // @[Mux.scala 81:58]
  wire [7:0] _result_T_149 = 16'h4b == mulResult ? 8'h1e : _result_T_147; // @[Mux.scala 81:58]
  wire [7:0] _result_T_151 = 16'h4c == mulResult ? 8'h1d : _result_T_149; // @[Mux.scala 81:58]
  wire [7:0] _result_T_153 = 16'h4d == mulResult ? 8'h1d : _result_T_151; // @[Mux.scala 81:58]
  wire [7:0] _result_T_155 = 16'h4e == mulResult ? 8'h1d : _result_T_153; // @[Mux.scala 81:58]
  wire [7:0] _result_T_157 = 16'h4f == mulResult ? 8'h1d : _result_T_155; // @[Mux.scala 81:58]
  wire [7:0] _result_T_159 = 16'h50 == mulResult ? 8'h1d : _result_T_157; // @[Mux.scala 81:58]
  wire [7:0] _result_T_161 = 16'h51 == mulResult ? 8'h1c : _result_T_159; // @[Mux.scala 81:58]
  wire [7:0] _result_T_163 = 16'h52 == mulResult ? 8'h1c : _result_T_161; // @[Mux.scala 81:58]
  wire [7:0] _result_T_165 = 16'h53 == mulResult ? 8'h1c : _result_T_163; // @[Mux.scala 81:58]
  wire [7:0] _result_T_167 = 16'h54 == mulResult ? 8'h1c : _result_T_165; // @[Mux.scala 81:58]
  wire [7:0] _result_T_169 = 16'h55 == mulResult ? 8'h1c : _result_T_167; // @[Mux.scala 81:58]
  wire [7:0] _result_T_171 = 16'h56 == mulResult ? 8'h1c : _result_T_169; // @[Mux.scala 81:58]
  wire [7:0] _result_T_173 = 16'h57 == mulResult ? 8'h1b : _result_T_171; // @[Mux.scala 81:58]
  wire [7:0] _result_T_175 = 16'h58 == mulResult ? 8'h1b : _result_T_173; // @[Mux.scala 81:58]
  wire [7:0] _result_T_177 = 16'h59 == mulResult ? 8'h1b : _result_T_175; // @[Mux.scala 81:58]
  wire [7:0] _result_T_179 = 16'h5a == mulResult ? 8'h1b : _result_T_177; // @[Mux.scala 81:58]
  wire [7:0] _result_T_181 = 16'h5b == mulResult ? 8'h1b : _result_T_179; // @[Mux.scala 81:58]
  wire [7:0] _result_T_183 = 16'h5c == mulResult ? 8'h1b : _result_T_181; // @[Mux.scala 81:58]
  wire [7:0] _result_T_185 = 16'h5d == mulResult ? 8'h1b : _result_T_183; // @[Mux.scala 81:58]
  wire [7:0] _result_T_187 = 16'h5e == mulResult ? 8'h1a : _result_T_185; // @[Mux.scala 81:58]
  wire [7:0] _result_T_189 = 16'h5f == mulResult ? 8'h1a : _result_T_187; // @[Mux.scala 81:58]
  wire [7:0] _result_T_191 = 16'h60 == mulResult ? 8'h1a : _result_T_189; // @[Mux.scala 81:58]
  wire [7:0] _result_T_193 = 16'h61 == mulResult ? 8'h1a : _result_T_191; // @[Mux.scala 81:58]
  wire [7:0] _result_T_195 = 16'h62 == mulResult ? 8'h1a : _result_T_193; // @[Mux.scala 81:58]
  wire [7:0] _result_T_197 = 16'h63 == mulResult ? 8'h1a : _result_T_195; // @[Mux.scala 81:58]
  wire [7:0] _result_T_199 = 16'h64 == mulResult ? 8'h1a : _result_T_197; // @[Mux.scala 81:58]
  wire [7:0] _result_T_201 = 16'h65 == mulResult ? 8'h19 : _result_T_199; // @[Mux.scala 81:58]
  wire [7:0] _result_T_203 = 16'h66 == mulResult ? 8'h19 : _result_T_201; // @[Mux.scala 81:58]
  wire [7:0] _result_T_205 = 16'h67 == mulResult ? 8'h19 : _result_T_203; // @[Mux.scala 81:58]
  wire [7:0] _result_T_207 = 16'h68 == mulResult ? 8'h19 : _result_T_205; // @[Mux.scala 81:58]
  wire [7:0] _result_T_209 = 16'h69 == mulResult ? 8'h19 : _result_T_207; // @[Mux.scala 81:58]
  wire [7:0] _result_T_211 = 16'h6a == mulResult ? 8'h19 : _result_T_209; // @[Mux.scala 81:58]
  wire [7:0] _result_T_213 = 16'h6b == mulResult ? 8'h19 : _result_T_211; // @[Mux.scala 81:58]
  wire [7:0] _result_T_215 = 16'h6c == mulResult ? 8'h19 : _result_T_213; // @[Mux.scala 81:58]
  wire [7:0] _result_T_217 = 16'h6d == mulResult ? 8'h19 : _result_T_215; // @[Mux.scala 81:58]
  wire [7:0] _result_T_219 = 16'h6e == mulResult ? 8'h18 : _result_T_217; // @[Mux.scala 81:58]
  wire [7:0] _result_T_221 = 16'h6f == mulResult ? 8'h18 : _result_T_219; // @[Mux.scala 81:58]
  wire [7:0] _result_T_223 = 16'h70 == mulResult ? 8'h18 : _result_T_221; // @[Mux.scala 81:58]
  wire [7:0] _result_T_225 = 16'h71 == mulResult ? 8'h18 : _result_T_223; // @[Mux.scala 81:58]
  wire [7:0] _result_T_227 = 16'h72 == mulResult ? 8'h18 : _result_T_225; // @[Mux.scala 81:58]
  wire [7:0] _result_T_229 = 16'h73 == mulResult ? 8'h18 : _result_T_227; // @[Mux.scala 81:58]
  wire [7:0] _result_T_231 = 16'h74 == mulResult ? 8'h18 : _result_T_229; // @[Mux.scala 81:58]
  wire [7:0] _result_T_233 = 16'h75 == mulResult ? 8'h18 : _result_T_231; // @[Mux.scala 81:58]
  wire [7:0] _result_T_235 = 16'h76 == mulResult ? 8'h18 : _result_T_233; // @[Mux.scala 81:58]
  wire [7:0] _result_T_237 = 16'h77 == mulResult ? 8'h17 : _result_T_235; // @[Mux.scala 81:58]
  wire [7:0] _result_T_239 = 16'h78 == mulResult ? 8'h17 : _result_T_237; // @[Mux.scala 81:58]
  wire [7:0] _result_T_241 = 16'h79 == mulResult ? 8'h17 : _result_T_239; // @[Mux.scala 81:58]
  wire [7:0] _result_T_243 = 16'h7a == mulResult ? 8'h17 : _result_T_241; // @[Mux.scala 81:58]
  wire [7:0] _result_T_245 = 16'h7b == mulResult ? 8'h17 : _result_T_243; // @[Mux.scala 81:58]
  wire [7:0] _result_T_247 = 16'h7c == mulResult ? 8'h17 : _result_T_245; // @[Mux.scala 81:58]
  wire [7:0] _result_T_249 = 16'h7d == mulResult ? 8'h17 : _result_T_247; // @[Mux.scala 81:58]
  wire [7:0] _result_T_251 = 16'h7e == mulResult ? 8'h17 : _result_T_249; // @[Mux.scala 81:58]
  wire [7:0] _result_T_253 = 16'h7f == mulResult ? 8'h17 : _result_T_251; // @[Mux.scala 81:58]
  wire [7:0] _result_T_255 = 16'h80 == mulResult ? 8'h17 : _result_T_253; // @[Mux.scala 81:58]
  wire [7:0] _result_T_257 = 16'h81 == mulResult ? 8'h17 : _result_T_255; // @[Mux.scala 81:58]
  wire [7:0] _result_T_259 = 16'h82 == mulResult ? 8'h16 : _result_T_257; // @[Mux.scala 81:58]
  wire [7:0] _result_T_261 = 16'h83 == mulResult ? 8'h16 : _result_T_259; // @[Mux.scala 81:58]
  wire [7:0] _result_T_263 = 16'h84 == mulResult ? 8'h16 : _result_T_261; // @[Mux.scala 81:58]
  wire [7:0] _result_T_265 = 16'h85 == mulResult ? 8'h16 : _result_T_263; // @[Mux.scala 81:58]
  wire [7:0] _result_T_267 = 16'h86 == mulResult ? 8'h16 : _result_T_265; // @[Mux.scala 81:58]
  wire [7:0] _result_T_269 = 16'h87 == mulResult ? 8'h16 : _result_T_267; // @[Mux.scala 81:58]
  wire [7:0] _result_T_271 = 16'h88 == mulResult ? 8'h16 : _result_T_269; // @[Mux.scala 81:58]
  wire [7:0] _result_T_273 = 16'h89 == mulResult ? 8'h16 : _result_T_271; // @[Mux.scala 81:58]
  wire [7:0] _result_T_275 = 16'h8a == mulResult ? 8'h16 : _result_T_273; // @[Mux.scala 81:58]
  wire [7:0] _result_T_277 = 16'h8b == mulResult ? 8'h16 : _result_T_275; // @[Mux.scala 81:58]
  wire [7:0] _result_T_279 = 16'h8c == mulResult ? 8'h16 : _result_T_277; // @[Mux.scala 81:58]
  wire [7:0] _result_T_281 = 16'h8d == mulResult ? 8'h16 : _result_T_279; // @[Mux.scala 81:58]
  wire [7:0] _result_T_283 = 16'h8e == mulResult ? 8'h15 : _result_T_281; // @[Mux.scala 81:58]
  wire [7:0] _result_T_285 = 16'h8f == mulResult ? 8'h15 : _result_T_283; // @[Mux.scala 81:58]
  wire [7:0] _result_T_287 = 16'h90 == mulResult ? 8'h15 : _result_T_285; // @[Mux.scala 81:58]
  wire [7:0] _result_T_289 = 16'h91 == mulResult ? 8'h15 : _result_T_287; // @[Mux.scala 81:58]
  wire [7:0] _result_T_291 = 16'h92 == mulResult ? 8'h15 : _result_T_289; // @[Mux.scala 81:58]
  wire [7:0] _result_T_293 = 16'h93 == mulResult ? 8'h15 : _result_T_291; // @[Mux.scala 81:58]
  wire [7:0] _result_T_295 = 16'h94 == mulResult ? 8'h15 : _result_T_293; // @[Mux.scala 81:58]
  wire [7:0] _result_T_297 = 16'h95 == mulResult ? 8'h15 : _result_T_295; // @[Mux.scala 81:58]
  wire [7:0] _result_T_299 = 16'h96 == mulResult ? 8'h15 : _result_T_297; // @[Mux.scala 81:58]
  wire [7:0] _result_T_301 = 16'h97 == mulResult ? 8'h15 : _result_T_299; // @[Mux.scala 81:58]
  wire [7:0] _result_T_303 = 16'h98 == mulResult ? 8'h15 : _result_T_301; // @[Mux.scala 81:58]
  wire [7:0] _result_T_305 = 16'h99 == mulResult ? 8'h15 : _result_T_303; // @[Mux.scala 81:58]
  wire [7:0] _result_T_307 = 16'h9a == mulResult ? 8'h15 : _result_T_305; // @[Mux.scala 81:58]
  wire [7:0] _result_T_309 = 16'h9b == mulResult ? 8'h15 : _result_T_307; // @[Mux.scala 81:58]
  wire [7:0] _result_T_311 = 16'h9c == mulResult ? 8'h14 : _result_T_309; // @[Mux.scala 81:58]
  wire [7:0] _result_T_313 = 16'h9d == mulResult ? 8'h14 : _result_T_311; // @[Mux.scala 81:58]
  wire [7:0] _result_T_315 = 16'h9e == mulResult ? 8'h14 : _result_T_313; // @[Mux.scala 81:58]
  wire [7:0] _result_T_317 = 16'h9f == mulResult ? 8'h14 : _result_T_315; // @[Mux.scala 81:58]
  wire [7:0] _result_T_319 = 16'ha0 == mulResult ? 8'h14 : _result_T_317; // @[Mux.scala 81:58]
  wire [7:0] _result_T_321 = 16'ha1 == mulResult ? 8'h14 : _result_T_319; // @[Mux.scala 81:58]
  wire [7:0] _result_T_323 = 16'ha2 == mulResult ? 8'h14 : _result_T_321; // @[Mux.scala 81:58]
  wire [7:0] _result_T_325 = 16'ha3 == mulResult ? 8'h14 : _result_T_323; // @[Mux.scala 81:58]
  wire [7:0] _result_T_327 = 16'ha4 == mulResult ? 8'h14 : _result_T_325; // @[Mux.scala 81:58]
  wire [7:0] _result_T_329 = 16'ha5 == mulResult ? 8'h14 : _result_T_327; // @[Mux.scala 81:58]
  wire [7:0] _result_T_331 = 16'ha6 == mulResult ? 8'h14 : _result_T_329; // @[Mux.scala 81:58]
  wire [7:0] _result_T_333 = 16'ha7 == mulResult ? 8'h14 : _result_T_331; // @[Mux.scala 81:58]
  wire [7:0] _result_T_335 = 16'ha8 == mulResult ? 8'h14 : _result_T_333; // @[Mux.scala 81:58]
  wire [7:0] _result_T_337 = 16'ha9 == mulResult ? 8'h14 : _result_T_335; // @[Mux.scala 81:58]
  wire [7:0] _result_T_339 = 16'haa == mulResult ? 8'h14 : _result_T_337; // @[Mux.scala 81:58]
  wire [7:0] _result_T_341 = 16'hab == mulResult ? 8'h14 : _result_T_339; // @[Mux.scala 81:58]
  wire [7:0] _result_T_343 = 16'hac == mulResult ? 8'h14 : _result_T_341; // @[Mux.scala 81:58]
  wire [7:0] _result_T_345 = 16'had == mulResult ? 8'h13 : _result_T_343; // @[Mux.scala 81:58]
  wire [7:0] _result_T_347 = 16'hae == mulResult ? 8'h13 : _result_T_345; // @[Mux.scala 81:58]
  wire [7:0] _result_T_349 = 16'haf == mulResult ? 8'h13 : _result_T_347; // @[Mux.scala 81:58]
  wire [7:0] _result_T_351 = 16'hb0 == mulResult ? 8'h13 : _result_T_349; // @[Mux.scala 81:58]
  wire [7:0] _result_T_353 = 16'hb1 == mulResult ? 8'h13 : _result_T_351; // @[Mux.scala 81:58]
  wire [7:0] _result_T_355 = 16'hb2 == mulResult ? 8'h13 : _result_T_353; // @[Mux.scala 81:58]
  wire [7:0] _result_T_357 = 16'hb3 == mulResult ? 8'h13 : _result_T_355; // @[Mux.scala 81:58]
  wire [7:0] _result_T_359 = 16'hb4 == mulResult ? 8'h13 : _result_T_357; // @[Mux.scala 81:58]
  wire [7:0] _result_T_361 = 16'hb5 == mulResult ? 8'h13 : _result_T_359; // @[Mux.scala 81:58]
  wire [7:0] _result_T_363 = 16'hb6 == mulResult ? 8'h13 : _result_T_361; // @[Mux.scala 81:58]
  wire [7:0] _result_T_365 = 16'hb7 == mulResult ? 8'h13 : _result_T_363; // @[Mux.scala 81:58]
  wire [7:0] _result_T_367 = 16'hb8 == mulResult ? 8'h13 : _result_T_365; // @[Mux.scala 81:58]
  wire [7:0] _result_T_369 = 16'hb9 == mulResult ? 8'h13 : _result_T_367; // @[Mux.scala 81:58]
  wire [7:0] _result_T_371 = 16'hba == mulResult ? 8'h13 : _result_T_369; // @[Mux.scala 81:58]
  wire [7:0] _result_T_373 = 16'hbb == mulResult ? 8'h13 : _result_T_371; // @[Mux.scala 81:58]
  wire [7:0] _result_T_375 = 16'hbc == mulResult ? 8'h13 : _result_T_373; // @[Mux.scala 81:58]
  wire [7:0] _result_T_377 = 16'hbd == mulResult ? 8'h13 : _result_T_375; // @[Mux.scala 81:58]
  wire [7:0] _result_T_379 = 16'hbe == mulResult ? 8'h13 : _result_T_377; // @[Mux.scala 81:58]
  wire [7:0] _result_T_381 = 16'hbf == mulResult ? 8'h13 : _result_T_379; // @[Mux.scala 81:58]
  wire [7:0] _result_T_383 = 16'hc0 == mulResult ? 8'h12 : _result_T_381; // @[Mux.scala 81:58]
  wire [7:0] _result_T_385 = 16'hc1 == mulResult ? 8'h12 : _result_T_383; // @[Mux.scala 81:58]
  wire [7:0] _result_T_387 = 16'hc2 == mulResult ? 8'h12 : _result_T_385; // @[Mux.scala 81:58]
  wire [7:0] _result_T_389 = 16'hc3 == mulResult ? 8'h12 : _result_T_387; // @[Mux.scala 81:58]
  wire [7:0] _result_T_391 = 16'hc4 == mulResult ? 8'h12 : _result_T_389; // @[Mux.scala 81:58]
  wire [7:0] _result_T_393 = 16'hc5 == mulResult ? 8'h12 : _result_T_391; // @[Mux.scala 81:58]
  wire [7:0] _result_T_395 = 16'hc6 == mulResult ? 8'h12 : _result_T_393; // @[Mux.scala 81:58]
  wire [7:0] _result_T_397 = 16'hc7 == mulResult ? 8'h12 : _result_T_395; // @[Mux.scala 81:58]
  wire [7:0] _result_T_399 = 16'hc8 == mulResult ? 8'h12 : _result_T_397; // @[Mux.scala 81:58]
  wire [7:0] _result_T_401 = 16'hc9 == mulResult ? 8'h12 : _result_T_399; // @[Mux.scala 81:58]
  wire [7:0] _result_T_403 = 16'hca == mulResult ? 8'h12 : _result_T_401; // @[Mux.scala 81:58]
  wire [7:0] _result_T_405 = 16'hcb == mulResult ? 8'h12 : _result_T_403; // @[Mux.scala 81:58]
  wire [7:0] _result_T_407 = 16'hcc == mulResult ? 8'h12 : _result_T_405; // @[Mux.scala 81:58]
  wire [7:0] _result_T_409 = 16'hcd == mulResult ? 8'h12 : _result_T_407; // @[Mux.scala 81:58]
  wire [7:0] _result_T_411 = 16'hce == mulResult ? 8'h12 : _result_T_409; // @[Mux.scala 81:58]
  wire [7:0] _result_T_413 = 16'hcf == mulResult ? 8'h12 : _result_T_411; // @[Mux.scala 81:58]
  wire [7:0] _result_T_415 = 16'hd0 == mulResult ? 8'h12 : _result_T_413; // @[Mux.scala 81:58]
  wire [7:0] _result_T_417 = 16'hd1 == mulResult ? 8'h12 : _result_T_415; // @[Mux.scala 81:58]
  wire [7:0] _result_T_419 = 16'hd2 == mulResult ? 8'h12 : _result_T_417; // @[Mux.scala 81:58]
  wire [7:0] _result_T_421 = 16'hd3 == mulResult ? 8'h12 : _result_T_419; // @[Mux.scala 81:58]
  wire [7:0] _result_T_423 = 16'hd4 == mulResult ? 8'h12 : _result_T_421; // @[Mux.scala 81:58]
  wire [7:0] _result_T_425 = 16'hd5 == mulResult ? 8'h12 : _result_T_423; // @[Mux.scala 81:58]
  wire [7:0] _result_T_427 = 16'hd6 == mulResult ? 8'h11 : _result_T_425; // @[Mux.scala 81:58]
  wire [7:0] _result_T_429 = 16'hd7 == mulResult ? 8'h11 : _result_T_427; // @[Mux.scala 81:58]
  wire [7:0] _result_T_431 = 16'hd8 == mulResult ? 8'h11 : _result_T_429; // @[Mux.scala 81:58]
  wire [7:0] _result_T_433 = 16'hd9 == mulResult ? 8'h11 : _result_T_431; // @[Mux.scala 81:58]
  wire [7:0] _result_T_435 = 16'hda == mulResult ? 8'h11 : _result_T_433; // @[Mux.scala 81:58]
  wire [7:0] _result_T_437 = 16'hdb == mulResult ? 8'h11 : _result_T_435; // @[Mux.scala 81:58]
  wire [7:0] _result_T_439 = 16'hdc == mulResult ? 8'h11 : _result_T_437; // @[Mux.scala 81:58]
  wire [7:0] _result_T_441 = 16'hdd == mulResult ? 8'h11 : _result_T_439; // @[Mux.scala 81:58]
  wire [7:0] _result_T_443 = 16'hde == mulResult ? 8'h11 : _result_T_441; // @[Mux.scala 81:58]
  wire [7:0] _result_T_445 = 16'hdf == mulResult ? 8'h11 : _result_T_443; // @[Mux.scala 81:58]
  wire [7:0] _result_T_447 = 16'he0 == mulResult ? 8'h11 : _result_T_445; // @[Mux.scala 81:58]
  wire [7:0] _result_T_449 = 16'he1 == mulResult ? 8'h11 : _result_T_447; // @[Mux.scala 81:58]
  wire [7:0] _result_T_451 = 16'he2 == mulResult ? 8'h11 : _result_T_449; // @[Mux.scala 81:58]
  wire [7:0] _result_T_453 = 16'he3 == mulResult ? 8'h11 : _result_T_451; // @[Mux.scala 81:58]
  wire [7:0] _result_T_455 = 16'he4 == mulResult ? 8'h11 : _result_T_453; // @[Mux.scala 81:58]
  wire [7:0] _result_T_457 = 16'he5 == mulResult ? 8'h11 : _result_T_455; // @[Mux.scala 81:58]
  wire [7:0] _result_T_459 = 16'he6 == mulResult ? 8'h11 : _result_T_457; // @[Mux.scala 81:58]
  wire [7:0] _result_T_461 = 16'he7 == mulResult ? 8'h11 : _result_T_459; // @[Mux.scala 81:58]
  wire [7:0] _result_T_463 = 16'he8 == mulResult ? 8'h11 : _result_T_461; // @[Mux.scala 81:58]
  wire [7:0] _result_T_465 = 16'he9 == mulResult ? 8'h11 : _result_T_463; // @[Mux.scala 81:58]
  wire [7:0] _result_T_467 = 16'hea == mulResult ? 8'h11 : _result_T_465; // @[Mux.scala 81:58]
  wire [7:0] _result_T_469 = 16'heb == mulResult ? 8'h11 : _result_T_467; // @[Mux.scala 81:58]
  wire [7:0] _result_T_471 = 16'hec == mulResult ? 8'h11 : _result_T_469; // @[Mux.scala 81:58]
  wire [7:0] _result_T_473 = 16'hed == mulResult ? 8'h11 : _result_T_471; // @[Mux.scala 81:58]
  wire [7:0] _result_T_475 = 16'hee == mulResult ? 8'h11 : _result_T_473; // @[Mux.scala 81:58]
  wire [7:0] _result_T_477 = 16'hef == mulResult ? 8'h11 : _result_T_475; // @[Mux.scala 81:58]
  wire [7:0] _result_T_479 = 16'hf0 == mulResult ? 8'h11 : _result_T_477; // @[Mux.scala 81:58]
  wire [7:0] _result_T_481 = 16'hf1 == mulResult ? 8'h10 : _result_T_479; // @[Mux.scala 81:58]
  wire [7:0] _result_T_483 = 16'hf2 == mulResult ? 8'h10 : _result_T_481; // @[Mux.scala 81:58]
  wire [7:0] _result_T_485 = 16'hf3 == mulResult ? 8'h10 : _result_T_483; // @[Mux.scala 81:58]
  wire [7:0] _result_T_487 = 16'hf4 == mulResult ? 8'h10 : _result_T_485; // @[Mux.scala 81:58]
  wire [7:0] _result_T_489 = 16'hf5 == mulResult ? 8'h10 : _result_T_487; // @[Mux.scala 81:58]
  wire [7:0] _result_T_491 = 16'hf6 == mulResult ? 8'h10 : _result_T_489; // @[Mux.scala 81:58]
  wire [7:0] _result_T_493 = 16'hf7 == mulResult ? 8'h10 : _result_T_491; // @[Mux.scala 81:58]
  wire [7:0] _result_T_495 = 16'hf8 == mulResult ? 8'h10 : _result_T_493; // @[Mux.scala 81:58]
  wire [7:0] _result_T_497 = 16'hf9 == mulResult ? 8'h10 : _result_T_495; // @[Mux.scala 81:58]
  wire [7:0] _result_T_499 = 16'hfa == mulResult ? 8'h10 : _result_T_497; // @[Mux.scala 81:58]
  wire [7:0] _result_T_501 = 16'hfb == mulResult ? 8'h10 : _result_T_499; // @[Mux.scala 81:58]
  wire [7:0] _result_T_503 = 16'hfc == mulResult ? 8'h10 : _result_T_501; // @[Mux.scala 81:58]
  wire [7:0] _result_T_505 = 16'hfd == mulResult ? 8'h10 : _result_T_503; // @[Mux.scala 81:58]
  wire [7:0] _result_T_507 = 16'hfe == mulResult ? 8'h10 : _result_T_505; // @[Mux.scala 81:58]
  wire [7:0] _result_T_509 = 16'hff == mulResult ? 8'h10 : _result_T_507; // @[Mux.scala 81:58]
  wire [7:0] _result_T_511 = 16'h100 == mulResult ? 8'h10 : _result_T_509; // @[Mux.scala 81:58]
  wire [7:0] _result_T_513 = 16'h101 == mulResult ? 8'h10 : _result_T_511; // @[Mux.scala 81:58]
  wire [7:0] _result_T_515 = 16'h102 == mulResult ? 8'h10 : _result_T_513; // @[Mux.scala 81:58]
  wire [7:0] _result_T_517 = 16'h103 == mulResult ? 8'h10 : _result_T_515; // @[Mux.scala 81:58]
  wire [7:0] _result_T_519 = 16'h104 == mulResult ? 8'h10 : _result_T_517; // @[Mux.scala 81:58]
  wire [7:0] _result_T_521 = 16'h105 == mulResult ? 8'h10 : _result_T_519; // @[Mux.scala 81:58]
  wire [7:0] _result_T_523 = 16'h106 == mulResult ? 8'h10 : _result_T_521; // @[Mux.scala 81:58]
  wire [7:0] _result_T_525 = 16'h107 == mulResult ? 8'h10 : _result_T_523; // @[Mux.scala 81:58]
  wire [7:0] _result_T_527 = 16'h108 == mulResult ? 8'h10 : _result_T_525; // @[Mux.scala 81:58]
  wire [7:0] _result_T_529 = 16'h109 == mulResult ? 8'h10 : _result_T_527; // @[Mux.scala 81:58]
  wire [7:0] _result_T_531 = 16'h10a == mulResult ? 8'h10 : _result_T_529; // @[Mux.scala 81:58]
  wire [7:0] _result_T_533 = 16'h10b == mulResult ? 8'h10 : _result_T_531; // @[Mux.scala 81:58]
  wire [7:0] _result_T_535 = 16'h10c == mulResult ? 8'h10 : _result_T_533; // @[Mux.scala 81:58]
  wire [7:0] _result_T_537 = 16'h10d == mulResult ? 8'h10 : _result_T_535; // @[Mux.scala 81:58]
  wire [7:0] _result_T_539 = 16'h10e == mulResult ? 8'h10 : _result_T_537; // @[Mux.scala 81:58]
  wire [7:0] _result_T_541 = 16'h10f == mulResult ? 8'h10 : _result_T_539; // @[Mux.scala 81:58]
  wire [7:0] _result_T_543 = 16'h110 == mulResult ? 8'h10 : _result_T_541; // @[Mux.scala 81:58]
  wire [1:0] _GEN_1 = mulResult < 16'h71c8 ? 2'h2 : 2'h1; // @[SqrtInv.scala 368:44 369:24 372:24]
  wire [1:0] _GEN_2 = mulResult < 16'h28f7 ? 2'h3 : _GEN_1; // @[SqrtInv.scala 365:44 366:24]
  wire [2:0] _GEN_3 = mulResult < 16'h14e6 ? 3'h4 : {{1'd0}, _GEN_2}; // @[SqrtInv.scala 362:43 363:24]
  wire [2:0] _GEN_4 = mulResult < 16'hca5 ? 3'h5 : _GEN_3; // @[SqrtInv.scala 359:43 360:24]
  wire [2:0] _GEN_5 = mulResult < 16'h877 ? 3'h6 : _GEN_4; // @[SqrtInv.scala 356:43 357:24]
  wire [2:0] _GEN_6 = mulResult < 16'h610 ? 3'h7 : _GEN_5; // @[SqrtInv.scala 353:43 354:24]
  wire [3:0] _GEN_7 = mulResult < 16'h48e ? 4'h8 : {{1'd0}, _GEN_6}; // @[SqrtInv.scala 350:43 351:24]
  wire [3:0] _GEN_8 = mulResult < 16'h38c ? 4'h9 : _GEN_7; // @[SqrtInv.scala 347:42 348:24]
  wire [3:0] _GEN_9 = mulResult < 16'h2d7 ? 4'ha : _GEN_8; // @[SqrtInv.scala 344:42 345:24]
  wire [3:0] _GEN_10 = mulResult < 16'h253 ? 4'hb : _GEN_9; // @[SqrtInv.scala 341:42 342:24]
  wire [3:0] _GEN_11 = mulResult < 16'h1f0 ? 4'hc : _GEN_10; // @[SqrtInv.scala 338:42 339:24]
  wire [3:0] _GEN_12 = mulResult < 16'h1a4 ? 4'hd : _GEN_11; // @[SqrtInv.scala 335:42 336:24]
  wire [3:0] _GEN_13 = mulResult < 16'h168 ? 4'he : _GEN_12; // @[SqrtInv.scala 332:42 333:24]
  wire [3:0] _GEN_14 = mulResult < 16'h138 ? 4'hf : _GEN_13; // @[SqrtInv.scala 329:42 330:24]
  wire [7:0] _GEN_15 = mulResult < 16'h111 ? _result_T_543 : {{4'd0}, _GEN_14}; // @[SqrtInv.scala 326:37 327:24]
  wire [1:0] _GEN_16 = 2'h3 == state ? 2'h0 : state; // @[SqrtInv.scala 309:19 380:19 24:24]
  assign io_done = state == 2'h3; // @[SqrtInv.scala 384:23]
  assign io_out = result; // @[SqrtInv.scala 385:12]
  always @(posedge clock) begin
    if (reset) begin // @[SqrtInv.scala 24:24]
      state <= 2'h0; // @[SqrtInv.scala 24:24]
    end else if (2'h0 == state) begin // @[SqrtInv.scala 309:19]
      if (io_start) begin // @[SqrtInv.scala 311:28]
        state <= 2'h1; // @[SqrtInv.scala 312:23]
      end
    end else if (2'h1 == state) begin // @[SqrtInv.scala 309:19]
      state <= 2'h2; // @[SqrtInv.scala 318:19]
    end else if (2'h2 == state) begin // @[SqrtInv.scala 309:19]
      state <= 2'h3; // @[SqrtInv.scala 376:19]
    end else begin
      state <= _GEN_16;
    end
    if (reset) begin // @[SqrtInv.scala 28:28]
      mulResult <= 16'h0; // @[SqrtInv.scala 28:28]
    end else if (!(2'h0 == state)) begin // @[SqrtInv.scala 309:19]
      if (2'h1 == state) begin // @[SqrtInv.scala 309:19]
        mulResult <= _mulResult_T; // @[SqrtInv.scala 317:23]
      end
    end
    if (reset) begin // @[SqrtInv.scala 29:25]
      result <= 8'h0; // @[SqrtInv.scala 29:25]
    end else if (!(2'h0 == state)) begin // @[SqrtInv.scala 309:19]
      if (!(2'h1 == state)) begin // @[SqrtInv.scala 309:19]
        if (2'h2 == state) begin // @[SqrtInv.scala 309:19]
          result <= _GEN_15;
        end
      end
    end
  end
// Register and memory initialization
`ifdef RANDOMIZE_GARBAGE_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_INVALID_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_MEM_INIT
`define RANDOMIZE
`endif
`ifndef RANDOM
`define RANDOM $random
`endif
`ifdef RANDOMIZE_MEM_INIT
  integer initvar;
`endif
`ifndef SYNTHESIS
`ifdef FIRRTL_BEFORE_INITIAL
`FIRRTL_BEFORE_INITIAL
`endif
initial begin
  `ifdef RANDOMIZE
    `ifdef INIT_RANDOM
      `INIT_RANDOM
    `endif
    `ifndef VERILATOR
      `ifdef RANDOMIZE_DELAY
        #`RANDOMIZE_DELAY begin end
      `else
        #0.002 begin end
      `endif
    `endif
`ifdef RANDOMIZE_REG_INIT
  _RAND_0 = {1{`RANDOM}};
  state = _RAND_0[1:0];
  _RAND_1 = {1{`RANDOM}};
  mulResult = _RAND_1[15:0];
  _RAND_2 = {1{`RANDOM}};
  result = _RAND_2[7:0];
`endif // RANDOMIZE_REG_INIT
  `endif // RANDOMIZE
end // initial
`ifdef FIRRTL_AFTER_INITIAL
`FIRRTL_AFTER_INITIAL
`endif
`endif // SYNTHESIS
endmodule

使用vivado上板测试

这里使用的vivado版本为2023.2,使用系统为Ubuntu22.04,开发板型号为芯驰科技AXU3EGB开发版,该板采用XILINX Zynq UltraScale+ EG芯片型号与双核 ARM Cortex-A53集成方案,其中FPGA型号为XCZU3EG-1SFVC784I。
本次测试均采用其中的PL差分系统时钟源,并将该时钟使用IBUFDS原语转为单端时钟作为系统时钟。配置启动模式为JTAG调试模式。

本文针对各个关键技术优化内容,分模块进行仿真及上板测试。为检测其输入输出逻辑是否符合预期,本文将采用仿真与上板向结合的方式进行,其中仿真生成随机的输入与并判定是否与期望的输出相符合,上板测试将采用仿真阶段生成的输入输出结果,通过嵌入的VIO(Virtual Input/Output)IP核模拟输入,并通过JTAG接口传至FPGA中,并同时监测输出结果。

项目创建过程

verilog仿真代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 01/02/2025 09:07:49 PM
// Design Name: 
// Module Name: SqrtInvTest
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module SqrtInvTest;

    // 输入信号
    reg clock;
    reg reset;
    reg [7:0] start_point_degree;
    reg [7:0] end_point_degree;
    reg start;

    // 输出信号
    wire done;
    wire [7:0] out;
        
    // 声明变量
    integer expected_result;
    // real sqrt_input;
    integer sqrt_input;

    // 仿真测试时去掉注释
    
    SqrtInv sqrtInv_inst (
        .clock(clock),
        .reset(reset),
        .io_start_point_degree(start_point_degree),
        .io_end_point_degree(end_point_degree),
        .io_start(start),
        .io_done(done),
        .io_out(out)
    );
    


    // 时钟生成
    initial begin
        clock = 0;
        forever #5 clock = ~clock; // 10ns 周期时钟
    end

    // 测试逻辑
    initial begin
        // 初始化信号
        reset = 1;
        start_point_degree = 0;
        end_point_degree = 0;
        start = 0;

        // 复位模块
        #20;
        reset = 0;



        // 开始测试
        $display("Start Testing");

        // 测试 10 次随机输入
        for (integer i = 0; i < 10; i = i + 1) begin
            // 生成随机输入
            start_point_degree = $urandom % 256;
            end_point_degree = $urandom % 256;
            start = 1;

            // 等待模块完成计算
            #10;
            start = 0;

            while (done == 0) begin
                #10; // 每个时钟周期检查一次 done 信号
            end

            // 计算预期结果
            sqrt_input = (start_point_degree) * (end_point_degree); // 将输入转换为 real 类型
            $display("Sqrt input: %d", sqrt_input);
            expected_result = 256 / ($sqrt(sqrt_input));

            // 打印结果
            $display("Iteration: %0d, A: %0d, B: %0d, Expected Result: %0d, Actual Result: %0d",
                     i, start_point_degree, end_point_degree, expected_result, out);

            // 断言验证
            if (out !== expected_result) begin
                $error("Test failed at iteration %0d! Start_point_degree: %0d, End_point_degree: %0d, Expected: %0d, Actual: %0d",
                       i, start_point_degree, end_point_degree, expected_result, out);
            end
            #10;
        end

        // 测试完成
        $display("Testing completed");
        $finish;
    end


endmodule

verilog仿真结果

测试思路同chisel

# run 1000ns
Start Testing
Sqrt input:       33201
Iteration: 0, A: 217, B: 153, Expected Result: 1, Actual Result: 1
Sqrt input:       33300
Iteration: 1, A: 150, B: 222, Expected Result: 1, Actual Result: 1
Sqrt input:       34160
Iteration: 2, A: 140, B: 244, Expected Result: 1, Actual Result: 1
Sqrt input:       14746
Iteration: 3, A: 146, B: 101, Expected Result: 2, Actual Result: 2
Sqrt input:        5680
Iteration: 4, A: 142, B: 40, Expected Result: 3, Actual Result: 3
Sqrt input:        1742
Iteration: 5, A: 67, B: 26, Expected Result: 6, Actual Result: 6
Sqrt input:        6206
Iteration: 6, A: 29, B: 214, Expected Result: 3, Actual Result: 3
Sqrt input:       21888
Iteration: 7, A: 128, B: 171, Expected Result: 2, Actual Result: 2
Sqrt input:       49530
Iteration: 8, A: 254, B: 195, Expected Result: 1, Actual Result: 1
Sqrt input:        5319
Iteration: 9, A: 197, B: 27, Expected Result: 4, Actual Result: 4
Testing completed
$finish called at time : 420 ns : File "/home/wzm/Graduate_project/Graduate_project.srcs/sim_1/new/SqrtInvTest.v" Line 112
INFO: [USF-XSim-96] XSim completed. Design snapshot 'SqrtInvTest_behav' loaded.
INFO: [USF-XSim-97] XSim simulation ran for 1000ns
launch_simulation: Time (s): cpu = 00:00:08 ; elapsed = 00:00:06 . Memory (MB): peak = 8106.234 ; gain = 7.246 ; free physical = 1565 ; free virtual = 9052

设计SqrtInv并将VIO IP核嵌入

点击创建IP核,并在界面中点击“+”,输入VIO,创建VIO IP核
在这里插入图片描述
双击VIO IP核,他的输出设计为模块所需的输入,输入设计为模块所需的输出,包括个数和位宽

VIO模拟输出信号,即待测模块输入信号为:
vio_0_probe_out0为start_point_degree,
vio_0_probe_out1为end_point_degree,
vio_0_probe_out2为io_start
VIO模拟输入信号,即待测模块输出信号为:
vio_0_probe_in0为io_done,
vio_0_probe_in1为io_out

在这里插入图片描述
上述配置完成后,右键点击对应端口,点击make external,创建端口如下,完成后点击保存,创建对应的IP及VIO.v文件
在这里插入图片描述
至此,VIO IP创建完成。

顶层设计与连接

设计顶层文件如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 01/03/2025 03:51:53 PM
// Design Name: 
// Module Name: SqurtInv_top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module SqrtInv_top(
    // 输入信号
    input        sys_clk_p,
    input        sys_clk_n,
    input        reset,
    output       io_done,
    output [7:0] io_out
);

    

    // 差分时钟缓冲器
    wire clock;
    IBUFDS ibufds_inst (
        .I(sys_clk_p),  // 差分时钟正端
        .IB(sys_clk_n), // 差分时钟负端
        .O(clock)      // 单端时钟输出
    );



    // 输出信号
    wire io_start;
    wire [7:0] start_point_degree;
    wire [7:0] end_point_degree;
    
    VIO vio_inst (
        .clk_0(clock),
        .probe_out0_0(start_point_degree),
        .probe_out1_0(end_point_degree),
        .probe_out2_0(io_start),
        .probe_in0_0(io_out),
        .probe_in1_0(io_done)
    );

    SqrtInv sqrtInv_inst (
        .clock(clock),
        .reset(reset),
        .io_start_point_degree(start_point_degree),
        .io_end_point_degree(end_point_degree),
        .io_start(io_start),
        .io_done(io_done),
        .io_out(io_out)
    );
endmodule

其中, IBUFDS为内置原语,将开发板上的差分时钟转为单端时钟。

运行综合(SYNTHESIS)

配置I/O

点击Open Synthesis Design,打开后点击Windows -> I/O Ports
在这里插入图片描述
参考手册对其中的管脚进行分配,完成后点击保存生成xdc文件。
在这里插入图片描述xdc文件如下:



set_property PACKAGE_PIN AE5 [get_ports sys_clk_p]
set_property IOSTANDARD DIFF_SSTL12 [get_ports sys_clk_p]
set_property IOSTANDARD LVCMOS33 [get_ports reset]
set_property IOSTANDARD LVCMOS12 [get_ports io_done]
set_property IOSTANDARD LVCMOS12 [get_ports {io_out[7]}]
set_property IOSTANDARD LVCMOS12 [get_ports {io_out[6]}]
set_property IOSTANDARD LVCMOS12 [get_ports {io_out[5]}]
set_property IOSTANDARD LVCMOS12 [get_ports {io_out[4]}]
set_property IOSTANDARD LVCMOS12 [get_ports {io_out[3]}]
set_property IOSTANDARD LVCMOS12 [get_ports {io_out[2]}]
set_property IOSTANDARD LVCMOS12 [get_ports {io_out[1]}]
set_property IOSTANDARD LVCMOS12 [get_ports {io_out[0]}]
set_property PACKAGE_PIN AF2 [get_ports {io_out[7]}]
set_property PACKAGE_PIN AD2 [get_ports {io_out[6]}]
set_property PACKAGE_PIN AD1 [get_ports {io_out[5]}]
set_property PACKAGE_PIN AG1 [get_ports {io_out[4]}]
set_property PACKAGE_PIN AF1 [get_ports {io_out[3]}]
set_property PACKAGE_PIN AH1 [get_ports {io_out[2]}]
set_property PACKAGE_PIN AH2 [get_ports {io_out[1]}]
set_property PACKAGE_PIN AF3 [get_ports {io_out[0]}]
set_property PACKAGE_PIN AE2 [get_ports io_done]
set_property PACKAGE_PIN AF12 [get_ports reset]

create_clock -period 5.000 -name sys_clk_p -waveform {0.000 2.500} [get_ports sys_clk_p]
set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub]
set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub]
set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub]
connect_debug_port dbg_hub/clk [get_nets clock_BUFG]

时序约束

打开Constraints Wizard,点击Next,在Primary Clocks中点击Recommended Constraints中的时钟,设定频率为200MHz,然后直接点击Skip to Finish保存约束。

在这里插入图片描述

综合、布局布线、生成bit流文件

上板测试

将开发板调成JTAG模式后接入电脑,在Auto Connect后Program device,写入开发板中。
vio界面弹出,可以模拟输入并检查输出。由于之前先将reset信号绑定在PL_key按键上,这里修改输入的值,设置probe_out2为1(io_start),按下按键,可以看到下面两个模块输出产生一闪而过的变化,如下所示。(如果未能捕获,多按几次按键即可)。至此成功完成验证。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值