Give the code for a mod-3 counter

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


module cntr_mod3 (input clk, rstn, output reg [1:0] out);
  always @(posedge clk) begin
    if (!rstn)
      out <= 0;
    else 
      if (out == 2)
        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 #(.RESET_VAL (10)) u_abc ( ... );
      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 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.


module clock_60_percent (
  input wire clk,
  input wire rst_n,
  output wire clk_60_percent
);

  // Define the maximum count value.
  // For a 60% duty cycle, we want the high time to be 3/5 of the period.
  // If the counter goes from 0 to 4 (5 states), we can have 'high' for 3 states and 'low' for 2 states.
  // So, MAX_COUNT = 4.
  localparam MAX_COUNT = 4;

  reg [2:0] counter; // Needs enough bits to represent MAX_COUNT

  // Duty cycle logic: HIGH for counter values 0, 1, 2 and LOW for 3, 4
  localparam HIGH_THRESHOLD = 3; // Counter values 0, 1, 2 will be HIGH

  assign clk_60_percent = (counter < HIGH_THRESHOLD) ? 1'b1 : 1'b0;

  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      counter <= 3'b0;
    end else begin
      if (counter == MAX_COUNT) begin
        counter <= 3'b0; // Reset counter
      end else begin
        counter <= counter + 1;
      end
    end
  end
endmodule          

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;

	initial clk = 0;   // without this, clk stays x forever
	// 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 SystemVerilog program block holds testbench code. Its initial procedures run in the Reactive region, after the design's events in the same time step, which avoids races between testbench and design. A program can contain initial and final procedures, tasks, functions and declarations, but not always procedures, UDPs, or module, interface or program instances.

    An always block is excluded because a program is expected to finish. When all of a program's initial procedures end, the program ends, and once every program has ended the simulator calls $finish. A free-running always block would prevent that.

    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
    

    Because this block is clocked, the missing else is fine here: synthesis infers a flip-flop with an enable that holds data_valid when data_ready is low. The same omission in a combinational always block would infer a latch.

    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.

    Did you find what you were looking for?

    Quiz

    No quiz questions available for this article.