pfv: add gpr_width parameter to explore designs with 32-bit GPRs.

main
Jean-François Nguyen 2 years ago
parent fa14ed223e
commit 28becc090c

@ -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)
@ -136,6 +142,7 @@ class _GPRFileTest(Elaboratable):
def __init__(self, check, *, 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

@ -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)

Loading…
Cancel
Save