Learning Path
Type of DUT signals
Global Signal - initial block is extremely useful
⇒ Will be utilised in testbench block(stimulus generation)
⇒ rest others will be utilised in the verification environment
Format of Initial Block in Testbench
⇒ Testbench module do not have ay input and output ports.
⇒ initial start execution at 0nsec (can have single or multiple statements) ⇒ reg holds the value
`timescale 1ns/1ps
module tb;
reg a = 0;
initial a = 1;
initial begin
a = 1;
#10;
a = 0;
endmodule
Usage of Initial Block
module tb();
///global signal clk, rst
reg clk; //defining a variable
reg rst;
reg[3:0] temp; //generating random waveform for muliple signal
initial begin //1. initialising a GLOBAL variable
clk = 1'b0; //generating a single bit value which 0 in binary format
rst = 1'b0;
end
//2. Random signal for data/ control
initial begin
rst = 1'b1;
#30;
rst = 1'b0;
end
initial begin
temp = 4'b0100; //4 Bits of temp
#10;
temp = 4'b1100;
#10;
temp = 4'b0011;
#10;
end
//3. System Task at the start of simulation
initial begin //as a control statement
$dumpfile("dump.vcd");
$dumpvars;
end
//send the values on console whenever there are changes in the value
//4. Analyzing values of variable on console
initial begin
$monitor("Temp : %0d at time: %0t", temp, $time);
end
//5. Stop simulation by forcefully calling $finish
initial begin
#200;
$finish();
end
endmodule
⇒ Initialized Variable ⇒ Generate Reset Signal ⇒ Executing System Task
Format of always block
'timescale 1ns / 1ps
module tb();
always@() // always_comb(combinational), always_ff(sequential), always_latch(latch)
// for testbench code, it's always
always statement;
always begin
..................
..................
..................
end
endmodule
y = a & b , Comb ⇒ all inputs, Sequential ⇒ Clock
always@(a,b) always@(posedge clk)
Usage of always block
`timescale 1ns/1ps
module tb();
reg clk; //x
reg rst;
reg clk50 = 0;
reg clk25 = 0;
initial begin
clk = 1'b0;
rst = 1'b0;
clk50 = 0;
end
always #5 clk = ~clk; //100 Mhz
always #10 clk50 = ~clk50; //50 Mhz
always #20 clk25 = ~clk25; //25 Mhz
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
initial begin
#200;
$finish();
end
endmodule
⇒ Generate Clock Signal
Aligning reference of the generated clock and reference clock
`timescale 1ns/1ps
module tb();
reg clk; //x
reg rst;
reg clk50 = 0;
reg clk25 = 0;
initial begin
clk = 1'b0;
rst = 1'b0;
clk50 = 0;
end
/*
always #5 clk = ~clk; //100 Mhz
always #10 clk50 = ~clk50; //50 Mhz
always #20 clk25 = ~clk25; //25 Mhz
*/
always #5 clk = ~clk;
always begin
#5;
clk50 = 1;
#10;
clk50 = 0;
#5;
end
always begin
#5;
clk25 = 1;
#20;
clk25 = 0;
#15;
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
initial begin
#200;
$finish();
end
endmodule
⇒ Both have their edge aligned
Understanding ‘timescale directive
`timescale 1ns / 1ns //1 -> 10^0
// 10^3 -> 1
module tb();
reg clk16 = 0;
reg clk8 = 0; //initialize variable
always #31.25 clk16 = clk16;
always #62.5 clk8 = ~clk8;
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
initial begin
#200
$finish();
end
endmodule
Understanding parameters for generating Clock
`timescale 1ns/ 1ps
module tb();
reg clk = 0;
reg clk50 = 0;
always #5 clk = ~clk //100 Mhz
real phase = 10;
real ton = 5;
real toff = 5;
initial begin
#phase;
while(1) begin
clk50 = 1;
#ton;
clk50 = 0;
#toff;
end
end
initial begin
#200;
$finish();
end
endmodule
Another way using task
`timescale 1ns/ 1ps
module tb();
reg clk = 0;
reg clk50 = 0;
always #5 clk = ~clk //100 Mhz
/*
real phase = 10;
real ton = 5;
real toff = 5;
*/*
task clkgen(input real phase, input real ron, input real toff);
#phase;
while(1) begin
clk50 = 1;
#ton;
clk50 = 0;
#toff;
end
endtask
initial begin
clkgen(7,5,5);
end
initial begin
#200;
$finish();
end
endmodule
`timescale 1ns / 1ps
module tb()'
reg clk = 0;
reg clk50 = 0;
always #5 clk = ~clk; //100 Mhz
/*
real phase = 10;
real ton = 5;
real toff = 5;
*/
/*
task clkgen(input real phase, input real ton, input real toff);
#phase;
while(1) begin
clk50 = 1;
#ton;
clk50 = 0;
#toff;
end
endtask
*/
task calc (input real freq_hz, input real duty_cycle, input real phase,
output real pout, output real ton, output real toff);
pout = phase;
ton = (1000_000_000 / frewq_hz) - ton;
endtask
task clkgen(input real phase, input real ton, input real toff);
@(possedge clk);
#phase;
while(1) begin
clk50 = 1;
#ton;
clk50 = 0;
#toff;
end
endtask
real phase;
real ton;
real toff;
initial begin
calc(100_000_000, 0.1,2,phase,ton,toff)
clkgen(phase,ton,toff);
end
initial begin
#200;
$finish();
end
endmodule