You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
1.6 KiB
Python

from collections import OrderedDict
from amaranth import *
from amaranth.asserts import *
from .. import pfv
__all__ = ["Check"]
class Check(Elaboratable):
"""Special Purpose Registers check.
Checks that reads from supported SPRs are consistent with the last value that was written to
them.
"""
def __init__(self):
self.pfv = pfv.Interface()
self.trig = Record([
("pre", 1),
("post", 1),
])
def elaborate(self, platform):
m = Module()
spr_map = OrderedDict()
for spr_name in ("lr", "ctr", "xer", "tar"):
spr = Record([
("written", 1),
("shadow", 64),
], name=spr_name)
spr_map[spr_name] = spr
spec_order = AnyConst(self.pfv.order.width)
with m.If(self.pfv.stb & (self.pfv.order <= spec_order)):
for spr_name, spr in spr_map.items():
pfv_spr = getattr(self.pfv, spr_name)
with m.If(pfv_spr.w_stb):
m.d.sync += [
spr.written.eq(1),
spr.shadow .eq(pfv_spr.w_data),
]
with m.If(self.trig.post):
m.d.sync += [
Assume(Past(self.pfv.stb)),
Assume(Past(self.pfv.order) == spec_order),
]
for spr_name, spr in spr_map.items():
pfv_spr = getattr(self.pfv, spr_name)
with m.If(spr.written & Past(pfv_spr.r_stb)):
m.d.sync += Assert(Past(spr.shadow) == Past(pfv_spr.r_data))
return m