08-13-2019 10:58 PM
I am trying to do a custom UART - RX module in VHDL. I am able to receive the data sent from PC.
But my problem is when RX wire is disconnected and re-connected my data will be erroneous.
In my current logic, I didnt add any error control mechanism. What could be the possible ways of doing the same?
How can I detect that my cable is reconnected so that I can set my FSM to a default or reset state? FSM is attached in the image.
Thanks & Regards,
08-14-2019 01:49 AM - edited 08-14-2019 02:13 AM
-try using a timeout timer. That is, write a VHDL process that, when triggered, will count down from some constant value to zero and then raise a time-out flag.
Then, in the VHDL process that implements your FSM, the IDLE state should trigger the timeout timer when a start bit is detected on the RX wire. If the IDLE state does not detect the start bit then it turns off the timeout timer. Also in this VHDL process, write new code that checks the timeout flag before allowing control to enter the FSM. If the new code finds that the timeout flag is set, then it clears the flag and tells the FSM to return to the IDLE state.
08-14-2019 02:30 AM
Hi firstname.lastname@example.org ,
Thanks for your reply.
But I didnt get it properly. I will describe the logic to be implemented as per your suggestion. Please correct me if I am wrong.
Could you please give more clarity?
Thnaks & Regards,
08-14-2019 04:31 AM
UART doesn't really have any good error control mechanisms. That said, there are two things you might consider using:
After those two, if you are still having problems, then you may need to get fancy.
These last two only sort of match the serial protocol, but they might match good enough for you to be successful trying them.
Just my thoughts,
08-14-2019 05:24 AM - edited 08-14-2019 05:25 AM
The VHDL snippets below shows key concepts of the timeout timer approach. Note how run_timer is used to start and stop the timeout timer and to clear the flag, timeout.
type state_type1 is (IDLE,s_RX_START,s_RX_Data,....); signal my_state : state_type1; signal CLK, RST, run_timer, timeout : std_logic; -- P1: process(CLK) --timeout timer constant CNTRMAX : integer := 10000; variable cntr : integer range 0 to CNTRMAX; begin if rising_edge(CLK) then if(run_timer = '0') then cntr := CNTRMAX; timeout <= '0'; else if(cntr = 0) then timeout <= '1'; else cntr := cntr - 1; timeout <= '0'; end if; end if; end if; end process P1; P2: process(RST,CLK) --Reshma FSM begin if rising_edge(CLK) then if ((RST = '1') or (timeout = '1')) then run_timer <= '0'; my_state <= IDLE; else case my_state is when IDLE => if (start_bit = '1') then --start bit detected? run_timer <= '1'; my_state <= s_RX_START; else run_timer <= '0'; my_state <= IDLE; end if; when s_RX_START => ... when s_RX_Data => ... end case; end if; end if; end process P2;
08-14-2019 05:35 AM
Hi email@example.com ,
Thanks for your kind support.
I missed the point.
if ((RST = '1') or (timeout = '1')) then
run_timer <= '0';
my_state <= IDLE;
Now the logic is almost clear. I will try to implement the same & update the results .