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