Keep the sequencer in the "done" state until ready_i is asserted
[soc.git] / src / soc / fu / div / main_stage.py
1 # This stage is intended to do most of the work of executing DIV
2 # This module however should not gate the carry or overflow, that's up
3 # to the output stage
4
5 from nmigen import (Module, Signal, Cat, Repl, Mux, Const, Array)
6 from nmutil.pipemodbase import PipeModBase
7 from soc.fu.logical.pipe_data import LogicalInputData
8 from soc.fu.alu.pipe_data import ALUOutputData
9 from ieee754.part.partsig import PartitionedSignal
10 from soc.decoder.power_enums import InternalOp
11
12 from soc.decoder.power_fields import DecodeFields
13 from soc.decoder.power_fieldsn import SignalBitRange
14
15
16 class DivMainStage(PipeModBase):
17 def __init__(self, pspec):
18 super().__init__(pspec, "main")
19 self.fields = DecodeFields(SignalBitRange, [self.i.ctx.op.insn])
20 self.fields.create_specs()
21
22 def ispec(self):
23 return LogicalInputData(self.pspec)
24
25 def ospec(self):
26 return ALUOutputData(self.pspec)
27
28 def elaborate(self, platform):
29 m = Module()
30 comb = m.d.comb
31 op, a, b, o = self.i.ctx.op, self.i.a, self.i.b, self.o.o
32
33 ##########################
34 # main switch for DIV
35
36 with m.Switch(op.insn_type):
37
38 ###### AND, OR, XOR #######
39 with m.Case(InternalOp.OP_AND):
40 comb += o.eq(a & b)
41 with m.Case(InternalOp.OP_OR):
42 comb += o.eq(a | b)
43 with m.Case(InternalOp.OP_XOR):
44 comb += o.eq(a ^ b)
45
46 ###### bpermd #######
47 with m.Case(InternalOp.OP_BPERM):
48 m.submodules.bpermd = bpermd = Bpermd(64)
49 comb += bpermd.rs.eq(a)
50 comb += bpermd.rb.eq(b)
51 comb += o.eq(bpermd.ra)
52
53 ###### sticky overflow and context, both pass-through #####
54
55 comb += self.o.xer_so.data.eq(self.i.xer_so)
56 comb += self.o.ctx.eq(self.i.ctx)
57
58 return m