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

Subversion Repositories wb4pb

[/] [wb4pb/] [trunk/] [rtl/] [wbs_uart.vhd] - Blame information for rev 22

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

Line No. Rev Author Line
1 12 ste.fis
--------------------------------------------------------------------------------
2
-- This sourcecode is released under BSD license.
3
-- Please see http://www.opensource.org/licenses/bsd-license.php for details!
4
--------------------------------------------------------------------------------
5
--
6
-- Copyright (c) 2010, Stefan Fischer <Ste.Fis@OpenCores.org>
7
-- All rights reserved.
8
--
9
-- Redistribution and use in source and binary forms, with or without 
10
-- modification, are permitted provided that the following conditions are met:
11
--
12
--  * Redistributions of source code must retain the above copyright notice, 
13
--    this list of conditions and the following disclaimer.
14
--  * Redistributions in binary form must reproduce the above copyright notice,
15
--    this list of conditions and the following disclaimer in the documentation
16
--    and/or other materials provided with the distribution. 
17
--  * Neither the name of the author nor the names of his contributors may be 
18
--    used to endorse or promote products derived from this software without 
19
--    specific prior written permission.
20
--
21
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
22
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
23
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
24
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
25
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
26
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
27
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
28
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
29
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
30
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31
-- POSSIBILITY OF SUCH DAMAGE.
32
--
33
--------------------------------------------------------------------------------
34
-- filename: wbs_uart.vhd
35
-- description: synthesizable wishbone slave uart sio module using Xilinx (R)
36
--              macros and adding some functionality like a configurable 
37
--              baud rate and buffer level checking 
38
-- todo4user: add other uart functionality as needed, i. e. interrupt logic or
39
--            modem control signals
40
-- version: 0.0.0
41
-- changelog: - 0.0.0, initial release
42
--            - ...
43
--------------------------------------------------------------------------------
44
 
45
 
46
library ieee;
47
use ieee.std_logic_1164.all;
48
use ieee.numeric_std.all;
49
 
50
 
51
entity wbs_uart is
52
  port
53
  (
54
    rst : in std_logic;
55
    clk : in std_logic;
56
 
57
    wbs_cyc_i : in std_logic;
58
    wbs_stb_i : in std_logic;
59
    wbs_we_i : in std_logic;
60
    wbs_adr_i : in std_logic_vector(7 downto 0);
61
    wbs_dat_m2s_i : in std_logic_vector(7 downto 0);
62
    wbs_dat_s2m_o : out std_logic_vector(7 downto 0);
63
    wbs_ack_o : out std_logic;
64
 
65
    uart_rx_si_i : in std_logic;
66
    uart_tx_so_o : out std_logic
67
  );
68
end wbs_uart;
69
 
70
 
71
architecture rtl of wbs_uart is
72
 
73
  signal wbs_dat_s2m : std_logic_vector(7 downto 0) := (others => '0');
74
  signal wbs_ack : std_logic := '0';
75
 
76
  signal uart_tx_so : std_logic := '0';
77
 
78
  signal wb_reg_we : std_logic := '0';
79
 
80
  constant ADDR_MSB : natural := 1;
81
  constant UART_RXTX_ADDR : std_logic_vector(7 downto 0) := x"00";
82
  constant UART_SR_ADDR : std_logic_vector(7 downto 0) := x"01";
83
  constant UART_SR_RX_F_FLAG : natural := 0;
84
  constant UART_SR_RX_HF_FLAG : natural := 1;
85
  constant UART_SR_RX_DP_FLAG : natural := 2;
86
  constant UART_SR_TX_F_FLAG : natural := 4;
87
  constant UART_SR_TX_HF_FLAG : natural := 5;
88
  constant UART_BAUD_LO_ADDR : std_logic_vector(7 downto 0) := x"02";
89
  constant UART_BAUD_HI_ADDR : std_logic_vector(7 downto 0) := x"03";
90
 
91
  signal baud_count : std_logic_vector(15 downto 0) := (others => '0');
92
  signal baud_limit : std_logic_vector(15 downto 0) := (others => '0');
93
 
94
  signal en_16_x_baud : std_logic := '0';
95
 
96
  component uart_rx is
97
    port
98
    (
99
      serial_in : in std_logic;
100
      data_out : out std_logic_vector(7 downto 0);
101
      read_buffer : in std_logic;
102
      reset_buffer : in std_logic;
103
      en_16_x_baud : in std_logic;
104
      buffer_data_present : out std_logic;
105
      buffer_full : out std_logic;
106
      buffer_half_full : out std_logic;
107
      clk : in std_logic
108
    );
109
  end component;
110
 
111
  signal rx_read_buffer : std_logic := '0';
112
  signal rx_buffer_full : std_logic := '0';
113
  signal rx_buffer_half_full : std_logic := '0';
114
  signal rx_buffer_data_present : std_logic := '0';
115
  signal rx_data_out : std_logic_vector(7 downto 0) := (others => '0');
116
 
117
  component uart_tx is
118
    port
119
    (
120
      data_in : in std_logic_vector(7 downto 0);
121
      write_buffer : in std_logic;
122
      reset_buffer : in std_logic;
123
      en_16_x_baud : in std_logic;
124
      serial_out : out std_logic;
125
      buffer_full : out std_logic;
126
      buffer_half_full : out std_logic;
127
      clk : in std_logic
128
    );
129
  end component;
130
 
131
  signal tx_write_buffer : std_logic := '0';
132
  signal tx_buffer_full : std_logic := '0';
133
  signal tx_buffer_half_full : std_logic := '0';
134
 
135
begin
136
 
137
  wbs_dat_s2m_o <= wbs_dat_s2m;
138
  wbs_ack_o <= wbs_ack;
139
 
140
  uart_tx_so_o <= uart_tx_so;
141
 
142
  -- internal register write enable signal
143
  wb_reg_we <= wbs_cyc_i and wbs_stb_i and wbs_we_i;
144
 
145
  process(clk)
146
  begin
147
    if clk'event and clk = '1' then
148
 
149
      -- baud rate configuration:
150
      -- baud_limit = round( system clock frequency / (16 * baud rate) ) - 1
151
      -- i. e. 9600 baud at 50 MHz system clock =>
152
      -- baud_limit = round( 50.0E6 / (16 * 9600) ) - 1 = 325 = 0x0145
153
 
154
      -- baud timer
155
      if baud_count = baud_limit then
156
        baud_count <= (others => '0');
157
        en_16_x_baud <= '1';
158
      else
159
        baud_count <= std_logic_vector(unsigned(baud_count) + 1);
160
        en_16_x_baud <= '0';
161
      end if;
162
 
163
      rx_read_buffer <= '0';
164
      tx_write_buffer <= '0';
165
 
166
      wbs_dat_s2m <= (others => '0');
167
      -- registered wishbone slave handshake (default)
168
      wbs_ack <= wbs_cyc_i and wbs_stb_i and (not wbs_ack);
169
 
170
      case wbs_adr_i(ADDR_MSB downto 0) is
171
        -- receive/transmit buffer access
172
        when UART_RXTX_ADDR(ADDR_MSB downto 0) =>
173
          if (wbs_cyc_i and wbs_stb_i) = '1' then
174
            -- overwriting wishbone slave handshake for blocking transactions 
175
            -- to rx/tx fifos by using buffer status flags
176
            if wbs_we_i = '1' then
177
              tx_write_buffer <= (not tx_buffer_full) and (not wbs_ack);
178
              wbs_ack <= (not tx_buffer_full) and (not wbs_ack);
179
            else
180
              rx_read_buffer <= rx_buffer_data_present and (not wbs_ack);
181
              wbs_ack <= rx_buffer_data_present and (not wbs_ack);
182
            end if;
183
          end if;
184
          wbs_dat_s2m <= rx_data_out;
185
        -- status register access
186
        when UART_SR_ADDR(ADDR_MSB downto 0) =>
187
          wbs_dat_s2m(UART_SR_RX_F_FLAG) <= rx_buffer_full;
188
          wbs_dat_s2m(UART_SR_RX_HF_FLAG) <= rx_buffer_half_full;
189
          wbs_dat_s2m(UART_SR_RX_DP_FLAG) <= rx_buffer_data_present;
190
          wbs_dat_s2m(UART_SR_TX_F_FLAG) <= tx_buffer_full;
191
          wbs_dat_s2m(UART_SR_TX_HF_FLAG) <= tx_buffer_half_full;
192
        -- baud rate register access / low byte
193
        when UART_BAUD_LO_ADDR(ADDR_MSB downto 0) =>
194
          if wb_reg_we = '1' then
195
            baud_limit(7 downto 0) <= wbs_dat_m2s_i;
196
            baud_count <= (others => '0');
197
          end if;
198
          wbs_dat_s2m <= baud_limit(7 downto 0);
199
        -- baud rate register access / high byte
200
        when UART_BAUD_HI_ADDR(ADDR_MSB downto 0) =>
201
          if wb_reg_we = '1' then
202
            baud_limit(15 downto 8) <= wbs_dat_m2s_i;
203
            baud_count <= (others => '0');
204
          end if;
205
          wbs_dat_s2m <= baud_limit(15 downto 8);
206
        when others => null;
207
      end case;
208
 
209
      if rst = '1' then
210
        wbs_ack <= '0';
211
      end if;
212
 
213
    end if;
214
  end process;
215
 
216
  -- Xilinx (R) uart macro instances
217
  ----------------------------------
218
 
219
  inst_uart_rx : uart_rx
220
    port map
221
    (
222
      serial_in => uart_rx_si_i,
223
      data_out => rx_data_out,
224
      read_buffer => rx_read_buffer,
225
      reset_buffer => rst,
226
      en_16_x_baud => en_16_x_baud,
227
      buffer_data_present => rx_buffer_data_present,
228
      buffer_full => rx_buffer_full,
229
      buffer_half_full => rx_buffer_half_full,
230
      clk => clk
231
    );
232
 
233
  inst_uart_tx : uart_tx
234
    port map
235
    (
236
      data_in => wbs_dat_m2s_i,
237
      write_buffer => tx_write_buffer,
238
      reset_buffer => rst,
239
      en_16_x_baud => en_16_x_baud,
240
      serial_out => uart_tx_so,
241
      buffer_full => tx_buffer_full,
242
      buffer_half_full => tx_buffer_half_full,
243
      clk => clk
244
    );
245
 
246
end rtl;

powered by: WebSVN 2.1.0

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