SystemVerilog and Verilog X Optimism – Hardware-like X Propagation with Xprop

In part 2 of this series, SystemVerilog and Verilog X Optimism – What About X Pessimism?, I discussed several coding styles that help to reduce the risk of missing design bugs due to Verilog X optimism. In part 3, we will take a look at how proprietary simulator features help avoid the problem by smartly doing X propagation. Specifically, we will look at Synopsys VCS Xprop.

Like the name suggests, X propagation means propagating an X at the input of some logic to its outputs. Synopsys VCS Xprop can do so smartly, in many cases avoiding X optimism, making simulation behave closer to real hardware.

Xprop has three modes: xmerge, tmerge, and vmerge. Xmerge simply assigns X to outputs whenever any of the inputs are X. This behaviour is similar to what would be observed in gate level simulations, but can sometimes be even more pessimistic. With tmerge, when an input is X, the simulator will traverse both code paths assuming the input is 0 and 1, and compare the results. If the results are the same, the determinate result is assigned to the output. If the results differ, X is assigned to the output to do X propagation. Vermge basically disables Xprop, allowing classic Verilog X optimism.

Consider the if…else statement again from part 1 of the series:

always_ff @(posedge clk) begin
  if (cond)
    c <= a;
  else
    c <= b;
end
MUX21NAND to illustrate xprop

Let’s also add a gate level implementation of this multiplexer for comparison.

The truth table of Xprop Tmerge and Xmerge is as follows. You can see that Tmerge closely resembles actual hardware behaviour (though not always; depending on how the statement is implemented in gates, the last row may return X in gates).

abcondClassic Verilog SimulationGate Level SimulationActual HardwareXprop XmergeXprop Tmerge
00X000X0
01X1X0/1XX
10X0X0/1XX
11X1X1X1

Xprop does similar X propagation on sequential logic with ambiguous clock transitions. Recall from part 1 of this series that Verilog normally treats ambiguous clock transitions as valid clock transitions (for example, 0->1, 0->X, 0->Z, X->1, Z->1 are all considered posedge), which can trigger sequential logic when real hardware may not. With Xprop enabled, an indeterminate clock transition will corrupt the outputs of sequential logic triggered by that clock.

Xprop can be even more useful with low power simulations, where powered off logic will drive X’s on outputs to indicate it is off. One of the ways that unisolated paths can be detected is to ensure these X’s can propagate to somewhere visible by your test environment.

Enabling Xprop takes relatively little effort. You simply need to provide some additional options to VCS, and an Xprop configuration file. The configuration file lists the module name, module hierarchy, or instance name to turn Xprop on or off. From the VCS User Guide:

vcs -xprop[=tmerge|xmerge] [-xprop=xprop_config_file] [-xprop=unifiedInference] source_files

A sample Xprop configuration file is as follows:

merge = tmerge
tree     {testbench}                             {xpropOff}; // marks a module name and its submodules
instance {u_testbench.u_dut_top}                 {xpropOff}; // marks an instance name
instance {u_testbench.u_dut_top.u_subsystem_top} {xpropOn};
module   {my_sram_module}                        {xpropOff}; // marks a module name

In a recent project I worked on, after turning on Xprop and debugging the resulting X’s, two design bugs were immediately found. The first bug was a list of flip-flops without reset that fed into the control path, causing a block to hang and not respond after reset. The block simulated fine without Xprop due to X optimism (in fact, block level verification was already complete). But once Xprop was enabled, it did not respond after reset until all the control path flip-flops were fixed and properly reset. The second bug was an incorrectly coded arbiter that could select an out of range bit out of a bus. Without Xprop, the arbiter returned 0 when the index was out of range of the bus width. With Xprop enabled, the arbiter assigned X to the output when the select became out of range and the bug surfaced.

One caveat when using Xprop is it can falsely score code coverage, as the simulator does in fact execute multiple branches of code when an X input causes divergent code paths. To work around this issue, since Xprop generally catches reset and testbench issues that are pervasive throughout an environment, you may be able to run only a small subset of tests with Xprop enabled to catch X optimism bugs, and collect code coverage with the remaining tests with Xprop disabled. Xprop may also not solve all your X optimism woes. X-Propagation: An Alternative to Gate Level Simulation discusses some false negatives from actual designs that Xprop stumbled on. Lastly, Xprop is not guaranteed to propagate X’s in your entire design and you should take a look at the Xprop reports to see which parts of your design it was able to instrument.

Xprop is a relatively easy way to make Verilog simulations behave closer to actual hardware. Provided that all block verification environments are Xprop clean, you will likely see diminishing returns using it at a cluster or full-chip environment. However, given the relatively low effort to setup and debug Xprop, it is definitely a simulator option that is recommended for any block level verification environment.

What are your experiences with using xprop in your simulations, especially in low power simulations with UPF? Have you found bugs you otherwise wouldn’t have? Leave a comment below!

16 thoughts on “SystemVerilog and Verilog X Optimism – Hardware-like X Propagation with Xprop”

  1. The code coverage issue you describe is probably an oversight in the implementation of the tool. The vendor might fix it if users want it fixed.

    Reply
  2. What is the purpose of XPROP simulations?
    I understand it as a way to setup your gatelevel simulation environment early using the RTL but is it any good to find real bugs in the design? Can you give one example of a bug which can be caught by this activity which otherwise would have been missed?

    Reply
    • I think your comment is that gate level simulation would have found these bugs too, and that xprop is a way for simulator to behave like gate level simulations? Yes I think that is true. Since we can generally get much better coverage and runtime at RTL stage we would like to do everything we can to find bugs at that stage. In the article I listed two examples which are real bugs I found with xprop simulations. One more bug that come to mind is incorrectly gated logic that uses SRAM contents (another personal experience); since SRAMs are uninitialized at beginning of simulation, they output X that can be propagated through logic using xprop. There might be logic that incorrectly uses SRAM contents without waiting for a valid read, and as a result would use the X and cause incorrect behaviour in Silicon. One more usage is you do low power simulations with UPF that involves shutting down power domains, there will be X coming out of powered off logic; xprop is then very useful in detecting missing isolation.

      Reply
  3. how to use xprop?
    i have a demo named test.v,and i type the following command to compile and simulate it.
    #vcs -Xprop=tmerge test.v
    #./simv
    but i cannot get the report for xprop?
    can you give me the details for it?please.thanks.

    Reply
  4. Hi,Jason!

    I gave the SCOPE top.dut.BLK_XXX.ISO_XXX.module_name.

    And I compile srun build-my DE(example peripheral)-lib-xprop.
    And elaborate srun build-my DE(example peripheral)-xprop.

    Then I ran my corresponding test-case.
    Test is passed.

    But I didn’t get any difference b/w normal simulation and xprop simulation.

    Could please tell me where can we observed the difference?

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.