Sign in

Learn

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

Practice

One Interface, Many Implementations

Anatomy of a Component split a component into an interface and an implementation. This lesson is where that split earns its keep: one interface can front several implementations, and you pick which one runs without touching anything that uses the component.

Why would you want two implementations of the same thing?

  • A straightforward version to get working first, then a leaner or faster version later, with the original kept around to test against.
  • A quick simulation-only model standing in for a circuit that isn't written yet.
  • Comparing forms of the same function, like a truth-table expression against its K-map-minimized form from Digital Foundations.

This lesson's example does the third: an alarm that fires when two redundant door sensors disagree. It is implemented once with the XOR operator and once with the gates that build it.

Two Implementations of the Alarm

The interface is the contract both implementations honor.

In VHDL it's declared exactly once, as the entity:

entity mismatch_alarm is
  port (
    sensor_a : in  std_logic;
    sensor_b : in  std_logic;
    alarm    : out std_logic
  );
end entity mismatch_alarm;

Now the two implementations.

In VHDL they are two architectures of that one entity, each tied to it by name (of mismatch_alarm) and carrying its own name (direct, gates):

architecture direct of mismatch_alarm is
begin
  alarm <= sensor_a xor sensor_b;
end architecture direct;

architecture gates of mismatch_alarm is
begin
  alarm <= (sensor_a and not sensor_b)
          or (not sensor_a and sensor_b);
end architecture gates;

Any number of architectures can coexist for one entity; same file or separate files, the library keeps them all.

Choosing One

Whoever uses a component decides which implementation runs. Using a component inside another (instantiation) gets its full treatment in Hierarchy and Reuse. But you've already been on the receiving end of one: every exercise testbench instantiates your design under the label dut. Here is how this lesson's testbench requests the direct implementation; read it as "build this implementation, wired to these signals":

dut_direct : entity work.mismatch_alarm(direct)
  port map (
    sensor_a => sensor_a,
    sensor_b => sensor_b,
    alarm    => alarm_direct
  );

The selector is the architecture name in parentheses. Change (direct) to (gates) and a different circuit gets built, while every connection stays the same.

Configurations: the Choice as Its Own File

VHDL can take the choice one step further: a configuration declaration is a separate design unit whose only job is to record which architecture an instance uses. This is a preview, not part of this lesson's example. Imagine some other testbench, some_alarm_tb, holding a single instance of the alarm under the label dut:

configuration pick_gates of some_alarm_tb is
  for tb
    for dut : mismatch_alarm
      use entity work.mismatch_alarm(gates);
    end for;
  end for;
end configuration pick_gates;

Read it top to bottom: "inside testbench some_alarm_tb's architecture tb, the instance dut of mismatch_alarm shall use architecture gates." Nobody edits the design or the testbench; the choice lives in its own swappable unit. The example panel's testbench has no use for one: it already names each architecture directly at the instantiation, as you saw above. Configurations pair with a different instantiation style (component instantiation) that you haven't met yet. Both arrive together in Hierarchy and Reuse, where you'll write a configuration yourself. For now, remember only that the binding can live outside the design files.

Mechanism Summary

VHDLSystemVerilog
Interface lives inthe entity, declared onceevery module header, repeated per sibling
Implementation lives inan architecture (many per entity)the module body (one per module)
Adding an implementationanother architecture of the same entitya sibling module with the same port list
Selecting onearchitecture name at instantiation, or a configurationmodule name at instantiation

In the Example

The example panel on the right holds the complete alarm.

It's a single file: the entity plus both architectures.

The testbench instantiates both implementations side by side and walks through all four sensor combinations. In the waveform, compare alarm_direct with alarm_gates: they match on every input, high exactly when the two sensors disagree. Two different circuits, one observable behavior. That interchangeability is the whole point of keeping the interface fixed.

Key Takeaways

  • An interface is a contract: implementations behind it are swappable without touching the component's users.
  • VHDL separates the two in syntax: one entity, many named architectures, selected at instantiation or in a configuration declaration (hands-on in Hierarchy and Reuse).
Loading editor...
Waveform not yet available. Run sync-content --examples to generate.