URL
https://opencores.org/ocsvn/System09/System09/trunk
Subversion Repositories System09
Compare Revisions
- This comparison shows the changes necessary to convert path
/System09/trunk/rtl
- from Rev 137 to Rev 138
- ↔ Reverse comparison
Rev 137 → Rev 138
/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. |
----------------------------------------------------------------------------- |
|
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; |
|
----------------------------------------------------------------------------- |
-- 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 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; |