Search code examples
vhdlfpga

Buffering an input parameter to the process statement


Take the following code for example:

s_Clock_Data <= pi_Clock_Data;

Shifter :
process(s_Clock_Data)
begin
    if falling_edge(s_Clock_Data) then
        s_Shifter <= s_Shifter(s_Shifter'high - 1 downto 0) & pi_Data;
    end if;
end process;

Where pi_Clock_Data and pi_Data are port inputs to the module.

Is there a certain reason that requires pi_Clock_Data to be first assigned to s_Clock_Data before the process can run? Since pi_Data is also an input to the fpga, it seems that by doing this, the clock data could be lagging behind by a delta cycle with respect to pi_Data.

Couldn't we just have process(pi_Clock_Data) instead?


Solution

  • Reassigning the clock should be avoided, due to the reason of delta cycle delay that you describe.

    It will have no effect on the synthesis result, but it is likely to cause problems in simulation, for example if several nested modules does reassigning of the clock, whereby the clock can end up being delayed by numerous delta delays, but the related data may not have similar delta delay, whereby the design will not simulate as the expected synchronous design.

    The image below show what happens, where clk updates cnt, clk is also used to capture cnt to cap_clk, and clk is then reassigned as:

    clk_delta_1 <= clk;
    

    and clk_delta_1 is then used to capture cnt to cap_delta_1. The result is that cap_clk and cap_delta_1 does not capture the same values in simulation.

    enter image description here

    However, in the synthesized design, the clk_delta_1 <= clk; will be a plain wire, so cap_delta_1 will capture based on clk, so simulation and synthesis result will not be the same for the design in this case, which is the reason reassigning clocks should be avoided.

    If for some reason a renaming of the signal is required, then an alias can be used, thus making a new name for clk without a delta delay, like:

    alias clk_delta_0 : std_logic is clk;
    

    As the figure shows, then cnt captured on clk_delta_0 to cap_delta_0 will have the same values as the cap_clk, since there is no delta delay between clk and clk_delta_0. However, such renaming should be avoided if possible, since it makes reading the searching the code difficult.