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