程序代写 Microsoft PowerPoint – HW_Verification_Lecture_2

Microsoft PowerPoint – HW_Verification_Lecture_2

Hardware Verification –

Copyright By PowCoder代写 加微信 powcoder

Autumn term 2022

• Effective verification of hardware requires a number of approaches:
• Constrained random unit-level testing on each module of a design
• Directed testing – e.g. running self-testing code on a CPU
• Assertion-based design enables formal verification
• Coverage is needed to measure quality and completeness of testing

• Code coverage
• Functional coverage

• SystemVerilog will be the language used to build a testbench
• SystemVerilog Assertions will be used to write properties

SystemVerilog – a language for verification

• SystemVerilog has some rich features that make it easier to build
testbenches and perform hardware verification

• In this lecture, we will cover:
• Data types
• Procedural statements and routines
• Connecting the testbench to the design

• In the next lecture:
• OOP features
• Randomisation and constrained random verification
• SystemVerilog Assertions (SVAs)

Agenda – Data types

• Built-in data types
• Arrays: fixed, packed, dynamic, associative
• New types with typedef
• User-defined structures
• Enumerated types

Agenda – Procedural Statements and Routines

• Operators and statements that are new for SystemVerilog
• Tasks and Functions
• Routine arguments
• Return statements
• Automatic storage
• Time values

Agenda – Connecting the testbench to the design

• Ports and interfaces
• Modports
• Stimulus timing

• Clocking blocks

• Clock generation
• Connecting the DUT, testbench and interfaces
• Introduction to SystemVerilog assertions

The Logic Type

• Verilog has wire and reg
• SystemVerilog introduces logic
• logic type can be used for any net, unless it has multiple drivers
• Use wire if there are multiple drivers (e.g. for a bidirectional bus)
• logic, wire and reg are 4-state types (0,1,X,Z)

logic clk, rst_n;
logic [31:0] data_in;

wire [31:0] data_in_out;

2-State Data Types

• 2-state types introduced to SystemVerilog
• bit – always unsigned
• byte, shortint, int and longint are signed by default
• But you can cast these to be unsigned

bit flag;
bit [31:0] dataword; 32-bit unsigned integer
int datavalue; 32-bit signed integer
int unsigned u_datavalue; 32-bit unsigned integer
byte databyte; 8-bit signed integer
shortint data16; 16-bit signed integer
longint data64; 64-bit signed integer
real value_of_pi; double-precision floating point

4-State Data Types

integer dataword; 32-bit signed integer
time timestamp; 64-bit unsigned integer

Connecting 2-state types to DUT

• Beware of connecting 2-state types between testbench and DUT
• If output from DUT goes X or Z, testbench won’t know unless you test

• If you do this, test for it with $isunknown()
• Probably best to avoid this!

• Fixed arrays – SystemVerilog allows shortcut of just giving array size
• Unpacked arrays – specify dimensions after variable name
• Arrays can be multi-dimensional
• Initialise arrays with array literal – ‘{initial_values}
• Manipulate arrays with for and foreach
• Use $size to return size of array

int sig_reg [4]; (equivalent to int sig_reg [3:0])
int mem_array [32] [8]; (multi-dimensional array)
sigreg = ‘{3,2,1,0};
sigreg = ‘{4{0}};

Packed Arrays
• Packed arrays – specify dimensions before variable name
• Dimensions must be in [msb:lsb] format, not [size]

bit [7:0] [7:0] word64; // pack 8 bytes into a 64-bit element

Dynamic Arrays
• Use a dynamic array if you don’t know the array size at compile time
• Specify dynamic array with empty subscripts [ ]
• Initially empty so call new[] to allocate space

int array1[];
initial begin
array1 = new[25];
foreach (array1[k]) array1[k] = 1;
array1 = new[75];
array1.delete();

• New for SystemVerilog – combines linked list and array – always dynamic
• Can add or remove elements anywhere in the queue
• Declare queue with subscripts containing ‘$’
• Queue operators: insert, delete, push_front(/back), pop_front(/back)

queue1[$] = {0,1,2,3,4,5,6,7};
queue1.insert(5,9); // insert value 9 before element #5
queue1.delete(7); // delete element #7
queue1.push_front(0); // insert 0 at front of queue
fifo_out = queue1.pop_back; //pop from the end of the queue

Associative Arrays
• Use an associate array if you want to model a large memory but your

data is sparse
• Declare associate array with data type in []
• Get index value with functions: first, next
• Delete elements with delete

int assoc_array[int], index;
initial begin

assoc_array[7] = 0;
if assoc_array.first[index]

$display(“index=%d”, index];

while assoc_array.next[index];

Array Methods
• Array reduction methods: sum, product, and, or, xor
• Array locator methods: min, max, unique
• Find elements in array: find_index with (item…)
• Also find_first, find_last, find_first_index,
find_last_index

• Array sorting: sort, rsort, shuffle, reverse

array_sum = array1.sum();
q2 = q1.min();
q3 = q1.find_index with (item>31);
data1.sort();

User-defined data types
• Define new type with typedef
• Convention is to identify user types with _t suffix, e.g. vec16_t

typedef logic [15:0] vec16_t;
vec16_t operand1, operand2;
typedef bit [31:0] unsigned_int_t;
unsigned_int_t data_width;
typedef byte byte_array_t[8];

User-defined structures
• A struct groups data fields together – use _s suffix
• A struct is not packed by default
• Use typedef to create a new structure type
• Assign values to struct as with an array
• Use a union to store different types in the same location

struct {bit sign, bit[4:0] exponent, bit[9:0] mantissa;} float16;
typedef struct {bit sign, bit[4:0] exponent, bit[9:0] mantissa;} float16_s;
float16_s float_register;
typedef union { bit[15:0] int_value; float16_s float_value; } dpreg_u;
dpreg_u dpreg;

Packed structures
• Both struct and union can be packed
• Can make more efficient use of memory

typedef struct packed {
logic valid;
logic [7:0] addr;

tag_t my_tag;
logic [8:0] vec;
vec = my_tag;
vec[8] = my_tag.valid; vec[7:0] = my_tag.addr; // equivalent to previous line
my_tag = vec;

• A package enables you to share declarations among other building

blocks, like modules
• Import symbols from a package with import statement

package float_types;
parameter int float_width = 16;
typedef logic [15:0] vec16_t;
typedef struct {bit sign, bit[4:0] exponent, bit[9:0] mantissa;} float16_s;

endpackage

module float_test;
import float_types::*;
float_reg float_16_s;

Enumerated Types
• Enumerated types let you create a set of unique but related constants
• Declare with typedef so it can be used for declaring multiple variables
• Values count up from zero by default – but you can declare your own values
• Functions for stepping through enums: first(), last(), next(), next (N), prev, prev(N)

typedef enum {RED, AMBER, GREEN} traffic_light_colours_e; // Take values 0,1,2
typedef enum {RED, AMBER=4, GREEN} traffic_light_colours_e; // Take values 0,4,5

traffic_light_colour_e tr_colour;
tr_colour = tr_colour.first;

• SystemVerilog string holds variable-length strings
• Each element of the string is a byte
• Elements of string of length N are numbered from 0 to N-1
• getc(N) returns byte at location N
• putc(N, char) writes a byte char into string at location N

string str;

initial begin
str = “Imperial College “;
str = {str, “,London”};

Procedural Statements and Routines

• Operators and statements that are new for SystemVerilog
• Tasks and Functions
• Routine arguments
• Return statements
• Automatic storage

New operators and statements
• SystemVerilog adopts many operators and statements from C and C++
• For example:

• Declare a loop variable in a for loop, to restrict its scope
• Auto-increment and auto-decrement operators: ++, —
• Compound assignments: +=, -=, ^=
• Labels can be added to begin/end, fork/join
• Labels can be added to endmodule, endtask, endfunction
• Use continue and break in a loop
• return statement added

begin : new_ops
for (int j=0; j < 5; j++) mem[j] = 0; acc += result; end : new_ops Tasks and Functions • In Verilog, task consumes time, function cannot • In SystemVerilog, a function can call a task – but only using fork..join_none • If you have a SystemVerilog task that does not consume time, you should make it a void function • Any debug routines should be a void function, so that it can be called from any task or function • Cast result of function to void if you want to ignore its return value void’ (myfunction(myval)); Routine arguments • Type and direction of routine arguments can be combined • Default is input logic and is sticky • But don’t rely on this – it’s best to declare all types and directions • Arguments can be passed by reference, using ref • Default values can be used for arguments • Names of arguments can be specified task convert_float_to_int (output logic [31:0] int_value, input logic [31:0] float_single); Automatic Storage • SystemVerilog uses static storage by default for modules and program • Make program blocks and their routines use automatic storage (use the stack), by putting automatic in the program statement • You can then call tasks defined in the program multiple times program automatic my_program(); task check_error (input logic [7:0] error, output logic exception) if (error == ’h39) exception = 1; Connecting the testbench to the design • Ports and interfaces • Modports • Stimulus timing • Clocking blocks • Clock generation • Connecting the DUT, testbench and interfaces • Introduction to SystemVerilog assertions Separating testbench from the design • DUT and testbench in separate modules separates them • SystemVerilog introduces the program block, to separate both logically and temporally • It also introduces the interface, to reduce wiring and timing errors Connect to design with ports • Part of multiplier example – see Exercise 1 module multiplier ( input logic clk, input logic rst_n, input logic req, output logic rdy ); logic busy; assign start = req & rdy; always @(posedge clk or negedge rst_n) if (!rst_n) busy <= 1’b0; else if (start) busy <= 1’b1; Create testbench with ports module multiplier_test ( input logic clk, output logic rst_n, input logic rdy, output logic req ); initial begin rst_n = 0; #100 rst_n = 1; @(posedge clk); @(posedge clk); if (rdy == 1) $display ("rdy is high"); Connect design and testbench with top module module top; logic rdy, req; initial begin forever #100 clk = !clk; multiplier mul1 (clk, rst_n, req, rdy); multiplier_test mul1_test (clk, rst_n, rdy, req); Add an interface to bundle wires together interface mult_if (input bit clk); logic req, rdy, rst; endinterface DUTTESTBENCH Multiplier design with interface module multiplier (mult_if multif); logic busy; assign start = multif.req & multif.rdy; always @(posedge multif.clk or negedge multif.rst_n) if (!multif.rst_n) busy <= 1’b0; else if (start) busy <= 1’b1; Create testbench with interface module multiplier_test (mult_if multif); initial begin multif.rst_n <= 0; #100 multif.rst_n <= 1; @(posedge multif.clk); multif.req <= 1; @(posedge multif.clk); if (multif.rdy == 1) $display ("rdy is high"); Connect design and testbench with interface module top; logic rdy, req; initial begin forever #100 clk = !clk; mult_if multif(clk); // Instantiate the interface multiplier mul1 (multif); // Instantiate the design multiplier_test mul1_test (multif); // Instantiate the testbench Use program for testbench to give temporal separation • Provides entry to test-bench execution • Encapsulates data, tasks and functions program automatic multiplier_test (mult_if multif); initial begin multif.rst_n <= 0; #100 multif.rst_n <= 1; @(posedge multif.clk); multif.req <= 1; @(posedge multif.clk); if (multif.rdy == 1) $display ("rdy is high"); endprogram • The modport in an interface lets you group signals and specify their direction. interface mult_if (input bit clk); logic req, rdy, rst_n; modport TEST (input rdy, clk, output req, rst_n); modport DUT (input req, clk, rst_n, output rdy); endinterface Including modports in modules • Add modport to interface name in module declarations • Top module can stay the same module multiplier (mult_if.DUT multif); module multiplier_test (mult_if.TEST multif); Clocking blocks • Interface should contain a clocking block • It specifies timing of synchronous signals relative to the clock • The signal directions are relative to the modport where they are used interface mult_if (input bit clk); logic req, rdy, rst_n; clocking cb @(posedge clk); input rdy; output req; endclocking modport TEST (output rst_n, clocking cb); modport DUT (input req, clk, rst_n, output rdy); endinterface Using clocking block in a module module multiplier_test (mult_if.TEST multif); initial begin multif.rst_n <= 0; #100 multif.rst_n <= 1; @multif.cb; multif.cb.req <= 1; @multif.cb; wait (multif.cb.rdy == 1); // Wait until rdy goes high $display ("rdy is high"); Introduction to SystemVerilog Assertions (SVA) • Use assertions to check signal behaviour and temporal relationships • Two main types: Immediate and Concurrent Assertions • Immediate - checks that statement is true when it is executed • Concurrent - checks behaviour continuously throughout simulation assert (ack == 1’b0); // Immediate - Checks ack is low at this point in simulation assert (ack == 1’b0) // With error message if assertion fails else $error (“Error: ack not negated”); property check_result; // Concurrent – requires a sampling clock @(posedge clk) disable iff (!rst_n) result == a+b; endproperty assert_check_result: assert property (check_result); Recommended reading • Updated reading list (contains links to on-line versions): • https://imperial.alma.exlibrisgroup.com/leganto/readinglist/lists/39647687740001591?institute=44IMP_INS T&institute=44IMP_INST&fromSaml=true&auth=SAML • SystemVerilog For Verification 3rd Edition, Spear and Tumbush, Springer (online version now available) • SystemVerilog Language Reference Manual (LRM) - Formal Verification – An Essential Toolkit for Modern VLSI Design Seligman, Schubert and • SystemVerilog Assertions (SVA) • Mentor QuestaSim – Help pages within tool • Gold – Help pages within tool Exercises related to Lecture #2 • Access the 3rd Edition of ‘SystemVerilog for Verification’ (Red cover) • Look for the ‘Exercises’ at the end of Chapters 2, 3 and 4 • Do any of these if you want some practice at writing SystemVerilog • If you have problems, you can raise these in the Lab Session • Not assessed Next lecture: SystemVerilog (continued) and more on SystemVerilog Assertions (SVA) Testbench timing issues Introduction to Object-Oriented Programming features Randomisation Principles of unit-level constrained random simulation More details on writing SVAs 程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com