Give the code for a mod-3 counter

A modulo-3 counter has 3 states (0, 1, 2) and requires 23 number of flip-flops.


module cntr_mod3 (input clk, rstn, output reg [1:0] out);
  always @(posedge clk) begin
    if (!rstn)
      out <= 0;
    else 
      if (&out)
        out <= 0;
      else
      	out <= out + 1;
  end 
endmodule

How can you override the existing parameter value?

In Verilog, you can override the existing parameter value in two ways:

  1. In module instantiation
  2. 
      module abc (input ..., output ...);
      	parameter RESET_VAL = 4;
      endmodule
      
      module xyz ();
      	abc 	u_abc #(.RESET_VAL (10)) ( ... );
      endmodule
      
  3. Using defparam
  4. 
      module abc (input ..., output ...);
      	parameter RESET_VAL = 4;
      endmodule
      
      module xyz ();
      	abc 	u_abc ( ... );
      
        defparam u_abc.RESET_VAL = 10;
      endmodule    
      

Read more on Verilog Parameters.

What is Synthesis?

Synthesis is the process of converting a high-level hardware description language (HDL) code, such as Verilog or VHDL, into a gate-level netlist that can be used for physical implementation of a digital circuit on an integrated circuit (IC) or field-programmable gate array (FPGA).

The synthesis process involves analyzing the HDL code to determine the intended functionality of the circuit, optimizing the design for the desired performance and resource utilization, and generating a gate-level netlist that describes the circuit in terms of logic gates and flip-flops.

The synthesis tool analyzes the HDL code and performs a series of transformations to optimize the design. This can involve simplifying logic expressions, removing redundant logic, optimizing resource usage, and mapping the design to a specific target technology, such as an FPGA or ASIC. The synthesis tool then generates a gate-level netlist that can be processed by other tools to perform place-and-route, to create a physical layout of the circuit, and finally to generate the programming files that can be used to program the target device.

Read more on ASIC Design Flow.

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

To generate a 60% duty cycle clock using RTL code, we can use a counter to divide the input clock signal and use the output of the counter as the inverted output of a D-type flip-flop.



Write simple Verilog code to generate 100MHz clock.

To generate 100M clock with 50% duty cycle, we have to flip the clock bit every 5ns.


module tb;
	reg clk;

	// 1/100M = 10ns period 
	always #5 clk = ~clk;
endmodule

Difference between `define and `include.

  • `define
  • It is a preprocessor keyword that is used to define a text macro. It can be used to define constants, expressions or strings that can be used later in the code. When the Verilog/SystemVerilog compiler encounters a `define directive, it replaces the defined text with the macro value throughout the code before compilation.

    
    `define MY_VALUE 4
    always @(posedge clk) begin
       if (i == `MY_VALUE) begin
          // some code
       end
    end
    

    Here, MY_VALUE is a macro that has been defined with a value of 4 . The macro is being used inside an always block to check if i is equal to 4 . When this code is compiled, the preprocessor will expand the MY_VALUE macro into the actual value of 4 .

  • `include
  • It is also a preprocessor directive that is used to include a file in the current code. When the Verilog/SystemVerilog compiler encounters an `include statement, it reads the contents of the specified file and inserts them into the current source file at the location of the `include statement. The `include statement is mainly used to insert common code, libraries or modules into multiple files without copying the same code multiple times.

    
    `include "my_file.v"
    module my_module (input clk, input rst, output reg out);
       // some code
    endmodule
    

    Here, the `include statement is used to include the contents of the file `my_file.v` into the current module. The code inside my_file.v could contain module definitions, declarations, `define statements or other common code that can be reused in multiple modules.

Why always block is not used inside a program block?

A program block is used in SystemVerilog to encapsulate design hierarchy and to allow for a more modular design approach. It is a static region of code and cannot contain any behavioral constructs. An always block, on the other hand, is used to describe behavioral functionality in a module or an interface.

Since a program block cannot contain any behavioral constructs, it cannot contain an always block. The only constructs that are allowed inside a program block are declarations, instantiations of other modules or interfaces, and control statements such as if-else, case, for, and while loops.

What is a FIFO and write Verilog code for the design?

FIFO (First-In-First-Out) is a type of buffer used in digital circuits to manage data transfer between devices or subsystems. It is a common design element in communication interfaces and memory management units. A FIFO stores data in a queue-like structure, where the first item that has been inserted into the buffer will be the first one to be removed.

Read more on Synchronous FIFO.

What will happen if there is no else part in if-else ?

If there is no else part in an if-else statement, then execution will simply move on to the next statement after the if-else block, without executing any code when the if condition is false.

For example, consider the following Verilog code:


always @(posedge clk) begin
	if (data_ready) begin
  		data_valid <= 1;
	end
end

Note that this is a typical error that synthesizes into a latch because it does not specify what has to be done to data_valid when data_ready is low, and hence it simply holds onto the previous value.

Explain overflow and underflow conditions in FIFO.

In a FIFO (First-In-First-Out) buffer, overflow and underflow occur when data is being added to or removed from the buffer and there is no space available to add new data (in the case of overflow) or no data available to remove (in the case of underflow).

Overflow occurs when new data is being written into the FIFO while it is full. This means that the buffer has reached its maximum capacity and cannot store any more data. In an overflowing FIFO, new data may overwrite the old data that is already in the FIFO, leading to data loss or corruption. This can cause serious issues in systems where data integrity is critical. To avoid overflow, a flag indicating whether the FIFO is full may be used.

Underflow, on the other hand, occurs when data is being read from the FIFO while it is empty. This means that there is no data available to remove from the buffer. When underflow occurs, the FIFO may return an invalid value or in some cases, return no value at all. To avoid underflow, a flag indicating whether the FIFO is empty may be used.

To minimize the impact of overflow and underflow, FIFOs are typically designed with a certain amount of headroom or slack, which is the difference between the maximum capacity of the FIFO and the actual data being stored. This allows the FIFO to accept some extra data without overflowing, and also allows for some data to be removed even if the buffer is not completely full. It's important to carefully choose the capacity of the FIFO to ensure that it can handle the maximum expected data rate in the system, while also providing enough slack to avoid overflow and underflow.

Also read on Synchronous FIFO.