From c49d316610ff0b35241203013fb551a87e62d0c8 Mon Sep 17 00:00:00 2001 From: colepoirier Date: Tue, 19 May 2020 13:43:13 -0700 Subject: [PATCH] Renamed bperm files in fu/logical and fu/logical formal to correct name of operation 'bpermd', added up-to-date docstring from spec v3.1 --- src/soc/fu/logical/bperm.py | 55 ----------- src/soc/fu/logical/bpermd.py | 92 +++++++++++++++++++ .../{proof_bperm.py => proof_bpermd.py} | 4 +- 3 files changed, 94 insertions(+), 57 deletions(-) delete mode 100644 src/soc/fu/logical/bperm.py create mode 100644 src/soc/fu/logical/bpermd.py rename src/soc/fu/logical/formal/{proof_bperm.py => proof_bpermd.py} (98%) diff --git a/src/soc/fu/logical/bperm.py b/src/soc/fu/logical/bperm.py deleted file mode 100644 index 674555b8..00000000 --- a/src/soc/fu/logical/bperm.py +++ /dev/null @@ -1,55 +0,0 @@ -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.width = width - self.rs = Signal(width, reset_less=True) - self.ra = Signal(width, reset_less=True) - self.rb = Signal(width, reset_less=True) - - def elaborate(self, platform): - m = Module() - perm = Signal(self.width, reset_less=True) - rb64 = [Signal(1, reset_less=True, name=f"rb64_{i}") for i in range(64)] - for i in range(64): - m.d.comb += rb64[i].eq(self.rb[i]) - rb64 = Array(rb64) - for i in range(8): - index = self.rs[8*i:8*i+8] - idx = Signal(8, name=f"idx_{i}", reset_less=True) - m.d.comb += idx.eq(index) - with m.If(idx < 64): - m.d.comb += perm[i].eq(rb64[idx]) - m.d.comb += self.ra[0:8].eq(perm) - return m - - -if __name__ == "__main__": - bperm = Bpermd(width=64) - main(bperm, ports=[bperm.rs, bperm.ra, bperm.rb]) diff --git a/src/soc/fu/logical/bpermd.py b/src/soc/fu/logical/bpermd.py new file mode 100644 index 00000000..1fc50e97 --- /dev/null +++ b/src/soc/fu/logical/bpermd.py @@ -0,0 +1,92 @@ +from nmigen import Elaboratable, Signal, Module, Repl, Cat, Const, Array +from nmigen.cli import main + + +class Bpermd(Elaboratable): + """ + from POWERISA v3.1 p105, chaper 3 + + This class does a Bit Permute on a Doubleword + + permd RA,RS,RB + + do i = 0 to 7 + index ← (RS)[8*i:8*i+7] + If index < 64 + then perm[i] ← (RB)[index] + else permi[i] ← 0 + RA ←56[0] || perm[0:7] + + Eight permuted bits are produced. + For each permutedbit 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 set to + 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-significant byte 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 byteof r6. + + bpermd r6,r1,r2 # select from high-order half of Q + xor r0,r1,r4 # adjust index values + bpermd r5,r0,r3 # select from low-order half of Q + or r6,r6,r5 # merge the two selections + """ + + def __init__(self, width): + self.width = width + self.rs = Signal(width, reset_less=True) + self.ra = Signal(width, reset_less=True) + self.rb = Signal(width, reset_less=True) + + def elaborate(self, platform): + m = Module() + perm = Signal(self.width, reset_less=True) + rb64 = [Signal(1, reset_less=True, name=f"rb64_{i}") for i in range(64)] + for i in range(64): + m.d.comb += rb64[i].eq(self.rb[i]) + rb64 = Array(rb64) + for i in range(8): + index = self.rs[8*i:8*i+8] + idx = Signal(8, name=f"idx_{i}", reset_less=True) + m.d.comb += idx.eq(index) + with m.If(idx < 64): + m.d.comb += perm[i].eq(rb64[idx]) + m.d.comb += self.ra[0:8].eq(perm) + return m + + +if __name__ == "__main__": + bperm = Bpermd(width=64) + main(bperm, ports=[bperm.rs, bperm.ra, bperm.rb]) diff --git a/src/soc/fu/logical/formal/proof_bperm.py b/src/soc/fu/logical/formal/proof_bpermd.py similarity index 98% rename from src/soc/fu/logical/formal/proof_bperm.py rename to src/soc/fu/logical/formal/proof_bpermd.py index 11b8e487..ba93a0ef 100644 --- a/src/soc/fu/logical/formal/proof_bperm.py +++ b/src/soc/fu/logical/formal/proof_bpermd.py @@ -7,7 +7,7 @@ from nmigen.asserts import Assert, AnyConst, Assume, Cover from nmigen.test.utils import FHDLTestCase from nmigen.cli import rtlil -from soc.fu.logical.bperm import Bpermd +from soc.fu.logical.bpermd import Bpermd import unittest @@ -124,7 +124,7 @@ class TestCase(FHDLTestCase): def test_ilang(self): dut = Driver() vl = rtlil.convert(dut, ports=[]) - with open("bperm.il", "w") as f: + with open("bpermd.il", "w") as f: f.write(vl) -- 2.30.2