library ieee ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all;
entity txmit is
port (CLK_IN, START, CTS, RTS : in std_logic ;
DATA_INPUT : in std_logic_vector(7 downto 0);
sdo : out std_logic ) ;
end txmit ;
architecture v1 of txmit is
signal LOAD_ENABLE : std_logic;
signal TXD_TEMP, TXD_TEMP_PUFFER: std_logic_vector (7 downto 0);
signal BAUD_CLK : std_logic;
signal state : unsigned (3 downto 0);
type states is (Idle, Transmit, Loaddata);
signal current_state : states;
signal next_state : states;
begin
tx_init: process (BAUD_CLK, current_state, state)
begin
if (rising_edge(BAUD_CLK) ) then
if (current_state = Transmit) then
state <= state + "0001" ;
else
state <= "0000" ;
end if;
end if;
end process;
NEXT_STATE_DECODE: process (current_state, state, START)
begin
next_state <= current_state; --default is to stay in current state
case (current_state) is
when Idle =>
if (START = '1') then
next_state <= Loaddata;
end if;
when Loaddata =>
if (START = '0') then
next_state <= Transmit;
end if;
when Transmit =>
if (START = '0' and std_logic_vector(state) = "1101") then
next_state <= Idle;
end if;
when others =>
next_state <= Idle;
end case;
end process;
LOAD_DATA: process (DATA_INPUT, CLK_IN, LOAD_ENABLE)
begin
if (rising_edge(CLK_IN))then
if (LOAD_ENABLE = '1') then
TXD_TEMP <= DATA_INPUT;
end if;
end if;
end process;
BAUD_RATE: process (CLK_IN)
variable clk_div_counter : integer range 0 to 5208;
begin
if (rising_edge(CLK_IN)) then
if (clk_div_counter = 5208) then --50MHz base CLK_IN / 9600baud = 5208,3
clk_div_counter := 0; --ISE 13.4 sucks with ranged integer, had to limit it manualy
BAUD_CLK <= '1';
else
clk_div_counter := clk_div_counter + 1;
BAUD_CLK <= '0';
end if;
end if;
End Process;
OUTPUT_DECODE: process (CLK_IN, current_state)
begin
if (rising_edge(CLK_IN)) then
if (current_state = Idle) then
LOAD_ENABLE <= '0';
elsif (current_state = Loaddata) then
LOAD_ENABLE <= '1';
elsif (current_state = Transmit) then
LOAD_ENABLE <= '0';
end if;
end if;
end process;
SYNC_PROC: process (CLK_IN)
begin
if (rising_edge(CLK_IN)) then
current_state <= next_state;
end if;
end process;
Transmit_process : process (BAUD_CLK, current_state, state, TXD_TEMP, CTS, RTS) -- data format: 1 start bit, 8 data bits, 2 stop bits, no parity bit
begin
if (rising_edge(BAUD_CLK) and current_state = Transmit and CTS = '1' and RTS = '1') then
if (std_logic_vector(state) = "0001") then --start '0' bit
sdo <= '0' ;
elsif (std_logic_vector(state) >= "0010" and std_logic_vector(state) <= "1010") then --shift out 8 bits data
TXD_TEMP_PUFFER <= TXD_TEMP(6 downto 0) & "0" ;
sdo <= TXD_TEMP_PUFFER(7) ;
elsif (std_logic_vector(state) = "1011") then -- 2 stop '1' bit
sdo <= '1';
elsif (std_logic_vector(state) = "1100") then
sdo <= '1';
end if ;
end if ;
end process ;
end ;