VHDL Code for UART Transmitter: Syntax and Example
A UART transmitter in
VHDL sends serial data by shifting bits out at a set baud rate. It typically includes a state machine to handle start, data, parity, and stop bits. The transmitter outputs a serial line signal that can be connected to a UART receiver.Syntax
The UART transmitter in VHDL usually has inputs for clock, reset, data to send, and a signal to start transmission. It outputs a serial data line and a busy flag. The main parts include:
- clk: Clock signal.
- reset: Resets the transmitter state.
- tx_start: Signal to start sending data.
- tx_data: 8-bit data to transmit.
- tx_serial: Serial output line.
- tx_busy: Indicates transmitter is busy.
The transmitter uses a baud rate generator to time bit transmission and a state machine to send start bit, data bits, and stop bit.
vhdl
entity uart_tx is
Port (
clk : in std_logic;
reset : in std_logic;
tx_start : in std_logic;
tx_data : in std_logic_vector(7 downto 0);
tx_serial : out std_logic;
tx_busy : out std_logic
);
end uart_tx;
architecture Behavioral of uart_tx is
-- Signals and states will be declared here
begin
-- Process for UART transmission logic
end Behavioral;Example
This example shows a simple UART transmitter that sends 8-bit data with 1 start bit (low), 8 data bits (LSB first), and 1 stop bit (high). It uses a 16x baud rate clock enable signal to time bits.
vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity uart_tx is
port(
clk : in std_logic;
reset : in std_logic;
tx_start : in std_logic;
tx_data : in std_logic_vector(7 downto 0);
tx_serial : out std_logic;
tx_busy : out std_logic
);
end uart_tx;
architecture Behavioral of uart_tx is
type state_type is (idle, start_bit, data_bits, stop_bit);
signal state : state_type := idle;
signal bit_index : integer range 0 to 7 := 0;
signal shift_reg : std_logic_vector(7 downto 0) := (others => '0');
signal baud_tick : std_logic := '0';
signal baud_count : integer range 0 to 15 := 0;
signal tx_out : std_logic := '1';
begin
-- Baud rate generator (assuming clk is 16x baud rate)
process(clk, reset)
begin
if reset = '1' then
baud_count <= 0;
baud_tick <= '0';
elsif rising_edge(clk) then
if baud_count = 15 then
baud_count <= 0;
baud_tick <= '1';
else
baud_count <= baud_count + 1;
baud_tick <= '0';
end if;
end if;
end process;
-- UART transmitter state machine
process(clk, reset)
begin
if reset = '1' then
state <= idle;
tx_out <= '1';
bit_index <= 0;
shift_reg <= (others => '0');
tx_busy <= '0';
elsif rising_edge(clk) then
if baud_tick = '1' then
case state is
when idle =>
tx_out <= '1'; -- line idle high
tx_busy <= '0';
if tx_start = '1' then
shift_reg <= tx_data;
state <= start_bit;
tx_busy <= '1';
end if;
when start_bit =>
tx_out <= '0'; -- start bit low
state <= data_bits;
bit_index <= 0;
when data_bits =>
tx_out <= shift_reg(bit_index);
if bit_index = 7 then
state <= stop_bit;
else
bit_index <= bit_index + 1;
end if;
when stop_bit =>
tx_out <= '1'; -- stop bit high
state <= idle;
tx_busy <= '0';
end case;
end if;
end if;
end process;
tx_serial <= tx_out;
end Behavioral;Output
The tx_serial line outputs a serial stream: start bit (0), 8 data bits LSB first, then stop bit (1). The tx_busy signal is high during transmission.
Common Pitfalls
Common mistakes when writing a UART transmitter in VHDL include:
- Not generating the correct baud rate timing, causing wrong bit durations.
- Forgetting to send the start bit low before data bits.
- Sending data bits in the wrong order (should be LSB first).
- Not setting the stop bit high at the end.
- Not managing the
tx_busysignal properly, leading to data overwrite.
Always test with a known baud rate clock and verify the serial output timing with a logic analyzer or simulation.
vhdl
-- wrong approach:
-- Sending data bits MSB first (incorrect)
-- tx_out <= shift_reg(7 - bit_index);
-- correct approach:
-- Sending data bits LSB first
-- tx_out <= shift_reg(bit_index);Quick Reference
Tips for implementing a UART transmitter in VHDL:
- Use a baud rate generator to create a tick for bit timing.
- Implement a state machine with states: idle, start bit, data bits, stop bit.
- Send start bit as low, data bits LSB first, stop bit as high.
- Use a shift register to hold data bits during transmission.
- Use a busy flag to prevent new data start until current transmission ends.
Key Takeaways
A UART transmitter sends serial data bit by bit using a state machine and baud rate timing.
Always send a low start bit, then data bits LSB first, followed by a high stop bit.
Use a baud rate generator to ensure correct timing for each bit.
Manage a busy signal to avoid starting new transmissions before the current one finishes.
Test your UART transmitter with simulation or hardware tools to verify timing and data order.