-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathbranch.py
65 lines (51 loc) · 1.73 KB
/
branch.py
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
from amaranth import *
from amaranth.back import verilog
from amaranth.build import Platform
from isa import *
from typing import List
from enum import Enum, unique
@unique
class BInsn(Enum):
BEQ = 0b000
BNE = 0b001
BLT = 0b100
BGE = 0b101
BLTU = 0b110
BGEU = 0b111
class Branch(Elaboratable):
def __init__(self, xlen: XLEN):
# Inputs
self.in1 = Signal(xlen.value)
self.in2 = Signal(xlen.value)
self.br_insn = Signal(BInsn)
# Output
self.take_branch = Signal()
def ports(self) -> List[Signal]:
return [
self.in1,
self.in2,
self.br_insn,
self.take_branch
]
def elaborate(self, platform: Platform) -> Module:
m = Module()
with m.Switch(self.br_insn):
with m.Case(BInsn.BEQ):
m.d.comb += self.take_branch.eq(self.in1 == self.in2)
with m.Case(BInsn.BNE):
m.d.comb += self.take_branch.eq(self.in1 != self.in2)
with m.Case(BInsn.BLT):
m.d.comb += self.take_branch.eq(self.in1.as_signed() < self.in2.as_signed())
with m.Case(BInsn.BGE):
m.d.comb += self.take_branch.eq(self.in1.as_signed() >= self.in2.as_signed())
with m.Case(BInsn.BLTU):
m.d.comb += self.take_branch.eq(self.in1 < self.in2)
with m.Case(BInsn.BGEU):
m.d.comb += self.take_branch.eq(self.in1 >= self.in2)
with m.Default():
m.d.comb += self.take_branch.eq(0)
return m
if __name__ == "__main__":
br = Branch(xlen=XLEN.RV32)
with open("branch.v", "w") as file:
file.write(verilog.convert(br, ports=br.ports()))