From 01a3101ac46a4b35a5e6d693483c6f108d4965df Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 9 Jun 2021 18:19:40 +0100 Subject: [PATCH] add first scalar mapreduce SVP64 example --- src/openpower/decoder/isa/caller.py | 14 ++-- .../isa/test_caller_svp64_mapreduce.py | 67 +++++++++++++++++++ src/openpower/decoder/power_decoder2.py | 2 +- 3 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 src/openpower/decoder/isa/test_caller_svp64_mapreduce.py diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 55e07ddd..495bd173 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -1339,24 +1339,26 @@ class ISACaller: mvl = self.svstate.maxvl.asint(msb0=True) srcstep = self.svstate.srcstep.asint(msb0=True) dststep = self.svstate.dststep.asint(msb0=True) + rm_mode = yield self.dec2.rm_dec.mode sv_ptype = yield self.dec2.dec.op.SV_Ptype - no_out_vec = not (yield self.dec2.no_out_vec) - no_in_vec = not (yield self.dec2.no_in_vec) + out_vec = not (yield self.dec2.no_out_vec) + in_vec = not (yield self.dec2.no_in_vec) log (" svstate.vl", vl) log (" svstate.mvl", mvl) log (" svstate.srcstep", srcstep) log (" svstate.dststep", dststep) - log (" no_out_vec", no_out_vec) - log (" no_in_vec", no_in_vec) + log (" mode", rm_mode) + log (" out_vec", out_vec) + log (" in_vec", in_vec) log (" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value) # check if srcstep needs incrementing by one, stop PC advancing # svp64 loop can end early if the dest is scalar for single-pred # but for 2-pred both src/dest have to be checked. # XXX this might not be true! it may just be LD/ST if sv_ptype == SVPtype.P2.value: - svp64_is_vector = (no_out_vec or no_in_vec) + svp64_is_vector = (out_vec or in_vec) else: - svp64_is_vector = no_out_vec + svp64_is_vector = out_vec if svp64_is_vector and srcstep != vl-1 and dststep != vl-1: self.svstate.srcstep += SelectableInt(1, 7) self.svstate.dststep += SelectableInt(1, 7) diff --git a/src/openpower/decoder/isa/test_caller_svp64_mapreduce.py b/src/openpower/decoder/isa/test_caller_svp64_mapreduce.py new file mode 100644 index 00000000..1c969c7b --- /dev/null +++ b/src/openpower/decoder/isa/test_caller_svp64_mapreduce.py @@ -0,0 +1,67 @@ +from nmigen import Module, Signal +from nmigen.back.pysim import Simulator, Delay, Settle +from nmutil.formaltest import FHDLTestCase +import unittest +from openpower.decoder.isa.caller import ISACaller +from openpower.decoder.power_decoder import (create_pdecode) +from openpower.decoder.power_decoder2 import (PowerDecode2) +from openpower.simulator.program import Program +from openpower.decoder.isa.caller import ISACaller, SVP64State +from openpower.decoder.selectable_int import SelectableInt +from openpower.decoder.orderedset import OrderedSet +from openpower.decoder.isa.all import ISA +from openpower.decoder.isa.test_caller import Register, run_tst +from openpower.sv.trans.svp64 import SVP64Asm +from openpower.consts import SVP64CROffs +from copy import deepcopy + + +class DecoderTestCase(FHDLTestCase): + + def _check_regs(self, sim, expected): + for i in range(32): + self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64)) + + def test_sv_add_scalar_reduce(self): + """>>> lst = ['sv.add/mr 1, 5.v, 1' + ] + adds: + * 1 starts at 0x0101 + * 1 = 5 + 1 => 0x101 + 0x202 => 0x303 + * 1 = 6 + 1 => 0x303 + 0x404 => 0x707 + """ + isa = SVP64Asm(['sv.add/mr 1, 5.v, 1' + ]) + lst = list(isa) + print ("listing", lst) + + # initial values in GPR regfile + initial_regs = [0] * 32 + initial_regs[1] = 0x0101 + initial_regs[5] = 0x0202 + initial_regs[6] = 0x0404 + # SVSTATE (in this case, VL=2) + svstate = SVP64State() + svstate.vl[0:7] = 2 # VL + svstate.maxvl[0:7] = 2 # MAXVL + print ("SVSTATE", bin(svstate.spr.asint())) + # copy before running, then compute answers + expected_regs = deepcopy(initial_regs) + expected_regs[1] = (initial_regs[1] + initial_regs[5] + + initial_regs[6]) # 0x0707 + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, initial_regs, svstate) + self._check_regs(sim, expected_regs) + + def run_tst_program(self, prog, initial_regs=None, + svstate=None): + if initial_regs is None: + initial_regs = [0] * 32 + simulator = run_tst(prog, initial_regs, svstate=svstate) + simulator.gpr.dump() + return simulator + + +if __name__ == "__main__": + unittest.main() diff --git a/src/openpower/decoder/power_decoder2.py b/src/openpower/decoder/power_decoder2.py index d0770862..3b854bdd 100644 --- a/src/openpower/decoder/power_decoder2.py +++ b/src/openpower/decoder/power_decoder2.py @@ -1198,7 +1198,7 @@ class PowerDecode2(PowerDecodeSubset): comb += self.no_in_vec.eq(~Cat(*l).bool()) # all input scalar l = map(lambda svdec: svdec.isvec, [o2_svdec, o_svdec, crout_svdec]) # in mapreduce mode, scalar out is *allowed* - with m.If(self.rm_dec.mode == SVP64RMMode.MAPREDUCE): + with m.If(self.rm_dec.mode == SVP64RMMode.MAPREDUCE.value): comb += self.no_out_vec.eq(0) with m.Else(): comb += self.no_out_vec.eq(~Cat(*l).bool()) # all output scalar -- 2.30.2