?? uart.vhd
字號:
--============================================================================
-- Project : line Control
-- Programmer : Byungchan Son
-- Function : line 價薦腳扁
-- Language : VHDL
--============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
--============================================================================
-- 澇免仿 器飄 瀝狼
--============================================================================
entity uart_tranceiver is
port(
-- 矯膠袍 腳齲
reset : in std_logic;
clock : in std_logic;
-- com 腳齲
tx_line : out std_logic;
rx_line : in std_logic;
-- line 力絹何
com_baudrate : in std_logic_vector(15 downto 0);
com_control : in std_logic_vector(1 downto 0);
com_tx_data : in std_logic_vector(7 downto 0);
com_tx_wrreq : in std_logic;
com_tx_full : out std_logic;
com_rx_data : out std_logic_vector(7 downto 0);
com_rx_rdreq : in std_logic;
com_rx_empty : out std_logic
);
end uart_tranceiver;
--============================================================================
-- 備煉 瀝狼
--============================================================================
architecture uart_tranceiver_a of uart_tranceiver is
--------------------------------------------------------------------
-- 郴何 葛碘
--------------------------------------------------------------------
-- com 價腳 滾欺
component transmit_buff
PORT
(
clock : IN STD_LOGIC ;
data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
rdreq : IN STD_LOGIC ;
wrreq : IN STD_LOGIC ;
empty : OUT STD_LOGIC ;
full : OUT STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
end component;
-- com 薦腳 滾欺
component receiver_buff
port(
clock : IN STD_LOGIC ;
data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
rdreq : IN STD_LOGIC ;
wrreq : IN STD_LOGIC ;
empty : OUT STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
end component;
--------------------------------------------------------------------
-- 郴何 腳齲
--------------------------------------------------------------------
--惑怕扁拌 腳齲
-- 薦腳 葛碘
type receive_state is(
rx_ready,
rx_start,
rx_data_accept,
rx_parity_bit,
rx_stop_bit
);
signal rx_current_state, rx_next_state : receive_state;
-- 價腳 葛碘
type transmit_state is(
tx_ready,
tx_read_delay,
tx_read_data,
tx_data_transmit,
tx_parity_bit,
tx_stop_bit
);
signal tx_current_state, tx_next_state : transmit_state;
------------------------------------------------------------------------------
-- 郴何 腳齲
------------------------------------------------------------------------------
-- baud rate 努釩 慣積扁
signal rx_baudrate_clock : std_logic;
signal rx_baudrate_clock1 : std_logic;
signal rx_baudrate_counter : std_logic_vector(15 downto 0);
signal tx_baudrate_clock : std_logic;
signal tx_baudrate_clock1 : std_logic;
signal tx_baudrate_counter : std_logic_vector(15 downto 0);
-- 薦腳何 腳齲
signal rx_baudrate_enable : std_logic;
signal sync_rx_line : std_logic;
signal clk1_rx_line : std_logic;
signal rx_buffer : std_logic_vector(7 downto 0);
signal rx_bit_count : std_logic_vector(2 downto 0);
-- 價腳何 腳齲
signal tx_baudrate_enable : std_logic;
signal tx_buffer : std_logic_vector(7 downto 0);
signal tx_bit_count : std_logic_vector(2 downto 0);
signal tx_parity : std_logic;
-- 薦腳 滾欺
signal rx_buff_data : STD_LOGIC_VECTOR (7 DOWNTO 0);
signal rx_buff_wrreq : STD_LOGIC;
-- 價腳 滾欺
signal tx_buff_rdreq : STD_LOGIC;
signal tx_buff_empty : STD_LOGIC;
signal tx_buff_q : STD_LOGIC_VECTOR (7 DOWNTO 0);
--============================================================================
-- 橇肺技輯 矯累
--============================================================================
begin
----------------------------------------------------------------
-- 郴何 葛碘 搬急
----------------------------------------------------------------
-- com 薦腳 滾欺
m1 : receiver_buff
port map(
clock => clock,
data => rx_buff_data,
rdreq => com_rx_rdreq,
wrreq => rx_buff_wrreq,
empty => com_rx_empty,
q => com_rx_data
);
-- com 價腳 滾欺
m2 : transmit_buff
port map(
clock => clock,
data => com_tx_data,
rdreq => tx_buff_rdreq,
wrreq => com_tx_wrreq,
empty => tx_buff_empty,
full => com_tx_full,
q => tx_buff_q
);
----------------------------------------------------------------
-- baud rate 努釩 慣積扁
----------------------------------------------------------------
baudrate_generator : process(
reset,
clock,
rx_baudrate_clock,
rx_baudrate_counter,
tx_baudrate_clock,
tx_baudrate_counter,
com_baudrate
)
begin
if(reset = '1')then
-- 惑怕 扁拌
-- 郴何 腳齲
rx_baudrate_clock <= '0';
rx_baudrate_counter <= (others => '0');
tx_baudrate_clock <= '0';
tx_baudrate_counter <= (others => '0');
elsif(clock'event and clock = '1')then
-- 價腳 baudrate 努釩 慣積扁
if(tx_baudrate_enable = '1')then
if(tx_baudrate_counter = com_baudrate)then
tx_baudrate_clock <= not tx_baudrate_clock;
tx_baudrate_counter <= (others => '0');
else
tx_baudrate_counter <= tx_baudrate_counter + 1;
end if;
else
tx_baudrate_clock <= '0';
end if;
-- 薦腳 baudrate 努釩 慣積扁
if(rx_baudrate_enable = '1')then
if(rx_baudrate_counter = com_baudrate)then
rx_baudrate_clock <= not rx_baudrate_clock;
rx_baudrate_counter <= (others => '0');
else
rx_baudrate_counter <= rx_baudrate_counter + 1;
end if;
else
rx_baudrate_counter <= (others => '0');
rx_baudrate_clock <= '0';
end if;
end if;
end process;
----------------------------------------------------------------
-- 薦腳 葛碘
----------------------------------------------------------------
receiver : process(
reset,
clock,
rx_line,
sync_rx_line,
clk1_rx_line,
rx_current_state,
rx_next_state,
rx_baudrate_clock,
rx_bit_count
)
begin
if(reset = '1')then
-- 惑怕 扁拌
rx_next_state <= rx_ready;
-- 郴何 腳齲
rx_buffer <= (others => '0');
rx_bit_count <= (others => '0');
rx_baudrate_enable <= '0';
rx_baudrate_clock1 <= '0';
rx_buff_data <= (others => '0');
rx_buff_wrreq <= '0';
elsif(clock'event and clock = '1')then
sync_rx_line <= rx_line;
clk1_rx_line <= sync_rx_line;
rx_baudrate_clock1 <= rx_baudrate_clock;
case rx_current_state is
when rx_ready =>
rx_buff_wrreq <= '0';
if(clk1_rx_line = '1' and sync_rx_line = '0')then
rx_baudrate_enable <= '1';
rx_next_state <= rx_start;
else
rx_baudrate_enable <= '0';
end if;
when rx_start =>
if(rx_baudrate_clock1 = '0' and rx_baudrate_clock = '1')then
if(sync_rx_line = '0')then
rx_next_state <= rx_data_accept;
else
rx_next_state <= rx_ready;
end if;
end if;
when rx_data_accept =>
if(rx_baudrate_clock1 = '0' and rx_baudrate_clock = '1')then
rx_buffer(7) <= sync_rx_line;
rx_buffer(6) <= rx_buffer(7);
rx_buffer(5) <= rx_buffer(6);
rx_buffer(4) <= rx_buffer(5);
rx_buffer(3) <= rx_buffer(4);
rx_buffer(2) <= rx_buffer(3);
rx_buffer(1) <= rx_buffer(2);
rx_buffer(0) <= rx_buffer(1);
if(rx_bit_count = "111")then
rx_bit_count <= (others => '0');
if(com_control(1) = '0')then
rx_next_state <= rx_stop_bit;
else
rx_next_state <= rx_parity_bit;
end if;
else
rx_bit_count <= rx_bit_count + 1;
end if;
end if;
when rx_parity_bit =>
if(rx_baudrate_clock1 = '0' and rx_baudrate_clock = '1')then
rx_next_state <= rx_stop_bit;
end if;
when rx_stop_bit =>
if(rx_baudrate_clock1 = '0' and rx_baudrate_clock = '1')then
if(sync_rx_line = '1')then
rx_buff_data <= rx_buffer;
rx_buff_wrreq <= '1';
end if;
rx_next_state <= rx_ready;
end if;
end case;
end if;
rx_current_state <= rx_next_state;
end process;
----------------------------------------------------------------
-- 價腳 葛碘
----------------------------------------------------------------
transmitter : process(
reset,
clock,
tx_current_state,
tx_next_state,
tx_baudrate_clock,
tx_bit_count
)
begin
if(reset = '1')then
-- 惑怕 扁拌
tx_next_state <= tx_ready;
-- 郴何 腳齲
tx_buffer <= (others => '0');
tx_bit_count <= (others => '0');
tx_baudrate_enable <= '0';
tx_line <= '1';
tx_baudrate_clock1 <= '0';
elsif(clock'event and clock = '1')then
tx_baudrate_clock1 <= tx_baudrate_clock;
case tx_current_state is
when tx_ready =>
if(tx_buff_empty = '0')then
tx_buff_rdreq <= '1';
tx_next_state <= tx_read_delay;
else
tx_baudrate_enable <= '0';
end if;
when tx_read_delay =>
tx_buff_rdreq <= '0';
tx_next_state <= tx_read_data;
when tx_read_data =>
tx_buffer <= tx_buff_q;
tx_baudrate_enable <= '1';
tx_line <= '0';
tx_parity <= '0';
tx_next_state <= tx_data_transmit;
when tx_data_transmit =>
if(tx_baudrate_clock1 = '1' and tx_baudrate_clock = '0')then
tx_line <= tx_buffer(0);
tx_parity <= tx_parity xor tx_buffer(0);
tx_buffer(0) <= tx_buffer(1);
tx_buffer(1) <= tx_buffer(2);
tx_buffer(2) <= tx_buffer(3);
tx_buffer(3) <= tx_buffer(4);
tx_buffer(4) <= tx_buffer(5);
tx_buffer(5) <= tx_buffer(6);
tx_buffer(6) <= tx_buffer(7);
if(tx_bit_count = "111")then
tx_bit_count <= (others => '0');
if(com_control(1) = '0')then
tx_next_state <= tx_stop_bit;
else
tx_next_state <= tx_parity_bit;
end if;
else
tx_bit_count <= tx_bit_count + 1;
end if;
end if;
when tx_parity_bit =>
if(tx_baudrate_clock1 = '1' and tx_baudrate_clock = '0')then
tx_line <= tx_parity xor com_control(0);
tx_next_state <= tx_stop_bit;
end if;
when tx_stop_bit =>
if(tx_baudrate_clock1 = '1' and tx_baudrate_clock = '0')then
if(tx_bit_count = "001")then
tx_bit_count <= (others => '0');
tx_next_state <= tx_ready;
else
tx_bit_count <= tx_bit_count + 1;
tx_line <= '1';
end if;
end if;
end case;
end if;
tx_current_state <= tx_next_state;
end process;
----------------------------------------------------------------
-- 肺流 腳齲
----------------------------------------------------------------
end uart_tranceiver_a;
--============================================================================
-- 場
--============================================================================
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -