[142] | 1 | ---------------------------------------------------------------------------- |
---|
| 2 | -- UART_TX_CTRL.vhd -- UART Data Transfer Component |
---|
| 3 | ---------------------------------------------------------------------------- |
---|
| 4 | -- Author: Sam Bobrowicz |
---|
| 5 | -- Copyright 2011 Digilent, Inc. |
---|
| 6 | ---------------------------------------------------------------------------- |
---|
| 7 | -- |
---|
| 8 | ---------------------------------------------------------------------------- |
---|
| 9 | -- This component may be used to transfer data over a UART device. It will |
---|
| 10 | -- serialize a byte of data and transmit it over a TXD line. The serialized |
---|
| 11 | -- data has the following characteristics: |
---|
| 12 | -- *9600 Baud Rate |
---|
| 13 | -- *8 data bits, LSB first |
---|
| 14 | -- *1 stop bit |
---|
| 15 | -- *no parity |
---|
| 16 | -- |
---|
| 17 | -- Port Descriptions: |
---|
| 18 | -- |
---|
| 19 | -- SEND - Used to trigger a send operation. The upper layer logic should |
---|
| 20 | -- set this signal high for a single clock cycle to trigger a |
---|
| 21 | -- send. When this signal is set high DATA must be valid . Should |
---|
| 22 | -- not be asserted unless READY is high. |
---|
| 23 | -- DATA - The parallel data to be sent. Must be valid the clock cycle |
---|
| 24 | -- that SEND has gone high. |
---|
| 25 | -- CLK - A 100 MHz clock is expected |
---|
| 26 | -- READY - This signal goes low once a send operation has begun and |
---|
| 27 | -- remains low until it has completed and the module is ready to |
---|
| 28 | -- send another byte. |
---|
| 29 | -- UART_TX - This signal should be routed to the appropriate TX pin of the |
---|
| 30 | -- external UART device. |
---|
| 31 | -- |
---|
| 32 | ---------------------------------------------------------------------------- |
---|
| 33 | -- |
---|
| 34 | ---------------------------------------------------------------------------- |
---|
| 35 | -- Revision History: |
---|
| 36 | -- 08/08/2011(SamB): Created using Xilinx Tools 13.2 |
---|
| 37 | ---------------------------------------------------------------------------- |
---|
| 38 | library IEEE; |
---|
| 39 | use IEEE.STD_LOGIC_1164.ALL; |
---|
| 40 | use IEEE.std_logic_unsigned.all; |
---|
| 41 | use IEEE.numeric_STD.All; |
---|
| 42 | entity UART_TX_CTRL is |
---|
| 43 | generic (ComRate : natural:=217); --vitesse de port serie pour 230400 Bauds @50 MHz |
---|
| 44 | Port ( SEND : in STD_LOGIC; |
---|
| 45 | DATA : in STD_LOGIC_VECTOR (7 downto 0); |
---|
| 46 | CLK : in STD_LOGIC; |
---|
| 47 | READY : out STD_LOGIC; |
---|
| 48 | UART_TX : out STD_LOGIC); |
---|
| 49 | end UART_TX_CTRL; |
---|
| 50 | |
---|
| 51 | architecture Behavioral of UART_TX_CTRL is |
---|
| 52 | |
---|
| 53 | type TX_STATE_TYPE is (RDY, LOAD_BIT, SEND_BIT); |
---|
| 54 | |
---|
| 55 | --constant BIT_TMR_MAX : std_logic_vector(13 downto 0) := "00000011011001";--217 = (round(50MHz / 230 400)) - 1 |
---|
| 56 | constant BIT_TMR_MAX : std_logic_vector(13 downto 0) := std_logic_vector(to_unsigned(comrate,14)); |
---|
| 57 | constant BIT_INDEX_MAX : natural := 10; |
---|
| 58 | |
---|
| 59 | --Counter that keeps track of the number of clock cycles the current bit has been held stable over the |
---|
| 60 | --UART TX line. It is used to signal when the ne |
---|
| 61 | signal bitTmr : std_logic_vector(13 downto 0) := (others => '0'); |
---|
| 62 | |
---|
| 63 | --combinatorial logic that goes high when bitTmr has counted to the proper value to ensure |
---|
| 64 | --a 9600 baud rate |
---|
| 65 | signal bitDone : std_logic; |
---|
| 66 | |
---|
| 67 | --Contains the index of the next bit in txData that needs to be transferred |
---|
| 68 | signal bitIndex : natural; |
---|
| 69 | |
---|
| 70 | --a register that holds the current data being sent over the UART TX line |
---|
| 71 | signal txBit : std_logic := '1'; |
---|
| 72 | |
---|
| 73 | --A register that contains the whole data packet to be sent, including start and stop bits. |
---|
| 74 | signal txData : std_logic_vector(9 downto 0); |
---|
| 75 | |
---|
| 76 | signal txState : TX_STATE_TYPE := RDY; |
---|
| 77 | |
---|
| 78 | begin |
---|
| 79 | |
---|
| 80 | --Next state logic |
---|
| 81 | next_txState_process : process (CLK) |
---|
| 82 | begin |
---|
| 83 | if (rising_edge(CLK)) then |
---|
| 84 | case txState is |
---|
| 85 | when RDY => |
---|
| 86 | if (SEND = '1') then |
---|
| 87 | txState <= LOAD_BIT; |
---|
| 88 | end if; |
---|
| 89 | when LOAD_BIT => |
---|
| 90 | txState <= SEND_BIT; |
---|
| 91 | when SEND_BIT => |
---|
| 92 | if (bitDone = '1') then |
---|
| 93 | if (bitIndex = BIT_INDEX_MAX) then |
---|
| 94 | txState <= RDY; |
---|
| 95 | else |
---|
| 96 | txState <= LOAD_BIT; |
---|
| 97 | end if; |
---|
| 98 | end if; |
---|
| 99 | when others=> --should never be reached |
---|
| 100 | txState <= RDY; |
---|
| 101 | end case; |
---|
| 102 | end if; |
---|
| 103 | end process; |
---|
| 104 | |
---|
| 105 | bit_timing_process : process (CLK) |
---|
| 106 | begin |
---|
| 107 | if (rising_edge(CLK)) then |
---|
| 108 | if (txState = RDY) then |
---|
| 109 | bitTmr <= (others => '0'); |
---|
| 110 | else |
---|
| 111 | if (bitDone = '1') then |
---|
| 112 | bitTmr <= (others => '0'); |
---|
| 113 | else |
---|
| 114 | bitTmr <= bitTmr + 1; |
---|
| 115 | end if; |
---|
| 116 | end if; |
---|
| 117 | end if; |
---|
| 118 | end process; |
---|
| 119 | |
---|
| 120 | bitDone <= '1' when (bitTmr = BIT_TMR_MAX) else |
---|
| 121 | '0'; |
---|
| 122 | |
---|
| 123 | bit_counting_process : process (CLK) |
---|
| 124 | begin |
---|
| 125 | if (rising_edge(CLK)) then |
---|
| 126 | if (txState = RDY) then |
---|
| 127 | bitIndex <= 0; |
---|
| 128 | elsif (txState = LOAD_BIT) then |
---|
| 129 | bitIndex <= bitIndex + 1; |
---|
| 130 | end if; |
---|
| 131 | end if; |
---|
| 132 | end process; |
---|
| 133 | |
---|
| 134 | tx_data_latch_process : process (CLK) |
---|
| 135 | begin |
---|
| 136 | if (rising_edge(CLK)) then |
---|
| 137 | if (SEND = '1') then |
---|
| 138 | txData <= '1' & DATA & '0'; |
---|
| 139 | end if; |
---|
| 140 | end if; |
---|
| 141 | end process; |
---|
| 142 | |
---|
| 143 | tx_bit_process : process (CLK) |
---|
| 144 | begin |
---|
| 145 | if (rising_edge(CLK)) then |
---|
| 146 | if (txState = RDY) then |
---|
| 147 | txBit <= '1'; |
---|
| 148 | elsif (txState = LOAD_BIT) then |
---|
| 149 | txBit <= txData(bitIndex); |
---|
| 150 | end if; |
---|
| 151 | end if; |
---|
| 152 | end process; |
---|
| 153 | |
---|
| 154 | UART_TX <= txBit; |
---|
| 155 | READY <= '1' when (txState = RDY) else |
---|
| 156 | '0'; |
---|
| 157 | |
---|
| 158 | end Behavioral; |
---|
| 159 | |
---|