Verilog Simulation & Debugging Toolsmedia.ee.ntu.edu.tw/Crash_course/2019/RTL_verification.pdfThe...

Post on 09-May-2020

13 views 0 download

Transcript of Verilog Simulation & Debugging Toolsmedia.ee.ntu.edu.tw/Crash_course/2019/RTL_verification.pdfThe...

Verilog Simulation

Tools &Verification

Outline

NC-Verilog

nLint

nWave

Nicotb

2

NC-Verilog

3

Introduction to NC-Verilog

The Cadence® NC-Verilog® simulator is a Verilog digital

logic simulator.

We can use NC-Verilog to

Compiles the Verilog source files.

Elaborates the design and generates a simulation snapshot.

Simulates the snapshot.

4

Before Using NC-Verilog

Source the environment settings of CAD tools.

If you try entering the command "ncverilog" but it turns

out "command not found," it means there's something

wrong with the "*.cshrc" file or the software license is out

of date.

tool 2

5

source /usr/cad/cadence/CIC/incisiv.cshrc

Running Verilog

Run the Verilog simulation:

"+access+r" is added to enable waveform file dumping.

*.fsdb has smaller file size than *.vcd. But $fsdbDumpfile

cannot work without sourcing verdi.cshrc.

6

ncverilog testbench.v design.v +access+r

or

Simulation Results

Check the simulation result to see if the Verilog design is

finished correctly.

7

nLint

8

Introduction to nLint

nLint is a comprehensive HDL design rule checker fully

integrated with the Debussy debugging system

(Developed by SpringSoft).

We can use nLint to check the coding style of our design

and if it is synthesizable.

9

Start nLint

Type the following command:

The token "&" enable you to use the terminal while nLint is

running in the background.

No gui command

10

nLint -gui &

Just ignore this warning.

nLint design.sv -sv -out screen

Specify the Design File

11

1

12

1

2

3

4

5

Start Checking

13

1

14

Not all the warnings or errors are valuable.

nWave

15

Introduction to nWave

nWave is one of the best waveform (*.vcd or *.fsdb)

viewer.

We can debug easily by checking the waveform file

dumped during simulation.

16

Start nWave

Type the following command:

Also, the token "&" enable you to use the terminal while

Verdi is running in the background.

17

nWave &

Just ignore this warning.

Open the FSDB File

18

1

19

1

2

3

Choose Signals

20

1

21

Choose signals we

are interested in.

1

2

3 4

Browse the Whole Waveform

22

1

Browse the Specified Interval

23

press & drag

24

Search for Specified Signal

25

1

2 34,5,…

26

cursor position

(Search by rising oe)

Jump to the cursor position (Used when we are lost)

Change Sign Representation

27

1

2

3

Change Radix Representation

28

2

1

3

4

Leading zeros

29

Change Signal Position

30

1

2

Press middle mouse button,

drag and then drop.

Signal Aliasing

31

1

2

3

4

32

1

2

3

Note that signal aliasing is a strict one-to-

one correspondence so the value

represented in the viewer must exactly

represent what format your filter expects.

(e.g., binary, hexadecimal)

6

4

5

33

Reload the Waveform

Remember to reload the waveform whenever finishing

another Verilog simulation.

Shift+L

34

1

Nicotb

35

UVM (Universal Verfication Methodology).

(We usually call this overall platform as testbench.)

What Forms Verification?

36

https://verificationacademy.comGenerate Golden Data Your RTL

Drive data to input ports

Monitor output ports and collect data

The non-RTL parts can be implemented without Verilog!

This is usuallyed called co-simulation (co-sim).

The Non-RTL Parts

37

Instantiate (make a copy of) your module.

Driver to send data.

Monitor to receive and collect them.

Driver and Monitor might follow specific protocols.

The collected data are compared by Scoreboard.

Golden (Mostly text file in Verilog, or programmatically when co-simed.)

Generated by your RTL module and collected by Monitor.

Brief Conclusions - A Testbench Must

38

Verilog provide external C accesses through VPI.

https://en.wikipedia.org/wiki/Verilog_Procedural_Interface

Based on C, people develops Java, Python... versions.

AFAIK, there are quite a lot Python based frameworks.

myhdl: https://github.com/myhdl/myhdl

cocotb: https://github.com/potentialventures/cocotb

nicotb: https://github.com/johnjohnlin/nicotb

No Need for Verify RTL with Verilog

39

We focus on this today.

Bridging Python and Verilog (Events)

Add these lines in Python

○ rst_out_ev, ck_ev = CreateEvents(["rst_out", "ck_ev",])

Add this lines in Verilog

○ `Pos(rst_out, rst)`PosIf(ck_ev, clk, rst)

This means, whenever a clk posedge in Python, ck_ev is triggered

Mostly your submodules use 1 reset and clock and you just copy it.

That is,

Python yield ck_ev = Verilog @posedge clk

However, simply writing yield in Python doesn't make thing easier.

We will explain later.

40

Bridging Python and Verilog (Wires)

● API to connect Verilog wires

○ my_data_bus = CreateBus((

("", "a_signal", (4,2)),

("dut", "sig"),

))

The Verilog to be connected

○ logic [7:0] a_signal [4][2];

DUT my_dut(

.clk(clk),

.sig(sig)

)

41

hierarchy: toplevel → ""

name: a_signal

shape: (4,2)

Bridging Python and Verilog (Wires)

API to connect Verilog wires

○ my_data_bus = CreateBus((

("", "a_signal", (4,2)),

("dut", "sig"),

))

The Verilog to be connected

○ logic [7:0] a_signal [4][2];

DUT dut(

.clk(clk),

.sig(sig)

)

42

hierarchy: "dut" (nested: "dut.a.b")

name: sig

shape: not a array

Some Notes

Make use of Python unpack easily.

a = CreateBus(A)b = CreateBus(B)c = CreateBus(C)a, b, c = CreateBuses([A, B, C])

● This is the method of Nicotb, every framework has its method connecting

Verilog to Python (or whatever).

43

For example, your code:

○ module Dut(

input clk,

input rst,

input irdy,

output logic iack,

input [10:0] iint,

output logic ordy,

input oack,

output logic [10:0] oint

);

You can test every module with the same API.

Interface Reuse → Testbench Reuse

44

DutInput Output

Dataflow graph.

First, you need to create the buses

irdy = CreateBus((("dut", "irdy")))iack = CreateBus((("dut", "iack")))iint = CreateBus((("dut", "iint")))ordy = CreateBus((("dut", "ordy")))oack = CreateBus((("dut", "oack")))oint = CreateBus((("dut", "oint")))

Then, construct the classes in Python.

master = TwoWire.Master(irdy, iack, iint, ck_ev, A=1, B=5)slave = TwoWire.Slave(

ordy, oack, oint, ck_ev, callbacks=[test.Get])

Convert Bus into Protocol

45

Generate golden data for Scoreboard (not today's main issue).

Ns = np.array([0,8,7], dtype=np.int32)# this create a column vector [0, 0, 1, 2, ..., 8, 0, 1, ..., 7]golden = np.concatenate([

np.arange(N+1, dtype=np.int32) for N in Ns])[:,np.newaxis]test.Expect((golden,))

What should I Expect?

Check at Scoreboard

46

Look at the data bus.

ordy = CreateBus((("dut", "ordy")))oack = CreateBus((("dut", "oack")))oint = CreateBus((("dut", "oint")))

Slave put that to Scoreboard.

st = Stacker(1+9+8, [bg.Get]) # PS: 1+9+8+=18bg = BusGetter(callbacks=[st.Get])slave = TwoWire.Slave(

ordy, oack, oint, ck_ev, callbacks=[bg.Get])

oint is a bus with one scalar (aka, not an array), so you get a tuple of size ([18,

1],).

Data Format in Nicotb

47

The actual code is slightly more

complex than above pages, while

you can just copy and modify.

Look at the data bus.

oint = CreateBus((("dut", "aaa")("dut", "bbb", (1,))("dut", "ccc", (12,3))

))

In this example, the tuple size is ([18, 1], [18, 1], [18, 12, 3]).

Data Format in Nicotb

48

Look at the data bus.

golden = np.concatenate([np.arange(N+1, dtype=np.int32) for N in Ns

])[:,np.newaxis]test.Expect((golden,))

golden is a tuple of size ([18, 1],).

np.concatenate generate a array of size [18,], namely a row vector.

The [:, np.newaxis] is the standard method converting Numpy row vector to a

column vector (vertical one).

Back to Our Example

49

Prepare the RTL for design under test (DUT).

Script for loading Python automatically (Makefile).

SystemVerilog wrapper.

Python testbench.

Prepare input data and golden (it's your task).

Send the data.

Check the data at scoreboard.

We are Almost Done!

50

OO

O

OX

O

OX

O O

O

Drive Verilog Wire In Python (Quite Easy!)

master = TwoWire.Master(irdy, iack, iint, ck_ev, A=1, B=5)values = master.valuesdef it():

for N in Ns:values.iint[0] = Nyield values

yield from master.SendIter(it())

yield from master.SendIter(it(), latency=100)

51

Access data bus by name

values.iint is a Numpy array of size (1,)

This randomly drive the input.

This drive data every 100 cycles.

Probability = A/B (default = 1/5)

Note

values = master.valuesdef it():

for N in Ns:values.iint[0] = Nyield values

yield from master.SendIter(it())yield from master.SendIter(it(), latency=100)

52

This part is only Python generator syntax,

it has no relationship with waiting Verilog

posedge!!!

Every 100 cycles (ignore probability)

Prepare a Verilog Wrapper

`Pos(rst_out, rst)`PosIf(ck_ev, clk, rst)

always #1 clk = ~clk;initial begin

clk = 0;rst = 1;#1 $NicotbInit();#11 rst = 0;#10 rst = 1;#1000 $display("Timeout");$NicotbFinal();$finish;

end

assign oack = ordy && ocanack;Dut dut(clk,rst,irdy,iack,iint,ordy,oack,oint);

53

Declare your module here!

While you might not understand it,

this template requires almost no

modifications!

Declare your module here!

(Prepare a Makefile)

NICOTB=~/nicotb/libIRUN=/opt/CAD/INCISIV/cur/tools.lnx86/bin/64bit/irun

%: %.svGLOG_logtostderr=1 \TEST=$(if $(TEST),$(TEST),$@) \TOPMODULE=$(if $(TOPMODULE),$(TOPMODULE),$@) \PYTHONPATH=$(NICOTB)/python:`pwd` \$(IRUN) +access+rw -loadvpi $(NICOTB)/cpp/nicotb.so:VpiBoot \$(NICOTB)/verilog/Utils.sv $<

54

Modify according to your path

(irun = ncverilog)

You must prepare XXX_test.py and XXX_test.sv under current directory

(see previous pages). Also, the top level testbench module is XXX_test.

Then, just type make XXX. The lab in these days is an example.

● Introduce the idea behind SystemVerilog UVM.

With Python, you can do the same thing much easily.

We introduce Nicotb today.

Document: https://johnjohnlin.github.io/nicotb/

And there are many choices.

myhdl: https://github.com/myhdl/myhdl

cocotb: https://github.com/potentialventures/cocotb

Conclusions

55

The End