VERILOG : 6. Primitives, Gate and Switch Delays in verilog

    When we design digital circuits in Verilog, we often rely on primitives—the building blocks of complex systems. These are the lowest-level components (gates, switches, buffers, etc.) that mimic real hardware behavior. Understanding how to design using primitives is crucial, especially in ASIC (Application-Specific Integrated Circuit) and library development.

In this blog, we’ll cover:
✅ What Verilog primitives are

✅ How delays are modeled (rise, fall, turn-off, min/typ/max)

✅ Examples of gate delays with testbenches

✅ N-input and N-output primitives

✅ Building complex circuits (AND gate, D-Flip-Flop, Multiplexer) using primitives

Let’s dive in 🚀


🔹 What are Verilog Primitives?

Primitives are the basic logic gates and switches provided by Verilog.

  • They are built-in keywords like and, or, not, buf, etc.

  • They do not require module definitions (unlike user-defined modules).

  • ASIC vendors often use User-Defined Primitives (UDP) and standard gate primitives for library creation.

Think of them as the “Lego blocks” of digital hardware.


🔹 Modeling Gate and Switch Delays

In real circuits, logic gates take time to respond to input changes. Verilog allows us to add delays to primitives, making simulations closer to reality.

⏱ Types of Delays in Verilog

  1. Rise Delay → Time to transition output to 1

  2. Fall Delay → Time to transition output to 0

  3. Turn-off Delay → Time to transition output to z (high-impedance)

Additionally, each delay can have minimum, typical, and maximum values:

  • min → Best-case delay (fastest response)

  • typ → Normal delay (realistic case)

  • max → Worst-case delay (slowest response)

👉 Syntax:

primitive #(delay_values) unique_name (connections);

🔹 Examples of Delays in Verilog

🟢 Example 1 – Single Delay

module buf_gate (); reg in; wire out; buf #(5) (out, in); // Delay of 5 time units initial begin $monitor("Time=%g in=%b out=%b", $time, in, out); in = 0; #10 in = 1; #10 in = 0; #10 $finish; end endmodule

Simulation Output:

Time = 0 in = 0 out = x Time = 5 in = 0 out = 0 Time = 10 in = 1 out = 0 Time = 15 in = 1 out = 1

Here, output changes 5 time units after input.


🟢 Example 2 – Rise and Fall Delays

buf #(2,3) (out, in);
  • Rise delay = 2

  • Fall delay = 3

So output is faster when rising, slower when falling.


🟢 Example 3 – All Delays Together

buf #(1,0) U_rise (rise_delay, in); buf #(0,1) U_fall (fall_delay, in); buf #(1) U_all (all_delay, in);

This allows different behaviors for rise, fall, and turn-off conditions.


🟢 Example 4 – Complex Delay Example

or #5 u_or (out1, b, c); // All delays = 5 and #(1,2) u_and (out2, b, c); // Rise=1, Fall=2 nor #(1,2,3) u_nor (out3, b, c); // Rise=1, Fall=2, Turn-off=3 nand #(1:2:3) u_nand (out4, b, c); // min:typ:max delays

This models realistic timing differences across different gates.


🔹 N-Input and N-Output Primitives

✅ N-Input Primitives

  • and, nand, or, nor, xor, xnor

  • First terminal = output

  • Remaining terminals = inputs

and u_and1 (out1, in1, in2); // 2-input AND and u_and2 (out2, in1, in2, in3, in4); // 4-input AND xnor u_xnor1 (out3, in1, in2, in3); // 3-input XNOR

✅ N-Output Primitives

  • buf, not

  • First terminals = outputs

  • Last terminal = input

buf u_buf0 (out, in); // 1 output buf u_buf1 (out_0, out_1, out_2, in); // multiple outputs not u_not0 (out_a, out_b, out_c, in); // multiple inverted outputs

🔹 Building Circuits Using Primitives

Now, let’s build some real circuits using only primitives.

🟢 Example – AND Gate from NANDs

module and_from_nand(); reg X, Y; wire F, W; nand U1(W, X, Y); nand U2(F, W, W); // NAND of same input works as NOT initial begin $monitor("X=%b Y=%b F=%b", X, Y, F); X=0; Y=0; #1 X=1; #1 Y=1; #1 X=0; #1 $finish; end endmodule

🟢 Example – D Flip-Flop from NANDs

module dff_from_nand(); wire Q, Q_BAR; reg D, CLK; nand U1(X, D, CLK); nand U2(Y, X, CLK); nand U3(Q, Q_BAR, X); nand U4(Q_BAR, Q, Y); initial begin $monitor("CLK=%b D=%b Q=%b Q_BAR=%b", CLK, D, Q, Q_BAR); CLK=0; D=0; #3 D=1; #3 D=0; #3 $finish; end always #2 CLK = ~CLK; endmodule

This mimics the latch + clock behavior of a flip-flop.


🟢 Example – Multiplexer from Primitives

module mux_from_gates (); reg c0,c1,c2,c3,A,B; wire Y; not (a_inv, A), (b_inv, B); and (y0, c0, a_inv, b_inv); and (y1, c1, a_inv, B); and (y2, c2, A, b_inv); and (y3, c3, A, B); or (Y, y0, y1, y2, y3); initial begin $monitor("c0=%b c1=%b c2=%b c3=%b A=%b B=%b Y=%b", c0,c1,c2,c3,A,B,Y); c0=0;c1=0;c2=0;c3=0; A=0; B=0; #1 A=1; #2 B=1; #4 A=0; #8 $finish; end endmodule

This is a 4:1 multiplexer built using just NOT, AND, OR gates.


🎯 Key Takeaways

✔ Verilog primitives are the basic hardware blocks for modeling real circuits.
✔ Delays (rise, fall, turn-off) bring realism to simulations.
✔ We can build larger designs like AND gates, D-FFs, and MUXes using only primitives.
✔ Understanding min/typ/max delays is crucial for ASIC design and timing analysis.

Comments

Popular posts from this blog

Fundamental of python : 1.Python Numbers