Verilog Quickstart: A Practical Guide to Simulation and Synthesis in Verilog, 3rd Edition

Although the aim of this book is to teach high level modeling in Verilog, the book would not be complete without mentioning user-defined primitives (UDPs). A UDP describes a piece of logic with a truth table. UDPs can be either combinatorial or sequential. As you may recall, the Verilog primitive set does not include any muxes. AND-OR-INVERT gates, or flip-flops. You can model all of these simple functions with UDPs.
Why use UDPs? For some types of logic, a truth table may be the easiest way to model them. The main reason UDPs are used is performance: Verilog evaluates UDPs quickly, and UDPs take up only a small amount of memory. For example, a mux is typically modeled with an inverter, two AND gates, and an OR gate. These four gates can be replaced with a single UDP. Flip-flops, which take even more gates to model than a mux, can be replaced by a UDP. The most common use for UDPs is in modeling a library of ASIC cells or standard components.
The simplest thing you might want to model with a UDP is a mux. If you want to model a mux, is the mux optimistic or pessimistic? If the two inputs are 1, and the select is unknown, is the output 1 or x? Because it is your UDP, you get to choose which result you want.
This mux is optimistic because if the inputs are the same and the select is...