So this code generates a 200 Hz clock based on a 100 Mhz clock.
We note that: 100 MHz / 500000 = 200 Hz
So, we need to take our 100 Mhz clock, and every 500000 cycles, we would have a full cycle of the 200 Hz clock that we would like to generate. Since we want the high time and low time to be the same, we know that we should oscillate the new clock every 500000 / 2
cycles.
From the perspective of the code, we will use hexadecimal, so it's worth noting that 500000 / 2 == 0x3D090
.
architecture foo of blah is
signal clk_200Hz : std_logic := '0';
signal counter : unsigned(19 downto 0) := x"00000";
begin
clkdiv : process (clk_100Mhz)
begin
if rising_edge(clk_100Mhz) then
if counter = x"00000" then
counter <= X"3D090"
clk_200Hz <= not clk_200Hz;
else
counter <= counter - 1;
end if;
end if;
end process clkdiv;
end architecture;
A concurrent signal assignment statement of the form:
OUTPUT <= CLK AND VAR;
Has an equivalent process (how it's simulated) of the form:
process
begin
OUTPUT <= CLK AND VAR;
wait on CLK, VAR; -- wait on 'sensitivity list'
end process;
With the wait statement the equivalent of putting both right hand side signals in a sensitivity list.
The second process is already sensitive to CLK events, the if CLK'EVENT
is redundant. I'd suggest that your synthesis tool should likely have generated a warning and may have not produced an assignment to OUTPUT, something examining synthesis warnings, any produced net list or generated schematic might indicate. Otherwise the second and third processes are equivalent.
You're likely to get warning for both the second and third process statements that VAR is missing from the sensitivity list, which is likely ignored for synthesis purposes. The effect of this is not have closure between simulation results pre- and post-synthesis.
Note that what you've defined is a gated clock and having VAR in the sensitivity list won't matter unless VAR transitions before the rising edge of CLK or after the falling edge of CLK, in which case it could move the OUTPUT clock edge (if OUTPUT'EVENT and OUTPUT = '1'
, if rising_edge(OUTPUT)
, or the same for the falling edge).
And if VAR could screw up your resulting 'clock' edge you have a problem that should be addressed anyway.
(And of course someone is bound to chime in that a sensitivity list can use the reserved word all to signify all right hand side signals in VHDL-2008).
addendum
The questioner has indicated he's trying to gate clocks, and from added information to his question shows this is using Xilinx tools.
Xilinx recommends against gating clocks this way [1], the most obvious reason is that clock skew becomes dependent on routing to and from a LUT as well as the the LUT delay itself. You could imagine trying to balance delays in all your clocks. With clocks generated from a higher clock rate you could for instance disable a clock with a clear or reset. The idea here is match delays on gated and non gated clocks as an FPGA implementation issue above and beyond all the measures you'd take to cross clock boundaries otherwise.
Xilinx supports gated clocks in series 7 FPGAs and ZYNQ devices using dedicated clock enables through the use of the paid version of ISE (Vivaldo), something called intelligent clock gating, where you don't gate your clocks, you let the tools do it for you.
You could also note the period constraint is lost passing through an non-sequential element manually gating clocks.
[1]
White Paper: HDL Coding Practices to Accelerate Design Performance, around Figure 11. Starting on Page 10, Clock Enable and Gated Clocks.
Best Answer
Flag state will be sampled on the next clock edge. In the synchronous design, all the conditions are (or must be) "prepared" before clock edge occurs, and when it occurs, circuit transitions to new state within very short timeframe. Thus in situations like yours circuit will see previously "prepared" condition, thus previous state of the flag. On the next clock edge new flag value will be "prepared", and it will be sampled.
You spend whole cycle to get the new propagated flag value; you may consider to trigger one process on rising edge, and another process on the falling edge, this way you will spend only half of the cycle.
Update (as per comments below): when designing circuits driven by both edges of the clock, you must pay close attention to the duty cycle of the clock, not just its period.