From d1d4b0051b676b69905593e0556f7def41515fca Mon Sep 17 00:00:00 2001 From: colepoirier Date: Fri, 15 May 2020 18:12:53 -0700 Subject: [PATCH] Added working bperm.py, but is too gate heavy, as well as dummy unit test file to be implemented tomorrow --- src/soc/logical/bperm.py | 53 ++++++++++++++++++++++++++++++ src/soc/logical/test/test_bperm.py | 1 + 2 files changed, 54 insertions(+) create mode 100644 src/soc/logical/bperm.py create mode 100644 src/soc/logical/test/test_bperm.py diff --git a/src/soc/logical/bperm.py b/src/soc/logical/bperm.py new file mode 100644 index 00000000..1dcb36d1 --- /dev/null +++ b/src/soc/logical/bperm.py @@ -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 index 00000000..7a742b0b --- /dev/null +++ b/src/soc/logical/test/test_bperm.py @@ -0,0 +1 @@ +'''Empty until I write the unit test''' -- 2.30.2