📄 uart_serial.vhd
字号:
tx_top_baud <= '0';
tx_br_divisor_cnt := 0;
elsif rising_edge(clk) then
tx_top_baud <= '0';
if top_ref_baud = '1' then
tx_br_divisor_cnt := tx_br_divisor_cnt + 1;
if tx_br_divisor_cnt = br_divisor then
tx_top_baud <= '1';
tx_br_divisor_cnt := 0;
end if;
end if;
end if;
end process;
rx_baud_proc:
process(reset, clk)
variable rx_br_divisor_cnt : std_logic_vector(9 downto 0);
begin
if reset = '1' then
rx_top_baud <= '0';
rx_br_divisor_cnt := (others => '0');
elsif rising_edge(clk) then
rx_top_baud <= '0';
if clr_rx_baud = '1' then
rx_br_divisor_cnt := (others => '0');
elsif top_ref_baud = '1' and rx_state /= IDLE then
rx_br_divisor_cnt := rx_br_divisor_cnt + 1;
if rx_br_divisor_cnt(8 downto 0) = br_divisor(9 downto 1) then
rx_top_baud <= '1';
rx_br_divisor_cnt := (others => '0');
end if;
end if;
end if;
end process;
-------------------------------------------------------------------------------
-- Transmition process
-------------------------------------------------------------------------------
tx_proc:
process(reset, clk)
variable tx_bit_cnt : integer;
begin
if reset = '1' then
tx_data_s <= (others => '0');
tx_data_reg <= (others => '1');
tx_ch_rdy <= '0';
elsif rising_edge(clk) then
case tx_state is
when IDLE =>
if tx_data_en = '1' then
tx_data_s <= tx_data_in;
tx_ch_rdy <= '0';
tx_state <= LOAD_TX_DATA;
else
tx_ch_rdy <= '1';
end if;
when LOAD_TX_DATA =>
if tx_top_baud = '1' then
if parity_en = '1' then
-- start + data + parity + stop
tx_bit_cnt := 8 + 3;
tx_data_reg(10 downto 0) <= '1' & parity(tx_data_s,parity_type) & tx_data_s(7 downto 0) & '0';
else
-- start + data + stop
tx_bit_cnt := 8 + 2;
tx_data_reg(10 downto 0) <= "11" & tx_data_s(7 downto 0) & '0';
end if;
tx_state <= TX_DATA;
end if;
when TX_DATA =>
if tx_top_baud = '1' then
tx_data_reg(10 downto 0) <= '1' & tx_data_reg(10 downto 1);
tx_bit_cnt := tx_bit_cnt-1;
if tx_bit_cnt = 1 then
tx_state <= TX_STOP;
end if;
end if;
when TX_STOP => -- stop bit
if tx_top_baud = '1' then
tx_state <= IDLE;
end if;
when others =>
null;
end case;
end if;
end process;
tx_data_serial <= tx_data_reg(0);
-------------------------------------------------------------------------------
-- Reception process
-------------------------------------------------------------------------------
process(reset, clk)
variable rx_bit_cnt : integer;
begin
if reset = '1' then
rx_data_out <= (others => '0');
rx_data_en <= '0';
rx_ovf_err <= '0';
rx_data_i <= (others => '0');
rx_parity_err <= '0';
rx_parity_err_i<= '0';
elsif rising_edge(clk) then
clr_rx_baud <= '0';
rx_ovf_err <= '0';
rx_parity_err <= '0';
rx_parity_err_i<= '0';
rx_data_en <= '0';
case rx_state is
when IDLE => -- Wait start bit
if top_ref_baud = '1' then
if rx_data_serial = '0' then
clr_rx_baud <= '1';
rx_state <= START_RX;
rx_bit_cnt := 1;
end if;
end if;
when START_RX =>
if rx_top_baud = '1' then
if rx_data_serial = '1' then
rx_state <= RX_OVF;
else
rx_state <= EDGE_RX;
end if;
end if;
when EDGE_RX =>
if rx_top_baud = '1' then
if (parity_en = '1' and rx_bit_cnt = 10) or -- start + data + parity + stop
(parity_en = '0' and rx_bit_cnt = 9) then -- start + data + stop
rx_state <= STOP_RX;
else -- data
rx_state <= SHIFT_RX;
end if;
end if;
when SHIFT_RX =>
if rx_top_baud = '1' then
rx_bit_cnt := rx_bit_cnt + 1;
if not((parity_en = '1' and rx_bit_cnt = 10)) then -- start + data + parity + stop
rx_data_i(7 downto 0) <= rx_data_serial & rx_data_i(7 downto 1);
else
if parity(rx_data_i,parity_type) /= rx_data_serial then
rx_parity_err_i <= '1';
end if;
end if;
rx_state <= EDGE_RX;
end if;
when STOP_RX =>
-- if rx_top_baud = '1' then
rx_data_out <= rx_data_i;
rx_parity_err <= rx_parity_err_i;
rx_ovf_err <= '0';
rx_data_en <= '1';
rx_state <= IDLE;
-- end if;
when RX_OVF => -- Overframe error
rx_ovf_err <= '1';
if rx_data_serial = '1' then
rx_state <= IDLE;
end if;
when others => null;
end case;
end if;
end process;
end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -