Uart VHD
Uart VHD
--
-- FileName: uart.vhd
-- Dependencies: none
-- Design Software: Quartus II 64-bit Version 13.1.0 Build 162 SJ Web Edition
--
-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY
-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--
-- Version History
-- Version 1.0 5/26/2017 Scott Larson
-- Initial Public Release
-- Version 1.1 8/3/2021 Scott Larson
-- Corrected rx start bit error checking
--
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY uart IS
GENERIC(
clk_freq : INTEGER := 50_000_000; --frequency of system clock in Hertz
baud_rate : INTEGER := 19_200; --data link baud rate in bits/second
os_rate : INTEGER := 16; --oversampling rate to find center of
receive bits (in samples per baud period)
d_width : INTEGER := 8; --data bus width
parity : INTEGER := 1; --0 for no parity, 1 for parity
parity_eo : STD_LOGIC := '0'); --'0' for even, '1' for odd parity
PORT(
clk : IN STD_LOGIC; --system clock
reset_n : IN STD_LOGIC; --ascynchronous reset
tx_ena : IN STD_LOGIC; --initiate transmission
tx_data : IN STD_LOGIC_VECTOR(d_width-1 DOWNTO 0); --data to transmit
rx : IN STD_LOGIC; --receive pin
rx_busy : OUT STD_LOGIC; --data reception in
progress
rx_error : OUT STD_LOGIC; --start, parity, or
stop bit error detected
rx_data : OUT STD_LOGIC_VECTOR(d_width-1 DOWNTO 0); --data received
tx_busy : OUT STD_LOGIC; --transmission in
progress
tx : OUT STD_LOGIC); --transmit pin
END uart;
--generate clock enable pulses at the baud rate and the oversampling rate
PROCESS(reset_n, clk)
VARIABLE count_baud : INTEGER RANGE 0 TO clk_freq/baud_rate-1 := 0; --
counter to determine baud rate period
VARIABLE count_os : INTEGER RANGE 0 TO clk_freq/baud_rate/os_rate-1 := 0; --
counter to determine oversampling period
BEGIN
IF(reset_n = '0') THEN --asynchronous reset asserted
baud_pulse <= '0'; --reset baud rate pulse
os_pulse <= '0'; --reset oversampling rate
pulse
count_baud := 0; --reset baud period counter
count_os := 0; --reset oversampling period
counter
ELSIF(clk'EVENT AND clk = '1') THEN
--create baud enable pulse
IF(count_baud < clk_freq/baud_rate-1) THEN --baud period not reached
count_baud := count_baud + 1; --increment baud period
counter
baud_pulse <= '0'; --deassert baud rate
pulse
ELSE --baud period reached
count_baud := 0; --reset baud period
counter
baud_pulse <= '1'; --assert baud rate pulse
count_os := 0; --reset oversampling
period counter to avoid cumulative error
END IF;
--create oversampling enable pulse
IF(count_os < clk_freq/baud_rate/os_rate-1) THEN --oversampling period not
reached
count_os := count_os + 1; --increment oversampling
period counter
os_pulse <= '0'; --deassert oversampling
rate pulse
ELSE --oversampling period
reached
count_os := 0; --reset oversampling
period counter
os_pulse <= '1'; --assert oversampling
pulse
END IF;
END IF;
END PROCESS;
END logic;