I am writing a specified UART component in VHDL.
send: process(send_start)
variable bit_index : integer range 0 to 2 := 0;
begin
if (falling_edge(send_start)) then
if (start = '0' and transceiver_start = '1') then
bit_index := 0;
end if;
transceiver_start <= '1';
if (bit_index = 0) then
temp_data <= data.RE;
bit_index := 1;
transceiver_start <= '0';
delay_counter <= 0;
elsif (bit_index = 1) then
temp_data <= data.IM;
bit_index := 2;
transceiver_start <= '0';
end if;
end if;
end process;
The falling edge of the transceiver_start
signal triggers the sub-component to run. I wanted to trigger it twice, but I do not know how to generate a second falling edge.
I thought about using a concurrent process, which would basically reset the transceiver_start
signal to it's hi-state after delay_counter
reaches some limit. Therefore I could bring it down inside the send
process again to generate a falling edge. However, this makes me have two driving processes for the delay_counter
signal, and I read that having resolution functions is not a good practice for synthesis (this code needs to be synthesizable.)
Is there any way for me to generate that falling edge when bit_index = 1
?
FPGA devices and related synthesis tools are optimized for synchronous logic, thus VHDL where a clock triggers process execution. Using a specific signal to trigger process execution, as in the question code, is thus not in line with the indented FPGA and VHDL design methodology.
Instead, use an internal clock to trigger process execution, usually the rising
edge of the clock. Actual update inside the process can then be conditional on
detection of change to a control signal, which can be send_start
.
process (clock) is
begin
if rising_edge(clock) then
send_start_prev <= send_start; -- Previous for edge detection
if ((send_start = '0') and (send_start_prev = '1')) then -- Falling edge of send_start
... -- More code
end if;
end if;
end process;
For rerunning of conditional process code, for example based on bit_index = 1
, the process contents can be updated like:
send_start_prev <= send_start; -- Previous for edge detection
rerun_request <= '0'; -- Default no rerun
if ((send_start = '0') and (send_start_prev = '1')) or -- Falling edge of send_start
(rerun_request = '1') then -- Rerun request
if bit_index = 1 then
rerun_request <= '1';
end if;
... -- More code
end if;