From 28becc090ca08e0258c0c50f406ff7a4dc2ecf1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Nguyen?= Date: Mon, 19 Sep 2022 17:28:47 +0200 Subject: [PATCH] pfv: add gpr_width parameter to explore designs with 32-bit GPRs. --- power_fv/check/insn/__init__.py | 19 +++++++++++++++---- power_fv/pfv.py | 11 +++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/power_fv/check/insn/__init__.py b/power_fv/check/insn/__init__.py index 138e0d0..e48271c 100644 --- a/power_fv/check/insn/__init__.py +++ b/power_fv/check/insn/__init__.py @@ -28,7 +28,13 @@ class InsnCheck(PowerFVCheck, metaclass=InsnCheckMeta): def __init__(self, *, depth, skip, core, **kwargs): super().__init__(depth=depth, skip=skip, core=core, **kwargs) self.insn = self.insn_cls() - self.spec = self.spec_cls(self.insn, mem_aligned=self.dut.pfv.mem_aligned, muldiv_altops=self.dut.pfv.muldiv_altops) + self.spec = self.spec_cls( + insn = self.insn, + gpr_width = self.dut.pfv.gpr_width, + mem_aligned = self.dut.pfv.mem_aligned, + illegal_insn_heai = self.dut.pfv.illegal_insn_heai, + muldiv_altops = self.dut.pfv.muldiv_altops, + ) def testbench(self): return InsnTestbench(self) @@ -134,8 +140,9 @@ class InsnTestbench(Elaboratable): class _GPRFileTest(Elaboratable): def __init__(self, check, *, port): - self._dut = getattr(check.dut .pfv, port) - self._spec = getattr(check.spec.pfv, port) + self._dut = getattr(check.dut .pfv, port) + self._spec = getattr(check.spec.pfv, port) + self._width = check.dut.pfv.gpr_width self.valid = Record([ ("read" , [("index", 1), ("r_stb", 1)]), @@ -148,6 +155,10 @@ class _GPRFileTest(Elaboratable): dut = Record.like(self._dut ) spec = Record.like(self._spec) + def gpr_equal(a, b): + mask = Const(2**self._width - 1, self._width) + return a & mask == b & mask + m.d.comb += [ dut .eq(self._dut ), spec.eq(self._spec), @@ -159,7 +170,7 @@ class _GPRFileTest(Elaboratable): # The DUT and the spec must write the same value to the same GPR. self.valid.write.index .eq(spec.w_stb.implies(dut.index == spec.index)), self.valid.write.w_stb .eq(spec.w_stb == dut.w_stb), - self.valid.write.w_data.eq(spec.w_stb.implies(dut.w_data == spec.w_data)), + self.valid.write.w_data.eq(spec.w_stb.implies(gpr_equal(dut.w_data, spec.w_data))), ] return m diff --git a/power_fv/pfv.py b/power_fv/pfv.py index 7c67c42..bb39a93 100644 --- a/power_fv/pfv.py +++ b/power_fv/pfv.py @@ -106,6 +106,9 @@ class Interface(Record): The following parameters describe implementation-specific behavior. They do not affect the layout of this interface. + gpr_width : int + General-purpose register width. Either 32 or 64. Compliance with Power ISA versions above + v2.7B requires 64-bit wide GPRs. mem_aligned : bool If ``True``, an Alignment interrupt is expected if the effective address of a Load/Store operation is not aligned to its operand; ``mem.addr`` is also expected to be aligned to @@ -215,8 +218,12 @@ class Interface(Record): srr1 : Record(:func:`reg_port_layout`) Save/Restore Register 1 access. """ - def __init__(self, *, mem_aligned=False, illegal_insn_heai=False, muldiv_altops=False, - name=None, src_loc_at=0): + def __init__(self, *, gpr_width=64, mem_aligned=False, illegal_insn_heai=False, + muldiv_altops=False, name=None, src_loc_at=0): + if gpr_width not in (32, 64): + raise ValueError("GPR width must be 32 or 64, not {!r}".format(gpr_width)) + + self.gpr_width = gpr_width self.mem_aligned = bool(mem_aligned) self.illegal_insn_heai = bool(illegal_insn_heai) self.muldiv_altops = bool(muldiv_altops)