2 questions
- in the system verilog 2012 reference guide there is a reference to coding a sequential logic in an
always_comb
, is this possible since there is no clocking reference for analways_comb
block - as seen here -> [sequential logic inalways_comb
]
- while using system verilog assertion in Synopsys Verdi, is it possible that the green arrow(indicating the asserted property is satisfied) to be fired half or once clock cycle later, after the property being satisfied
Thanks :D
Regarding question 1. non-blocking assignments don't necessarily imply sequential behavior. Blocking/non-blocking assignments are a simulation construct. Let's look at a small example to understand it better:
We have two input signals and two output signals. We want to model a composite gate.
In classical Verilog style, we would write the following:
This means, whenever
a
orb
changes, compute the values ofc
and ofd
. Because we used a blocking assignment forc
, the value we computed here gets "propagated" to the computation ofd
. This essentially means that we've chained the logic described byd
to come after the logic forc
.We can test this using a little testbench:
If we simulate this, we'll get:
This is because the display process triggers once for each change of the variables.
a
gets changed fromx
to1
, butc
haven't been updated yet. Thenc
andd
get updated in the same time step. Later on, we changeb
, but this doesn't trigger any changes onc
ord
. Then, we changea
again and later in the same time slice,d
gets updated.It's a bit redundant to have to specify the sensitivity list, since if we know that we want combinatorial logic, we should re-trigger the process whenever something on the right hand side of an assignment changes. This is what
always_comb
is for.We can re-write our code using
always_comb
, by just getting rid of the sensitivity list:Running this code will lead to the same prints:
Now comes the interesting part. We can model the exact same circuit using
always_comb
and non-blocking assignments:Running this code, though, will produce slightly different prints:
Notice that in the first time step we have 3 prints, instead of one. Let's look closer at what happens here. First, we change
a
, butc
andd
haven't been updated yet. Second,c
gets updated, butd
stays the same. This is because of the non-blocking assignment onc
, leading tod
"seeing" the "old" value ofc
. Third, afterc
was officially updated, the tool schedules an update ond
and we see the last print for the first time step. The rest is the same as in the previous cases.Remember from a previous paragraph that
always_comb
re-triggers whenever something on the right hand side of an assignment changes. The trick here is that thisalways_comb
actually behaves like:This is non-standard Verilog, but would still model the same logic. Notice that
c
has been explicitly added to the sensitivity list. If we omit this, then we'd be describing a latch. This style is discouraged, because it's easy to get wrong (i.e. forget to add intermediate logic nodes to the sensitivity list).The key takeaway point here is that blocking or non-blocking assignments don't either describe sequential or combinatorial logic. It's the entire context (i.e. the sensitivity lists that determine when they get executed) that controls what logic circuit gets inferred from the code.
The full code example is available on EDAPlayground.
Regarding question 2. this is tool specific and this isn't the forum for this. You should ask this on the vendor's website.