Advertisement

Concurrent Assertions: Basics (Sequence, Property, Assert)

Chapter

Abstract

These are temporal domain assertions that allow creation of complex sequences using clock (sampling) edge based semantics. This is in contrast to the immediate assertions that are purely combinatorial and do not allow temporal domain sequences.

Keywords

Design Module Property Module Internal Signal Formal Argument Implication Operator 
These keywords were added by machine and not by the authors. This process is experimental and the keywords may be updated as the learning algorithm improves.

These are temporal domain assertions that allow creation of complex sequences using clock (sampling) edge based semantics. This is in contrast to the immediate assertions that are purely combinatorial and do not allow temporal domain sequences.

Concurrent assertions are the gist of SVA language. They are called concurrent because they execute in parallel with the rest of the design logic. Let us start with basics and move onto the complex concepts of concurrent assertions.

Let us first learn the basic syntax of a concurrent assertion and then study it’s semantics.

In Fig. 4.1 we have declared a property ‘pr1’ and asserted it with a label ‘reqGnt’ (label is optional but highly recommended). The figure explains various parts of a concurrent assertion including a property; a sequence and assertion of the property.
Fig. 4.1

Concurrent assertion—basics

The ‘assert property (pr1)’ statement triggers property ‘pr1’. ‘pr1’ in turn waits for the antecedent ‘cStart’ to be true at a (posedge clk) and on it being true implies (fires) a sequence called ‘sr1’. ‘sr1’ checks to see that ‘req’ is high when it is fired and that 2 ‘clocks’ later ‘gnt’ is true. If this temporal domain condition is satisfied then the sequence ‘sr1’ will PASS and so will property ‘pr1’ and the ‘assert property’ will be a PASS as well. Let us continue with this example and study other key semantics.

As explained in Fig. 4.2, following are the basic and mandatory parts of an assertion. Each of these features will be further explored as we move along.
  1. (1)

    ‘assert’—you have to assert a property; i.e., invoke or trigger it.

     
  2. (2)

    There is an action block associated with either the pass or fail of the assertion

     
  3. (3)

    ‘property pr1’ is edge triggered on posedge of clk (more on the fact that you must have a sampling edge for trigger is explained further on).

     
  4. (4)

    ‘property pr1’ has an antecedent which is a signal called cStart, which if sampled high (in the preponed region) on the posedge clk, will imply that the consequent (sequence sr1) be executed.

     
  5. (5)

    Sequence sr1 samples ‘req’ to see if it is high exactly at the time it was triggered (i.e., the same posedge of clk when the sequence was triggered because of the overlapping implication operator) and then waits for 2 clks and sees if ‘gnt’ is high.

     
  6. (6)

    Note that each of ‘cStart’, ‘req’, ‘gnt’ are sampled at the edge specified in the property which is the posedge of ‘clk’. In other words, even though there is no edge specified in the sequence, the edge is inherited from property pr1.

     
Fig. 4.2

Concurrent assertion—sampling edge and action blocks

Note also that we are using the notion of sampling the values at posedge clk which means that the ‘posedge clk’ is the ‘sampling edge’. In other words, the sampling edge can be anything (as long as it’s an edge and not level sensitive), meaning it does not necessarily have to be a synchronous edge such as a clock. It can be an asynchronous edge as well. However, be very careful about using an asynchronous edge unless you are sure what you want to achieve. I have devoted a complete example on the pitfalls of using an asynchronous edge as the sampling edge. It’s too soon to get into. This is a very important concept in concurrent assertions and should be well understood. However, do not worry, you will get much more insight as we move further.

Now, let us slightly modify the sequence ‘sr1’ to highlight boolean expression in a sequence or a property and study some more key elements of a concurrent assertion.

As shown in Fig. 4.3 there are three main parts of the expression that determines when an assertion will fire, what will it do once fired and time duration between the firing event and execution event.
Fig. 4.3

Concurrent assertion—implication, antecedent and consequent

The condition under which an assertion will be fired is called an ‘antecedent.’ This is the LHS of the implication operator.

RHS of the assertion that executes once the antecedent matches is called the ‘consequent

The ‘implication’ operator determines the time duration that will lapse between the antecedent and the consequent. In other words, the implication operator ties the antecedent and the consequent in one of two ways. It ties them with an ‘overlapping’ implication operator or a ‘non-overlapping’ implication operator. The way to ‘read’ the implication operator is “if there is a match on the antecedent that the consequent will be executed. If there is no match, consequent will not fire and the assertion will continue to wait for a match on the antecedent”.

Figure 4.4 further explains the antecedent and consequent. As shown, you donot have to have a sequence in order to model a property. If the logic to execute in consequent is simple enough then it can be declared directly in consequent as shown. But please note that it is always best to break down a property into smaller sequences to model complex properties/sequences. Hence, consider this example only as describing the semantics of the language. Practice should be to divide and conquer. You will see many examples, which seem very complex to start with, but once you break them down into smaller chunks of logic and model them with smaller sequences, tying all those together will be much easier then writing one long complex assertion sequence.
Fig. 4.4

Property with an embedded sequence

4.1 Implication Operator, Antecedent and Consequent

Implication operator ties the antecedent and consequent. If antecedent holds true it implies that the consequent should hold true.

There are two types of implication operators as shown in Fig. 4.5.
  1. (1)
    Overlapping Implication Operator: Referring to Fig. 4.5, the top most property shows the use of an overlapping operator. Note its symbol (|->), which differs from that of the non-overlapping operator (|=>). Overlapping means that when the antecedent is found to be true, that the consequent will start it is execution (evaluation) the ‘same’ clk. As shown in the figure, when cStart is sampled High at posedge of clk that the req is required to be High at the ‘same’ posedge clk. This is shown in the timing diagram associated with the property.
    1. a.

      So, what happens if ‘req’ is sampled true at the next posedge clk after the antecedent (and false before that)? Will the overlapping property pass?

       
     
  2. (2)
    Non-Overlapping Implication Operator: In contrast, non-overlapping means that when the antecedent is found to be true that the consequent should start it is execution, one clk later. This is shown in the timing diagram associated with the property.
    1. a.

      So, what happens if ‘req’ is sampled true at the same posedge clk as the antecedent (and False after that)? Will the non-overlapping property pass?

       
     
Fig. 4.5

Implication operator—overlapping and non-overlapping

Answer to both 1.a and 2.a is NO.

Figure 4.6 further shows the equivalence between overlapping and non-overlapping operators. ‘|=>’ is equivalent to ‘|-> ##1’. Note that ##1 is not the same as Verilog’s #1 delay. ##1 means one clock edge (sampling edge). Hence ‘|-> ##1’ means the same as ‘|=>’.
Fig. 4.6

Equivalence between overlapping and non-overlapping implication operators

Suggestion: To make debugging easier and have project wide uniformity, use the overlapping operator in your assertions. Reason? Overlapping is the common denominator of the two types of operator. You can always model non-overlapping from overlapping and but you cannot do vice versa. What this means is that during debug everyone would know that all the properties are modeled using overlapping and that the # of clocks are exactly the same as specified in the property. You do not have to add or subtract from the # of clocks specified in the chip specification. More important, if everyone uses his or her favorite operator, debugging would be very messy not knowing which property uses which operator.

4.2 Clocking Basics

As mentioned before, a concurrent assertion is evaluated only on the occurrence of an ‘edge’, known as the ‘sampling edge’. The reason for continually mentioning this ‘edge’ as ‘clk’ is because it is best to have this ‘edge’ synchronous to either posedge or negedge for a signal. You can indeed have an asynchronous edge as well. BUT be very careful. I have devoted a complete example precisely to explain how an assertion with an asynchronous edge works. It gets—very—complicated and I highly discourage you from writing one unless you are absolutely sure you know what you are doing. In Fig. 4.7, we are using a non-overlapping implication operator, which means that at a posedge of clk if cStart is high, then one clock later sr1 should be executed.
Fig. 4.7

Clocking basics

Let us revisit ‘sampling’ of variables. The expression variables cStart, req and gnt are all sampled in the preponed region of posedge clk. In other words, if (e.g.) cStart = 1 and posedge clk changed at the same time, the sampled value of cStart in the preponed region will be equal to ‘zero’ and not ‘one’. We will soon discuss what ‘preponed region’ really means in a simulation time tick and how it affects the evaluation of an assertion, especially when the sampling edge and the sampled variable change at the same time.

Note again that ‘sequence sr1’ does not have a clock in its expression. The clock for ‘sequence sr1’ is inherited from the ‘property pr1’. This is explained next using Fig. 4.8.
Fig. 4.8

Clocking basics—clock in ‘assert’, ‘property’ and ‘sequence’

As explained in Fig. 4.8, the ‘clk’ as an edge can be specified either directly in the assert statement or in the property or in the sequence. Regardless of where it is declared, it will be inherited by the entire assertion (i.e. the assert, property and sequence blocks).

Suggestion: As noted in the Fig. 4.8, my recommendation is to specify the ‘clk’ in a property. Reason being you can keep sequences void of sampling edge (i.e., ‘clk’) and thus make them reusable. The sampling edge can change in the property but sequence (or cascaded sequences) remain untouched and can change their logic without worrying about the sampling edge. Note that it is also more readable when the sampling edge ‘clk’ is declared just before the antecedent in a property. “At posedge of clk, if cStart is high, trigger sr1”.

4.3 Sampling Edge (Clock Edge) Value: How are Assertions Evaluated in a Simulation Time Tick?

How does the so-called sampling edge sample the variables in a property or a sequence is one of the most important concept you need to understand when designing assertions. As shown in Fig. 4.9 the important thing to note is that the variables used in assertions (property/sequence/expression) are sampled in the ‘preponed’ region. What does that mean? It means (for example) if a sampled variable changes the same time as the sampling edge (e.g. clk) that the value of the variable will be the value it held—before—the clock edge.
Fig. 4.9

Assertions variable sampling and evaluation/execution in a simulation time tick

@ (posedge clk) a |=> !a;

In the above sequence, let us say that variable ‘a’ changes to ‘1’ the same time that the sampling edge clock goes posedge clk (and assume ‘a’ was ‘0’ before it went to a ‘1’). Will there be a match of the antecedent ‘a’? No! Since a’ went from ‘0’ to ‘1’ the same time that clock went posedge clk, the value of ‘a’ sampled by clock will be ‘0’ (preponed region) and not ‘1’. This will not cause the property to trigger because the antecedent is not evaluated to be true. This will confuse you during debug. You would expect ‘1’ to be sampled and the property triggered thereof. However, you will get just the opposite result.

This is a very important point to understand because in a simulation waveform (or for that matter with Verilog $monitor or $strobe) you will see a ‘1’ on ‘a’ with posedge clk and would not understand why the property did not fire or why it failed (or passed for that matter). Always remember that at the sampling edge, the ‘previous’ value (i.e. a delta before the sampling edge in the preponed region) of the sampled variable is used.

Here is a complete example including the test-bench and comments that explain how sampling of variables in the preponed region affects assertion results.
  • module assert1;

  • reg A, B, C, D, clk;

  • property ab;
    • @ (posedge clk) !A |-> B;

  • endproperty

  • aba: assert property (ab) else $display($stime,,, “ab FAIL”);

  • abc: cover property (ab) $display($stime,,, “ab PASS”);

  • initial begin
    • clk = 0; A = 0; B = 0; //Note: A and B are equal to ‘0’ at time 0.

    • forever #10 clk = !clk;

  • end

  • initial begin

  • `ifdef PASS

  • /* Following sequence of events will cause property ‘ab’ to PASS because even though A = 0 and B = 1 change simultaneously they had settled down because of #1 before posedge clk. Hence when @ (posedge clk) samples A, B; A = 0 and B = 1 are sampled. The property antecedent ‘!A’ is evaluated to be true and at that same time (overlapping operator) B == 1. Hence the property passes */

  • A = 0;

  • B = 1;

  • #1;

  • @ (posedge clk)

  • `else

  • /* Following sequence of events will cause property ‘ab’ to FAIL. Here’s the story. A = 0 and B = 1 change at the same time as posedge clk. This causes the sampled value of B to be equal to ‘0’ and not ‘1’ because the sampling edge (posedge clk) samples the variable values in the preponed region and B was equal to ‘0’ in the preponed region. Note that A was equal to ‘0’ in the preponed region because of its initialization in the ‘initial’ block above. So, now you have both ‘A’ and ‘B’ == 0. Since A is 0, !A is true and the property evaluation takes place. Property expects B == 1 the same time (overlapping operator) that !A is true. However, ‘B’s sampled value is ‘0’ and the property fails. */

  • @ (posedge clk)
    • A = 0;

    • B = 1;

  • `endif
    • @ (negedge clk)

    • $finish(2);

  • end

  • endmodule

4.3.1 Default Clocking Block

For a long chain of properties and sequences in the file, you can also use the default clocking block as explained in the Fig. 4.10. The figure is self-explanatory in the different ways in which clocking block can be declared and the scope in which it is effective. The top block of the figure shows declaration of ‘default clocking cb1’ which is then inherited by the properties ‘checkReqGnt’ and ‘checkBusGrant’ that follow. This default clocking block will be in effect until another default clocking block is defined. The bottom part of the figure is interesting. Here the properties are directly embedded in the default clocking block. I donot recommend doing that though. The clocking block should only contain clock specifications, which will keep it modular and reusable. Use your judgment call wisely on such issues.
Fig. 4.10

Default clocking block

Figure 4.11 declares two clocking blocks, namely ‘cb1’ and ‘cb2’ in a standalone Verilog module called ‘design_clocks’. This is a great way to organize your clocking strategy in one module. Once defined, you can use any of the clocking block that is required simply by referring to it by its hierarchical instance name as shown in the figure.
Fig. 4.11

‘Clocking’ and ‘default clocking’

Here is some food for thought. I have outlined a couple of pros and cons of using a default-clocking block. It is mostly advantageous but there are some caveats.

Pros: The argument towards default block is reusability. You may change the clocking relation in the default block and it will be applicable to all the following blocks. You do not have to individually change clocking scheme in each property. This is indeed a true advantage and if you plan to change the clocking scheme in the default block without affecting the properties that follow, do use the default block by all means.

Cons: Readability/debuggability: When you see a property without any sampling edge, you have to scroll back to ‘someplace’ above the property to see what sampling edge is being used. You have to find the very preceding clocking block and cannot just go to the top of the file. I like properties that are mostly self-contained with the sampling edge. Sure, it is a bit more typing but a lot more readable.

4.3.2 Gated Clk

Figure 4.12 shows an interesting modeling application of using a gated clk as the sampling edge for a property. Note that assign is out of the scope of assertion. But it is assigned value ‘clkstart’ can indeed be used in the property. In general, any variable declared in a given scope in which the property/sequence is defined is available to the assertion. If the assertions are declared out of the module but bound to the module using ‘bind’ method, the same rule applies. More on ‘bind’ statement coming up soon.
Fig. 4.12

Gated clock

In this example, the sampling edge will be the posedge of (clk && cGate). In the preponed region of this sampling edge, the variables in property and sequence will be sampled.

4.4 Concurrent Assertions are Multi-Threaded

This is about the most important concept you need to grasp when it comes to concurrent assertions. We all know SystemVerilog is a concurrent language but is it multi-threaded (except when auto variables are used)? SVA is by default concurrent and multi-threaded.

In Fig. 4.13, we have declared the same assertion that you have seen before, namely at posedge clk, if cStart is sampled high that sr1 will be triggered at the same posedge clk which will then look for ‘req’ to be high at that clock and ‘gnt’ to be sampled high two clocks later.
Fig. 4.13

Multi-threaded concurrent assertions

Now, let us say that cStart is sampled high (S1) at a posedge of clk and that ‘req’ is also sampled high at that same edge. After this posedge clk, the sequence will wait for 2 clocks to see if ‘gnt’ is high.

But before the two clocks are over, clk cStart goes low and then goes high (S2) exactly two clocks after it was sampled high. This is also the same edge when our first trigger of assertion will look for gnt to be high (S1). So, what will the assertion do? Will it re-fire itself because it meets its antecedent condition (S2) and ignore ‘gnt’ that it is been waiting for from the first trigger (S1)? No, it will not ignore ‘gnt’. It will sample ‘gnt’ to be high (S1) and consider the first trigger (cStart (S1)) to PASS. So, what happens to the second trigger (cStart (S2))? It will start another thread. It will again wait for 2 clocks to check for ‘gnt’. So far so good. We see one instance of SVA being threaded.

But life just got more interesting.

After S2, the very next clock cStart is sampled high again (S3). And ‘req’ is high as well (req(S3)). Now what will the assertion do? Well, S3 will thread itself with S2. In other words, there are now two distinct triggers of the same assertions waiting to sample ‘gnt’ two clocks after their trigger. The figure perfectly (!) lines up ‘gnt’ to be high two clocks after both S2 as well as after S3 and all 3 triggers of the same assertions will PASS.

This has many implications in terms of design of assertions and performance thereof. We will discuss this further when we discuss edge triggered antecedent. In other words, the way the property in our example is coded, it will drag your simulation performance because every time the property sees cStart to be high at posedge of clk, it will start a new thread. But if you want to evaluate the property only at the first rise of cStart and then ignore it if it stays high (unless it goes low and goes high again) then you have to use edge sensitive antecedent. More on this in  Chap. 5. In addition, the concept of multi-threaded language gets much more interesting as you will see in  Sect. 6.2.1.

4.5 Formal Arguments

One of the key features of assertions is that they can be parameterized. In other words, assertions can be designed with formal arguments to keep them generic enough for use with different actual arguments.

Figure 4.14 is self-explanatory. Notice that the formal arguments can be specified in a sequence, in a property as well as in the assert statement.
Fig. 4.14

Formal and actual arguments

The application shows the advantage of formal arguments in reusability. Property ‘noChangeSig’ has 3 formal arguments, namely pclk, refSig and Sig. The property checks to see that if refSig is sampled high at posedge pclk, that the Sig is not unknown. Once such a generic property is written you can invoke it with different clk, different refSig and Sig. CheckRd is a property that uses sysClk and OE_ and RdData to check for unknown condition while CheckWr uses WE_ and WrData to check for WrData to be not unknown.

In any project, there are generic properties that can be reused multiple times by passing different actual arguments. This is reusable not only in the same project but also among projects.

Companies have created libraries of such pool of properties that projects look up and reuse according to their needs.

As shown in Fig. 4.15, properties can be both position based as well as name based. I highly recommend name based to make sure that actuals are connected to correct formals without ambiguity. This rule is the same as that we have been using for Verilog port connections.
Fig. 4.15

Formal and actual arguments—default value and name based connection

Figure 4.16 describes the following points
  1. (1)
    Default values can be assigned to the formal arguments.
    1. a.

      If actual and formal both specify a ‘default’ value, the actual will overwrite the formal default value

       
    2. b.

      You may leave passing an actual to a formal if the formal has a default value. Please refer to Fig. 4.16.

       
     
Fig. 4.16

Formal and actual arguments—default value and position based connection

This is a very interesting feature and very useful at that for reusability. A formal can be used for event control as well. A sampling edge can be passed as an actual to a formal and the actual can be used as a sampling edge in the property. We are passing ‘posedge clk’ as an actual to the formal ‘csig’. The property uses @ (csig) as it is sampling edge. ‘@ (csig)’ will change to ‘@ (posedge clk)’ when the property ‘pr1’ is called with ‘posedge clk’ as the actual argument. Please refer to Fig. 4.17 for clarity on this point. Such properties can indeed be part of a common pool of properties that individual projects can reuse with their own sampling edge specification.
Fig. 4.17

Passing event control to a formal

4.6 Disable (Property) Operator: ‘disable iff’

Of course, you need a way to disable a property under conditions when the circuit is not stable (think Reset). That is exactly what ‘disable iff’ operator does. It allows you to explicitly disable the property under a given condition. Note that ‘disable iff’ reads as ‘disable if and only if’. The example in Fig. 4.18 shows how you can disable an assertion during an active Reset. There is a good chance you will use this Reset based disable method in all your properties throughout the project. Note below the rules governing ‘disable iff’
  1. (1)

    ‘disable iff’ can be used only in a property—not a sequence.

     
  2. (2)

    ‘disable iff’ can only be used before the declaration of the antecedent condition.

     
Fig. 4.18

‘disable iff’ operator

Ok, so what happens if a property has started executing and the ‘disable iff’ condition occurs in the middle of its execution?

The property in Fig. 4.18 checks to see that sdack_ falls (i.e. contained) within soe_ (donot worry, we will see how such properties work in later chapters). It also has the ‘disable iff (! reset)’ condition. Disable this property if reset is asserted (active low).

Let us examine the simulations logs.

In the LHS simulation log, reset is never asserted and the assertion completes (and passes in this case).

In the RHS simulation block, reset is asserted in the middle of check “sdack_ within soe”. Guess what, the entire assertion is discarded. You will not see pass/fail for this assertion because it has been discarded. Entire assertion is disabled if the disable iff condition occurs in the middle of an executing assertion. Some folks mistake such discard as a failure, which is incorrect.

Once an assertion has been disabled with ‘disable iff’ construct, it will re-start only after the ‘disable iff’ condition is not true anymore.

As we will discuss in  Sect. 7.4, there are system tasks that provide global control over execution of assertions.

4.7 Severity Levels (for Both Concurrent and Immediate Assertions)

Assertions also allow error reporting with different severity levels. $fatal, $error (default), $warning and $info. Figure 4.19 explains meaning of each.
Fig. 4.19

Severity levels for concurrent and immediate assertions

$error is default, meaning if no failure clause is specified in the assert statement, $error will kick in and provide a simulator generated error message. If you have specified a label (and you should have) to the assertion, that will be (most likely) displayed in the $error message. I say most likely because the SystemVerilog LRM does not specify exact format of $error. It is simulator vendor specific. $warning and $info are self-explanatory as described in the Fig. 4.19.

4.8 Binding Properties

‘bind’ allow us to keep design logic separate from the assertion logic. Design managers do not like to see anything in RTL that is not going to be synthesized. ‘bind’ helps in that direction.

There are three modules in Fig. 4.20. The ‘designModule’ contains the design. The ‘propertyModule’ contains the assertions/properties that operate on the logic in ‘designModule’. And the ‘test_bindProperty’ module binds the propertyModule to the designModule. By doing so, we have kept the properties of the ‘propertyModule’ separate from the ‘designModule’. That is the idea behind ‘bind’. You do not have to place properties in the same module as the design module. As mentioned before, you should keep your design void of all constructs that are non-synthesizable. In addition, keeping assertions and design in separate modules allow both the design and the DV engineers work in parallel without restrictions of a database management system where a file cannot be modified by two engineers at the same time.
Fig. 4.20

Binding properties

In order for ‘bind’ to work, you have to declare either the instance name or the module name of the designModule in the ‘bind’ statement. You need the design module/instance name, property module name and the ‘bind’ instance name for ‘bind’ to work. In our case the design module name is designModule, its instance name is ‘dM’ and the property module name is propertyModule.

The (uncommented) ‘bind’ statement uses the module instance ‘dM’ and binds it to the property module ‘propertyModule’ and gives this ‘bind’ an instance name ‘dpM’. It connects the ports of propertyModule with those of the designModule. With this the ‘property rc1’ in propertyModule will act on designModule ports as connected.

The commented ‘bind’ statement uses the module name ‘designModule’ to bind to the ‘propertyModule’ whereby all instanced of the ‘designModule’ will be bound to the ‘propertyModule’.

In essence, we have kept the properties/assertions of the design and the logic of the design separate. This is the recommended methodology. You could achieve the same results by putting properties in the same module as the design module but that is highly non-modular and intrusive methodology. In addition, as noted above, keeping them separate allows both the DV and the Design engineer to work in parallel.

4.8.1 Binding Properties (Scope Visibility)

But what if you want to bind the assertions of the propertyModule to internal signals of the designModule? That is quite doable.

As shown in Fig. 4.21, ‘rda’ and ‘rdb’ are signals internal to designModule. These are the signals that you want to use in your assertions in the ‘propertyModule’. Hence, you need to make ‘rda’ and ‘rdb’ visible to the ‘propertyModule’. However, you do not want to bring ‘designModule’ internal variables to external ports in order to make them visible to the ‘propertyModule’. You want to keep the ‘designModule’ completely untouched. To do that, you need to add input ports to the ‘propertyModule’ and bind those to the internal signals of the ‘designModule’ as shown in Fig. 4.21. Note that in our example we bind the propertyModule ports ‘pa’ and ‘pb’ to the designModule internal registers ‘rda’ and ‘rdb’. In other words, you can directly refer to the internal signals of designModule during ‘bind’. ‘bind’ has complete scope visibility into the bound module ‘designModule’. Note that with this method you do not have to provide the entire hierarchical instance name when binding to ‘propertyModule’ input ports.
Fig. 4.21

Binding properties to design ‘module’ internal signals (scope visibility)

4.8.2 Assertion Adoption in Existing Design

Figure 4.22 shows that if you have an existing design, you can effectively use the ‘bind’ construct to write assertions outside of the design scope and bind them. This can be very useful, if you are bringing in legacy blocks in your new SoC and want to make sure that the legacy blocks work well in your new design. This figure is a methodology component. Upfront in your project, determine your ‘bind’ methodology. See that all the assertions are outside RTL and not a messy mix of some in RTL and some bound with external properties file.
Fig. 4.22

Binding properties to an existing design. Assertions adoption in existing design

Other advantage of keeping assertions in a separate file is that they can be independently verified without the need to have control of RTL files. A big advantage when you want to make sure that both the design and verification progress in parallel.

4.9 Difference Between ‘sequence’ and ‘property’

Now that we have seen assertions using sequences and properties, it is good to recap and clearly understand the differences between the two.
  • ‘sequence
    • A sequence is a building block. Think of it as a macro or a subroutine where you can define a specific relationship for a given set of signals.

    • A sequence on its own does not trigger. It must be asserted.

    • A sequence does not allow implication operator. Simply allows temporal (or combinatorial) domain relationship between signals.

    • A sequence can have optional formal arguments.

    • A clocking event can be used in a sequence.

    • A sequence can be declared in a module, an interface, a program, a clocking block, a package (but –not- in aclass’).

  • ‘property
    • A property also does not trigger by itself until ‘assert’ed (or ‘cover’ed).

    • Properties have implication operator that imply the relationship between an antecedent and a consequent.

    • Sequences can be used as building blocks of complex properties.

    • Clocking event can be applied in a property, in a sequence, or in both.

    • A property can be declared in a module, an interface, a program, a clocking block, a package (but –not- in aclass’).

Copyright information

© Springer Science+Business Media New York 2014

Authors and Affiliations

  1. 1.Los GatosUSA

Personalised recommendations