Introduction¶
Property IR is an intermediate representation for temporal properties as specified by SystemVerilog Assertions (SVA). The goal is to support formal verification flows, while decoupling front-end tasks (parsing, name resolution, etc.) from checker circuit synthesis and optimization. This is achieved by providing a unified representation for assertions, automata, and circuits.
This document focuses on the public interface of Property IR, that is, the part relevant to someone who wants to construct Property IR expressions from SVA. We will start with an introduction to the general concept behind Property IR expressions before discussing all features in detail.
Note
The new verification flow based on Property IR is at an early stage of development and currently not yet available. Note that details of this specification might still change throughout the implementation process.
General Concept¶
The syntax of the Property IR expressions is based on s-expressions (symbolic expressions). This is a notation for expressions in the form of nested lists, with the first element of a list representing an operation, and the subsequent elements representing its arguments (each being either atomic or a list again).
(mul 5 (add 2 3))
Note: Example for illustrative purposes only. These operations are not part of Property IR.
The operations of Property IR are called primitives. Each primitive has
a signature, consisting of its argument types
and its return type (or simply type).
Property IR expressions are well-typed, having distinct types for example
for boolean expressions, sequences, and temporal properties
(and internally used types for automata and circuits).
When specifying the signature of primitives in this document, we write
parameters enclosed in angle brackets
(e.g., <clk_seq>), which needs to be replaced by an expression with the correct
type to yield a valid expression.
The (return) type of the first element (or root) of an expression is also the
(return) type of the whole expression.
Consider overlapped implication (clk_seq |-> clk_prop in SVA) as an example primitive.
It expects two arguments having the types clocked sequence (<clk_seq>) and clocked
property (<clk_prop>),
and returns a clocked property (indicated by the prefix clk-prop- of the primitive).
(clk-prop-overlapped-implication <clk_seq> <clk_prop>)
Property IR provides primitives that closely match the operators of SVA, which allows for a direct syntactic translation of elaborated SVA. Note that parameterized sequences and properties can not be represented, and the frontend needs to instantiate them with concrete arguments before they can be translated to Property IR expressions. Let us consider for example the following SystemVerilog property.
property p;
a ##1 b |-> always(c);
endproperty
It corresponds to the following Property IR expression.
(declare p
(clk-prop-overlapped-implication
(clk-seq-concat (clk-seq-bool a) (clk-seq-bool b))
(clk-prop-always (clk-prop-bool c))))
The signals a, b, and c have type bool.
Concatenation (clk-seq-concat) expects arguments of type clk-seq, therefore
clk-seq-bool is used to convert the signals to clocked sequences of length 1.
Similarly, clk-prop-bool converts signal c to a clocked sequence property,
because clk-prop-always requires an argument of type clk-prop.
With declare we can bind expressions to identifiers to reference them later.
Expressions can be regarded as an expression graph, and this is also how they are stored and processed internally. In this graph, the nodes are primitives in the case of internal nodes, and external signals or literals (like integers or ranges) in the case of leaf nodes. The edges are connections between nodes, pointing from primitives as parents to their arguments as children.
expression graph of p¶
Different from the classical s-expressions in the strict sense,
Property IR provides a syntax to represent cycles by naming
and referencing nodes.
Using this feature, recursive properties like the following
(which is equivalent to always(a)) can be expressed.
property always_a;
a and (1'b1 |=> always_a);
endproperty
(declare-rec
(declare always_a
(clk-prop-and
(clk-prop-bool a)
(clk-prop-non-overlapped-implication
(clk-seq-bool (constant true))
always_a))))
expression graph of always_a¶
Similarly, mutually recursive properties can be expressed.
property prop1;
a and (1'b1 |=> prop2);
endproperty
property prop2;
b and (1'b1 |=> prop1);
endproperty
(declare-rec
(declare prop1 (clk-prop-and
(clk-prop-bool a)
(clk-prop-non-overlapped-implication (clk-seq-bool (constant true)) prop2)))
(declare prop2 (clk-prop-and
(clk-prop-bool b)
(clk-prop-non-overlapped-implication (clk-seq-bool (constant true)) prop1))))
expression graph of prop1 and prop2¶
The same syntax will also be used to represent cycles in the automata or checker circuit representations of properties in later steps of the verification flow.
Embedding in Yosys¶
Property IR embeds into RTLIL via a new $property cell that stores
the textual Property IR code in a parameter.
One $property cell may contain several assertions, which enables optimizations
that were otherwise not possible. We call the contents of one $property cell
a Property IR document.
The $property cell takes a parametric number of input bits and produces a
parametric number of output bits.
The meaning of individual bits is declared as part of the embedded
Property IR code and can include:
observed signals of the design as inputs
checker status of properties as outputs
sequence matches as outputs
There are certain SystemVerilog expressions that can be used in SystemVerilog
assertions but can not be represented in Property IR.
This concerns the extended Booleans, including sampled value functions like
$past, $rose etc. and
the matched and triggered functions.
The reason is that Property IR operates on time-variable Booleans,
that is, stateless functions from time to Boolean, whose current value depends only on the current
input values, and not on previous output values.
(An exception is made for the global clocking future sampled value functions,
which can look one global time step into the future and are used to represent clock expressions.)
Note
Future revisions of Property IR might include native support for some of these functions.
Extended Boolean expressions need to be synthesized outside of Property IR, and
the output signals of the synthesized circuits become input signals of the
$property cell. Then they are treated like any other Boolean input inside Property IR.
property prop;
$rose(b) |-> always(a);
endproperty
In this example, let signal rose_b be the output of the circuit that was
synthesized for $rose(b) and becomes an input for a $property cell.
(For simplicity, we omitted the declaration of inputs in previous examples.)
(declare-input a)
(declare-input rose_b)
(declare prop (clk-prop-overlapped-implication (clk-seq-bool rose_b) (clk-prop-bool a)))
Registering properties for FV continues to use the existing $check cell
(or the lower level $assert, $assume, etc. cells).
The synthesis of checker circuits will be done in multiple passes with
intermediate results representable as Property IR.
Note
This revision of Property IR does not include support for local variables yet, but it is planned for future revisions.
Note
The MLIR dialect for RTLIL will be extended to represent Property IR in order to ensure interoperability with CIRCT.