From c9776ab4ec22b9fc3976659026aa95a7758cbaba Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Tue, 21 Nov 2023 10:03:24 -0800 Subject: [PATCH] Update assert to use inline_verilog2 (#333) * Update assert to use inline_verilog2 * Fix style * Update expectation * Fix ready_valid tests * Fix style * Add verilator version logic --------- Co-authored-by: Lenny Truong --- fault/assert_immediate.py | 22 ++++------- fault/property.py | 24 ++++-------- tests/test_assert_immediate.py | 71 ++++++++++++++++++++-------------- tests/test_ready_valid.py | 43 ++++++++++++-------- 4 files changed, 84 insertions(+), 76 deletions(-) diff --git a/fault/assert_immediate.py b/fault/assert_immediate.py index ce86ba1b..607fba07 100644 --- a/fault/assert_immediate.py +++ b/fault/assert_immediate.py @@ -5,10 +5,7 @@ def _make_assert(type_, cond, success_msg=None, failure_msg=None, - severity="error", name=None, compile_guard=None, delay=False, - inline_wire_prefix=None): - if inline_wire_prefix is None: - inline_wire_prefix = "_FAULT_ASSERT_WIRE_" + severity="error", name=None, compile_guard=None, delay=False): success_msg_str = "" if success_msg is not None: success_msg_str = f" $display(\"{success_msg}\");" @@ -38,9 +35,7 @@ def _make_assert(type_, cond, success_msg=None, failure_msg=None, end """ assert_str = add_compile_guards(compile_guard, assert_str) - m.inline_verilog( - assert_str, inline_wire_prefix=inline_wire_prefix, - **format_args, type_=type_) + m.inline_verilog2(assert_str, **format_args, type_=type_) def _add_docstr(fn): @@ -66,7 +61,7 @@ def _add_docstr(fn): @_add_docstr def assert_immediate(cond, success_msg=None, failure_msg=None, severity="error", - name=None, compile_guard=None, inline_wire_prefix=None): + name=None, compile_guard=None): if get_curr_when_block(): # guard condition by current active when using a boolean with default 0 # and assigned inside when @@ -77,19 +72,18 @@ def assert_immediate(cond, success_msg=None, failure_msg=None, severity="error", cond = ~when_cond | cond _make_assert("always @(*)", cond, success_msg, failure_msg, severity, name, - compile_guard, inline_wire_prefix=inline_wire_prefix) + compile_guard) @_add_docstr def assert_final(cond, success_msg=None, failure_msg=None, severity="error", - name=None, compile_guard=None, inline_wire_prefix=None): + name=None, compile_guard=None): _make_assert("final", cond, success_msg, failure_msg, severity, name, - compile_guard, inline_wire_prefix=inline_wire_prefix) + compile_guard) @_add_docstr def assert_initial(cond, success_msg=None, failure_msg=None, severity="error", - name=None, compile_guard=None, inline_wire_prefix=None): + name=None, compile_guard=None): _make_assert("initial", cond, success_msg, failure_msg, severity, name, - compile_guard, delay=True, - inline_wire_prefix=inline_wire_prefix) + compile_guard, delay=True) diff --git a/fault/property.py b/fault/property.py index fe1dd96c..f0ea481f 100644 --- a/fault/property.py +++ b/fault/property.py @@ -245,8 +245,7 @@ def compile(self, prop): return compiled -def _make_statement(statement, prop, on, disable_iff, compile_guard, name, - inline_wire_prefix): +def _make_statement(statement, prop, on, disable_iff, compile_guard, name): format_args = {} _compiler = _Compiler(format_args) prop = _compiler.compile(prop) @@ -260,26 +259,19 @@ def _make_statement(statement, prop, on, disable_iff, compile_guard, name, raise TypeError("Expected string for name") prop_str = f"{name}: {prop_str}" prop_str = add_compile_guards(compile_guard, prop_str) - m.inline_verilog(prop_str, inline_wire_prefix=inline_wire_prefix, - **format_args) + m.inline_verilog2(prop_str, **format_args) -def assert_(prop, on, disable_iff=None, compile_guard=None, name=None, - inline_wire_prefix="_FAULT_ASSERT_WIRE_"): - _make_statement("assert", prop, on, disable_iff, compile_guard, name, - inline_wire_prefix) +def assert_(prop, on, disable_iff=None, compile_guard=None, name=None): + _make_statement("assert", prop, on, disable_iff, compile_guard, name) -def cover(prop, on, disable_iff=None, compile_guard=None, name=None, - inline_wire_prefix="_FAULT_COVER_WIRE_"): - _make_statement("cover", prop, on, disable_iff, compile_guard, name, - inline_wire_prefix) +def cover(prop, on, disable_iff=None, compile_guard=None, name=None): + _make_statement("cover", prop, on, disable_iff, compile_guard, name) -def assume(prop, on, disable_iff=None, compile_guard=None, name=None, - inline_wire_prefix="_FAULT_ASSUME_WIRE_"): - _make_statement("assume", prop, on, disable_iff, compile_guard, name, - inline_wire_prefix) +def assume(prop, on, disable_iff=None, compile_guard=None, name=None): + _make_statement("assume", prop, on, disable_iff, compile_guard, name) class Sequence: diff --git a/tests/test_assert_immediate.py b/tests/test_assert_immediate.py index 2d7666f9..d8569684 100644 --- a/tests/test_assert_immediate.py +++ b/tests/test_assert_immediate.py @@ -16,60 +16,67 @@ def test_immediate_assert(capsys, failure_msg, success_msg, severity, name): if verilator_version() < 4.0: pytest.skip("Untested with earlier verilator versions") - if verilator_version() > 5.0: - pytest.skip("Untested with later verilator versions") if failure_msg is not None and severity == "fatal": - # Use integer exit code - failure_msg = 1 + # Verilator won't report failure msg for fatal + failure_msg = None class Foo(m.Circuit): io = m.IO( I0=m.In(m.Bit), - I1=m.In(m.Bit) - ) + m.ClockIO() - io.CLK.unused() + I1=m.In(m.Bit), + O=m.Out(m.Bit) + ) + io.O @= io.I0 ^ io.I1 f.assert_immediate(~(io.I0 & io.I1), success_msg=success_msg, failure_msg=failure_msg, severity=severity, name=name) - tester = f.Tester(Foo, Foo.CLK) + tester = f.Tester(Foo) tester.circuit.I0 = 1 tester.circuit.I1 = 1 - tester.step(2) + tester.eval() try: with tempfile.TemporaryDirectory() as dir_: - tester.compile_and_run("verilator", magma_opts={"inline": True}, + tester.compile_and_run("verilator", magma_output="mlir-verilog", flags=['--assert'], directory=dir_, disp_type="realtime") except AssertionError: assert failure_msg is None or severity in ["error", "fatal"] else: - # warning doesn't trigger exit code/failure (but only if there's a - # failure_msg, otherwise severity is ignored) - assert severity == "warning" + assert ( + (severity == "warning") or + # If success msg but no failure msg, doesn't return error code. + (failure_msg is None and success_msg is not None) + ) out, _ = capsys.readouterr() if failure_msg is not None: - if severity == "warning": - msg = "%Warning:" + msg = { + "warning": "%Warning:", + "fatal": "%Fatal:", + "error": "%Error:", + }[severity] + msg += " Foo.v:9: " + if verilator_version() >= 5.016: + if severity == "error": + msg += "Assertion failed in " else: - msg = "%Error:" - msg += " Foo.v:31: Assertion failed in TOP.Foo" + msg += "Assertion failed in " + msg += "TOP.Foo" if name is not None: msg += f".{name}" - if severity == "error": + if failure_msg is not None: msg += f": {failure_msg}" assert msg in out, out tester.clear() tester.circuit.I0 = 0 tester.circuit.I1 = 1 - tester.step(2) + tester.eval() with tempfile.TemporaryDirectory() as dir_: tester.compile_and_run("verilator", - magma_opts={"inline": True, - "verilator_compat": True}, + magma_output="mlir-verilog", flags=['--assert'], directory=dir_, disp_type="realtime") out, _ = capsys.readouterr() @@ -97,11 +104,11 @@ class Foo(m.Circuit): tester.eval() with pytest.raises(AssertionError): with tempfile.TemporaryDirectory() as dir_: - tester.compile_and_run("verilator", magma_opts={"inline": True}, + tester.compile_and_run("verilator", magma_output="mlir-verilog", flags=['--assert', '-Wno-UNUSED'], directory=dir_, disp_type="realtime") out, _ = capsys.readouterr() - msg = ("%Error: Foo.v:15: Assertion failed in TOP.Foo: io.I0 -> 1 != 0 <-" + msg = ("%Error: Foo.v:8: Assertion failed in TOP.Foo: io.I0 -> 1 != 0 <-" " io.I1") assert msg in out, out @@ -124,15 +131,18 @@ class Foo(m.Circuit): tester.step(2) # Should pass without macro defined with tempfile.TemporaryDirectory() as dir_: - tester.compile_and_run("verilator", magma_opts={"inline": True}, + tester.compile_and_run("verilator", magma_output="mlir-verilog", flags=['--assert', '-Wno-UNUSED'], directory=dir_, disp_type="realtime") # Should fail without macro defined with pytest.raises(AssertionError): with tempfile.TemporaryDirectory() as dir_: - tester.compile_and_run("verilator", magma_opts={"inline": True}, - flags=['--assert', '-DASSERT_ON=1', - '-Wno-UNUSED'], directory=dir_) + tester.compile_and_run( + "verilator", + magma_output="mlir-verilog", + flags=['--assert', '-DASSERT_ON=1', '-Wno-UNUSED'], + directory=dir_ + ) def test_assert_final(): @@ -152,12 +162,12 @@ class Foo(m.Circuit): with pytest.raises(AssertionError): with tempfile.TemporaryDirectory() as dir_: dir_ = "build" - tester.compile_and_run("verilator", magma_opts={"inline": True}, + tester.compile_and_run("verilator", magma_output="mlir-verilog", flags=['--assert'], directory=dir_) tester.step(2) # Should pass since count is 3 with tempfile.TemporaryDirectory() as dir_: - tester.compile_and_run("verilator", magma_opts={"inline": True}, + tester.compile_and_run("verilator", magma_output="mlir-verilog", flags=['--assert'], directory=dir_) @@ -176,7 +186,8 @@ class Foo(m.Circuit): with pytest.raises(AssertionError) if not should_pass else nullcontext(): with tempfile.TemporaryDirectory() as dir_: tester.compile_and_run("system-verilog", simulator="ncsim", - magma_opts={"inline": True, "sv": True}, + magma_output="mlir-verilog", + magma_opts={"sv": True}, directory=dir_) diff --git a/tests/test_ready_valid.py b/tests/test_ready_valid.py index afabb4cd..6a6a196f 100644 --- a/tests/test_ready_valid.py +++ b/tests/test_ready_valid.py @@ -1,4 +1,3 @@ -import tempfile from hwtypes import BitVector import magma as m import fault as f @@ -23,9 +22,14 @@ def test_basic_ready_valid_sequence(): pytest.skip("Untested with earlier verilator versions") I = [BitVector.random(8) for _ in range(8)] + [0] O = [0] + [i + 1 for i in I[:-1]] - f.run_ready_valid_test(Main, {"I": I, "O": O}, "verilator", - compile_and_run_kwargs={"tmp_dir": True, - "flags": ['-Wno-UNUSED']}) + f.run_ready_valid_test( + Main, + {"I": I, "O": O}, + "verilator", + compile_and_run_kwargs={'magma_output': 'mlir-verilog', + 'tmp_dir': True, + 'magma_opts': {'flatten_all_tuples': True}} + ) def test_basic_ready_valid_sequence_fail(): @@ -35,10 +39,12 @@ def test_basic_ready_valid_sequence_fail(): O = [0] + [i - 1 for i in I[:-1]] with pytest.raises(AssertionError): f.run_ready_valid_test( - Main, {"I": I, "O": O}, + Main, + {"I": I, "O": O}, "verilator", - compile_and_run_kwargs={"tmp_dir": True, - "flags": ['-Wno-UNUSED']} + compile_and_run_kwargs={'magma_output': 'mlir-verilog', + 'tmp_dir': True, + 'magma_opts': {'flatten_all_tuples': True}} ) @@ -64,9 +70,11 @@ def test_lifted_ready_valid_sequence_simple(): tester = f.ReadyValidTester(Main2, {"I": I, "O": O}) tester.circuit.inc = 2 tester.finish_sequences() - with tempfile.TemporaryDirectory(dir=".") as _dir: - tester.compile_and_run("verilator", disp_type="realtime", - flags=['-Wno-UNUSED'], directory=_dir) + tester.compile_and_run("verilator", disp_type="realtime", + flags=['-Wno-UNUSED'], + magma_output="mlir-verilog", + magma_opts={"flatten_all_tuples": True}, + tmp_dir=True) def test_lifted_ready_valid_sequence_simple_fail(): @@ -83,9 +91,10 @@ def test_lifted_ready_valid_sequence_simple_fail(): tester.circuit.inc = 3 tester.finish_sequences() with pytest.raises(AssertionError): - with tempfile.TemporaryDirectory(dir=".") as _dir: - tester.compile_and_run("verilator", disp_type="realtime", - directory=_dir) + tester.compile_and_run("verilator", disp_type="realtime", + magma_output="mlir-verilog", + magma_opts={"flatten_all_tuples": True}, + tmp_dir=True) def test_lifted_ready_valid_sequence_changing_inc(): @@ -102,6 +111,8 @@ def test_lifted_ready_valid_sequence_changing_inc(): # Advance one cycle to finish last handshake tester.advance_cycle() tester.expect_sequences_finished() - with tempfile.TemporaryDirectory(dir=".") as _dir: - tester.compile_and_run("verilator", disp_type="realtime", - flags=['-Wno-UNUSED'], directory=_dir) + tester.compile_and_run("verilator", disp_type="realtime", + flags=['-Wno-UNUSED'], + magma_output="mlir-verilog", + magma_opts={"flatten_all_tuples": True}, + tmp_dir=True)