?? rxcver.vhd
字號:
-- *******************************************************************
--
-- Owner: Xilinx Inc.
-- File: rxcver.vhd
--
-- Purpose: Main UART receiver logic module. Receives
-- incoming serial data and present parallel
-- byte of data to system. Includes rxrdy control
-- signals for handshaking of system bus. Includes
-- control flags for parity, overrun data, and
-- framing errors.
--
-- Created: VHDL code generated by Visual HDL 8-15-01
--
-- *******************************************************************
library ieee;
use ieee.STD_LOGIC_1164.all;
use ieee.STD_LOGIC_ARITH.all;
use ieee.STD_LOGIC_MISC.all;
use ieee.STD_LOGIC_UNSIGNED.all;
use work.pkg_util.all;
entity rxcver is
port (
mclkx16 : in STD_LOGIC;
read : in STD_LOGIC;
sin : in STD_LOGIC;
reset : in STD_LOGIC;
rxrdy : out STD_LOGIC;
parity_error : out STD_LOGIC;
framing_error : out STD_LOGIC;
overrun : out STD_LOGIC;
rxdata : out STD_LOGIC_VECTOR(7 downto 0 )
);
end rxcver;
architecture behavior of rxcver is
-- Internal control signals.
signal rxcnt : STD_LOGIC_VECTOR(3 downto 0 ); -- Count of clock cycles
signal rx1 : STD_LOGIC; -- Delayed version signals
signal read1 : STD_LOGIC;
signal read2 : STD_LOGIC;
signal idle1 : STD_LOGIC;
signal hunt : STD_LOGIC;
-- Receive shift register bits
signal rhr : STD_LOGIC_VECTOR(7 downto 0 ); -- Receive hold register
signal rsr : STD_LOGIC_VECTOR(7 downto 0 ); -- Receive shift register
signal rxparity : STD_LOGIC; -- Received parity bit
signal paritygen : STD_LOGIC; -- Parity generated from received data
signal rxstop : STD_LOGIC; -- Received data stop bit
-- Receive clock and control signals.
signal rxclk : STD_LOGIC; -- Receive data shift clock
signal idle : STD_LOGIC; -- idle = 1 when receiver is idle
signal rxdatardy : STD_LOGIC; -- rsdatardy = 1 when data is ready to be read
begin
-- Idle signal enables rxclk generation - idle = 0 when not shifting data
-- idle = 1 when low "rxstop" bit = rsr[0]
process (rxclk, reset)
begin
if (reset) = '1' then
idle <= '1';
elsif (rxclk'event and rxclk = '1' ) then
idle <= not(idle) and not(rsr(0));
end if ;
end process ;
-- Synchronizing rxclk to the centerpoint of low leading startbit
process (mclkx16)
begin
if (mclkx16'event and mclkx16 = '1' ) then
-- A start bit is eight clock times with sin=0 after a falling edge of sin
if (reset) = '1' then
hunt <= '0';
else
-- Look for falling edge of sin
if (idle) = '1' and (sin = '0' ) and (rx1) = '1' then
hunt <= '1';
else
-- Stop when shifting in data, or a 1 is found on sin
if (idle = '0' ) or (sin) = '1' then
hunt <= '0';
end if ;
end if ;
end if ;
if (idle = '0' ) or (hunt) = '1' then
-- Count clocks when not idle, or looking for start bit
rxcnt <= ext(ext(rxcnt,32) + 1,abs(3-0)+1);
else
-- Hold rxcnt = 1, when idle and waiting for falling edge of sin
rxcnt <= "0001";
end if ;
rx1 <= sin; -- Looking for falling edge detect on sin
rxclk <= rxcnt(3); -- rxclk = mclkx16 / 16
end if;
end process ;
-- When not idle, sample data at the sin input and create parity
process (rxclk, reset)
begin
if (reset) = '1' then
rsr <= "11111111"; -- Initialize shift register
rxparity <= '1'; -- Set to 1 -> for data shifting
paritygen <= '1'; -- Set to 1 -> odd parity mode
rxstop <= '0'; -- Controls idle = 1, when rsr[0] gets rxstop bit
elsif (rxclk'event and rxclk = '1' ) then
if (idle) = '1' then
rsr <= "11111111"; -- Initialize shift register
rxparity <= '1'; -- Set to 1 -> for data shifting
paritygen <= '1'; -- Set to 1 -> odd parity mode
rxstop <= '0'; -- Controls idle = 1, when rsr[0] gets rxstop bit
else
-- Right shift sin shift register
rsr <= std_logic_vector(SHR(unsigned(rsr) ,
unsigned'("00000000000000000000000000000001")));
rsr(7) <= rxparity; -- Load rsr[7] with rxparity
rxparity <= rxstop; -- Load rxparity with rxstop
rxstop <= sin; -- Load rxstop with sin
paritygen <= paritygen xor rxstop; -- Generate running parity
end if ;
end if ;
end process ;
-- Generate status & error flags
process (mclkx16, reset)
begin
if (reset) = '1' then
rhr <= "00000000";
rxdatardy <= '0';
overrun <= '0';
parity_error <= '0';
framing_error <= '0';
idle1 <= '1';
read2 <= '1';
read1 <= '1';
elsif (mclkx16'event and mclkx16 = '1' ) then
-- Look for rising edge of idle and update output registers
if (idle) = '1' and (idle1 = '0' ) then
if (rxdatardy) = '1' then
overrun <= '1'; -- Overrun error, if previous data
-- still in holding register
else
overrun <= '0'; -- No overrun error, since holding register is empty
rhr <= rsr; -- Update holding register with contens of shift register
parity_error <= paritygen; -- paritygen = 1, if parity error
framing_error <= not(rxstop); -- framing_error, if stop bit is not 1
rxdatardy <= '1'; -- Data is ready for reading flag
end if ;
end if ;
-- Clear error and data registers when data is read
if (read2 = '0' ) and (read1) = '1' then
rxdatardy <= '0';
parity_error <= '0';
framing_error <= '0';
overrun <= '0';
end if ;
idle1 <= idle; -- Edge detect on idle signal
read2 <= read1; -- 2 cycle delayed version of read - edge detection
read1 <= read; -- 1 cycle delayed version of read - edge detection
end if ;
end process ;
rxrdy <= rxdatardy; -- Receive data ready output signal
process (read, rhr)
begin
if not((read) = '1' ) then
rxdata <= rhr;
end if ;
end process ;
-- Latch data output when read goes low
end ;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -