Commit 2cec051e authored by Stefan Rauch's avatar Stefan Rauch

uart: moved from wr-cores to bel-projects

This had nothing to do with WR, wasn't used here, and is now removed.
parent 2c71597a
files = [
"slib_clock_div.vhd",
"slib_counter.vhd",
"slib_edge_detect.vhd",
"slib_fifo_cyclone2.vhd",
"slib_fifo.vhd",
"slib_input_filter.vhd",
"slib_input_sync.vhd",
"slib_mv_filter.vhd",
"uart_16750.vhd",
"uart_baudgen.vhd",
"uart_interrupt.vhd",
"uart_receiver.vhd",
"uart_transmitter.vhd"
]
--
-- Clock divider (clock enable generator)
--
-- Author: Sebastian Witt
-- Date: 27.01.2008
-- Version: 1.1
--
-- This code is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA 02111-1307 USA
--
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
entity slib_clock_div is
generic (
RATIO : integer := 4 -- Clock divider ratio
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
CE : in std_logic; -- Clock enable input
Q : out std_logic -- New clock enable output
);
end slib_clock_div;
architecture rtl of slib_clock_div is
-- Signals
signal iQ : std_logic; -- Internal Q
signal iCounter : integer range 0 to RATIO-1; -- Counter
begin
-- Main process
CD_PROC: process (RST, CLK)
begin
if (RST = '1') then
iCounter <= 0;
iQ <= '0';
elsif (CLK'event and CLK='1') then
iQ <= '0';
if (CE = '1') then
if (iCounter = (RATIO-1)) then
iQ <= '1';
iCounter <= 0;
else
iCounter <= iCounter + 1;
end if;
end if;
end if;
end process;
-- Output signals
Q <= iQ;
end rtl;
\ No newline at end of file
--
-- Counter
--
-- Author: Sebastian Witt
-- Date: 27.01.2008
-- Version: 1.2
--
-- This code is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA 02111-1307 USA
--
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
-- Counter
entity slib_counter is
generic (
WIDTH : natural := 4 -- Counter width
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
CLEAR : in std_logic; -- Clear counter register
LOAD : in std_logic; -- Load counter register
ENABLE : in std_logic; -- Enable count operation
DOWN : in std_logic; -- Count direction down
D : in std_logic_vector(WIDTH-1 downto 0); -- Load counter register input
Q : out std_logic_vector(WIDTH-1 downto 0); -- Shift register output
OVERFLOW : out std_logic -- Counter overflow
);
end slib_counter;
architecture rtl of slib_counter is
signal iCounter : unsigned(WIDTH downto 0); -- Counter register
begin
-- Counter process
COUNT_SHIFT: process (RST, CLK)
begin
if (RST = '1') then
iCounter <= (others => '0'); -- Reset counter register
elsif (CLK'event and CLK='1') then
if (CLEAR = '1') then
iCounter <= (others => '0'); -- Clear counter register
elsif (LOAD = '1') then -- Load counter register
iCounter <= unsigned('0' & D);
elsif (ENABLE = '1') then -- Enable counter
if (DOWN = '0') then -- Count up
iCounter <= iCounter + 1;
else -- Count down
iCounter <= iCounter - 1;
end if;
end if;
if (iCounter(WIDTH) = '1') then -- Clear overflow
iCounter(WIDTH) <= '0';
end if;
end if;
end process;
-- Output ports
Q <= std_logic_vector(iCounter(WIDTH-1 downto 0));
OVERFLOW <= iCounter(WIDTH);
end rtl;
\ No newline at end of file
--
-- Signal edge detect
--
-- Author: Sebastian Witt
-- Data: 27.01.2008
-- Version: 1.1
--
-- This code is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA 02111-1307 USA
--
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
entity slib_edge_detect is
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
D : in std_logic; -- Signal input
RE : out std_logic; -- Rising edge detected
FE : out std_logic -- Falling edge detected
);
end slib_edge_detect;
architecture rtl of slib_edge_detect is
signal iDd : std_logic; -- D register
begin
-- Store D
ED_D: process (RST, CLK)
begin
if (RST = '1') then
iDd <= '0';
elsif (CLK'event and CLK='1') then
iDd <= D;
end if;
end process;
-- Output ports
RE <= '1' when iDd = '0' and D = '1' else '0';
FE <= '1' when iDd = '1' and D = '0' else '0';
end rtl;
\ No newline at end of file
--
-- FIFO
--
-- Author: Sebastian Witt
-- Date: 29.01.2008
-- Version: 1.3
--
-- This code is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA 02111-1307 USA
--
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
entity slib_fifo is
generic (
WIDTH : integer := 8; -- FIFO width
SIZE_E : integer := 6 -- FIFO size (2^SIZE_E)
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
CLEAR : in std_logic; -- Clear FIFO
WRITE : in std_logic; -- Write to FIFO
READ : in std_logic; -- Read from FIFO
D : in std_logic_vector(WIDTH-1 downto 0); -- FIFO input
Q : out std_logic_vector(WIDTH-1 downto 0); -- FIFO output
EMPTY : out std_logic; -- FIFO is empty
FULL : out std_logic; -- FIFO is full
USAGE : out std_logic_vector(SIZE_E-1 downto 0) -- FIFO usage
);
end slib_fifo;
architecture rtl of slib_fifo is
-- Signals
signal iEMPTY : std_logic; -- Internal EMPTY
signal iFULL : std_logic; -- Internal FULL
signal iWRAddr : unsigned(SIZE_E downto 0); -- FIFO write address
signal iRDAddr : unsigned(SIZE_E downto 0); -- FIFO read address
signal iUSAGE : unsigned(SIZE_E-1 downto 0); -- FIFO usage
-- FIFO memory
type FIFO_Mem_Type is array (2**SIZE_E-1 downto 0) of std_logic_vector(WIDTH-1 downto 0);
signal iFIFOMem : FIFO_Mem_Type := (others => (others => '0'));
begin
-- Full signal (biggest difference of read and write address)
iFULL <= '1' when (iRDAddr(SIZE_E-1 downto 0) = iWRAddr(SIZE_E-1 downto 0)) and
(iRDAddr(SIZE_E) /= iWRAddr(SIZE_E)) else '0';
-- Write/read address counter and empty signal
FF_ADDR: process (RST, CLK)
begin
if (RST = '1') then
iWRAddr <= (others => '0');
iRDAddr <= (others => '0');
iEMPTY <= '1';
elsif (CLK'event and CLK='1') then
if (WRITE = '1' and iFULL = '0') then -- Write to FIFO
iWRAddr <= iWRAddr + 1;
end if;
if (READ = '1' and iEMPTY = '0') then -- Read from FIFO
iRDAddr <= iRDAddr + 1;
end if;
if (CLEAR = '1') then -- Reset FIFO
iWRAddr <= (others => '0');
iRDAddr <= (others => '0');
end if;
if (iRDAddr = iWRAddr) then -- Empty signal (read address same as write address)
iEMPTY <= '1';
else
iEMPTY <= '0';
end if;
end if;
end process;
-- FIFO memory process
FF_MEM: process (RST, CLK)
begin
if (RST = '1') then
--iFIFOMem(2**SIZE_E-1 downto 0) <= (others => (others => '0'));
elsif (CLK'event and CLK = '1') then
if (WRITE = '1' and iFULL = '0') then
iFIFOMem(to_integer(iWRAddr(SIZE_E-1 downto 0))) <= D;
end if;
Q <= iFIFOMem(to_integer(iRDAddr(SIZE_E-1 downto 0)));
end if;
end process;
-- Usage counter
FF_USAGE: process (RST, CLK)
begin
if (RST = '1') then
iUSAGE <= (others => '0');
elsif (CLK'event and CLK = '1') then
if (CLEAR = '1') then
iUSAGE <= (others => '0');
else
if (READ = '0' and WRITE = '1' and iFULL = '0') then
iUSAGE <= iUSAGE + 1;
end if;
if (WRITE = '0' and READ = '1' and iEMPTY = '0') then
iUSAGE <= iUSAGE - 1;
end if;
end if;
end if;
end process;
-- Output signals
EMPTY <= iEMPTY;
FULL <= iFULL;
USAGE <= std_logic_vector(iUSAGE);
end rtl;
\ No newline at end of file
--
-- FIFO (using Altera scfifo for Cyclone II)
--
-- Author: Sebastian Witt
-- Date: 07.03.2008
-- Version: 1.0
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.all;
entity slib_fifo is
generic (
WIDTH : integer := 8; -- FIFO width
SIZE_E : integer := 6 -- FIFO size (2^SIZE_E)
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
CLEAR : in std_logic; -- Clear FIFO
WRITE : in std_logic; -- Write to FIFO
READ : in std_logic; -- Read from FIFO
D : in std_logic_vector(WIDTH-1 downto 0); -- FIFO input
Q : out std_logic_vector(WIDTH-1 downto 0); -- FIFO output
EMPTY : out std_logic; -- FIFO is empty
FULL : out std_logic; -- FIFO is full
USAGE : out std_logic_vector(SIZE_E-1 downto 0) -- FIFO usage
);
end slib_fifo;
architecture altera of slib_fifo is
COMPONENT scfifo
GENERIC (
add_ram_output_register : STRING;
intended_device_family : STRING;
lpm_numwords : NATURAL;
lpm_showahead : STRING;
lpm_type : STRING;
lpm_width : NATURAL;
lpm_widthu : NATURAL;
overflow_checking : STRING;
underflow_checking : STRING;
use_eab : STRING
);
PORT (
usedw : OUT STD_LOGIC_VECTOR (SIZE_E-1 DOWNTO 0);
rdreq : IN STD_LOGIC ;
sclr : IN STD_LOGIC ;
empty : OUT STD_LOGIC ;
clock : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (WIDTH-1 DOWNTO 0);
wrreq : IN STD_LOGIC ;
data : IN STD_LOGIC_VECTOR (WIDTH-1 DOWNTO 0);
full : OUT STD_LOGIC
);
END COMPONENT;
begin
scfifo_component : scfifo
GENERIC MAP (
add_ram_output_register => "OFF",
intended_device_family => "Cyclone II",
lpm_numwords => 2**SIZE_E,
lpm_showahead => "ON",
lpm_type => "scfifo",
lpm_width => WIDTH,
lpm_widthu => SIZE_E,
overflow_checking => "ON",
underflow_checking => "ON",
use_eab => "ON"
)
PORT MAP (
rdreq => READ,
sclr => CLEAR,
clock => CLK,
wrreq => WRITE,
data => D,
usedw => USAGE,
empty => EMPTY,
q => Q,
full => FULL
);
end altera;
\ No newline at end of file
--
-- Input filter
--
-- Author: Sebastian Witt
-- Data: 06.03.2008
-- Version: 1.0
--
-- This code is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA 02111-1307 USA
--
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
entity slib_input_filter is
generic (
SIZE : natural := 4 -- Filter counter size
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
CE : in std_logic; -- Clock enable
D : in std_logic; -- Signal input
Q : out std_logic -- Signal output
);
end slib_input_filter;
architecture rtl of slib_input_filter is
signal iCount : integer range 0 to SIZE;
begin
IF_D: process (RST, CLK)
begin
if (RST = '1') then
iCount <= 0;
Q <= '0';
elsif (CLK'event and CLK='1') then
-- Input counter
if (CE = '1' ) then
if (D = '1' and iCount /= SIZE) then
iCount <= iCount + 1;
elsif (D = '0' and iCount /= 0) then
iCount <= iCount - 1;
end if;
end if;
-- Output
if (iCount = SIZE) then
Q <= '1';
elsif (iCount = 0) then
Q <= '0';
end if;
end if;
end process;
end rtl;
\ No newline at end of file
--
-- Input synchronization
--
-- Author: Sebastian Witt
-- Data: 27.01.2008
-- Version: 1.0
--
-- This code is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA 02111-1307 USA
--
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
entity slib_input_sync is
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
D : in std_logic; -- Signal input
Q : out std_logic -- Signal output
);
end slib_input_sync;
architecture rtl of slib_input_sync is
signal iD : std_logic_vector(1 downto 0);
begin
IS_D: process (RST, CLK)
begin
if (RST = '1') then
iD <= (others => '0');
elsif (CLK'event and CLK='1') then
iD(0) <= D;
iD(1) <= iD(0);
end if;
end process;
-- Output ports
Q <= iD(1);
end rtl;
\ No newline at end of file
--
-- Majority voting filter
--
-- Author: Sebastian Witt
-- Date: 27.01.2008
-- Version: 1.1
--
-- This code is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA 02111-1307 USA
--
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
entity slib_mv_filter is
generic (
WIDTH : natural := 4;
THRESHOLD : natural := 10
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
SAMPLE : in std_logic; -- Clock enable for sample process
CLEAR : in std_logic; -- Reset process
D : in std_logic; -- Signal input
Q : out std_logic -- Signal D was at least THRESHOLD samples high
);
end slib_mv_filter;
architecture rtl of slib_mv_filter is
-- Signals
signal iCounter : unsigned(WIDTH downto 0); -- Sample counter
signal iQ : std_logic; -- Internal Q
begin
-- Main process
MV_PROC: process (RST, CLK)
begin
if (RST = '1') then
iCounter <= (others => '0');
iQ <= '0';
elsif (CLK'event and CLK='1') then
if (iCounter >= THRESHOLD) then -- Compare with threshold
iQ <= '1';
else
if (SAMPLE = '1' and D = '1') then -- Take sample
iCounter <= iCounter + 1;
end if;
end if;
if (CLEAR = '1') then -- Reset logic
iCounter <= (others => '0');
iQ <= '0';
end if;
end if;
end process;
-- Output signals
Q <= iQ;
end rtl;
\ No newline at end of file
This diff is collapsed.
--
-- UART Baudrate generator
--
-- Author: Sebastian Witt
-- Date: 27.01.2008
-- Version: 1.1
--
-- This code is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA 02111-1307 USA
--
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
-- Serial UART baudrate generator
entity uart_baudgen is
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
CE : in std_logic; -- Clock enable
CLEAR : in std_logic; -- Reset generator (synchronization)
DIVIDER : in std_logic_vector(15 downto 0); -- Clock divider
BAUDTICK : out std_logic -- 16xBaudrate tick
);
end uart_baudgen;
architecture rtl of uart_baudgen is
-- Signals
signal iCounter : unsigned(15 downto 0);
begin
-- Baudrate counter
BG_COUNT: process (CLK, RST)
begin
if (RST = '1') then
iCounter <= (others => '0');
BAUDTICK <= '0';
elsif (CLK'event and CLK = '1') then
if (CLEAR = '1') then
iCounter <= (others => '0');
elsif (CE = '1') then
iCounter <= iCounter + 1;
end if;
BAUDTICK <= '0';
if (iCounter = unsigned(DIVIDER)) then
iCounter <= (others => '0');
BAUDTICK <= '1';
end if;
end if;
end process;
end rtl;
\ No newline at end of file
--
-- UART interrupt control
--
-- Author: Sebastian Witt
-- Date: 27.01.2008
-- Version: 1.1
--
-- History: 1.0 - Initial version
-- 1.1 - Automatic flow control
--
--
-- This code is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA 02111-1307 USA
--
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
-- Serial UART interrupt control
entity uart_interrupt is
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
IER : in std_logic_vector(3 downto 0); -- IER 3:0
LSR : in std_logic_vector(4 downto 0); -- LSR 4:0
THI : in std_logic; -- Transmitter holding register empty interrupt
RDA : in std_logic; -- Receiver data available
CTI : in std_logic; -- Character timeout indication
AFE : in std_logic; -- Automatic flow control enable
MSR : in std_logic_vector(3 downto 0); -- MSR 3:0
IIR : out std_logic_vector(3 downto 0); -- IIR 3:0
INT : out std_logic -- Interrupt
);
end uart_interrupt;
architecture rtl of uart_interrupt is
-- Signals
signal iRLSInterrupt : std_logic; -- Receiver line status interrupt
signal iRDAInterrupt : std_logic; -- Received data available interrupt
signal iCTIInterrupt : std_logic; -- Character timeout indication interrupt
signal iTHRInterrupt : std_logic; -- Transmitter holding register empty interrupt
signal iMSRInterrupt : std_logic; -- Modem status interrupt
signal iIIR : std_logic_vector(3 downto 0); -- IIR register
begin
-- Priority 1: Receiver line status interrupt on: Overrun error, parity error, framing error or break interrupt
iRLSInterrupt <= IER(2) and (LSR(1) or LSR(2) or LSR(3) or LSR(4));
-- Priority 2: Received data available or trigger level reached in FIFO mode
iRDAInterrupt <= IER(0) and RDA;
-- Priority 2: Character timeout indication
iCTIInterrupt <= IER(0) and CTI;
-- Priority 3: Transmitter holding register empty
iTHRInterrupt <= IER(1) and THI;
-- Priority 4: Modem status interrupt: dCTS (when AFC is disabled), dDSR, TERI, dDCD
iMSRInterrupt <= IER(3) and ((MSR(0) and not AFE) or MSR(1) or MSR(2) or MSR(3));
-- IIR
IC_IIR: process (CLK, RST)
begin
if (RST = '1') then
iIIR <= "0001"; -- TODO: Invert later
elsif (CLK'event and CLK = '1') then
-- IIR register
if (iRLSInterrupt = '1') then
iIIR <= "0110";
elsif (iCTIInterrupt = '1') then
iIIR <= "1100";
elsif (iRDAInterrupt = '1') then
iIIR <= "0100";
elsif (iTHRInterrupt = '1') then
iIIR <= "0010";
elsif (iMSRInterrupt = '1') then
iIIR <= "0000";
else
iIIR <= "0001";
end if;
end if;
end process;
-- Outputs
IIR <= iIIR;
INT <= not iIIR(0);
end rtl;
\ No newline at end of file
This diff is collapsed.
--
-- UART transmitter
--
-- Author: Sebastian Witt
-- Date: 27.01.2008
-- Version: 1.0
--
-- This code is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-- Boston, MA 02111-1307 USA
--
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
-- Serial UART transmitter
entity uart_transmitter is
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
TXCLK : in std_logic; -- Transmitter clock (2x baudrate)
TXSTART : in std_logic; -- Start transmitter
CLEAR : in std_logic; -- Clear transmitter state
WLS : in std_logic_vector(1 downto 0); -- Word length select
STB : in std_logic; -- Number of stop bits
PEN : in std_logic; -- Parity enable
EPS : in std_logic; -- Even parity select
SP : in std_logic; -- Stick parity
BC : in std_logic; -- Break control
DIN : in std_logic_vector(7 downto 0); -- Input data
TXFINISHED : out std_logic; -- Transmitter operation finished
SOUT : out std_logic -- Transmitter output
);
end uart_transmitter;
architecture rtl of uart_transmitter is
-- FSM
type state_type is (IDLE, START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PAR, STOP, STOP2);
signal CState, NState : state_type;
-- Signals
signal iTx2 : std_logic; -- Next TX step
signal iSout : std_logic; -- Transmitter output
signal iParity : std_logic; -- Parity
signal iFinished : std_logic; -- TX finished
begin
-- Transmitter FSM update process
TX_PROC: process (RST, CLK)
begin
if (RST = '1') then
CState <= IDLE;
iTx2 <= '0';
elsif (CLK'event and CLK='1') then
if (TXCLK = '1') then -- TX clock
if (iTx2 = '0') then -- Two TX clocks per step
CState <= NState; -- Next step
iTx2 <= '1';
else
if ((WLS = "00") and (STB = '1') and CState = STOP2) then
CState <= NState; -- 1.5 stop bits for 5 bit word mode
iTx2 <= '1';
else
CState <= CState; -- First TX clock, wait
iTx2 <= '0';
end if;
end if;
end if;
end if;
end process;
-- Transmitter FSM
TX_FSM: process (CState, TXSTART, DIN, WLS, PEN, SP, EPS, STB, iParity)
begin
-- Defaults
NState <= IDLE;
iSout <= '1';
case CState is
when IDLE => if (TXSTART = '1') then
NState <= START;
end if;
when START => iSout <= '0';
NState <= BIT0;
when BIT0 => iSout <= DIN(0);
NState <= BIT1;
when BIT1 => iSout <= DIN(1);
NState <= BIT2;
when BIT2 => iSout <= DIN(2);
NState <= BIT3;
when BIT3 => iSout <= DIN(3);
NState <= BIT4;
when BIT4 => iSout <= DIN(4);
if (WLS = "00") then -- 5 bits
if (PEN = '1') then
NState <= PAR; -- Parity enabled
else
NState <= STOP; -- No parity
end if;
else
NState <= BIT5;
end if;
when BIT5 => iSout <= DIN(5);
if (WLS = "01") then -- 6 bits
if (PEN = '1') then
NState <= PAR; -- Parity enabled
else
NState <= STOP; -- No parity
end if;
else
NState <= BIT6;
end if;
when BIT6 => iSout <= DIN(6);
if (WLS = "10") then -- 7 bits
if (PEN = '1') then
NState <= PAR; -- Parity enabled
else
NState <= STOP; -- No parity
end if;
else
NState <= BIT7;
end if;
when BIT7 => iSout <= DIN(7);
if (PEN = '1') then
NState <= PAR; -- Parity enabled
else
NState <= STOP; -- No parity
end if;
when PAR => if (SP = '1') then -- Sticky parity
if (EPS = '1') then
iSout <= '0'; -- Even parity -> cleared
else
iSout <= '1'; -- Odd parity -> set
end if;
else
if (EPS = '1') then
iSout <= iParity; -- Even parity
else
iSout <= not iParity; -- Odd parity
end if;
end if;
NState <= STOP;
when STOP => if (STB = '1') then -- 2 stop bits
NState <= STOP2;
else
if (TXSTART = '1') then -- Next transmission
NState <= START;
end if;
end if;
when STOP2 => if (TXSTART = '1') then -- Next transmission
NState <= START;
end if;
when others => null;
end case;
end process;
-- Parity generation
TX_PAR: process (DIN, WLS)
variable iP40, iP50, iP60, iP70 : std_logic;
begin
iP40 := DIN(4) xor DIN(3) xor DIN(2) xor DIN(1) xor DIN(0);
iP50 := DIN(5) xor iP40;
iP60 := DIN(6) xor iP50;
iP70 := DIN(7) xor iP60;
case WLS is
when "00" => iParity <= iP40;
when "01" => iParity <= iP50;
when "10" => iParity <= iP60;
when others => iParity <= iP70;
end case;
end process;
-- Signal TX finished on STOP bit transmission
TX_FIN: process (CLK, RST)
variable iLast : std_logic;
begin
if (RST = '1') then
iFinished <= '0';
iLast := '0';
elsif (CLK'event and CLK = '1') then
iFinished <= '0';
if (iLast = '0' and CState = STOP) then
iFinished <= '1';
end if;
if (CState = STOP) then
iLast := '1';
else
iLast := '0';
end if;
end if;
end process;
-- Output signals
SOUT <= iSout when BC = '0' else '0';
TXFINISHED <= iFinished;
end rtl;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment