input_reg: PROCESS IS
BEGIN
WAIT UNTIL clk = '1';
data_in_i <= data_in;
END PROCESS input_reg;
I stronly agree with inferring a register, rather than instantiating
one. Instantiated primitive names are often not portable across
differen devices.
There are lots of ways to infer a register; the simplest is probably:
data_in_i <= data_in when rising_edge(clk); -- concurrent statement,
no process needed
Where data_in_i is the output of the inferred register.
However, I believe a more standard (and more appropriate for new
users) process template for inferring one or more registers is as
follows:
input_reg: process (clk) is
begin
if rising_edge(clk) then
data_in_i <= data_in;
end if;
end process;
The rising_edge() function specifically avoids simulation problems
from strange transitions on the clock signal. Pieter's template could
be improved in this regard by using "wait until rising_edge(clk);"
The wait statement template is more difficult to add an asynchronous
reset input.
For an asynchronously reset register:
input_reg: process (clk, rst) is
begin
if rst = '1' then -- active high reset
data_in_i <= (others -> '0');
elsif rising_edge(clk) then
data_in_i <= data_in;
end if;
end process;
Or, in the concurrent template:
data_in_i <= (others => '0') when rst = '1'
else data_in when rising_edge(clk);
All of these are roughly equivalent if all you need to do is insert a
register between two other entities, etc. If you are also specifying
the logic that is in between the registers, the process templates are
much better suited, since you can describe the logic and the registers
in the same process, at the same time.
Andy