1. How System Verilog differs from Verilog?
    1. Verilog is a HDL, which makes it more suitable only for design RTL coding.
    1. SV is HDVL, which has constructs for TB development also.
      1. SV has both static and dynamic data types, which results in better memory efficiency

SV has more constructs like OOP, interface, various types of array, FC, assertions, which makes it easy to develop the test bench

Write SV code to initialize below array elements with random
number between 200 to 300

  1. int intA[2:0][3:0]
  2. logic [4:0][5:0] array [7:0];

module top;
int intA[2:0][3:0]
logic [4:0][5:0] array [7:0];

initial begin
foreach (intA[i,j]) begin //2 stages of for or foreach is also posisble
intA[i][j] = $urandom_range(200,300);
end
foreach (array[i,j]) begin //2 stages of for or foreach is also posisble
array[i][j] = $urandom_range(200, 300);
end
end

endmodule
Explain difference between

  1. byte and bit [7:0]
  2. int and integer

byte is signed data type
bit [7:0] unsinged data type

byte a;
bit [7:0] b;
a = -20;
b = -20;
a will hold negative number, b will store it as +number(236)

int is 2 stage data type, with defautl value of 0
integer is 4 stage data type, with defautl value of x
Define a function which takes two integer array’s as input and output
is an integer array which is index wise sum of both the array
elements.

function array_sum (input integer intA1[5:0], input integer intA2[5:0], output integer intO[5:0]);
for (i = 0 ; i < 6; i++) begin
intO[i] = intA1[i] + intA2[i];
end
endfunction
What is the difference of running elaboration with -novopt and without this option?

  1. Explain with examples

only whole array assignment and compare operations can be performed.

int intA1[5:0];
int intA2[5:0];

intA1 = intA2;
if (intA1 == intA2) begin
end
Declare a dynamic array of byte data type.

  1. Allocate 10 elements
  2. Assign each element with index value.
  3. Increase the size of array to 20 while preserving the existing 10
    elements.

module top;
byte byteDA[];

initial begin
byteDA = new[10];
foreach (byteDA[i]) begin
byteDA[i] = i;
end
byteDA = new20;
end
endmodule
Declare array of Queues of apb_tx

  1. Populate array with 4 Queues
  2. Each Queue having 5 transactions.
  3. Print all the transactions content in a foreach loop.

module top;
apb_tx apb_txAQ[3:0][$:4];
apb_tx tx;
initial begin
foreach (apb_txAQ[i]) begin
for (int j = 0; j < 5; j++) begin
tx = new();
tx.randomize();
apb_txAQ[i][j] = new tx; //shallow copy
end
end
//now Queue is populated, we can write foreach on both array and Queue
foreach (apb_txAQ[i,j]) begin
apb_txAQ[i][j].print(); //apb_tx has print method
end
end
endmodule
Implement parameterized class which can be used as both FIFO and
Stack

  1. Same class having a parameter by name stack_fifo_f
  2. Stack_fifo_f = 1 => class acts like a stack, else like a fifo
  3. Hint: Declare Queue with its methods

class stack_fifo #(type DT=int, bit stack_fifo_f = 1);
DT dtQ[$];

function void put(DT t);
dtQ.push_back(t);
endfunction

function void get(output DT t);
if (stack_fifo_f == 1) begin
t = dtQ.pop_back();
end
else begin
t = dtQ.pop_front();
end
endfunction
endclass

  1. List down all built in methods of Queue and associative array.

Queue:
push_back, push_front, pop_back, pop_front, insert, delete, shuffle, revert, size, sort, rsort
Associative array
first, next, prev, last, exists, num

  1. Declare Queue of int data type with maximum size of 15
    int intQ[$:14];
    Explain the difference between function in Verilog and Systemverilog

function in SV:

Declare a 2Kb size memory of depth 64 locations, each memory
element of size 16 bits.

module top;
bit [15:0] memory [63:0];
//2Kb => 2*1024 = 2048 bits => 2048/64 = 32
bit [31:0] memory [63:0];
endmodule

Write a task named memory_initialize to assign 0’s to all
memory locations.

task memory_initialize();
for (i = 0; i < 64; i++) begin
memory[i] = 0;
end
endtask
Declare a dynamic array of integer data type, populate with 10
random values, Write a logic to reverse the contents of Dynamic
array by using Queue.

integer intDA[];
integer intQ[$];
initial begin
intDA = new[10];
foreach (intDA[i]) begin
intDA[i] = $random;
end
//logic to reverse
intQ = intDA;
intQ.reverse();
intDA = intQ;
end
Explain difference between === and ==? Operator using simple
example?

=== : case equality operator, this compare all 0, 1, x and z as they are. comapre x to x and z to z, hence output is only eitehr 0 or 1
==? : wild equality operator, if the variable in RHS of comparision has any ‘x’ or ‘z’, that position will not be compared, whereas if the variable on the LHS has x or z, output will be ‘x’

if (a ==? b) => if b has ‘x’ or ‘z’, those positions are not compared
if (a ==? b) => if a has ‘x’ or ‘z’, Output is ‘x’
Write a pack function to pack the fields of ethernet packet in Queue
of half word(16 bits)

  1. Packet fields: preamble, sof, da, sa, len, payload and crc

typedef bit [15:0] halfword_t;
function void pack(output halfword_t hwQ[$]);
hwQ = {halfword_t>>{preamble, sof, da, sa, len, payload, crc}};
endfunction
/*
Declare two strings name1 and name2, assign then “system” and
“Verilog” respectively. Write a logic to get below pattern.

  1. VSeyrsitleomg (do not directly assign value to new string)
  2. Hint: Use getc and insert methods of string.
    */

module top;

string name1, name2, name3;
byte b, b1;
string str, str1;
initial begin
name1 = “system”;
name2 = “verilog”;

for (int i = 0 ;  i < 7; i++) begin
    b = name1.getc(i);
    b1 = name2.getc(i);
    str = string'(b);
    str1 = string'(b1);
    $display("str=%s",str);
    $display("str1=%s",str1);
    name3.putc(str1[0], 2*i);
    name3.putc(str[0], 2*i+1);
end
$display("name3=%s",name3);

end
endmodule
Explain difference between signed shift and unsigned right shift
operators using an example

int a, b;
a=-60;
b=-60;
a >>= 2;
b >>>= 2;

a will not hold – value(it will not be -15)
b will hold – value(it will be -15)
List down few reasons why we prefer using conditional operator compared to if else statements.

conditional operator
– results in concise description of the required code
– it can be used in both procedural and continous assign statements

if-else:
– generally longer code
– it can be only used in procedural statements
/*
Write a System Verilog code to assign string pattern of “name1” to
nameN”

  1. N is an integer
  2. Hint: use $sformat
    */

module top;
parameter N=10;
string name;
initial begin
for (int i = 0; i < N; i++) begin
$sformat(name, “name%0d”,i+1);
$display(“name=%s”,name);
end
end
endmodule
Implement deep copy method for ethernet packet

  1. Packet fields: preamble, sof, da, sa, len, payload and crc

function void copy(eth_pkt pkt);
pkt = new this;

//
pkt.preamble = preamble;
pkt.sof = sof;
pkt.da = da;
pkt.sa = sa;
pkt.len = len;
pkt.payload = payload;
pkt.crc = crc;

endfunction
/*
Explain difference between passing argument by ref and by value.
1.ref Illustrate using an example

*/

module top;
int a, b;
function automatic pass_ref(ref int count);
count = count + 1;
endfunction
function void pass_val(int count);
count = count + 1;
endfunction

initial begin
a = 15;
b = 15;
pass_ref(a);
$display(“a=%d”,a);
pass_val(b);
$display(“b=%d”,b);
end
endmodule

/*
2.Write a function to generate a 10 random floating number between 1
to 2 to the 2-point decimal and print them using $display

*/

module top;
real r;
initial begin
repeat(10) begin
r = $urandom_range(100,200)/100.0;
$display(“r=%f”,r);
end
end
endmodule
/*
23.Read image from hex file, load it in to a memory, read back image
from memory and store it in binary format in to another image file.

  1. Make assumption about image file and memory
    */

module top;
byte mem[31:0];
initial begin
$readmemh(“image.hex”, mem);
$writememb(“image.bin”, mem);
end
endmodule
/*
Write logic to parse testname(string) and count(integer) from
command line arguments
*/
module top;
string testname;
integer count;

initial begin
$value$plusargs(“testname=%s”,testname);
$value$plusargs(“count=%d”,count);
$display(“testname=%s,count=%d”,testname,count);
end
endmodule

/*
Implement req ##[3:5] ack ##[4:5] addr ##[5:6] resp==2’b11; using
fork join
*/
module top;
initial begin
forever begin
@(posedge clk);
if (req == 1) begin
repeat(3) @(posedge clk);
fork : P1
begin
repeat(2) @(posedge clk);
$display(“ERROR: ACk did not come in 5 clock cycles”);
end
begin
if (ack == 1) begin
repeat(4) @(posedge clk);
fork : P2
begin
repeat(1) @(posedge clk);
$display(“ERROR: Addr is 0”);
end
begin
if (addr != 0) begin
repeat(5) @(posedge clk);
fork : P3
begin
repeat(1) @(posedge clk);
$display(“ERROR: resp is not 2’b11”);
end
begin
if (resp == 2’b11) begin
$display(“CHECK PASSED”);
end
end
join_any
disable P3;
end
end
join_any
disable P2;
end
end
join_any
disable P1;
end
end
endmodule
26.List down practical use cases of fork join_none. Illustrate using an example.
o fork join_none is used for acheiving out of order tx driving or overlapping tx driving behavior

task run();
forever begin
mbox.get(tx);
fork
drive_tx(tx);
#200; //some delay so that all txs are not driven at same time
join_none
end
endtask
27.Write a logic to use Queue instead of mailbox for Generator to BFM
connection.

  1. Implement BFM run task

task run();
forever begin
wait (queue.size() > 0);
tx = Queue.pop_front();
drive_tx(tx);
end
endtask

  1. Explain practical usage of below interface elements
  2. Modport
  3. Clocking block
  4. Physical and virtual interface

Modport:
o these are used for giving sense of direction to the interface signals
o they can be used in correspoding blocks of the testbench based on how the signals needs to be driven or sampled

clocking block:
o they have input and output skew, which ensure that signals are driven and smapled with proper skew values to avoid the race condition related to signals driving and sampling

Physical and virtual interface
o physical interface is used in top module to allocate the memory to the interface instiantion
o virtual interface is used in other TB components, to ensure that there is no memory allocated and it is just pointing to the physical itnerface memory
/*
Write a constraint to generate a queue of random size with unique
value, and each value being divisible by 3 and 7 both, also size of
queue can be 15 at maximum and minimum of 5.
*/

class sample;
rand int intQ[$];

constraint Queue_c {
intQ.size() inside {[5:15]};
unique {intQ};
foreach (intQ[i]) {
intQ[i] % 3 == 0;
intQ[i] % 7 == 0;
intQ[i] inside {[100:500]};
}
}
endclass

module top;
sample s = new();
initial begin
assert(s.randomize());
$display(“intQ=%p”,s.intQ);
end
endmodule
Write a randcase based code to generate different types of
packets(eth_large, eth_medium, and eth_small) with user defined
weightage, it is being passed on elaboration argument.

  1. Generate a total of 20 packets, each having len field declared
    as integer.

class eth_large extends eth_pkt;
rand int len;
constraint len_c {len > 1000 ; len < 2000;};
endclass

eth_large l_pkt;
eth_med m_pkt;
eth_small s_pkt;

initial begin
$display(“pkt_large=%d”,pkt_large);
$display(“pkt_med=%d”,pkt_med);
$display(“pkt_small=%d”,pkt_small);
repeat(20) begin
randcase
pkt_large: begin //pkt_large/(total)
l_pkt = new();
assert(l_pkt.randomize());
mbox.put(l_pkt);
end
pkt_med: begin //pkt_med/total
m_pkt = new();
assert(m_pkt.randomize());
mbox.put(m_pkt);
end
pkt_small: begin
s_pkt = new();
assert(s_pkt.randomize());
mbox.put(s_pkt);
end
endcase
end
end

vsim work.top +pkt_large=7 +pkt_med=2 +pkt_small=1
vsim work.top +pkt_large=10 +pkt_med=0 +pkt_small=0
vsim work.top +pkt_large=0 +pkt_med=1 +pkt_small=0
Illustrate expression coverage(part of code coverage) using a
complex expression.

initial begin
a = bc + de – f;
//expression coverage will do coverage all possible combinations for RHS expression.
//possible values of b, c, d, e, f
//it indicates what cases, a is getting updated
end
List down assertions for Asynchronous FIFO and implement the
assertions.

a. FIFO is full, write should not be done
b. FIFO is empty, read should not be done
c. FIFO error should never happen
d. FIFO wr=1, wdata should be valid
e. FIFO rd=1, rdata should be valid after 1 clock cycle
f. Full and empty should never be ‘1’ at same time

.Explain below constructs in property(assertion) definition

  1. Iff
    to make sure that assertion gets checked only if specific condition is true
    iff (a ==1) => only if a=1, then proepryty gets checked
  2. Overlapping and non-overlapping implication operators
    o overlapping implicaiton: consequnt gets checked in the same clock cycle where antecednt beame true
    o non-overlapping implicaiton: consequnt gets checked in the next clock cycle where antecednt beame true
  3. not
    o used to check that antecendet should not happen
    not(antedecent_expression) a == 1 |-> not(antedecent_expression); if a==1 , antedecent_expression should not happen => property is passing Req-ack-data-resp-eot check
  4. req is given
  5. slave should give ack in 1 to 3 clocks
  6. master should give data within 5 cycles after ack is received
  7. slave should give responds exactly 4 clock after data is
    collected
  8. after resp is collected by master, it should of a signal called
    EOT=1 within 1 to 2 clock
  9. In above what is antecedent?
  10. What is consequent?

property prop_req;
@(posedge clk) req |-> ##[1:3] ack ##[0:5] ~$isunknown(data) ##4 resp ##[1:2] eot == 1;
endproperty
Write a property to check if a given clock (pclk) is running at
100Mhz

`timescale 1ns/1ns
property clk_freq_p;
time t;
@(posedge clk) (1, t=$time) |=> ($time-t == 10); //10ns => 100Mhz
//antecednt -> consequent
//if antecednt is true, only then consequent is checked
//antecednt=1 => 1 is true => antecednt is always in true in above example
//we want consequent to be checked in every clock edge
//t will capture current clock edge time
//|=> non overlapping => consequent will be checked in the next clock cycle edge
endproperty
assert property (clk_freq_p);
monitor: main class
ref_model: callback class

class monitor;
task run(mon_cb cb);
cb.pre_run();
//functioality
cb.post_run();
endtask
endclass

class ref_model extends mob_cb;
task pre_run();
endtask
task post_run();
endtask
endclass

Explain find, find_index using an array example.

int intA[9:0];

//to find all elements which are divisble by 5
outQ = intA.find(item) with (item%5 == 0); //it gives values
outQ = intA.find_index(item) with (item%5 == 0); //it gives index of those vlaues

Declare a queue of integers

  1. Fill Queue with 20 unique elements with values between 100 to
    200
  2. Easiest way to do this is using sample class with Queue
    declared in it.
  3. Find all the elements whose values is greater than 150
  4. Find their index also
  5. FInd all the elements whose values is between 120 to 170
  6. Find their index also
  7. find all elements in array, which are multiple of ‘5’

class sample;
rand int intQ[$];

constraint intQ_c {
intQ.size() == 20;
unique {intQ};
foreach (intQ[i]) {
intQ[i] inside {[100:200]};
}
}
endclass

intQo = intQ.find(item) with (item > 150);
intQo = intQ.find_index(item) with (item > 150);
intQo = intQ.find(item) with (item > 120 && item < 170);
intQo = intQ.find(item) with (item % 5 == 0);

Array reduction methods

  1. Declare an integer array with size 8
  2. Get the sum of all the elements in array
  3. Get the product of all the elements in array

integer intA[7:0];
sum = intA.sum();
prod = intA.product();
Write a logic to compare Queue of integers with array of integers,
both are size 10.

  1. Write smallest possible code.
  2. Also copy logic to copy Queue elements to the array

int intQ[$];
int intA[9:0];

if (intQ == intA) begin
end
intA = intQ;

Course Registration