I'm working on a UART transmit process (uart_transmit)
in VHDL (115200 baud, 8 data bits, 1 stop bit and no parity). I need the transmit line (tx_line)
in the process to go idle whenever the carriage return (CARR_RET)
in the message buffer is detected.
The buffer is part of another process but it shifts each character into char_byte
when the transmission of the last byte has finished. It is clocked by the TX_DONE
signal.
The issue I'm having, however, is that the FPGA transmits the entire message as required except for the carriage return. I know it's because the process uart_ready
detects the carriage return and changes the state of TX_READY
accordingly but I don't know how to workaround the instantaneous change, I thought about delaying the TX_READY
signal with an FDC but that didn't work. Are there any suggestions as to how I can detect the carriage return, transmit the carriage return and still send the transmit line to idle?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD;
entity uart_tx is
Port (clk : in std_logic;
reset : in std_logic;
tx_line : out std_logic;
switch : in std_logic;
TX_DONE : out std_logic;
char_byte : in std_logic_vector(7 downto 0));
end uart_tx;
architecture Behavioral of uart_tx is
constant stop_bit : std_logic :='1';
constant start_bit : std_logic :='0';
constant idle : std_logic :='1';
constant CARR_RET : std_logic_vector(7 downto 0) :="00001010";
signal TX_READY : std_logic :='0';
signal TX_MESSAGE : std_logic_vector(9 downto 0) :=(others => '0');
begin
uart_ready: process (clk,reset)
begin
if(reset='1') then
TX_READY<='0';
elsif rising_edge(clk)then
if(switch = '1')then
if(char_byte = CARR_RET)then
TX_READY<='0';
else
TX_READY<='1';
end if;
end if;
end if;
end process;
uart_transmit: process (clk,reset)
variable bit_count: integer range 0 to 9:=0;
begin
if(reset='1') then
tx_line<=idle;
bit_count:=0;
TX_DONE<='0';
TX_MESSAGE<="0000000000";
elsif rising_edge(clk)then
if(switch = '1')then
TX_MESSAGE(9 downto 0) <= stop_bit &char_byte &start_bit;
if(TX_READY = '1')then
if(bit_count=9)then
TX_MESSAGE<="0000000000";
TX_DONE<='1';
tx_line<=idle;
bit_count:=0;
else
tx_line<=TX_MESSAGE(bit_count);
bit_count:= bit_count+1;
TX_DONE<='0';
end if;
elsif(TX_READY = '0')then
tx_line<=idle;
end if;
end if;
end if;
end process;
end Behavioral;