3 from ..isa
import Funct3
6 __all__
= ["DividerInterface", "Divider", "DummyDivider"]
9 class DividerInterface
:
12 self
.x_src1
= Signal(32)
13 self
.x_src2
= Signal(32)
14 self
.x_valid
= Signal()
15 self
.x_stall
= Signal()
17 self
.m_result
= Signal(32)
18 self
.m_busy
= Signal()
21 class Divider(DividerInterface
, Elaboratable
):
22 def elaborate(self
, platform
):
29 with m
.Switch(self
.x_op
):
30 with m
.Case(Funct3
.DIV
):
31 m
.d
.comb
+= x_enable
.eq(1), x_signed
.eq(1)
32 with m
.Case(Funct3
.DIVU
):
33 m
.d
.comb
+= x_enable
.eq(1)
34 with m
.Case(Funct3
.REM
):
35 m
.d
.comb
+= x_enable
.eq(1), x_modulus
.eq(1), x_signed
.eq(1)
36 with m
.Case(Funct3
.REMU
):
37 m
.d
.comb
+= x_enable
.eq(1), x_modulus
.eq(1)
41 m
.d
.comb
+= x_negative
.eq(x_signed
& self
.x_src1
[31])
43 m
.d
.comb
+= x_negative
.eq(x_signed
& (self
.x_src1
[31] ^ self
.x_src2
[31]))
45 x_dividend
= Signal(32)
46 x_divisor
= Signal(32)
48 x_dividend
.eq(Mux(x_signed
& self
.x_src1
[31], -self
.x_src1
, self
.x_src1
)),
49 x_divisor
.eq(Mux(x_signed
& self
.x_src2
[31], -self
.x_src2
, self
.x_src2
))
55 timer
= Signal(range(33), reset
=32)
58 remainder
= Signal(32)
59 difference
= Signal(33)
63 with m
.If(x_enable
& self
.x_valid
& ~self
.x_stall
):
65 m_modulus
.eq(x_modulus
),
66 m_negative
.eq(x_negative
)
68 with m
.If(x_divisor
== 0):
72 remainder
.eq(self
.x_src1
)
74 with m
.Elif(x_signed
& (self
.x_src1
== -2**31) & (self
.x_src2
== -1)):
77 quotient
.eq(self
.x_src1
),
80 with m
.Elif(x_dividend
== 0):
87 quotient
.eq(x_dividend
),
89 divisor
.eq(x_divisor
),
94 with m
.State("DIVIDE"):
95 m
.d
.comb
+= self
.m_busy
.eq(1)
96 with m
.If(timer
!= 0):
97 m
.d
.sync
+= timer
.eq(timer
- 1)
98 m
.d
.comb
+= difference
.eq(Cat(quotient
[31], remainder
) - divisor
)
99 with m
.If(difference
[32]):
101 remainder
.eq(Cat(quotient
[31], remainder
)),
102 quotient
.eq(Cat(0, quotient
))
106 remainder
.eq(difference
),
107 quotient
.eq(Cat(1, quotient
))
111 quotient
.eq(Mux(m_negative
, -quotient
, quotient
)),
112 remainder
.eq(Mux(m_negative
, -remainder
, remainder
))
116 m
.d
.comb
+= self
.m_result
.eq(Mux(m_modulus
, remainder
, quotient
))
121 class DummyDivider(DividerInterface
, Elaboratable
):
122 def elaborate(self
, platform
):
125 x_result
= Signal
.like(self
.m_result
)
127 with m
.Switch(self
.x_op
):
128 # As per the RVFI specification (ยง "Alternative Arithmetic Operations").
129 # https://github.com/SymbioticEDA/riscv-formal/blob/master/docs/rvfi.md
130 with m
.Case(Funct3
.DIV
):
131 m
.d
.comb
+= x_result
.eq((self
.x_src1
- self
.x_src2
) ^
C(0x7f8529ec))
132 with m
.Case(Funct3
.DIVU
):
133 m
.d
.comb
+= x_result
.eq((self
.x_src1
- self
.x_src2
) ^
C(0x10e8fd70))
134 with m
.Case(Funct3
.REM
):
135 m
.d
.comb
+= x_result
.eq((self
.x_src1
- self
.x_src2
) ^
C(0x8da68fa5))
136 with m
.Case(Funct3
.REMU
):
137 m
.d
.comb
+= x_result
.eq((self
.x_src1
- self
.x_src2
) ^
C(0x3138d0e1))
139 with m
.If(~self
.x_stall
):
140 m
.d
.sync
+= self
.m_result
.eq(x_result
)
142 m
.d
.comb
+= self
.m_busy
.eq(C(0))