count until read next signal

Discussion in 'VHDL' started by matchstick86, Oct 2, 2009.

  1. matchstick86

    matchstick86

    Joined:
    Oct 2, 2009
    Messages:
    19
    Hi,

    im trying to create counter where it counts the number of cycles upon receiving the first signal, stops the count on receiving the second one, stores the counts between the two signals and resets the counter immediately after the second sig'event.

    i have something like this and i know for sure that it's not the right code:

    process (clk, reset, sig)
    begin
    wait on sig'event and sig = '1';
    if (reset = '1') then
    count(15 downto 0) <= "0000000000000000";
    elsif (clk'event and clk = '1') then
    count <= count + 1;
    end if;
    end process;

    process (sig, t)
    begin
    for i in 1 to 8 loop
    if sig’event and sig = ‘1’ then
    t(i) <= sig'last_event; reset = '1';
    end if;
    end loop;
    end process;

    what bugs me is the 'last_event attribute. so if t = 0, and t1 = n, sig'last_event is n? how does this differ from 'last_active?
    i know how to set the counter going, but i have no idea how to stop it. any hints/ideas? thanks!
     
    matchstick86, Oct 2, 2009
    #1
    1. Advertising

  2. matchstick86

    jeppe

    Joined:
    Mar 10, 2008
    Messages:
    348
    Location:
    Denmark
    Would this be code for simulation or synthesizing (hardware implementation) ?
    Jeppe
     
    jeppe, Oct 2, 2009
    #2
    1. Advertising

  3. matchstick86

    matchstick86

    Joined:
    Oct 2, 2009
    Messages:
    19
    hey jeppe,

    yes it is. is there a requirement to state an upper limit for the counter to stop and reset, because the upper limit cycle counts is each subsequent signal?
     
    matchstick86, Oct 4, 2009
    #3
  4. matchstick86

    jeppe

    Joined:
    Mar 10, 2008
    Messages:
    348
    Location:
    Denmark
    Hi Matchstick

    Well you better forget about the Last_event attributes - they bound to fail in the matter of synthesizing.
    My answer would be - State Machines - Consider this solution:

    Code:
    ----------------------------------------------------------------------------------
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    
    entity Bike_computer_ver1 is
    	 Generic( N: Natural := 8); -- Change to 16 if needed
        Port ( Clk,Sig :    in   STD_LOGIC;
               Last_Count : out  STD_LOGIC_VECTOR (N-1 downto 0));
    end Bike_computer_ver1;
    
    architecture Behavioral of Bike_computer_ver1 is
    	type   States is (Idle0, Idle1, Wait_for_Sig_0, Wait_for_Sig_1);
    	signal State:   States := Idle1;
    	signal Counter: STD_LOGIC_VECTOR (N-1 downto 0);
    begin
    
    	process( Clk)
    	begin
    		if Clk'event and Clk='1' then
    			case State is
    			   ------------------------Sig='0'--------------------
    				when Idle0 =>
    					Counter    <= (others=>'0');
    					Last_Count <= (others=>'1');
    					if Sig='1' then
    						State <= Wait_for_Sig_0;
    					end if;
    			   -------------------------Sig='1'--------------------
    				when Idle1 =>
    					Counter    <= (others=>'0');
    					Last_Count <= (others=>'1');
    					if Sig='0' then
    						State <= Idle0;
    					end if;
    				-------------------------Sig='1'--------------------	
    				when Wait_for_Sig_0 =>
    					Counter <= Counter+1;
    					if Counter=Conv_std_logic_vector(-1,N) then
    						State <= Idle1;
    					end if;
    					if Sig='0' then
    						State <= Wait_for_Sig_1;
    					end if;					
    				-------------------------Sig='0'-------------------	
    				when Wait_for_Sig_1 =>
    					if Counter=Conv_std_logic_vector(-1,N) then
    						State <= Idle0;
    					end if;
    					if Sig='1' then
    						State <= Wait_for_Sig_0;
    						Last_Count <= Counter;
    						Counter    <= (others=>'0');
    					else
    					   Counter <= Counter+1;
    					end if;				
    			end case;
    		end if;
    	end process;
    
    end Behavioral;
    And a code for simulation could look like this:

    Code:
    --------------------------------------------------------------
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    USE ieee.std_logic_unsigned.all;
    USE ieee.numeric_std.ALL;
     
    ENTITY TB_Bike1 IS
    END TB_Bike1;
     
    ARCHITECTURE behavior OF TB_Bike1 IS 
        -- Component Declaration for the Unit Under Test (UUT)
        COMPONENT Bike_computer_ver1
        PORT(Clk : IN  std_logic;
             Sig : IN  std_logic;
             Last_Count : OUT  std_logic_vector(7 downto 0));
        END COMPONENT;
       --Inputs
       signal Clk : std_logic := '0';
       signal Sig : std_logic := '0';
     	--Outputs
       signal Last_Count : std_logic_vector(7 downto 0);
       -- Clock period definitions
       constant Clk_period : time := 10 ns;
    BEGIN
    	-- Instantiate the Unit Under Test (UUT)
       uut: Bike_computer_ver1 PORT MAP (
              Clk => Clk,
              Sig => Sig,
              Last_Count => Last_Count);
    
       -- Clock process definitions
       Clk_process :process
       begin
    		Clk <= '0';
    		wait for Clk_period/2;
    		Clk <= '1';
    		wait for Clk_period/2;
       end process;
     
       -- Stimulus process
       stim_proc: process
       begin		
          wait for 100 ns;	
          Sig <= '1';
          wait for Clk_period*2;
          Sig <= '0';		
          wait for Clk_period*50;
          Sig <= '1';
          wait for Clk_period*2;
          Sig <= '0';		
          wait for Clk_period*127;     
    		Sig <= '1';
          wait for Clk_period*2;
          Sig <= '0';		
          wait for Clk_period*250;
    		Sig <= '1'; 
          wait;
       end process;
    END;
    Jeppe
     
    Last edited: Oct 5, 2009
    jeppe, Oct 5, 2009
    #4
  5. matchstick86

    matchstick86

    Joined:
    Oct 2, 2009
    Messages:
    19
    Wow, Jeppe.

    I'm a little lost. So you're saying that while the clock is ticking, when the signal is '0', the counter will not move until signal reads '1' and falls to '0' (wait_for_Sig_0)

    *I'm not sure how conv_std_logic (convert integers into bits) works when it comes to (-1,N). What does "-1" mean?

    The counter continues to count while signal is '0', waiting to stop when it hits signal = '1' (wait_for_sig_1).

    Once it hits '1' again, the previous count is stored and the counter is reset to count again. This is how I understand the code and it looks like what I have in mind. conv_std_logic is still bugging me.

    I originally had process(clk,reset) along with the counter code so I guess that made simulation impossible. I will give it a shot at your code anyway (or modify if necessary) and see it works. Thanks!

    edit: I understand the process now (still don't get the conv_std_logic). But another question is how do I store the counts in, say, t : std_logic_vector(7 (for example) downto 0), so I will have t(0) to t(7) each storing the counts as a result of the states. One way I can think of is by FOR loop:

    Code:
    process (clk)
    begin
    	if clk'event and clk='1' then
    		for i in 1 to 8 loop
    
    		case state is
    		----sig = '1' (step 1)----
    			when idle1 =>
    				count <= (others=>'0');		--start all zero
    				lastcount <= (others=>'1');
    			if sig='0' then
    				state <= idle0;
    			end if;
    
    		----sig = '0' (step 2)----
    			when idle0 => 
    				count <= (others=>'0');
    				lastcount <= (others=>'1');
    			if sig='1' then
    				state <= wait_sig0;
    			end if;
    
    		----sig = '1' (step 3a)----
    			when wait_sig0 =>
    				count <= count+1;
    			if count = conv_std_logic_vector(-1,N) then
    				state <= idle1;
    			end if;
    
    			if sig='0' then
    				state <= wait_sig1;
    			end if;
    
    		----sig = '0' (stage 3b)----
    			when wait_sig1 =>
    			if count = conv_logic_vector(-1,N) then
    				state <= idle0;
    			end if;
    
    			if sig = '1' then
    				state <= wait_sig0;
    				t(i) <= count;
    				count <= (others=>'0');
    			else
    				count <= count+1;
    			end if;
    		end case;
    
    		end loop;
    	end if;
    end process;
    end LOOP;
    
    Will this work? Can a CASE be within a loop?
     
    Last edited: Oct 6, 2009
    matchstick86, Oct 6, 2009
    #5
  6. matchstick86

    jeppe

    Joined:
    Mar 10, 2008
    Messages:
    348
    Location:
    Denmark
    Hi again
    Your bound to fail - putting a loop inside a State Machine (only allowed in a Reset operation).

    Take a look at this code - the conversion explained also.

    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    
    entity Bike_computer_ver2 is
       Generic( N: Natural := 8);
        Port ( Clk,Sig :   in   STD_LOGIC;
                Reset:     in   STD_LOGIC;
               Count0 :    out  STD_LOGIC_VECTOR (N-1 downto 0);
               Count1 :    out  STD_LOGIC_VECTOR (N-1 downto 0);           
               Count2 :    out  STD_LOGIC_VECTOR (N-1 downto 0);
               Count3 :    out  STD_LOGIC_VECTOR (N-1 downto 0);
               Count4 :    out  STD_LOGIC_VECTOR (N-1 downto 0);
               Count5 :    out  STD_LOGIC_VECTOR (N-1 downto 0);
               Count6 :    out  STD_LOGIC_VECTOR (N-1 downto 0);
               Count7 :    out  STD_LOGIC_VECTOR (N-1 downto 0)           
               );
    end Bike_computer_ver2;
    
    architecture Behavioral of Bike_computer_ver2 is
       type   States is (Idle0, Idle1, Wait_for_Sig_0, Wait_for_Sig_1);
       signal State:   States := Idle1;
       ----------------------------------------------------------------
       subtype Counter_type is STD_LOGIC_VECTOR (N-1 downto 0);
       signal Counter: Counter_type;
       ----------------------------------------------------------------
       type   Count_type is array (0 to 7) of Counter_type;
       signal Count:   Count_type; 
       ----------------------------------------------------------------
       Signal Index: integer range 0 to 7;
    begin
       Count0 <= Count(0); -- Send the first result to a output
       Count1 <= Count(1);
       Count2 <= Count(2);
       Count3 <= Count(3);
       Count4 <= Count(4);
       Count5 <= Count(5);
       Count6 <= Count(6);
       Count7 <= Count(7);
    
       process( Clk)
       begin
          if Clk'event and Clk='1' then
             if Reset='1' then
                State   <= Idle1;
                Counter <= (others=>'0');
                Index   <= 0;
                for i in 0 to 7 loop          -- In this case will a
                   Count(i) <= (others=>'0'); -- loop be possible
                end loop;
             else
                case State is
                   ------------------------Sig='0'--------------------
                   when Idle0 =>
                      Counter      <= (others=>'0');
                      Count(Index) <= (others=>'1');
                      if Sig='1' then
                         State <= Wait_for_Sig_0;
                      end if;
                   -------------------------Sig='1'--------------------
                   when Idle1 =>
                      Counter      <= (others=>'0');
                      Count(Index) <= (others=>'1');
                      if Sig='0' then
                         State <= Idle0;
                      end if;
                   -------------------------Sig='1'--------------------	
                   when Wait_for_Sig_0 =>
                      Counter <= Counter+1;
                         if Counter="11111111" then -- if Max counter value
                         State <= Idle1;
                      end if;
                      if Sig='0' then
                         State <= Wait_for_Sig_1;
                      end if;
                   -------------------------Sig='0'-------------------	
                   when Wait_for_Sig_1 =>
                      if Counter=Conv_std_logic_vector(-1,N) then --if Max counter value
                         State <= Idle0;
                      end if;
                      if Sig='1' then
                         State <= Wait_for_Sig_0;
                         Count(Index) <= Counter;
                         if Index <7 then      -- Depend on the application
                            Index <= Index+1;  -- Move the Index +1
                         else
                            Index <= 0; -- start once again at 0 ????
                         end if;
                         Counter      <= (others=>'0');
                      else
                         Counter <= Counter+1;
                      end if;
                end case;
             end if;
          end if;
       end process;
    
    end Behavioral;
     
    jeppe, Oct 7, 2009
    #6
  7. matchstick86

    matchstick86

    Joined:
    Oct 2, 2009
    Messages:
    19
    Alrighty. State machines don't seem to churn out my output well, ie. not churning out...

    But I managed to come out with this easier code (though I'm going bald from trying to figure out the basics):

    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    
    entity counter is
        Port ( clk : in  STD_LOGIC;
                sig : in  STD_LOGIC;
    	    t : out std_logic_vector(0 to 7)); --hoping to have t(0),..., t(7)
    end counter;
    
    architecture Behavioral of counter is
    
    signal count : std_logic_vector(7 downto 0); --8 bit counter
    
    begin
    process(clk,sig) is
    
    begin
    	if sig='1' then
    			count<=(others=>'0');
    	elsif rising_edge(clk) then
    			count<=count+1;
    	end if;
    
    	t<=count;
    end process;
    
    end Behavioral;
    
    Now, I'm trying to output the counts (as integers) at each sig='1', like

    clk_||_||_||_||_||_||_||_||_||_||_||_
    sig____||_____||__||__||____||_____
    ........start.......t0...t1..t2.....t3
    ......counter
    Thus I will get t0 = 2, t1 = 1, t2 = 1, t3 = 2

    I tried to automate the process with a FOR LOOP by having

    Code:
    port ( ... t : out std_logic_vector(0 to 7));
    
    process
    variable i : integer;
    
    begin
          for i in 1 to 8 loop
          ...counting...
          t(i) <= conv_integer(unsigned(count));
          end loop;
    end process;
    
    Failed miserably. conv_integer also requires that "count" be std_ulogic. After digging around for a while, it turns out that conv_integer doesn't seem to work well with std_logic.

    Anyway I thought of a way to output the counts is subtraction from previous count. So like, T0 = t0 - 0, T1 = t1 - t0, T2 = t2 - t1,
    where tn is counts relative to 0 and Tn relative to Tn-1. Haven't quite figured out the code for that yet.

    Nutshell:
    1) how to output integer counts for each t0, t1, ...t7
    2) what's up with conv_integer and std_ulogic? Jeez.

    edit:
    another uneducated idea I have is this:
    make an array of sixteen t's such that each holds a 16-bit value of "count"
    example: t(0) = 00001100, t(1) = 00000101, etc. After which, I would like to do something like, for example, b(0) = t(0) + t(1)
    or essentially, b(i) <= t(i) + t(i+1) (b(15) <= t(15) + t(16) will not exist). Is all this possible or am I just hoping for something non-existent? I tried loops, and I don't wish to continue with state machines. Any others ideas on where I can start?
     
    Last edited: Oct 15, 2009
    matchstick86, Oct 14, 2009
    #7
  8. matchstick86

    matchstick86

    Joined:
    Oct 2, 2009
    Messages:
    19
    Update:

    So I needed to declare a package within the code and the testbench that will allow me to have an array of std_logic_vector's. So 1) is solved. 2) won't be needed for now but would be nice to know more about the problem

    Question remains is the last bit. Still trying out a code for that
     
    matchstick86, Oct 16, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Deniz Bahar
    Replies:
    2
    Views:
    481
    Andrey Tarasevich
    Mar 9, 2005
  2. =?ISO-8859-2?Q?Miros=B3aw?= Makowiecki

    Reading of file by next of map file and by next of file descriptor.

    =?ISO-8859-2?Q?Miros=B3aw?= Makowiecki, Jul 10, 2007, in forum: C++
    Replies:
    1
    Views:
    797
    Alf P. Steinbach
    Jul 10, 2007
  3. MJ
    Replies:
    4
    Views:
    1,091
  4. Tad McClellan
    Replies:
    3
    Views:
    154
    Edward Wijaya
    May 13, 2004
  5. john woo
    Replies:
    1
    Views:
    145
Loading...

Share This Page