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 | |
---|