Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When cover #334

Merged
merged 44 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
142c0d1
Update assert to use inline_verilog2
leonardt Nov 15, 2023
c1eee08
Merge branch 'master' into fix-deprecation
leonardt Nov 16, 2023
fa70ff0
Fix style
leonardt Nov 16, 2023
5f53c3c
Update expectation
leonardt Nov 16, 2023
3ce813e
Fix ready_valid tests
leonardt Nov 16, 2023
a8daa1d
Add when support for props
leonardt Nov 16, 2023
f93c1d0
Merge branch 'master' into fix-deprecation
leonardt Nov 21, 2023
d482c64
Merge branch 'fix-deprecation' into when-cover
leonardt Nov 21, 2023
8cd51cd
Update opts
leonardt Nov 21, 2023
1337031
Fix style
leonardt Nov 21, 2023
d49c1a3
Merge branch 'fix-deprecation' into when-cover
leonardt Nov 21, 2023
3456032
Fix import
leonardt Nov 21, 2023
f837bcc
Add verilator version logic
leonardt Nov 21, 2023
5000bca
Merge branch 'master' into fix-deprecation
leonardt Nov 21, 2023
fa88dc8
Merge branch 'fix-deprecation' into when-cover
leonardt Nov 21, 2023
9c668d0
Merge branch 'master' into when-cover
leonardt Nov 21, 2023
728331c
Fix arg
leonardt Nov 21, 2023
ef38db7
Fix comment
leonardt Nov 21, 2023
c9dde86
Use implies logic
leonardt Nov 21, 2023
74301ac
Improve when cond logic
leonardt Nov 21, 2023
14748a0
Fix comment
leonardt Nov 21, 2023
49904c3
Formatting
leonardt Nov 21, 2023
c3bc2cb
Disable initial blocks
leonardt Nov 21, 2023
1dd2098
Fix expectation
leonardt Nov 21, 2023
1030dd9
Try skip compile pattern
leonardt Nov 21, 2023
2c41d09
Fix expectations
leonardt Nov 21, 2023
417d213
Try setting magma opts
leonardt Nov 22, 2023
66e06c9
Add advance_cycle
leonardt Nov 22, 2023
fe6c1c7
Try not instead of ~
leonardt Nov 22, 2023
5d3f906
Try parens
leonardt Nov 25, 2023
e4c8afb
Try different expression
leonardt Nov 27, 2023
1cba67c
Skip parens on inside
leonardt Nov 27, 2023
327fa8c
remove paren logic
leonardt Nov 27, 2023
3c7c291
Remove string wrapper
leonardt Nov 27, 2023
196b73e
Fix decorator
leonardt Nov 28, 2023
c190346
Set J 0
leonardt Nov 28, 2023
8ea24d5
Add decorator
leonardt Nov 28, 2023
451ff4a
Simplify property
leonardt Nov 28, 2023
b5a5b43
Add boolean test
leonardt Nov 28, 2023
b527b50
Fix numeric literal
leonardt Nov 28, 2023
fc202eb
Fix clock logic
leonardt Nov 28, 2023
c5e7649
Revert to use implies
leonardt Nov 28, 2023
e88d916
Fix sequence
leonardt Nov 28, 2023
83b92f4
Remove paren
leonardt Nov 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions fault/assert_immediate.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import magma as m
from magma.when import get_curr_block as get_curr_when_block, no_when
from fault.property import Posedge
from fault.assert_utils import add_compile_guards
from fault.assert_utils import add_compile_guards, get_when_cond


def _make_assert(type_, cond, success_msg=None, failure_msg=None,
severity="error", name=None, compile_guard=None, delay=False):
if (when_cond := get_when_cond()) is not None:
cond = ~when_cond | cond

success_msg_str = ""
if success_msg is not None:
success_msg_str = f" $display(\"{success_msg}\");"
Expand Down Expand Up @@ -62,15 +63,6 @@ def _add_docstr(fn):
@_add_docstr
def assert_immediate(cond, success_msg=None, failure_msg=None, severity="error",
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
with no_when():
when_cond = m.Bit()
when_cond @= 0
when_cond @= 1
cond = ~when_cond | cond

_make_assert("always @(*)", cond, success_msg, failure_msg, severity, name,
compile_guard)

Expand Down
17 changes: 17 additions & 0 deletions fault/assert_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from magma.bit import Bit
from magma.when import get_curr_block as get_curr_when_block, no_when


def add_compile_guards(compile_guard, verilog_str):
if compile_guard is None:
return verilog_str
Expand All @@ -14,3 +18,16 @@ def add_compile_guards(compile_guard, verilog_str):
`endif
"""
return verilog_str


def get_when_cond():
"""If active when cond, return a boolean that is true when the when
condition is true.
"""
if not get_curr_when_block():
return None
with no_when():
when_cond = Bit()
when_cond @= 0
when_cond @= 1
return when_cond
7 changes: 6 additions & 1 deletion fault/property.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from fault.sva import SVAProperty
from fault.expression import Expression, UnaryOp, BinaryOp
from fault.infix import Infix
from fault.assert_utils import add_compile_guards
from fault.assert_utils import add_compile_guards, get_when_cond


class Property:
Expand Down Expand Up @@ -221,6 +221,8 @@ def _compile(self, value):
# Double escape on curly braces since this will run through format
# inside inline_verilog logic
return f"{{{{{contents}}}}}"
if isinstance(value, bool):
return f"1'b{int(value)}"
if isinstance(value, int):
return str(value)
if isinstance(value, BinaryOp):
Expand All @@ -246,6 +248,9 @@ def compile(self, prop):


def _make_statement(statement, prop, on, disable_iff, compile_guard, name):
if (when_cond := get_when_cond()) is not None:
prop = when_cond | implies | prop

format_args = {}
_compiler = _Compiler(format_args)
prop = _compiler.compile(prop)
Expand Down
148 changes: 148 additions & 0 deletions tests/test_property.py
Original file line number Diff line number Diff line change
Expand Up @@ -876,3 +876,151 @@ class Foo(m.Circuit):
assert not should_pass
else:
assert should_pass


@requires_ncsim
def test_cover_when(capsys):
class Main(m.Circuit):
io = m.IO(I=m.In(m.Bit), S=m.In(m.Bit), O=m.Out(m.Bit)) + m.ClockIO()
io.O @= m.Register(T=m.Bit)()(io.I)
with m.when(io.S):
f.cover(io.I | f.delay[1] | ~io.I, on=f.posedge(io.CLK))
with m.otherwise():
f.cover(io.I | f.delay[1] | io.I, on=f.posedge(io.CLK))
tester = f.SynchronousTester(Main, Main.CLK)
tester.circuit.S = 0
tester.circuit.I = 1
tester.advance_cycle()
tester.circuit.I = 1
tester.advance_cycle()
tester.compile_and_run("system-verilog",
simulator="ncsim",
magma_output="mlir-verilog",
flags=["-sv"],
magma_opts={"sv": True,
"disable_initial_blocks": True},
disp_type="realtime",
coverage=True)

out, _ = capsys.readouterr()
assert """\
Disabled Finish Failed Assertion Name
0 0 0 Main_tb.dut.__cover1
0 1 0 Main_tb.dut.__cover2
Total Assertions = 2, Failing Assertions = 0, Unchecked Assertions = 1\
""" in out, out
tester.clear()
tester.circuit.CLK = 0
tester.circuit.S = 0
tester.circuit.I = 1
tester.advance_cycle()
tester.circuit.I = 0
tester.advance_cycle()
tester.compile_and_run("system-verilog", simulator="ncsim",
magma_output="mlir-verilog", flags=["-sv"],
skip_compile=True, disp_type="realtime",
magma_opts={"sv": True,
"disable_initial_blocks": True},
coverage=True)

out, _ = capsys.readouterr()
assert """\
Disabled Finish Failed Assertion Name
0 0 0 Main_tb.dut.__cover1
0 0 0 Main_tb.dut.__cover2
Total Assertions = 2, Failing Assertions = 0, Unchecked Assertions = 2\
""" in out, out
tester.clear()
tester.circuit.CLK = 0
tester.circuit.S = 1
tester.circuit.I = 0
tester.advance_cycle()
tester.circuit.I = 0
tester.advance_cycle()
tester.compile_and_run("system-verilog", simulator="ncsim",
flags=["-sv"], skip_compile=True,
magma_opts={"sv": True,
"disable_initial_blocks": True},
disp_type="realtime", coverage=True)

out, _ = capsys.readouterr()
assert """\
Disabled Finish Failed Assertion Name
0 0 0 Main_tb.dut.__cover1
0 0 0 Main_tb.dut.__cover2
Total Assertions = 2, Failing Assertions = 0, Unchecked Assertions = 2\
""" in out, out
tester.clear()
tester.circuit.CLK = 0
tester.circuit.S = 1
tester.circuit.I = 1
tester.advance_cycle()
tester.circuit.I = 0
tester.advance_cycle()
tester.compile_and_run("system-verilog",
simulator="ncsim",
magma_output="mlir-verilog",
flags=["-sv"],
skip_compile=True,
disp_type="realtime",
magma_opts={"sv": True,
"disable_initial_blocks": True},
coverage=True)

out, _ = capsys.readouterr()
# covered
assert """\
Disabled Finish Failed Assertion Name
0 1 0 Main_tb.dut.__cover1
0 0 0 Main_tb.dut.__cover2
Total Assertions = 2, Failing Assertions = 0, Unchecked Assertions = 1\
""" in out, out


@requires_ncsim
def test_cover_when_true(capsys):
class Main(m.Circuit):
io = m.IO(
I=m.In(m.Bit), J=m.In(m.Bit), S=m.In(m.Bit), O=m.Out(m.Bit)
) + m.ClockIO()
io.O @= m.Register(T=m.Bit)()(io.I)
with m.when(io.S):
f.cover(True, on=f.posedge(io.CLK))
with m.otherwise():
f.cover(True, on=f.posedge(io.CLK))
tester = f.SynchronousTester(Main, Main.CLK)
tester.circuit.S = 0
tester.advance_cycle()
tester.compile_and_run("system-verilog",
simulator="ncsim",
magma_output="mlir-verilog",
flags=["-sv"],
magma_opts={"sv": True,
"disable_initial_blocks": True},
disp_type="realtime",
coverage=True)

out, _ = capsys.readouterr()
assert """\
Disabled Finish Failed Assertion Name
0 0 0 Main_tb.dut.__cover1
0 1 0 Main_tb.dut.__cover2
Total Assertions = 2, Failing Assertions = 0, Unchecked Assertions = 1\
""" in out, out
tester.clear()
tester.circuit.CLK = 0
tester.circuit.S = 1
tester.advance_cycle()
tester.compile_and_run("system-verilog", simulator="ncsim",
flags=["-sv"], skip_compile=True,
magma_opts={"sv": True,
"disable_initial_blocks": True},
disp_type="realtime", coverage=True)

out, _ = capsys.readouterr()
assert """\
Disabled Finish Failed Assertion Name
0 1 0 Main_tb.dut.__cover1
0 0 0 Main_tb.dut.__cover2
Total Assertions = 2, Failing Assertions = 0, Unchecked Assertions = 1\
""" in out, out
Loading