rename pipe to fu
[soc.git] / src / soc / fu / shift_rot / maskgen.py
1 from nmigen import (Elaboratable, Signal, Module)
2 import math
3
4 class MaskGen(Elaboratable):
5 """MaskGen - create a diff mask
6
7 example: x=5 --> a=0b11111
8 y=3 --> b=0b00111
9 o: 0b11000
10 x=2 --> a=0b00011
11 y=4 --> b=0b01111
12 o: 0b10011
13 """
14 def __init__(self, width):
15 self.width = width
16 self.shiftwidth = math.ceil(math.log2(width))
17 self.mb = Signal(self.shiftwidth, reset_less=True)
18 self.me = Signal(self.shiftwidth, reset_less=True)
19
20 self.o = Signal(width, reset_less=True)
21
22 def elaborate(self, platform):
23 m = Module()
24 comb = m.d.comb
25
26 x = Signal.like(self.mb)
27 y = Signal.like(self.mb)
28
29 comb += x.eq(64 - self.mb)
30 comb += y.eq(63 - self.me)
31
32 mask_a = Signal.like(self.o)
33 mask_b = Signal.like(self.o)
34
35 comb += mask_a.eq((1<<x) - 1)
36 comb += mask_b.eq((1<<y) - 1)
37
38 with m.If(x > y):
39 comb += self.o.eq(mask_a ^ mask_b)
40 with m.Else():
41 comb += self.o.eq(mask_a ^ ~mask_b)
42
43
44 return m
45
46 def ports(self):
47 return [self.mb, self.me, self.o]