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.