283 lines
9.8 KiB
VHDL
283 lines
9.8 KiB
VHDL
-------------------------------------------------------
|
|
--! @file
|
|
--! @brief <short description>
|
|
--! @author Dominik Meyer
|
|
--! @email dmeyer@hsu-hh.de
|
|
--! @date 2013-07-18
|
|
-------------------------------------------------------
|
|
|
|
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.std_logic_unsigned.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
library work;
|
|
use work.cpupkg.all;
|
|
|
|
entity MMIO_Uart is
|
|
generic (
|
|
GEN_start : std_logic_vector(15 downto 0) := x"FFF0";
|
|
GEN_SysClockinHz : integer := 100000000;
|
|
GEN_Baudrate : integer := 57600;
|
|
GEN_HasExternBaudLimit : boolean := true
|
|
);
|
|
port (
|
|
|
|
odRS232 : out std_logic;
|
|
idRS232 : in std_logic;
|
|
|
|
ocInterrupt : out std_logic; --! high if data is available
|
|
|
|
odDebug : out std_logic_vector(7 downto 0);
|
|
|
|
|
|
iClk : in std_logic;
|
|
iReset : in std_logic;
|
|
bdData : inout DATA; --! connection to databus
|
|
idAddress : in ADDRESS; --! connection to addressbus
|
|
icEnable : in std_logic; --! enable or disable RAM
|
|
icRnotW : in std_logic --! read/write control
|
|
);
|
|
end MMIO_Uart;
|
|
|
|
architecture arch of MMIO_Uart is
|
|
|
|
component UART
|
|
generic (
|
|
GEN_SysClockinHz : integer;
|
|
GEN_Baudrate : integer;
|
|
GEN_HasExternBaudLimit : boolean
|
|
);
|
|
port (
|
|
iSysClk : in std_logic;
|
|
ieClkEn : in std_logic;
|
|
iReset : in std_logic;
|
|
icBaudLExt : in integer;
|
|
icSend : in std_logic;
|
|
idDataSend : in std_logic_vector ( 7 downto 0 );
|
|
ocSEmpty : out std_logic;
|
|
ocSFull : out std_logic;
|
|
ocSAlmostE : out std_logic;
|
|
ocSAlmostF : out std_logic;
|
|
odTransmit : out std_logic;
|
|
odDataRcvd : out std_logic_vector ( 7 downto 0 );
|
|
ocREmpty : out std_logic;
|
|
ocRFull : out std_logic;
|
|
ocRAlmostE : out std_logic;
|
|
ocRAlmostF : out std_logic;
|
|
icRReadEn : in std_logic;
|
|
idReceive : in std_logic
|
|
);
|
|
end component;
|
|
|
|
|
|
|
|
signal srTransmit : std_logic_vector(31 downto 0);
|
|
signal srReceive : std_logic_vector(31 downto 0);
|
|
signal srStatus : std_logic_vector(31 downto 0);
|
|
signal srBaud : std_logic_vector(31 downto 0);
|
|
signal scBaud : integer;
|
|
|
|
|
|
signal tData : DATA;
|
|
|
|
--
|
|
-- UART
|
|
--
|
|
signal scUARTsend, scUartReadEnable : std_logic;
|
|
signal scUARTSempty, scUARTSfull : std_logic;
|
|
signal scUARTSalmostE, scUARTSalmostF : std_logic;
|
|
signal scUARTRempty, scUARTRfull : std_logic;
|
|
signal scUARTRalmostE, scUARTRalmostF : std_logic;
|
|
|
|
|
|
--
|
|
-- FSM
|
|
--
|
|
type states is (st_start, st_idle, st_read, st_write);
|
|
signal current_state : states;
|
|
|
|
begin
|
|
|
|
scBaud <= to_integer(unsigned(srBaud));
|
|
|
|
odDebug <= scUARTRempty & srReceive(6 downto 0);
|
|
|
|
uart0: UART
|
|
generic map(
|
|
GEN_SysClockinHz => GEN_SysClockinHz,
|
|
GEN_Baudrate => GEN_Baudrate,
|
|
GEN_HasExternBaudLimit => GEN_HasExternBaudLimit
|
|
)
|
|
port map(
|
|
iSysClk => iClk,
|
|
ieClkEn => '1',
|
|
iReset => iReset,
|
|
icBaudLExt => scBaud,
|
|
icSend => scUARTsend,
|
|
idDataSend => srTransmit(7 downto 0),
|
|
ocSEmpty => scUARTSempty,
|
|
ocSFull => scUARTSfull,
|
|
ocSAlmostE => scUARTSalmostE,
|
|
ocSAlmostF => scUARTSalmostF,
|
|
odTransmit => odRS232,
|
|
odDataRcvd => srReceive(7 downto 0),
|
|
ocREmpty => scUARTRempty,
|
|
ocRFull => scUARTRfull,
|
|
ocRAlmostE => scUARTRalmostE,
|
|
ocRAlmostF => scUARTRalmostF,
|
|
icRReadEn => scUartReadEnable,
|
|
idReceive => idRS232
|
|
);
|
|
|
|
srStatus <= scUARTRempty & scUARTRfull & scUARTRalmostE & scUARTRalmostF & scUARTSempty & scUARTSfull & scUARTSalmostE & scUARTSalmostF & x"000000";
|
|
|
|
ocInterrupt <= not scUARTRempty;
|
|
|
|
process(iClk, iReset)
|
|
begin
|
|
if (iReset = '1') then
|
|
srBaud <= (others=>'0');
|
|
srTransmit <= x"00000000";
|
|
srReceive(30 downto 8) <= (others=>'0');
|
|
|
|
current_state <= st_start;
|
|
|
|
elsif (rising_edge(iClk)) then
|
|
case current_state is
|
|
when st_start =>
|
|
scUARTsend <= '0';
|
|
scUartReadEnable <= '0';
|
|
|
|
current_state <= st_idle;
|
|
when st_idle =>
|
|
if (icEnable = '1' and idAddress >= GEN_start and idAddress <= GEN_start + 2) then
|
|
|
|
-- Status Register
|
|
if (idAddress = GEN_start) then
|
|
if (icRnotW = '0') then
|
|
|
|
scUARTsend <= '0';
|
|
scUartReadEnable <= '0';
|
|
|
|
|
|
current_state <= st_write;
|
|
|
|
else
|
|
|
|
scUARTsend <= '0';
|
|
scUartReadEnable <= '0';
|
|
|
|
|
|
current_state <= st_read;
|
|
end if;
|
|
-- Transmit Register
|
|
elsif(idAddress = GEN_start+1) then
|
|
if (icRnotW = '0') then
|
|
srTransmit <= bdData;
|
|
|
|
scUARTsend <= '1';
|
|
scUartReadEnable <= '0';
|
|
|
|
|
|
current_state <= st_write;
|
|
|
|
else
|
|
tData <= (others=>'0');
|
|
|
|
scUARTsend <= '0';
|
|
scUartReadEnable <= '0';
|
|
|
|
|
|
current_state <= st_read;
|
|
end if;
|
|
|
|
-- receive Register
|
|
elsif(idAddress = GEN_start+2) then
|
|
if (icRnotW = '0') then
|
|
|
|
scUARTsend <= '0';
|
|
scUartReadEnable <= '0';
|
|
|
|
|
|
current_state <= st_write;
|
|
|
|
else
|
|
tData <= srReceive;
|
|
|
|
scUARTsend <= '0';
|
|
scUartReadEnable <= '1';
|
|
|
|
|
|
current_state <= st_read;
|
|
end if;
|
|
end if;
|
|
|
|
else
|
|
scUARTsend <= '0';
|
|
scUartReadEnable <= '0';
|
|
|
|
current_state <= st_idle;
|
|
end if;
|
|
when st_read =>
|
|
scUARTsend <= '0';
|
|
scUartReadEnable <= '0';
|
|
|
|
current_state <= st_idle;
|
|
|
|
when st_write =>
|
|
scUARTsend <= '0';
|
|
scUartReadEnable <= '0';
|
|
|
|
current_state <= st_idle;
|
|
end case;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
bdData <= srStatus when icRnotW = '1' and idAddress=GEN_start else
|
|
srReceive when icRnotW = '1' and idAddress=GEN_start+2 else
|
|
(others => 'Z');
|
|
|
|
end arch;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|