Remove property from assert message

Assert macros in prim_assert.sv report the asserted property as part of
the error message if the assertion fails. Doing that requires us to
stringify the property. If the property is multi-line in the source
code, this produces a multi-line string. According to the
SystemVerilog standard, a multi-line string requires a backslash (`\`)
at the end of a line. Adding this backslash through a macro is not
possible (at least to my knowledge), giving us no way to produce a
standards-compliant implementation of the `ASSERT` macros that report
the property as string.

This commit therefore removes the property from the error message if an
assertion fails. It makes these messages less useful, but the
information can still be recovered in a less convenient way through the
name of the assertion, and the file and line numbers. File and line
number were missing from the non-UVM code path before, this commit adds
them there as well.

Fixes #669
This commit is contained in:
Philipp Wagner 2020-03-12 21:46:00 +00:00 committed by Philipp Wagner
parent 80269c82ab
commit 1c82c20132

View file

@ -35,12 +35,12 @@
`define PRIM_STRINGIFY(__x) `"__x`" `define PRIM_STRINGIFY(__x) `"__x`"
// ASSERT_RPT is available to change the reporting mechanism when an assert fails // ASSERT_RPT is available to change the reporting mechanism when an assert fails
`define ASSERT_RPT(__name, __msg) \ `define ASSERT_RPT(__name) \
`ifdef UVM \ `ifdef UVM \
assert_rpt_pkg::assert_rpt($sformatf("[%m] %s: %s (%s:%0d)", \ assert_rpt_pkg::assert_rpt($sformatf("[%m] %s (%s:%0d)", \
__name, __msg, `__FILE__, `__LINE__)); \ __name, `__FILE__, `__LINE__)); \
`else \ `else \
$error("[ASSERT FAILED] [%m] %s: %s", __name, __msg); \ $error("[ASSERT FAILED] [%m] %s (%s:%0d)", __name, `__FILE__, `__LINE__); \
`endif `endif
/////////////////////////////////////// ///////////////////////////////////////
@ -56,7 +56,7 @@
`define ASSERT_I(__name, __prop) \ `define ASSERT_I(__name, __prop) \
`ifdef INC_ASSERT \ `ifdef INC_ASSERT \
__name: assert (__prop) \ __name: assert (__prop) \
else `ASSERT_RPT(`PRIM_STRINGIFY(__name), `PRIM_STRINGIFY(__prop)) \ else `ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
`endif `endif
// Assertion in initial block. Can be used for things like parameter checking. // Assertion in initial block. Can be used for things like parameter checking.
@ -64,7 +64,7 @@
`ifdef INC_ASSERT \ `ifdef INC_ASSERT \
initial \ initial \
__name: assert (__prop) \ __name: assert (__prop) \
else `ASSERT_RPT(`PRIM_STRINGIFY(__name), `PRIM_STRINGIFY(__prop)) \ else `ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
`endif `endif
// Assertion in final block. Can be used for things like queues being empty // Assertion in final block. Can be used for things like queues being empty
@ -74,7 +74,7 @@
`ifdef INC_ASSERT \ `ifdef INC_ASSERT \
final \ final \
__name: assert (__prop || $test$plusargs("disable_assert_final_checks")) \ __name: assert (__prop || $test$plusargs("disable_assert_final_checks")) \
else `ASSERT_RPT(`PRIM_STRINGIFY(__name), `PRIM_STRINGIFY(__prop)) \ else `ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
`endif `endif
// Assert a concurrent property directly. // Assert a concurrent property directly.
@ -82,7 +82,7 @@
`define ASSERT(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \ `define ASSERT(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
`ifdef INC_ASSERT \ `ifdef INC_ASSERT \
__name: assert property (@(posedge __clk) disable iff ((__rst) !== '0) (__prop)) \ __name: assert property (@(posedge __clk) disable iff ((__rst) !== '0) (__prop)) \
else `ASSERT_RPT(`PRIM_STRINGIFY(__name), `PRIM_STRINGIFY(__prop)) \ else `ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
`endif `endif
// Note: Above we use (__rst !== '0) in the disable iff statements instead of // Note: Above we use (__rst !== '0) in the disable iff statements instead of
// (__rst == '1). This properly disables the assertion in cases when reset is X at // (__rst == '1). This properly disables the assertion in cases when reset is X at
@ -93,7 +93,7 @@
`define ASSERT_NEVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \ `define ASSERT_NEVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
`ifdef INC_ASSERT \ `ifdef INC_ASSERT \
__name: assert property (@(posedge __clk) disable iff ((__rst) !== '0) not (__prop)) \ __name: assert property (@(posedge __clk) disable iff ((__rst) !== '0) not (__prop)) \
else `ASSERT_RPT(`PRIM_STRINGIFY(__name), `PRIM_STRINGIFY(__prop)) \ else `ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
`endif `endif
// Assert that signal has a known value (each bit is either '0' or '1') after reset. // Assert that signal has a known value (each bit is either '0' or '1') after reset.
@ -142,14 +142,14 @@
`define ASSUME(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \ `define ASSUME(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \
`ifdef INC_ASSERT \ `ifdef INC_ASSERT \
__name: assume property (@(posedge __clk) disable iff ((__rst) !== '0) (__prop)) \ __name: assume property (@(posedge __clk) disable iff ((__rst) !== '0) (__prop)) \
else begin `ASSERT_RPT(`PRIM_STRINGIFY(__name), `PRIM_STRINGIFY(__prop)) end \ else `ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
`endif `endif
// Assume an immediate property // Assume an immediate property
`define ASSUME_I(__name, __prop) \ `define ASSUME_I(__name, __prop) \
`ifdef INC_ASSERT \ `ifdef INC_ASSERT \
__name: assume (__prop) \ __name: assume (__prop) \
else `ASSERT_RPT(`PRIM_STRINGIFY(__name), `PRIM_STRINGIFY(__prop)) \ else `ASSERT_RPT(`PRIM_STRINGIFY(__name)) \
`endif `endif
////////////////////////////////// //////////////////////////////////