1
0
SEm-Labos/Libs/RS232/hdl/serialPortReceiver_rtl.vhd

152 lines
3.7 KiB
VHDL
Raw Permalink Normal View History

2024-02-23 13:01:05 +00:00
--===========================================================================--
-- Design units : CoCa.serialPortReceiver.rtl
--
-- File name : serialPortReceiver_rtl.vhd
--
-- Purpose : Decode data from UART into words
--
-- Input : serial line data
--
-- Output :
-- dataOut : word of data
-- dataValid : active when a new word of data is available
--
--
-- Limitations :
--
--
--
-- Errors: : None known
--
-- Library : Common
--
-- Dependencies : None
--
-- Author :
-- Haute école d'ingénierie (HEI/HES-SO)
-- Institut systèmes industriels (ISI)
-- Rue de l'industrie 23
-- 1950 Sion
-- Switzerland (CH)
--
-- Simulator : Mentor ModelSim V10.7c
------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- V1.0 04.04.2022 - First version
--===========================================================================--
library Common;
use Common.CommonLib.all;
architecture RTL of serialPortReceiver is
signal dividerCounter: unsigned(requiredBitNb(baudRateDivide-1)-1 downto 0);
signal dividerCounterReset: std_uLogic;
signal rxDelayed: std_uLogic;
signal dividerCounterSynchronize: std_uLogic;
signal rxSample: std_uLogic;
signal rxShiftReg: std_ulogic_vector(dataBitNb-1 downto 0);
signal rxReceiving: std_uLogic;
signal rxDataValid: std_uLogic;
signal rxCounter: unsigned(requiredBitNb(dataBitNb)-1 downto 0);
begin
divide: process(reset, clock)
begin
if reset = '1' then
dividerCounter <= (others => '0');
elsif rising_edge(clock) then
if dividerCounterSynchronize = '1' then
dividerCounter <= to_unsigned(baudRateDivide/2, dividerCounter'length);
elsif dividerCounterReset = '1' then
dividerCounter <= (others => '0');
else
dividerCounter <= dividerCounter + 1;
end if;
end if;
end process divide;
endOfCount: process(dividerCounter)
begin
if dividerCounter = baudRateDivide-1 then
dividerCounterReset <= '1';
else
dividerCounterReset <= '0';
end if;
end process endOfCount;
delayRx: process(reset, clock)
begin
if reset = '1' then
rxDelayed <= '0';
elsif rising_edge(clock) then
rxDelayed <= RxD;
end if;
end process delayRx;
rxSynchronize: process(RxD, rxDelayed)
begin
if RxD /= rxDelayed then
dividerCounterSynchronize <= '1';
else
dividerCounterSynchronize <= '0';
end if;
end process rxSynchronize;
rxSample <= dividerCounterReset and not dividerCounterSynchronize;
shiftReg: process(reset, clock)
begin
if reset = '1' then
rxShiftReg <= (others => '0');
elsif rising_edge(clock) then
if rxSample = '1' then
rxShiftReg(rxShiftReg'high-1 downto 0) <= rxShiftReg(rxShiftReg'high downto 1);
rxShiftReg(rxShiftReg'high) <= RxD;
end if;
end if;
end process shiftReg;
detectReceive: process(reset, clock)
begin
if reset = '1' then
rxReceiving <= '0';
rxDataValid <= '0';
elsif rising_edge(clock) then
if rxSample = '1' then
if rxCounter = dataBitNb-1 then
rxDataValid <= '1';
elsif RxD = '0' then
rxReceiving <= '1';
end if;
elsif rxDataValid = '1' then
rxReceiving <= '0';
rxDataValid <= '0';
end if;
end if;
end process detectReceive;
countRxBitNb: process(reset, clock)
begin
if reset = '1' then
rxCounter <= (others => '0');
elsif rising_edge(clock) then
if rxSample = '1' then
if rxReceiving = '1' then
rxCounter <= rxCounter + 1;
else
rxCounter <= (others => '0');
end if;
end if;
end if;
end process countRxBitNb;
dataOut <= rxShiftReg;
dataValid <= rxDataValid;
end RTL;