Verilog Interview Qs
Verilog Interview Qs
Ex: a = 5;
Ex: a <= 5;
Function Task
Can not contain simulation delay, so can or can not contain a simulation time
execute in the same time unit. It can not delay(#), @, wait, negedge, and posedge
contain @, wait, negedge, and posedge time-controlled statements.
time-controlled statements.
Can return a single value Can return multiple values as output or
inout argument. It can not return a value
that a function can do.
Can not call another task Can call another function or task
module function_example; module task_example;
Net types:
1) The net (wire, tri) is used for physical connection between structural elements.
2) Value is assigned by a continuous assignment or a gate output or port of a
module.
3) It can not store any value. The values can be either read or assigned.
4) Default value – z
Register type:
1) The register (reg, integer, time, real, real-time) represents an abstract data storage
element and they are not the physical registers.
2) Value is assigned only within an initial or an always statement.
3) It can store the value.
4) Default value – x
4. What is generate block in Verilog and its usage?
Control Scope: The block controls variables, functions, tasks, and instantiation
declarations.
Inside a generate block, you can use data types like integers, real numbers, nets, regs,
time, and events. It also supports structures like modules, gate primitives, continuous
assignments, initial and always blocks, and user-defined primitives. However, it does not
allow port declarations, specify blocks, or parameter declarations.
Generate Loop: Uses genvar for index variables in loop constructs, similar to a for-loop
but specific to compile-time generation.
Generate Conditional: Uses if-else and case structures to conditionally generate code.
In do while loop, even if a condition is not true, a loop can execute at once.
count_A++;
count_B++;
count_C++;
$display("Static: count_A = %0d, count_B = %0d, count_C = %0d", count_A,
count_B, count_C);
endtask
count_A++;
count_B++;
count_C++;
$display("Automatic: count_A = %0d, count_B = %0d, count_C = %0d", count_A,
count_B, count_C);
endtask
task increment();
static int count_A;
automatic int count_B;
int count_C;
count_A++;
count_B++;
count_C++;
$display("Normal: count_A = %0d, count_B = %0d, count_C = %0d", count_A,
count_B, count_C);
endtask
initial begin
$display("Calling static tasks");
increment_static();
increment_static();
increment_static();
$display("\nCalling automatic tasks");
increment_automatic();
increment_automatic();
increment_automatic();
$display("\nCalling normal tasks: without static/automatic keyword");
increment();
increment();
increment();
OUTPUT
Calling static functions
Static: count_A = 1, count_B = 1, count_C = 1
Static: count_A = 2, count_B = 1, count_C = 2
Static: count_A = 3, count_B = 1, count_C = 3
Static: count_A = 3
Automatic: count_A = 3
Normal: count_A = 3
Static: count_C = 3
Normal: count_C = 3
8. Difference between $stop and $finish.
$stop suspends the simulation and puts a simulator in an interactive mode.
initial
begin
repeat(5)
begin
address = $random()%10; // signed numbers
data = $urandom()%10; // unsigned numbers
$display("address = %0d;",address);
$display("data = %0d;",data);
end
end
endmodule
RESULTS:
address = 8;
data = 2;
address = -9;
data = 0;
address = -9;
data = 2;
address = -9;
data = 2;
address = 7;
data = 6;
Intermediate level questions
1. What is the default value of wire and reg?
The regular delay control delays the execution of the entire statement by a specified
value. The non-zero delay is specified at the LHS of the procedural statement.
In this case, the result signal value will be updated after 5-time units for change happen
in its input.
Intra-assignment delay:
Full Case:
In a full case statement, case statements cover every possible input value is explicitly
specified and there are no unspecified or “don’t care” conditions.
Example:
case (input)
3'b000: ………
3'b001: ………
3'b010: ………
3'b011: ………
3'b100: ………
3'b101: ………
3'b110: ………
3'b110: ………
default: // any other input case which is not covered
endcase
Parallel Case:
In a parallel case statement, multiple case items can match the input value
simultaneously and the corresponding behaviors for that will be executed in parallel.
Example:
case (input)
4'b0?: ………
4'b1?: ………
// other cases
default: // any other input case which is not covered
endcase
The case statement also has a total of three variations: case, casex and casez. Note the
following differences.
1) case: considers x and z as it is (as shown in above example). If an exact match is not
found, the default statement will be executed.
2) casex: considers all x and z values as don’t care.
3) casez: considers all z values as don’t cares. The z can also be specified as ?
Note:
1) In simple terms, casez ignores bit positions having z value alone and casex ignores
bit positions having x or z values.
2) The ‘casez’ is more likely used as compared to ‘casex’ as the ‘casez’ does not ignore
bit positions having x values and ‘casex’ is not synthesizable as well.
In synchronous reset, a flip flop gets reset at the active ‘clock’ edge when the ‘reset’ signal
is asserted.
Thus, in Verilog implementation, the ‘reset’ signal must not be written in the sensitivity
list of always block.
Example:
reg [2:0] data;
initial begin
data = 2;
end
initial begin
#0 data = 3;
End
Without zero delay control, the ‘data’ variable may have a value of either 2 or 3 due to
race conditions. Having zero delay statement as specified in the above code guarantees
the outcome to be 3. However, it is not recommended to assign value to the variable at
the same simulation time.
7. How to generate two different clocks in testbench?
module tb;
bit clk1, clk2;
initial forever #5ns clk1 = ~clk1;
initial forever #4ns clk2 = ~clk2;
endmodule
//Testbench Code
module TB;
reg clk, rst_n, x;
wire z;
initial begin
x = 0;
#1 rst_n = 0;
#2 rst_n = 1;
#3 x = 1;
#4 x = 1;
#4 x = 0;
#4 x = 1;
#4 x = 0;
#4 x = 1;
#4 x = 0;
#4 x = 1;
#4 x = 1;
#4 x = 1;
#4 x = 0;
#4 x = 1;
#4 x = 0;
#4 x = 1;
#4 x = 0;
#10;
$finish;
end
initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(0);
end
endmodule
9. Write a Verilog code for D-Latch.
The latch has two inputs ‘data (D)’ and ‘clock (clk)’
One output data (Q)
If clk = 1, then data passes to the output Q
If clk = 0, then data is not passed to the output Q
Example:
initial begin
$display("DATA_WIDTH = %0d, ID_WIDTH = %0d", DATA_WIDTH, ID_WIDTH);
`define D_WIDTH 32
`define I_WIDTH 8
module tb_top;
module clk_gen;
realtime on_t = `CLK_PERIOD * 0.6;
realtime off_t = `CLK_PERIOD * 0.4;
bit clk;
always begin
#on_t clk = 0;
#off_t clk = 1;
end
initial begin
clk = 1;
#50 $finish;
end
initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(0);
end
endmodule
13. Write an RTL code to generate 100MHz clock.
To generate clock frequency, time period needs to be calculated.
With a 50% duty cycle, clock has to flip a bit after every 5ns.
module clk_gen;
reg clk;
always #5 clk = ~clk;
endmodule
The `include is also a compiler directive is used to include another filename. The double
quote “<file_name>” is used in the `include directive. It is widely used to include library
files, and common code instead of pasting the same code repeatedly.
For a need basic, we can use the ‘forever’ loop as a work-around with a ‘break’ statement
to terminate the loop as per requirement.
Underflow: When an attempt is made to read data from an empty FIFO, it is called an
underflow. The design should have an ‘empty’ flag to avoid getting invalid values
Overflow: When an attempt is made to write data into the already full FIFO, it is called
an overflow. The design should have a ‘full’ flag to avoid losing the data sent from the
previous module.
Example:
always@(*) begin
if(en) begin
data <= 8‘hFF;
end
end
4. Swap register content with and without using an extra register.
Without using an extra register:
always @(posedge clk) begin
m <= n;
n <= m;
end
Infer latch means creating a feedback loop from the output back to the input due to
missing if-else condition or missing ‘default’ in a ‘case’ statement.
Infer latch indicates that the design might not be implemented as intended and can
result in race conditions and timing issues.
Verilog parameter is used to pass a constant to the module when it is instantiated. The
parameter value can not be changed at run time.
`timescale
Syntax:
`timescale <time_unit>/<time_precision>
`timescale 10ns/1ns
`timescale 10ns/1ns
module tb;
initial begin
$display ("At time T=%0t", $realtime);
#0.45;
$display ("At time T=%0t", $realtime);
#0.50;
$display ("At time T=%0t", $realtime);
#0.55;
$display ("At time T=%0t", $realtime);
end
endmodule
Output:
At time T=0
At time T=5
At time T=10
At time T=16
Explaination:
`timescale 1ns/1ns: Since precision = 1ns, the simulator will advance its time if the
delay value is greater or equal to 0.5ns. Thus, time advancement does not happen for
0.45ns delay.
`timescale 1ns/1ps: Since precision = 1ps, the simulator will advance for all the cases.
`timescale 10ns/1ns: Since precision = 1ns, the simulator will advance for all the cases.
Here, the delay involved is multiplied with mentioned time units and then it rounds off
based on precision to calculate actual simulation advancement.
reg n = c;
wire o = c;
But if we do declaration and assignment in the ‘always’ block then m and n can be driven
same as a clock, but ‘o = c’ assignment can not be possible inside ‘always’ block as the ‘o’
variable is a wire type.