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 16

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 11 leonardoar
signal byte_to_receive : std_logic_vector((nBits-1) downto 0);
30
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
        process (rst, clk, reg_addr,WE)
65
        begin
66
                if rising_edge(clk) then
67
                        if (WE = '0') and (start = '1') then
68
                                case reg_addr is
69
                                        when "00" =>
70
                                                DAT_O <= config_clk;
71
                                        when "01" =>
72
                                                DAT_O <= config_baud;
73
                                        when "10" =>
74
                                                -- Byte that will be transmitted
75 11 leonardoar
                                                DAT_O <= "000000000000000000000000" & byte_to_transmitt;
76 10 leonardoar
                                        when "11" =>
77
                                                -- Byte that will be received
78 11 leonardoar
                                                DAT_O <= "000000000000000000000000" & byte_to_receive;
79 10 leonardoar
                                        when others =>
80
                                                null;
81
                                end case;
82
                        end if;
83
                end if;
84
        end process;
85
 
86
        -- Process that populate the uart control registers
87 16 leonardoar
        process (rst, clk, reg_addr,WE,start)
88 9 leonardoar
        begin
89
                if rst = '1' then
90
                        config_clk <= (others => '0');
91
                        config_baud <= (others => '0');
92 11 leonardoar
                        byte_to_transmitt <= (others => '0');
93 9 leonardoar
                elsif rising_edge(clk) then
94 10 leonardoar
                        if (WE = '1') and (start = '1') then
95 9 leonardoar
                                case reg_addr is
96
                                        when "00" =>
97
                                                config_clk <= DAT_I;
98
                                        when "01" =>
99
                                                config_baud <= DAT_I;
100
                                        when "10" =>
101 10 leonardoar
                                                -- Byte that will be transmitted
102
                                                byte_to_transmitt <= DAT_I((nBits-1) downto 0);
103 9 leonardoar
                                        when others =>
104
                                                null;
105
                                end case;
106
                        end if;
107
                end if;
108
        end process;
109
 
110
        -- Process to handle the next state logic
111
        process (rst, clk, reg_addr, WE)
112
        variable baud_configured : std_logic;
113 10 leonardoar
        variable clk_configured : std_logic;
114
        variable div_result_baud_wait : std_logic_vector ((nBitsLarge-1) downto 0);
115 9 leonardoar
        begin
116
                if rst = '1' then
117
                        controlStates <= idle;
118 11 leonardoar
                        baud_configured := '0';
119
                        clk_configured := '0';
120
                        div_result_baud_wait := (others => '0');
121 13 leonardoar
                        done <= '0';
122
                        sigDivRst <= '1';
123 14 leonardoar
                        rst_comm_blocks <= '1';
124
                        tx_start <= '0';
125 9 leonardoar
                elsif rising_edge(clk) then
126
                        case controlStates is
127
                                when idle =>
128 10 leonardoar
                                        done <= '0';
129 9 leonardoar
                                        -- Go to config state
130
                                        if (reg_addr = "00") and (WE = '1') then
131
                                                controlStates <= config_state_clk;
132 11 leonardoar
                                                clk_configured := '1';
133 9 leonardoar
                                        elsif (reg_addr = "01") and (WE = '1') then
134
                                                controlStates <= config_state_baud;
135 11 leonardoar
                                                baud_configured := '1';
136 9 leonardoar
                                        end if;
137
 
138
                                when config_state_clk =>
139
                                        sigDivRst <= '1';
140 10 leonardoar
                                        sigDivNumerator <= config_clk;
141 9 leonardoar
                                        if baud_configured = '0' then
142
                                                -- Baud not configured yet so wait for it...
143 10 leonardoar
                                                controlStates <= idle;
144
                                                done <= '1';
145 9 leonardoar
                                        else
146
                                                -- If already configured wait for division completion...
147
                                                controlStates <= start_division;
148
                                        end if;
149
 
150
                                when config_state_baud =>
151
                                        sigDivRst <= '1';
152 10 leonardoar
                                        sigDivDividend <= config_baud;
153 9 leonardoar
                                        if clk_configured = '0' then
154
                                                -- Clock not configured yet so wait for it...
155 10 leonardoar
                                                controlStates <= idle;
156
                                                done <= '1';
157 9 leonardoar
                                        else
158
                                                -- If already configured wait for division completion...
159
                                                controlStates <= start_division;
160
                                        end if;
161
 
162
                                when start_division =>
163
                                        sigDivRst <= '0';
164
                                        controlStates <= wait_division;
165
 
166
                                when wait_division =>
167
                                        if sigDivDone = '0' then
168
                                                controlStates <= wait_division;
169
                                        else
170 10 leonardoar
                                                -- Division done, get the result to put on the wait_cycles signal of the baud generator
171
                                                div_result_baud_wait := sigDivQuotient;
172
                                                controlStates <= config_state_baud_generator;
173
                                        end if;
174
 
175
                                when config_state_baud_generator =>
176
                                        -- Configure the wait_cycle for the desired baud rate...
177
                                        baud_wait <= div_result_baud_wait;
178
                                        controlStates <= rx_tx_state;
179
                                        done <= '1';
180
 
181
                                -- Control the serial_receiver or serial_transmitter block
182
                                when rx_tx_state =>
183 13 leonardoar
                                        rst_comm_blocks <= '0';
184 14 leonardoar
                                        tx_start <= '0';
185 10 leonardoar
                                        controlStates <= rx_tx_state;
186
                                        if (WE = '1') and (start = '1') then
187
                                                if reg_addr = "10" then
188
                                                        controlStates <= tx_state_wait;
189
                                                        done <= '0';
190
                                                end if;
191
                                        end if;
192
 
193
                                        if (WE = '0') and (start = '1') then
194
                                                if reg_addr = "11" then
195
                                                        controlStates <= rx_state_wait;
196
                                                        done <= '0';
197
                                                end if;
198
                                        end if;
199
 
200
 
201
                                -- Send data and wait to transmit
202
                                when tx_state_wait =>
203 14 leonardoar
                                        tx_start <= '1';
204 10 leonardoar
                                        data_byte_tx <= byte_to_transmitt;
205
                                        if tx_data_sent = '0' then
206
                                                controlStates <= tx_state_wait;
207
                                        else
208
                                                controlStates <= rx_tx_state;
209
                                                done <= '1';
210
                                        end if;
211
 
212
                                -- Receive data and wait to receive
213
                                when rx_state_wait =>
214
                                        if rx_data_ready = '1' then
215
                                                byte_to_receive <= data_byte_rx;
216
                                                done <= '1';
217
                                                controlStates <= rx_tx_state;
218
                                        else
219
                                                controlStates <= rx_state_wait;
220
                                        end if;
221 9 leonardoar
                        end case;
222
                end if;
223
        end process;
224
 
225
end Behavioral;
226
 

powered by: WebSVN 2.1.0

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