Hello I am new to VHDL and I want to ask if it is ok to have a process like this where I have multiple clocks in one process C256Hz and C4Hz are clock enables driven from the 50MHz clock
process (Reset, C50Mhz, Go, start_flag, C256Hz, C4Hz)
begin
if reset = '1' then
start_flag <= '0';
elsif rising_edge (C50Mhz) then
if C4Hz = '1' then
if count4 = "11" and single_run_flag = '0' then
start_flag <= '0';
end if;
end if;
if C256Hz = '1' then
if Go = '1' and start_flag = '0' then
start_flag <= '1';
end if;
end if;
end if;
end process; `
It is okay, but whether synthesis will generate a good result depends on the fabric.
The sensitivity list should have just reset
and C50MHz
, because these are the only events that actually change signals. When C4Hz
toggles, then rising_edge(C50MHz)
is false
, because these are not synchronized, and nothing would happen if the process were to run then.
The separate enable can be assumed to be available everywhere -- clock fanout is so high that everyone implements separate clock distribution networks, and the enable on the registers is required then. So this is safe to use.
The asynchronous reset might not be available on all fabrics, but usually is. Some devices will support asynchronous load (i.e. you can decide the value to be taken on reset), others only reset (i.e. you can set the register to zero only, and initializing to one would generate an inverted table, a register with reset-to-zero, and an inverter in the next LE.
So in general, this is fairly safe, this can be synthesized as
-- intermediates
do_clear_start_flag := C4Hz = '1' and count4 = "11" and single_run_flag = '0';
do_set_start_flag := C256Hz = '1' and Go = '1' and start_flag = '0';
-- to register
enable_start_flag := do_clear_start_flag or do_set_start_flag;
new_start_flag := do_set_start_flag;
The check for the old value of start_flag
in do_set_start_flag
cannot be optimized out even if setting start_flag
has no effect if it has been set before, because it might just be reset in the current clock cycle.
If the block beginning with if C256Hz = '1'
were an elsif
instead, the second intermediate would read
do_set_start_flag := C256Hz = '1' and Go = '1' and do_clear_start_flag = '0'