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
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
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?
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.
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
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
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
Queue:
push_back, push_front, pop_back, pop_front, insert, delete, shuffle, revert, size, sort, rsort
Associative array
first, next, prev, last, exists, num
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)
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.
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”
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
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.
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.
task run();
forever begin
wait (queue.size() > 0);
tx = Queue.pop_front();
drive_tx(tx);
end
endtask
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.
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
a == 1 |-> not(antedecent_expression); if a==1 , antedecent_expression should not happen => property is passing
Req-ack-data-resp-eot checkproperty 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
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
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.
int intQ[$];
int intA[9:0];
if (intQ == intA) begin
end
intA = intQ;