--===========================================================================-- -- -- 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 OCRP-1 -- -- File name : RxUnit.vhd -- -- Purpose : Implements an miniUART device for communication purposes -- between the OR1K processor and the Host computer through -- an RS-232 communication protocol. -- -- Library : uart_lib.vhd -- -- Dependencies : IEEE.Std_Logic_1164 -- --===========================================================================-- ------------------------------------------------------------------------------- -- Revision list -- Ver 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 -- 2.1 Ed Williamson-Brown 27 Sep 2006 Trim code to reduce space required -- 2.2 Ed 19 Feb 2007 DMX enabled -- olupas@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. ------------------------------------------------------------------------------- -- Entity for Receive Unit - 250K DMX baudrate -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --library work; -- use work.UART_Def.all; ------------------------------------------------------------------------------- -- Receive unit ------------------------------------------------------------------------------- entity RxUnit is port ( Clk : in Std_Logic; -- system clock signal Reset : in Std_Logic; -- Reset input RxD : in Std_Logic; -- RS-232 data input BREAK : out Std_Logic; -- Status signal DataIn : out Std_Logic_Vector(7 downto 0); BitStart: out Std_Logic); end entity; --================== End of entity ==============================-- ------------------------------------------------------------------------------- -- Architecture for receive Unit ------------------------------------------------------------------------------- architecture Behaviour of RxUnit is ----------------------------------------------------------------------------- -- Signals ----------------------------------------------------------------------------- signal Start : Std_Logic; -- Syncro signal signal tmpRxD : Std_Logic; -- RxD buffer signal BreakDetected : Std_Logic; -- signal BitCnt : Unsigned(3 downto 0); -- signal SampleCnt : Unsigned(3 downto 0); -- samples on one bit counter signal ShtReg : Std_Logic_Vector(7 downto 0); -- signal DOut : Std_Logic_Vector(7 downto 0); -- begin --------------------------------------------------------------------- -- Receiver process --------------------------------------------------------------------- RcvProc : process(Clk,Reset,RxD) variable tmpBitCnt : Integer range 0 to 15; variable tmpSampleCnt : Integer range 0 to 15; constant CntOne : Unsigned(3 downto 0):="0001"; begin if Rising_Edge(Clk) then --tmpBitCnt := ToInteger(BitCnt); tmpBitCnt := To_Integer(BitCnt); --tmpSampleCnt := ToInteger(SampleCnt); tmpSampleCnt := To_Integer(SampleCnt); if Reset = '0' then BitCnt <= "0000"; SampleCnt <= "0000"; Start <= '0'; BreakDetected <= '0'; ShtReg <= "00000000"; -- DOut <= "00000000"; -- else if Start = '0' then if RxD = '0' then -- Start bit, SampleCnt <= SampleCnt + CntOne; Start <= '1'; BreakDetected <= '0'; -- clear output end if; else if tmpSampleCnt = 8 then -- reads the RxD line tmpRxD <= RxD; --BitStart <= '1'; -- position marker for debugging SampleCnt <= SampleCnt + CntOne; elsif tmpSampleCnt = 15 then --BitStart <= '0'; -- position marker for debugging case tmpBitCnt is when 0 => -- Waiting for start bit (should be '0') if tmpRxD = '1' then -- Not detected. Start <= '0'; --tmpDRdy <= '0'; else BitCnt <= BitCnt + CntOne; end if; SampleCnt <= SampleCnt + CntOne; when 1|2|3|4|5|6|7|8 => BitCnt <= BitCnt + CntOne; SampleCnt <= SampleCnt + CntOne; ShtReg <= tmpRxD & ShtReg(7 downto 1); when 9 => --1st stop bit if tmpRxD = '0' then -- Check for stop bit (should be '1') -- Stop bit not detected. Either fault, or BREAK signal. BreakDetected <= '1'; BitCnt <= BitCnt + CntOne; -- Goto state 10 and wait for stop SampleCnt <= SampleCnt + CntOne; else -- Stop bit found so reset and wait for -- next falling edge of start bit. BreakDetected <= '0'; BitCnt <= "0000"; -- Goto state 00 and wait for start SampleCnt <= "0000"; Start <= '0'; end if; DOut <= ShtReg; when 10 => -- Ensure RxD is high before continuing... -- This caters for BREAK byte length (88uS with no stop bits) if BreakDetected = '1' then -- we are waiting for a return to a high state if tmpRxD = '1' then -- check for high state -- High state detected, so abandon this and wait for the falling -- edge of the next START bit. BitCnt <= "0000"; SampleCnt <= "0000"; Start <= '0'; end if; SampleCnt <= SampleCnt + CntOne; end if; when others => null; end case; else SampleCnt <= SampleCnt + CntOne; end if; end if; end if; -- if reset=... end if; -- rising clock end process; DataIn <= DOut; BREAK <= BreakDetected; BitStart <= Start; end Behaviour; --==================== End of architecture ====================--