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}