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

Subversion Repositories System09

[/] [System09/] [tags/] [V10/] [rtl/] [vhdl/] [rxunit2.vhd] - Rev 201

Go to most recent revision | 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      : rxunit2.vhd
--
-- Purpose        : Implements an miniUART device for communication purposes 
--                  between the cpu68 cpu and the Host computer through
--                  an RS-232 communication protocol.
--                  
-- Dependencies   : ieee.std_logic_1164.all;
--                  ieee.numeric_std.all;
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version   Author                 Date                        Changes
--
-- 0.1      Ovidiu Lupas     15 January 2000                   New model
-- 2.0      Ovidiu Lupas     17 April   2000  samples counter cleared for bit 0
--        olupas@opencores.org
--
-- 3.0      John Kent         5 January 2003     Added 6850 word format control
-- 3.1      John Kent        12 January 2003     Significantly revamped receive code.
-- 3.3      John Kent        6  September 2003   Changed Clock Edge.
--        dilbert57@opencores.org
-------------------------------------------------------------------------------
-- Description    : Implements the receive unit of the miniUART core. Samples
--                  16 times the RxD line and retain the value in the middle of
--                  the time interval. 
library ieee;
   use ieee.std_logic_1164.all;
   use ieee.std_logic_unsigned.all;
 
-------------------------------------------------------------------------------
-- Receive unit
-------------------------------------------------------------------------------
entity RxUnit is
  port (
     Clk    : in  Std_Logic;  -- system clock signal
     Reset  : in  Std_Logic;  -- Reset input
     Enable : in  Std_Logic;  -- Enable input
     RxD    : in  Std_Logic;  -- RS-232 data input
     ReadD  : in  Std_Logic;  -- Read data signal
	  Format : in  Std_Logic_Vector(2 downto 0);
     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; --================== End of entity ==============================--
-------------------------------------------------------------------------------
-- Architecture for receive Unit
-------------------------------------------------------------------------------
architecture Behaviour of RxUnit is
  -----------------------------------------------------------------------------
  -- Signals
  -----------------------------------------------------------------------------
  signal RxStart    : Std_Logic;             -- Start Receive Request
  signal RxFinish   : Std_Logic;             -- Receive finished
  signal RxValid    : Std_Logic;             -- Receive data valid
  signal RxFalse    : Std_Logic;             -- False start flag
  signal tmpRxD     : Std_Logic;             -- RxD buffer
  signal tmpRxC     : Std_Logic;             -- Rx clock
  signal tmpDRdy    : Std_Logic;             -- Data Ready flag
  signal tmpRxVal   : Std_Logic;             -- Rx Data Valid
  signal tmpRxFin   : Std_Logic;             -- Rx Finish
  signal outErr     : Std_Logic;             -- Over run error bit
  signal frameErr   : Std_Logic;             -- Framing error bit
  signal ParityErr  : Std_Logic;             -- Parity Error Bit
  signal RxParity   : Std_Logic;             -- Calculated RX parity bit
  signal RxState    : Std_Logic_Vector(3 downto 0);  -- receive bit state
  signal SampleCnt  : Std_Logic_Vector(3 downto 0);  -- samples on one bit counter
  signal ShtReg     : Std_Logic_Vector(7 downto 0);  -- Shift Register
  signal DataOut    : Std_Logic_Vector(7 downto 0);  -- Data Output register
 
  constant CntOne    : Std_Logic_Vector(3 downto 0):= "0001";
  constant CntZero   : Std_Logic_Vector(3 downto 0):= "0000";
 
begin
  ---------------------------------------------------------------------
  -- Receiver Read process
  ---------------------------------------------------------------------
  RcvRead : process(Clk, Reset, ReadD, RxValid, tmpRxVal, tmpDRdy )
  begin
    if Clk'event and Clk='0' then
      if Reset = '1' then
        tmpDRdy   <= '0';
		  tmpRxVal  <= '0';
      else
        if ReadD = '1' then
          tmpDRdy  <= '0';              -- Data was read
			 tmpRxVal <= tmpRxVal;
		  else
		    if RxValid = '1' and tmpRxVal = '0' then
			   tmpDRdy  <= '1';            -- Data was received
				tmpRxVal <= '1';
			 else
		      tmpDRdy <= tmpDRdy;
			   if RxValid = '0' and tmpRxVal = '1' then
			     tmpRxVal  <= '0';
			   else
			     tmpRxVal  <= tmpRxVal;
				end if;
			 end if; -- RxValid
        end if; -- ReadD
      end if; -- reset
    end if; -- clk
  end process;
 
  ---------------------------------------------------------------------
  -- Receiver Synchronisation process
  ---------------------------------------------------------------------
  RcvSync : process(Clk, Reset, Enable, RxStart, RxFalse, RxFinish, RxD, SampleCnt )
		variable CntIni   : Std_Logic_Vector(3 downto 0);
		variable CntAdd   : Std_Logic_Vector(3 downto 0);
  begin
    if Clk'event and Clk='0' then
      if Reset = '1' then
		  RxStart   <= '0';
        SampleCnt <= "0000";
		  CntIni    := SampleCnt;
		  CntAdd    := CntZero;
      else
        if Enable = '1' then
          if RxFinish = '1' and RxStart = '0' then    -- Are we looking for a start bit ?
            if RxD = '0' then                         -- yes, look for Start Edge 
              RxStart   <= '1';                       -- we have a start edge
		        CntIni    := CntZero;
		        CntAdd    := CntZero;
			   else
				  RxStart   <= '0';                       -- no start, spin sample count
		        CntIni    := SampleCnt;
		        CntAdd    := CntOne;
            end if;
          else
			   if RxFinish = '0' and RxStart = '1' then  -- have we received a start bit ?
			     RxStart <= '0';                         -- yes, reset start request
				else
				  if RxFalse = '1' and RxStart = '1' then -- false start ?
				    RxStart <= '0';                       -- yep, reset start request
              else
			       RxStart <= RxStart;
				  end if;
				end if;
		      CntIni    := SampleCnt;
		      CntAdd    := CntOne;
			 end if; -- RxStart
		  else
		    CntIni    := SampleCnt;
		    CntAdd    := CntZero;
          RxStart   <= RxStart;
        end if; -- enable
      end if; -- reset
		SampleCnt <= CntIni + CntAdd;
    end if; -- clk
  end process;
 
 
  ---------------------------------------------------------------------
  -- Receiver Clock process
  ---------------------------------------------------------------------
  RcvClock : process(Clk, Reset, SampleCnt, RxD, tmpRxD )
  begin
    if Clk'event and Clk='0' then
      if Reset = '1' then
		  tmpRxC    <= '0';
		  tmpRxD    <= '1';
      else
		  if SampleCnt = "1000" then
			 tmpRxD <= RxD;
		  else
			 tmpRxD <= tmpRxD;
 		  end if;
 
		  if SampleCnt = "1111" then
			 tmpRxC <= '1';
		  else
			 tmpRxC <= '0';
 		  end if;
      end if; -- reset
    end if; -- clk
  end process;
 
  ---------------------------------------------------------------------
  -- Receiver process
  ---------------------------------------------------------------------
  RcvProc : process(Clk, Reset, RxState, tmpRxC, Enable, tmpRxD, RxStart,
  				frameErr, outErr, DataOut, tmpDRdy,
			   ShtReg, RxParity, parityErr, Format,
				RxValid, RxFalse, RxFinish
			 )
  begin
    if Clk'event and Clk='0' then
      if Reset = '1' then
        frameErr  <= '0';
        outErr    <= '0';
		  parityErr <= '0';
 
        ShtReg    <= "00000000";  -- Shift register
		  RxParity  <= '0';         -- Parity bit
		  RxFinish  <= '1';         -- Data RX finish flag
		  RxValid   <= '0';         -- Data RX data valid flag
		  RxFalse   <= '0';
        RxState   <= "1111";
		  DataOut   <= "00000000";
      else
        if tmpRxC = '1' and Enable = '1' then
          case RxState is
          when "0000" | "0001" | "0010" | "0011" |
					"0100" | "0101" | "0110" => -- data bits 0 to 6
            ShtReg    <= tmpRxD & ShtReg(7 downto 1);
			   RxParity  <= RxParity xor tmpRxD;
				parityErr <= parityErr;
				frameErr  <= frameErr;
				outErr    <= outErr;
				RxValid   <= '0';   
				DataOut   <= DataOut;
		      RxFalse   <= '0';
            RxFinish  <= '0';
				if RxState = "0110" then
 			     if Format(2) = '0' then
                RxState <= "1000";          -- 7 data + parity
			     else
                RxState <= "0111";          -- 8 data bits
				  end if; -- Format(2)
				else
              RxState   <= RxState + CntOne;
				end if; -- RxState
          when "0111" =>                 -- data bit 7
            ShtReg    <= tmpRxD & ShtReg(7 downto 1);
			   RxParity  <= RxParity xor tmpRxD;
				parityErr <= parityErr;
				frameErr  <= frameErr;
				outErr    <= outErr;
				RxValid   <= '0';   
				DataOut   <= DataOut;
		      RxFalse   <= '0';
            RxFinish  <= '0';
			   if Format(1) = '1' then      -- parity bit ?
              RxState <= "1000";         -- yes, go to parity
				else
              RxState <= "1001";         -- no, must be 2 stop bit bits
			   end if;
	       when "1000" =>                 -- parity bit
			   if Format(2) = '0' then
              ShtReg <= tmpRxD & ShtReg(7 downto 1); -- 7 data + parity
				else
				  ShtReg <= ShtReg;          -- 8 data + parity
				end if;
				RxParity <= RxParity;
				if Format(0) = '0' then      -- parity polarity ?
				  if RxParity = tmpRxD then  -- check even parity
					  parityErr <= '1';
				  else
					  parityErr <= '0';
				  end if;
				else
				  if RxParity = tmpRxD then  -- check for odd parity
					  parityErr <= '0';
				  else
					  parityErr <= '1';
				  end if;
				end if;
				frameErr  <= frameErr;
				outErr    <= outErr;
				RxValid   <= '0';   
				DataOut   <= DataOut;
		      RxFalse   <= '0';
            RxFinish  <= '0';
            RxState   <= "1001";
          when "1001" =>                 -- stop bit (Only one required for RX)
			   ShtReg    <= ShtReg;
				RxParity  <= RxParity;
				parityErr <= parityErr;
            if tmpRxD = '1' then         -- stop bit expected
              frameErr <= '0';           -- yes, no framing error
            else
              frameErr <= '1';           -- no, framing error
            end if;
            if tmpDRdy = '1' then        -- Has previous data been read ? 
              outErr <= '1';             -- no, overrun error
            else
              outErr <= '0';             -- yes, no over run error
            end if;
				RxValid   <= '1';   
				DataOut   <= ShtReg;
		      RxFalse   <= '0';
            RxFinish  <= '1';
            RxState   <= "1111";
          when others =>                 -- this is the idle state
            ShtReg    <= ShtReg;
			   RxParity  <= RxParity;
				parityErr <= parityErr;
				frameErr  <= frameErr;
				outErr    <= outErr;
				RxValid   <= '0';   
				DataOut   <= DataOut;
			   if RxStart = '1' and tmpRxD = '0' then  -- look for start request
		        RxFalse   <= '0';
              RxFinish <= '0';
              RxState  <= "0000"; -- yes, read data
			   else
				  if RxStart = '1' and tmpRxD = '1' then -- start request, but no start bit
				  	 RxFalse   <= '1';
              else
				    RxFalse   <= '0';
				  end if;
			     RxFinish  <= '1';
				  RxState <= "1111";    -- otherwise idle
			   end if;
          end case; -- RxState
		  else
            ShtReg    <= ShtReg;
			   RxParity  <= RxParity;
				parityErr <= parityErr;
				frameErr  <= frameErr;
				outErr    <= outErr;
				RxValid   <= RxValid;   
				DataOut   <= DataOut;
		      RxFalse   <= RxFalse;
			   RxFinish  <= RxFinish;
				RxState   <= RxState;
        end if; -- tmpRxC
      end if; -- reset
    end if; -- clk
  end process;
 
  DARdy <= tmpDRdy;
  DAOut <= DataOut;
  FRErr <= frameErr;
  ORErr <= outErr;
  PAErr <= parityErr;
 
end Behaviour; --==================== End of architecture ====================--

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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