Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
9 years ago

pulse counting

Hello,

I'd like to code a pulse counter : after X pulses from a signal, another signal toggles (I choose 4 in my example).

I wrote this piece of code, and the behavior is not as i expected.

http://www.alteraforum.com/forum/attachment.php?attachmentid=13204&stc=1

pulse_gen : process (clk) -- square generation from a given frequency
begin
    if rising_edge (clk) then
        if reset = '0' then
        
            pulse_counter        <= (others => '0');
            pulse_tick            <= '0';
            pulse_toggle4        <= '0';        
            
        else
        
            if ((en_in <= '1')) then
            
                
                if pulse_counter = max_count then
                
                    pulse_counter     <= (others => '0');
                    pulse_tick         <= not pulse_tick;
                    counter_dir        <= counter_dir +1;
                    
                    if ((counter_dir = "00001000"))  then  -- 8 for 4 pulses
                        
                        counter_dir <= (others => '0') ;
                        pulse_toggle4    <= not pulse_toggle4 ;
                                
                    end if ;
                    
                else
                
                    pulse_counter     <= pulse_counter + 1;
                    
                end if;
                
            else
                
                pulse_counter    <= (others => '0');
                pulse_tick        <= '0';        
                
            end if;
        end if;
    end if;
end process pulse_gen;
pulse         <= pulse_tick; 
toggle4        <= pulse_toggle4;

I would be grateful if you could have a look

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Are you sure this is the correct code. The toggle signal is falling on the falling edge of the clock, not the rising.

    Can you post all of the code AND testbench?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Code :

    
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    entity pulsegen is
    	
    	generic (
    	
    		pulse_to_count	 : unsigned(7 downto 0) := "00001000"
    	 
    	);
       
       port(
          clk				: in std_logic;
          reset 				: in std_logic;
          ratio_freq			: in unsigned(19 downto 0);	 
          en_in 				: in std_logic;             			 
          pulse			 	: out std_logic;				 			 
          toggle_pulse	 	: out std_logic				 		    
       );
    	
    end pulsegen ;
    architecture arch of pulsegen is 
    signal pulse_tick			: std_logic 		     :='0';
    signal pulse_dir			: std_logic 		     :='0';
    signal pulse_counter		: unsigned(19 downto 0) := (others => '0');
    signal counter_dir		: unsigned(7 downto 0)   := (others => '0');
    begin
    	pulse               <= pulse_tick; 
    	toggle_pulse    <= pulse_dir;
    pulsegen : process (clk) 
    begin
    	if rising_edge (clk) then
    		if reset = '0' then
    		
    			pulse_counter		<= (others => '0');
    			pulse_tick			<= '0';
    			pulse_dir			<= '0';	
    			
    		else
    		
    			if (en_in <= '1') then
    				
    				if pulse_counter = ratio_freq then
    				
    					pulse_counter 	<= (others => '0');
    					pulse_tick 		<= not pulse_tick;
    					counter_dir	<= counter_dir +1;
    					
    					if (counter_dir = pulse_to_count)  then 
    						
    						counter_dir <= (others => '0') ;
    						pulse_dir	 <= not pulse_dir ;
    								
    					end if ;
    					
    				else
    				
    					pulse_counter 	<= pulse_counter + 1;
    					
    				end if;
    				
    			else
    				
    				pulse_counter	<= (others => '0');
    				pulse_tick		<= '0';		
    				
    			end if;
    		end if;
    	end if;
    end process pulsegen;
    end arch; 
    

    Test Bench :

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    entity tb is
    end tb;
    architecture behavior of tb is
        component pulsegen  
       	generic (
    					pulse_to_count	 : unsigned(7 downto 0) := "00001000"
    					);
    		
    		port(
    			clk					: in std_logic;
    			reset 				: in std_logic;
    			ratio_freq			        : in unsigned(19 downto 0);	 
    			en_in 				: in std_logic;             			 
    			pulse 				: out std_logic;				 			 
    			toggle_pulse 		        : out std_logic				 		    
    			);
    	
        end component;
     
       signal clk : std_logic								:= '0';
    	signal reset : std_logic							:= '0';
    	signal en_in : std_logic							:= '0';
    	signal pulse : std_logic							:= '0';
    	signal toggle_pulse : std_logic					        := '0';
    	
    	signal ratio_freq : unsigned(19 downto 0) 		                := "00000000000011111010";	--determines pulse output frequency
    	constant pulse_to_count : unsigned(7 downto 0) 	                := "00001000";				--toggles every 8 pulses from pulse output
            constant clk_period : time 							:= 20 ns;					--50MHz
    	
    	begin
    	
    	
    	uut: pulsegen  generic map(pulse_to_count=>pulse_to_count)
    			      port map(clk=>clk, reset=>reset,ratio_freq =>ratio_freq, en_in=>en_in,pulse=>pulse,toggle_pulse=>toggle_pulse);  
    	
       clk_process : process
       begin
       
            clk <= '0';
            wait for clk_period/2; 
            clk <= '1';
            wait for clk_period/2; 
       
       end process;
       stim_rx_proc: process
    	
    	begin
    	
    		wait for 100 ns;
    		reset <= '1';
    		wait for 200 ns;
    		en_in <= '1';
    		wait;
       end process;
    end;
    

    If you use my code and TB you'll see there is something wrong. I'd like to have the "toggle_pulse" toggling every 4 pulses from "pulse".
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Then just do a rising edge detection circuit on the pulse, and count 4 of them.

    Rising edge detect compars the current value with the last value:

    
    process(clk)
    begin
      if rising_edge(clk) then
        pulse_r <= pulse;
        if pulse_r = '0' and pulse = '1' then
          toggle_cnt <= toggle_cnt + 1;
        end if;
        if toggle_cnt = 3 then
          toggle_cnt <= 0;
          toggle <= not toggle;
        end if;
      end if;
    end process;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Ok, thank you ! :), I didn't know rising edge on an other signal than a clock was a good practice

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Ok, thank you ! :), I didn't know rising edge on an other signal than a clock was a good practice

    --- Quote End ---

    You're not using the rising edge function - you're building a rising edge detector. There is still only a single system clock.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    What is the difference between your submitted code and using the rising edge function ?

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    What is the difference between your submitted code and using the rising edge function ?

    --- Quote End ---

    The rising edge function looks for the rising edge on an actual signal, like a clock (its not a logic circuit, just a langauge function).

    An edge detect is a synchronous circuit that uses the input and a registered version of the input. Its a real logic circuit.