Skip to content

Commit 3ddbc0b

Browse files
committed
Some progress on the Chisel3 implementation
1 parent 441f8ca commit 3ddbc0b

File tree

5 files changed

+318
-712
lines changed

5 files changed

+318
-712
lines changed

chisel/src/main/scala/why/ALU.scala

Lines changed: 218 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,55 +5,226 @@ import chisel3.util._
55

66
class ALU extends Module {
77
val io = IO(new Bundle {
8-
val in = Input(ALUInput())
9-
val out = Output(SInt(64.W))
8+
val in = Flipped(Valid(ALUInput()))
9+
val out = Valid(UInt(128.W))
1010
})
1111

12-
val a_u = io.in.a.asUInt
13-
val b_u = io.in.b.asUInt
14-
15-
val b_short = Wire(UInt(19.W))
16-
b_short := io.in.b.asUInt()
17-
18-
io.out := "hdeadbeef".U.asSInt
19-
20-
switch (io.in.op) {
21-
is (ALU.Zero) { io.out := 0.S }
22-
is (ALU.Add) { io.out := io.in.a + io.in.b }
23-
is (ALU.Subtract) { io.out := io.in.a - io.in.b }
24-
is (ALU.SignedMultiply) { io.out := io.in.a * io.in.b }
25-
is (ALU.UnsignedMultiply) { io.out := (a_u * b_u).asSInt }
26-
is (ALU.SignedDivide) { io.out := io.in.a / io.in.b }
27-
is (ALU.UnsignedDivide) { io.out := (a_u / b_u).asSInt }
28-
is (ALU.SignedModulo) { io.out := io.in.a % io.in.b }
29-
is (ALU.UnsignedModulo) { io.out := (a_u % b_u).asSInt }
30-
is (ALU.BitwiseAND) { io.out := io.in.a & io.in.b }
31-
is (ALU.BitwiseOR) { io.out := io.in.a | io.in.b }
32-
is (ALU.BitwiseXOR) { io.out := io.in.a ^ io.in.b }
33-
is (ALU.BitwiseNAND) { io.out := ~(io.in.a & io.in.b) }
34-
is (ALU.BitwiseNOR) { io.out := ~(io.in.a | io.in.b) }
35-
is (ALU.BitwiseXNOR) { io.out := ~(io.in.a ^ io.in.b) }
36-
is (ALU.LogicalAND) { io.out := (a_u.orR & b_u.orR).asSInt * -1.S }
37-
is (ALU.LogicalOR) { io.out := (a_u.orR | b_u.orR).asSInt * -1.S }
38-
is (ALU.LogicalXOR) { io.out := (a_u.orR ^ b_u.orR).asSInt * -1.S }
39-
is (ALU.LogicalNAND) { io.out := ((a_u.orR & b_u.orR) === 0.U).asSInt * -1.S }
40-
is (ALU.LogicalNOR) { io.out := ((a_u.orR | b_u.orR) === 0.U).asSInt * -1.S }
41-
is (ALU.LogicalXNOR) { io.out := ((a_u.orR ^ b_u.orR) === 0.U).asSInt * -1.S }
42-
is (ALU.ShiftLeftLogical) { io.out := io.in.a << b_short }
43-
is (ALU.ShiftRightLogical) { io.out := io.in.a >> b_short }
44-
is (ALU.ShiftRightArithmetic) { io.out := (a_u >> b_short).asSInt }
45-
is (ALU.Equal) { io.out := (io.in.a === io.in.b).asSInt * -1.S }
46-
is (ALU.NotEqual) { io.out := (io.in.a =/= io.in.b).asSInt * -1.S }
47-
is (ALU.SignedLessThan) { io.out := (io.in.a < io.in.b).asSInt * -1.S }
48-
is (ALU.SignedLessThanOrEqual) { io.out := (io.in.a <= io.in.b).asSInt * -1.S }
49-
is (ALU.SignedGreaterThan) { io.out := (io.in.a > io.in.b).asSInt * -1.S }
50-
is (ALU.SignedGreaterThanOrEqual) { io.out := (io.in.a >= io.in.b).asSInt * -1.S }
51-
is (ALU.UnsignedLessThan) { io.out := (a_u < b_u).asSInt * -1.S }
52-
is (ALU.UnsignedLessThanOrEqual) { io.out := (a_u <= b_u).asSInt * -1.S }
53-
is (ALU.UnsignedGreaterThan) { io.out := (a_u > b_u).asSInt * -1.S }
54-
is (ALU.UnsignedGreaterThanOrEqual) { io.out := (a_u >= b_u).asSInt * -1.S }
55-
is (ALU.BitwiseNOT) { io.out := ~io.in.a }
56-
is (ALU.LogicalNOT) { io.out := (io.in.a.asUInt.orR === 0.U).asSInt * -1.S }
12+
val a = io.in.bits.a
13+
val b = io.in.bits.b
14+
val aS = io.in.bits.a.asSInt
15+
val bS = io.in.bits.b.asSInt
16+
17+
val shiftOverflow = 64.U <= b
18+
19+
io.out.bits := DontCare
20+
io.out.valid := false.B
21+
22+
val sReady :: sSignedMultiply :: sUnsignedMultiply :: Nil = Enum(3)
23+
val state = RegInit(sReady)
24+
25+
val booth = Module(new BoothMultiplier)
26+
booth.io.in.bits := DontCare
27+
booth.io.in.valid := false.B
28+
29+
30+
when (state === sSignedMultiply) {
31+
32+
when (booth.io.out.valid) {
33+
io.out.bits := booth.io.out.bits
34+
io.out.valid := true.B
35+
state := sReady
36+
}
37+
38+
} .elsewhen (state === sReady) {
39+
40+
switch (io.in.bits.op) {
41+
is (ALU.Zero) {
42+
io.out.bits := 0.S
43+
io.out.valid := true.B
44+
}
45+
46+
is (ALU.Add) {
47+
io.out.bits := aS + bS
48+
io.out.valid := true.B
49+
}
50+
51+
is (ALU.Subtract) {
52+
io.out.bits := aS - bS
53+
io.out.valid := true.B
54+
}
55+
56+
is (ALU.SignedMultiply) {
57+
booth.io.in.bits.m := aS
58+
booth.io.in.bits.r := bS
59+
booth.io.in.valid := true.B
60+
state := sSignedMultiply
61+
}
62+
63+
is (ALU.UnsignedMultiply) {
64+
// io.out.bits := (a * b).asSInt
65+
// io.out.valid := true.B
66+
}
67+
68+
is (ALU.SignedDivide) {
69+
// io.out.bits := aS / bS
70+
// io.out.valid := true.B
71+
}
72+
73+
is (ALU.UnsignedDivide) {
74+
// io.out.bits := (a / b).asSInt
75+
// io.out.valid := true.B
76+
}
77+
78+
is (ALU.SignedModulo) {
79+
// io.out.bits := aS % bS
80+
// io.out.valid := true.B
81+
}
82+
83+
is (ALU.UnsignedModulo) {
84+
// io.out.bits := (a % b).asSInt
85+
// io.out.valid := true.B
86+
}
87+
88+
is (ALU.BitwiseAND) {
89+
io.out.bits := a & b
90+
io.out.valid := true.B
91+
}
92+
93+
is (ALU.BitwiseOR) {
94+
io.out.bits := a | b
95+
io.out.valid := true.B
96+
}
97+
98+
is (ALU.BitwiseXOR) {
99+
io.out.bits := a ^ b
100+
io.out.valid := true.B
101+
}
102+
103+
is (ALU.BitwiseNAND) {
104+
io.out.bits := ~(a & b)
105+
io.out.valid := true.B
106+
}
107+
108+
is (ALU.BitwiseNOR) {
109+
io.out.bits := ~(a | b)
110+
io.out.valid := true.B
111+
}
112+
113+
is (ALU.BitwiseXNOR) {
114+
io.out.bits := ~(a ^ b)
115+
io.out.valid := true.B
116+
}
117+
118+
is (ALU.LogicalAND) {
119+
io.out.bits := (a.orR & b.orR) =/= 0.U
120+
io.out.valid := true.B
121+
}
122+
123+
is (ALU.LogicalOR) {
124+
io.out.bits := (a.orR | b.orR) =/= 0.U
125+
io.out.valid := true.B
126+
}
127+
128+
is (ALU.LogicalXOR) {
129+
io.out.bits := (a.orR ^ b.orR) =/= 0.U
130+
io.out.valid := true.B
131+
}
132+
133+
is (ALU.LogicalNAND) {
134+
io.out.bits := (a.orR & b.orR) === 0.U
135+
io.out.valid := true.B
136+
}
137+
138+
is (ALU.LogicalNOR) {
139+
io.out.bits := (a.orR | b.orR) === 0.U
140+
io.out.valid := true.B
141+
}
142+
143+
is (ALU.LogicalXNOR) {
144+
io.out.bits := (a.orR ^ b.orR) === 0.U
145+
io.out.valid := true.B
146+
}
147+
148+
is (ALU.ShiftLeftLogical) {
149+
io.out.bits := Mux(shiftOverflow, 0.U, a << b(5, 0))
150+
io.out.valid := true.B
151+
}
152+
153+
is (ALU.ShiftRightLogical) {
154+
io.out.bits := Mux(shiftOverflow, 0.U, a >> b(5, 0))
155+
io.out.valid := true.B
156+
}
157+
158+
is (ALU.ShiftRightArithmetic) {
159+
when (shiftOverflow) {
160+
io.out.bits := Mux(a(63), -1.U(64.W).asSInt, 0.U)
161+
} .otherwise {
162+
io.out.bits := a >> b(5, 0)
163+
}
164+
io.out.valid := true.B
165+
}
166+
167+
is (ALU.Equal) {
168+
io.out.bits := a === b
169+
io.out.valid := true.B
170+
}
171+
172+
is (ALU.NotEqual) {
173+
io.out.bits := a =/= b
174+
io.out.valid := true.B
175+
}
176+
177+
is (ALU.SignedLessThan) {
178+
io.out.bits := aS < bS
179+
io.out.valid := true.B
180+
}
181+
182+
is (ALU.SignedLessThanOrEqual) {
183+
io.out.bits := aS <= bS
184+
io.out.valid := true.B
185+
}
186+
187+
is (ALU.SignedGreaterThan) {
188+
io.out.bits := aS > bS
189+
io.out.valid := true.B
190+
}
191+
192+
is (ALU.SignedGreaterThanOrEqual) {
193+
io.out.bits := aS >= bS
194+
io.out.valid := true.B
195+
}
196+
197+
is (ALU.UnsignedLessThan) {
198+
io.out.bits := a < b
199+
io.out.valid := true.B
200+
}
201+
202+
is (ALU.UnsignedLessThanOrEqual) {
203+
io.out.bits := a <= b
204+
io.out.valid := true.B
205+
}
206+
207+
is (ALU.UnsignedGreaterThan) {
208+
io.out.bits := a > b
209+
io.out.valid := true.B
210+
}
211+
212+
is (ALU.UnsignedGreaterThanOrEqual) {
213+
io.out.bits := a >= b
214+
io.out.valid := true.B
215+
}
216+
217+
is (ALU.BitwiseNOT) {
218+
io.out.bits := ~a
219+
io.out.valid := true.B
220+
}
221+
222+
is (ALU.LogicalNOT) {
223+
io.out.bits := a === 0.U
224+
io.out.valid := true.B
225+
}
226+
}
227+
57228
}
58229
}
59230

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package why
2+
3+
import chisel3._
4+
import chisel3.util._
5+
6+
class BoothMultiplier extends Module {
7+
val io = IO(new Bundle {
8+
val in = Flipped(Valid(new Bundle {
9+
val m = SInt(64.W)
10+
val r = SInt(64.W)
11+
}))
12+
13+
val out = Valid(SInt(128.W))
14+
})
15+
16+
val sReady :: sBusy :: Nil = Enum(2)
17+
val state = RegInit(sReady)
18+
19+
val m = RegInit(0.S(64.W))
20+
val r = RegInit(0.S(64.W))
21+
22+
val a = RegInit(0.S(129.W))
23+
val s = RegInit(0.S(129.W))
24+
val p = RegInit(0.S(129.W))
25+
val t = RegInit(0.S(129.W))
26+
val c = RegInit(0.U(6.W))
27+
28+
val out = RegInit(0.U.asTypeOf(chiselTypeOf(io.out)))
29+
io.out := out
30+
31+
val step = RegInit(0.U(3.W))
32+
33+
when (state === sReady && io.in.valid) {
34+
35+
m := io.in.bits.m
36+
r := io.in.bits.r
37+
c := 0.U
38+
t := 0.U
39+
40+
state := sBusy
41+
42+
out.bits := 0.U
43+
out.valid := false.B
44+
45+
} .elsewhen (state === sBusy) {
46+
47+
when (step === 0.U) {
48+
49+
a := Cat(m.asUInt, 0.U(65.W)).asSInt
50+
s := Cat((-m).asUInt, 0.U(65.W)).asSInt
51+
p := Cat(0.U(64.W), r.asUInt, 0.U(1.W)).asSInt
52+
step := 1.U
53+
54+
} .elsewhen (step === 1.U) {
55+
56+
switch (p(1, 0)) {
57+
is ("b01".U) {
58+
t := p + a
59+
}
60+
is ("b10".U) {
61+
t := p + s
62+
}
63+
is ("b00".U) {
64+
t := p
65+
}
66+
is ("b11".U) {
67+
t := p
68+
}
69+
}
70+
71+
step := 2.U
72+
73+
} .elsewhen (step === 2.U) {
74+
75+
p := t >> 1
76+
77+
when (c === 63.U) {
78+
out.bits := t(128, 1)
79+
out.valid := true.B
80+
state := sReady
81+
} .otherwise {
82+
c := c + 1.U
83+
step := 1.U
84+
}
85+
86+
}
87+
88+
}
89+
}

0 commit comments

Comments
 (0)