-- UART Transmitter
--
-- Version : 1.00 
-- Version Date : 15 December 2016
--
------------------------------------------------------------------------------------
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
--
------------------------------------------------------------------------------------
--
-- Main Entity
--
entity juart_tx is
	Port
	(
		rst				: in std_logic;
		clk				: in std_logic;
		we				: in std_logic;
		din				: in unsigned(7 downto 0);
		en_16_x_baud	: in std_logic;
		Tx_complete		: out std_logic;
		ser_out			: out std_logic
	);
end juart_tx;
--
------------------------------------------------------------------------------------
--
-- Start of Main Architecture
--	 
architecture behavior of juart_tx is
--
------------------------------------------------------------------------------------
--
------------------------------------------------------------------------------------
--
-- Signals used
--
------------------------------------------------------------------------------------
--
signal dinreg				: unsigned (7 downto 0);
signal shiftreg				: unsigned (9 downto 0);
signal busy					: std_logic;
signal start				: std_logic;
signal shift_enable			: std_logic;
signal shift_enable_count	: unsigned (3 downto 0);
signal bit_count			: unsigned (3 downto 0);

--
--
begin
ser_out		<= shiftreg(0);
Tx_complete	<= not busy;

shift_enable_counter:
process(clk)
begin
	if rising_edge(clk) then
		shift_enable <= '0';
		if rst = '1' then
			shift_enable_count <= (others => '1');
		elsif en_16_x_baud = '1' then
			if shift_enable_count = 0 then
				shift_enable	<= '1';
				shift_enable_count <= (others => '1');
			else
				shift_enable_count <= shift_enable_count - 1;
			end if;
		end if;
	end if;
end process;
	
bit_counter:
process(clk)
begin
	if rising_edge(clk) then
		if start = '1' then
			bit_count <= to_unsigned(shiftreg'length-1, bit_count'length);
		elsif shift_enable = '1' then
			if not (bit_count = 0) then
				bit_count <= bit_count - 1;
			end if;
		end if;
	end if;
end process;

transmit:
process(clk)
begin
	if rising_edge(clk) then
		if rst = '1' then
			shiftreg <= (others => '1');
			busy	<= '0';
			start	<= '0';
		elsif busy = '0' then
			if we = '1' then
				busy		<= '1';
				start		<= '1';
				dinreg		<= din;
			end if;
		elsif shift_enable = '1' then
			if start = '1' then
				start		<= '0';
				shiftreg	<= '1' & dinreg & '0';
			elsif bit_count /= 0 then
				shiftreg	<= '1' & shiftreg(shiftreg'left downto 1);
				if bit_count = 1 then
					busy	<= '0';
				end if;

			end if;
		end if;
	end if;
end process;

end behavior;

------------------------------------------------------------------------------------
--
-- END OF FILE
--
------------------------------------------------------------------------------------


