-- -- miniUARTSend v1.01 -- By PEK '2004 -- -- v1.01 - 2004.04.04 -- * stop_bit -- * better documentation of signals -- * better possibilities of sending several bytes -- -- -- About: -- Component to send messages via standard UART serial communication. The -- routine is coded to be as small as possible and no extra features are added. -- -- Baudrate - Set by the programmer as a generic integer -- Parity - None -- Stopbit - One -- -- Generic constants: -- CLOCKS_PER_BIT - Clock cycles to wait per bit in the message to send -- -- Input: -- clk - System clock, used to calculate CLOCKS_PER_BIT -- reset_n - System reset, negative -- data_in - Byte to send -- new_byte - Set high when you want to send a new byte -- -- Output: -- ready_out - High when the component is ready to send a new byte (syncronous output) -- data_out - The output (syncronous output) -- stop_bit - High when data_out = stop bit in message (syncronous output) -- -- -- Send one byte (S = start bit, s = stop bit): -- -- data_in (in) XXXXXXXXXXXXXXX .... ==================XXXXXXXXXXX -- -- new_byte (in) ______|¯¯XXXXXX .... XXXXXXXXXXXXXXXXXX___________ -- -- ready_out (out) ¯¯¯¯¯¯¯|_______ .... ___________________|¯¯¯¯¯¯¯¯¯ -- -- stop_bit (out) _______________ .... _________________|¯|_________ -- -- data_out (out) ¯¯¯¯¯¯¯¯|______ .... S 1 2 3 4 5 6 7 8 s ¯¯¯¯¯¯¯¯¯ -- -- -- Send several bytes: -- -- data_in (in) XXXXXXXXXXXXXXX .... ==================XXX=================XXXXXXXX -- -- new_byte (in) ______|¯¯¯¯¯¯¯¯ .... ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯XXXXXXXXXXXXXXXXXX________ -- -- ready_out (out) ¯¯¯¯¯¯¯|_______ .... _______________________________________|¯¯¯¯¯¯ -- -- stop_bit (out) _______________ .... _________________|¯|_________________|¯|______ -- -- data_out (out) ¯¯¯¯¯¯¯¯|______ .... S 1 2 3 4 5 6 7 8 s S 1 2 3 4 5 6 7 8 s ¯¯¯¯¯¯ -- -- -- Baudrate calculations: -- The baudrate is set by the constant CLOCKS_PER_BIT. You need to calculate the required -- value for your program. -- Example: 19200 bps with a 50 MHz system clock. CLOCKS_PER_BIT = 50000000/19200 = 2604. -- -- Notes: -- Allways begin to set reset_n low for atleast a clock cycle to reset all registers -- during the upstart period. -- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity miniUARTSend is generic ( CLOCKS_PER_BIT: integer := 10 -- Clocks per bit to send ); port ( clk: in std_logic; -- System clock reset_n: in std_logic; -- System reset, negative data_in: in std_logic_vector(7 downto 0); -- Byte in new_byte: in std_logic; -- New byte to send ready_out: out std_logic; -- Ready to send new byte data_out: out std_logic; -- Bit out stop_bit: out std_logic -- Stop bit ); end; architecture rtl of miniUARTSend is type sendstate_type is (WAITING, START_B, B0, B1, B2, B3, B4, B5, B6, B7, PARITY, STOP_B); signal counter: integer range 0 to CLOCKS_PER_BIT; signal ready: std_logic; signal sendstate: sendstate_type; signal nextstate: sendstate_type; signal new_bit: std_logic; signal dataout: std_logic; signal stopbit: std_logic; begin process(clk, ready) begin if ready = '1' then counter <= CLOCKS_PER_BIT; new_bit <= '0'; elsif clk'event and clk='1' then if counter = CLOCKS_PER_BIT then counter <= 0; new_bit <= '1'; else counter <= counter + 1; new_bit <= '0'; end if; end if; end process; process(reset_n, new_bit) begin if reset_n = '0' then sendstate <= WAITING; elsif new_bit'event and new_bit = '1' then sendstate <= nextstate; end if; end process; process(reset_n, clk) begin if reset_n = '0' then data_out <= '1'; stop_bit <= '0'; ready_out <= '1'; elsif clk'event and clk = '1' then data_out <= dataout; stop_bit <= stopbit; ready_out <= ready; end if; end process; process(reset_n, sendstate, new_byte, data_in) begin if reset_n = '0' then nextstate <= START_B; dataout <= '1'; ready <= '1'; stopbit <= '0'; else case sendstate is when WAITING => nextstate <= START_B; dataout <= '1'; stopbit <= '0'; ready <= not new_byte; when START_B => nextstate <= B0; dataout <= '0'; ready <= '0'; stopbit <= '0'; when B0 => nextstate <= B1; dataout <= data_in(0); ready <= '0'; stopbit <= '0'; when B1 => nextstate <= B2; dataout <= data_in(1); ready <= '0'; stopbit <= '0'; when B2 => nextstate <= B3; dataout <= data_in(2); ready <= '0'; stopbit <= '0'; when B3 => nextstate <= B4; dataout <= data_in(3); ready <= '0'; stopbit <= '0'; when B4 => nextstate <= B5; dataout <= data_in(4); ready <= '0'; stopbit <= '0'; when B5 => nextstate <= B6; dataout <= data_in(5); ready <= '0'; stopbit <= '0'; when B6 => nextstate <= B7; dataout <= data_in(6); ready <= '0'; stopbit <= '0'; when B7 => nextstate <= STOP_B; dataout <= data_in(7); ready <= '0'; stopbit <= '0'; when STOP_B => if new_byte = '1' then nextstate <= START_B; else nextstate <= WAITING; end if; dataout <= '1'; ready <= '0'; stopbit <= '1'; when others => nextstate <= WAITING; dataout <= '1'; ready <= '0'; stopbit <= '0'; end case; end if; end process; end;