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

Subversion Repositories signed_unsigned_multiplier_and_divider

[/] [signed_unsigned_multiplier_and_divider/] [trunk/] [uart-for-fpga-master/] [source/] [comp/] [uart_tx.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 zpekic
--------------------------------------------------------------------------------
2
-- PROJECT: SIMPLE UART FOR FPGA
3
--------------------------------------------------------------------------------
4
-- MODULE:  UART TRANSMITTER
5
-- AUTHORS: Jakub Cabal <jakubcabal@gmail.com>
6
-- LICENSE: The MIT License (MIT), please read LICENSE file
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" -- type of parity: "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; -- serial transmit data
24
        -- USER DATA INPUT INTERFACE
25
        DATA_IN     : in  std_logic_vector(7 downto 0); -- input data
26
        DATA_SEND   : in  std_logic; -- when DATA_SEND = 1, input data are valid and will be transmit
27
        BUSY        : out std_logic  -- when BUSY = 1, transmitter is busy and 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_p : 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
                    else
63
                        tx_ticks <= tx_ticks + 1;
64
                    end if;
65
                else
66
                    tx_ticks <= tx_ticks;
67
                end if;
68
            else
69
                tx_ticks <= (others => '0');
70
            end if;
71
        end if;
72
    end process;
73
 
74
    uart_tx_clk_en_p : process (CLK)
75
    begin
76
        if (rising_edge(CLK)) then
77
            if (RST = '1') then
78
                tx_clk_en <= '0';
79
            elsif (uart_clk_en = '1' AND tx_ticks = "0001") then
80
                tx_clk_en <= '1';
81
            else
82
                tx_clk_en <= '0';
83
            end if;
84
        end if;
85
    end process;
86
 
87
    -- -------------------------------------------------------------------------
88
    -- UART TRANSMITTER INPUT DATA REGISTER
89
    -- -------------------------------------------------------------------------
90
 
91
    uart_tx_input_data_reg_p : process (CLK)
92
    begin
93
        if (rising_edge(CLK)) then
94
            if (RST = '1') then
95
                tx_data <= (others => '0');
96
            elsif (DATA_SEND = '1' AND tx_busy = '0') then
97
                tx_data <= DATA_IN;
98
            end if;
99
        end if;
100
    end process;
101
 
102
    -- -------------------------------------------------------------------------
103
    -- UART TRANSMITTER BIT COUNTER
104
    -- -------------------------------------------------------------------------
105
 
106
    uart_tx_bit_counter_p : process (CLK)
107
    begin
108
        if (rising_edge(CLK)) then
109
            if (RST = '1') then
110
                tx_bit_count <= (others => '0');
111
            elsif (tx_bit_count_en = '1' AND tx_clk_en = '1') then
112
                if (tx_bit_count = "111") then
113
                    tx_bit_count <= (others => '0');
114
                else
115
                    tx_bit_count <= tx_bit_count + 1;
116
                end if;
117
            end if;
118
        end if;
119
    end process;
120
 
121
    -- -------------------------------------------------------------------------
122
    -- UART TRANSMITTER PARITY GENERATOR
123
    -- -------------------------------------------------------------------------
124
 
125
    uart_tx_parity_g : if (PARITY_BIT /= "none") generate
126
        uart_tx_parity_gen_i: entity work.UART_PARITY
127
        generic map (
128
            DATA_WIDTH  => 8,
129
            PARITY_TYPE => PARITY_BIT
130
        )
131
        port map (
132
            DATA_IN     => tx_data,
133
            PARITY_OUT  => tx_parity_bit
134
        );
135
    end generate;
136
 
137
    uart_tx_noparity_g : if (PARITY_BIT = "none") generate
138
        tx_parity_bit <= 'Z';
139
    end generate;
140
 
141
    -- -------------------------------------------------------------------------
142
    -- UART TRANSMITTER OUTPUT DATA REGISTER
143
    -- -------------------------------------------------------------------------
144
 
145
    uart_tx_output_data_reg_p : process (CLK)
146
    begin
147
        if (rising_edge(CLK)) then
148
            if (RST = '1') then
149
                UART_TXD <= '1';
150
            else
151
                case tx_data_out_sel is
152
                    when "01" => -- START BIT
153
                        UART_TXD <= '0';
154
                    when "10" => -- DATA BITS
155
                        UART_TXD <= tx_data(to_integer(tx_bit_count));
156
                    when "11" => -- PARITY BIT
157
                        UART_TXD <= tx_parity_bit;
158
                    when others => -- STOP BIT OR IDLE
159
                        UART_TXD <= '1';
160
                end case;
161
            end if;
162
        end if;
163
    end process;
164
 
165
    -- -------------------------------------------------------------------------
166
    -- UART TRANSMITTER FSM
167
    -- -------------------------------------------------------------------------
168
 
169
    -- PRESENT STATE REGISTER
170
    process (CLK)
171
    begin
172
        if (rising_edge(CLK)) then
173
            if (RST = '1') then
174
                tx_pstate <= idle;
175
            else
176
                tx_pstate <= tx_nstate;
177
            end if;
178
        end if;
179
    end process;
180
 
181
    -- NEXT STATE AND OUTPUTS LOGIC
182
    process (tx_pstate, DATA_SEND, tx_clk_en, tx_bit_count)
183
    begin
184
 
185
        case tx_pstate is
186
 
187
            when idle =>
188
                tx_busy <= '0';
189
                tx_data_out_sel <= "00";
190
                tx_bit_count_en <= '0';
191
                tx_clk_divider_en <= '0';
192
 
193
                if (DATA_SEND = '1') then
194
                    tx_nstate <= txsync;
195
                else
196
                    tx_nstate <= idle;
197
                end if;
198
 
199
            when txsync =>
200
                tx_busy <= '1';
201
                tx_data_out_sel <= "00";
202
                tx_bit_count_en <= '0';
203
                tx_clk_divider_en <= '1';
204
 
205
                if (tx_clk_en = '1') then
206
                    tx_nstate <= startbit;
207
                else
208
                    tx_nstate <= txsync;
209
                end if;
210
 
211
            when startbit =>
212
                tx_busy <= '1';
213
                tx_data_out_sel <= "01";
214
                tx_bit_count_en <= '0';
215
                tx_clk_divider_en <= '1';
216
 
217
                if (tx_clk_en = '1') then
218
                    tx_nstate <= databits;
219
                else
220
                    tx_nstate <= startbit;
221
                end if;
222
 
223
            when databits =>
224
                tx_busy <= '1';
225
                tx_data_out_sel <= "10";
226
                tx_bit_count_en <= '1';
227
                tx_clk_divider_en <= '1';
228
 
229
                if ((tx_clk_en = '1') AND (tx_bit_count = "111")) then
230
                    if (PARITY_BIT = "none") then
231
                        tx_nstate <= stopbit;
232
                    else
233
                        tx_nstate <= paritybit;
234
                    end if ;
235
                else
236
                    tx_nstate <= databits;
237
                end if;
238
 
239
            when paritybit =>
240
                tx_busy <= '1';
241
                tx_data_out_sel <= "11";
242
                tx_bit_count_en <= '0';
243
                tx_clk_divider_en <= '1';
244
 
245
                if (tx_clk_en = '1') then
246
                    tx_nstate <= stopbit;
247
                else
248
                    tx_nstate <= paritybit;
249
                end if;
250
 
251
            when stopbit =>
252
                tx_busy <= '0';
253
                tx_data_out_sel <= "00";
254
                tx_bit_count_en <= '0';
255
                tx_clk_divider_en <= '1';
256
 
257
                if (DATA_SEND = '1') then
258
                    tx_nstate <= txsync;
259
                elsif (tx_clk_en = '1') then
260
                    tx_nstate <= idle;
261
                else
262
                    tx_nstate <= stopbit;
263
                end if;
264
 
265
            when others =>
266
                tx_busy <= '1';
267
                tx_data_out_sel <= "00";
268
                tx_bit_count_en <= '0';
269
                tx_clk_divider_en <= '0';
270
                tx_nstate <= idle;
271
 
272
        end case;
273
    end process;
274
 
275
end FULL;

powered by: WebSVN 2.1.0

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