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

Subversion Repositories present

[/] [present/] [trunk/] [DecodeTesting/] [rtl/] [vhdl/] [RS232RefComp.vhd] - Rev 17

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

------------------------------------------------------------------------
--  RS232RefCom.vhd
------------------------------------------------------------------------
-- Author:  Dan Pederson
--          Copyright 2004 Digilent, Inc.
------------------------------------------------------------------------
-- Description:  	This file defines a UART which tranfers data from 
--				serial form to parallel form and vice versa.			
------------------------------------------------------------------------
-- Revision History:
--  07/15/04 (Created) DanP
--	 02/25/08 (Created) ClaudiaG: made use of the baudDivide constant
--											in the Clock Dividing Processes
------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
--  Uncomment the following lines to use the declarations that are
--  provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity Rs232RefComp is
    Port ( 
		TXD 	: out std_logic  	:= '1';
    	RXD 	: in  std_logic;					
    	CLK 	: in  std_logic;								--Master Clock
		DBIN 	: in  std_logic_vector (7 downto 0);	--Data Bus in
		DBOUT : out std_logic_vector (7 downto 0);	--Data Bus out
		RDA	: inout std_logic;						--Read Data Available
		TBE	: inout std_logic 	:= '1';			--Transfer Bus Empty
		RD		: in  std_logic;					--Read Strobe
		WR		: in  std_logic;					--Write Strobe
		PE		: out std_logic;					--Parity Error Flag
		FE		: out std_logic;					--Frame Error Flag
		OE		: out std_logic;					--Overwrite Error Flag
		RST		: in  std_logic	:= '0');	--Master Reset
end Rs232RefComp;
 
architecture Behavioral of Rs232RefComp is
------------------------------------------------------------------------
-- Component Declarations
------------------------------------------------------------------------
 
------------------------------------------------------------------------
--  Local Type Declarations
------------------------------------------------------------------------
	--Receive state machine
	type rstate is (					  
		strIdle,			--Idle state
		strEightDelay,	--Delays for 8 clock cycles
		strGetData,		--Shifts in the 8 data bits, and checks parity
		strCheckStop		--Sets framing error flag if Stop bit is wrong
	);
 
	type tstate is (
		sttIdle,			--Idle state
		sttTransfer,	--Move data into shift register
		sttShift			--Shift out data
		);
 
	type TBEstate is (
		stbeIdle,
		stbeSetTBE,
		stbeWaitLoad,
		stbeWaitWrite
		);
 
 
------------------------------------------------------------------------
-- Signal Declarations
------------------------------------------------------------------------
	constant baudDivide : std_logic_vector(7 downto 0) := "00001101"; 	--Baud Rate dividor, set now for a rate of 9600.
																								--Found by dividing 50MHz by 9600 and 16.
	signal rdReg	:  std_logic_vector(7 downto 0) := "00000000";			--Receive holding register
	signal rdSReg	:  std_logic_vector(9 downto 0) := "1111111111";		--Receive shift register
	signal tfReg	:  std_logic_vector(7 downto 0);								--Transfer holding register
	signal tfSReg  :  std_logic_vector(10 downto 0) 	:= "11111111111";	--Transfer shift register
	signal clkDiv	:  std_logic_vector(8 downto 0)	:= "000000000";		--used for rClk
	signal rClkDiv :  std_logic_vector(3 downto 0)	:= "0000";				--used for tClk
	signal ctr	:  std_logic_vector(3 downto 0)	:= "0000";					--used for delay times
	signal tfCtr	:  std_logic_vector(3 downto 0)	:= "0000";				--used to delay in transfer
	signal rClk	:  std_logic := '0';							--Receiving Clock
	signal tClk	:  std_logic;									--Transfering Clock
	signal dataCtr :  std_logic_vector(3 downto 0)	:= "0000";		--Counts the number of read data bits
	signal parError:  std_logic;									--Parity error bit
	signal frameError: std_logic;									--Frame error bit
	signal CE		:  std_logic;									--Clock enable for the latch
	signal ctRst	:  std_logic := '0';
	signal load	:  std_logic := '0';
	signal shift	:  std_logic := '0';
	signal par	:  std_logic;
   signal tClkRST	:  std_logic := '0';
	signal rShift	:  std_logic := '0';
	signal dataRST :  std_logic := '0';
	signal dataIncr:  std_logic := '0';
 
	signal strCur	:  rstate	:= strIdle; 				--Current state in the Receive state machine
	signal strNext	:  rstate;									--Next state in the Receive state machine
	signal sttCur  :  tstate := sttIdle;					--Current state in the Transfer state machine
	signal sttNext :  tstate;									--Next state in the Transfer staet machine
	signal stbeCur :  TBEstate := stbeIdle;
	signal stbeNext:  TBEstate;
 
------------------------------------------------------------------------
-- Module Implementation
------------------------------------------------------------------------
 
begin
	frameError <= not rdSReg(9);
	parError <= not ( rdSReg(8) xor (((rdSReg(0) xor rdSReg(1)) xor (rdSReg(2) xor rdSReg(3))) xor ((rdSReg(4) xor rdSReg(5)) xor (rdSReg(6) xor rdSReg(7)))) );
	DBOUT <= rdReg;
	tfReg <= DBIN;
	par <=  not ( ((tfReg(0) xor tfReg(1)) xor (tfReg(2) xor tfReg(3))) xor ((tfReg(4) xor tfReg(5)) xor (tfReg(6) xor tfReg(7))) );
 
--Clock Dividing Functions--
 
	process (CLK, clkDiv)	    						--set up clock divide for rClk
		begin
			if (Clk = '1' and Clk'event) then
				if (clkDiv = baudDivide) then
					clkDiv <= "000000000";
				else
					clkDiv <= clkDiv +1;
				end if;
			end if;
		end process;
 
	process (clkDiv, rClk, CLK)	 					--Define rClk
	begin
		if CLK = '1' and CLK'Event then
			if clkDiv = baudDivide then
				rClk <= not rClk;
			else
				rClk <= rClk;
			end if;
		end if;
	end process;	
 
	process (rClk)	  								     --set up clock divide for tClk
		begin
			if (rClk = '1' and rClk'event) then
				rClkDiv <= rClkDiv +1;
			end if;
		end process;
 
	tClk <= rClkDiv(3);									--define tClk
 
	process (rClk, ctRst)				   			--set up a counter based on rClk
		begin
			if rClk = '1' and rClk'Event then
				if ctRst = '1' then
					ctr <= "0000";
				else
					ctr <= ctr +1;
				end if;
			end if;
		end process;
 
	process (tClk, tClkRST)	 							--set up a counter based on tClk
		begin
			if (tClk = '1' and tClk'event) then
				if tClkRST = '1' then
					tfCtr <= "0000";
				else
					tfCtr <= tfCtr +1;
				end if;
			end if;
		end process;
 
 	--This process controls the error flags--
	process (rClk, RST, RD, CE)
		begin
			if RD = '1' or RST = '1' then
				FE <= '0';
				OE <= '0';
				RDA <= '0';
				PE <= '0';
			elsif rClk = '1' and rClk'event then
				if CE = '1' then
					FE <= frameError;
					OE <= RDA;
					RDA <= '1';	 
					PE <= parError;
					rdReg(7 downto 0) <= rdSReg (7 downto 0);
				end if;				
			end if;
		end process;
 
	--This process controls the receiving shift register--
	process (rClk, rShift)
		begin
			if rClk = '1' and rClk'Event then
				if rShift = '1' then
					rdSReg <= (RXD & rdSReg(9 downto 1));
				end if;
			end if;
		end process;
 
	--This process controls the dataCtr to keep track of shifted values--
 	process (rClk, dataRST)
		begin
			if (rClk = '1' and rClk'event) then
				if dataRST = '1' then
					dataCtr <= "0000";
				elsif dataIncr = '1' then
					dataCtr <= dataCtr +1;
				end if;
			end if;
		end process;
 
  	--Receiving State Machine--
	process (rClk, RST)
		begin
			if rClk = '1' and rClk'Event then
				if RST = '1' then
					strCur <= strIdle;
				else
					strCur <= strNext;
				end if;
			end if;
		end process;
 
	--This process generates the sequence of steps needed receive the data
 
	process (strCur, ctr, RXD, dataCtr, rdSReg, rdReg, RDA)
		begin   
			case strCur is
 
				when strIdle =>
					dataIncr <= '0';
					rShift <= '0';
					dataRst <= '0';
 
					CE <= '0';
					if RXD = '0' then
						ctRst <= '1';
						strNext <= strEightDelay;
					else
						ctRst <= '0';
						strNext <= strIdle;
					end if;
 
				when strEightDelay => 
					dataIncr <= '0';
					rShift <= '0';
					CE <= '0';
 
					if ctr(2 downto 0) = "111" then
						ctRst <= '1';
					    	dataRST <= '1';
						strNext <= strGetData;
					else
						ctRst <= '0';
						dataRST <= '0';
						strNext <= strEightDelay;
					end if;
 
				when strGetData =>	
					CE <= '0';
					dataRst <= '0';
					if ctr(3 downto 0) = "1111" then
						ctRst <= '1';
						dataIncr <= '1';
						rShift <= '1';
					else
						ctRst <= '0';
						dataIncr <= '0';
						rShift <= '0';		
					end if;
 
					if dataCtr = "1010" then
						strNext <= strCheckStop;
					else
						strNext <= strGetData;
					end if;
 
				when strCheckStop =>
					dataIncr <= '0';
					rShift <= '0';
					dataRst <= '0';
					ctRst <= '0';
 
					CE <= '1';
					strNext <= strIdle;
 
			end case;
 
		end process;
 
	--TBE State Machine--
	process (CLK, RST)
		begin
			if CLK = '1' and CLK'Event then
				if RST = '1' then
					stbeCur <= stbeIdle;
				else
					stbeCur <= stbeNext;
				end if;
			end if;
		end process;
 
	--This process gererates the sequence of events needed to control the TBE flag--
	process (stbeCur, CLK, WR, DBIN, load)
		begin
 
			case stbeCur is
 
				when stbeIdle =>
					TBE <= '1';
					if WR = '1' then
						stbeNext <= stbeSetTBE;
					else
						stbeNext <= stbeIdle;
					end if;
 
				when stbeSetTBE =>
					TBE <= '0';
					if load = '1' then
						stbeNext <= stbeWaitLoad;
					else
						stbeNext <= stbeSetTBE;
					end if;
 
				when stbeWaitLoad =>
					if load = '0' then
						stbeNext <= stbeWaitWrite;
					else
						stbeNext <= stbeWaitLoad;
					end if;
 
				when stbeWaitWrite =>
					if WR = '0' then 
						stbeNext <= stbeIdle;
					else
						stbeNext <= stbeWaitWrite;
					end if;
				end case;
			end process;
 
	--This process loads and shifts out the transfer shift register--
	process (load, shift, tClk, tfSReg)
		begin
			TXD <= tfsReg(0);
			if tClk = '1' and tClk'Event then
				if load = '1' then
					tfSReg (10 downto 0) <= ('1' & par & tfReg(7 downto 0) &'0');
				end if;
				if shift = '1' then
 
					tfSReg (10 downto 0) <= ('1' & tfSReg(10 downto 1));
				end if;
			end if;
		end process;
 
	--  Transfer State Machine--
	process (tClk, RST)
		begin
			if (tClk = '1' and tClk'Event) then
				if RST = '1' then
					sttCur <= sttIdle;
				else
					sttCur <= sttNext;
				end if;
			end if;
		end process;
 
	--  This process generates the sequence of steps needed transfer the data--
	process (sttCur, tfCtr, tfReg, TBE, tclk)
		begin   	   
 
			case sttCur is
 
				when sttIdle =>
					tClkRST <= '0';
					shift <= '0';
					load <= '0';
					if TBE = '1' then
						sttNext <= sttIdle;
					else
						sttNext <= sttTransfer;
					end if;	
 
				when sttTransfer =>	
					shift <= '0';
					load <= '1';
					tClkRST <= '1';		
					sttNext <= sttShift;
 
 
				when sttShift =>
					shift <= '1';
					load <= '0';
					tClkRST <= '0';
					if tfCtr = "1100" then
						sttNext <= sttIdle;
					else
						sttNext <= sttShift;
					end if;
			end case;
		end process;						 	
 
end Behavioral;

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.