1 from nmigen
import Module
, Signal
2 from nmigen
.back
.pysim
import Simulator
, Delay
, Settle
3 from nmutil
.formaltest
import FHDLTestCase
5 from openpower
.decoder
.isa
.caller
import ISACaller
6 from openpower
.decoder
.power_decoder
import (create_pdecode
)
7 from openpower
.decoder
.power_decoder2
import (PowerDecode2
)
8 from openpower
.simulator
.program
import Program
9 from openpower
.decoder
.isa
.caller
import ISACaller
, SVP64State
10 from openpower
.decoder
.selectable_int
import SelectableInt
11 from openpower
.decoder
.orderedset
import OrderedSet
12 from openpower
.decoder
.isa
.all
import ISA
13 from openpower
.decoder
.isa
.test_caller
import Register
, run_tst
14 from openpower
.sv
.trans
.svp64
import SVP64Asm
15 from openpower
.consts
import SVP64CROffs
16 from copy
import deepcopy
17 from openpower
.decoder
.helpers
import fp64toselectable
18 from openpower
.decoder
.isafunctions
.double2single
import DOUBLE2SINGLE
20 class DecoderTestCase(FHDLTestCase
):
22 def _check_regs(self
, sim
, expected
):
24 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64))
26 def test_sv_fpmadds_fft(self
):
27 """>>> lst = ["sv.ffmadds 2.v, 2.v, 2.v, 10.v"
29 four in-place vector mul-adds, four in-place vector mul-subs
31 this is the twin "butterfly" mul-add-sub from Cooley-Tukey
32 https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm#Data_reordering,_bit_reversal,_and_in-place_algorithms
34 there is the *option* to target a different location (non-in-place)
37 SVP64 "FFT" mode will *automatically* offset FRB and an implicit
38 FRS to perform the two multiplies. one add, one subtract.
40 sv.ffmadds FRT, FRA, FRC, FRB actually does:
41 fmadds FRT , FRA, FRC, FRA
42 fnmsubs FRT+vl, FRA, FRC, FRB+vl
44 lst
= SVP64Asm(["sv.ffmadds 2.v, 2.v, 2.v, 10.v"
49 av
= [7.0, -9.8, 2.0, -32.3] # first half of array 0..3
50 bv
= [-2.0, 2.0, -9.8, 32.3] # second half of array 4..7
51 coe
= [-1.0, 4.0, 3.1, 6.2] # coefficients
53 # work out the results with the twin mul/add-sub
54 for i
, (a
, b
, c
) in enumerate(zip(av
, bv
, coe
)):
55 fprs
[i
+2] = fp64toselectable(a
)
56 fprs
[i
+6] = fp64toselectable(b
)
57 fprs
[i
+10] = fp64toselectable(c
)
61 t
= DOUBLE2SINGLE(fp64toselectable(t
)) # convert to Power single
62 u
= DOUBLE2SINGLE(fp64toselectable(u
)) # from double
64 print ("FFT", i
, "in", a
, b
, "coeff", c
, "mul", mul
, "res", t
, u
)
66 # SVSTATE (in this case, VL=2)
67 svstate
= SVP64State()
68 svstate
.vl
[0:7] = 4 # VL
69 svstate
.maxvl
[0:7] = 4 # MAXVL
70 print ("SVSTATE", bin(svstate
.spr
.asint()))
72 with
Program(lst
, bigendian
=False) as program
:
73 sim
= self
.run_tst_program(program
, svstate
=svstate
,
75 # confirm that the results are as expected
76 for i
, (t
, u
) in enumerate(res
):
77 self
.assertEqual(sim
.fpr(i
+2), t
)
78 self
.assertEqual(sim
.fpr(i
+6), u
)
80 def run_tst_program(self
, prog
, initial_regs
=None,
84 if initial_regs
is None:
85 initial_regs
= [0] * 32
86 simulator
= run_tst(prog
, initial_regs
, mem
=initial_mem
,
87 initial_fprs
=initial_fprs
,
98 if __name__
== "__main__":