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

Subversion Repositories wb4pb

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

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

powered by: WebSVN 2.1.0

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