What is a defparam used for ?

In Verilog, the defparam statement is used to override or set values for module parameters that were declared in the module definition.

When a module is instantiated, it can have several parameters, such as size or width of a bus, that are declared in the module definition. By default, the parameters are assigned default or predetermined values. However, sometimes the module might need to be instantiated with different parameter values. In such cases, defparam statement can be used to override default parameter values.

Here's an example:


module my_module #(parameter WIDTH=8) (
  input [WIDTH-1:0] data_in,
  output [WIDTH-1:0] data_out
);
// ...
endmodule

In this example, my_module has a single parameter, WIDTH , that has a default value of 8. When my_module is instantiated by default, the WIDTH parameter would be set to 8. However, the defparam statement could be used to assign a different value to WIDTH , as shown:


  my_module u1 ( .data_in(in_data), .data_out(out_data) );

  defparam u1.WIDTH = 16;

In this case, a new instance of my_module , u1 , is created with the default WIDTH value of 8. However, the defparam statement is used to override the default value and set WIDTH parameter to 16 for instance u1 .

Read more on Verilog Parameters.

What is $time in Verilog?

In Verilog, $time is a system task that returns the current simulation time in simulation cycles or time units. It returns a 64-bit unsigned integer value.

The value returned by $time is calculated based on the `timescale directive in the Verilog code. The `timescale directive specifies the simulation time units and time precision used during simulation.

Here's an example of how $time can be used in Verilog:


module testbench;
  reg clk;

  initial begin
    clk = 1'b0;
    #10;
    while(1) begin
      #5;
      clk = ~clk;
      $display("Sim time is %d", $time);
    end
  end
endmodule

In this example, a testbench module with a clock (clk ) is defined. The initial block sets the clk to 0 and waits for 10 time units. Then, an infinite loop starts toggling the clk signal every 5 time units, and $display statement prints the current simulation time ($time) to the console.

By running the simulation, the console output would display the simulation time at each clock edge change. The simulation time increases by 5 time units per iteration. Read more on Verilog Timescale.

How is rise, fall and turnoff delays represented in Verilog ?

In Verilog, rise, fall, and turnoff delays for digital signals can be represented using different methods, depending on the design specifications and requirements. One common way to represent delays is by using the delay model # operator, which specifies a delay in simulation time units. The delay value is specified as a positive integer value preceded by the # symbol. For example:


wire a, b, out;

nand  #5 (out, a, b);

In this example, the nand gate has a delay of 5 time units. This means that the output will be generated 5 time units after the input signals change.

Another way to represent delays is by using the specify block, which is a construct used to model delay or timing constraints in Verilog. Within a specify block, timing paths or delay models can be defined. Here's an example:


specify
  specparam delay = 5;
  delay (a, out) = (specify_values => (delay, 0));
endspecify

In this example, a specify block is used to define the delay timing path between signals a and out . The specparam statement is used to define the delay parameter with a value of 5. Then, the delay statement is used to specify the timing path between a and out .

The above code declares that the output (out) is delayed by 5 time units from the input signal (a).

Alternatively, the delays can be specified in the gate-level netlist (which can be generated from a higher-level description). The gate-level model can specify delays using the Delay Model Template (DMT).

In summary, rise, fall, and turnoff delays for digital signals in Verilog can be represented using the # operator, specify block or Delay Model Template (DMT) in the gate-level. Selecting the appropriate delay representation method depends on the specific requirements of the design being implemented.

What is meant by logic synthesis ?

Logic synthesis is the process of transforming an electronic circuit design description (specified in a high-level hardware description language like Verilog or VHDL) into a gate-level netlist (specific sequences of AND, OR, NAND, NOR gates, etc.) that can be implemented in hardware.

The synthesis process involves several steps, including technology mapping, optimization, logic restructuring, and timing optimization.

During the technology mapping step, the high-level circuit design is mapped to a set of primitives (like AND, OR, NAND, NOR gates, etc.) provided by the target technology library. The optimization step tries to reduce the complexity of the circuit by simplifying the logic using Boolean algebra and other optimization algorithms. The logic restructuring stage helps rearrange the circuit layout to further optimize it. Finally, timing optimization ensures that the circuit meets the timing constraints defined in the design.

The end result of the logic synthesis process is a gate-level netlist that can be further processed and physically implemented using Electronic Design Automation (EDA) tools, such as place and route tools to optimize the physical layout of the circuit.

Logic synthesis helps in improving the hardware implementation of digital circuits and reduces the design implementation and debugging time. It is a crucial stage in the development process of digital hardware because it forms the foundation for subsequent stages like placement and routing, static timing analysis, and formal verification.

Read more on ASIC Design Flow.

Give a few examples of compiler directives.

Compiler directives are used in computer programming to provide specific instructions to the compiler or preprocessor to process the code in a certain way or to add additional functionality to the code. Here are some examples of compiler directives:

  • `include: This directive is used to include another source file in the code. The content of the source file is added to the current file during the pre-processing phase. For instance,
    
       `include "interface.sv"
    
  • `define: This directive defines a macro, which can be used to represent a value or expression in the code. For instance,
    
       `define NUM_MUX_INST   4
    

This will define a macro named NUM_MUX_INST with the value 4.

  • `ifdef / `ifndef: These directives test whether a certain macro is defined or not. These are useful for creating cross-platform code that works on multiple systems. For instance,
    
       `ifdef FEATURE_1
         // some verilog code
       `else
         // some other verilog code
       `endif
    

Read more on Verilog `ifdef Conditional Compilation.

What are Verilog parallel case and full case statements ?

When all binary values of the case expression are covered by the case items, the statement is called a full case statement and it avoids inferrence of latches.


// Example of full case with all possible matches 
case(abc)
  2'b11 : out3 = 1'b1;
  2'b10 : out2 = 1'b1;
  2'b01 : out1 = 1'b1;
  2'b00 : out0 = 1'b1;
endcase

It is a parallel case if the case items are mutually exclusive.


// Example of parallel case where items are mutually exclusive
case (abc)
  3'b1?? : out2 = 1'b1;
  3'b01? : out1 = 1'b1;
  3'b001 : out0 = 1'b1;
endcase

What does a wire refer to?

In Verilog, a wire is a type of net data type that represents a physical connection between two or more logic gates. It is called a "wire" because it behaves like a real-world electrical wire, allowing signals to flow from one point to another.

Wires are used to connect signals between modules, and can only be driven by a module's output. They are also used internally to connect different logic gates within a module. Wires are meant to represent continuous values, such as analog signals, rather than discrete values like bits.

Read more on Verilog Data Types.

What is a reg in Verilog?

In Verilog, reg is a data type used to store and manipulate binary and integer values.

Despite its name, a reg does not always represent a physical register or flip-flop. It is a variable that can store a value determined by combinational logic or sequential logic. It's value can be set or reset using an always block or an initial block. Once set, the value can be updated or accessed anytime within the module.

Read more on Verilog Data Types.

What are blocking and non-blocking statements ?

Blocking assignments are represented using the = symbol, and they execute sequentially, one after another. The next statement will not start until the current blocking assignment is completed. The value of the right-hand side expression is immediately computed and assigned to the left-hand side variable.

Non-blocking assignments are represented using the <= symbol. They appear to execute simultaneously, without waiting for the previous non-blocking assignment to complete. The right-hand side expression is scheduled for execution but the actual assignment to the left-hand side variable is delayed until the end of the time step or clock cycle.

Read more on Verilog Blocking & Non-Blocking.

Give major differences between a task and a function

Tasks and functions are the subroutines used in Verilog. The primary difference is that a task can contain statements that consume simulation time like delays, whereas a function cannot.

Read more on Verilog Task and Verilog Functions.