Skip to content

Commit

Permalink
fix selectRom & add selection of Radix
Browse files Browse the repository at this point in the history
  • Loading branch information
wissygh committed Jun 12, 2022
1 parent bf3eec4 commit ffdb455
Show file tree
Hide file tree
Showing 11 changed files with 166 additions and 96 deletions.
34 changes: 34 additions & 0 deletions arithmetic/src/division/srt/SRT.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package division.srt

import division.srt.srt4._
import division.srt.srt8._
import division.srt.srt16._
import chisel3._
import chisel3.util.{DecoupledIO, ValidIO}

class SRT(
dividendWidth: Int,
dividerWidth: Int,
n: Int, // the longest width
radixLog2: Int = 2,
a: Int = 2,
dTruncateWidth: Int = 4,
rTruncateWidth: Int = 4)
extends Module {
val input = IO(Flipped(DecoupledIO(new SRTInput(dividendWidth, dividerWidth, n))))
val output = IO(ValidIO(new SRTOutput(dividerWidth, dividendWidth)))
// select radix
if (radixLog2 == 2) { // SRT4
val srt = Module(new SRT4(dividendWidth, dividerWidth, n, radixLog2, a, dTruncateWidth, rTruncateWidth))
srt.input <> input
output <> srt.output
} else if (radixLog2 == 3) { // SRT8
val srt = Module(new SRT8(dividendWidth, dividerWidth, n, radixLog2, a, dTruncateWidth, rTruncateWidth))
srt.input <> input
output <> srt.output
} else if (radixLog2 == 4) { //SRT16
val srt = Module(new SRT16(dividendWidth, dividerWidth, n, radixLog2 >> 1, a, dTruncateWidth, rTruncateWidth))
srt.input <> input
output <> srt.output
}
}
25 changes: 24 additions & 1 deletion arithmetic/src/division/srt/SRTIO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package division.srt

import chisel3._
import chisel3.util.log2Ceil

// SRTIO
class SRTInput(dividendWidth: Int, dividerWidth: Int, n: Int) extends Bundle {
val dividend = UInt(dividendWidth.W) //.***********
val divider = UInt(dividerWidth.W) //.1**********
Expand All @@ -13,3 +13,26 @@ class SRTOutput(reminderWidth: Int, quotientWidth: Int) extends Bundle {
val reminder = UInt(reminderWidth.W)
val quotient = UInt(quotientWidth.W)
}

//OTFIO
class OTFInput(qWidth: Int, ohWidth: Int) extends Bundle {
val quotient = UInt(qWidth.W)
val quotientMinusOne = UInt(qWidth.W)
val selectedQuotientOH = UInt(ohWidth.W)
}

class OTFOutput(qWidth: Int) extends Bundle {
val quotient = UInt(qWidth.W)
val quotientMinusOne = UInt(qWidth.W)
}

// QDSIO
class QDSInput(rWidth: Int, partialDividerWidth: Int) extends Bundle {
val partialReminderCarry: UInt = UInt(rWidth.W)
val partialReminderSum: UInt = UInt(rWidth.W)
val partialDivider: UInt = UInt(partialDividerWidth.W)
}

class QDSOutput(ohWidth: Int) extends Bundle {
val selectedQuotientOH: UInt = UInt(ohWidth.W)
}
12 changes: 1 addition & 11 deletions arithmetic/src/division/srt/srt16/OTF.scala
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
package division.srt.srt16

import division.srt._
import chisel3._
import chisel3.util.Mux1H

class OTFInput(qWidth: Int, ohWidth: Int) extends Bundle {
val quotient = UInt(qWidth.W)
val quotientMinusOne = UInt(qWidth.W)
val selectedQuotientOH = UInt(ohWidth.W)
}

class OTFOutput(qWidth: Int) extends Bundle {
val quotient = UInt(qWidth.W)
val quotientMinusOne = UInt(qWidth.W)
}

class OTF(radixLog2: Int, qWidth: Int, ohWidth: Int) extends Module {
val input = IO(Input(new OTFInput(qWidth, ohWidth)))
val output = IO(Output(new OTFOutput(qWidth)))
Expand Down
23 changes: 4 additions & 19 deletions arithmetic/src/division/srt/srt16/QDS.scala
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
package division.srt.srt16

import division.srt._
import chisel3._
import chisel3.util.BitPat
import chisel3.util.BitPat.bitPatToUInt
import chisel3.util.experimental.decode._
import utils.extend

class QDSInput(rWidth: Int, partialDividerWidth: Int) extends Bundle {
val partialReminderCarry: UInt = UInt(rWidth.W)
val partialReminderSum: UInt = UInt(rWidth.W)
val partialDivider: UInt = UInt(partialDividerWidth.W)
}

class QDSOutput(ohWidth: Int) extends Bundle {
val selectedQuotientOH: UInt = UInt(ohWidth.W)
}
import utils.{extend, sIntToBitPat}

class QDS(rWidth: Int, ohWidth: Int, partialDividerWidth: Int, tables: Seq[Seq[Int]]) extends Module {
// IO
Expand All @@ -24,14 +16,7 @@ class QDS(rWidth: Int, ohWidth: Int, partialDividerWidth: Int, tables: Seq[Seq[I
lazy val selectRom = VecInit(tables.map {
case x =>
VecInit(x.map {
case x =>
new StringBuffer("b")
.append(
if ((-x).toBinaryString.length >= rWidth) (-x).toBinaryString.reverse.substring(0, rWidth).reverse
else (-x).toBinaryString
)
.toString
.U(rWidth.W)
case x => bitPatToUInt(sIntToBitPat(-x, rWidth))
})
})

Expand Down
12 changes: 1 addition & 11 deletions arithmetic/src/division/srt/srt4/OTF.scala
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
package division.srt.srt4

import division.srt._
import chisel3._
import chisel3.util.Mux1H

class OTFInput(qWidth: Int, ohWidth: Int) extends Bundle {
val quotient = UInt(qWidth.W)
val quotientMinusOne = UInt(qWidth.W)
val selectedQuotientOH = UInt(ohWidth.W)
}

class OTFOutput(qWidth: Int) extends Bundle {
val quotient = UInt(qWidth.W)
val quotientMinusOne = UInt(qWidth.W)
}

class OTF(radixLog2: Int, qWidth: Int, ohWidth: Int) extends Module {
val input = IO(Input(new OTFInput(qWidth, ohWidth)))
val output = IO(Output(new OTFOutput(qWidth)))
Expand Down
25 changes: 5 additions & 20 deletions arithmetic/src/division/srt/srt4/QDS.scala
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
package division.srt.srt4

import division.srt._
import chisel3._
import chisel3.util.BitPat
import chisel3.util.experimental.decode.{TruthTable}
import utils.extend

class QDSInput(rWidth: Int, partialDividerWidth: Int) extends Bundle {
val partialReminderCarry: UInt = UInt(rWidth.W)
val partialReminderSum: UInt = UInt(rWidth.W)
val partialDivider: UInt = UInt(partialDividerWidth.W)
}

class QDSOutput(ohWidth: Int) extends Bundle {
val selectedQuotientOH: UInt = UInt(ohWidth.W)
}
import chisel3.util.BitPat.bitPatToUInt
import chisel3.util.experimental.decode.TruthTable
import utils.{extend, sIntToBitPat}

class QDS(rWidth: Int, ohWidth: Int, partialDividerWidth: Int, tables: Seq[Seq[Int]]) extends Module {
// IO
Expand Down Expand Up @@ -46,14 +38,7 @@ class QDS(rWidth: Int, ohWidth: Int, partialDividerWidth: Int, tables: Seq[Seq[I
lazy val selectRom = VecInit(tables.map {
case x =>
VecInit(x.map {
case x =>
new StringBuffer("b")
.append(
if ((-x).toBinaryString.length >= rWidth) (-x).toBinaryString.reverse.substring(0, rWidth).reverse
else (-x).toBinaryString
)
.toString
.U(rWidth.W)
case x => bitPatToUInt(sIntToBitPat(-x, rWidth))
})
})

Expand Down
12 changes: 1 addition & 11 deletions arithmetic/src/division/srt/srt8/OTF.scala
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
package division.srt.srt8

import division.srt._
import chisel3._
import chisel3.util.Mux1H

class OTFInput(qWidth: Int, ohWidth: Int) extends Bundle {
val quotient = UInt(qWidth.W)
val quotientMinusOne = UInt(qWidth.W)
val selectedQuotientOH = UInt(ohWidth.W)
}

class OTFOutput(qWidth: Int) extends Bundle {
val quotient = UInt(qWidth.W)
val quotientMinusOne = UInt(qWidth.W)
}

class OTF(radixLog2: Int, qWidth: Int, ohWidth: Int) extends Module {
val input = IO(Input(new OTFInput(qWidth, ohWidth)))
val output = IO(Output(new OTFOutput(qWidth)))
Expand Down
27 changes: 6 additions & 21 deletions arithmetic/src/division/srt/srt8/QDS.scala
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
package division.srt.srt8

import division.srt._
import chisel3._
import chisel3.util.{BitPat}
import chisel3.util.experimental.decode.{TruthTable}
import utils.extend

class QDSInput(rWidth: Int, partialDividerWidth: Int) extends Bundle {
val partialReminderCarry: UInt = UInt(rWidth.W)
val partialReminderSum: UInt = UInt(rWidth.W)
val partialDivider: UInt = UInt(partialDividerWidth.W)
}

class QDSOutput(ohWidth: Int) extends Bundle {
val selectedQuotientOH: UInt = UInt(ohWidth.W)
}
import chisel3.util.BitPat
import chisel3.util.BitPat.bitPatToUInt
import chisel3.util.experimental.decode.TruthTable
import utils.{extend, sIntToBitPat}

class QDS(rWidth: Int, ohWidth: Int, partialDividerWidth: Int, tables: Seq[Seq[Int]]) extends Module {
// IO
Expand All @@ -25,14 +17,7 @@ class QDS(rWidth: Int, ohWidth: Int, partialDividerWidth: Int, tables: Seq[Seq[I
lazy val selectRom = VecInit(tables.map {
case x =>
VecInit(x.map {
case x =>
new StringBuffer("b")
.append(
if ((-x).toBinaryString.length >= rWidth) (-x).toBinaryString.reverse.substring(0, rWidth).reverse
else (-x).toBinaryString
)
.toString
.U(rWidth.W)
case x => bitPatToUInt(sIntToBitPat(-x, rWidth))
})
})

Expand Down
2 changes: 1 addition & 1 deletion arithmetic/src/division/srt/srt8/SRT8.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import division.srt._
import division.srt.SRTTable
import chisel3._
import chisel3.util._
import utils.{leftShift}
import utils.leftShift

/** SRT8
* 1/2 <= d < 1, 1/2 < rho <=1, 0 < q < 2
Expand Down
2 changes: 1 addition & 1 deletion arithmetic/src/utils/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ package object utils {
else
BitPat((x + (1 << w)).U(w.W))
}

// left shift and keep the width of Bits
def leftShift(x: Bits, n: Int): UInt = {
val length: Int = x.getWidth
Expand Down
88 changes: 88 additions & 0 deletions arithmetic/tests/src/division/srt/SRTTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package division.srt

import chisel3._
import chisel3.tester.{ChiselUtestTester, testableClock, testableData}
import utest._

import scala.util.Random

object SRTTest extends TestSuite with ChiselUtestTester {
def tests: Tests = Tests {
test("SRT should pass") {
def testcase(n: Int = 64,
radixLog2: Int = 4,
a: Int = 2,
dTruncateWidth: Int = 4,
rTruncateWidth: Int = 4): Unit ={
//tips
println("SRT%d(width = %d, a = %d, dTruncateWidth = %d, rTruncateWidth = %d) should pass ".format(
1 << radixLog2 , n , a, dTruncateWidth, rTruncateWidth))
// parameters
val m: Int = n - 1
val p: Int = Random.nextInt(m - radixLog2 +1) //order to offer guardwidth
val q: Int = Random.nextInt(m - radixLog2 +1)
val dividend: BigInt = BigInt(p, Random)
val divider: BigInt = BigInt(q, Random)
// val dividend: BigInt = BigInt("65")
// val divider: BigInt = BigInt("1")
def zeroCheck(x: BigInt): Int = {
var flag = false
var k: Int = m
while (!flag && (k >= -1)) {
flag = ((BigInt(1) << k) & x) != 0
k = k - 1
}
k + 1
}
val zeroHeadDividend: Int = m - zeroCheck(dividend)
val zeroHeadDivider: Int = m - zeroCheck(divider)
val needComputerWidth: Int = zeroHeadDivider - zeroHeadDividend + 1 + (if(radixLog2 == 4) 2 else radixLog2) -1
val noguard: Boolean = needComputerWidth % radixLog2 == 0
val guardWidth: Int = if (noguard) 0 else radixLog2 - needComputerWidth % radixLog2
val counter: Int = (needComputerWidth + guardWidth) / radixLog2
if ((divider == 0) || (divider > dividend) || (needComputerWidth <= 0))
return
val quotient: BigInt = dividend / divider
val remainder: BigInt = dividend % divider
val leftShiftWidthDividend: Int = zeroHeadDividend - guardWidth
val leftShiftWidthDivider: Int = zeroHeadDivider
// println("dividend = %8x, dividend = %d ".format(dividend, dividend))
// println("divider = %8x, divider = %d".format(divider, divider))
// println("zeroHeadDividend = %d, dividend << zeroHeadDividend = %d".format(zeroHeadDividend, dividend << leftShiftWidthDividend))
// println("zeroHeadDivider = %d, divider << zeroHeadDivider = %d".format(zeroHeadDivider, divider << leftShiftWidthDivider))
// println("quotient = %d, remainder = %d".format(quotient, remainder))
// println("counter = %d, needComputerWidth = %d".format(counter, needComputerWidth))
// test
testCircuit(new SRT(n, n, n, radixLog2, a, dTruncateWidth, rTruncateWidth),
Seq(chiseltest.internal.NoThreadingAnnotation,
chiseltest.simulator.WriteVcdAnnotation)) {
dut: SRT =>
dut.clock.setTimeout(0)
dut.input.valid.poke(true.B)
dut.input.bits.dividend.poke((dividend << leftShiftWidthDividend).U)
dut.input.bits.divider.poke((divider << leftShiftWidthDivider).U)
dut.input.bits.counter.poke(counter.U)
dut.clock.step()
dut.input.valid.poke(false.B)
var flag = false
for (a <- 1 to 1000 if !flag) {
if (dut.output.valid.peek().litValue == 1) {
flag = true
println(dut.output.bits.quotient.peek().litValue)
println(dut.output.bits.reminder.peek().litValue)
utest.assert(dut.output.bits.quotient.peek().litValue == quotient)
utest.assert(dut.output.bits.reminder.peek().litValue >> zeroHeadDivider == remainder)
}
dut.clock.step()
}
utest.assert(flag)
dut.clock.step(scala.util.Random.nextInt(5))
}
}
testcase(64)
for( i <- 1 to 50){
testcase(64,3,7,4)
}
}
}
}

0 comments on commit ffdb455

Please sign in to comment.