📄 rxcver.vhd
字号:
end process HuntOne_r_Proc;
-- RbrDataRDY :
-- This will be set to indicate that the data in RBR is ready for read and
-- will be cleared after RBR is read.
RbrDataRDY_Proc: process(Clk16X, Reset)
begin
if (Reset='1') then
RbrDataRDY <= '0';
elsif rising_edge(Clk16X) then
if (RxIdle_r='1') and (RxIdle1_r='0') then
-- set RbrDataRDY at RxIdle_r rising edge
RbrDataRDY <= '1';
elsif (RbrRDn_re='1') then
-- clear RbrDataRDY when RBR is read by CPU
RbrDataRDY <= '0';
end if;
end if;
end process RbrDataRDY_Proc;
-- SampledOnce :
-- This will be set for one Clk16X clock after a framing error occurs not
-- because of BREAK and a low SIN signal is sampled by the Clk16X right
-- after the sample time of the Stop bit which causes the framing error.
SampledOnce_Proc: process (Reset, Clk16X)
begin
if (Reset='1') then
SampledOnce <= '0';
elsif rising_edge(Clk16X) then
if (RxFrmErr='1') and (RxFrmErr1_r='0') and
(SIN='0') and (HuntOne_r='1') then
-- Start bit got sampled once
SampledOnce <= '1';
else
SampledOnce <= '0';
end if;
end if;
end process SampledOnce_Proc;
-- RxIdle_r Flag
RxIdle_Proc: process(Reset, Clk16X)
begin
if (Reset='1') then
RxIdle_r <= '1';
elsif rising_edge(Clk16X) then
if (Rx_State=idle) then
RxIdle_r <= '1';
elsif (CNT_r(3)='1') then
RxIdle_r <= '0';
end if;
end if;
end process RxIdle_Proc;
--------------------------------------------------------------------------------
-- Receiver Finite State Machine
--------------------------------------------------------------------------------
Shift_data_Proc: process(Clk16X, Reset)
begin
if (Reset='1') then
RSR <= (others=>'0');
NumDataBitReceived_r <= (others=>'0');
RxPrtyErr <= '1';
RxFrmErr <= '0';
Rx_State <= idle;
elsif rising_edge(Clk16X) then
case Rx_State is
when idle =>
if (RxIdle_r='1') and (SIN='0') and (RxClkEn='1') then
RSR <= (others=>'0');
NumDataBitReceived_r <= (others=>'0');
-- RxPrtyErr:
-- RxPrtyErr is a dynamic Parity Error indicator which is
-- initialized to 0 for even parity and 1 for odd parity.
-- For odd parity, if there are odd number of '1's in the
-- (data + parity) bits, the XOR will bring RxPrtyErr back to 0
-- which means no parity error, otherwise RxPrtyErr will be 1 to
-- indicate a parity error.
RxPrtyErr <= not ParityEven;
RxFrmErr <= '0';
Rx_State <= shift;
end if;
when shift =>
if (RxClkEn='1') then
RSR <= SIN & RSR(7 downto 1);
RxPrtyErr <= RxPrtyErr xor SIN; -- Update RxPrtyErr dynamically
NumDataBitReceived_r <= NumDataBitReceived_r + 1;
if ((DataBits="00" and NumDataBitReceived_r=4) or
(DataBits="01" and NumDataBitReceived_r=5) or
(DataBits="10" and NumDataBitReceived_r=6) or
(DataBits="11" and NumDataBitReceived_r=7)) then
if (ParityEnable='0') then
Rx_State <= stop;
else
Rx_State <= parity;
end if;
end if;
end if;
when parity =>
if (RxClkEn='1') then
if (ParityStick='0') then
RxPrtyErr <= RxPrtyErr xor SIN; -- Update RxPrtyErr dynamically
else
-- ParityStick='1' means Stick Parity is enabled. In this case,
-- the accumulated dynamic RxPrtyErr result will be ignored. A new
-- value will be assigned to RxPrtyErr based on the even/odd parity
-- mode setting and the SIN sampled in parity bit.
-- ParityEven='0'(odd parity):
-- SIN needs to be '1', otherwise it's a stick parity error.
-- ParityEven='1'(even parity):
-- SIN needs to be '0', otherwise it's a stick parity error.
if (ParityEven='0') then
RxPrtyErr <= not SIN;
else
RxPrtyErr <= SIN;
end if;
end if;
Rx_State <= stop;
end if;
when stop =>
if (RxClkEn='1') then
-- The Receiver checks the 1st Stopbit only regardless of the number
-- of Stop bits selected.
-- Stop bit needs to be '1', otherwise it's a Framing error
RxFrmErr <= not SIN;
Rx_State <= idle;
end if;
when others =>
if (RxClkEn='1') then
Rx_State <= idle;
end if;
end case;
end if;
end process Shift_Data_Proc;
--------------------------------------------------------------------------------
-- Receiver Buffer Register
--------------------------------------------------------------------------------
RBR_Proc: process(Clk16X, Reset)
begin
if (Reset='1') then
RBR_r <= (others=>'0');
elsif rising_edge(Clk16X) then
if (RxIdle_r='1') and (RxIdle1_r='0') then
-- Update RBR at RxIdle_r rising edge
case DataBits is
when "00" => -- 5-bit data
RBR_r <= "000" & RSR(7 downto 3);
when "01" => -- 6-bit data
RBR_r <= "00" & RSR(7 downto 2);
when "10" => -- 7-bit data
RBR_r <= '0' & RSR(7 downto 1);
when others => -- 8-bit data
RBR_r <= RSR;
end case;
end if;
end if;
end process RBR_Proc;
RBR <= RBR_r;
--------------------------------------------------------------------------------
-- Delayed Signals for edge detections
--------------------------------------------------------------------------------
Delay_Signals_Proc: process(Clk16X, Reset)
begin
if (Reset='1') then
SIN1_r <= '0';
RxFrmErr1_r <= '1';
RxIdle1_r <= '1';
elsif rising_edge(Clk16X) then
-- SIN1_r : Signal for falling edge detection of signal SIN
SIN1_r <= SIN;
-- RxFrmErr1_r :
-- a delayed version of RxFrmErr for detacting the rising edge
-- used to resynchronize the next frame after framing error
RxFrmErr1_r <= RxFrmErr;
-- RxIdle1_r : Signal for rising edge detection of signal RxIdle_r
RxIdle1_r <= RxIdle_r;
end if;
end process Delay_Signals_Proc;
--------------------------------------------------------------------------------
-- Generate Error Flags
--------------------------------------------------------------------------------
-- Receiver Error Flags in LSR
-- OverrunErr(OE), ParityErr_r(PE), FrameErr_r(FE), BreakInt_r(BI)
-- will be set to reflect the SIN line status only after the whole frame
-- (Start bit + Data bits + Parity bit + Stop bit) is received. A rising
-- edge of RxIdle_r indicates the whole frame is received.
Error_Flags_Proc: process(Clk16X, Reset)
begin
if (Reset='1') then
OverrunErr_r <= '0';
ParityErr_r <= '0';
FrameErr_r <= '0';
BreakInt_r <= '0';
elsif rising_edge(Clk16X) then
if (RxIdle_r='1') and (RxIdle1_r='0') then -- update at RxIdle_r rising
-- Set OverrunErr_r flag if RBR data is still not read by CPU
OverrunErr_r <= RbrDataRDY;
-- Set ParityErr_r flag if RxPrtyErr is 1 when Parity enable
ParityErr_r <= (ParityErr_r or RxPrtyErr) and ParityEnable;
-- Set FrameErr_r flag if RxFrmErr is 1(Stop bit is sampled low)
FrameErr_r <= FrameErr_r or RxFrmErr;
-- Set BreakInt_r flag if HuntOne_r is still low
BreakInt_r <= BreakInt_r or (not HuntOne_r);
elsif (LsrRDn_re='1') then -- clear when LSR is read
ParityErr_r <= '0';
FrameErr_r <= '0';
OverrunErr_r <= '0';
BreakInt_r <= '0';
end if;
end if;
end process Error_Flags_Proc;
-- Receiver ready for read when data is available in RBR
RxRDY <= RbrDataRDY;
-- Overrun Error flag
OverrunErr <= OverrunErr_r;
-- Parity Error flag
ParityErr <= ParityErr_r;
-- Frame Error flag
FrameErr <= FrameErr_r;
-- Break Interrupt flag
BreakInt <= BreakInt_r;
end Rxcver_a;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -