UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Adventurer
Adventurer
2,891 Views
Registered: ‎01-05-2017

How to change counter range depending on an input

Jump to solution

Hello

 

I'm trying to design a simple stop watch to control some connected processes. So I want to change the counting value depending on an input value "Period_Info". Below code is my trial and the errors I got as following:

 

" signal Period : integer := 0 "

 

Xst:773 -> "Constant 'Period' Period is at left hand side of signal assignment statement." 

 

Then I tried " constant Period : integer := 0 "

 

Xst:410 -> Constant 'Period' Period is at left hand side of signal assignment statement.

 

I didn't get the point after google search why it gives these errors. So could you please help me how to change the "Period" value for the timer range max value?

 

 

 

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity Stop_Watch is
	Port ( 	clk: IN  STD_LOGIC  ;   -- 48 MHz 
		RESET	: IN  STD_LOGIC  ;
		Period_Info	: IN	STD_LOGIC_VECTOR(7 DOWNTO 0) ;
		SW_Period_Over_Flag 	: OUT STD_LOGIC );
end Stop_Watch;

architecture Behavioral of Stop_Watch is

signal s_clk : STD_LOGIC ;
signal s_RESET : STD_LOGIC ;
signal s_SW_Period_Over_Flag : STD_LOGIC ;
signal s_Period_Info : STD_LOGIC_VECTOR(7 DOWNTO 0) ;
signal Period	: integer  := 0;

begin
    
  s_clk <= clk ;
  s_RESET <= RESET ;
  s_Period_Info	<= Period_Info	;
	
  Period <= 48E+6 when s_period_info = "01000001" else
	    2*48E+6 when s_period_info = "01000010" else
	    5*48E+6 when s_period_info = "01000011" else
	    10*48E+6 when s_period_info = "01000100" else
	    48E+6 ;
					 
			 
  process(s_clk, s_RESET)
  variable timer : integer range 0 to Period := 0;
  begin
    if ( rising_edge( s_clk ) ) then		
      if ( s_RESET = '1' ) then
	timer := 0 ;
      else
        timer := timer + 1 ;
        if ( timer = 48E+6 ) then
	  s_SW_Period_Over_Flag <= '1' ;
	  timer := 0;
	else
	  s_SW_Period_Over_Flag <= '0' ;
	end if ;
      end if ;		
    end if ;
  end process ;
  
SW_Period_Over_Flag <= s_SW_Period_Over_Flag ; end Behavioral;

 

 

Thanks in advance!

 

0 Kudos
1 Solution

Accepted Solutions
Voyager
Voyager
5,195 Views
Registered: ‎06-24-2013

Re: How to change counter range depending on an input

Jump to solution

Hey @macellan85,

 

I want to use a variable to change this period value and didn't find out how to do it yet ...

Well, you can't change the 'range' at runtime, but you can use a generic to change it at compile time like this:

entity foo is
    generic (
        MAX_RANGE : natural := 100 );
    port (
        clk : in std_logic;
        seq : out std_logic );
end entity;

architecture RTL of foo is

    signal count : integer range 0 to MAX_RANGE := 0;
    ...

Note that I don't think that this is what you actually want :)

 

So how should it be?

In your example, the highest value for Period is 10*48E+6, so defining the range for variable timer like this:

 

    variable timer : integer range 0 to 10*48E6 := 0;

... will work for all cases.

 

Hope this clarifies,

Herbert

-------------- Yes, I do this for fun!
0 Kudos
4 Replies
Voyager
Voyager
2,882 Views
Registered: ‎06-24-2013

Re: How to change counter range depending on an input

Jump to solution

Hey @macellan85,

 

The main problem here is that you cannot have a variable range in

  variable timer : integer range 0 to Period := 0;

So you basically need to set the range at compile time to the maximum possible value for your case.

 

Hope this clarifies,

Herbert

-------------- Yes, I do this for fun!
0 Kudos
Adventurer
Adventurer
2,875 Views
Registered: ‎01-05-2017

Re: How to change counter range depending on an input

Jump to solution

Hi @hpoetzl 

 

Actually that is the main point. I want to use a variable to change this period value and didn't find out how to do it yet. So "how it should be?" can be a better question may be ??

 

Thank you

0 Kudos
Voyager
Voyager
5,196 Views
Registered: ‎06-24-2013

Re: How to change counter range depending on an input

Jump to solution

Hey @macellan85,

 

I want to use a variable to change this period value and didn't find out how to do it yet ...

Well, you can't change the 'range' at runtime, but you can use a generic to change it at compile time like this:

entity foo is
    generic (
        MAX_RANGE : natural := 100 );
    port (
        clk : in std_logic;
        seq : out std_logic );
end entity;

architecture RTL of foo is

    signal count : integer range 0 to MAX_RANGE := 0;
    ...

Note that I don't think that this is what you actually want :)

 

So how should it be?

In your example, the highest value for Period is 10*48E+6, so defining the range for variable timer like this:

 

    variable timer : integer range 0 to 10*48E6 := 0;

... will work for all cases.

 

Hope this clarifies,

Herbert

-------------- Yes, I do this for fun!
0 Kudos
Adventurer
Adventurer
2,851 Views
Registered: ‎01-05-2017

Re: How to change counter range depending on an input

Jump to solution

Thanks @hpoetzl

 

This is my only question so far solved this much fast :)

 

Here is the final version of my stop_watch design. It may be useful for someothers as well...

 

 

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity Stop_Watch is
   Port ( clk : IN  STD_LOGIC  ;   -- 48 MHz
	  RESET	: IN  STD_LOGIC  ;
	  Period_Info : IN STD_LOGIC_VECTOR(7 DOWNTO 0) ;
	  SW_Period_Over_Flag : OUT STD_LOGIC );
end Stop_Watch;

architecture Behavioral of Stop_Watch is

signal s_clk : STD_LOGIC ;
signal s_RESET : STD_LOGIC ;
signal s_SW_Period_Over_Flag : STD_LOGIC ;
signal s_Period_Info : STD_LOGIC_VECTOR(7 DOWNTO 0) ;
signal Period : integer range 0 to 10*48E+6 := 0;

begin
	
  s_clk <= clk ;
  s_RESET <= RESET ;
  s_Period_Info	<= Period_Info	;
	
  Period <= 48E+6 when s_period_info = "01000001" else
	    2*48E+6 when s_period_info = "01000010" else
	    5*48E+6 when s_period_info = "01000011" else
	    10*48E+6 when s_period_info = "01000100" else
	    48E+6 ;
					 
					 
  process(s_clk, s_RESET, Period)
  variable timer : integer range 0 to 10*48E+6 := 0;
  begin
     if ( rising_edge( s_clk ) ) then
        if ( s_RESET = '1' ) then
	   timer := 0 ;
	else
	   timer := timer + 1 ;
	   if ( timer = Period ) then
	      s_SW_Period_Over_Flag <= '1' ;
	      timer := 0;
	   else
	      s_SW_Period_Over_Flag <= '0' ;
	   end if ;
	 end if ;
		
      end if ;
  end process ;

  SW_Period_Over_Flag <= s_SW_Period_Over_Flag ;

end Behavioral;

 

 

0 Kudos