OpenCores
URL https://opencores.org/ocsvn/simple_uart_for_fpga/simple_uart_for_fpga/trunk

Subversion Repositories simple_uart_for_fpga

[/] [simple_uart_for_fpga/] [trunk/] [source/] [comp/] [uart_tx.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jakubcabal
--------------------------------------------------------------------------------
2
-- PROJECT: SIMPLE UART FOR FPGA
3
--------------------------------------------------------------------------------
4
-- MODULE:  UART TRANSMITTER
5
-- AUTHORS: Jakub Cabal <jakubcabal@gmail.com>
6
-- lICENSE: The MIT License (MIT)
7
-- WEBSITE: https://github.com/jakubcabal/uart_for_fpga
8
--------------------------------------------------------------------------------
9
 
10
library IEEE;
11
use IEEE.STD_LOGIC_1164.ALL;
12
use IEEE.NUMERIC_STD.ALL;
13
 
14
entity UART_TX is
15
    Generic (
16
        PARITY_BIT  : string := "none" -- legal values: "none", "even", "odd", "mark", "space"
17
    );
18
    Port (
19
        CLK         : in  std_logic; -- system clock
20
        RST         : in  std_logic; -- high active synchronous reset
21
        -- UART INTERFACE
22
        UART_CLK_EN : in  std_logic; -- oversampling (16x) UART clock enable
23
        UART_TXD    : out std_logic;
24
        -- USER DATA INPUT INTERFACE
25
        DATA_IN     : in  std_logic_vector(7 downto 0);
26
        DATA_SEND   : in  std_logic; -- when DATA_SEND = 1, data on DATA_IN will be transmit, DATA_SEND can set to 1 only when BUSY = 0
27
        BUSY        : out std_logic  -- when BUSY = 1 transiever is busy, you must not set DATA_SEND to 1
28
    );
29
end UART_TX;
30
 
31
architecture FULL of UART_TX is
32
 
33
    signal tx_clk_en         : std_logic;
34
    signal tx_clk_divider_en : std_logic;
35
    signal tx_ticks          : unsigned(3 downto 0);
36
    signal tx_data           : std_logic_vector(7 downto 0);
37
    signal tx_bit_count      : unsigned(2 downto 0);
38
    signal tx_bit_count_en   : std_logic;
39
    signal tx_busy           : std_logic;
40
    signal tx_parity_bit     : std_logic;
41
    signal tx_data_out_sel   : std_logic_vector(1 downto 0);
42
 
43
    type state is (idle, txsync, startbit, databits, paritybit, stopbit);
44
    signal tx_pstate : state;
45
    signal tx_nstate : state;
46
 
47
begin
48
 
49
    BUSY <= tx_busy;
50
 
51
    -- -------------------------------------------------------------------------
52
    -- UART TRANSMITTER CLOCK DIVIDER
53
    -- -------------------------------------------------------------------------
54
 
55
    uart_tx_clk_divider : process (CLK)
56
    begin
57
        if (rising_edge(CLK)) then
58
            if (tx_clk_divider_en = '1') then
59
                if (uart_clk_en = '1') then
60
                    if (tx_ticks = "1111") then
61
                        tx_ticks <= (others => '0');
62
                        tx_clk_en <= '0';
63
                    elsif (tx_ticks = "0001") then
64
                        tx_ticks <= tx_ticks + 1;
65
                        tx_clk_en <= '1';
66
                    else
67
                        tx_ticks <= tx_ticks + 1;
68
                        tx_clk_en <= '0';
69
                    end if;
70
                else
71
                    tx_ticks <= tx_ticks;
72
                    tx_clk_en <= '0';
73
                end if;
74
            else
75
                tx_ticks <= (others => '0');
76
                tx_clk_en <= '0';
77
            end if;
78
        end if;
79
    end process;
80
 
81
    -- -------------------------------------------------------------------------
82
    -- UART TRANSMITTER INPUT DATA REGISTER
83
    -- -------------------------------------------------------------------------
84
 
85
    uart_tx_input_data_reg : process (CLK)
86
    begin
87
        if (rising_edge(CLK)) then
88
            if (RST = '1') then
89
                tx_data <= (others => '0');
90
            elsif (DATA_SEND = '1' AND tx_busy = '0') then
91
                tx_data <= DATA_IN;
92
            end if;
93
        end if;
94
    end process;
95
 
96
    -- -------------------------------------------------------------------------
97
    -- UART TRANSMITTER BIT COUNTER
98
    -- -------------------------------------------------------------------------
99
 
100
    uart_tx_bit_counter : process (CLK)
101
    begin
102
        if (rising_edge(CLK)) then
103
            if (RST = '1') then
104
                tx_bit_count <= (others => '0');
105
            elsif (tx_bit_count_en = '1' AND tx_clk_en = '1') then
106
                if (tx_bit_count = "111") then
107
                    tx_bit_count <= (others => '0');
108
                else
109
                    tx_bit_count <= tx_bit_count + 1;
110
                end if;
111
            end if;
112
        end if;
113
    end process;
114
 
115
    -- -------------------------------------------------------------------------
116
    -- UART TRANSMITTER PARITY GENERATOR
117
    -- -------------------------------------------------------------------------
118
 
119
    uart_tx_parity_g : if (PARITY_BIT /= "none") generate
120
        uart_tx_parity_gen_i: entity work.UART_PARITY
121
        generic map (
122
            DATA_WIDTH  => 8,
123
            PARITY_TYPE => PARITY_BIT
124
        )
125
        port map (
126
            DATA_IN     => tx_data,
127
            PARITY_OUT  => tx_parity_bit
128
        );
129
    end generate;
130
 
131
    uart_tx_noparity_g : if (PARITY_BIT = "none") generate
132
        tx_parity_bit <= 'Z';
133
    end generate;
134
 
135
    -- -------------------------------------------------------------------------
136
    -- UART TRANSMITTER OUTPUT DATA REGISTER
137
    -- -------------------------------------------------------------------------
138
 
139
    uart_tx_output_data_reg : process (CLK)
140
    begin
141
        if (rising_edge(CLK)) then
142
            if (RST = '1') then
143
                UART_TXD <= '1';
144
            else
145
                case tx_data_out_sel is
146
                    when "01" => -- START BIT
147
                        UART_TXD <= '0';
148
                    when "10" => -- DATA BITS
149
                        UART_TXD <= tx_data(to_integer(tx_bit_count));
150
                    when "11" => -- PARITY BIT
151
                        UART_TXD <= tx_parity_bit;
152
                    when others => -- STOP BIT OR IDLE
153
                        UART_TXD <= '1';
154
                end case;
155
            end if;
156
        end if;
157
    end process;
158
 
159
    -- -------------------------------------------------------------------------
160
    -- UART TRANSMITTER FSM
161
    -- -------------------------------------------------------------------------
162
 
163
    -- PRESENT STATE REGISTER
164
    process (CLK)
165
    begin
166
        if (rising_edge(CLK)) then
167
            if (RST = '1') then
168
                tx_pstate <= idle;
169
            else
170
                tx_pstate <= tx_nstate;
171
            end if;
172
        end if;
173
    end process;
174
 
175
    -- NEXT STATE AND OUTPUTS LOGIC
176
    process (tx_pstate, DATA_SEND, tx_clk_en, tx_bit_count)
177
    begin
178
 
179
        case tx_pstate is
180
 
181
            when idle =>
182
                tx_busy <= '0';
183
                tx_data_out_sel <= "00";
184
                tx_bit_count_en <= '0';
185
                tx_clk_divider_en <= '0';
186
 
187
                if (DATA_SEND = '1') then
188
                    tx_nstate <= txsync;
189
                else
190
                    tx_nstate <= idle;
191
                end if;
192
 
193
            when txsync =>
194
                tx_busy <= '1';
195
                tx_data_out_sel <= "00";
196
                tx_bit_count_en <= '0';
197
                tx_clk_divider_en <= '1';
198
 
199
                if (tx_clk_en = '1') then
200
                    tx_nstate <= startbit;
201
                else
202
                    tx_nstate <= txsync;
203
                end if;
204
 
205
            when startbit =>
206
                tx_busy <= '1';
207
                tx_data_out_sel <= "01";
208
                tx_bit_count_en <= '0';
209
                tx_clk_divider_en <= '1';
210
 
211
                if (tx_clk_en = '1') then
212
                    tx_nstate <= databits;
213
                else
214
                    tx_nstate <= startbit;
215
                end if;
216
 
217
            when databits =>
218
                tx_busy <= '1';
219
                tx_data_out_sel <= "10";
220
                tx_bit_count_en <= '1';
221
                tx_clk_divider_en <= '1';
222
 
223
                if ((tx_clk_en = '1') AND (tx_bit_count = "111")) then
224
                    if (PARITY_BIT = "none") then
225
                        tx_nstate <= stopbit;
226
                    else
227
                        tx_nstate <= paritybit;
228
                    end if ;
229
                else
230
                    tx_nstate <= databits;
231
                end if;
232
 
233
            when paritybit =>
234
                tx_busy <= '1';
235
                tx_data_out_sel <= "11";
236
                tx_bit_count_en <= '0';
237
                tx_clk_divider_en <= '1';
238
 
239
                if (tx_clk_en = '1') then
240
                    tx_nstate <= stopbit;
241
                else
242
                    tx_nstate <= paritybit;
243
                end if;
244
 
245
            when stopbit =>
246
                tx_busy <= '0';
247
                tx_data_out_sel <= "00";
248
                tx_bit_count_en <= '0';
249
                tx_clk_divider_en <= '1';
250
 
251
                if (DATA_SEND = '1') then
252
                    tx_nstate <= txsync;
253
                elsif (tx_clk_en = '1') then
254
                    tx_nstate <= idle;
255
                else
256
                    tx_nstate <= stopbit;
257
                end if;
258
 
259
            when others =>
260
                tx_busy <= '1';
261
                tx_data_out_sel <= "00";
262
                tx_bit_count_en <= '0';
263
                tx_clk_divider_en <= '0';
264
                tx_nstate <= idle;
265
 
266
        end case;
267
    end process;
268
 
269
end FULL;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.