xref: /XiangShan/src/test/scala/fu/IntDiv.scala (revision a58e33519795596dc4f85fe66907cbc7dde2d66a)
1*a58e3351SLi Qianruo/***************************************************************************************
2*a58e3351SLi Qianruo * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3*a58e3351SLi Qianruo * Copyright (c) 2020-2021 Peng Cheng Laboratory
4*a58e3351SLi Qianruo *
5*a58e3351SLi Qianruo * XiangShan is licensed under Mulan PSL v2.
6*a58e3351SLi Qianruo * You can use this software according to the terms and conditions of the Mulan PSL v2.
7*a58e3351SLi Qianruo * You may obtain a copy of Mulan PSL v2 at:
8*a58e3351SLi Qianruo *          http://license.coscl.org.cn/MulanPSL2
9*a58e3351SLi Qianruo *
10*a58e3351SLi Qianruo * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11*a58e3351SLi Qianruo * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12*a58e3351SLi Qianruo * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*a58e3351SLi Qianruo *
14*a58e3351SLi Qianruo * See the Mulan PSL v2 for more details.
15*a58e3351SLi Qianruo ***************************************************************************************/
16*a58e3351SLi Qianruo
17*a58e3351SLi Qianruopackage futest
18*a58e3351SLi Qianruo
19*a58e3351SLi Qianruoimport chisel3._
20*a58e3351SLi Qianruoimport chiseltest._
21*a58e3351SLi Qianruoimport chiseltest.ChiselScalatestTester
22*a58e3351SLi Qianruoimport chiseltest.experimental.TestOptionBuilder._
23*a58e3351SLi Qianruoimport chiseltest.internal.{LineCoverageAnnotation, ToggleCoverageAnnotation, VerilatorBackendAnnotation}
24*a58e3351SLi Qianruoimport chiseltest.legacy.backends.verilator.VerilatorFlags
25*a58e3351SLi Qianruoimport org.scalatest.flatspec.AnyFlatSpec
26*a58e3351SLi Qianruoimport org.scalatest.matchers.must.Matchers
27*a58e3351SLi Qianruoimport firrtl.stage.RunFirrtlTransformAnnotation
28*a58e3351SLi Qianruoimport xstransforms.PrintModuleName
29*a58e3351SLi Qianruo
30*a58e3351SLi Qianruoimport xiangshan.backend.fu._
31*a58e3351SLi Qianruo
32*a58e3351SLi Qianruoimport scala.util.Random
33*a58e3351SLi Qianruo
34*a58e3351SLi Qianruo
35*a58e3351SLi Qianruoclass SRT4DividerWrapper extends Module {
36*a58e3351SLi Qianruo  val io = IO(new Bundle{
37*a58e3351SLi Qianruo    val dividend = Input(UInt(64.W))
38*a58e3351SLi Qianruo    val divisor = Input(UInt(64.W))
39*a58e3351SLi Qianruo    val sign = Input(Bool())
40*a58e3351SLi Qianruo    val isHi = Input(Bool())
41*a58e3351SLi Qianruo    val isW = Input(Bool())
42*a58e3351SLi Qianruo    val in_valid = Input(Bool())
43*a58e3351SLi Qianruo    val out_ready = Input(Bool())
44*a58e3351SLi Qianruo    val in_ready = Output(Bool())
45*a58e3351SLi Qianruo    val out_valid = Output(Bool())
46*a58e3351SLi Qianruo    val result = Output(UInt(64.W))
47*a58e3351SLi Qianruo  })
48*a58e3351SLi Qianruo  val divider = Module(new SRT16DividerDataModule(len = 64))
49*a58e3351SLi Qianruo  divider.io.src(0) := io.dividend
50*a58e3351SLi Qianruo  divider.io.src(1) := io.divisor
51*a58e3351SLi Qianruo  divider.io.kill_r := false.B
52*a58e3351SLi Qianruo  divider.io.kill_w := false.B
53*a58e3351SLi Qianruo  divider.io.sign := io.sign
54*a58e3351SLi Qianruo  divider.io.isHi := io.isHi
55*a58e3351SLi Qianruo  divider.io.isW := io.isW
56*a58e3351SLi Qianruo  divider.io.out_ready := io.out_ready
57*a58e3351SLi Qianruo  divider.io.valid := io.in_valid
58*a58e3351SLi Qianruo
59*a58e3351SLi Qianruo  io.in_ready := divider.io.in_ready
60*a58e3351SLi Qianruo  io.out_valid := divider.io.out_valid
61*a58e3351SLi Qianruo
62*a58e3351SLi Qianruo  io.result := divider.io.out_data
63*a58e3351SLi Qianruo
64*a58e3351SLi Qianruo}
65*a58e3351SLi Qianruo
66*a58e3351SLi Qianruoclass IntDividerTest extends AnyFlatSpec with ChiselScalatestTester with Matchers {
67*a58e3351SLi Qianruo  behavior of "srt16 divider"
68*a58e3351SLi Qianruo  it should "run" in {
69*a58e3351SLi Qianruo    val rand = new Random(0x14226)
70*a58e3351SLi Qianruo    val testNum = 1000
71*a58e3351SLi Qianruo    test(new SRT4DividerWrapper).withAnnotations(Seq(VerilatorBackendAnnotation,
72*a58e3351SLi Qianruo      LineCoverageAnnotation,
73*a58e3351SLi Qianruo      ToggleCoverageAnnotation,
74*a58e3351SLi Qianruo      VerilatorFlags(Seq("--output-split 5000", "--output-split-cfuncs 5000",
75*a58e3351SLi Qianruo        "+define+RANDOMIZE_REG_INIT", "+define+RANDOMIZE_MEM_INIT", "--trace")),
76*a58e3351SLi Qianruo      RunFirrtlTransformAnnotation(new PrintModuleName))){ m =>
77*a58e3351SLi Qianruo      println("Test started!")
78*a58e3351SLi Qianruo      m.clock.step(20)
79*a58e3351SLi Qianruo
80*a58e3351SLi Qianruo      for (i <- 1 to testNum) {
81*a58e3351SLi Qianruo        m.clock.step(3)
82*a58e3351SLi Qianruo        m.io.in_ready.expect(true.B)
83*a58e3351SLi Qianruo        val divisor = rand.nextLong()
84*a58e3351SLi Qianruo        val dividend = rand.nextLong()
85*a58e3351SLi Qianruo        // val sign = rand.nextBoolean()
86*a58e3351SLi Qianruo
87*a58e3351SLi Qianruo        // val isSigned = if (sign) s"Signed division" else s"Unsigned division"
88*a58e3351SLi Qianruo        println(s"$i th iteration\n" + s"divisor is ${divisor.toHexString}, dividend is ${dividend.toHexString}")
89*a58e3351SLi Qianruo        m.io.in_valid.poke(true.B)
90*a58e3351SLi Qianruo        m.io.dividend.poke((s"b" + dividend.toBinaryString).asUInt(64.W))
91*a58e3351SLi Qianruo        m.io.divisor.poke((s"b" + divisor.toBinaryString).asUInt(64.W))
92*a58e3351SLi Qianruo        m.io.sign.poke(true.B)
93*a58e3351SLi Qianruo        val (quotient, remainder) = (dividend / divisor, dividend % divisor)
94*a58e3351SLi Qianruo        println(s"quotient is ${quotient.toHexString}, remainder is ${remainder.toHexString}")
95*a58e3351SLi Qianruo        var timeTaken = 0
96*a58e3351SLi Qianruo        while (m.io.out_valid.peek().litToBoolean != true) {
97*a58e3351SLi Qianruo          m.clock.step()
98*a58e3351SLi Qianruo          timeTaken += 1
99*a58e3351SLi Qianruo          if (timeTaken >= 62) assert(false, s"Timeout for single execution!!!")
100*a58e3351SLi Qianruo        }
101*a58e3351SLi Qianruo
102*a58e3351SLi Qianruo        m.io.in_valid.poke(false.B)
103*a58e3351SLi Qianruo        m.io.out_ready.poke(true.B)
104*a58e3351SLi Qianruo        m.io.isHi.poke(false.B)
105*a58e3351SLi Qianruo        m.clock.step()
106*a58e3351SLi Qianruo
107*a58e3351SLi Qianruo        m.io.result.expect((s"b" + quotient.toBinaryString).asUInt(64.W))
108*a58e3351SLi Qianruo        m.io.isHi.poke(true.B)
109*a58e3351SLi Qianruo        m.clock.step()
110*a58e3351SLi Qianruo
111*a58e3351SLi Qianruo        m.io.result.expect((s"b" + remainder.toBinaryString).asUInt(64.W))
112*a58e3351SLi Qianruo      }
113*a58e3351SLi Qianruo    }
114*a58e3351SLi Qianruo  }
115*a58e3351SLi Qianruo}