📄 uartc.vhd
字号:
--################################################################################
--######### UART CONTROLLER FOR PKX RADAR ##########
--######### DEVICE : XC2VP50-1152-6 ##########
--######### DATE : 2008 / 00 / 00 ##########
--######### EDITED BY CHLEE IN LUMENS CO., LTD. ##########
--######### SPEC : 1STOPBIT/NOPARITY/NOFLOWCONTROL/115200BAUD ##########
--################################################################################
LIBRARY IEEE;
LIBRARY UNISIM;
--USE UNISIM.VCOPONENTS.ALL;
USE UNISIM.ALL;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY UARTC IS
PORT (
RESET : IN STD_LOGIC :='1';
CLK2X : IN STD_LOGIC :='0'; -- 106M OR 100M
TXDIN : IN STD_LOGIC_VECTOR(7 DOWNTO 0) :=X"00";
TXDV : IN STD_LOGIC :='0';
RXDO : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) :=X"00";
RXD_OE : IN STD_LOGIC :='0';
STXD : OUT STD_LOGIC :='1';
SRXD : IN STD_LOGIC :='1';
STATUS : OUT STD_LOGIC_VECTOR(15 DOWNTO 0) :=X"0000";
DEBUG : OUT STD_LOGIC :='0'
);
END UARTC;
ARCHITECTURE BEHAVIORAL OF UARTC IS
COMPONENT AFF_16_8B
PORT (
DIN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
RD_CLK : IN STD_LOGIC;
RD_EN : IN STD_LOGIC;
RST : IN STD_LOGIC;
WR_CLK : IN STD_LOGIC;
WR_EN : IN STD_LOGIC;
DOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
EMPTY : OUT STD_LOGIC;
FULL : OUT STD_LOGIC;
VALID : OUT STD_LOGIC;
RD_DATA_COUNT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
WR_DATA_COUNT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END COMPONENT;
SIGNAL TXFF_EMPTY : STD_LOGIC :='0';
SIGNAL TXFF_FULL : STD_LOGIC :='0';
SIGNAL RXFF_EMPTY : STD_LOGIC :='0';
SIGNAL RXFF_FULL : STD_LOGIC :='0';
SIGNAL TXFF_DO : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RXFF_DO : STD_LOGIC_VECTOR(7 DOWNTO 0);
-- SIGNAL TXD_BUF : STD_LOGIC_VECTOR(7 DOWNTO 0);
-- SIGNAL RXD_BUF : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL STX_BUF : STD_LOGIC_VECTOR(9 DOWNTO 0);
SIGNAL SRX_BUF : STD_LOGIC_VECTOR(9 DOWNTO 0);
SIGNAL STX_BIT_CNT : INTEGER RANGE 0 TO 15 :=0;
SIGNAL SRX_BIT_CNT : INTEGER RANGE 0 TO 15 :=0;
CONSTANT CLK3M_CNT_MAX : INTEGER :=15; -- 39 FOR 106M, 18 FOR 100M, 13 FOR 75M, 15 for 96M
CONSTANT BD_CNT_MAX : INTEGER :=25; -- 22 FOR 106M, 23 FOR 100M, 22 for 75M, 25 for 96M
-- CONSTANT BD_CNT_MAX : INTEGER :=47; -- HALF BAUD RATE
SIGNAL CLK3M : STD_LOGIC :='0';
SIGNAL CLK3M_CNT : INTEGER RANGE 0 TO 63 :=0;
SIGNAL SRX_BD_CNT : INTEGER RANGE 0 TO 63 :=0;
SIGNAL STX_BD_CNT : INTEGER RANGE 0 TO 63 :=0;
SIGNAL SYNC_TX_BIT : STD_LOGIC :='0';
SIGNAL SYNC_RX_BIT : STD_LOGIC :='0';
SIGNAL RX_STARTBIT_VLD : STD_LOGIC :='0';
SIGNAL RX_STOPBIT_VLD : STD_LOGIC :='0';
SIGNAL RX_IDLE : STD_LOGIC :='0';
SIGNAL IRQ : STD_LOGIC :='0';
SIGNAL TXFF_OVR : STD_LOGIC :='0';
SIGNAL RXFF_OVR : STD_LOGIC :='0';
SIGNAL TXFF_RE : STD_LOGIC :='0';
SIGNAL RXFF_RE : STD_LOGIC :='0';
SIGNAL TXFF_WE : STD_LOGIC :='0';
SIGNAL RXFF_WE : STD_LOGIC :='0';
SIGNAL TXFF_TXDV : STD_LOGIC :='0';
SIGNAL RXFF_RXDV : STD_LOGIC :='0';
SIGNAL TXFF_COUNT : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL RXFF_COUNT : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
DEBUG <= SYNC_TX_BIT;
STATUS <= TXFF_EMPTY & TXFF_FULL & TXFF_OVR & IRQ & TXFF_COUNT &
RXFF_EMPTY & RXFF_FULL & RXFF_OVR & '0' & RXFF_COUNT;
IRQ <= NOT RXFF_EMPTY AND NOT RESET;
TTL_OVER_FLOW:
PROCESS(RESET,CLK3M)
BEGIN
IF (RESET='1') THEN
TXFF_OVR <= '0';
RXFF_OVR <= '0';
ELSE
IF RISING_EDGE(CLK3M) THEN -- 2.656 MHZ
IF ((TXFF_OVR='0') AND (RXFF_OVR='0')) THEN
TXFF_OVR <= TXFF_FULL AND TXFF_WE;
RXFF_OVR <= RXFF_FULL AND RXFF_WE;
END IF;
END IF;
END IF;
END PROCESS;
TTL_CLK3M:
-- CLK3M <= '1' WHEN(CLK3M_CNT>(CLK3M_CNT_MAX/2)) ELSE '0'; -- 2.656 MHZ
PROCESS(RESET,CLK2X) -- 106.25 MHZ
BEGIN
IF RESET='1' THEN
CLK3M_CNT <= CLK3M_CNT_MAX;
CLK3M <= '0';
ELSE
IF RISING_EDGE(CLK2X) THEN
IF CLK3M_CNT>0 THEN
CLK3M_CNT <= CLK3M_CNT-1;
ELSE
CLK3M_CNT <= CLK3M_CNT_MAX; -- BAUD RATE 115200 WHEN CLKDV=53.125/2 MHZ
CLK3M <= NOT CLK3M;
END IF;
END IF;
END IF;
END PROCESS;
--<< TX FIFO AND TRANSMITTER >>-------------------------------------------------------------
TTL_SFF_TX: AFF_16_8B PORT MAP
(
DIN => TXDIN,
RD_CLK => CLK3M, -- 2.656 MHZ
RD_EN => TXFF_RE,
RST => RESET,
WR_CLK => CLK2X,
WR_EN => TXFF_WE,
DOUT => TXFF_DO,
EMPTY => TXFF_EMPTY, -- STATUS(15)
FULL => TXFF_FULL, -- STATUS(14)
VALID => TXFF_TXDV,
RD_DATA_COUNT => OPEN,
WR_DATA_COUNT => TXFF_COUNT
);
TXFF_WE <= TXDV;
STXD <= STX_BUF(0) WHEN((STX_BIT_CNT<11) AND (STX_BIT_CNT>0)) ELSE '1';
PROCESS(RESET,CLK3M)
BEGIN
IF (RESET='1') THEN
STX_BIT_CNT <= 0;
STX_BUF <= "0000000000";
ELSE
IF RISING_EDGE(CLK3M) THEN -- 2.656 MHZ
CASE STX_BIT_CNT IS
WHEN 13 =>
STX_BIT_CNT <= STX_BIT_CNT-1;
TXFF_RE <= '1';
WHEN 12 =>
STX_BIT_CNT <= STX_BIT_CNT-1;
TXFF_RE <= '0';
WHEN 11 =>
IF (SYNC_TX_BIT='1') THEN
STX_BUF <= '1' & TXFF_DO & '0'; -- STOPBIT + DATA + STARTBIT
STX_BIT_CNT <= STX_BIT_CNT-1;
END IF;
TXFF_RE <= '0';
WHEN 0 =>
IF (TXFF_EMPTY='0') THEN
STX_BIT_CNT <= 13;
END IF;
WHEN OTHERS =>
IF (SYNC_TX_BIT='1') THEN
STX_BUF(8 DOWNTO 0) <= STX_BUF(9 DOWNTO 1);
STX_BIT_CNT <= STX_BIT_CNT-1;
END IF;
END CASE;
END IF;
END IF;
END PROCESS;
-- SYNC_TX_BIT <= '1' WHEN(STX_BD_CNT=0) ELSE '0';
TTL_TX_BAUD:
PROCESS(RESET,CLK3M) -- 2.656 MHZ
BEGIN
IF RESET='1' THEN
STX_BD_CNT <= BD_CNT_MAX;
SYNC_TX_BIT <= '0';
ELSE
IF RISING_EDGE(CLK3M) THEN -- 2.656 MHZ
IF STX_BD_CNT>0 THEN
STX_BD_CNT <= STX_BD_CNT-1;
SYNC_TX_BIT <= '0';
ELSE
STX_BD_CNT <= BD_CNT_MAX; -- BAUD RATE 115200 WHEN CLKDV=53.125/2 MHZ
SYNC_TX_BIT <= '1';
END IF;
END IF;
END IF;
END PROCESS;
--<< RX FIFO AND RECEIVER >>-------------------------------------------------------------
TTL_SFF_RX: AFF_16_8B PORT MAP
(
DIN => SRX_BUF(8 DOWNTO 1),
RD_CLK => CLK2X,
RD_EN => RXFF_RE,
RST => RESET,
WR_CLK => CLK3M, -- 2.656 MHZ
WR_EN => RXFF_WE,
DOUT => RXFF_DO,
EMPTY => RXFF_EMPTY, -- STATUS(7)
FULL => RXFF_FULL, -- STATUS(6)
VALID => RXFF_RXDV,
RD_DATA_COUNT => OPEN,
WR_DATA_COUNT => RXFF_COUNT
);
RXFF_RE <= RXD_OE;
RXFF_WE <= NOT RX_IDLE AND RX_STOPBIT_VLD;
RXDO <= RXFF_DO;
PROCESS(RESET,CLK3M) -- 2.656 MHZ
BEGIN
IF (RESET='1') THEN
RX_IDLE <= '1';
ELSE
IF RISING_EDGE(CLK3M) THEN -- 2.656 MHZ
IF RX_IDLE='1' THEN
RX_IDLE <= NOT RX_STARTBIT_VLD;
ELSE
IF SRX_BIT_CNT=10 THEN
RX_IDLE <= '1';
END IF;
END IF;
END IF;
END IF;
END PROCESS;
TTL_RX_BAUD:
PROCESS(RESET,RX_IDLE,CLK3M)
BEGIN
IF ((RESET='1') OR (RX_IDLE='1')) THEN
SRX_BD_CNT <= 0;
ELSE
IF RISING_EDGE(CLK3M) THEN
IF SRX_BD_CNT>0 THEN
SRX_BD_CNT <= SRX_BD_CNT-1;
ELSE
SRX_BD_CNT <= BD_CNT_MAX;
END IF;
END IF;
END IF;
END PROCESS;
RX_STARTBIT_VLD <= '1' WHEN((RX_IDLE='1') AND (SRX_BUF="000000000")) ELSE '0';
RX_STOPBIT_VLD <= SRX_BUF(9) WHEN((RX_IDLE='0') AND (SRX_BIT_CNT=10)) ELSE '0';
SYNC_RX_BIT <= '1' WHEN(SRX_BD_CNT=0) ELSE '0';
TTL_RXBIT_RECIEVING:
PROCESS(RESET,CLK3M) -- 2.656 MHZ
BEGIN
IF (RESET='1') THEN
SRX_BUF <= "1111111111";
ELSE
IF RISING_EDGE(CLK3M) THEN -- 2.656 MHZ
IF (SYNC_RX_BIT='1') THEN
SRX_BUF(9) <= SRXD;
SRX_BUF(8 DOWNTO 0) <= SRX_BUF(9 DOWNTO 1);
END IF;
END IF;
END IF;
END PROCESS;
TTL_RX_BIT_COUNTING:
PROCESS(RX_IDLE,CLK3M)
BEGIN
IF (RX_IDLE='1') THEN
SRX_BIT_CNT <= 0;
ELSE
IF RISING_EDGE(CLK3M) THEN -- 2.656 MHZ
IF SRX_BIT_CNT<11 THEN
IF (SYNC_RX_BIT='1') THEN
SRX_BIT_CNT <= SRX_BIT_CNT+1;
END IF;
ELSE
SRX_BIT_CNT <= 0;
END IF;
END IF;
END IF;
END PROCESS;
END BEHAVIORAL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -