count until read next signal

Joined
Oct 2, 2009
Messages
19
Reaction score
0
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!
 
Joined
Mar 10, 2008
Messages
348
Reaction score
0
Would this be code for simulation or synthesizing (hardware implementation) ?
Jeppe
 
Joined
Oct 2, 2009
Messages
19
Reaction score
0
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?
 
Joined
Mar 10, 2008
Messages
348
Reaction score
0
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:
Joined
Oct 2, 2009
Messages
19
Reaction score
0
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:
Joined
Mar 10, 2008
Messages
348
Reaction score
0
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;
 
Joined
Oct 2, 2009
Messages
19
Reaction score
0
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:
Joined
Oct 2, 2009
Messages
19
Reaction score
0
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top