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
regwhen usingalwaysblocks. - Using blocking assignments (
=) incorrectly in sequential logic (should use non-blocking<=only in sequential always blocks). - Not including a
defaultcase, 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
regif assigned insidealwaysblock. - Use
casestatement to select output line. - Include a
defaultcase 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.