--===========================================================================--
|
--===========================================================================--
|
--
|
--
|
-- S Y N T H E Z I A B L E ACIA 6850 C O R E
|
-- S Y N T H E Z I A B L E ACIA 6850 C O R E
|
--
|
--
|
-- www.OpenCores.Org - January 2007
|
-- www.OpenCores.Org - January 2007
|
-- This core adheres to the GNU public license
|
-- This core adheres to the GNU public license
|
--
|
--
|
-- Design units : 6850 ACIA core for the System68/09
|
-- Design units : 6850 ACIA core for the System68/09
|
--
|
--
|
-- File name : ACIA_RX.vhd
|
-- File name : ACIA_RX.vhd
|
--
|
--
|
-- Purpose : Implements a 6850 ACIA device for communication purposes
|
-- Purpose : Implements a 6850 ACIA device for communication purposes
|
-- between the cpu68/09 cpu and the Host computer through
|
-- between the cpu68/09 cpu and the Host computer through
|
-- an RS-232 communication protocol.
|
-- an RS-232 communication protocol.
|
--
|
--
|
-- Dependencies : ieee.std_logic_1164.all;
|
-- Dependencies : ieee.std_logic_1164.all;
|
-- ieee.numeric_std.all;
|
-- ieee.numeric_std.all;
|
-- ieee.std_logic_unsigned.all;
|
-- ieee.std_logic_unsigned.all;
|
-- unisim.vcomponents.all;
|
-- unisim.vcomponents.all;
|
--
|
--
|
--===========================================================================--
|
--===========================================================================--
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Revision list
|
-- Revision list
|
-- Version Author Date Changes
|
-- Version Author Date Changes
|
--
|
--
|
-- 0.1 Ovidiu Lupas 15 January 2000 New model
|
-- 0.1 Ovidiu Lupas 15 January 2000 New model
|
-- 2.0 Ovidiu Lupas 17 April 2000 samples counter cleared for bit 0
|
-- 2.0 Ovidiu Lupas 17 April 2000 samples counter cleared for bit 0
|
-- olupas@opencores.org
|
-- olupas@opencores.org
|
--
|
--
|
-- 3.0 John Kent 5 January 2003 Added 6850 word format control
|
-- 3.0 John Kent 5 January 2003 Added 6850 word format control
|
-- 3.1 John Kent 12 January 2003 Significantly revamped receive code.
|
-- 3.1 John Kent 12 January 2003 Significantly revamped receive code.
|
-- 3.2 John Kent 10 January 2004 Rewrite of code.
|
-- 3.2 John Kent 10 January 2004 Rewrite of code.
|
-- 4.0 John Kent 3 February 2007 Renamed to ACIA 6850
|
-- 4.0 John Kent 3 February 2007 Renamed to ACIA 6850
|
-- Removed input debounce
|
-- Removed input debounce
|
-- 4.1 John Kent 4 February 2007 Cleaned up Rx state machine
|
-- 4.1 John Kent 4 February 2007 Cleaned up Rx state machine
|
-- 4.2 John Kent 25 February 2007 Modified sensitivity lists
|
-- 4.2 John Kent 25 February 2007 Modified sensitivity lists
|
--
|
--
|
-- dilbert57@opencores.org
|
-- dilbert57@opencores.org
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
--
|
--
|
-- Description : Implements the receive unit of the ACIA_6850 core.
|
-- Description : Implements the receive unit of the ACIA_6850 core.
|
-- Samples 16 times the RxD line and retain the value
|
-- Samples 16 times the RxD line and retain the value
|
-- in the middle of the time interval.
|
-- in the middle of the time interval.
|
--
|
--
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
--library unisim;
|
--library unisim;
|
-- use unisim.vcomponents.all;
|
-- use unisim.vcomponents.all;
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Entity for the ACIA Receiver
|
-- Entity for the ACIA Receiver
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
entity ACIA_RX is
|
entity ACIA_RX is
|
port (
|
port (
|
Clk : in Std_Logic; -- Clock signal
|
Clk : in Std_Logic; -- Clock signal
|
RxRst : in Std_Logic; -- Reset input
|
RxRst : in Std_Logic; -- Reset input
|
RxRd : in Std_Logic; -- Read data strobe
|
RxRd : in Std_Logic; -- Read data strobe
|
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
|
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
|
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
|
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
|
RxClk : in Std_Logic; -- RS-232 clock input
|
RxClk : in Std_Logic; -- RS-232 clock input
|
RxDat : in Std_Logic; -- RS-232 data input
|
RxDat : in Std_Logic; -- RS-232 data input
|
RxFErr : out Std_Logic; -- Framing Error status
|
RxFErr : out Std_Logic; -- Framing Error status
|
RxOErr : out Std_Logic; -- Over Run Error Status
|
RxOErr : out Std_Logic; -- Over Run Error Status
|
RxPErr : out Std_logic; -- Parity Error Status
|
RxPErr : out Std_logic; -- Parity Error Status
|
RxRdy : out Std_Logic; -- Data Ready Status
|
RxRdy : out Std_Logic; -- Data Ready Status
|
RxDout : out Std_Logic_Vector(7 downto 0)
|
RxDout : out Std_Logic_Vector(7 downto 0)
|
);
|
);
|
end ACIA_RX; --================== End of entity ==============================--
|
end ACIA_RX; --================== End of entity ==============================--
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Architecture for ACIA receiver
|
-- Architecture for ACIA receiver
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
|
|
architecture rtl of ACIA_RX is
|
architecture rtl of ACIA_RX is
|
|
|
type RxStateType is ( RxStart_State, RxData_state,
|
type RxStateType is ( RxStart_State, RxData_state,
|
RxParity_state, RxStop_state );
|
RxParity_state, RxStop_state );
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Signals
|
-- Signals
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
signal RxDatDel0 : Std_Logic := '0'; -- Delayed Rx Data
|
signal RxDatDel0 : Std_Logic := '0'; -- Delayed Rx Data
|
signal RxDatDel1 : Std_Logic := '0'; -- Delayed Rx Data
|
signal RxDatDel1 : Std_Logic := '0'; -- Delayed Rx Data
|
signal RxDatDel2 : Std_Logic := '0'; -- Delayed Rx Data
|
signal RxDatDel2 : Std_Logic := '0'; -- Delayed Rx Data
|
signal RxDatEdge : Std_Logic := '0'; -- Rx Data Edge pulse
|
signal RxDatEdge : Std_Logic := '0'; -- Rx Data Edge pulse
|
signal RxClkDel : Std_Logic := '0'; -- Delayed Rx Input Clock
|
signal RxClkDel : Std_Logic := '0'; -- Delayed Rx Input Clock
|
signal RxClkEdge : Std_Logic := '0'; -- Rx Input Clock Edge pulse
|
signal RxClkEdge : Std_Logic := '0'; -- Rx Input Clock Edge pulse
|
signal RxStart : Std_Logic := '0'; -- Rx Start request
|
signal RxStart : Std_Logic := '0'; -- Rx Start request
|
signal RxEnable : Std_Logic := '0'; -- Rx Enabled
|
signal RxEnable : Std_Logic := '0'; -- Rx Enabled
|
signal RxClkCnt : Std_Logic_Vector(5 downto 0) := (others => '0'); -- Rx Baud Clock Counter
|
signal RxClkCnt : Std_Logic_Vector(5 downto 0) := (others => '0'); -- Rx Baud Clock Counter
|
signal RxBdClk : Std_Logic := '0'; -- Rx Baud Clock
|
signal RxBdClk : Std_Logic := '0'; -- Rx Baud Clock
|
signal RxBdDel : Std_Logic := '0'; -- Delayed Rx Baud Clock
|
signal RxBdDel : Std_Logic := '0'; -- Delayed Rx Baud Clock
|
signal RxBdEdge : Std_Logic := '0'; -- Rx Baud Clock Edge pulse
|
signal RxBdEdge : Std_Logic := '0'; -- Rx Baud Clock Edge pulse
|
|
|
signal RxReady : Std_Logic := '0'; -- Data Ready flag
|
signal RxReady : Std_Logic := '0'; -- Data Ready flag
|
signal RxReq : Std_Logic := '0'; -- Rx Data Valid
|
signal RxReq : Std_Logic := '0'; -- Rx Data Valid
|
signal RxAck : Std_Logic := '0'; -- Rx Data Valid
|
signal RxAck : Std_Logic := '0'; -- Rx Data Valid
|
signal RxParity : Std_Logic := '0'; -- Calculated RX parity bit
|
signal RxParity : Std_Logic := '0'; -- Calculated RX parity bit
|
signal RxState : RxStateType; -- receive bit state
|
signal RxState : RxStateType; -- receive bit state
|
signal RxBitCount : Std_Logic_Vector(2 downto 0) := (others => '0'); -- Rx Bit counter
|
signal RxBitCount : Std_Logic_Vector(2 downto 0) := (others => '0'); -- Rx Bit counter
|
signal RxShiftReg : Std_Logic_Vector(7 downto 0) := (others => '0'); -- Shift Register
|
signal RxShiftReg : Std_Logic_Vector(7 downto 0) := (others => '0'); -- Shift Register
|
|
|
begin
|
begin
|
|
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Receiver Clock Edge Detection
|
-- Receiver Clock Edge Detection
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- A rising edge will produce a one clock cycle pulse
|
-- A rising edge will produce a one clock cycle pulse
|
--
|
--
|
-- acia_rx_clock_edge : process( Clk, RxRst, RxClk, RxClkDel )
|
-- acia_rx_clock_edge : process( Clk, RxRst, RxClk, RxClkDel )
|
acia_rx_clock_edge : process( RxRst, Clk )
|
acia_rx_clock_edge : process( RxRst, Clk )
|
begin
|
begin
|
if RxRst = '1' then
|
if RxRst = '1' then
|
RxClkDel <= '0';
|
RxClkDel <= '0';
|
RxClkEdge <= '0';
|
RxClkEdge <= '0';
|
elsif Clk'event and Clk = '0' then
|
elsif Clk'event and Clk = '0' then
|
RxClkDel <= RxClk;
|
RxClkDel <= RxClk;
|
RxClkEdge <= (not RxClkDel) and RxClk;
|
RxClkEdge <= (not RxClkDel) and RxClk;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Receiver Data Edge Detection
|
-- Receiver Data Edge Detection
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- A falling edge will produce a pulse on RxClk wide
|
-- A falling edge will produce a pulse on RxClk wide
|
--
|
--
|
-- acia_rx_data_edge : process(Clk, RxRst, RxClkEdge, RxDat, RxDatDel0, RxDatDel1, RxDatDel2 )
|
-- acia_rx_data_edge : process(Clk, RxRst, RxClkEdge, RxDat, RxDatDel0, RxDatDel1, RxDatDel2 )
|
acia_rx_data_edge : process( RxRst, Clk )
|
acia_rx_data_edge : process( RxRst, Clk )
|
begin
|
begin
|
if RxRst = '1' then
|
if RxRst = '1' then
|
RxDatDel0 <= '0';
|
RxDatDel0 <= '0';
|
RxDatDel1 <= '0';
|
RxDatDel1 <= '0';
|
RxDatDel2 <= '0';
|
RxDatDel2 <= '0';
|
RxDatEdge <= '0';
|
RxDatEdge <= '0';
|
elsif Clk'event and Clk = '0' then
|
elsif Clk'event and Clk = '0' then
|
-- if RxClkEdge = '1' then
|
-- if RxClkEdge = '1' then
|
RxDatDel0 <= RxDat;
|
RxDatDel0 <= RxDat;
|
RxDatDel1 <= RxDatDel0;
|
RxDatDel1 <= RxDatDel0;
|
RxDatDel2 <= RxDatDel1;
|
RxDatDel2 <= RxDatDel1;
|
RxDatEdge <= RxDatDel0 and (not RxDat);
|
RxDatEdge <= RxDatDel0 and (not RxDat);
|
-- end if;
|
-- end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Receiver Start / Stop
|
-- Receiver Start / Stop
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Enable the receive clock on detection of a start bit
|
-- Enable the receive clock on detection of a start bit
|
-- Disable the receive clock after a byte is received.
|
-- Disable the receive clock after a byte is received.
|
--
|
--
|
-- acia_rx_start_stop : process( Clk, RxRst, RxDatEdge, RxAck, RxStart, RxEnable )
|
-- acia_rx_start_stop : process( Clk, RxRst, RxDatEdge, RxAck, RxStart, RxEnable )
|
acia_rx_start_stop : process( RxRst, Clk )
|
acia_rx_start_stop : process( RxRst, Clk )
|
begin
|
begin
|
if RxRst = '1' then
|
if RxRst = '1' then
|
RxEnable <= '0';
|
RxEnable <= '0';
|
RxStart <= '0';
|
RxStart <= '0';
|
elsif Clk'event and Clk='0' then
|
elsif Clk'event and Clk='0' then
|
if (RxEnable = '0') and (RxDatEdge = '1') then
|
if (RxEnable = '0') and (RxDatEdge = '1') then
|
-- Data Edge detected
|
-- Data Edge detected
|
-- Request Start and Enable Receive Clock.
|
-- Request Start and Enable Receive Clock.
|
RxEnable <= '1';
|
RxEnable <= '1';
|
RxStart <= '1';
|
RxStart <= '1';
|
else
|
else
|
if (RxStart = '1') and (RxAck = '1') then
|
if (RxStart = '1') and (RxAck = '1') then
|
-- Data is being received
|
-- Data is being received
|
-- reset start request
|
-- reset start request
|
RxStart <= '0';
|
RxStart <= '0';
|
else
|
else
|
-- Data has now been received
|
-- Data has now been received
|
-- Disable Receiver until next start bit
|
-- Disable Receiver until next start bit
|
if (RxStart = '0') and (RxAck = '0') then
|
if (RxStart = '0') and (RxAck = '0') then
|
RxEnable <= '0';
|
RxEnable <= '0';
|
end if;
|
end if;
|
end if; -- RxStart
|
end if; -- RxStart
|
end if; -- RxDatEdge
|
end if; -- RxDatEdge
|
end if; -- clk / RxRst
|
end if; -- clk / RxRst
|
end process;
|
end process;
|
|
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Receiver Clock Divider
|
-- Receiver Clock Divider
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Hold the Rx Clock divider in reset when the receiver is disabled
|
-- Hold the Rx Clock divider in reset when the receiver is disabled
|
-- Advance the count only on a rising Rx clock edge
|
-- Advance the count only on a rising Rx clock edge
|
--
|
--
|
-- acia_rx_clock_divide : process( Clk, RxRst, RxEnable, RxClkEdge, RxClkCnt )
|
-- acia_rx_clock_divide : process( Clk, RxRst, RxEnable, RxClkEdge, RxClkCnt )
|
acia_rx_clock_divide : process( RxRst, Clk )
|
acia_rx_clock_divide : process( RxRst, Clk )
|
begin
|
begin
|
if RxRst = '1' then
|
if RxRst = '1' then
|
RxClkCnt <= (others => '0');
|
RxClkCnt <= (others => '0');
|
elsif Clk'event and Clk = '0' then
|
elsif Clk'event and Clk = '0' then
|
-- if RxEnable = '0' then
|
-- if RxEnable = '0' then
|
if RxDatEdge = '1' then
|
if RxDatEdge = '1' then
|
RxClkCnt <= (others => '0'); -- reset on falling data edge
|
RxClkCnt <= (others => '0'); -- reset on falling data edge
|
else
|
else
|
if RxClkEdge = '1' then -- increment count on Clock edge
|
if RxClkEdge = '1' then -- increment count on Clock edge
|
RxClkCnt <= RxClkCnt + "000001";
|
RxClkCnt <= RxClkCnt + "000001";
|
end if; -- RxClkEdge
|
end if; -- RxClkEdge
|
end if; -- RxState
|
end if; -- RxState
|
end if; -- clk / RxRst
|
end if; -- clk / RxRst
|
end process;
|
end process;
|
|
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Receiver Baud Clock Selector
|
-- Receiver Baud Clock Selector
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- BdFmt
|
-- BdFmt
|
-- 0 0 - Baud Clk divide by 1
|
-- 0 0 - Baud Clk divide by 1
|
-- 0 1 - Baud Clk divide by 16
|
-- 0 1 - Baud Clk divide by 16
|
-- 1 0 - Baud Clk divide by 64
|
-- 1 0 - Baud Clk divide by 64
|
-- 1 1 - Reset
|
-- 1 1 - Reset
|
--
|
--
|
acia_rx_baud_clock_select : process( BdFmt, RxClk, RxClkCnt )
|
acia_rx_baud_clock_select : process( BdFmt, RxClk, RxClkCnt )
|
begin
|
begin
|
case BdFmt is
|
case BdFmt is
|
when "00" => -- Div by 1
|
when "00" => -- Div by 1
|
RxBdClk <= RxClk;
|
RxBdClk <= RxClk;
|
when "01" => -- Div by 16
|
when "01" => -- Div by 16
|
RxBdClk <= RxClkCnt(3);
|
RxBdClk <= RxClkCnt(3);
|
when "10" => -- Div by 64
|
when "10" => -- Div by 64
|
RxBdClk <= RxClkCnt(5);
|
RxBdClk <= RxClkCnt(5);
|
when others => -- RxRst
|
when others => -- RxRst
|
RxBdClk <= '0';
|
RxBdClk <= '0';
|
end case;
|
end case;
|
end process;
|
end process;
|
|
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Receiver Baud Clock Edge Detect
|
-- Receiver Baud Clock Edge Detect
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
--
|
--
|
-- Generate one clock strobe on rising baud clock edge
|
-- Generate one clock strobe on rising baud clock edge
|
--
|
--
|
-- acia_rx_baud_clock_edge : process( Clk, RxRst, RxBdClk, RxBdDel )
|
-- acia_rx_baud_clock_edge : process( Clk, RxRst, RxBdClk, RxBdDel )
|
acia_rx_baud_clock_edge : process( RxRst, Clk )
|
acia_rx_baud_clock_edge : process( RxRst, Clk )
|
begin
|
begin
|
if RxRst = '1' then
|
if RxRst = '1' then
|
RxBdDel <= '0';
|
RxBdDel <= '0';
|
RxBdEdge <= '0';
|
RxBdEdge <= '0';
|
elsif Clk'event and Clk = '0' then
|
elsif Clk'event and Clk = '0' then
|
RxBdDel <= RxBdClk;
|
RxBdDel <= RxBdClk;
|
RxBdEdge <= RxBdClk and (not RxBdDel);
|
RxBdEdge <= RxBdClk and (not RxBdDel);
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Receiver process
|
-- Receiver process
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- WdFmt - Bits[4..2]
|
-- WdFmt - Bits[4..2]
|
-- 0 0 0 - 7 data, even parity, 2 stop
|
-- 0 0 0 - 7 data, even parity, 2 stop
|
-- 0 0 1 - 7 data, odd parity, 2 stop
|
-- 0 0 1 - 7 data, odd parity, 2 stop
|
-- 0 1 0 - 7 data, even parity, 1 stop
|
-- 0 1 0 - 7 data, even parity, 1 stop
|
-- 0 1 1 - 7 data, odd parity, 1 stop
|
-- 0 1 1 - 7 data, odd parity, 1 stop
|
-- 1 0 0 - 8 data, no parity, 2 stop
|
-- 1 0 0 - 8 data, no parity, 2 stop
|
-- 1 0 1 - 8 data, no parity, 1 stop
|
-- 1 0 1 - 8 data, no parity, 1 stop
|
-- 1 1 0 - 8 data, even parity, 1 stop
|
-- 1 1 0 - 8 data, even parity, 1 stop
|
-- 1 1 1 - 8 data, odd parity, 1 stop
|
-- 1 1 1 - 8 data, odd parity, 1 stop
|
-- acia_rx_receive : process( Clk, RxRst, RxState, RxBdEdge, RxDatDel2, RxBitCount, RxReady, RxShiftReg )
|
-- acia_rx_receive : process( Clk, RxRst, RxState, RxBdEdge, RxDatDel2, RxBitCount, RxReady, RxShiftReg )
|
acia_rx_receive : process( RxRst, Clk )
|
acia_rx_receive : process( RxRst, Clk )
|
begin
|
begin
|
if RxRst = '1' then
|
if RxRst = '1' then
|
RxFErr <= '0';
|
RxFErr <= '0';
|
RxOErr <= '0';
|
RxOErr <= '0';
|
RxPErr <= '0';
|
RxPErr <= '0';
|
RxShiftReg <= (others => '0'); -- Resert Shift register
|
RxShiftReg <= (others => '0'); -- Resert Shift register
|
RxDOut <= (others => '0');
|
RxDOut <= (others => '0');
|
RxParity <= '0'; -- reset Parity bit
|
RxParity <= '0'; -- reset Parity bit
|
RxAck <= '0'; -- Receiving data
|
RxAck <= '0'; -- Receiving data
|
RxBitCount <= (others => '0');
|
RxBitCount <= (others => '0');
|
RxState <= RxStart_state;
|
RxState <= RxStart_state;
|
elsif Clk'event and Clk='0' then
|
elsif Clk'event and Clk='0' then
|
if RxBdEdge = '1' then
|
if RxBdEdge = '1' then
|
case RxState is
|
case RxState is
|
when RxStart_state =>
|
when RxStart_state =>
|
RxShiftReg <= (others => '0'); -- Reset Shift register
|
RxShiftReg <= (others => '0'); -- Reset Shift register
|
RxParity <= '0'; -- Parity bit
|
RxParity <= '0'; -- Parity bit
|
if WdFmt(2) = '0' then
|
if WdFmt(2) = '0' then
|
-- WdFmt(2) = '0' => 7 data
|
-- WdFmt(2) = '0' => 7 data
|
RxBitCount <= "110";
|
RxBitCount <= "110";
|
else
|
else
|
-- WdFmt(2) = '1' => 8 data
|
-- WdFmt(2) = '1' => 8 data
|
RxBitCount <= "111";
|
RxBitCount <= "111";
|
end if;
|
end if;
|
if RxDatDel2 = '0' then -- look for start request
|
if RxDatDel2 = '0' then -- look for start request
|
RxState <= RxData_state; -- yes, read data
|
RxState <= RxData_state; -- yes, read data
|
end if;
|
end if;
|
|
|
when RxData_state => -- data bits 0 to 6
|
when RxData_state => -- data bits 0 to 6
|
RxShiftReg <= RxDatDel2 & RxShiftReg(7 downto 1);
|
RxShiftReg <= RxDatDel2 & RxShiftReg(7 downto 1);
|
RxParity <= RxParity xor RxDatDel2;
|
RxParity <= RxParity xor RxDatDel2;
|
RxAck <= '1'; -- Flag receive in progress
|
RxAck <= '1'; -- Flag receive in progress
|
RxBitCount <= RxBitCount - "001";
|
RxBitCount <= RxBitCount - "001";
|
if RxBitCount = "000" then
|
if RxBitCount = "000" then
|
if WdFmt(2) = '0' then -- WdFmt(2) = '0' => 7 data
|
if WdFmt(2) = '0' then -- WdFmt(2) = '0' => 7 data
|
RxState <= RxParity_state; -- 7 bits always has parity
|
RxState <= RxParity_state; -- 7 bits always has parity
|
else -- WdFmt(2) = '1' => 8 data
|
else -- WdFmt(2) = '1' => 8 data
|
if WdFmt(1) = '0' then
|
if WdFmt(1) = '0' then
|
RxState <= RxStop_state; -- WdFmt(1) = '0' no parity
|
RxState <= RxStop_state; -- WdFmt(1) = '0' no parity
|
else
|
else
|
RxState <= RxParity_state; -- WdFmt(1) = '1' parity
|
RxState <= RxParity_state; -- WdFmt(1) = '1' parity
|
end if; -- WdFmt(1)
|
end if; -- WdFmt(1)
|
end if; -- WdFmt(2)
|
end if; -- WdFmt(2)
|
end if; -- RxBitCount
|
end if; -- RxBitCount
|
|
|
when RxParity_state => -- parity bit
|
when RxParity_state => -- parity bit
|
if WdFmt(2) = '0' then -- 7 data, shift right
|
if WdFmt(2) = '0' then -- 7 data, shift right
|
RxShiftReg <= RxDatDel2 & RxShiftReg(7 downto 1); -- 7 data + parity
|
RxShiftReg <= RxDatDel2 & RxShiftReg(7 downto 1); -- 7 data + parity
|
end if;
|
end if;
|
if WdFmt(0) = '0' then -- parity polarity ?
|
if WdFmt(0) = '0' then -- parity polarity ?
|
if RxParity = RxDatDel2 then -- check even parity
|
if RxParity = RxDatDel2 then -- check even parity
|
RxPErr <= '1';
|
RxPErr <= '1';
|
else
|
else
|
RxPErr <= '0';
|
RxPErr <= '0';
|
end if;
|
end if;
|
else
|
else
|
if RxParity = RxDatDel2 then -- check for odd parity
|
if RxParity = RxDatDel2 then -- check for odd parity
|
RxPErr <= '0';
|
RxPErr <= '0';
|
else
|
else
|
RxPErr <= '1';
|
RxPErr <= '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
RxState <= RxStop_state;
|
RxState <= RxStop_state;
|
|
|
when RxStop_state => -- stop bit (Only one required for RX)
|
when RxStop_state => -- stop bit (Only one required for RX)
|
RxAck <= '0'; -- Flag Receive Complete
|
RxAck <= '0'; -- Flag Receive Complete
|
RxDOut <= RxShiftReg;
|
RxDOut <= RxShiftReg;
|
if RxDatDel2 = '1' then -- stop bit expected
|
if RxDatDel2 = '1' then -- stop bit expected
|
RxFErr <= '0'; -- yes, no framing error
|
RxFErr <= '0'; -- yes, no framing error
|
else
|
else
|
RxFErr <= '1'; -- no, framing error
|
RxFErr <= '1'; -- no, framing error
|
end if;
|
end if;
|
if RxReady = '1' then -- Has previous data been read ?
|
if RxReady = '1' then -- Has previous data been read ?
|
RxOErr <= '1'; -- no, overrun error
|
RxOErr <= '1'; -- no, overrun error
|
else
|
else
|
RxOErr <= '0'; -- yes, no over run error
|
RxOErr <= '0'; -- yes, no over run error
|
end if;
|
end if;
|
RxState <= RxStart_state;
|
RxState <= RxStart_state;
|
|
|
when others =>
|
when others =>
|
RxAck <= '0'; -- Flag Receive Complete
|
RxAck <= '0'; -- Flag Receive Complete
|
RxState <= RxStart_state;
|
RxState <= RxStart_state;
|
end case; -- RxState
|
end case; -- RxState
|
|
|
end if; -- RxBdEdge
|
end if; -- RxBdEdge
|
end if; -- clk / RxRst
|
end if; -- clk / RxRst
|
|
|
end process;
|
end process;
|
|
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Receiver Read process
|
-- Receiver Read process
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- acia_rx_read : process(Clk, RxRst, RxRd, RxReq, RxAck, RxReady )
|
-- acia_rx_read : process(Clk, RxRst, RxRd, RxReq, RxAck, RxReady )
|
acia_rx_read : process( RxRst, Clk, RxReady )
|
acia_rx_read : process( RxRst, Clk, RxReady )
|
begin
|
begin
|
if RxRst = '1' then
|
if RxRst = '1' then
|
RxReady <= '0';
|
RxReady <= '0';
|
RxReq <= '0';
|
RxReq <= '0';
|
elsif Clk'event and Clk='0' then
|
elsif Clk'event and Clk='0' then
|
if RxRd = '1' then
|
if RxRd = '1' then
|
-- Data was read, Reset data ready
|
-- Data was read, Reset data ready
|
-- Request more data
|
-- Request more data
|
RxReady <= '0';
|
RxReady <= '0';
|
RxReq <= '1';
|
RxReq <= '1';
|
else
|
else
|
if RxReq = '1' and RxAck = '1' then
|
if RxReq = '1' and RxAck = '1' then
|
-- Data is being received
|
-- Data is being received
|
-- reset receive request
|
-- reset receive request
|
RxReq <= '0';
|
RxReq <= '0';
|
else
|
else
|
-- Data now received
|
-- Data now received
|
-- Flag RxReady and read Shift Register
|
-- Flag RxReady and read Shift Register
|
if RxReq = '0' and RxAck = '0' then
|
if RxReq = '0' and RxAck = '0' then
|
RxReady <= '1';
|
RxReady <= '1';
|
end if;
|
end if;
|
end if; -- RxReq
|
end if; -- RxReq
|
end if; -- RxRd
|
end if; -- RxRd
|
end if; -- clk / RxRst
|
end if; -- clk / RxRst
|
RxRdy <= RxReady;
|
RxRdy <= RxReady;
|
end process;
|
end process;
|
|
|
|
|