Which scope are continuous assignments and primitive instances with scheduled # 0

All #0

related code examples I found are related to procedural code (IE code inside begin

- end

). How about continuous jobs and primitive instances? IEEE 1364 and IEEE 1800 (Verilog and SystemVerilog respectively) give only one line description that I can find (quoted from the entire IEEE 1364 version under the heading "Stratified Event Queue"):

Explicit zero latency ( #0

) requires the process to be paused and added as an inactive event during the current time, so that the process resumes at the next simulation cycle at the current time.

I read the docs and spoke to several engineers who worked with Verilog long before IEEE Std 1364-1995. Thus, the inactive region was unsuccessful for synchronizing triggers with undefined processing order by Verilog. Verilog later created non-blocking assignments ( <=

) and allowed synchronization with undefined order. The inactive region remained in the scheduler to avoid breaking legacy code and a few obscure edge cases. Modern guides recommend avoiding the use of#0

because it creates race conditions and can impede simulation. The performance impact doesn't care about small projects. I am running huge projects that are mixed RTL with transistor level modules. So even small performance gains add up and don't have to debug race conditions - these are time savers.

I ran a test file by removing / adding #0

to Verilog primitives on large scale projects. Some simulators have noticeable changes, others have not. It's hard to say who is better at LRM or has a smarter optimizer.

Adding a compile script to remove hardcoded forms #0

is straightforward enough. The challenge is parameterized delay. Do I need to create generation blocks to avoid an inactive region? It looks like this might cause more problems than it solves:

generate
  if ( RISE > 0 || FALL > 0)
    tranif1 #(RISE,FALL) ipassgate ( D, S, G );
  else
    tranif1              ipassgate ( D, S, G );
  if ( RISE > 0 || FALL > 0 || DECAY > 0)
    cmos #(RISE,FALL,DECAY) i1 ( out, in, NG, PG );
  else
    cmos                    i1 ( out, in, NG, PG );
  if (DELAY > 0)
    assign #(DELAY) io = drive ? data : 'z;
  else
    assign          io = drive ? data : 'z;
endgenerate

      

The original Verilog primitives and continuous assignments have been with Verilog since the beginning. I believe the parameterized delay was longer than the inactive region. I haven't found any documentation to recommend or explain these terms. My local network guru Verilog / SystemVerilog doesn't know what area it should work in. Is there some detail we all ignore, or is it a gray area in this language? If it is a gray area, how to determine how it is being implanted?

The accepted answer must reference any version of IEEE1364 or IEEE1800. Or at least a way to demonstrate concept testing.

+3


source to share


1 answer


It's easy. Section 28.16 Shutter and 1800 LRM reticle delays and section 7.14. Gate delays and LRM 1364-2005 networks say:

For both gates and networks, the default delay should be zero when no delay is given. So this means

gateName instanceName (pins);

      

is equivalent to writing

gateName #0 instanceName (pins);

      



I'm not sure where the text you quoted came from, but section 4.4.2.3. The area of โ€‹โ€‹inactive events in 1800 LRM says

If events run on a set of hotspots, explicit # 0 latency control requires the process to be suspended and the events are scheduled to the Inactive region of the current time slot so that the process can be resumed in the next Inactive to Active iteration.

Key text delay control

, which is a procedural construct. Thus, # 0 as an inactive event only applies to procedural statements.

The problem with procedural #0

is that they move race conditions, they don't eliminate them. Sometimes you need to add some # 0 serial numbers to get away from a race condition, but you don't always know how many, because another piece of code also adds # 0. Just look at the UVM code; it was lying around with dirty # 0 because they didn't take the time to encode correctly.

+4


source







All Articles