Advanced VHDL Concepts
Distinguish elaboration, simulation and synthesis, then cover CDC, latency and advanced genericity.
Why This Chapter
At this point, the goal is not to stack more syntax. The important point is understanding when a construct acts:
- during design elaboration;
- during simulation;
- or in the synthesized hardware.
The next chapters detail IEEE functions, generate, fixed_pkg, packages and attributes. Here, we keep an overview to avoid confusion.
Elaboration, Simulation, Synthesis
| Phase | Role | Example |
|---|---|---|
| Elaboration | Build hierarchy before simulation/synthesis | generic, generate |
| Simulation | Execute the model in the simulator | wait for, assert, files |
| Synthesis | Turn RTL into registers, LUTs, DSPs, BRAMs | process, signals, operators |
A for ... generate does not loop at runtime. It creates hardware blocks during elaboration.
g_regs : for i in 0 to g_WIDTH - 1 generate
U_FF : entity work.dff
port map (
i_clk => i_clk,
i_d => i_d(i),
o_q => o_q(i)
);
end generate g_regs;If g_WIDTH = 8, the design contains 8 instances. It is not a software loop inside the FPGA.
Synthesizable or Testbench
Everything valid in VHDL is not necessarily synthesizable.
| Construct | Recommended use |
|---|---|
wait for 10 ns | Testbench |
file, textio, hread | Testbench |
real as a signal | Simulation, not RTL |
Simple assert | Possible in RTL, mostly verification/simulation |
rising_edge(i_clk) | Synchronous RTL |
process(i_clk) | Synchronous RTL |
Practical rule: if code describes an absolute delay, a file or a scenario, it probably belongs in a testbench.
Advanced Genericity
Classic generic parameters configure a width, depth or option. VHDL-2008 also allows more advanced forms, such as generic types.
entity delay_line is
generic (
type t_DATA;
g_DEPTH : positive := 4
);
port (
i_clk : in std_logic;
i_d : in t_DATA;
o_q : out t_DATA
);
end entity delay_line;The idea is to make a block independent from the transported data type. This is powerful for internal libraries, but exact support depends on tools. At first, keep generics simple: width, depth, boolean option.
Clock Domain Crossing
A signal crossing from one clock to another can become metastable. For a slow 1-bit signal, the minimal idiom is a two-flip-flop synchronizer in the destination domain.
process(i_clk_dst)
begin
if rising_edge(i_clk_dst) then
r_meta <= i_async;
r_sync <= r_meta;
end if;
end process;For a bus, this is not enough. Use a handshake protocol, an asynchronous FIFO or an equivalent mechanism. Synchronizing each bit separately can produce an incoherent word.
Latency and Interface Contract
An advanced design often has latency: pipeline, FIFO, filter, iterative computation. That latency must be part of the contract.
-- Example: i_valid enters at cycle N.
-- o_valid must leave at cycle N+3 with the matching data.The testbench should verify:
- the value;
- the exact cycle where it becomes valid;
- reset behavior;
- cycles where
i_valid = '0'.
A faster pipeline is not useful if the output is no longer aligned with its valid signal.
Keep the Right Abstraction Level
Advanced constructs do not automatically make a design better. They are useful when they clarify the contract or remove real duplication.
- Use
generatefor repeated structures. - Use a package for shared types.
- Use attributes to avoid hardcoded sizes.
- Use a pipeline when the critical path is too long.
- Avoid hiding simple logic behind too much abstraction.
Key Point
| Topic | Question to ask |
|---|---|
generate | Is this a repeated hardware structure? |
| Testbench | Is this a simulation scenario? |
| CDC | Does the signal cross a clock domain? |
| Pipeline | What is the exact latency? |
| Genericity | Is this truly reusable? |
Advanced VHDL is mostly about writing a design whose behavior, latency and limits are explicit.
📝 Test your knowledge - Chapter quiz