c386397aa2f26b0b62550c260ef56aff529c24de
[soc.git] / src / soc / pipe / alu / pipe_data.py
1 from nmigen import Signal, Const
2 from nmutil.dynamicpipe import SimpleHandshakeRedir
3 from soc.alu.alu_input_record import CompALUOpSubset
4 from ieee754.fpcommon.getop import FPPipeContext
5
6
7 class IntegerData:
8
9 def __init__(self, pspec):
10 self.ctx = FPPipeContext(pspec)
11 self.muxid = self.ctx.muxid
12
13 def __iter__(self):
14 yield from self.ctx
15
16 def eq(self, i):
17 return [self.ctx.eq(i.ctx)]
18
19 def ports(self):
20 return self.ctx.ports()
21
22
23 class ALUInputData(IntegerData):
24 def __init__(self, pspec):
25 super().__init__(pspec)
26 self.a = Signal(64, reset_less=True) # RA
27 self.b = Signal(64, reset_less=True) # RB/immediate
28 self.so = Signal(reset_less=True)
29 self.carry_in = Signal(reset_less=True)
30
31 def __iter__(self):
32 yield from super().__iter__()
33 yield self.a
34 yield self.b
35 yield self.carry_in
36 yield self.so
37
38 def eq(self, i):
39 lst = super().eq(i)
40 return lst + [self.a.eq(i.a), self.b.eq(i.b),
41 self.carry_in.eq(i.carry_in),
42 self.so.eq(i.so)]
43
44 # TODO: ALUIntermediateData which does not have
45 # cr0, ov, ov32 in it (because they are generated as outputs by
46 # the final output stage, not by the intermediate stage)
47 # https://bugs.libre-soc.org/show_bug.cgi?id=305#c19
48
49 class ALUOutputData(IntegerData):
50 def __init__(self, pspec):
51 super().__init__(pspec)
52 self.o = Signal(64, reset_less=True, name="stage_o")
53 self.carry_out = Signal(reset_less=True)
54 self.carry_out32 = Signal(reset_less=True)
55 self.cr0 = Signal(4, reset_less=True)
56 self.ov = Signal(reset_less=True)
57 self.ov32 = Signal(reset_less=True)
58 self.so = Signal(reset_less=True)
59
60 def __iter__(self):
61 yield from super().__iter__()
62 yield self.o
63 yield self.carry_out
64 yield self.carry_out32
65 yield self.cr0
66 yield self.ov
67 yield self.ov32
68 yield self.so
69
70 def eq(self, i):
71 lst = super().eq(i)
72 return lst + [self.o.eq(i.o),
73 self.carry_out.eq(i.carry_out),
74 self.carry_out32.eq(i.carry_out32),
75 self.cr0.eq(i.cr0), self.ov.eq(i.ov),
76 self.ov32.eq(i.ov32), self.so.eq(i.so)]
77
78
79 class IntPipeSpec:
80 def __init__(self, id_wid=2, op_wid=1):
81 self.id_wid = id_wid
82 self.op_wid = op_wid
83 self.opkls = lambda _: CompALUOpSubset(name="op")
84 self.stage = None
85
86
87 class ALUPipeSpec(IntPipeSpec):
88 def __init__(self, id_wid, op_wid):
89 super().__init__(id_wid, op_wid)
90 self.pipekls = SimpleHandshakeRedir