📄 uart_rx.vhd.bak
字号:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY UART_RX IS
GENERIC(
SYNC_CLOCK : INTEGER := 50000000;
BAUD_RATE : INTEGER := 9600
);
PORT(
CLOCK : IN STD_LOGIC;
RXD : IN STD_LOGIC;
RXD_DATA_VALID : OUT STD_LOGIC;
RXD_DATA : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END UART_RX;
ARCHITECTURE BEHAV OF UART_RX IS
TYPE STATE_TYPE IS (IDLE, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, STOP);
-- SIGNAL ---------------------------
SIGNAL STATE : STATE_TYPE := IDLE;
SIGNAL BAUD_TICK : STD_LOGIC := '0';
SIGNAL BAUD_DIVIDER : integer range 0 to (SYNC_CLOCK/100 + BAUD_RATE/100 - 1) := 0;
SIGNAL RECEIVE_DATA : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RECEIVE_BUSY : STD_LOGIC := '0';
SIGNAL TEMP : STD_LOGIC := '0';
BEGIN
BAUD_GEN: PROCESS(CLOCK)
BEGIN
IF (CLOCK'EVENT AND CLOCK = '1') THEN
IF (RECEIVE_BUSY = '1') THEN
BAUD_DIVIDER <= BAUD_DIVIDER + (BAUD_RATE/100);
if (BAUD_DIVIDER > (SYNC_CLOCK/100)) then
BAUD_TICK <= '1';
BAUD_DIVIDER <= 0;
else
BAUD_TICK <= '0';
end if;
END IF;
END IF;
END PROCESS;
STATE_SWITCH: PROCESS(BAUD_TICK)
BEGIN
IF (BAUD_TICK'EVENT AND BAUD_TICK = '1') THEN
CASE STATE IS
WHEN IDLE => STATE <= BIT1;
WHEN BIT0 => STATE <= BIT1;
WHEN BIT1 => STATE <= BIT2;
WHEN BIT2 => STATE <= BIT3;
WHEN BIT3 => STATE <= BIT4;
WHEN BIT4 => STATE <= BIT5;
WHEN BIT5 => STATE <= BIT6;
WHEN BIT6 => STATE <= BIT7;
WHEN BIT7 => STATE <= STOP;
WHEN STOP => STATE <= IDLE;
END CASE;
END IF;
END PROCESS;
LINE_STATUS: PROCESS(BAUD_TICK)
BEGIN
IF (BAUD_TICK'EVENT AND BAUD_TICK = '1') THEN
CASE STATE IS
WHEN BIT0 => RECEIVE_DATA(0) <= RXD;
WHEN BIT1 => RECEIVE_DATA(1) <= RXD;
WHEN BIT2 => RECEIVE_DATA(2) <= RXD;
WHEN BIT3 => RECEIVE_DATA(3) <= RXD;
WHEN BIT4 => RECEIVE_DATA(4) <= RXD;
WHEN BIT5 => RECEIVE_DATA(5) <= RXD;
WHEN BIT6 => RECEIVE_DATA(6) <= RXD;
WHEN BIT7 => RECEIVE_DATA(7) <= RXD;
WHEN OTHERS => TEMP <= '1';
END CASE;
END IF;
END PROCESS;
START_CONDITION: PROCESS(CLOCK)
BEGIN
IF (CLOCK'EVENT AND CLOCK = '1') THEN
IF (RECEIVE_BUSY = '0') THEN
IF (RXD = '0') THEN
RECEIVE_BUSY <= '1';
END IF;
ELSE
IF (BAUD_TICK = '1') THEN
IF (STATE = IDLE) THEN
RECEIVE_BUSY <= '0';
RXD_DATA <= RECEIVE_DATA;
END IF;
END IF;
END IF;
END IF;
END PROCESS;
RXD_DATA_VALID <= NOT RECEIVE_BUSY;
END BEHAV;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -