Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > count until read next signal

Reply
Thread Tools

count until read next signal

 
 
matchstick86 matchstick86 is offline
Junior Member
Join Date: Oct 2009
Posts: 19
 
      10-02-2009
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!
 
Reply With Quote
 
 
 
 
jeppe jeppe is offline
Senior Member
Join Date: Mar 2008
Location: Denmark
Posts: 348
 
      10-02-2009
Would this be code for simulation or synthesizing (hardware implementation) ?
Jeppe
 
Reply With Quote
 
 
 
 
matchstick86 matchstick86 is offline
Junior Member
Join Date: Oct 2009
Posts: 19
 
      10-04-2009
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?
 
Reply With Quote
 
jeppe jeppe is offline
Senior Member
Join Date: Mar 2008
Location: Denmark
Posts: 348
 
      10-05-2009
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 by jeppe; 10-05-2009 at 07:58 AM..
Reply With Quote
 
matchstick86 matchstick86 is offline
Junior Member
Join Date: Oct 2009
Posts: 19
 
      10-06-2009
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 by matchstick86; 10-06-2009 at 05:25 AM..
Reply With Quote
 
jeppe jeppe is offline
Senior Member
Join Date: Mar 2008
Location: Denmark
Posts: 348
 
      10-07-2009
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;
 
Reply With Quote
 
matchstick86 matchstick86 is offline
Junior Member
Join Date: Oct 2009
Posts: 19
 
      10-14-2009
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 by matchstick86; 10-15-2009 at 07:20 AM..
Reply With Quote
 
matchstick86 matchstick86 is offline
Junior Member
Join Date: Oct 2009
Posts: 19
 
      10-16-2009
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Signal Transition detection - wait until... or if construct MJ VHDL 4 02-11-2008 01:56 PM
how to highlight a row when on click and keep it highlighted until next click john woo Javascript 1 06-16-2005 01:30 PM
CurrentElement->next = CurrentElement->next->next (UNDEFINED?) Deniz Bahar C Programming 2 03-09-2005 12:45 AM
Count(*) in a Subquery with multiple tables: How does SQL determine which table to generate the Count() from? Kaimuri MCSD 3 12-29-2004 06:38 PM
D70 now or wait until next model? bmoag Digital Photography 16 12-01-2004 03:26 AM



Advertisments