Standard Verilog primitives like nand and not may not always be easy or sufficient to represent complex logic. New primitive elements called UDP or user-defined primitives can be defined to model combinational or sequential logic.

All UDPs have exactly one output that can be either 0, 1 or X and never Z (not supported). Any input that has the value Z will be treated as X.

Verilog timescale directive specifies time unit and precision for simulations.

Verilog $timeformat system function specifies %t format specifier reporting style in display statements like $display and $strobe.

Default timescale

Although Verilog modules are expected to have a timescale defined before the module, simulators may insert a default timescale. The actual timescale that gets applied at any scope in a Verilog elaborated hierarchy can be printed using the system task $printtimescale which accepts the scope as an argument.

  
  
module tb;
	initial begin
		// Print timescale of this module
		$printtimescale(tb);
		// $printtimescale($root);
	end
endmodule

  

Verilog delay statements can have delays specified either on the left hand side or the right hand side of the assignment operator.

Inter-assignment Delays

  
  
	// Delay is specified on the left side
	#<delay> <LHS> = <RHS>

  

An inter-assignment delay statement has delay value on the LHS of the assignment operator. This indicates that the statement itself is executed after the delay expires, and is the most commonly using form of delay control.

Until now in previous articles, simple boolean expressions were checked on every clock edge. But sequential checks take several clock cycles to complete and the time delay is specified by ## sign.

## Operator

If a is not high on any given clock cycle, the sequence starts and fails on the same cycle. However, if a is high on any clock, the assertion starts and succeeds if b is high 2 clocks later. It fails if b is low 2 clocks later.