From: Luke Kenneth Casson Leighton Date: Fri, 2 Sep 2022 20:46:53 +0000 (+0100) Subject: add test_caller_svshape2.py and make corrections to csv and fields.txt X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ddbc38bd588bec5b01c551269a738f010a0a275d;p=openpower-isa.git add test_caller_svshape2.py and make corrections to csv and fields.txt yx needed to be SVM2-form and was in a different bitposition offs needed to be 6:9 not 6:10 XO was off-by-one in minor_22.csv --- diff --git a/openpower/isatables/fields.text b/openpower/isatables/fields.text index a8fb5bf4..5a08d23e 100644 --- a/openpower/isatables/fields.text +++ b/openpower/isatables/fields.text @@ -674,7 +674,7 @@ Field used to specify the number of bytes to move in an immediate Move Assist instruction. Formats: X - offs (6:10) + offs (6:9) Field used by the svshape2 instruction as an offset Formats: SVM2 OC (6:20) @@ -1051,3 +1051,6 @@ yx (23) Field used to specify loop dimension order in svindex Formats: SVI + yx (10) + Field used to specify loop dimension order in svshape2 + Formats: SVM2 diff --git a/openpower/isatables/minor_22.csv b/openpower/isatables/minor_22.csv index 8f29693b..30a636da 100644 --- a/openpower/isatables/minor_22.csv +++ b/openpower/isatables/minor_22.csv @@ -22,7 +22,7 @@ opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry ou 1110-011001,VL,OP_SVSHAPE,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svshape,SVM,,1,unofficial until submitted and approved/renumbered by the opf isa wg 1111-011001,VL,OP_SVSHAPE,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svshape,SVM,,1,unofficial until submitted and approved/renumbered by the opf isa wg # svshape2: {-100,mm,011001} --100-011001,VL,OP_SVSHAPE,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svshape2,SVM,,1,unofficial until submitted and approved/renumbered by the opf isa wg +100--011001,VL,OP_SVSHAPE,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svshape2,SVM,,1,unofficial until submitted and approved/renumbered by the opf isa wg # A/V bitmanip 0111001110-,ALU,OP_MINMAX,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC_ONLY,0,0,maxs,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg 0011001110-,ALU,OP_MINMAX,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC_ONLY,0,0,maxu,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg diff --git a/src/openpower/decoder/isa/test_caller_svshape2.py b/src/openpower/decoder/isa/test_caller_svshape2.py new file mode 100644 index 00000000..fdef4ede --- /dev/null +++ b/src/openpower/decoder/isa/test_caller_svshape2.py @@ -0,0 +1,385 @@ +"""SVP64 unit test for svshape2 +svshape2 offs,yx,rmm,SVd,sk,mm +""" +from nmigen import Module, Signal +from nmigen.sim 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, CRFields +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 SVSTATETestCase(FHDLTestCase): + + def _check_regs(self, sim, expected): + print ("GPR") + sim.gpr.dump() + for i in range(32): + self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64), + "GPR %d %x expected %x" % (i, sim.gpr(i).value, expected[i])) + + def test_0_sv_shape2(self): + """sets VL=10 (via SVSTATE) then does svshape mm=0, checks SPRs after + """ + isa = SVP64Asm(['svshape2 12, 1, 15, 5, 0, 0' + ]) + lst = list(isa) + print ("listing", lst) + + # initial values in GPR regfile + initial_regs = [0] * 32 + initial_regs[9] = 0x1234 + initial_regs[10] = 0x1111 + initial_regs[5] = 0x4321 + initial_regs[6] = 0x2223 + + # SVSTATE vl=10 + svstate = SVP64State() + svstate.vl = 10 # VL + svstate.maxvl = 10 # MAXVL + print ("SVSTATE", bin(svstate.asint())) + + # copy before running + expected_regs = deepcopy(initial_regs) + #expected_regs[1] = 0x3334 + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, initial_regs, svstate=svstate) + self._check_regs(sim, expected_regs) + + print (sim.spr) + SVSHAPE0 = sim.spr['SVSHAPE0'] + print ("SVSTATE after", bin(sim.svstate.asint())) + print (" vl", bin(sim.svstate.vl)) + print (" mvl", bin(sim.svstate.maxvl)) + print (" srcstep", bin(sim.svstate.srcstep)) + print (" dststep", bin(sim.svstate.dststep)) + print (" RMpst", bin(sim.svstate.RMpst)) + print (" SVme", bin(sim.svstate.SVme)) + print (" mo0", bin(sim.svstate.mo0)) + print (" mo1", bin(sim.svstate.mo1)) + print (" mi0", bin(sim.svstate.mi0)) + print (" mi1", bin(sim.svstate.mi1)) + print (" mi2", bin(sim.svstate.mi2)) + print ("STATE0 ", SVSHAPE0) + print ("STATE0 offs", SVSHAPE0.offset) + print ("STATE0 xdim", SVSHAPE0.xdimsz) + print ("STATE0 ydim", SVSHAPE0.ydimsz) + print ("STATE0 skip", bin(SVSHAPE0.skip)) + print ("STATE0 inv", SVSHAPE0.invxyz) + print ("STATE0order", SVSHAPE0.order) + self.assertEqual(SVSHAPE0.xdimsz, 5) # set + self.assertEqual(SVSHAPE0.ydimsz, 2) # calculated from MVL/xdimsz + self.assertEqual(SVSHAPE0.skip, 0) # no skip + self.assertEqual(SVSHAPE0.invxyz, 0) # (no inversion possible) + self.assertEqual(SVSHAPE0.offset, 12) + self.assertEqual(SVSHAPE0.order, (1, 0, 2)) # y,x(,z) + self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0 + self.assertEqual(sim.svstate.SVme, 0b01111) # same as rmm + # rmm is 0b01111 which means mi0=0 mi1=1 mi2=2 mo0=3 mo1=0 + self.assertEqual(sim.svstate.mi0, 0) + self.assertEqual(sim.svstate.mi1, 1) + self.assertEqual(sim.svstate.mi2, 2) + self.assertEqual(sim.svstate.mo0, 3) + self.assertEqual(sim.svstate.mo1, 0) + + def tst_1_sv_index(self): + """sets VL=10 (via SVSTATE) then does svindex mm=1, checks SPRs after + """ + # rmm: bits 0-2 (MSB0) are 0b011 and bits 3-4 are 0b10. + # therefore rmm is 0b011 || 0b10 --> 0b01110 -> 14 + isa = SVP64Asm(['svindex 1, 14, 5, 0, 0, 1, 0' + ]) + lst = list(isa) + print ("listing", lst) + + # initial values in GPR regfile + initial_regs = [0] * 32 + initial_regs[9] = 0x1234 + initial_regs[10] = 0x1111 + initial_regs[5] = 0x4321 + initial_regs[6] = 0x2223 + + # SVSTATE vl=10 + svstate = SVP64State() + svstate.vl = 10 # VL + svstate.maxvl = 10 # MAXVL + print ("SVSTATE", bin(svstate.asint())) + + # copy before running + expected_regs = deepcopy(initial_regs) + #expected_regs[1] = 0x3334 + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, initial_regs, svstate=svstate) + self._check_regs(sim, expected_regs) + + print (sim.spr) + SVSHAPE2 = sim.spr['SVSHAPE2'] + print ("SVSTATE after", bin(sim.svstate.asint())) + print (" vl", bin(sim.svstate.vl)) + print (" mvl", bin(sim.svstate.maxvl)) + print (" srcstep", bin(sim.svstate.srcstep)) + print (" dststep", bin(sim.svstate.dststep)) + print (" RMpst", bin(sim.svstate.RMpst)) + print (" SVme", bin(sim.svstate.SVme)) + print (" mo0", bin(sim.svstate.mo0)) + print (" mo1", bin(sim.svstate.mo1)) + print (" mi0", bin(sim.svstate.mi0)) + print (" mi1", bin(sim.svstate.mi1)) + print (" mi2", bin(sim.svstate.mi2)) + print ("STATE2svgpr", hex(SVSHAPE2.svgpr)) + print ("STATE2 xdim", SVSHAPE2.xdimsz) + print ("STATE2 ydim", SVSHAPE2.ydimsz) + print ("STATE2 skip", bin(SVSHAPE2.skip)) + print ("STATE2 inv", SVSHAPE2.invxyz) + print ("STATE2order", SVSHAPE2.order) + self.assertEqual(sim.svstate.RMpst, 1) # mm=1 so persist=1 + # rmm is 0b01110 which means mo0 = 2 + self.assertEqual(sim.svstate.mi0, 0) + self.assertEqual(sim.svstate.mi1, 0) + self.assertEqual(sim.svstate.mi2, 0) + self.assertEqual(sim.svstate.mo0, 2) + self.assertEqual(sim.svstate.mo1, 0) + # and mo0 should be activated + self.assertEqual(sim.svstate.SVme, 0b01000) + # now check the SVSHAPEs. 2 was the one targetted + self.assertEqual(SVSHAPE2.svgpr, 2) # SVG is shifted up by 1 + self.assertEqual(SVSHAPE2.xdimsz, 5) # SHAPE2 xdim set to 5 + self.assertEqual(SVSHAPE2.ydimsz, 1) # SHAPE2 ydim 1 + # all others must be zero + for i in [0,1,3]: + shape = sim.spr['SVSHAPE%d' % i] + self.assertEqual(shape.asint(), 0) # all others zero + + def tst_0_sv_index_add(self): + """sets VL=6 (via SVSTATE) then does svindex, and an add. + + only RA is re-mapped via Indexing, not RB or RT + """ + isa = SVP64Asm(['svindex 8, 1, 1, 0, 0, 0, 0', + 'sv.add *8, *0, *0', + ]) + lst = list(isa) + print ("listing", lst) + + # initial values in GPR regfile + initial_regs = [0] * 32 + idxs = [1, 0, 5, 2, 4, 3] # random enough + for i in range(6): + initial_regs[16+i] = idxs[i] + initial_regs[i] = i + + # SVSTATE vl=10 + svstate = SVP64State() + svstate.vl = 6 # VL + svstate.maxvl = 6 # MAXVL + print ("SVSTATE", bin(svstate.asint())) + + # copy before running + expected_regs = deepcopy(initial_regs) + for i in range(6): + RA = initial_regs[0+idxs[i]] + RB = initial_regs[0+i] + expected_regs[i+8] = RA+RB + print ("expected", i, expected_regs[i+8]) + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, initial_regs, svstate=svstate) + + print (sim.spr) + SVSHAPE0 = sim.spr['SVSHAPE0'] + print ("SVSTATE after", bin(sim.svstate.asint())) + print (" vl", bin(sim.svstate.vl)) + print (" mvl", bin(sim.svstate.maxvl)) + print (" srcstep", bin(sim.svstate.srcstep)) + print (" dststep", bin(sim.svstate.dststep)) + print (" RMpst", bin(sim.svstate.RMpst)) + print (" SVme", bin(sim.svstate.SVme)) + print (" mo0", bin(sim.svstate.mo0)) + print (" mo1", bin(sim.svstate.mo1)) + print (" mi0", bin(sim.svstate.mi0)) + print (" mi1", bin(sim.svstate.mi1)) + print (" mi2", bin(sim.svstate.mi2)) + print ("STATE0svgpr", hex(SVSHAPE0.svgpr)) + print (sim.gpr.dump()) + self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0 + self.assertEqual(sim.svstate.SVme, 0b00001) # same as rmm + # rmm is 0b00001 which means mi0=0 and all others inactive (0) + self.assertEqual(sim.svstate.mi0, 0) + self.assertEqual(sim.svstate.mi1, 0) + self.assertEqual(sim.svstate.mi2, 0) + self.assertEqual(sim.svstate.mo0, 0) + self.assertEqual(sim.svstate.mo1, 0) + self.assertEqual(SVSHAPE0.svgpr, 16) # SVG is shifted up by 1 + for i in range(1,4): + shape = sim.spr['SVSHAPE%d' % i] + self.assertEqual(shape.svgpr, 0) + self._check_regs(sim, expected_regs) + + def tst_1_sv_index_add(self): + """sets VL=6 (via SVSTATE) then does modulo 3 svindex, and an add. + + only RA is re-mapped via Indexing, not RB or RT + """ + isa = SVP64Asm(['svindex 8, 1, 3, 0, 0, 0, 0', + 'sv.add *8, *0, *0', + ]) + lst = list(isa) + print ("listing", lst) + + # initial values in GPR regfile + initial_regs = [0] * 32 + idxs = [1, 0, 5, 2, 4, 3] # random enough + for i in range(6): + initial_regs[16+i] = idxs[i] + initial_regs[i] = i + + # SVSTATE vl=10 + svstate = SVP64State() + svstate.vl = 6 # VL + svstate.maxvl = 6 # MAXVL + print ("SVSTATE", bin(svstate.asint())) + + # copy before running + expected_regs = deepcopy(initial_regs) + for i in range(6): + RA = initial_regs[0+idxs[i%3]] # modulo 3 but still indexed + RB = initial_regs[0+i] + expected_regs[i+8] = RA+RB + print ("expected", i, expected_regs[i+8]) + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, initial_regs, svstate=svstate) + + print (sim.spr) + SVSHAPE0 = sim.spr['SVSHAPE0'] + print ("SVSTATE after", bin(sim.svstate.asint())) + print (" vl", bin(sim.svstate.vl)) + print (" mvl", bin(sim.svstate.maxvl)) + print (" srcstep", bin(sim.svstate.srcstep)) + print (" dststep", bin(sim.svstate.dststep)) + print (" RMpst", bin(sim.svstate.RMpst)) + print (" SVme", bin(sim.svstate.SVme)) + print (" mo0", bin(sim.svstate.mo0)) + print (" mo1", bin(sim.svstate.mo1)) + print (" mi0", bin(sim.svstate.mi0)) + print (" mi1", bin(sim.svstate.mi1)) + print (" mi2", bin(sim.svstate.mi2)) + print ("STATE0svgpr", hex(SVSHAPE0.svgpr)) + print ("STATE0 xdim", SVSHAPE0.xdimsz) + print ("STATE0 ydim", SVSHAPE0.ydimsz) + print ("STATE0 skip", bin(SVSHAPE0.skip)) + print ("STATE0 inv", SVSHAPE0.invxyz) + print ("STATE0order", SVSHAPE0.order) + print (sim.gpr.dump()) + self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0 + self.assertEqual(sim.svstate.SVme, 0b00001) # same as rmm + # rmm is 0b00001 which means mi0=0 and all others inactive (0) + self.assertEqual(sim.svstate.mi0, 0) + self.assertEqual(sim.svstate.mi1, 0) + self.assertEqual(sim.svstate.mi2, 0) + self.assertEqual(sim.svstate.mo0, 0) + self.assertEqual(sim.svstate.mo1, 0) + self.assertEqual(SVSHAPE0.svgpr, 16) # SVG is shifted up by 1 + for i in range(1,4): + shape = sim.spr['SVSHAPE%d' % i] + self.assertEqual(shape.svgpr, 0) + self._check_regs(sim, expected_regs) + + def tst_2_sv_index_add(self): + """sets VL=6 (via SVSTATE) then does 2D remapped svindex, and an add. + + dim=3,yx=1 + only RA is re-mapped via Indexing, not RB or RT + """ + isa = SVP64Asm(['svindex 8, 1, 3, 0, 1, 0, 0', + 'sv.add *8, *0, *0', + ]) + lst = list(isa) + print ("listing", lst) + + # initial values in GPR regfile + initial_regs = [0] * 32 + idxs = [1, 0, 5, 2, 4, 3] # random enough + for i in range(6): + initial_regs[16+i] = idxs[i] + initial_regs[i] = i + + # SVSTATE vl=10 + svstate = SVP64State() + svstate.vl = 6 # VL + svstate.maxvl = 6 # MAXVL + print ("SVSTATE", bin(svstate.asint())) + + # copy before running + expected_regs = deepcopy(initial_regs) + for i in range(6): + xi = i % 3 + yi = i // 3 + remap = yi+xi*2 + RA = initial_regs[0+idxs[remap]] # modulo 3 but still indexed + RB = initial_regs[0+i] + expected_regs[i+8] = RA+RB + print ("expected", i, expected_regs[i+8]) + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, initial_regs, svstate=svstate) + + print (sim.spr) + SVSHAPE0 = sim.spr['SVSHAPE0'] + print ("SVSTATE after", bin(sim.svstate.asint())) + print (" vl", bin(sim.svstate.vl)) + print (" mvl", bin(sim.svstate.maxvl)) + print (" srcstep", bin(sim.svstate.srcstep)) + print (" dststep", bin(sim.svstate.dststep)) + print (" RMpst", bin(sim.svstate.RMpst)) + print (" SVme", bin(sim.svstate.SVme)) + print (" mo0", bin(sim.svstate.mo0)) + print (" mo1", bin(sim.svstate.mo1)) + print (" mi0", bin(sim.svstate.mi0)) + print (" mi1", bin(sim.svstate.mi1)) + print (" mi2", bin(sim.svstate.mi2)) + print ("STATE0svgpr", hex(SVSHAPE0.svgpr)) + print ("STATE0 xdim", SVSHAPE0.xdimsz) + print ("STATE0 ydim", SVSHAPE0.ydimsz) + print ("STATE0 skip", bin(SVSHAPE0.skip)) + print ("STATE0 inv", SVSHAPE0.invxyz) + print ("STATE0order", SVSHAPE0.order) + print (sim.gpr.dump()) + self.assertEqual(sim.svstate.RMpst, 0) # mm=0 so persist=0 + self.assertEqual(sim.svstate.SVme, 0b00001) # same as rmm + # rmm is 0b00001 which means mi0=0 and all others inactive (0) + self.assertEqual(sim.svstate.mi0, 0) + self.assertEqual(sim.svstate.mi1, 0) + self.assertEqual(sim.svstate.mi2, 0) + self.assertEqual(sim.svstate.mo0, 0) + self.assertEqual(sim.svstate.mo1, 0) + self.assertEqual(SVSHAPE0.svgpr, 16) # SVG is shifted up by 1 + for i in range(1,4): + shape = sim.spr['SVSHAPE%d' % i] + self.assertEqual(shape.svgpr, 0) + 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/sv/trans/svp64.py b/src/openpower/sv/trans/svp64.py index aa694b7f..e094392e 100644 --- a/src/openpower/sv/trans/svp64.py +++ b/src/openpower/sv/trans/svp64.py @@ -215,7 +215,7 @@ def svshape2(fields): return instruction( (PO, 0, 5), - (offs, 6, 10), # offset (the whole point of adding svshape2) + (offs, 6, 9), # offset (the whole point of adding svshape2) (yx, 10, 10), # like svindex (rmm, 11, 15), # ditto svindex (SVd, 16, 20), # ditto svindex