-- This package may be used to accept data from an RS_232 Port -- The clock to this package should be at a rate 16 times that of -- the RS_232 port. ie. the input signal will be sampled at 16 times -- the baud rate for more accurate detection of the start bit for -- asynchronous communication. Data must be read off immediately when -- the data signal valid goes high -- there is no method provided here to delay the incoming data stream. -- -- Adpated from the 1998_w application note by Tim Bensler & Eric Chan -- I recommend a 0.5 to 1ms delay between characters, but it is not essential LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_arith.ALL; USE ieee.std_logic_unsigned.ALL; library work; PACKAGE RS_232_In_pkg IS component RS_232_In port( clock : in STD_LOGIC ; shiftin : in STD_LOGIC ; q : out STD_LOGIC_VECTOR (7 DOWNTO 0); data_valid : out std_logic ); end component RS_232_In; END RS_232_In_pkg; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity RS_232_In is port( clock : in STD_LOGIC ; --this clock should be SAMPLE times greater than baud rate shiftin : in STD_LOGIC ; -- RS_232 data stream in q : out STD_LOGIC_VECTOR (7 DOWNTO 0); -- 8 bit word data_valid : out std_logic -- complete word has been received ); end RS_232_In; architecture mixed of RS_232_In is component serialShiftRight IS PORT ( clock : IN STD_LOGIC ; enable : IN STD_LOGIC ; shiftin : IN STD_LOGIC ; aclr : IN STD_LOGIC ; q : OUT STD_LOGIC_VECTOR (9 DOWNTO 0) ); end component serialShiftRight; constant SAMPLE:natural:= 16; -- how many times faster than baud rate we are sampling at constant clear_time: natural :=4; -- how long to hold the clear low to wipe the shift register constant counterOffset: natural:= 8; --counter offset to take sample in the middle of pulse constant counterMax: natural:= 164; -- 10bits * SAMPLE + SAMPLE/2 (SAMPLE/2) to sample middle of pulse signal qout: std_logic_vector(9 downto 0); -- temporary variable used by the shift register signal delayValid: std_logic; -- delays the valid signal until the character has stabilized on the bus signal clearshift : std_logic; -- used to clear the shift register when a startbit is found signal enableSignal : std_logic; -- enables the shift register to process another bit begin -- Converts the incoming bit stream from LSB first to an 8-bit would MSB on the left shift_register : serialShiftRight port map( clock => clock, enable => enableSignal, shiftin => shiftin, aclr => clearshift, q => qout ); process(clock) variable counter: integer range 0 to SAMPLE*10 := 0; variable counter_target: integer range 0 to SAMPLE*10 := 16; variable startbit: integer range 0 to 1; -- when a valid packet is being recieved signal goes to 1 begin if rising_edge(clock) then if shiftin = '0' and startbit = 0 then startbit := 1; -- have first bit of packet counter_target := counterOffset; -- set the target for the counter, clearshift <= '1'; -- clear the shift register -- when the sample counter reach 4, set the clear signal back to 0 on the shift register elsif counter = clear_time then clearshift <= '0'; end if; -- increment the sample counter if startbit = 1 then counter := counter +1; else counter := 0; end if; -- if the counter reachs the target value add the current serial input to the shift register if counter = counter_target then enableSignal <= '1'; counter_target := counter_target + SAMPLE; -- increment the target to the next bit value else enableSignal <= '0'; end if; -- when the start bit is received rset the counter and startbit values back If shiftin = '1' and counter = counterMax then startbit := 0; counter := 0; counter_target := counterOffset; q <= qout(8 downto 1); delayValid <='1'; -- delay datavalid until qout stabalized else data_valid <= delayValid; -- tell the system that there is valid data on the bus delayValid <= '0'; end if; end if; end process; end mixed;