Distinguish elaboration, simulation and synthesis, then cover CDC, latency and advanced genericity.
A VHDL construct may act during elaboration, simulation or in the described hardware. Distinguishing those stages helps explain generics, repeated structures and latency.
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
Create a structure during elaboration
for / generate creates instances before model execution:
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;
With g_WIDTH = 8, this fragment contains eight instances. The FPGA does not execute them by running a software loop.
Generics set width, depth or options. VHDL-2008 also permits 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 block can then accept different data types. Check support for this construct; size parameters or a Boolean option often meet the requirement.
Separate RTL from test scenarios
Simulator acceptance does not imply synthesizability:
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
Absolute delays, files and stimulus sequences often indicate testbench code. IEEE functions, fixed_pkg and packages likewise need uses appropriate to simulation or hardware calculations.
Cross domains and preserve latency
An asynchronous signal can make a flip-flop metastable. For a sufficiently slow single-bit signal, two destination-domain flip-flops form a common synchronizer:
process(i_clk_dst)begin if rising_edge(i_clk_dst) then r_meta <= i_async; r_sync <= r_meta; end if;end process;
It reduces risk without guaranteeing capture of a short pulse. Synchronizing bus bits separately can produce an inconsistent word. Use a handshake, asynchronous FIFO or mechanism suited to the transfer.
A pipeline, FIFO, filter or iterative calculation adds delay that belongs in the interface contract:
-- Example: i_valid enters at cycle N.-- o_valid must leave at cycle N+3 with the matching data.
The testbench checks value, valid cycle, reset and cycles with i_valid = '0'. Data and validity must remain aligned.
Choose constructs for specific needs: generate for repeated structure, packages for shared types, attributes for derived sizes and pipelines for shorter critical paths. Keep simple logic visible.