checks.insn: add checks for CR logical instructions.
parent
bc06e67fe8
commit
fee59d2257
@ -0,0 +1,117 @@
|
|||||||
|
from amaranth import *
|
||||||
|
from amaranth.asserts import *
|
||||||
|
|
||||||
|
from .. import PowerFVCheck
|
||||||
|
from ... import pfv, tb
|
||||||
|
|
||||||
|
from ._fmt import *
|
||||||
|
from ._insn import *
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["CRSpec", "CRCheck"]
|
||||||
|
|
||||||
|
|
||||||
|
class CRSpec(Elaboratable):
|
||||||
|
def __init__(self, insn_cls, post):
|
||||||
|
self.insn_cls = insn_cls
|
||||||
|
self.pfv = pfv.Interface()
|
||||||
|
self.post = tb.Trigger(cycle=post)
|
||||||
|
|
||||||
|
def triggers(self):
|
||||||
|
yield self.post
|
||||||
|
|
||||||
|
def elaborate(self, platform):
|
||||||
|
m = Module()
|
||||||
|
|
||||||
|
spec_insn = self.insn_cls()
|
||||||
|
|
||||||
|
with m.If(self.post.stb):
|
||||||
|
m.d.sync += [
|
||||||
|
Assume(self.pfv.stb),
|
||||||
|
Assume(self.pfv.insn[32:] == spec_insn),
|
||||||
|
]
|
||||||
|
|
||||||
|
# CR
|
||||||
|
|
||||||
|
spec_cr_r_stb = Signal( 8)
|
||||||
|
spec_cr_w_stb = Signal( 8)
|
||||||
|
spec_cr_w_data = Signal(32)
|
||||||
|
|
||||||
|
if isinstance(spec_insn, (Instruction_XL_crl)):
|
||||||
|
|
||||||
|
ba_r_field = Signal(4)
|
||||||
|
bb_r_field = Signal(4)
|
||||||
|
bt_r_field = Signal(4)
|
||||||
|
ba_r_bit = Signal()
|
||||||
|
bb_r_bit = Signal()
|
||||||
|
bt_w_bit = Signal()
|
||||||
|
|
||||||
|
m.d.comb += [
|
||||||
|
ba_r_field.eq(self.pfv.cr.r_data[::-1].word_select(spec_insn.ba[2:], width=4)),
|
||||||
|
bb_r_field.eq(self.pfv.cr.r_data[::-1].word_select(spec_insn.bb[2:], width=4)),
|
||||||
|
bt_r_field.eq(self.pfv.cr.r_data[::-1].word_select(spec_insn.bt[2:], width=4)),
|
||||||
|
|
||||||
|
ba_r_bit.eq(ba_r_field.bit_select(spec_insn.ba[:2], width=1)),
|
||||||
|
bb_r_bit.eq(bb_r_field.bit_select(spec_insn.bb[:2], width=1)),
|
||||||
|
]
|
||||||
|
|
||||||
|
if isinstance(spec_insn, CRAND):
|
||||||
|
m.d.comb += bt_w_bit.eq(ba_r_bit & bb_r_bit)
|
||||||
|
elif isinstance(spec_insn, CROR):
|
||||||
|
m.d.comb += bt_w_bit.eq(ba_r_bit | bb_r_bit)
|
||||||
|
elif isinstance(spec_insn, CRNAND):
|
||||||
|
m.d.comb += bt_w_bit.eq(~(ba_r_bit & bb_r_bit))
|
||||||
|
elif isinstance(spec_insn, CRXOR):
|
||||||
|
m.d.comb += bt_w_bit.eq(ba_r_bit ^ bb_r_bit)
|
||||||
|
elif isinstance(spec_insn, CRNOR):
|
||||||
|
m.d.comb += bt_w_bit.eq(~(ba_r_bit | bb_r_bit))
|
||||||
|
elif isinstance(spec_insn, CRANDC):
|
||||||
|
m.d.comb += bt_w_bit.eq(ba_r_bit & ~bb_r_bit)
|
||||||
|
elif isinstance(spec_insn, CREQV):
|
||||||
|
m.d.comb += bt_w_bit.eq(ba_r_bit == bb_r_bit)
|
||||||
|
elif isinstance(spec_insn, CRORC):
|
||||||
|
m.d.comb += bt_w_bit.eq(ba_r_bit | ~bb_r_bit)
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
spec_bt_w_field = Signal(4)
|
||||||
|
|
||||||
|
for i, spec_bt_w_bit in enumerate(spec_bt_w_field):
|
||||||
|
bt_r_bit = bt_r_field[i]
|
||||||
|
with m.If(spec_insn.bt[:2] == i):
|
||||||
|
m.d.comb += spec_bt_w_bit.eq(bt_w_bit)
|
||||||
|
with m.Else():
|
||||||
|
m.d.comb += spec_bt_w_bit.eq(bt_r_bit)
|
||||||
|
|
||||||
|
m.d.comb += [
|
||||||
|
spec_cr_r_stb[::-1].bit_select(spec_insn.ba[2:], width=1).eq(1),
|
||||||
|
spec_cr_r_stb[::-1].bit_select(spec_insn.bb[2:], width=1).eq(1),
|
||||||
|
spec_cr_w_stb[::-1].bit_select(spec_insn.bt[2:], width=1).eq(1),
|
||||||
|
spec_cr_w_data.eq(Repl(spec_bt_w_field, 8))
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
with m.If(self.post.stb & ~self.pfv.intr):
|
||||||
|
for i in range(8):
|
||||||
|
spec_cr_w_field = spec_cr_w_data .word_select(i, width=4)
|
||||||
|
pfv_cr_w_field = self.pfv.cr.w_data.word_select(i, width=4)
|
||||||
|
|
||||||
|
m.d.sync += [
|
||||||
|
Assert(spec_cr_r_stb[i].implies(self.pfv.cr.r_stb[i])),
|
||||||
|
Assert(self.pfv.cr.w_stb[i] == spec_cr_w_stb[i]),
|
||||||
|
Assert(spec_cr_w_stb[i].implies(pfv_cr_w_field == spec_cr_w_field)),
|
||||||
|
]
|
||||||
|
|
||||||
|
return m
|
||||||
|
|
||||||
|
|
||||||
|
class CRCheck(PowerFVCheck, name="_insn_cr"):
|
||||||
|
def __init_subclass__(cls, name, insn_cls):
|
||||||
|
super().__init_subclass__(name)
|
||||||
|
cls.insn_cls = insn_cls
|
||||||
|
|
||||||
|
def get_testbench(self, dut, post):
|
||||||
|
tb_spec = CRSpec(self.insn_cls, post)
|
||||||
|
tb_top = tb.Testbench(tb_spec, dut)
|
||||||
|
return tb_top
|
Loading…
Reference in New Issue