-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathFPMult.scala
128 lines (98 loc) · 3.62 KB
/
FPMult.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Takes 2 clock cyles to produce the result
package fpDivision
import chisel3._
import chisel3.util.Cat
//import FloatUtils.{floatToBigInt, doubleToBigInt}
class MantissaRounder(val n: Int) extends Module {
val io = IO(new Bundle {
val in = Input(Bits(width = n.W))
val out = Output(Bits(width = (n - 1).W))
})
io.out := io.in(n - 1, 1)// + io.in(0)
}
class FPMult(val n: Int) extends Module {
val io = IO(new Bundle {
val a = Input(Bits(width = n.W))
val b = Input(Bits(width = n.W))
val res = Output(Bits(width = n.W))
})
val a_wrap = new FloatWrapper(io.a)
val b_wrap = new FloatWrapper(io.b)
val stage1_sign = a_wrap.sign ^ b_wrap.sign
val stage1_exponent = a_wrap.exponent + b_wrap.exponent
val stage1_mantissa = a_wrap.mantissa * b_wrap.mantissa
val stage1_zero = a_wrap.zero || b_wrap.zero
/*
val sign_reg = Reg(next = stage1_sign)
val exponent_reg = Reg(next = stage1_exponent)
val mantissa_reg = Reg(next = stage1_mantissa)
val zero_reg = Reg(next = stage1_zero)
*/
val sign_reg = stage1_sign
val exponent_reg = stage1_exponent
val mantissa_reg = stage1_mantissa
val zero_reg = stage1_zero
val stage2_sign = sign_reg
val stage2_exponent = Wire(UInt(width = (a_wrap.exponent.getWidth).W))
val stage2_mantissa = Wire(UInt(width = (a_wrap.mantissa.getWidth - 1).W))
val (mantissaLead, mantissaSize, exponentSize, exponentSub) = n match {
case 32 => (47, 23, 8, 127)
case 64 => (105, 52, 11, 1023)
}
val rounder = Module(new MantissaRounder(mantissaSize + 1))
when (zero_reg) {
stage2_exponent := UInt(0, exponentSize)
rounder.io.in := UInt(0, mantissaSize + 1)
} .elsewhen (mantissa_reg(mantissaLead) === Bits(1)) {
stage2_exponent := exponent_reg - UInt(exponentSub - 1)
rounder.io.in := mantissa_reg(mantissaLead - 1,
mantissaLead - mantissaSize - 1)
} .otherwise {
stage2_exponent := exponent_reg - UInt(exponentSub)
rounder.io.in := mantissa_reg(mantissaLead - 2,
mantissaLead - mantissaSize - 2)
}
stage2_mantissa := rounder.io.out
io.res := Cat(stage2_sign.toBits,
stage2_exponent.toBits,
stage2_mantissa.toBits)
}
class FPMult32 extends FPMult(32) {}
class FPMult64 extends FPMult(64) {}
/*
class FPMult32Test(c: FPMult32) extends Tester(c) {
var lastExpected = 0.0f
poke(c.io.a, floatToBigInt(0.0f))
poke(c.io.b, floatToBigInt(3.0f))
step(1)
for (i <- 0 until 8) {
val a = rnd.nextFloat() * 10000.0f - 5000.0f
val b = rnd.nextFloat() * 10000.0f - 5000.0f
val expected = a * b
poke(c.io.a, floatToBigInt(a))
poke(c.io.b, floatToBigInt(b))
step(1)
println(s"Expecting $lastExpected or ${floatToBigInt(lastExpected)}")
expect(c.io.res, floatToBigInt(lastExpected))
lastExpected = expected
}
step(1)
expect(c.io.res, floatToBigInt(lastExpected))
}
class FPMult64Test(c: FPMult64) extends Tester(c) {
var lastExpected = 0.0
for (i <- 0 until 8) {
val a = rnd.nextDouble() * 10000.0 - 5000.0
val b = rnd.nextDouble() * 10000.0 - 5000.0
val expected = a * b
poke(c.io.a, doubleToBigInt(a))
poke(c.io.b, doubleToBigInt(b))
step(1)
if (i > 0) {
expect(c.io.res, doubleToBigInt(lastExpected))
}
lastExpected = expected
}
step(1)
expect(c.io.res, doubleToBigInt(lastExpected))
}*/