I have been trying to design an RS-232 receiver taking an FSM approach. I will admit that I do not have a very well-rounded understanding of VHDL, so I have been working on the code on the fly and learning as I go. However, I believe I've hit a brick wall at this point.
My issue is that I have two processes in my code, one to trigger the next state and the other to perform the combinational logic. My code is as follows:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity ASyncReceiverV4 is Port ( DataIn : in STD_LOGIC; Enable : in STD_LOGIC; CLK : in STD_LOGIC; BadData : out STD_LOGIC; DataOut : out STD_LOGIC_VECTOR (7 downto 0)); end ASyncReceiverV4; architecture Behavioral of ASyncReceiverV4 is type states is (StartBitCheck, ReadData, StopBitCheck); signal currentState, nextState : states; begin process(CLK) begin if rising_edge(CLK) then currentState <= nextState; end if; end process; process(CLK) variable counter : integer := 0; variable dataIndex : integer := 0; begin case currentState is when StartBitCheck => if Enable = '1' then if (DataIn = '0' and counter < 8) then counter := counter + 1; elsif (DataIn = '0' and counter = 8) then BadData <= '0'; nextState <= ReadData; counter := 0; else nextState <= StartBitCheck; end if; end if; when ReadData => if Enable = '1' then if counter < 16 then counter := counter + 1; elsif (counter = 16 and dataIndex < 8) then DataOut(dataIndex) <= DataIn; counter := 0; dataIndex := dataIndex + 1; elsif dataIndex = 8 then dataIndex := 0; nextState <= StopBitCheck; else nextState <= ReadData; end if; end if; when StopBitCheck => if Enable = '1' then if DataIn = '1' then if counter < 16 then counter := counter + 1; nextState <= StopBitCheck; elsif counter = 16 then counter := 0; nextState <= StartBitCheck; end if; else DataOut <= "11111111"; BadData <= '1'; nextState <= StartBitCheck; end if; end if; end case; end process; end Behavioral;
For whatever reason, based on my simulations, it seems that my processes are out of sync. Although things are only supposed to occur at the rising edge of the clock, I have transitions occurring at the falling edge. Furthermore, it seems like things are not changing according to the value of counter.
The Enable input is high in all of my simulations. However, this is just to keep it simple for now, it will eventually be fed the output of a 153,600 Baud generator (the Baud generator will be connected to the Enable input). Hence, I only want things to change when my Baud generator is high. Otherwise, do nothing. Am I taking the right approach for that with my code?
I can supply a screenshot of my simulation if that would be helpful. I am also not sure if I am including the correct variables in my process sensitivity list. Also, am I taking the right approach with my counter and dataIndex variables? What if I made them signals as part of my architecture before any of my processes?
Any help on this would be very much so appreciated!