Added working bperm.py, but is too gate heavy, as well as dummy unit
authorcolepoirier <colepoirier@gmail.com>
Sat, 16 May 2020 01:12:53 +0000 (18:12 -0700)
committercolepoirier <colepoirier@gmail.com>
Sat, 16 May 2020 01:55:32 +0000 (18:55 -0700)
test file to be implemented tomorrow

src/soc/logical/bperm.py [new file with mode: 0644]
src/soc/logical/test/test_bperm.py [new file with mode: 0644]

diff --git a/src/soc/logical/bperm.py b/src/soc/logical/bperm.py
new file mode 100644 (file)
index 0000000..1dcb36d
--- /dev/null
@@ -0,0 +1,53 @@
+from nmigen import Elaboratable, Signal, Module, Repl, Cat, Const, Array
+from nmigen.cli import main
+
+class Bpermd(Elaboratable):
+    """This class does a Bit Permute on a Doubleword
+
+       X-form bpermd RA,RS,RB]
+
+       Eight permuted bits are produced. For each permuted bit i where i ranges
+       from 0 to 7 and for each byte i of RS, do the following. If byte i of RS
+       is less than 64, permuted bit i is setto the bit of RB specified by byte
+       i of RS; otherwise permuted bit i is set to 0. The  permuted  bits are
+       placed in the least-significantbyte of RA, and the remaining bits are
+       filled with 0s.
+       Special Registers Altered: None
+
+       Programming note:
+       The fact that the permuted bit is 0 if the corresponding index value
+       exceeds 63 permits the permuted bits to be selected from a 128-bit
+       quantity, using a single index register. For example, assume that the
+       128-bit quantity Q, from which the permuted bits are to be selected, is
+       in registers r2(high-order 64 bits of Q) and r3 (low-order 64 bits of Q),
+       that the index values are in register r1, with each byte of r1 containing
+       a value in the range 0:127, and that each byte of register r4 contains
+       the value 64. The following code sequence selects eight permuted bits
+       from Q and places them into the low-order byte of r6.
+    """
+
+    def __init__(self, width):
+        self.perm = Signal(width)
+        self.rs   = Signal(width)
+        self.ra   = Signal(width)
+        self.rb   = Signal(width)
+
+    def elaborate(self, platform):
+        m = Module()
+        index = Signal(8)
+        signals = [ Signal(1) for i in range(64) ]
+        for i,n in enumerate(signals):
+            n.eq(self.rb[i])
+        rb64 = Array(signals)
+        for i in range(0, 8):
+            index = self.rs[8 * i:8 * i + 8]
+            with m.If(index < 64):
+                m.d.comb += self.perm[i].eq(rb64[index])
+            with m.Else():
+                continue
+        m.d.comb += self.ra[0:8].eq(self.perm)
+        return m
+
+if __name__ == "__main__":
+    bperm = Bpermd(width=64)
+    main(bperm,ports=[bperm.perm, bperm.rs, bperm.ra, bperm.rb])
diff --git a/src/soc/logical/test/test_bperm.py b/src/soc/logical/test/test_bperm.py
new file mode 100644 (file)
index 0000000..7a742b0
--- /dev/null
@@ -0,0 +1 @@
+'''Empty until I write the unit test'''