-----------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------
|
-- uart receive module
|
-- uart receive module
|
--
|
--
|
-----------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------
|
library IEEE;
|
library IEEE;
|
use IEEE.STD_LOGIC_1164.ALL;
|
use IEEE.STD_LOGIC_1164.ALL;
|
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
|
|
entity uartRx is
|
entity uartRx is
|
port ( clr : in std_logic; -- global reset input
|
port ( clr : in std_logic; -- global reset input
|
clk : in std_logic; -- global clock input
|
clk : in std_logic; -- global clock input
|
ce16 : in std_logic; -- baud rate multiplyed by 16 - generated by baud module
|
ce16 : in std_logic; -- baud rate multiplyed by 16 - generated by baud module
|
serIn : in std_logic; -- serial data input
|
serIn : in std_logic; -- serial data input
|
rxData : out std_logic_vector(7 downto 0); -- data byte received
|
rxData : out std_logic_vector(7 downto 0); -- data byte received
|
newRxData : out std_logic); -- signs that a new byte was received
|
newRxData : out std_logic); -- signs that a new byte was received
|
end uartRx;
|
end uartRx;
|
|
|
architecture Behavioral of uartRx is
|
architecture Behavioral of uartRx is
|
|
|
signal ce1 : std_logic; -- clock enable at bit rate
|
signal ce1 : std_logic; -- clock enable at bit rate
|
signal ce1Mid : std_logic; -- clock enable at the middle of each bit - used to sample data
|
signal ce1Mid : std_logic; -- clock enable at the middle of each bit - used to sample data
|
signal inSync : std_logic_vector(1 downto 0);
|
signal inSync : std_logic_vector(1 downto 0);
|
signal count16 : std_logic_vector(3 downto 0);
|
signal count16 : std_logic_vector(3 downto 0);
|
signal rxBusy : std_logic;
|
signal rxBusy : std_logic;
|
signal bitCount : std_logic_vector(3 downto 0);
|
signal bitCount : std_logic_vector(3 downto 0);
|
signal dataBuf : std_logic_vector(7 downto 0);
|
signal dataBuf : std_logic_vector(7 downto 0);
|
|
|
begin
|
begin
|
-- input async input is sampled twice
|
-- input async input is sampled twice
|
process (clr, clk)
|
process (clr, clk)
|
begin
|
begin
|
if (clr = '1') then
|
if (clr = '1') then
|
inSync <= (others => '1');
|
inSync <= (others => '1');
|
elsif (rising_edge(clk)) then
|
elsif (rising_edge(clk)) then
|
inSync <= inSync(0) & serIn;
|
inSync <= inSync(0) & serIn;
|
end if;
|
end if;
|
end process;
|
end process;
|
-- a counter to count 16 pulses of ce_16 to generate the ce_1 and ce_1_mid pulses.
|
-- a counter to count 16 pulses of ce_16 to generate the ce_1 and ce_1_mid pulses.
|
-- this counter is used to detect the start bit while the receiver is not receiving and
|
-- this counter is used to detect the start bit while the receiver is not receiving and
|
-- signs the sampling cycle during reception.
|
-- signs the sampling cycle during reception.
|
process (clr, clk)
|
process (clr, clk)
|
begin
|
begin
|
if (clr = '1') then
|
if (clr = '1') then
|
count16 <= (others => '0');
|
count16 <= (others => '0');
|
elsif (rising_edge(clk)) then
|
elsif (rising_edge(clk)) then
|
if (ce16 = '1') then
|
if (ce16 = '1') then
|
if ((rxBusy = '1') or (inSync(1) = '0')) then
|
if ((rxBusy = '1') or (inSync(1) = '0')) then
|
count16 <= count16 + 1;
|
count16 <= count16 + 1;
|
else
|
else
|
count16 <= (others => '0');
|
count16 <= (others => '0');
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
-- receiving busy flag
|
-- receiving busy flag
|
process (clr, clk)
|
process (clr, clk)
|
begin
|
begin
|
if (clr = '1') then
|
if (clr = '1') then
|
rxBusy <= '0';
|
rxBusy <= '0';
|
elsif (rising_edge(clk)) then
|
elsif (rising_edge(clk)) then
|
if ((rxBusy = '0') and (ce1Mid = '1')) then
|
if ((rxBusy = '0') and (ce1Mid = '1')) then
|
rxBusy <= '1';
|
rxBusy <= '1';
|
elsif ((rxBusy = '1') and (bitCount = "1001") and (ce1 = '1')) then
|
elsif ((rxBusy = '1') and (bitCount = "1000") and (ce1 = '1')) then
|
rxBusy <= '0';
|
rxBusy <= '0';
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
-- bit counter
|
-- bit counter
|
process (clr, clk)
|
process (clr, clk)
|
begin
|
begin
|
if (clr = '1') then
|
if (clr = '1') then
|
bitCount <= (others => '0');
|
bitCount <= (others => '0');
|
elsif (rising_edge(clk)) then
|
elsif (rising_edge(clk)) then
|
if (rxBusy = '0') then
|
if (rxBusy = '0') then
|
bitCount <= (others => '0');
|
bitCount <= (others => '0');
|
elsif ((rxBusy = '1') and (ce1Mid = '1')) then
|
elsif ((rxBusy = '1') and (ce1Mid = '1')) then
|
bitCount <= bitCount + 1;
|
bitCount <= bitCount + 1;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
-- data buffer shift register
|
-- data buffer shift register
|
process (clr, clk)
|
process (clr, clk)
|
begin
|
begin
|
if (clr = '1') then
|
if (clr = '1') then
|
dataBuf <= (others => '0');
|
dataBuf <= (others => '0');
|
elsif (rising_edge(clk)) then
|
elsif (rising_edge(clk)) then
|
if ((rxBusy = '1') and (ce1Mid = '1')) then
|
if ((rxBusy = '1') and (ce1Mid = '1')) then
|
dataBuf <= inSync(1) & dataBuf(7 downto 1);
|
dataBuf <= inSync(1) & dataBuf(7 downto 1);
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
-- data output and flag
|
-- data output and flag
|
process (clr, clk)
|
process (clr, clk)
|
begin
|
begin
|
if (clr = '1') then
|
if (clr = '1') then
|
rxData <= (others => '0');
|
rxData <= (others => '0');
|
newRxData <= '0';
|
newRxData <= '0';
|
elsif (rising_edge(clk)) then
|
elsif (rising_edge(clk)) then
|
if ((rxBusy = '1') and (bitCount = "1000") and (ce1 = '1')) then
|
if ((rxBusy = '1') and (bitCount = "1000") and (ce1 = '1')) then
|
rxData <= dataBuf;
|
rxData <= dataBuf;
|
newRxData <= '1';
|
newRxData <= '1';
|
else
|
else
|
newRxData <= '0';
|
newRxData <= '0';
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
-- ce_1 pulse indicating expected end of current bit
|
-- ce_1 pulse indicating expected end of current bit
|
ce1 <= '1' when ((count16 = "1111") and (ce16 = '1')) else '0';
|
ce1 <= '1' when ((count16 = "1111") and (ce16 = '1')) else '0';
|
-- ce_1_mid pulse indication the sampling clock cycle of the current data bit
|
-- ce_1_mid pulse indication the sampling clock cycle of the current data bit
|
ce1Mid <= '1' when ((count16 = "0111") and (ce16 = '1')) else '0';
|
ce1Mid <= '1' when ((count16 = "0111") and (ce16 = '1')) else '0';
|
end Behavioral;
|
end Behavioral;
|
|
|