sim: add eval_format
function.
This will be used in an upcoming PR for VCD output.
This commit is contained in:
parent
580706fafd
commit
eebffc15d6
|
@ -128,6 +128,33 @@ def eval_value(sim, value):
|
||||||
assert False # :nocov:
|
assert False # :nocov:
|
||||||
|
|
||||||
|
|
||||||
|
def value_to_string(value):
|
||||||
|
"""Unpack a Verilog-like (but LSB-first) string of unknown width from an integer."""
|
||||||
|
msg = bytearray()
|
||||||
|
while value:
|
||||||
|
byte = value & 0xff
|
||||||
|
value >>= 8
|
||||||
|
if byte:
|
||||||
|
msg.append(byte)
|
||||||
|
return msg.decode()
|
||||||
|
|
||||||
|
|
||||||
|
def eval_format(sim, fmt):
|
||||||
|
fmt = Format("{}", fmt)
|
||||||
|
chunks = []
|
||||||
|
for chunk in fmt._chunks:
|
||||||
|
if isinstance(chunk, str):
|
||||||
|
chunks.append(chunk)
|
||||||
|
else:
|
||||||
|
value, spec = chunk
|
||||||
|
value = eval_value(sim, value)
|
||||||
|
if spec.endswith("s"):
|
||||||
|
chunks.append(format(value_to_string(value), spec[:-1]))
|
||||||
|
else:
|
||||||
|
chunks.append(format(value, spec))
|
||||||
|
return "".join(chunks)
|
||||||
|
|
||||||
|
|
||||||
def _eval_assign_inner(sim, lhs, lhs_start, rhs, rhs_len):
|
def _eval_assign_inner(sim, lhs, lhs_start, rhs, rhs_len):
|
||||||
if isinstance(lhs, Operator) and lhs.operator in ("u", "s"):
|
if isinstance(lhs, Operator) and lhs.operator in ("u", "s"):
|
||||||
_eval_assign_inner(sim, lhs.operands[0], lhs_start, rhs, rhs_len)
|
_eval_assign_inner(sim, lhs.operands[0], lhs_start, rhs, rhs_len)
|
||||||
|
|
|
@ -8,6 +8,7 @@ from ..hdl._ast import SignalSet, _StatementList, Property
|
||||||
from ..hdl._xfrm import ValueVisitor, StatementVisitor
|
from ..hdl._xfrm import ValueVisitor, StatementVisitor
|
||||||
from ..hdl._mem import MemoryInstance
|
from ..hdl._mem import MemoryInstance
|
||||||
from ._base import BaseProcess
|
from ._base import BaseProcess
|
||||||
|
from ._pyeval import value_to_string
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["PyRTLProcess"]
|
__all__ = ["PyRTLProcess"]
|
||||||
|
@ -356,17 +357,6 @@ class _LHSValueCompiler(_ValueCompiler):
|
||||||
return gen
|
return gen
|
||||||
|
|
||||||
|
|
||||||
def value_to_string(value):
|
|
||||||
"""Unpack a Verilog-like (but LSB-first) string of unknown width from an integer."""
|
|
||||||
msg = bytearray()
|
|
||||||
while value:
|
|
||||||
byte = value & 0xff
|
|
||||||
value >>= 8
|
|
||||||
if byte:
|
|
||||||
msg.append(byte)
|
|
||||||
return msg.decode()
|
|
||||||
|
|
||||||
|
|
||||||
def pin_blame(src_loc, exc):
|
def pin_blame(src_loc, exc):
|
||||||
if src_loc is None:
|
if src_loc is None:
|
||||||
raise exc
|
raise exc
|
||||||
|
|
|
@ -13,9 +13,9 @@ with warnings.catch_warnings():
|
||||||
from amaranth.hdl._dsl import *
|
from amaranth.hdl._dsl import *
|
||||||
from amaranth.hdl._ir import *
|
from amaranth.hdl._ir import *
|
||||||
from amaranth.sim import *
|
from amaranth.sim import *
|
||||||
|
from amaranth.sim._pyeval import eval_format
|
||||||
from amaranth.lib.memory import Memory
|
from amaranth.lib.memory import Memory
|
||||||
from amaranth.lib.data import View, StructLayout
|
from amaranth.lib import enum, data
|
||||||
from amaranth.lib import enum
|
|
||||||
|
|
||||||
from .utils import *
|
from .utils import *
|
||||||
from amaranth._utils import _ignore_deprecated
|
from amaranth._utils import _ignore_deprecated
|
||||||
|
@ -1302,6 +1302,44 @@ class SimulatorIntegrationTestCase(FHDLTestCase):
|
||||||
with sim.write_vcd("test.vcd", fs_per_delta=1):
|
with sim.write_vcd("test.vcd", fs_per_delta=1):
|
||||||
sim.run()
|
sim.run()
|
||||||
|
|
||||||
|
def test_eval_format(self):
|
||||||
|
class MyEnum(enum.Enum, shape=2):
|
||||||
|
A = 0
|
||||||
|
B = 1
|
||||||
|
C = 2
|
||||||
|
|
||||||
|
sig = Signal(8)
|
||||||
|
sig2 = Signal(MyEnum)
|
||||||
|
sig3 = Signal(data.StructLayout({"a": signed(3), "b": 2}))
|
||||||
|
sig4 = Signal(data.ArrayLayout(2, 4))
|
||||||
|
sig5 = Signal(32, init=0x44434241)
|
||||||
|
|
||||||
|
def testbench():
|
||||||
|
state = sim._engine._state
|
||||||
|
yield sig.eq(123)
|
||||||
|
self.assertEqual(eval_format(state, sig._format), "123")
|
||||||
|
self.assertEqual(eval_format(state, Format("{:#04x}", sig)), "0x7b")
|
||||||
|
self.assertEqual(eval_format(state, Format("sig={}", sig)), "sig=123")
|
||||||
|
|
||||||
|
self.assertEqual(eval_format(state, sig2.as_value()._format), "A")
|
||||||
|
yield sig2.eq(1)
|
||||||
|
self.assertEqual(eval_format(state, sig2.as_value()._format), "B")
|
||||||
|
yield sig2.eq(3)
|
||||||
|
self.assertEqual(eval_format(state, sig2.as_value()._format), "[unknown]")
|
||||||
|
|
||||||
|
yield sig3.eq(0xc)
|
||||||
|
self.assertEqual(eval_format(state, sig3.as_value()._format), "{a=-4, b=1}")
|
||||||
|
|
||||||
|
yield sig4.eq(0x1e)
|
||||||
|
self.assertEqual(eval_format(state, sig4.as_value()._format), "[2, 3, 1, 0]")
|
||||||
|
|
||||||
|
self.assertEqual(eval_format(state, Format("{:s}", sig5)), "ABCD")
|
||||||
|
self.assertEqual(eval_format(state, Format("{:<5s}", sig5)), "ABCD ")
|
||||||
|
|
||||||
|
sim = Simulator(Module())
|
||||||
|
sim.add_testbench(testbench)
|
||||||
|
with sim.write_vcd("test.vcd", fs_per_delta=1):
|
||||||
|
sim.run()
|
||||||
|
|
||||||
class SimulatorRegressionTestCase(FHDLTestCase):
|
class SimulatorRegressionTestCase(FHDLTestCase):
|
||||||
def test_bug_325(self):
|
def test_bug_325(self):
|
||||||
|
|
Loading…
Reference in a new issue