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

Subversion Repositories System09

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /System09
    from Rev 138 to Rev 137
    Reverse comparison

Rev 138 → Rev 137

/trunk/rtl/VHDL/acia6850.vhd
1,32 → 1,32
--===========================================================================--
-- --
-- Synthesizable 6850 compatible ACIA --
-- --
--===========================================================================--
--===========================================================================--
-- --
-- Synthesizable 6850 compatible ACIA --
-- --
--===========================================================================--
--
-- File name : acia6850.vhd
--
--
-- Entity name : acia6850
--
-- Purpose : Implements a RS232 6850 compatible
-- Purpose : Implements a RS232 6850 compatible
-- Asynchronous Communications Interface Adapter (ACIA)
--
-- Dependencies : ieee.std_logic_1164
-- ieee.numeric_std
-- ieee.numeric_std
-- ieee.std_logic_unsigned
--
-- Author : John E. Kent
--
-- Email : dilbert57@opencores.org
--
-- Web : http://opencores.org/project,system09
--
--
-- Author : John E. Kent
--
-- Email : dilbert57@opencores.org
--
-- Web : http://opencores.org/project,system09
--
-- Origins : miniUART written by Ovidiu Lupas olupas@opencores.org
--
-- Registers :
--
-- IO address + 0 Read - Status Register
--
--
-- Registers :
--
-- IO address + 0 Read - Status Register
--
-- Bit[7] - Interrupt Request Flag
-- Bit[6] - Receive Parity Error (parity bit does not match)
-- Bit[5] - Receive Overrun Error (new character received before last read)
37,15 → 37,15
-- Bit[0] - Receive Data Ready (character received)
--
-- IO address + 0 Write - Control Register
--
--
-- Bit[7] - Rx Interupt Enable
-- 0 - disabled
-- 1 - enabled
-- Bits[6..5] - Transmit Control
-- Bits[6..5] - Transmit Control
-- 0 0 - TX interrupt disabled, RTS asserted
-- 0 1 - TX interrupt enabled, RTS asserted
-- 1 0 - TX interrupt disabled, RTS cleared
-- 1 1 - TX interrupt disabled, RTS asserted, Send Break
-- 0 1 - TX interrupt enabled, RTS asserted
-- 1 0 - TX interrupt disabled, RTS cleared
-- 1 1 - TX interrupt disabled, RTS asserted, Send Break
-- Bits[4..2] - Word Control
-- 0 0 0 - 7 data, even parity, 2 stop
-- 0 0 1 - 7 data, odd parity, 2 stop
60,44 → 60,44
-- 0 1 - Baud Clk divide by 16
-- 1 0 - Baud Clk divide by 64
-- 1 1 - Reset
--
-- IO address + 1 Read - Receive Data Register
--
-- Read when Receive Data Ready bit set
-- Read resets Receive Data Ready bit
--
-- IO address + 1 Write - Transmit Data Register
--
-- Write when Transmit Buffer Empty bit set
-- Write resets Transmit Buffer Empty Bit
--
--
-- Copyright (C) 2002 - 2010 John Kent
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
--===========================================================================--
--
-- IO address + 1 Read - Receive Data Register
--
-- Read when Receive Data Ready bit set
-- Read resets Receive Data Ready bit
--
-- IO address + 1 Write - Transmit Data Register
--
-- Write when Transmit Buffer Empty bit set
-- Write resets Transmit Buffer Empty Bit
--
--
-- Copyright (C) 2002 - 2010 John Kent
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
--===========================================================================--
-- --
-- Revision History --
-- Revision History --
-- --
--===========================================================================--
--
--===========================================================================--
--
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 2000-01-15 New model
-- 1.0 Ovidiu Lupas 2000-01 Synthesis optimizations
-- 2.0 Ovidiu Lupas 2000-04 Bugs removed - the RSBusCtrl did not
-- 2.0 Ovidiu Lupas 2000-04 Bugs removed - the RSBusCtrl did not
-- process all possible situations
--
-- 3.0 John Kent 2002-10 Changed Status bits to match MC6805
108,7 → 108,7
-- TX / RX Baud Clock now external
-- also supports x1 clock and DCD.
-- 3.4 John Kent 2005-09-13 Removed LoadCS signal.
-- Fixed ReadCS and Read
-- Fixed ReadCS and Read
-- in miniuart_DCD_Init process
-- 3.5 John Kent 2006-11-28 Cleaned up code.
--
116,14 → 116,14
-- 4.1 John Kent 2007-02-06 Made software reset synchronous
-- 4.2 John Kent 2007-02-25 Changed sensitivity lists
-- Rearranged Reset process.
-- 4.3 John Kent 2010-06-17 Updated header
-- 4.4 John Kent 2010-08-27 Combined with ACIA_RX & ACIA_TX
-- Renamed to acia6850
--
 
-- 4.3 John Kent 2010-06-17 Updated header
-- 4.4 John Kent 2010-08-27 Combined with ACIA_RX & ACIA_TX
-- Renamed to acia6850
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
--library unisim;
-- use unisim.vcomponents.all;
143,8 → 143,8
addr : in std_logic; -- Register Select
rw : in std_logic; -- Read / Not Write
data_in : in std_logic_vector(7 downto 0); -- Data Bus In
data_out : out std_logic_vector(7 downto 0); -- Data Bus Out
irq : out std_logic; -- Interrupt Request out
data_out : out std_logic_vector(7 downto 0); -- Data Bus Out
irq : out std_logic; -- Interrupt Request out
--
-- RS232 Interface Signals
--
169,9 → 169,9
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
--
-- Reset signals
--
--
-- Reset signals
--
signal ac_rst : std_logic; -- Reset (Software & Hardware)
signal rx_rst : std_logic; -- Receive Reset (Software & Hardware)
signal tx_rst : std_logic; -- Transmit Reset (Software & Hardware)
181,10 → 181,10
----------------------------------------------------------------------
--
-- IO address + 0 Read
--
--
-----------+--------+-------+--------+--------+--------+--------+--------+
-- Irq | PErr | OErr | FErr | CTS | DCD | TxRdy | RxRdy |
-----------+--------+-------+--------+--------+--------+--------+--------+
-----------+--------+-------+--------+--------+--------+--------+--------+
--
-- Irq - Bit[7] - Interrupt request
-- PErr - Bit[6] - Receive Parity error (parity bit does not match)
195,7 → 195,7
-- TxRdy - Bit[1] - Transmit Buffer Empty (ready to accept next transmit character)
-- RxRdy - Bit[0] - Receive Data Ready (character received)
--
 
 
signal StatReg : std_logic_vector(7 downto 0) := (others => '0'); -- status register
 
----------------------------------------------------------------------
203,7 → 203,7
----------------------------------------------------------------------
--
-- IO address + 0 Write
--
--
-----------+--------+--------+--------+--------+--------+--------+--------+
-- RxIE |TxCtl(1)|TxCtl(0)|WdFmt(2)|WdFmt(1)|WdFmt(0)|BdCtl(1)|BdCtl(0)|
-----------+--------+--------+--------+--------+--------+--------+--------+
236,7 → 236,7
-- IO address + 1 Read
--
signal RxReg : std_logic_vector(7 downto 0) := (others => '0');
 
 
----------------------------------------------------------------------
-- Transmit Register
----------------------------------------------------------------------
257,7 → 257,7
signal RxIE : std_logic := '0'; -- Receive interrupt enable
--
signal RxRd : std_logic := '0'; -- Read receive buffer
signal TxWr : std_logic := '0'; -- Write Transmit buffer
signal TxWr : std_logic := '0'; -- Write Transmit buffer
signal StRd : std_logic := '0'; -- Read status register
--
signal DCDState : DCD_State_Type; -- DCD Reset state sequencer
273,14 → 273,14
-----------------------------------------------------------------------------
 
type RxStateType is ( RxState_Wait, RxState_Data, RxState_Parity, RxState_Stop );
 
 
signal RxState : RxStateType; -- receive bit state
 
 
signal RxDatDel0 : Std_Logic := '0'; -- Delayed Rx Data
signal RxDatDel1 : Std_Logic := '0'; -- Delayed Rx Data
signal RxDatDel2 : Std_Logic := '0'; -- Delayed Rx Data
signal RxDatEdge : Std_Logic := '0'; -- Rx Data Edge pulse
 
 
signal RxClkDel : Std_Logic := '0'; -- Delayed Rx Input Clock
signal RxClkEdge : Std_Logic := '0'; -- Rx Input Clock Edge pulse
signal RxStart : Std_Logic := '0'; -- Rx Start request
301,13 → 301,13
type TxStateType is ( TxState_Idle, TxState_Start, TxState_Data, TxState_Parity, TxState_Stop );
 
signal TxState : TxStateType; -- Transmitter state
 
 
signal TxClkDel : Std_Logic := '0'; -- Delayed Tx Input Clock
signal TxClkEdge : Std_Logic := '0'; -- Tx Input Clock Edge pulse
signal TxClkCnt : Std_Logic_Vector(5 downto 0) := (others => '0'); -- Tx Baud Clock Counter
signal TxBdClk : Std_Logic := '0'; -- Tx Baud Clock
signal TxBdDel : Std_Logic := '0'; -- Delayed Tx Baud Clock
 
 
signal TxReq : std_logic := '0'; -- Request transmit start
signal TxAck : std_logic := '0'; -- Acknowledge transmit start
signal TxParity : Std_logic := '0'; -- Parity Bit
320,60 → 320,60
-- ACIA Reset may be hardware or software
---------------------------------------------------------------
acia_reset : process( clk, rst, ac_rst, dcd_n )
begin
begin
--
-- ACIA reset Synchronous
-- Includes software reset
-- ACIA reset Synchronous
-- Includes software reset
--
if falling_edge(clk) then
ac_rst <= (CtrlReg(1) and CtrlReg(0)) or rst;
end if;
-- Receiver reset
rx_rst <= ac_rst or DCD_n;
rx_rst <= ac_rst or DCD_n;
-- Transmitter reset
tx_rst <= ac_rst;
 
end process;
 
-----------------------------------------------------------------------------
-- Generate Read / Write strobes.
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Generate Read / Write strobes.
-----------------------------------------------------------------------------
 
acia_read_write : process(clk, ac_rst)
begin
if falling_edge(clk) then
if rst = '1' then
CtrlReg(1 downto 0) <= "11";
CtrlReg(7 downto 2) <= (others => '0');
TxReg <= (others => '0');
RxRd <= '0';
TxWr <= '0';
StRd <= '0';
else
RxRd <= '0';
TxWr <= '0';
StRd <= '0';
if cs = '1' then
if Addr = '0' then -- Control / Status register
if rw = '0' then -- write control register
CtrlReg <= data_in;
else -- read status register
StRd <= '1';
end if;
else -- Data Register
if rw = '0' then -- write transmiter register
TxReg <= data_in;
TxWr <= '1';
else -- read receiver register
RxRd <= '1';
end if;
end if;
end if;
end if;
end if;
end process;
 
acia_read_write : process(clk, ac_rst)
begin
if falling_edge(clk) then
if rst = '1' then
CtrlReg(1 downto 0) <= "11";
CtrlReg(7 downto 2) <= (others => '0');
TxReg <= (others => '0');
RxRd <= '0';
TxWr <= '0';
StRd <= '0';
else
RxRd <= '0';
TxWr <= '0';
StRd <= '0';
if cs = '1' then
if Addr = '0' then -- Control / Status register
if rw = '0' then -- write control register
CtrlReg <= data_in;
else -- read status register
StRd <= '1';
end if;
else -- Data Register
if rw = '0' then -- write transmiter register
TxReg <= data_in;
TxWr <= '1';
else -- read receiver register
RxRd <= '1';
end if;
end if;
end if;
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- ACIA Status Register
-----------------------------------------------------------------------------
390,8 → 390,8
StatReg(6) <= PErr; -- Parity error
StatReg(7) <= (RxIE and RxRdy) or
(RxIE and DCDInt) or
(TxIE and TxRdy);
end if;
(TxIE and TxRdy);
end if;
end process;
 
 
416,15 → 416,15
RTS_n <= '1';
when "11" => -- Disable Tx interrupts, Assert RTS, send break
TxD <= '0';
TxIE <= '0';
TxIE <= '0';
RTS_n <= '0';
when others =>
null;
end case;
 
RxIE <= CtrlReg(7);
RxIE <= CtrlReg(7);
WdFmt <= CtrlReg(4 downto 2);
BdFmt <= CtrlReg(1 downto 0);
BdFmt <= CtrlReg(1 downto 0);
end process;
 
---------------------------------------------------------------
451,9 → 451,9
if ac_rst = '1' then
DCDDel <= '0';
DCDEdge <= '0';
else
else
DCDDel <= DCD_n;
DCDEdge <= DCD_n and (not DCDDel);
DCDEdge <= DCD_n and (not DCDDel);
end if;
end if;
end process;
472,7 → 472,7
if ac_rst = '1' then
DCDInt <= '0';
DCDState <= DCD_State_Idle;
else
else
case DCDState is
when DCD_State_Idle =>
-- DCD Edge activates interrupt
494,12 → 494,12
end if;
when others =>
null;
end case;
end case;
end if;
end if;
end process;
 
 
 
---------------------------------------------------------------------
-- Receiver Clock Edge Detection
---------------------------------------------------------------------
510,10 → 510,10
if falling_edge(clk) then
if rx_rst = '1' then
RxClkDel <= '0';
RxClkEdge <= '0';
RxClkEdge <= '0';
else
RxClkDel <= RxC;
RxClkEdge <= (not RxClkDel) and RxC;
RxClkEdge <= (not RxClkDel) and RxC;
end if;
end if;
end process;
525,7 → 525,7
--
acia_rx_data_edge : process( clk, rx_rst )
begin
if falling_edge(clk) then
if falling_edge(clk) then
if rx_rst = '1' then
RxDatDel0 <= '0';
RxDatDel1 <= '0';
535,7 → 535,7
RxDatDel0 <= RxD;
RxDatDel1 <= RxDatDel0;
RxDatDel2 <= RxDatDel1;
RxDatEdge <= RxDatDel0 and (not RxD);
RxDatEdge <= RxDatDel0 and (not RxD);
end if;
end if;
end process;
548,13 → 548,13
--
acia_rx_start_stop : process( clk, rx_rst )
begin
if falling_edge(clk) then
if falling_edge(clk) then
if rx_rst = '1' then
RxEnable <= '0';
RxStart <= '0';
elsif (RxEnable = '0') and (RxDatEdge = '1') then
-- Data Edge detected
RxStart <= '1'; -- Request Start and
RxStart <= '1'; -- Request Start and
RxEnable <= '1'; -- Enable Receive Clock
elsif (RxStart = '1') and (RxAck = '1') then
-- Data is being received
579,10 → 579,10
RxClkCnt <= (others => '0');
elsif RxDatEdge = '1' then
-- reset on falling data edge
RxClkCnt <= (others => '0');
elsif RxClkEdge = '1' then
RxClkCnt <= (others => '0');
elsif RxClkEdge = '1' then
-- increment count on Clock edge
RxClkCnt <= RxClkCnt + "000001";
RxClkCnt <= RxClkCnt + "000001";
end if;
end if;
end process;
624,7 → 624,7
-- 1 1 1 - 8 data, odd parity, 1 stop
acia_rx_receive : process( clk, rst )
begin
if falling_edge( clk ) then
if falling_edge( clk ) then
if rx_rst = '1' then
FErr <= '0';
OErr <= '0';
634,7 → 634,7
RxParity <= '0'; -- reset Parity bit
RxAck <= '0'; -- Receiving data
RxBitCount <= (others => '0');
RxState <= RxState_Wait;
RxState <= RxState_Wait;
else
RxBdDel <= RxBdClk;
if RxBdDel = '0' and RxBdClk = '1' then
671,7 → 671,7
if WdFmt(2) = '0' then -- if 7 data bits, shift parity into MSB
RxShiftReg <= RxDatDel2 & RxShiftReg(7 downto 1); -- 7 data + parity
end if;
if RxParity = (RxDatDel2 xor WdFmt(0)) then
if RxParity = (RxDatDel2 xor WdFmt(0)) then
PErr <= '1'; -- If parity not the same flag error
else
PErr <= '0';
711,8 → 711,8
if falling_edge(clk) then
if rx_rst = '1' then
RxRdy <= '0';
RxReq <= '0';
elsif RxRd = '1' then
RxReq <= '0';
elsif RxRd = '1' then
-- Data was read,
RxRdy <= '0'; -- Reset receive full
RxReq <= '1'; -- Request more data
723,10 → 723,10
-- Data now received
RxRdy <= '1'; -- Flag RxRdy and read Shift Register
end if;
end if;
end if;
end process;
 
 
 
---------------------------------------------------------------------
-- Transmit Clock Edge Detection
-- A falling edge will produce a one clock cycle pulse
737,10 → 737,10
if falling_edge(clk) then
if tx_rst = '1' then
TxClkDel <= '0';
TxClkEdge <= '0';
TxClkEdge <= '0';
else
TxClkDel <= TxC;
TxClkEdge <= TxClkDel and (not TxC);
TxClkEdge <= TxClkDel and (not TxC);
end if;
end if;
end process;
804,7 → 804,7
TxParity <= '0';
TxBitCount <= (others=>'0');
TxAck <= '0';
TxState <= TxState_Idle;
TxState <= TxState_Idle;
else
 
TxBdDel <= TxBdClk;
814,7 → 814,7
case TxState is
when TxState_Idle =>
TxDat <= '1';
if TxReq = '1' then
if TxReq = '1' then
TxShiftReg <= TxReg; -- Load Shift reg with Tx Data
TxAck <= '1';
TxState <= TxState_Start;
845,7 → 845,7
end if;
else
TxState <= TxState_Parity; -- parity
end if;
end if;
end if;
 
when TxState_Parity => -- 7/8 data + parity bit
856,22 → 856,22
end if;
if WdFmt(1) = '0' then
TxState <= TxState_Stop; -- 2 stops
else
else
TxAck <= '0';
TxState <= TxState_Idle; -- 1 stop
end if;
 
when TxState_Stop => -- first of two stop bits
TxDat <= '1';
TxDat <= '1';
TxAck <= '0';
TxState <= TxState_Idle;
 
end case;
end case;
end if;
end if;
end if;
end process;
 
 
---------------------------------------------------------------------
-- Transmitter Write process
---------------------------------------------------------------------
881,8 → 881,8
if falling_edge(clk) then
if tx_rst = '1' then
TxRdy <= '0';
TxReq <= '0';
elsif TxWr = '1' then
TxReq <= '0';
elsif TxWr = '1' then
-- Data was read,
TxRdy <= '0'; -- Reset transmit empty
TxReq <= '1'; -- Request data transmit
891,7 → 891,7
elsif TxReq = '0' and TxAck = '0' then -- Data transmitted
TxRdy <= '1'; -- Flag TxRdy
end if;
end if;
end if;
end process;
 
end rtl;

powered by: WebSVN 2.1.0

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