import unittest
-from nmigen import Elaboratable, Module
+from nmigen import (
+ Cat,
+ Const,
+ Elaboratable,
+ Module,
+)
from nmigen.asserts import Assert, AnyConst
from nmigen.cli import rtlil
from nmutil.formaltest import FHDLTestCase
+from soc.decoder.power_enums import MicrOp
+
from soc.fu.trap.main_stage import TrapMainStage
from soc.fu.trap.pipe_data import TrapPipeSpec
+def is_ok(sig, value):
+ """
+ Answers with a list of assertions that checks for valid data on
+ a pipeline stage output. sig.data must have the anticipated value,
+ and sig.ok must be asserted. The `value` is constrained to the width
+ of the sig.data field it's verified against, so it's safe to add, etc.
+ offsets to Nmigen signals without having to worry about inequalities from
+ differing signal widths.
+ """
+ return [
+ Assert(sig.data == value[0:len(sig.data)]),
+ Assert(sig.ok),
+ ]
+
+
+def full_function_bits(msr):
+ """
+ Answers with a numeric constant signal with all "full functional"
+ bits filled in, but all partial functional bits zeroed out.
+
+ See src/soc/fu/trap/main_stage.py:msr_copy commentary for details.
+ """
+ zeros16_21 = Const(0, (22 - 16))
+ zeros27_30 = Const(0, (31 - 27))
+ return Cat(msr[0:16], zeros16_21, msr[22:27], zeros27_30, msr[31:64])
+
+
class Driver(Elaboratable):
"""
"""
m.submodules.dut = dut = TrapMainStage(pspec)
+ # frequently used aliases
+ op = dut.i.ctx.op
+
+ # start of properties
+ with m.Switch(op.insn_type):
+ with m.Case(MicrOp.OP_SC):
+ comb += [
+ is_ok(dut.o.nia, Const(0xC00)),
+ is_ok(dut.o.srr0, dut.i.cia + 4),
+ is_ok(dut.o.srr1, full_function_bits(dut.i.msr)),
+ ]
+
comb += dut.i.ctx.matches(dut.o.ctx)
return m