URL
https://opencores.org/ocsvn/System68/System68/trunk
Subversion Repositories System68
[/] [System68/] [trunk/] [vhdl/] [miniUART3.vhd] - Rev 8
Compare with Previous | Blame | View Log
--===========================================================================-- -- -- S Y N T H E Z I A B L E miniUART C O R E -- -- www.OpenCores.Org - January 2000 -- This core adheres to the GNU public license -- -- Design units : miniUART core for the System68 -- -- File name : miniuart2.vhd -- -- Purpose : Implements an miniUART device for communication purposes -- between the CPU68 processor and the Host computer through -- an RS-232 communication protocol. -- -- Dependencies : ieee.std_logic_1164 -- ieee.numeric_std -- --===========================================================================-- ------------------------------------------------------------------------------- -- Revision list -- Version Author Date Changes -- -- 0.1 Ovidiu Lupas 15 January 2000 New model -- 1.0 Ovidiu Lupas January 2000 Synthesis optimizations -- 2.0 Ovidiu Lupas April 2000 Bugs removed - RSBusCtrl -- the RSBusCtrl did not process all possible situations -- -- olupas@opencores.org -- -- 3.0 John Kent October 2002 Changed Status bits to match mc6805 -- Added CTS, RTS, Baud rate control -- & Software Reset -- 3.1 John Kent 5 January 2003 Added Word Format control a'la mc6850 -- 3.2 John Kent 19 July 2003 Latched Data input to UART -- 3.3 John Kent 16 January 2004 Integrated clkunit in rxunit & txunit -- Now has external TX 7 RX Baud Clock -- inputs like the MC6850... -- also supports x1 clock and DCD. -- -- dilbert57@opencores.org -- ------------------------------------------------------------------------------- -- Entity for miniUART Unit - 9600 baudrate -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity miniUART is port ( -- -- CPU signals -- clk : in Std_Logic; -- System Clock rst : in Std_Logic; -- Reset input (active high) cs : in Std_Logic; -- miniUART Chip Select rw : in Std_Logic; -- Read / Not Write irq : out Std_Logic; -- Interrupt Addr : in Std_Logic; -- Register Select DataIn : in Std_Logic_Vector(7 downto 0); -- Data Bus In DataOut : out Std_Logic_Vector(7 downto 0); -- Data Bus Out -- -- Uart Signals -- RxC : in Std_Logic; -- Receive Baud Clock TxC : in Std_Logic; -- Transmit Baud Clock RxD : in Std_Logic; -- Receive Data TxD : out Std_Logic; -- Transmit Data DCD_n : in Std_Logic; -- Data Carrier Detect CTS_n : in Std_Logic; -- Clear To Send RTS_n : out Std_Logic ); -- Request To send end; --================== End of entity ==============================-- ------------------------------------------------------------------------------- -- Architecture for miniUART Controller Unit ------------------------------------------------------------------------------- architecture uart of miniUART is ----------------------------------------------------------------------------- -- Signals ----------------------------------------------------------------------------- signal RxData : Std_Logic_Vector(7 downto 0); -- signal TxData : Std_Logic_Vector(7 downto 0); -- signal StatReg : Std_Logic_Vector(7 downto 0); -- status register -- StatReg detailed -----------+--------+--------+--------+--------+--------+--------+--------+ -- Irq | PErr | ORErr | FErr | CTS | DCD | TBufE | DRdy | -----------+--------+--------+--------+--------+--------+--------+--------+ signal CtrlReg : Std_Logic_Vector(7 downto 0); -- control register -- CtrlReg detailed -----------+--------+--------+--------+--------+--------+--------+--------+ -- RxIEnb |TxCtl(1)|TxCtl(0)|WdFmt(2)|WdFmt(1)|WdFmt(0)|BdCtl(1)|BdCtl(0)| -----------+--------+--------+--------+--------+--------+--------+--------+ -- RxIEnb -- 0 - Rx Interrupt disabled -- 1 - Rx Interrupt enabled -- TxCtl -- 0 1 - Tx Interrupt Enable -- 1 0 - RTS high -- WdFmt -- 0 0 0 - 7 data, even parity, 2 stop -- 0 0 1 - 7 data, odd parity, 2 stop -- 0 1 0 - 7 data, even parity, 1 stop -- 0 1 1 - 7 data, odd parity, 1 stop -- 1 0 0 - 8 data, no parity, 2 stop -- 1 0 1 - 8 data, no parity, 1 stop -- 1 1 0 - 8 data, even parity, 1 stop -- 1 1 1 - 8 data, odd parity, 1 stop -- BdCtl -- 0 0 - Baud Clk divide by 1 -- 0 1 - Baud Clk divide by 16 -- 1 0 - Baud Clk divide by 64 -- 1 1 - reset signal TxDbit : Std_Logic; -- Transmit data bit signal DRdy : Std_Logic; -- Receive Data ready signal TBufE : Std_Logic; -- Transmit buffer empty signal FErr : Std_Logic; -- Frame error signal OErr : Std_Logic; -- Output error signal PErr : Std_Logic; -- Parity Error signal TxIEnb : Std_Logic; -- Transmit interrupt enable signal Read : Std_Logic; -- Read receive buffer signal Load : Std_Logic; -- Load transmit buffer signal ReadCS : Std_Logic; -- Read Status register signal LoadCS : Std_Logic; -- Load Control register signal Reset : Std_Logic; -- Reset (Software & Hardware) signal RxRst : Std_Logic; -- Receive Reset (Software & Hardware) signal TxRst : Std_Logic; -- Transmit Reset (Software & Hardware) signal DCDDel : Std_Logic; -- Delayed DCD_n signal DCDEdge : Std_Logic; -- Rising DCD_N Edge Pulse signal DCDState : Std_Logic; -- DCD Reset sequencer signal DCDInt : Std_Logic; -- DCD Interrupt ----------------------------------------------------------------------------- -- Receive Unit ----------------------------------------------------------------------------- component RxUnit port ( Clk : in Std_Logic; -- Clock signal Reset : in Std_Logic; -- Reset input ReadD : in Std_Logic; -- Read data signal WdFmt : in Std_Logic_Vector(2 downto 0); -- word format BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format RxClk : in Std_Logic; -- RS-232 clock input RxDat : in Std_Logic; -- RS-232 data input FRErr : out Std_Logic; -- Status signal ORErr : out Std_Logic; -- Status signal PAErr : out Std_logic; -- Status signal DARdy : out Std_Logic; -- Status signal DAOut : out Std_Logic_Vector(7 downto 0)); end component; ----------------------------------------------------------------------------- -- Transmitter Unit ----------------------------------------------------------------------------- component TxUnit port ( Clk : in Std_Logic; -- Clock signal Reset : in Std_Logic; -- Reset input LoadD : in Std_Logic; -- Load transmit data DAIn : in Std_Logic_Vector(7 downto 0); WdFmt : in Std_Logic_Vector(2 downto 0); -- word format BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format TxClk : in Std_Logic; -- Enable input TxDat : out Std_Logic; -- RS-232 data output TBE : out Std_Logic ); -- Tx buffer empty end component; begin ----------------------------------------------------------------------------- -- Instantiation of internal components ----------------------------------------------------------------------------- RxDev : RxUnit port map ( Clk => clk, Reset => RxRst, ReadD => Read, WdFmt => CtrlReg(4 downto 2), BdFmt => CtrlReg(1 downto 0), RxClk => RxC, RxDat => RxD, FRErr => FErr, ORErr => OErr, PAErr => PErr, DARdy => DRdy, DAOut => RxData ); TxDev : TxUnit port map ( Clk => clk, Reset => TxRst, LoadD => Load, DAIn => TxData, WdFmt => CtrlReg(4 downto 2), BdFmt => CtrlReg(1 downto 0), TxClk => TxC, TxDat => TxDbit, TBE => TBufE ); ----------------------------------------------------------------------------- -- Implements the controller for Rx&Tx units ----------------------------------------------------------------------------- miniUart_Status : process(clk, Reset, CtrlReg, TxIEnb, DRdy, TBufE, DCD_n, CTS_n, DCDInt, FErr, OErr, PErr ) variable Int : Std_Logic; begin if Reset = '1' then Int := '0'; StatReg <= "00000000"; irq <= '0'; elsif clk'event and clk='0' then Int := (CtrlReg(7) and DRdy) or (CtrlReg(7) and DCDInt) or (TxIEnb and TBufE); StatReg(0) <= DRdy; -- Receive Data Ready StatReg(1) <= TBufE and (not CTS_n); -- Transmit Buffer Empty StatReg(2) <= DCDInt; -- Data Carrier Detect StatReg(3) <= CTS_n; -- Clear To Send StatReg(4) <= FErr; -- Framing error StatReg(5) <= OErr; -- Overrun error StatReg(6) <= PErr; -- Parity error StatReg(7) <= Int; irq <= Int; end if; end process; ----------------------------------------------------------------------------- -- Transmit control ----------------------------------------------------------------------------- miniUart_TxControl : process( CtrlReg, TxDbit ) begin case CtrlReg(6 downto 5) is when "00" => -- Disable TX Interrupts, Assert RTS RTS_n <= '0'; TxIEnb <= '0'; TxD <= TxDbit; when "01" => -- Enable TX interrupts, Assert RTS RTS_n <= '0'; TxIEnb <= '1'; TxD <= TxDbit; when "10" => -- Disable Tx Interrupts, Clear RTS RTS_n <= '1'; TxIEnb <= '0'; TxD <= TxDbit; when "11" => -- Disable Tx interrupts, Assert RTS, send break RTS_n <= '0'; TxIEnb <= '0'; TxD <= '0'; when others => RTS_n <= '0'; TxIEnb <= '0'; TxD <= TxDbit; end case; end process; ----------------------------------------------------------------------------- -- Write to control register ----------------------------------------------------------------------------- miniUart_Control: process(clk, Reset, cs, rw, Addr, DataIn, CtrlReg, TxData ) begin if (reset = '1') then TxData <= "00000000"; Load <= '0'; Read <= '0'; CtrlReg <= "00000000"; LoadCS <= '0'; ReadCS <= '0'; elsif clk'event and clk='0' then if cs = '1' then if Addr = '1' then -- Data Register if rw = '0' then -- write data register TxData <= DataIn; Load <= '1'; Read <= '0'; else -- read Data Register TxData <= TxData; Load <= '0'; Read <= '1'; end if; -- rw CtrlReg <= CtrlReg; LoadCS <= '0'; ReadCS <= '0'; else -- Control / Status register TxData <= TxData; Load <= '0'; Read <= '0'; if rw = '0' then -- write control register CtrlReg <= DataIn; LoadCS <= '1'; ReadCS <= '0'; else -- read status Register CtrlReg <= CtrlReg; LoadCS <= '0'; ReadCS <= '1'; end if; -- rw end if; -- Addr else -- not selected TxData <= TxData; Load <= '0'; Read <= '0'; CtrlReg <= CtrlReg; LoadCS <= '0'; ReadCS <= '0'; end if; -- cs end if; -- clk / reset end process; --------------------------------------------------------------- -- -- set data output mux -- -------------------------------------------------------------- miniUart_data_read: process(Addr, StatReg, RxData) begin if Addr = '1' then DataOut <= RxData; -- read data register else DataOut <= StatReg; -- read status register end if; -- Addr end process; --------------------------------------------------------------- -- -- Data Carrier Detect Edge rising edge detect -- --------------------------------------------------------------- miniUart_DCD_edge : process( reset, clk, DCD_n, DCDDel ) begin if reset = '1' then DCDEdge <= '0'; DCDDel <= '0'; elsif clk'event and clk = '0' then DCDDel <= DCD_n; DCDEdge <= DCD_n and (not DCDDel); end if; end process; --------------------------------------------------------------- -- -- Data Carrier Detect Interrupt -- --------------------------------------------------------------- miniUart_DCD_int : process( reset, clk, DCDEdge, DCDState, Read, ReadCS, DCDInt ) begin if reset = '1' then DCDInt <= '0'; DCDState <= '0'; elsif clk'event and clk = '0' then if DCDEdge = '1' then DCDInt <= '1'; DCDState <= '0'; elsif DCDState = '0' then -- To reset DCD interrupt, First read status if (ReadCS <= '1') and (DCDInt = '1') then DCDState <= '1'; else DCDState <= '0'; end if; DCDInt <= DCDInt; else -- DCDstate = '1' -- Then read the data register if Read <= '1' then DCDState <= '0'; DCDInt <= '0'; else DCDState <= DCDState; DCDInt <= DCDInt; end if; end if; -- DCDState end if; -- clk / reset end process; --------------------------------------------------------------- -- -- reset may be hardware or software -- --------------------------------------------------------------- miniUart_reset: process(rst, CtrlReg, Reset, DCD_n ) begin Reset <= (CtrlReg(1) and CtrlReg(0)) or rst; TxRst <= Reset; RxRst <= Reset or DCD_n; end process; end; --===================== End of architecture =======================--