Electronic – How exactly does SystemC/SystemVerilog make the verification flow less laborious task


Now days SystemC or SystemVerilog are used for verification of complex designs, especially for things like SoC designs that are really complex. I do know that these languages bring in the OOP design techniques into the digital IC design domain.

What I don't know is exactly how do they make things easier when it comes to verification. I want to see an example side by side e.g HDL vs SystemC/SystemVerilog. Is there some resource that I can use to understand this?

Best Answer

SystemVerilog included a range of new features intended to improve verification productivity and the most significant are probably:

  1. Object Oriented programming
  2. Constrained randomsation

Functional verification in simulation is entirely a software problem, so by including classes the verification community acquired all of the productivity gains of traditional OO programming (although from ~10 years ago - the lack of reflection and limits of introspection mean that libraries written in SystemVerilog like UVM are massively dependent on the pre-processor rather than the language itself).

By adding constrained randomisation, the language enforces compliant simulators must provide a constrains solver. This allows the testspace to be defined by a set of rules and the simulator to generate test sequences. A classic analogy would be Sudoku, by defining the problem in terms of constrains the simulator can solve the problem rather than the verification engineer having to think of stimulus to exercise the DUT. Typically this makes it possible to hit corner cases that might have been missed with directed testing.

Another improvement in SystemVerilog was the DPI layer, which makes it easier to interface to external languages.

SystemC is a slightly different beast - it can be used for modelling, interfacing to other languages, high-level synthesis etc.

You asked for a comparison of code; I use Python for verification so I don't have any good System[C|Verilog] examples, but Python is an OOP and therefore this example might be useful.

From a testbench I created of the OpenCores JPEG encoder:

def compare(i1, i2):
    Compare the similarity of two images

    From http://rosettacode.org/wiki/Percentage_difference_between_images
    assert i1.mode == i2.mode, "Different kinds of images."
    assert i1.size == i2.size, "Different sizes."

    pairs = izip(i1.getdata(), i2.getdata())
    dif = sum(abs(c1-c2) for p1,p2 in pairs for c1,c2 in zip(p1,p2))
    ncomponents = i1.size[0] * i1.size[1] * 3
    return (dif / 255.0 * 100) / ncomponents

def process_image(dut, filename="", debug=False, threshold=0.22):
    """Run an image file through the jpeg encoder and compare the result"""

    cocotb.fork(Clock(dut.clk, 100).start())

    driver = ImageDriver(dut)
    monitor = JpegMonitor(dut)

    stimulus = Image.open(filename)
    yield driver.send(stimulus)
    output = yield monitor.wait_for_recv()

    if debug: output.save(filename + "_process.jpg")

    difference = compare(stimulus, output)

    dut.log.info("Compressed image differs to original by %f%%" % (difference))

    if difference > threshold:
        raise TestFailure("Resulting image file was too different (%f > %f)" %
                          (difference, threshold))

You can see that the use of a structured testbench and OOP makes this code very understandable and quick to create. There was a pure verilog testbench for this block and although it doesn't have the same level of functionality the comparison is still interesting.