From 9078b2935beb4ba89dcd2af91bb5e3a0bcffbe71 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Fri, 12 Feb 2021 14:41:48 +0000 Subject: [PATCH] add srcstep and correct PC-advancing during Sub-PC looping in ISACaller --- src/soc/decoder/isa/caller.py | 37 +++++++++++++---- src/soc/decoder/isa/test_caller.py | 2 +- src/soc/decoder/isa/test_caller_svp64.py | 52 +++++++++++++++++++++++- 3 files changed, 82 insertions(+), 9 deletions(-) diff --git a/src/soc/decoder/isa/caller.py b/src/soc/decoder/isa/caller.py index 7ade13af..4a38a1ed 100644 --- a/src/soc/decoder/isa/caller.py +++ b/src/soc/decoder/isa/caller.py @@ -211,14 +211,17 @@ class GPR(dict): class PC: def __init__(self, pc_init=0): self.CIA = SelectableInt(pc_init, 64) - self.NIA = self.CIA + SelectableInt(4, 64) + self.NIA = self.CIA + SelectableInt(4, 64) # only true for v3.0B! + + def update_nia(self, is_svp64): + increment = 8 if is_svp64 else 4 + self.NIA = self.CIA + SelectableInt(increment, 64) def update(self, namespace, is_svp64): """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64 """ - increment = 8 if is_svp64 else 4 self.CIA = namespace['NIA'].narrow(64) - self.NIA = self.CIA + SelectableInt(increment, 64) + self.update_nia(is_svp64) namespace['CIA'] = self.CIA namespace['NIA'] = self.NIA @@ -695,6 +698,7 @@ class ISACaller: self.is_svp64_mode = ((major == 0b000001) and pfx.insn[7].value == 0b1 and pfx.insn[9].value == 0b1) + self.pc.update_nia(self.is_svp64_mode) if not self.is_svp64_mode: return @@ -863,6 +867,9 @@ class ISACaller: dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {} print ("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname) + # get SVSTATE srcstep. TODO: dststep (twin predication) + srcstep = self.svstate.srcstep.asint(msb0=True) + # main input registers (RT, RA ...) inputs = [] for name in input_names: @@ -873,6 +880,10 @@ class ISACaller: # doing this is not part of svp64, it's because output # registers, to be modified, need to be in the namespace. regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name) + # here's where we go "vector". TODO: zero-testing (RA_IS_ZERO) + if is_vec: + regnum += srcstep # TODO, elwidth overrides + # in case getting the register number is needed, _RA, _RB regname = "_" + name self.namespace[regname] = regnum @@ -943,6 +954,9 @@ class ISACaller: if rc_en: self.handle_comparison(results) + # svp64 loop can end early if the dest is scalar + svp64_dest_vector = False + # any modified return results? if info.write_regs: for name, output in zip(output_names, results): @@ -971,13 +985,15 @@ class ISACaller: # temporary hack for not having 2nd output regnum = yield getattr(self.decoder, name) is_vec = False + # here's where we go "vector". + if is_vec: + regnum += srcstep # TODO, elwidth overrides + svp64_dest_vector = True print('writing reg %d %s' % (regnum, str(output)), is_vec) if output.bits > 64: output = SelectableInt(output.value, 64) self.gpr[regnum] = output - print("end of call", self.namespace['CIA'], self.namespace['NIA']) - # check if it is the SVSTATE.src/dest step that needs incrementing # this is our Sub-Program-Counter loop from 0 to VL-1 if self.is_svp64_mode: @@ -988,16 +1004,23 @@ class ISACaller: print (" svstate.vl", vl) print (" svstate.mvl", mvl) print (" svstate.srcstep", srcstep) - # check if srcstep needs incrementing by one - if srcstep != vl-1: + # check if srcstep needs incrementing by one, stop PC advancing + if svp64_dest_vector and srcstep != vl-1: self.svstate.srcstep += SelectableInt(1, 7) + self.pc.NIA.value = self.pc.CIA.value + self.namespace['NIA'] = self.pc.NIA + print("end of sub-pc call", self.namespace['CIA'], + self.namespace['NIA']) return # DO NOT allow PC to update whilst Sub-PC loop running # reset to zero self.svstate.srcstep[0:7] = 0 print (" svstate.srcstep loop end (PC to update)") + self.pc.update_nia(self.is_svp64_mode) + self.namespace['NIA'] = self.pc.NIA # UPDATE program counter self.pc.update(self.namespace, self.is_svp64_mode) + print("end of call", self.namespace['CIA'], self.namespace['NIA']) def inject(): diff --git a/src/soc/decoder/isa/test_caller.py b/src/soc/decoder/isa/test_caller.py index 8f190ca0..691d9a71 100644 --- a/src/soc/decoder/isa/test_caller.py +++ b/src/soc/decoder/isa/test_caller.py @@ -53,7 +53,7 @@ def run_tst(generator, initial_regs, initial_sprs=None, svstate=0): yield Settle() ins, code = instructions[index] - print("0x{:X}".format(ins & 0xffffffff)) + print(" 0x{:X}".format(ins & 0xffffffff)) opname = code.split(' ')[0] print(code, opname) diff --git a/src/soc/decoder/isa/test_caller_svp64.py b/src/soc/decoder/isa/test_caller_svp64.py index 90f2d409..c164b91c 100644 --- a/src/soc/decoder/isa/test_caller_svp64.py +++ b/src/soc/decoder/isa/test_caller_svp64.py @@ -17,7 +17,10 @@ from soc.sv.trans.svp64 import SVP64Asm class DecoderTestCase(FHDLTestCase): def test_sv_add(self): - isa = SVP64Asm(['sv.add 1, 5, 9' + # adds: + # 1 = 5 + 9 => 0x5555 = 0x4321+0x1234 + # 2 = 6 + 10 => 0x3334 = 0x2223+0x1111 + isa = SVP64Asm(['sv.add 1.v, 5.v, 9.v' ]) lst = list(isa) @@ -34,6 +37,53 @@ class DecoderTestCase(FHDLTestCase): with Program(lst, bigendian=False) as program: sim = self.run_tst_program(program, initial_regs, svstate) self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64)) + self.assertEqual(sim.gpr(2), SelectableInt(0x3334, 64)) + + def test_sv_add_2(self): + # adds: + # 1 = 5 + 9 => 0x5555 = 0x4321+0x1234 + # r1 is scalar so ENDS EARLY + isa = SVP64Asm(['sv.add 1, 5.v, 9.v' + ]) + + lst = list(isa) + print ("listing", lst) + initial_regs = [0] * 32 + initial_regs[9] = 0x1234 + initial_regs[10] = 0x1111 + initial_regs[5] = 0x4321 + initial_regs[6] = 0x2223 + svstate = SVP64State() + svstate.vl[0:7] = 2 # VL + svstate.maxvl[0:7] = 2 # MAXVL + print ("SVSTATE", bin(svstate.spr.asint())) + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, initial_regs, svstate) + self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64)) + self.assertEqual(sim.gpr(2), SelectableInt(0, 64)) + + def test_sv_add_3(self): + # adds: + # 1 = 5 + 9 => 0x5555 = 0x4321+0x1234 + # 2 = 5 + 10 => 0x5432 = 0x4321+0x1111 + isa = SVP64Asm(['sv.add 1.v, 5, 9.v' + ]) + + lst = list(isa) + print ("listing", lst) + initial_regs = [0] * 32 + initial_regs[9] = 0x1234 + initial_regs[10] = 0x1111 + initial_regs[5] = 0x4321 + initial_regs[6] = 0x2223 + svstate = SVP64State() + svstate.vl[0:7] = 2 # VL + svstate.maxvl[0:7] = 2 # MAXVL + print ("SVSTATE", bin(svstate.spr.asint())) + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, initial_regs, svstate) + self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64)) + self.assertEqual(sim.gpr(2), SelectableInt(0x5432, 64)) def run_tst_program(self, prog, initial_regs=[0] * 32, svstate=None): -- 2.30.2