HomeFPGA from ScratchDay 5
DAY 5 · FPGA FOUNDATIONS

Verilog vs VHDL & Your First Module

By EcrioniX · Updated Jun 7, 2026

Time to actually write hardware. First we'll settle the age-old question — Verilog or VHDL? — then dissect a Verilog module piece by piece, and finally write your first real design: a 2-to-1 multiplexer, complete with a testbench you can run in the browser. Every port explained, nothing skipped.

1. Verilog vs VHDL — which to learn?

There are two main hardware description languages (HDLs), and beginners always ask which to pick. Both describe hardware and both synthesize to the same gates — the difference is mostly style:

VerilogVHDL
Feelconcise, C-likeverbose, Ada-like
Typinglooser, quickerstrict, more checks
Popular inUS, Asia, most industryEurope, aerospace/defence
Lines for a mux~5~15

For this course we use Verilog — it's shorter, dominant in industry, and runs in our online simulator. (Once you know one, the other is easy to read.) For deeper Verilog, see our Verilog tutorials.

2. Anatomy of a Verilog module

The basic building block in Verilog is the module — one block of hardware. It always has the same skeleton:

3. Your first design — a 2-to-1 multiplexer

A multiplexer (mux) is a digital switch: it picks one of several inputs to pass to the output, chosen by a select line. A 2-to-1 mux chooses between two inputs a and b using sel:

2-to-1 multiplexer (mux2) MUX a b sel y sel=0 → y=a sel=1 → y=b
Figure — A 2:1 mux: output y follows a or b depending on sel.

Here's the whole design — five lines. Copy or download it:

mux2.v — the design module
// EcrioniX · FPGA from Scratch — your first module: a 2-to-1 multiplexer
module mux2 (
    input  wire a,      // data input 0
    input  wire b,      // data input 1
    input  wire sel,    // select: 0 picks a, 1 picks b
    output wire y       // output
);
    assign y = sel ? b : a;   // if sel==1 -> y=b, else y=a
endmodule

Every port, explained cleanly

PortDirWidthMeaning
ainput1 bitData input chosen when sel = 0.
binput1 bitData input chosen when sel = 1.
selinput1 bitSelect line — decides which input passes through.
youtput1 bitThe output — equals a or b per sel.

The single line assign y = sel ? b : a; is a ternary: "if sel is 1, y = b, otherwise y = a." assign means this is combinationaly updates instantly whenever an input changes, no clock involved.

4. The testbench (always test before hardware!)

A design isn't done until you've verified it. A testbench is a special module with no ports that creates the design, drives its inputs through every case, and prints the results. Here's one for our mux — copy/download and run it alongside mux2.v:

tb_mux2.v — the testbench
// Testbench for mux2 — drives all input combinations and prints the result.
`timescale 1ns/1ps
module tb_mux2;
    reg  a, b, sel;     // 'reg' = signals we drive from the testbench
    wire y;             // 'wire' = output we observe

    // Instantiate the design under test (DUT), connecting ports by name
    mux2 dut (.a(a), .b(b), .sel(sel), .y(y));

    integer i;
    initial begin
        $display(" sel a b | y");
        $display(" ---------+--");
        for (i = 0; i < 8; i = i + 1) begin
            {sel, a, b} = i[2:0];   // walk through all 8 combinations
            #1;                     // wait 1 ns for y to settle
            $display("  %b  %b %b | %b", sel, a, b, y);
        end
        $finish;
    end
endmodule

▶ Run it — expected output

Paste both files into the online Verilog simulator and Run. When sel=0, y follows a; when sel=1, y follows b:

 sel a b | y
 ---------+--
  0  0 0 | 0
  0  0 1 | 0
  0  1 0 | 1   <- sel=0, y follows a
  0  1 1 | 1
  1  0 0 | 0
  1  0 1 | 1   <- sel=1, y follows b
  1  1 0 | 0
  1  1 1 | 1

If your output matches, congratulations — you've designed, simulated and verified your first piece of hardware. 🎉 Notice the testbench uses reg for signals it drives and wire for the output it watches, and connects ports by name (.a(a)) — habits we'll keep all course.

5. The same module in VHDL (just so you've seen it)

For contrast, the identical mux in VHDL — notice how much more ceremony it needs. You don't need to write VHDL in this course, just recognise it:

mux2.vhd — VHDL version (for comparison)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux2 is
    port ( a, b, sel : in  STD_LOGIC;
           y         : out STD_LOGIC );
end mux2;
architecture rtl of mux2 is
begin
    y <= b when sel = '1' else a;
end rtl;

💡 Design vs. testbench

Think of the design module as the product you're building, and the testbench as the quality-inspector who pokes every button and checks every light before it ships. The inspector (testbench) never goes into the final product — it has no ports and isn't synthesized — but you never ship without it. Design + testbench always travel together.

✅ Day 5 in one line

Verilog (concise, industry-standard) and VHDL (verbose, strict) both describe hardware; we use Verilog. A module = module…endmodule with ports (input/output, optional width) and logic. Your first design, a 2:1 mux, is one line: assign y = sel ? b : a; — and you verify it with a testbench (a port-less module that drives inputs and prints outputs) before ever touching hardware.

🎯 Day 5 takeaways

Quick check

  1. What does assign y = sel ? b : a; do?
  2. What's the difference between input and output ports? What does [7:0] mean?
  3. Why does a testbench have no ports of its own?
  4. In a testbench, which signals are reg and which are wire, and why?

FAQ

Verilog vs VHDL?

Verilog is concise and C-like (US/Asia/industry); VHDL is verbose and strict (Europe/defence). Both synthesize to the same hardware.

What is a module?

Verilog's basic block — module…endmodule with ports (inputs/outputs) and logic; can be instantiated inside other modules.

What is a testbench?

A port-less, non-synthesizable module that instantiates your design, applies stimulus and prints/checks outputs in simulation.

How do I write a 2:1 mux?

A module with inputs a, b, sel and output y, and one line: assign y = sel ? b : a;.

Previous
← Day 4: The design flow

← Back to the full roadmap  ·  Run this in the Verilog simulator →