Add should_trap signal to trap output data
[soc.git] / src / soc / fu / trap / main_stage.py
1
2 from nmigen import (Module, Signal, Cat, Repl, Mux, Const, signed)
3 from nmutil.pipemodbase import PipeModBase
4 from nmutil.clz import CLZ
5 from soc.fu.trap.pipe_data import TrapInputData, TrapOutputData
6 from soc.decoder.power_enums import InternalOp
7
8 from soc.decoder.power_fields import DecodeFields
9 from soc.decoder.power_fieldsn import SignalBitRange
10
11
12 def array_of(count, bitwidth):
13 res = []
14 for i in range(count):
15 res.append(Signal(bitwidth, reset_less=True))
16 return res
17
18
19 class LogicalMainStage(PipeModBase):
20 def __init__(self, pspec):
21 super().__init__(pspec, "main")
22 self.fields = DecodeFields(SignalBitRange, [self.i.ctx.op.insn])
23 self.fields.create_specs()
24
25 def ispec(self):
26 return TrapInputData(self.pspec)
27
28 def ospec(self):
29 return TrapOutputData(self.pspec)
30
31 def elaborate(self, platform):
32 m = Module()
33 comb = m.d.comb
34 op = self.i.ctx.op
35
36 i_fields = self.fields.FormD
37 to = Signal(i_fields.TO[0:-1].shape())
38 comb += to.eq(i_fields.TO[0:-1])
39
40 a_signed = Signal(signed(64), reset_less=True)
41 b_signed = Signal(signed(64), reset_less=True)
42
43 a = Signal(64, reset_less=True)
44 b = Signal(64, reset_less=True)
45
46 with m.If(self.i.ctx.op.is_32bit):
47 comb += a_signed.eq(self.i.a[0:32],
48 Repl(self.i.a[32], 32))
49 comb += b_signed.eq(self.i.b[0:32],
50 Repl(self.i.b[32], 32))
51 comb += a.eq(self.i.a[0:32])
52 comb += b.eq(self.i.b[0:32])
53 with m.Else():
54 comb += a_signed.eq(self.i.a)
55 comb += b_signed.eq(self.i.b)
56 comb += a.eq(self.i.a)
57 comb += b.eq(self.i.b)
58
59 lt_signed = Signal()
60 gt_signed = Signal()
61 lt_unsigned = Signal()
62 gt_unsigned = Signal()
63 equal = Signal()
64
65 comb += lt_signed.eq(a_signed < b_signed)
66 comb += gt_signed.eq(a_signed > b_signed)
67 comb += lt_unsigned.eq(a < b)
68 comb += gt_unsigned.eq(a > b)
69 comb += equal.eq(a == b)
70
71 trap_bits = Signal(5)
72 # They're in reverse bit order because POWER. Check Book 1,
73 # Appendix C.6 for chart
74 comb += trap_bits.eq(Cat(gt_unsigned, lt_unsigned, equal,
75 gt_signed, lt_signed))
76 should_trap = Signal()
77 comb += should_trap.eq((trap_bits & to).any())
78
79 with m.Switch(op):
80 with m.Case(InternalOp.OP_TRAP):
81 with m.If(should_trap):
82 comb += self.o.nia.eq(0x700)
83 comb += self.o.srr1.eq(self.i.msr)
84 comb += self.o.srr1[63-46].eq(1)
85 comb += self.o.srr0.eq(self.i.cia)
86
87
88 comb += self.o.ctx.eq(self.i.ctx)
89 comb += self.o.should_trap.eq(should_trap)
90
91 return m