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 19

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 13 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 10 leonardoar
                          start : in std_logic;                                                                                                         -- Start (Strobe)
14
                          done : out std_logic;                                                                                                         -- Done (ACK)
15 13 leonardoar
           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 10 leonardoar
                          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 13 leonardoar
           tx_data_sent : in  std_logic;                                                                                        -- Signal comming from serial_transmitter
21 14 leonardoar
                          tx_start : out std_logic;                                                                                             -- Signal to start sending serial data...
22 13 leonardoar
                          rst_comm_blocks : out std_logic;                                                                              -- Reset Communication blocks
23
           rx_data_ready : in  std_logic);                                                                              -- Signal comming from serial_receiver
24 9 leonardoar
end uart_control;
25
 
26
architecture Behavioral of uart_control is
27
signal config_clk : std_logic_vector((nBitsLarge-1) downto 0);
28
signal config_baud : std_logic_vector((nBitsLarge-1) downto 0);
29 19 leonardoar
--signal byte_to_receive : std_logic_vector((nBits-1) downto 0);
30 11 leonardoar
signal byte_to_transmitt : std_logic_vector((nBits-1) downto 0);
31 9 leonardoar
signal controlStates : uartControl;
32
 
33
signal sigDivRst : std_logic;
34
signal sigDivDone : std_logic;
35
signal sigDivQuotient : std_logic_vector((nBitsLarge-1) downto 0);
36 16 leonardoar
--signal sigDivReminder : std_logic_vector((nBitsLarge-1) downto 0);
37 9 leonardoar
signal sigDivNumerator : std_logic_vector((nBitsLarge-1) downto 0);
38
signal sigDivDividend : std_logic_vector((nBitsLarge-1) downto 0);
39
 
40
-- Divisor component
41
component divisor is
42
    Port ( rst : in  STD_LOGIC;
43
           clk : in  STD_LOGIC;
44
           quotient : out  STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
45
                          reminder : out  STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
46
           numerator : in  STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
47
           divident : in  STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
48
           done : out  STD_LOGIC);
49
end component;
50
 
51
begin
52
        -- Instantiate block for calculate division
53
        uDiv : divisor port map (
54
                rst => sigDivRst,
55
                clk => clk,
56
                quotient => sigDivQuotient,
57 16 leonardoar
                reminder => open,       -- Indicates that this port will not be connected to anything
58 9 leonardoar
                numerator => sigDivNumerator,
59
                divident => sigDivDividend,
60
                done => sigDivDone
61
        );
62
 
63 10 leonardoar
        -- Process that read uart control registers
64 19 leonardoar
        process (rst, reg_addr, WE, start, byte_to_transmitt, data_byte_rx, rx_data_ready, config_clk, config_baud)
65 10 leonardoar
        begin
66 19 leonardoar
                if rst = '1' then
67
                        DAT_O <= (others => 'Z');
68
                else
69 10 leonardoar
                        if (WE = '0') and (start = '1') then
70
                                case reg_addr is
71
                                        when "00" =>
72
                                                DAT_O <= config_clk;
73
                                        when "01" =>
74
                                                DAT_O <= config_baud;
75
                                        when "10" =>
76
                                                -- Byte that will be transmitted
77 11 leonardoar
                                                DAT_O <= "000000000000000000000000" & byte_to_transmitt;
78 10 leonardoar
                                        when "11" =>
79 19 leonardoar
                                                -- Byte that will be received
80
                                                if rx_data_ready = '1' then
81
                                                        DAT_O <= "000000000000000000000000" & data_byte_rx;
82
                                                        --DAT_O <= "000000000000000000000000" & byte_to_receive;
83
                                                else
84
                                                        DAT_O <= (others => 'Z');
85
                                                end if;
86 10 leonardoar
                                        when others =>
87 19 leonardoar
                                                DAT_O <= (others => 'Z');
88
                                end case;
89
                        else
90
                                DAT_O <= (others => 'Z');
91
                        end if;
92
                end if;
93 10 leonardoar
        end process;
94
 
95
        -- Process that populate the uart control registers
96 16 leonardoar
        process (rst, clk, reg_addr,WE,start)
97 9 leonardoar
        begin
98
                if rst = '1' then
99
                        config_clk <= (others => '0');
100
                        config_baud <= (others => '0');
101 11 leonardoar
                        byte_to_transmitt <= (others => '0');
102 9 leonardoar
                elsif rising_edge(clk) then
103 10 leonardoar
                        if (WE = '1') and (start = '1') then
104 9 leonardoar
                                case reg_addr is
105
                                        when "00" =>
106
                                                config_clk <= DAT_I;
107
                                        when "01" =>
108
                                                config_baud <= DAT_I;
109
                                        when "10" =>
110 10 leonardoar
                                                -- Byte that will be transmitted
111
                                                byte_to_transmitt <= DAT_I((nBits-1) downto 0);
112 9 leonardoar
                                        when others =>
113
                                                null;
114
                                end case;
115
                        end if;
116
                end if;
117
        end process;
118
 
119
        -- Process to handle the next state logic
120 19 leonardoar
        process (rst, clk, reg_addr, WE, start)
121 9 leonardoar
        variable baud_configured : std_logic;
122 10 leonardoar
        variable clk_configured : std_logic;
123
        variable div_result_baud_wait : std_logic_vector ((nBitsLarge-1) downto 0);
124 9 leonardoar
        begin
125
                if rst = '1' then
126
                        controlStates <= idle;
127 11 leonardoar
                        baud_configured := '0';
128
                        clk_configured := '0';
129
                        div_result_baud_wait := (others => '0');
130 13 leonardoar
                        done <= '0';
131
                        sigDivRst <= '1';
132 14 leonardoar
                        rst_comm_blocks <= '1';
133
                        tx_start <= '0';
134 19 leonardoar
                        --byte_to_receive <= (others => 'Z');
135 9 leonardoar
                elsif rising_edge(clk) then
136
                        case controlStates is
137
                                when idle =>
138 10 leonardoar
                                        done <= '0';
139 9 leonardoar
                                        -- Go to config state
140
                                        if (reg_addr = "00") and (WE = '1') then
141
                                                controlStates <= config_state_clk;
142 11 leonardoar
                                                clk_configured := '1';
143 9 leonardoar
                                        elsif (reg_addr = "01") and (WE = '1') then
144
                                                controlStates <= config_state_baud;
145 11 leonardoar
                                                baud_configured := '1';
146 9 leonardoar
                                        end if;
147
 
148
                                when config_state_clk =>
149
                                        sigDivRst <= '1';
150 10 leonardoar
                                        sigDivNumerator <= config_clk;
151 9 leonardoar
                                        if baud_configured = '0' then
152
                                                -- Baud not configured yet so wait for it...
153 10 leonardoar
                                                controlStates <= idle;
154
                                                done <= '1';
155 9 leonardoar
                                        else
156
                                                -- If already configured wait for division completion...
157
                                                controlStates <= start_division;
158
                                        end if;
159
 
160
                                when config_state_baud =>
161
                                        sigDivRst <= '1';
162 10 leonardoar
                                        sigDivDividend <= config_baud;
163 9 leonardoar
                                        if clk_configured = '0' then
164
                                                -- Clock not configured yet so wait for it...
165 10 leonardoar
                                                controlStates <= idle;
166
                                                done <= '1';
167 9 leonardoar
                                        else
168
                                                -- If already configured wait for division completion...
169
                                                controlStates <= start_division;
170
                                        end if;
171
 
172
                                when start_division =>
173
                                        sigDivRst <= '0';
174
                                        controlStates <= wait_division;
175
 
176
                                when wait_division =>
177
                                        if sigDivDone = '0' then
178
                                                controlStates <= wait_division;
179
                                        else
180 10 leonardoar
                                                -- Division done, get the result to put on the wait_cycles signal of the baud generator
181
                                                div_result_baud_wait := sigDivQuotient;
182
                                                controlStates <= config_state_baud_generator;
183
                                        end if;
184
 
185
                                when config_state_baud_generator =>
186
                                        -- Configure the wait_cycle for the desired baud rate...
187
                                        baud_wait <= div_result_baud_wait;
188
                                        controlStates <= rx_tx_state;
189
                                        done <= '1';
190
 
191
                                -- Control the serial_receiver or serial_transmitter block
192
                                when rx_tx_state =>
193 13 leonardoar
                                        rst_comm_blocks <= '0';
194 14 leonardoar
                                        tx_start <= '0';
195 10 leonardoar
                                        controlStates <= rx_tx_state;
196
                                        if (WE = '1') and (start = '1') then
197
                                                if reg_addr = "10" then
198
                                                        controlStates <= tx_state_wait;
199
                                                        done <= '0';
200
                                                end if;
201
                                        end if;
202
 
203
                                        if (WE = '0') and (start = '1') then
204
                                                if reg_addr = "11" then
205 19 leonardoar
                                                        controlStates <= rx_state_wait;
206 10 leonardoar
                                                end if;
207
                                        end if;
208
 
209
 
210
                                -- Send data and wait to transmit
211
                                when tx_state_wait =>
212 14 leonardoar
                                        tx_start <= '1';
213 10 leonardoar
                                        data_byte_tx <= byte_to_transmitt;
214
                                        if tx_data_sent = '0' then
215
                                                controlStates <= tx_state_wait;
216
                                        else
217
                                                controlStates <= rx_tx_state;
218
                                                done <= '1';
219
                                        end if;
220
 
221
                                -- Receive data and wait to receive
222
                                when rx_state_wait =>
223 19 leonardoar
                                        if rx_data_ready = '1' then
224
                                                -- Put an ack on the next cycle
225
                                                controlStates <= rx_state_ack;
226 10 leonardoar
                                        else
227 19 leonardoar
                                                controlStates <= rx_state_wait;
228
                                                done <= '0';
229
                                        end if;
230
 
231
                                -- Ack that we got a value
232
                                when rx_state_ack =>
233
                                        done <= '1';
234
                                        controlStates <= rx_tx_state;
235 9 leonardoar
                        end case;
236
                end if;
237
        end process;
238
 
239
end Behavioral;
240
 

powered by: WebSVN 2.1.0

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