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

Subversion Repositories copyblaze

[/] [copyblaze/] [trunk/] [copyblaze/] [rtl/] [vhdl/] [ip/] [wb_uart/] [wb_uart.vhd] - Rev 65

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

-----------------------------------------------------------------------------
-- Wishbone UART ------------------------------------------------------------
-- (c) 2007 Joerg Bornschein (jb@capsec.org)
--
-- All files under GPLv2 -- please contact me if you use this component
-----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
-----------------------------------------------------------------------------
-- Wishbone UART ------------------------------------------------------------
entity wb_uart is
	port (
		clk        : in  std_logic;
		reset      : in  std_logic;
		-- Wishbone slave
		wb_adr_i   : in  std_logic_vector(31 downto 0);
		wb_dat_i   : in  std_logic_vector(31 downto 0);
		wb_dat_o   : out std_logic_vector(31 downto 0);
		wb_sel_i   : in  std_logic_vector( 3 downto 0);
		wb_cyc_i   : in  std_logic;
		wb_stb_i   : in  std_logic;
		wb_ack_o   : out std_logic;
		wb_we_i    : in  std_logic;
		wb_rxirq_o : out std_logic;
		wb_txirq_o : out std_logic;
		-- Serial I/O ports
		uart_rx    : in  std_logic;
		uart_tx    : out std_logic );
end wb_uart;
 
-----------------------------------------------------------------------------
-- 0x00 Status Register
-- 0x04 Divisor Register
-- 0x08 RX / TX Data
--
-- Status Register:
-- 
--       +-------------+----------+----------+---------+---------+
--       |  ... 0 ...  | TX_IRQEN | RX_IRQEN | TX_BUSY | RX_FULL |
--       +-------------+----------+----------+---------+---------+
--
-- Divisor Register:
--   Example: 115200 Baud with clk beeing 50MHz:   50MHz/115200 = 434
--
-----------------------------------------------------------------------------
-- Implementation -----------------------------------------------------------
architecture rtl of wb_uart is
 
-----------------------------------------------------------------------------
-- Components ---------------------------------------------------------------
component myuart is
	port (
		clk       : in  std_logic;
		reset     : in  std_logic;
		--
		divisor   : in  std_logic_vector(15 downto 0);
		txdata    : in  std_logic_vector( 7 downto 0);
		rxdata    : out std_logic_vector( 7 downto 0);
		wr        : in  std_logic;
		rd        : in  std_logic;
		tx_avail  : out std_logic;
		tx_busy   : out std_logic;
		rx_avail  : out std_logic;
		rx_full   : out std_logic;
		rx_error  : out std_logic;
		-- 
		uart_rxd  : in  std_logic;
		uart_txd  : out std_logic );
end component;
 
 
-----------------------------------------------------------------------------
-- Local Signals ------------------------------------------------------------
 
constant ZEROS  : std_logic_vector(31 downto 0) := (others => '0');
 
signal active     : std_logic;
signal activeLast : std_logic;
signal ack        : std_logic;
 
signal wr         : std_logic;
signal rd         : std_logic;
signal rx_avail   : std_logic;
signal tx_avail   : std_logic;
signal rxdata     : std_logic_vector(7 downto 0);
signal txdata     : std_logic_vector(7 downto 0);
 
signal status_reg : std_logic_vector(31 downto 0);
signal data_reg   : std_logic_vector(31 downto 0);
signal div_reg    : std_logic_vector(31 downto 0);
 
signal tx_irqen   : std_logic;
signal rx_irqen   : std_logic;
signal divisor    : std_logic_vector(15 downto 0);
 
begin
 
-- Instantiate actual UART engine
uart0: myuart
	port map (
		clk       => clk,
		reset     => reset,
        -- Sync Interface
		divisor   => divisor,
		txdata    => txdata,
		rxdata    => rxdata,
		wr        => wr,
		rd        => rd,
		tx_avail  => tx_avail,
		tx_busy   => open,
		rx_avail  => rx_avail,
		rx_full   => open,
		rx_error  => open,
		-- Async Interface
		uart_txd  => uart_tx,
		uart_rxd  => uart_rx );
 
 
-- Status & divisor register + Wishbine glue logic
status_reg <= ZEROS(31 downto  4) & tx_irqen & rx_irqen & not tx_avail & rx_avail;
data_reg   <= ZEROS(31 downto  8) & rxdata;
div_reg    <= ZEROS(31 downto 16) & divisor;
 
-- Bus cycle?
active <= wb_stb_i and wb_cyc_i;
 
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
            div_reg    when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"4" else
            data_reg   when wb_we_i='0' and (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"8" else
            (others => '0');
 
rd <= '1' when (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"8" and wb_we_i='0' else
      '0';
 
wr <= '1' when (active='1' or ack='1') and wb_adr_i(3 downto 0)=x"8" and wb_we_i='1' else
      '0';
 
txdata   <= wb_dat_i(7 downto 0);
wb_ack_o <= ack;
 
-- Handle Wishbone write request (and reset condition)
proc: process(reset, clk) is
begin
	if clk'event and clk='1' then
		if reset='1' then
			tx_irqen <= '0';
			rx_irqen <= '0';
			divisor  <= (others => '1');
		else 
 
		if active='1' then
			if	activeLast='0' then
				activeLast <= '1';
				ack        <= '0';
			else 
				activeLast <= '0';
				ack        <= '1';
			end if;
		else 
			ack        <= '0';
			activeLast <= '0';	
		end if;
 
		if active='1' and wb_we_i='1' then    
			if wb_adr_i(3 downto 0)=x"0" then     -- write to status register
				tx_irqen <= wb_dat_i(3);
				rx_irqen <= wb_dat_i(2);
			elsif wb_adr_i(3 downto 0)=x"4" then  -- write to divisor register
				divisor  <= wb_dat_i(15 downto 0);
			end if;
		end if;
		end if;
	end if;
end process;
 
-- Generate interrupts when enabled
wb_rxirq_o <= rx_avail and rx_irqen;
wb_txirq_o <= tx_avail and tx_irqen;
 
end rtl;
 

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

powered by: WebSVN 2.1.0

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