add div and shift (as experiment)
[soc.git] / src / experiment / alu_hier.py
1 from nmigen import Elaboratable, Signal, Module
2 from nmigen.cli import main
3
4
5 class Adder(Elaboratable):
6 def __init__(self, width):
7 self.a = Signal(width)
8 self.b = Signal(width)
9 self.o = Signal(width)
10
11 def elaborate(self, platform):
12 m = Module()
13 m.d.comb += self.o.eq(self.a + self.b)
14 return m
15
16
17 class Subtractor(Elaboratable):
18 def __init__(self, width):
19 self.a = Signal(width)
20 self.b = Signal(width)
21 self.o = Signal(width)
22
23 def elaborate(self, platform):
24 m = Module()
25 m.d.comb += self.o.eq(self.a - self.b)
26 return m
27
28
29 class Multiplier(Elaboratable):
30 def __init__(self, width):
31 self.a = Signal(width)
32 self.b = Signal(width)
33 self.o = Signal(width)
34
35 def elaborate(self, platform):
36 m = Module()
37 m.d.comb += self.o.eq(self.a * self.b)
38 return m
39
40
41 class Shifter(Elaboratable):
42 def __init__(self, width):
43 self.a = Signal(width)
44 self.b = Signal(max=width)
45 self.o = Signal(width)
46
47 def elaborate(self, platform):
48 m = Module()
49 m.d.comb += self.o.eq(self.a << self.b)
50 return m
51
52
53 class ALU(Elaboratable):
54 def __init__(self, width):
55 self.op = Signal(2)
56 self.a = Signal(width)
57 self.b = Signal(width)
58 self.o = Signal(width)
59 self.width = width
60
61 def elaborate(self, platform):
62 m = Module()
63 add = Adder(self.width)
64 sub = Subtractor(self.width)
65 mul = Multiplier(self.width)
66 shf = Shifter(self.width)
67
68 m.submodules.add = add
69 m.submodules.sub = sub
70 m.submodules.mul = mul
71 m.submodules.shf = shf
72 for mod in [add, sub, mul, shf]:
73 m.d.comb += [
74 mod.a.eq(self.a),
75 mod.b.eq(self.b),
76 ]
77 with m.Switch(self.op):
78 with m.Case(0):
79 m.d.comb += self.o.eq(add.o)
80 with m.Case(1):
81 m.d.comb += self.o.eq(sub.o)
82 with m.Case(2):
83 m.d.comb += self.o.eq(mul.o)
84 with m.Case(3):
85 m.d.comb += self.o.eq(shf.o)
86 return m
87
88
89 if __name__ == "__main__":
90 alu = ALU(width=16)
91 main(alu, ports=[alu.op, alu.a, alu.b, alu.o])