Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Verilog Function and Task Examples, Quizzes of Verilog and VHDL

Examples of verilog functions and tasks, including how to compare values, use generate loops, and work with static and automatic variables. It covers intermediate-level verilog concepts such as casez and casex statements, race conditions, and sequential state machine design. The document also includes examples of parameter passing, clock generation, and multiplexer implementation. Overall, this document serves as a comprehensive reference for verilog programming techniques and can be useful for students and engineers working with verilog hdl.

Typology: Quizzes

2022/2023

Uploaded on 04/27/2024

nikhil-ml
nikhil-ml 🇮🇳

1 / 23

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
INTERVIEW
HANDBOOK
E R I L O G
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17

Partial preview of the text

Download Verilog Function and Task Examples and more Quizzes Verilog and VHDL in PDF only on Docsity!

INTERVIEW

HANDBOOK

E R I L O G

Basic Level Questions

1. Difference between blocking and non-blocking assignments

Blocking Assignments: The blocking assignment statements are executed sequentially

by evaluating the RHS operand and finishes the assignment to LHS operand without any

interruption from another Verilog statement. Hence, it blocks other assignments until

the current assignment completes and is named a “blocking assignment”.

Ex: a = 5;

Non-Blocking Assignments: The non-blocking assignment statement starts its

execution by evaluating the RHS operand at the beginning of a time slot and schedules

its update to the LHS operand at the end of a time slot. Other Verilog statements can be

executed between the evaluation of the RHS operand and the update of the LHS

operand. As it does not block other Verilog statement assignments, it is called a non-

blocking assignment.

Ex: a <= 5;

2. Difference between task and function

Function Task

Can not contain simulation delay, so

execute in the same time unit. It can not

contain @, wait, negedge, and posedge

time-controlled statements.

can or can not contain a simulation time

delay(#), @, wait, negedge, and posedge

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; function compare(input int a, b); if(a>b) $display("a is greater than b"); else if(a<b) $display("a is less than b"); else module task_example; task compare(input int a, b, output done); if(a>b) $display("a is greater than b"); else if(a<b) $display("a is less than b");

4. What is generate block in Verilog and its usage?

A generate block in Verilog is used to dynamically generate synthesizable code during

the elaboration phase. It helps automate the replication of module instances or repeated

code segments, enhancing design scalability and manageability. The primary uses

include:

Code Repetition: It allows for the generation of multiple instances of modules or

repetitive code structures, reducing manual coding.

Conditional Instantiation: It enables conditional instantiation of code based on

parameters, though parameters themselves cannot be declared within the generate

block.

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.

There are two main types of generate constructs:

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.

Here’s a quick example using a generate loop:

genvar k; generate for (k = 0 ; k < 4 ; k++) begin always@(posedge clk) begin val[k] = a[k] & b[k]; end end endgenerate

5. Difference between while and do-while loop

In the while loop, a condition is checked first, and if it holds true statements will be

executed else the loop terminates.

In do while loop, even if a condition is not true, a loop can execute at once.

Example of do while when a condition is not true:

module do_while_example; int count = 2 ; initial begin do begin $display("Value of count = %0d", count); count++; end while(count< 1 ); end endmodule

6. What is an automatic keyword in the task?

The automatic keyword specifies the variable’s scope within a task i.e. memory is

allocated for the variables in the task and deallocated once the task completes execution.

All variables declared in an automatic task are automatic variables unless they are

specifically mentioned as a static variable.

7. Explain the difference between a static and automatic function

with example.

Static and Automatic Functions

1) By default, functions declared are static except they are declared inside a class scope.

If the function is declared within class scope, they behave as an automatic function

by default unless they are specifically mentioned as static functions. We will discuss

more on this concept in class (OOP) concepts.

2) All variables declared in a static function are static variables unless they are

specifically mentioned as an automatic variable.

3) All variables declared in an automatic function are automatic variables unless they

are specifically mentioned as a static variable.

increment_automatic(); $display("\nCalling normal tasks: without static/automatic keyword"); increment(); increment(); increment(); //Accessing variables using task // count_A $display("\nStatic: count_A = %0d", increment_static.count_A); $display("Automatic: count_A = %0d", increment_automatic.count_A); $display("Normal: count_A = %0d", increment.count_A); // count_B: Hierarchical reference to automatic variable is not legal. /* $display("\nStatic: count_B = %0d", increment_static.count_B); $display("Automatic: count_B = %0d", increment_automatic.count_B); $display("Normal: count_B = %0d", increment.count_B); */ // count_C $display("\nStatic: count_C = %0d", increment_static.count_C); //$display("Automatic: count_C = %0d", increment_automatic.count_C); // illegal reference to automatic variable $display("Normal: count_C = %0d", increment.count_C); end endmodule

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 Calling automatic functions Automatic: count_A = 1 , count_B = 1 , count_C = 1 Automatic: count_A = 2 , count_B = 1 , count_C = 1 Automatic: count_A = 3 , count_B = 1 , count_C = 1 Calling normal functions: without static/automatic keyword Normal: count_A = 1 , count_B = 1 , count_C = 1 Normal: count_A = 2 , count_B = 1 , count_C = 2 Normal: 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.

$finish exits the simulation.

9. Difference between $random and $urandom

Both generate 32-bit pseudorandom numbers, but $random generates signed whereas

$urandom generates unsigned numbers.

EXAMPLE:

module Tb(); integer address; integer data; 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 ;

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

4. Difference between casex and casez

casex and cazez statements

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?

casez statement example casex statement example

module casez_example( input [ 1 : 0 ] data, output reg [ 3 : 0 ] out); always @() begin casez(data) 2'b0z: out = 1 ; 2'bz0: out = 2 ; 2'b1z: out = 3 ; 2'bxz: out = 4 ; 2'b0x: out = 5 ; 2'bx0: out = 6 ; 2'b1x: out = 7 ; 2'bx1: out = 8 ; default: $display("Invalid sel input"); endcase end endmodule module casex_example( input [ 1 : 0 ] data, output reg [ 3 : 0 ] out); always @() begin casex(data) 2'b0z: out = 1 ; 2'bz0: out = 2 ; 2'b1z: out = 3 ; 2'bxz: out = 4 ; 2'b0x: out = 5 ; 2'bx0: out = 6 ; 2'b1x: out = 7 ; 2'bx1: out = 8 ; default: $display("Invalid sel input"); endcase end endmodule

Output: data = x1 - > out = 4 data = 0x - > out = 1 data = x0 - > out = 2 data = z1 - > out = 1 data = 0z - > out = 1 data = z0 - > out = 1 data = 1z - > out = 2 Output: data = x1 - > out = 1 data = 0x - > out = 1 data = x0 - > out = 1 data = z1 - > out = 1 data = 0z - > out = 1 data = z0 - > out = 1 data = 1z - > out = 2

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.

5. What is synchronous and asynchronous reset? Can you explain

using DFF and write their Verilog code?

In asynchronous reset, a flip flop gets reset as soon as the ‘reset’ signal is asserted. Thus,

in Verilog implementation, the ‘reset’ signal has to be written in the sensitivity list of

always block.

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.

Asynchronous Reset Synchronous Reset

module D_flipflop ( input clk, rst_n, input d, output reg q ); always@(posedge clk or negedge rst_n) begin if(!rst_n) q <= 0 ; else q <= d; end endmodule module D_flipflop ( input clk, rst_n, input d, output reg q ); always@(posedge clk) begin if(!rst_n) q <= 0 ; else q <= d; end endmodule

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

8. Design overlapping and non-overlapping FSM for sequence

detector 1010.

module seq_detector_1010(input bit clk, rst_n, x, output z); parameter A = 4'h1; parameter B = 4'h2; parameter C = 4'h3; parameter D = 4'h4; bit [ 3 : 0 ] state, next_state; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin state <= A; end else state <= next_state; end always @(state or x) begin case(state) A: begin if(x == 0 ) next_state = A; else next_state = B; end B: begin if(x == 0 ) next_state = C; else next_state = B; end

C: begin if(x == 0 ) next_state = A; else next_state = D; end D: begin if(x == 0 ) next_state = A; //This state only differs when compared with Mealy Overlaping Machine else next_state = B; end default: next_state = A; endcase end assign z = (state == D) && (x == 0 )? 1 : 0 ; endmodule //Testbench Code module TB; reg clk, rst_n, x; wire z; seq_detector_1010 sd(clk, rst_n, x, z); initial clk = 0 ; always # 2 clk = ~clk; 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

Testbench: define D_WIDTH 32define I_WIDTH 8 module tb_top; param_example p1(.data( 2 ), .id( 1 )); // without passing parameter param_example #( 4 , 16 ) p2(.data( 3 ), .id( 2 )); // constant parameter passing param_example #(D_WIDTH,I_WIDTH) p3(.data( 6 ), .id( 3 )); // macro define based parameter passing param_example p4(.data( 9 ), .id( 4 )); // Change parameter value using defparam defparam p4.DATA_WIDTH = 10 ; defparam p4.ID_WIDTH = 16 ; endmodule

11. What is Synthesis?

The process of converting hardware description language like Verilog code into the

equivalent netlist design that has flip-flops, logic gates, and required digital circuit

components.

12. Write an RTL code to generate 60% duty cycle clock.

define CLK_PERIOD 10ns 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.

Time Period = 1/frequency = 1/100MHz = 10ns

With a 50% duty cycle, clock has to flip a bit after every 5ns.

module clk_gen; reg clk; always # 5 clk = ~clk; endmodule

14. Difference between define andinclude.

`define is a compiler directive that substitutes itself in the code with a defined context.

In simple words, wherever macro is used, it is replaced with macro context and gives

compilation error in case of misuse.

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.

15. What will be output of the following code?

always@(clock) begin a = 0 ; a <= 1 ; $display(a); end

In brief, A single time cycle or slot is divided into various regions and that helps to

schedule the events. The scheduling an event terminology describes keeping all such

events in an event queue and processing them in the correct order. In this case, there

are 3 events scheduled in an event queue.

1. Active event – blocking statement “a = 0”.

2. A non-blocking event – non-blocking statement “a <= 1”

3. Monitor event – “$display(a)”.

$display acknowledges and displays what value is being calculated as an active region.

Also, a non-blocking event computes (not assigned to RHS ‘a’ variable) LHS during the

active region. Thus, it will pick up the value calculated by the statement “a = 0”. But in the

next clock cycle, the value of a = 1.

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

Using an extra register (in case the interviewer asks):

Here, temp is an extra register used.

always @(posedge clk) begin temp = n; n = m; m = temp; end

5. What is infer latch means? How can you avoid it?

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.

How to avoid it?

1. Always use all branches in the ‘if’ and ‘case’ statements.

2. Use default in the ‘case’ statement.

3. Have a proper code review.

4. Use lint tools, and logical-equivalence-check tools

6. What is parameter overriding in Verilog?

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.

There are two ways to override the parameters in Verilog

[1]. During module instantiation

module param_example #(parameter DATA_WIDTH = 8 , ID_WIDTH = 32 ) (data, id); param_example #( 4 , 16 ) p2(.data( 3 ), .id( 2 ));

[2]. Using defparam

defparam p4.DATA_WIDTH = 10 ; defparam p4.ID_WIDTH = 16 ;

7. Write a Verilog code for 5:1 MUX

5:1 MUX selects one out of 5 signals based on 3-bit select input and forwards it to single-

bit output.

module mux_5_1 (input [ 4 : 0 ] i_data, [ 2 : 0 ] sel, output reg out); always@(*) begin case(sel) 5'h0: out = i_data[ 0 ]; 5'h1: out = i_data[ 1 ]; 5'h2: out = i_data[ 2 ]; 5'h3: out = i_data[ 3 ]; default: out = i_data[ 4 ]; endcase end endmodule

8. Can you talk about the Verilog event scheduler?

The Verilog scheduling semantics is used to describe the Verilog language element’s

behavior and their interaction with each other. This interaction is described for event

execution and its scheduling. Verilog is like a parallel programming language in terms of

blocks or process executions. Hence, the user should know the guaranteed or

indeterminate execution order while using it.