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

Subversion Repositories copyblaze

[/] [copyblaze/] [trunk/] [copyblaze/] [rtl/] [vhdl/] [ip/] [wb_uart/] [wb_uart.vhd] - Blame information for rev 59

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 ameziti
-----------------------------------------------------------------------------
2
-- Wishbone UART ------------------------------------------------------------
3
-- (c) 2007 Joerg Bornschein (jb@capsec.org)
4
--
5
-- All files under GPLv2 -- please contact me if you use this component
6
-----------------------------------------------------------------------------
7
library ieee;
8
use ieee.std_logic_1164.all;
9
use ieee.numeric_std.all;
10
 
11
-----------------------------------------------------------------------------
12
-- Wishbone UART ------------------------------------------------------------
13
entity wb_uart is
14
        port (
15
                clk        : in  std_logic;
16
                reset      : in  std_logic;
17
                -- Wishbone slave
18
                wb_adr_i   : in  std_logic_vector(31 downto 0);
19
                wb_dat_i   : in  std_logic_vector(31 downto 0);
20
                wb_dat_o   : out std_logic_vector(31 downto 0);
21
                wb_sel_i   : in  std_logic_vector( 3 downto 0);
22
                wb_cyc_i   : in  std_logic;
23
                wb_stb_i   : in  std_logic;
24
                wb_ack_o   : out std_logic;
25
                wb_we_i    : in  std_logic;
26
                wb_rxirq_o : out std_logic;
27
                wb_txirq_o : out std_logic;
28
                -- Serial I/O ports
29
                uart_rx    : in  std_logic;
30
                uart_tx    : out std_logic );
31
end wb_uart;
32
 
33
-----------------------------------------------------------------------------
34
-- 0x00 Status Register
35
-- 0x04 Divisor Register
36
-- 0x08 RX / TX Data
37
--
38
-- Status Register:
39
-- 
40
--       +-------------+----------+----------+---------+---------+
41
--       |  ... 0 ...  | TX_IRQEN | RX_IRQEN | TX_BUSY | RX_FULL |
42
--       +-------------+----------+----------+---------+---------+
43
--
44
-- Divisor Register:
45
--   Example: 115200 Baud with clk beeing 50MHz:   50MHz/115200 = 434
46
--
47
-----------------------------------------------------------------------------
48
-- Implementation -----------------------------------------------------------
49
architecture rtl of wb_uart is
50
 
51
-----------------------------------------------------------------------------
52
-- Components ---------------------------------------------------------------
53
component myuart is
54
        port (
55
                clk       : in  std_logic;
56
                reset     : in  std_logic;
57
                --
58
                divisor   : in  std_logic_vector(15 downto 0);
59
                txdata    : in  std_logic_vector( 7 downto 0);
60
                rxdata    : out std_logic_vector( 7 downto 0);
61
                wr        : in  std_logic;
62
                rd        : in  std_logic;
63
                tx_avail  : out std_logic;
64
                tx_busy   : out std_logic;
65
                rx_avail  : out std_logic;
66
                rx_full   : out std_logic;
67
                rx_error  : out std_logic;
68
                -- 
69
                uart_rxd  : in  std_logic;
70
                uart_txd  : out std_logic );
71
end component;
72
 
73
 
74
-----------------------------------------------------------------------------
75
-- Local Signals ------------------------------------------------------------
76
 
77
constant ZEROS  : std_logic_vector(31 downto 0) := (others => '0');
78
 
79
signal active     : std_logic;
80
signal activeLast : std_logic;
81
signal ack        : std_logic;
82
 
83
signal wr         : std_logic;
84
signal rd         : std_logic;
85
signal rx_avail   : std_logic;
86
signal tx_avail   : std_logic;
87
signal rxdata     : std_logic_vector(7 downto 0);
88
signal txdata     : std_logic_vector(7 downto 0);
89
 
90
signal status_reg : std_logic_vector(31 downto 0);
91
signal data_reg   : std_logic_vector(31 downto 0);
92
signal div_reg    : std_logic_vector(31 downto 0);
93
 
94
signal tx_irqen   : std_logic;
95
signal rx_irqen   : std_logic;
96
signal divisor    : std_logic_vector(15 downto 0);
97
 
98
begin
99
 
100
-- Instantiate actual UART engine
101
uart0: myuart
102
        port map (
103
                clk       => clk,
104
                reset     => reset,
105
        -- Sync Interface
106
                divisor   => divisor,
107
                txdata    => txdata,
108
                rxdata    => rxdata,
109
                wr        => wr,
110
                rd        => rd,
111
                tx_avail  => tx_avail,
112
                tx_busy   => open,
113
                rx_avail  => rx_avail,
114
                rx_full   => open,
115
                rx_error  => open,
116
                -- Async Interface
117
                uart_txd  => uart_tx,
118
                uart_rxd  => uart_rx );
119
 
120
 
121
-- Status & divisor register + Wishbine glue logic
122
status_reg <= ZEROS(31 downto  4) & tx_irqen & rx_irqen & not tx_avail & rx_avail;
123
data_reg   <= ZEROS(31 downto  8) & rxdata;
124
div_reg    <= ZEROS(31 downto 16) & divisor;
125
 
126
-- Bus cycle?
127
active <= wb_stb_i and wb_cyc_i;
128
 
129
wb_dat_o <= status_reg when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"0" else
130
            div_reg    when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"4" else
131
            data_reg   when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"8" else
132
            (others => '0');
133
 
134
rd <= '1' when (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"8" and wb_we_i='0' else
135
      '0';
136
 
137
wr <= '1' when (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"8" and wb_we_i='1' else
138
      '0';
139
 
140
txdata   <= wb_dat_i(7 downto 0);
141
wb_ack_o <= ack;
142
 
143
-- Handle Wishbone write request (and reset condition)
144
proc: process(reset, clk) is
145
begin
146
        if clk'event and clk='1' then
147
                if reset='1' then
148
                        tx_irqen <= '0';
149
                        rx_irqen <= '0';
150
                        divisor  <= (others => '1');
151
                else
152
 
153
                if active='1' then
154
                        if      activeLast='0' then
155
                                activeLast <= '1';
156
                                ack        <= '0';
157
                        else
158
                                activeLast <= '0';
159
                                ack        <= '1';
160
                        end if;
161
                else
162
                        ack        <= '0';
163
                        activeLast <= '0';
164
                end if;
165
 
166
                if active='1' and wb_we_i='1' then
167
                        if wb_adr_i(3 downto 0)=x"0" then     -- write to status register
168
                                tx_irqen <= wb_dat_i(3);
169
                                rx_irqen <= wb_dat_i(2);
170
                        elsif wb_adr_i(3 downto 0)=x"4" then  -- write to divisor register
171
                                divisor  <= wb_dat_i(15 downto 0);
172
                        end if;
173
                end if;
174
                end if;
175
        end if;
176
end process;
177
 
178
-- Generate interrupts when enabled
179
wb_rxirq_o <= rx_avail and rx_irqen;
180
wb_txirq_o <= tx_avail and tx_irqen;
181
 
182
end rtl;

powered by: WebSVN 2.1.0

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