Sign in

Learn

0/8
0/6
0/6
0/6

Practice

Anatomy of a Component

In Digital Foundations you described logic with single assignments, but the file around them was always written for you. This topic removes the scaffolding. Every design you will ever write is a component: a box with named pins on the outside and circuitry on the inside. This lesson walks through both halves: the interface the outside world sees, and the implementation hidden behind it. By the end you can write a complete design file from the first line to the last.

Think of a chip on a circuit board. The board only cares about the pins: their names, which way each signal flows, what kind of signal it carries. What happens inside the package is invisible from outside. HDL components draw exactly the same line, and the language splits the file along it.

The Interface

Here is the interface of this lesson's example, a watchdog that monitors a status line:

entity line_monitor is
  port (
    line_in  : in  std_logic;
    line_out : out std_logic;
    alarm    : out std_logic
  );
end entity line_monitor;

VHDL calls this unit an entity.

Each line inside the parentheses declares one port, one pin on the box, and every port answers three questions:

  • Name: line_in, line_out, alarm. Plain names that say what the pin carries: the declaration already states which way it flows, so the name doesn't have to. Some teams do add direction suffixes like _i/_o to every port, and you will meet that style in code elsewhere.
  • Direction: in means the outside world drives the pin and the component reads it; out is the reverse. There is a third direction, inout, for shared wires. That's the subject of Port Directions, the last lesson of this topic.
  • Type: std_logic means "one wire". The wider world of types opens up in Signals and Data Types.

Where std_logic Comes From

The type std_logic is not built into the language. It lives in a package, and every file that uses it starts with the same two lines, above the entity:

library ieee;
use ieee.std_logic_1164.all;

The first line makes the ieee library visible; the second pulls in everything from its std_logic_1164 package, including std_logic. For now treat the pair as a fixed preamble: copy it to the top of every VHDL file. A second ieee package, numeric_std, holds the number types used for arithmetic. You'll add a use ieee.numeric_std.all; line beneath the first when those types appear in Numeric Types and Constants.

The Implementation

The second half of the file describes what's inside the box:

architecture rtl of line_monitor is
begin
  line_out  <= line_in;
  alarm <= not line_in;
end architecture rtl;

VHDL puts the implementation in a separate unit, the architecture, tied to its entity by name (of line_monitor). The architecture also carries a name of its own: rtl here, the conventional name for synthesizable code.

The two statements are connections, not steps.

line_out <= line_in doesn't copy a value once and move on; it permanently wires line_out to line_in.

Solder, not assignment. Whenever line_in changes, line_out follows. Both statements are active all the time, so their order in the file doesn't matter. Why they're written this way, and what else they can do, is the subject of Concurrent Statements.

One Driver, Many Readers

Look closely at line_in: it feeds both statements. That's fan-out: one signal may be read by any number of statements, just as one pin can be soldered to many destinations. The reverse is not allowed: each signal must be driven from exactly one place. A second assignment to line_out would not "overwrite" the first; it would put two drivers on the same wire, fighting each other. (Wires that are deliberately shared between drivers taking turns do exist. That's what inout ports are for, in Port Directions.)

Putting It Together

The example panel on the right assembles the whole file: every piece from this lesson, in order. The story: line_in comes from a remote sensor that holds the wire high while it's healthy. The monitor passes the level through on line_out and raises alarm whenever the line drops. In the waveform, watch line_out copy line_in exactly, while alarm is its mirror image, high in precisely the intervals where line_in is low. All three move at the same instant: nothing in this design stores anything, these are wires.

One entity can have more than one architecture: the same interface fronting different implementations. That's the next lesson: One Interface, Many Implementations.

Key Takeaways

  • A design file has two halves: the interface (the entity, with name, direction, and type for every port) and the implementation (the architecture).

  • Concurrent assignments are permanent connections: solder, not steps. Their order in the file doesn't matter.

  • One signal has exactly one driver but any number of readers.

Loading editor...
Waveform not yet available. Run sync-content --examples to generate.