Topic 11 · Digital Electronics

Encoders & Decoders

Priority encoder, 2-to-4 decoder, BCD-to-7-segment, binary-to-Gray code — with three interactive simulators, Verilog for every type, and VLSI applications in interrupt controllers and memory address decoding.

Overview

Encoders and decoders are complementary circuits for code conversion. An encoder compresses many input lines into a smaller binary code. A decoder expands a binary code back into individual output lines.

Encoder
2ⁿ inputs → n outputs. Converts a one-hot input to a compact binary code.
Keyboard, interrupt controller
Priority Encoder
Like encoder, but handles multiple simultaneous inputs by encoding the highest-priority active line.
IRQ controller, arbitration
Decoder
n inputs → 2ⁿ outputs. Activates exactly one output matching the binary input.
Address decode, chip select, minterm generator
BCD-to-7seg
4-bit BCD (0–9) → 7 segment drive signals for a numeric display.
Displays, meters, counters

Interactive Priority Encoder (4-to-2)

Click any input to toggle it ON. If multiple inputs are HIGH, the highest-numbered active input takes priority.

4-to-2 Priority Encoder Interactive
Click buttons to activate inputs (I3 = highest priority):
Encoded output:
Y1 (MSB)
0
Y0 (LSB)
0
Valid (V)
0
→ Encoding: No input

4-to-2 Priority Encoder Truth Table

I3I2I1I0Y1Y0V
0000XX0
0001001
001X011
01XX101
1XXX111

Verilog: Priority Encoder

module priority_enc4 (
  input  wire [3:0] in,
  output reg  [1:0] y,
  output reg        valid
);
  always_comb begin
    valid = 1'b1;
    casez (in)               // casez: 'z' matches X and Z (don't care)
      4'b1???: {y, valid} = {2'd3, 1'b1};
      4'b01??: {y, valid} = {2'd2, 1'b1};
      4'b001?: {y, valid} = {2'd1, 1'b1};
      4'b0001: {y, valid} = {2'd0, 1'b1};
      default: {y, valid} = {2'd0, 1'b0};  // no input active
    endcase
  end
endmodule

Interactive 2-to-4 Decoder

2-to-4 Decoder Interactive

Select the 2-bit input (A1, A0) to activate the corresponding output:

Select (A1A0):
Outputs:

2-to-4 Decoder Truth Table

A1A0Y0Y1Y2Y3
001000
010100
100010
110001

Verilog: 2-to-4 Decoder (with enable)

module dec2to4 (
  input  wire [1:0] a,
  input  wire       en,     // active-high enable
  output reg  [3:0] y
);
  always_comb begin
    y = 4'b0;
    if (en) y = 4'b1 << a;  // shift 1 to position 'a'
  end
endmodule

// Active-low version (like 74HC139):
// assign y_n = ~(4'b1 << a) | {4{~en}};

Verilog: 3-to-8 Decoder (74HC138 equivalent)

module dec3to8 (
  input  wire [2:0] a,
  input  wire       g1,       // active-high enable
  input  wire       g2a_n, g2b_n,  // active-low enables
  output reg  [7:0] y_n       // active-low outputs
);
  wire en = g1 & ~g2a_n & ~g2b_n;
  always_comb
    y_n = en ? ~(8'b1 << a) : 8'hFF;
endmodule

BCD-to-7-Segment Decoder

Click a digit to see which segments illuminate on the 7-segment display.

BCD-to-7-Segment Simulator Interactive
Active segments:
BCD:
Digit:
DigitBCDabcdefg

Verilog: BCD-to-7-Segment

module bcd_to_7seg (
  input  wire [3:0] bcd,
  output reg  [6:0] seg   // {a,b,c,d,e,f,g} active-high
);
  always_comb
    case (bcd)
      //        abcdefg
      4'd0: seg = 7'b1111110;
      4'd1: seg = 7'b0110000;
      4'd2: seg = 7'b1101101;
      4'd3: seg = 7'b1111001;
      4'd4: seg = 7'b0110011;
      4'd5: seg = 7'b1011011;
      4'd6: seg = 7'b1011111;
      4'd7: seg = 7'b1110000;
      4'd8: seg = 7'b1111111;
      4'd9: seg = 7'b1111011;
      default: seg = 7'b0000000;  // blank for invalid BCD
    endcase
endmodule

Binary-to-Gray Code Converter

Gray code ensures adjacent values differ by exactly one bit — critical for rotary encoders and asynchronous FIFO pointers.

Binary ↔ Gray Code Converter Interactive
Enter a binary number (up to 8 bits):
Binary
Gray Code
Decimal

Verilog: Binary-to-Gray & Gray-to-Binary

// Binary to Gray: G[i] = B[i] ^ B[i+1]  (G[MSB] = B[MSB])
module bin2gray #(parameter N = 8) (
  input  wire [N-1:0] bin,
  output wire [N-1:0] gray
);
  assign gray = bin ^ (bin >> 1);
endmodule

// Gray to Binary: B[MSB] = G[MSB]; B[i] = B[i+1] ^ G[i]
module gray2bin #(parameter N = 8) (
  input  wire [N-1:0] gray,
  output reg  [N-1:0] bin
);
  integer i;
  always_comb begin
    bin[N-1] = gray[N-1];
    for (i = N-2; i >= 0; i--)
      bin[i] = bin[i+1] ^ gray[i];
  end
endmodule
Why Gray code in async FIFOs? The read and write pointers cross clock domains. If the pointer uses binary, a count like 0111→1000 changes 4 bits simultaneously — the receiving domain may catch a glitchy intermediate value. Gray code changes only 1 bit per increment, so any single-bit glitch still decodes to an adjacent valid pointer value, preventing false full/empty signals.

Decoder as Minterm Generator

A 2-to-4 decoder simultaneously generates all 4 minterms of 2 variables. Any 2-variable Boolean function can be implemented by ORing the appropriate outputs:

FunctionBooleanDecoder implementation
ANDA·BY3 alone
ORA+BY1 OR Y2 OR Y3
XORA⊕BY1 OR Y2
XNORA⊙BY0 OR Y3
NANDĀ+B̄Y0 OR Y1 OR Y2

VLSI Applications

Interrupt Controller (Priority Encoder)

A CPU interrupt controller (like the x86 PIC 8259A or ARM GIC) accepts interrupt request lines from multiple peripherals. A priority encoder resolves simultaneous requests: it outputs the highest-priority active IRQ number and a valid signal to the CPU. The CPU uses the encoded output as an index into the interrupt vector table.

Memory Address Decoder

The memory controller uses a decoder to select which DRAM bank is active based on high-order address bits. A 3-to-8 decoder can manage 8 separate 512 MB banks to compose a 4 GB memory space. The enable input of the decoder is driven by a chip-select logic that ensures only one bank is active at a time, preventing bus contention.

One-Hot to Binary (Encoder in Arbiters)

Round-robin arbiters grant access to one requester at a time, producing a one-hot grant signal. A priority encoder converts this one-hot grant back to a binary index, used to steer the winning requester's data onto the shared bus.

Related Topics