------------------------------------------------------------------------------- -- File: IRdecoder.vhd -- -- Project: DPF -- Date: 3/4/02 -- -- Purpose: IR PCM decoder -- This module takes in a bitstream and converts it -- to one of 4 different values, start, stop, 1, 0 -- -- Inputs: irstream <- incoming bitsream from IR reciever -- streamValue <- decoded stream of values -- ('1'<="11",'0'<="00",OFF<="10, START<="01") -- reset <- resets the decoding system -- clock <- incoming clock signal -- -- -- Outputs: streamValue <- decoded stream of values -- ('1'<="11",'0'<="00",OFF<="10, START<="01") -- stateReset <- internal reset used for initializing the -- command decoder hardware -- streamValue_valid <- value at StreamValue is valid -- -- External Connections: -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; LIBRARY lpm; USE lpm.lpm_components.all; entity IRdecoder is -- width of the value symbols generic( valuewidth : positive := 2); port( irstream : in std_logic; streamValue : out std_logic_vector(valuewidth-1 downto 0); clock : in std_logic; streamValue_valid : out std_logic; reset : in std_logic; stateReset : out std_logic ); end IRdecoder; architecture mixed of IRdecoder is -- Size of the counter used to find the number of clocks in a pulse constant counterwidth : positive := 8; -- Number of different symbols created for the system constant SYMBOL_NUMBER : positive := 4; subtype SymbolType is std_logic_vector(counterwidth-1 downto 0); type irdecoder_map is array (SYMBOL_NUMBER-1 downto 0) of SymbolType; -- Range values for the number of clock pulses per pulse code modulation value constant VALUE1MAX : SymbolType := X"16"; constant VALUE1MIN : SymbolType := X"0A"; constant VALUE0MAX : SymbolType := X"06"; constant VALUE0MIN : SymbolType := X"01"; constant OFFMAX : SymbolType := X"32"; constant OFFMIN : SymbolType := X"1E"; constant STARTMAX : SymbolType := X"70"; constant STARTMIN : SymbolType := X"50"; component registerN is generic( counterwidth : positive:=8); PORT ( clock : IN STD_LOGIC ; enable : IN STD_LOGIC ; aclr : IN STD_LOGIC ; data : IN STD_LOGIC_VECTOR (counterwidth-1 DOWNTO 0); q : OUT STD_LOGIC_VECTOR (counterwidth-1 DOWNTO 0) ); end component registerN; component counterN IS generic( counterWidth : positive := 8 ); port( clock : in std_logic; cnt_en : in std_logic; sclr : in std_logic; aclr : in std_logic; q : out std_logic_vector (counterWidth-1 DOWNTO 0); cout : out std_logic ); end component counterN; component ir1DFF IS PORT ( clock : IN STD_LOGIC ; data : IN STD_LOGIC ; q : OUT STD_LOGIC ); end component ir1DFF; component irgreater IS generic(compareWidth : positive := 8); port ( dataA : in std_logic_vector (compareWidth-1 DOWNTO 0); dataB : in std_logic_vector (compareWidth-1 DOWNTO 0); AgeB : out STD_LOGIC ); end component irgreater; component irlesser IS generic(compareWidth : positive := 8); PORT ( dataA : IN STD_LOGIC_VECTOR (compareWidth-1 DOWNTO 0); dataB : IN STD_LOGIC_VECTOR (compareWidth-1 DOWNTO 0); AleB : OUT STD_LOGIC ); end component irlesser; -- In order to use the generate statement to produce a generic PCM decoder -- each signal stage needs its own outputs and counter values signal lesser_vector : std_logic_vector(SYMBOL_NUMBER-1 downto 0); signal greater_vector : std_logic_vector(SYMBOL_NUMBER-1 downto 0); signal lesser_matrix : irdecoder_map; signal greater_matrix : irdecoder_map; signal counter_matrix : irdecoder_map; --Define counter signals for counting the low and the high pulses signal counterLow_in : std_logic_vector(counterwidth-1 downto 0); signal counterLow_out : std_logic_vector(counterwidth-1 downto 0); signal counterHigh_in : std_logic_vector(counterwidth-1 downto 0); signal counterHigh_out : std_logic_vector(counterwidth-1 downto 0); -- Delay the input into the decoder for one clock cycle to ensure that the values -- have proper synchronization signal delayed_irstream : std_logic; signal not_delayirstream : std_logic; signal not_irstream : std_logic; -- If set is '1' then data_valid needs to be reset back to 0 signal set : std_logic; signal stateResetHigh, stateResetLow : std_logic; begin not_delayirstream <= not delayed_irstream; not_irstream <= not irstream; -- Assign the range values to the matrix so a generate command can be used to --make the comparators lesser_matrix(0) <= VALUE1MAX; lesser_matrix(1) <= VALUE0MAX; lesser_matrix(2) <= OFFMAX; lesser_matrix(3) <= STARTMAX; greater_matrix(0) <= VALUE1MIN; greater_matrix(1) <= VALUE0MIN; greater_matrix(2) <= OFFMIN; greater_matrix(3) <= STARTMIN; -- Specify if the comparitors are using active high or active low counter_matrix(0) <= counterHigh_out; counter_matrix(1) <= counterHigh_out; counter_matrix(2) <= counterHigh_out; counter_matrix(3) <= counterLow_out; --Counts the number of clocks that occur in a high pulse counterHigh: counterN generic map( counterWidth => counterwidth ) port map( clock => clock, cnt_en => irstream, aclr => reset, sclr => not_delayirstream, q => counterHigh_in, cout => stateResetHigh ); -- Counts the number of clocks that occur in a low pulse counterLow: counterN generic map( counterWidth => counterwidth ) port map( clock => clock, cnt_en => not_irstream, aclr => reset, sclr => delayed_irstream, q => counterLow_in, cout => stateResetLow ); -- Delay the incoming bitstream vy one clock cycle so that handshaking between -- the active high counter and the active low counter can occur inputdelay : component ir1DFF port map( clock => clock, data => irStream, q => delayed_irstream ); -- Instantiate a resgister to store the number of High clock pulses registerHigh : component registerN port map( clock => clock, aclr => reset, enable => not_irstream, data => counterHigh_in, q => counterHigh_out ); -- Instantiate a resgister to store the number of Low clock pulses registerLow : component registerN port map( clock => clock, aclr => reset, enable => irstream, data => counterLow_in, q => counterLow_out ); --instantiate the lesser comparators gen_lesser: for I in 0 to SYMBOL_NUMBER-1 generate begin lesser: irlesser generic map(compareWidth => counterwidth ) port map( dataA => counter_matrix(I), dataB => lesser_matrix(I), AleB => lesser_vector(I) ); end generate; --instantiate the greater comparators gen_greater: for J in 0 to SYMBOL_NUMBER-1 generate begin greater: irgreater generic map(compareWidth => counterwidth ) port map( dataA => counter_matrix(J), dataB => greater_matrix(J), AgeB => greater_vector(J) ); end generate; -- Overflow in the counter resets the symbol detector overflow_reset : process(stateResetHigh, stateResetLow) begin if stateResetHigh = '1' or stateResetLow = '1' then stateReset <= '1'; else stateReset <= '0'; end if; end process overflow_reset; -- Compare the any symbol was found and send the output. streamout: process(clock) is begin if rising_edge(clock) then if reset = '1' then streamValue <= "00"; streamValue_valid <= '0'; set <= '1'; elsif set = '1' then set <= '0'; streamValue_valid <= '0'; elsif (greater_vector(0)= '1' and lesser_vector(0)= '1') then streamValue <= "11"; streamValue_valid <= '1'; set <= '1'; elsif (greater_vector(1)= '1' and lesser_vector(1)= '1') then streamValue <= "00"; streamValue_valid <= '1'; set <= '1'; elsif (greater_vector(2)= '1' and lesser_vector(2)= '1') then streamValue <= "10"; streamValue_valid <= '1'; set <= '1'; elsif (greater_vector(3)= '1' and lesser_vector(3)= '1') then streamValue <= "01"; streamValue_valid <= '1'; set <= '1'; end if; end if; end process streamout; end mixed;