library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--------------------------------------------
entity RS232_RX is
Port ( RxDO : out STD_LOGIC_VECTOR (7 downto 0);
RxRdy : out STD_LOGIC;
Reset : in STD_LOGIC;
Clk : in STD_LOGIC;
RS232_RxD : in STD_LOGIC;
idx_test: out std_logic_vector( 3 downto 0 ));
end RS232_RX;
--------------------------------------------
architecture Behavioral of RS232_RX is
-- stany FSM
type state_type is (
sReset,
sWait,
sSync,
sReady,
sBusy);
-- sygnaly pomocnicze FSM
signal State, next_State : state_type;
-- licznik 434*50Mhz = 115207Hz
signal counter: std_logic_vector( 8 downto 0 ) := ( others => '0' );
-- licznik 217*50Mhz =~ 57600Hz
signal fcount : std_logic_vector ( 7 downto 0 ) := ( others => '0' );
-- indeks bitowy 1b start + 8b dane + 1b stop
signal idx: std_logic_vector( 3 downto 0 ) := ( others => '0' );
-- kopia sygnalu TxDI(+bit start,stop) zatrzaskiwana gdy TxStart = '1', a bylo '0'
signal TxDO_cpy : STD_LOGIC_VECTOR (9 downto 0) := ( others => '0' );
begin
-----------------------------------------------------
FSM_zmiana: process (Clk)
begin
if rising_edge(clk) then
-------------------
if State = sReset then
counter <= (others => '0');
idx <= (others => '0');
fcount <= (others => '0');
TxDO_cpy <= (others => '0');
--------------------
elsif State = sSync then
if fcount = "11011001" then
TxDO_cpy (conv_integer(idx)) <= RS232_RxD;
idx <= idx + 1;
else
fcount <= fcount + 1;
end if;
--------------------
elsif State = sBusy then
if counter = "110110010" then
counter <= (others => '0');
TxDO_cpy (conv_integer(idx)) <= RS232_RxD;
idx <= idx + 1;
else
counter <= counter + 1;
end if;
--------------------
end if;
end if;
end process FSM_zmiana;
-----------------------------------------------------
FSM_next: process (Clk,Reset)
begin
if Reset = '1' then state <= sReset;
elsif rising_edge(Clk) then state <= next_State;
end if;
end process FSM_next;
-----------------------------------------------------
FSM_przejsc: process (State,RS232_RxD,idx)
begin
next_state <= state;
case State is
when sReset => next_state <= sWait;
--------------------------------------------
when sBusy => if conv_integer(idx) < 10 then
next_state <= sBusy;
else
next_state <= sReady;
end if;
--------------------------------------------
when sWait => if RS232_RxD = '0' then
next_state <= sSync;
else next_state <= sWait;
end if;
--------------------------------------------
when sReady => next_state <= sReset;
--------------------------------------------
when sSync => if idx = "0000" then
next_state <= sSync;
else
next_state <= sBusy;
end if;
end case;
end process FSM_przejsc;
-----------------------------------------------------
FSM_wyjsc: process (State)
begin
case State is
when sReset => RxDO <= "00000000";
RxRdy <= '0';
when sWait => RxDO <= "00000000";
RxRdy <= '0';
when sSync => RxDO <= "00000000";
RxRdy <= '0';
when sBusy => RxDO <= "00000000";
RxRdy <= '0';
when sReady => RxDO <= TxDO_cpy (9 downto 2);
RxRdy <= '1';
end case;
end process FSM_wyjsc;
-----------------------------------------------------
idx_test <= idx;
end Behavioral;