1 from nmigen
import Elaboratable
, Signal
, Module
, Repl
, Cat
, Const
, Array
2 from nmigen
.cli
import main
5 class Bpermd(Elaboratable
):
7 from POWERISA v3.1 p105, chaper 3
9 This class does a Bit Permute on a Doubleword
14 index ← (RS)[8*i:8*i+7]
16 then perm[i] ← (RB)[index]
18 RA ←56[0] || perm[0:7]
20 Eight permuted bits are produced. For each permutedbit i where i
21 ranges from 0 to 7 and for each byte i of RS, do the following.
23 If byte i of RS is less than 64, permuted bit i is set to
24 the bit of RB specified by byte i of RS; otherwise
25 permuted bit i is set to 0.
27 The permuted bits are placed in the least-significant byte of RA,
28 and the remaining bits are filled with 0s.
30 Special Registers Altered:
35 The fact that the permuted bit is 0 if the corresponding index value
36 exceeds 63 permits the permuted bits to be selected from a 128-bit
37 quantity, using a single index register. For example, assume that
38 the 128-bit quantity Q, from which the permuted bits are to be
39 selected, is in registers r2 (high-order 64 bits of Q) and r3
40 (low-order 64 bits of Q), that the index values are in register r1,
41 with each byte of r1 containing a value in the range 0:127, and that
42 each byte of register r4 contains the value 64. The following code
43 sequence selects eight permuted bits from Q and places them into
44 the low-order byteof r6.
46 bpermd r6,r1,r2 # select from high-order half of Q
47 xor r0,r1,r4 # adjust index values
48 bpermd r5,r0,r3 # select from low-order half of Q
49 or r6,r6,r5 # merge the two selections
52 def __init__(self
, width
):
54 self
.rs
= Signal(width
, reset_less
=True)
55 self
.ra
= Signal(width
, reset_less
=True)
56 self
.rb
= Signal(width
, reset_less
=True)
58 def elaborate(self
, platform
):
60 perm
= Signal(self
.width
, reset_less
=True)
61 rb64
= [Signal(1, reset_less
=True, name
=f
"rb64_{i}") for i
in range(64)]
63 m
.d
.comb
+= rb64
[i
].eq(self
.rb
[63-i
])
66 index
= self
.rs
[8*i
:8*i
+8]
67 idx
= Signal(8, name
=f
"idx_{i}", reset_less
=True)
68 m
.d
.comb
+= idx
.eq(index
)
70 m
.d
.comb
+= perm
[i
].eq(rb64
[idx
])
71 m
.d
.comb
+= self
.ra
[0:8].eq(perm
)
75 if __name__
== "__main__":
76 bperm
= Bpermd(width
=64)
77 main(bperm
, ports
=[bperm
.rs
, bperm
.ra
, bperm
.rb
])