0
0
VerilogHow-ToBeginner · 3 min read

Verilog Code for 3-to-8 Decoder: Syntax and Example

A 3-to-8 decoder in Verilog converts 3 input bits into 8 output lines, where only one output is active at a time. You can write it using a case statement inside an always block or with continuous assignments using bit shifts.
📐

Syntax

The basic syntax for a 3-to-8 decoder uses an always block triggered by changes in the input. Inside, a case statement selects which output line to activate based on the 3-bit input.

  • input [2:0] in: 3-bit input signal.
  • output reg [7:0] out: 8-bit output signal, one-hot encoded.
  • always @(*): Sensitivity list for combinational logic.
  • case (in): Selects output line based on input value.
verilog
module decoder3to8(input [2:0] in, output reg [7:0] out);
  always @(*) begin
    case (in)
      3'b000: out = 8'b00000001;
      3'b001: out = 8'b00000010;
      3'b010: out = 8'b00000100;
      3'b011: out = 8'b00001000;
      3'b100: out = 8'b00010000;
      3'b101: out = 8'b00100000;
      3'b110: out = 8'b01000000;
      3'b111: out = 8'b10000000;
      default: out = 8'b00000000;
    endcase
  end
endmodule
💻

Example

This example shows a complete 3-to-8 decoder module and a simple testbench that cycles through all input values. The output activates only one bit corresponding to the input.

verilog
module decoder3to8(input [2:0] in, output reg [7:0] out);
  always @(*) begin
    case (in)
      3'b000: out = 8'b00000001;
      3'b001: out = 8'b00000010;
      3'b010: out = 8'b00000100;
      3'b011: out = 8'b00001000;
      3'b100: out = 8'b00010000;
      3'b101: out = 8'b00100000;
      3'b110: out = 8'b01000000;
      3'b111: out = 8'b10000000;
      default: out = 8'b00000000;
    endcase
  end
endmodule

module testbench;
  reg [2:0] in;
  wire [7:0] out;
  decoder3to8 uut(.in(in), .out(out));

  initial begin
    $display("Input | Output");
    for (integer i = 0; i < 8; i = i + 1) begin
      in = i;
      #10;
      $display("%b    | %b", in, out);
    end
    $finish;
  end
endmodule
Output
Input | Output 000 | 00000001 001 | 00000010 010 | 00000100 011 | 00001000 100 | 00010000 101 | 00100000 110 | 01000000 111 | 10000000
⚠️

Common Pitfalls

Common mistakes when writing a 3-to-8 decoder include:

  • Not covering all input cases, which can cause latches or undefined outputs.
  • Forgetting to declare the output as reg when using always blocks.
  • Using blocking assignments (=) incorrectly in sequential logic (should use non-blocking <= only in sequential always blocks).
  • Not including a default case, which can lead to simulation mismatches.

Example of a wrong approach missing default case:

verilog
module wrong_decoder(input [2:0] in, output reg [7:0] out);
  always @(*) begin
    case (in)
      3'b000: out = 8'b00000001;
      3'b001: out = 8'b00000010;
      // Missing other cases and default
    endcase
  end
endmodule

// Corrected version includes all cases and default as shown in previous examples.
📊

Quick Reference

Tips for writing a 3-to-8 decoder in Verilog:

  • Use always @(*) for combinational logic.
  • Declare output as reg if assigned inside always block.
  • Use case statement to select output line.
  • Include a default case to avoid latches.
  • Test all input combinations in a testbench.

Key Takeaways

A 3-to-8 decoder activates one of eight outputs based on 3 input bits using a case statement.
Always use an always block with a complete case including a default to avoid unintended latches.
Declare outputs as reg when assigned inside always blocks for combinational logic.
Test all input combinations to verify correct output activation.
Avoid missing cases or default to prevent simulation mismatches and hardware issues.