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

Subversion Repositories uart_block

[/] [uart_block/] [trunk/] [hdl/] [iseProject/] [uart_control.vhd] - Blame information for rev 10

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 leonardoar
--! uart control unit
2
library IEEE;
3
use IEEE.STD_LOGIC_1164.ALL;
4
 
5
--! Use CPU Definitions package
6
use work.pkgDefinitions.all;
7
 
8
entity uart_control is
9 10 leonardoar
    Port ( rst : in  STD_LOGIC;                                                                                                         -- Global reset
10
           clk : in  STD_LOGIC;                                                                                                         -- Global clock
11
                          WE    : in STD_LOGIC;                                                                                                         -- Write enable
12
           reg_addr : in  STD_LOGIC_VECTOR (1 downto 0);                                         -- Register address
13
                          start : in std_logic;                                                                                                         -- Start (Strobe)
14
                          done : out std_logic;                                                                                                         -- Done (ACK)
15
           DAT_I : in  STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);               -- Data Input (Wishbone)
16
           DAT_O : out  STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);              -- Data output (Wishbone)
17
                          baud_wait : out STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);    -- Signal to control the baud rate frequency
18
                          data_byte_tx : out std_logic_vector((nBits-1) downto 0);               -- 1 Byte to be send to serial_transmitter
19
                          data_byte_rx : in std_logic_vector((nBits-1) downto 0);        -- 1 Byte to be received by serial_receiver
20
           tx_data_sent : in  STD_LOGIC;                                                                                        -- Signal comming from serial_transmitter
21
           rx_data_ready : in  STD_LOGIC);                                                                              -- Signal comming from serial_receiver
22 9 leonardoar
end uart_control;
23
 
24
architecture Behavioral of uart_control is
25
signal config_clk : std_logic_vector((nBitsLarge-1) downto 0);
26
signal config_baud : std_logic_vector((nBitsLarge-1) downto 0);
27 10 leonardoar
signal byte_to_receive : std_logic_vector((nBitsLarge-1) downto 0);
28
signal byte_to_transmitt : std_logic_vector((nBitsLarge-1) downto 0);
29 9 leonardoar
signal controlStates : uartControl;
30
 
31
signal sigDivRst : std_logic;
32
signal sigDivDone : std_logic;
33
signal sigDivQuotient : std_logic_vector((nBitsLarge-1) downto 0);
34
signal sigDivReminder : std_logic_vector((nBitsLarge-1) downto 0);
35
signal sigDivNumerator : std_logic_vector((nBitsLarge-1) downto 0);
36
signal sigDivDividend : std_logic_vector((nBitsLarge-1) downto 0);
37
 
38
-- Divisor component
39
component divisor is
40
    Port ( rst : in  STD_LOGIC;
41
           clk : in  STD_LOGIC;
42
           quotient : out  STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
43
                          reminder : out  STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
44
           numerator : in  STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
45
           divident : in  STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
46
           done : out  STD_LOGIC);
47
end component;
48
 
49
begin
50
        -- Instantiate block for calculate division
51
        uDiv : divisor port map (
52
                rst => sigDivRst,
53
                clk => clk,
54
                quotient => sigDivQuotient,
55
                reminder => sigDivReminder,
56
                numerator => sigDivNumerator,
57
                divident => sigDivDividend,
58
                done => sigDivDone
59
        );
60
 
61 10 leonardoar
        -- Process that read uart control registers
62
        process (rst, clk, reg_addr,WE)
63
        begin
64
                if rising_edge(clk) then
65
                        if (WE = '0') and (start = '1') then
66
                                case reg_addr is
67
                                        when "00" =>
68
                                                DAT_O <= config_clk;
69
                                        when "01" =>
70
                                                DAT_O <= config_baud;
71
                                        when "10" =>
72
                                                -- Byte that will be transmitted
73
                                                DAT_O <= "0000000000000000000000000" & byte_to_transmitt;
74
                                        when "11" =>
75
                                                -- Byte that will be received
76
                                                DAT_O <= "0000000000000000000000000" & byte_to_receive;
77
                                        when others =>
78
                                                null;
79
                                end case;
80
                        end if;
81
                end if;
82
        end process;
83
 
84
        -- Process that populate the uart control registers
85 9 leonardoar
        process (rst, clk, reg_addr,WE)
86
        begin
87
                if rst = '1' then
88
                        config_clk <= (others => '0');
89
                        config_baud <= (others => '0');
90 10 leonardoar
                        byte_to_transmitt <= (others => '0');
91
                        byte_to_receive <= (others => '0');
92 9 leonardoar
                elsif rising_edge(clk) then
93 10 leonardoar
                        if (WE = '1') and (start = '1') then
94 9 leonardoar
                                case reg_addr is
95
                                        when "00" =>
96
                                                config_clk <= DAT_I;
97
                                        when "01" =>
98
                                                config_baud <= DAT_I;
99
                                        when "10" =>
100 10 leonardoar
                                                -- Byte that will be transmitted
101
                                                byte_to_transmitt <= DAT_I((nBits-1) downto 0);
102 9 leonardoar
                                        when others =>
103
                                                null;
104
                                end case;
105
                        end if;
106
                end if;
107
        end process;
108
 
109
        -- Process to handle the next state logic
110
        process (rst, clk, reg_addr, WE)
111
        variable baud_configured : std_logic;
112 10 leonardoar
        variable clk_configured : std_logic;
113
        variable div_result_baud_wait : std_logic_vector ((nBitsLarge-1) downto 0);
114 9 leonardoar
        begin
115
                if rst = '1' then
116
                        controlStates <= idle;
117
                        baud_configured <= '0';
118 10 leonardoar
                        clk_configured <= '0';
119
                        div_result_baud_wait <= (others => '0');
120
                        done <= '0';
121 9 leonardoar
                elsif rising_edge(clk) then
122
                        case controlStates is
123
                                when idle =>
124 10 leonardoar
                                        done <= '0';
125 9 leonardoar
                                        -- Go to config state
126
                                        if (reg_addr = "00") and (WE = '1') then
127
                                                controlStates <= config_state_clk;
128
                                                clk_configured <= '1';
129
                                        elsif (reg_addr = "01") and (WE = '1') then
130
                                                controlStates <= config_state_baud;
131
                                                baud_configured <= '1';
132
                                        end if;
133
 
134
                                when config_state_clk =>
135
                                        sigDivRst <= '1';
136 10 leonardoar
                                        sigDivNumerator <= config_clk;
137 9 leonardoar
                                        if baud_configured = '0' then
138
                                                -- Baud not configured yet so wait for it...
139 10 leonardoar
                                                controlStates <= idle;
140
                                                done <= '1';
141 9 leonardoar
                                        else
142
                                                -- If already configured wait for division completion...
143
                                                controlStates <= start_division;
144
                                        end if;
145
 
146
                                when config_state_baud =>
147
                                        sigDivRst <= '1';
148 10 leonardoar
                                        sigDivDividend <= config_baud;
149 9 leonardoar
                                        if clk_configured = '0' then
150
                                                -- Clock not configured yet so wait for it...
151 10 leonardoar
                                                controlStates <= idle;
152
                                                done <= '1';
153 9 leonardoar
                                        else
154
                                                -- If already configured wait for division completion...
155
                                                controlStates <= start_division;
156
                                        end if;
157
 
158
                                when start_division =>
159
                                        sigDivRst <= '0';
160
                                        controlStates <= wait_division;
161
 
162
                                when wait_division =>
163
                                        if sigDivDone = '0' then
164
                                                controlStates <= wait_division;
165
                                        else
166 10 leonardoar
                                                -- Division done, get the result to put on the wait_cycles signal of the baud generator
167
                                                div_result_baud_wait := sigDivQuotient;
168
                                                controlStates <= config_state_baud_generator;
169
                                        end if;
170
 
171
                                when config_state_baud_generator =>
172
                                        -- Configure the wait_cycle for the desired baud rate...
173
                                        baud_wait <= div_result_baud_wait;
174
                                        controlStates <= rx_tx_state;
175
                                        done <= '1';
176
 
177
                                -- Control the serial_receiver or serial_transmitter block
178
                                when rx_tx_state =>
179
                                        controlStates <= rx_tx_state;
180
                                        if (WE = '1') and (start = '1') then
181
                                                if reg_addr = "10" then
182
                                                        controlStates <= tx_state_wait;
183
                                                        done <= '0';
184
                                                end if;
185
                                        end if;
186
 
187
                                        if (WE = '0') and (start = '1') then
188
                                                if reg_addr = "11" then
189
                                                        controlStates <= rx_state_wait;
190
                                                        done <= '0';
191
                                                end if;
192
                                        end if;
193
 
194
 
195
                                -- Send data and wait to transmit
196
                                when tx_state_wait =>
197
                                        data_byte_tx <= byte_to_transmitt;
198
                                        if tx_data_sent = '0' then
199
                                                controlStates <= tx_state_wait;
200
                                        else
201
                                                controlStates <= rx_tx_state;
202
                                                done <= '1';
203
                                        end if;
204
 
205
                                -- Receive data and wait to receive
206
                                when rx_state_wait =>
207
                                        if rx_data_ready = '1' then
208
                                                byte_to_receive <= data_byte_rx;
209
                                                done <= '1';
210
                                                controlStates <= rx_tx_state;
211
                                        else
212
                                                controlStates <= rx_state_wait;
213
                                        end if;
214 9 leonardoar
                        end case;
215
                end if;
216
        end process;
217
 
218
end Behavioral;
219
 

powered by: WebSVN 2.1.0

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