Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   VHDL (http://www.velocityreviews.com/forums/f18-vhdl.html)
-   -   problem in procedure (http://www.velocityreviews.com/forums/t371473-problem-in-procedure.html)

ashu 09-19-2006 04:12 AM

problem in procedure
 
hi ,

is it possible to write any clocked function in procedure i.e. i had
written a simple DOWNCOUNTER by using procedure, but when i m calling
the procedure it is counting only up to one place like 15, 14....

can any body suggest some remedy ........code is given below

------------------------------------------------------------------------------------------------------------------------------------
ibrary ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_unsigned.all ;
use ieee.std_logic_arith.all ;



entity check is

port (
clk ,rst : in std_logic ;
count : out std_logic_vector(3 downto 0)
);

end check ;

architecture a of check is

--- declaration of procedure ---
procedure my (
signal clock ,reset : in std_logic ;
signal co : out std_logic_vector(3 downto 0)
) is



variable q : integer range 15 downto 0 ;

begin

if ( reset = '1' ) then


if (clock'event and clock = '1') then


if (q = 0) then

q := 15 ;

else

q := q - 1 ;

end if ;

co <= conv_std_logic_vector(q,4) ;

end if ;

else

q := 15 ;

co <= "1111" ;


end if ;


end my ;

begin

-------------- -------- procedure call ----- -----------------
----------------

my (clk,rst,count); ------ here it is counting only upto
14 i.e. only one place


end a ;


burn.sir@gmail.com 09-19-2006 08:43 PM

Re: problem in procedure
 
ashu wrote:
> hi ,
>
> is it possible to write any clocked function in procedure i.e. i had
> written a simple DOWNCOUNTER by using procedure, but when i m calling
> the procedure it is counting only up to one place like 15, 14....
>
> can any body suggest some remedy ........code is given below
>


if i remember correctly, you can not have wait statements inside a
procedure in synthesizable VHDL code.


check out the UART code by Mike Treseler for a simple example:
http://home.comcast.net/~mike_treseler/uart.vhd


Paul Uiterlinden 09-19-2006 09:05 PM

Re: problem in procedure
 
ashu wrote:

> hi ,
>
> is it possible to write any clocked function in procedure i.e. i had
> written a simple DOWNCOUNTER by using procedure, but when i m
> calling the procedure it is counting only up to one place like 15,
> 14....
>
> can any body suggest some remedy ........code is given below


Yikes, the indentation is awfull! There seem t be funny characters in
you code.

Anyhow, your problem is caused by the local variable q of procedure
my.

Everytime the procedure exits, the value the local variable is lost.
On entering the procedure again, it is initialized again to the left
most value of its type, 15 in this case. Hence, you see only value
14.

To avoid losing the value of a local variable, the procedure must not
exit. So an endless loop is needed. With that, also a wait statement
is needed.

I've rewritten the code below.

Please note that I use package numeric_std and function to_unsigned.
Packages std_logic_arith and std_logic_unsigned are not IEEE
standardized and should not be used anymore.

Furthermore, I've rewritten the reset a bit, so that there's only one
assignment to co and no need for the magical constant "1111". This
improves maintainability of the code.

I've not tested the code and I have no idea whether it is
synthesizable. It should simulate though.


library ieee ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all ;

entity check is
port
(
clk*,rst*:*in*std_logic*;
count****:*out*std_logic_vector(3*downto*0)
);
end*check*;

architecture a of check is

--- declaration of procedure ---
procedure my
(
signal*clock, reset*:*in* std_logic*;
signal*co**** :*out*std_logic_vector(3*downto*0)
)*is
variable q : integer range 15 downto 0 ;
begin
forever: loop
wait on clock, reset;

if*clock'event*and*clock*=*'1'*then
if*q*=*0*then
q*:=*15*;
else
q*:=*q*-*1*;
end*if*;
end*if*;

if reset = '0' then
q*:=*15*;
end*if*;

co*<=*std_logic_vecctor(to_unsigned(q, 4))*;
end loop ;
end my ;

begin
my*(clk,rst,count);*
end*a;

--
Paul.

Andy 09-20-2006 01:27 PM

Re: problem in procedure
 
You cannot do this with a variable, since you can't declare one outside
the procedure and outside of a process, but you could use an inout
signal parameter that remembers the value from one invocation to the
next.

Keep in mind that a concurrent procedure call is really inside an
implied process, with "wait on" list equal to all the in or inout
parameters in the procedure call. When the procedure exits and
re-enters when the implied process triggers again, the internal
variables are reset to their initial conditions (implied or explicit in
their declarations).

You could also put the procedure call in an explicit process, with an
appropriate sensitivity list or wait statement prior to the procedure
call. If the procedure is declared within the process, and after a
process variable, then the process sutomatically has visibility of that
variable, and it need not be even passed as a parameter. Because the
variable would be declared (and initialized, either explicilty or
implicitly) in the process, which never exits, it would retain its
value between procedure invocations.

process (clk, rst) is

-- declare variable to be used inside procedure here
variable q integer range 15 downto 0; -- initializes to 15!

-- declare procedure that uses variable here
procedure my (clk,rst .... ) is
....
begin
-- call procedure here
my(clk, rst, co);
end process;

Andy


Paul Uiterlinden wrote:
> ashu wrote:
>
> > hi ,
> >
> > is it possible to write any clocked function in procedure i.e. i had
> > written a simple DOWNCOUNTER by using procedure, but when i m
> > calling the procedure it is counting only up to one place like 15,
> > 14....
> >
> > can any body suggest some remedy ........code is given below

>
> Yikes, the indentation is awfull! There seem t be funny characters in
> you code.
>
> Anyhow, your problem is caused by the local variable q of procedure
> my.
>
> Everytime the procedure exits, the value the local variable is lost.
> On entering the procedure again, it is initialized again to the left
> most value of its type, 15 in this case. Hence, you see only value
> 14.
>
> To avoid losing the value of a local variable, the procedure must not
> exit. So an endless loop is needed. With that, also a wait statement
> is needed.
>
> I've rewritten the code below.
>
> Please note that I use package numeric_std and function to_unsigned.
> Packages std_logic_arith and std_logic_unsigned are not IEEE
> standardized and should not be used anymore.
>
> Furthermore, I've rewritten the reset a bit, so that there's only one
> assignment to co and no need for the magical constant "1111". This
> improves maintainability of the code.
>
> I've not tested the code and I have no idea whether it is
> synthesizable. It should simulate though.
>
>
> library ieee ;
> use ieee.std_logic_1164.all ;
> use ieee.numeric_std.all ;
>
> entity check is
> port
> (
> clk ,rst : in std_logic ;
> count : out std_logic_vector(3 downto 0)
> );
> end check ;
>
> architecture a of check is
>
> --- declaration of procedure ---
> procedure my
> (
> signal clock, reset : in std_logic ;
> signal co : out std_logic_vector(3 downto 0)
> ) is
> variable q : integer range 15 downto 0 ;
> begin
> forever: loop
> wait on clock, reset;
>
> if clock'event and clock = '1' then
> if q = 0 then
> q := 15 ;
> else
> q := q - 1 ;
> end if ;
> end if ;
>
> if reset = '0' then
> q := 15 ;
> end if ;
>
> co <= std_logic_vecctor(to_unsigned(q, 4)) ;
> end loop ;
> end my ;
>
> begin
> my (clk,rst,count);
> end a;
>
> --
> Paul.



Paul Uiterlinden 09-20-2006 07:27 PM

Re: problem in procedure
 
Andy wrote:

> You cannot do this with a variable,


Yes, you can (see below).

> since you can't declare one
> outside the procedure and outside of a process, but you could use an
> inout signal parameter that remembers the value from one invocation
> to the next.
>
> Keep in mind that a concurrent procedure call is really inside an
> implied process, with "wait on" list equal to all the in or inout
> parameters in the procedure call. When the procedure exits and
> re-enters when the implied process triggers again, the internal
> variables are reset to their initial conditions (implied or explicit
> in their declarations).


I think you missed the fact that I added an endless loop in the
procedure. By doing so, the procedure never exits, hence the value of
the local variable is not lost. I use this technique quite often in
behavioural models.

>> library ieee ;
>> use ieee.std_logic_1164.all ;
>> use ieee.numeric_std.all ;
>>
>> entity check is
>> port
>> (
>> clk ,rst : in std_logic ;
>> count : out std_logic_vector(3 downto 0)
>> );
>> end check ;
>>
>> architecture a of check is
>>
>> --- declaration of procedure ---
>> procedure my
>> (
>> signal clock, reset : in std_logic ;
>> signal co : out std_logic_vector(3 downto 0)
>> ) is
>> variable q : integer range 15 downto 0 ;
>> begin

-- Endless loop to retain value of variable <<<<<<<<<
-- <<<<<<<<<
>> forever: loop
>> wait on clock, reset;
>>
>> if clock'event and clock = '1' then
>> if q = 0 then
>> q := 15 ;
>> else
>> q := q - 1 ;
>> end if ;
>> end if ;
>>
>> if reset = '0' then
>> q := 15 ;
>> end if ;
>>
>> co <= std_logic_vecctor(to_unsigned(q, 4)) ;
>> end loop forever;
>> end my ;
>>
>> begin
>> my (clk,rst,count);
>> end a;


--
Paul.


Andy 09-20-2006 09:12 PM

Re: problem in procedure
 

Paul Uiterlinden wrote:
> Andy wrote:
>
> > You cannot do this with a variable,

>
> Yes, you can (see below).


I'm assuming we are talking about synthesizable code here (e.g. clocks
and resets)...

I should have said "... in a synthesizable, concurrent procedure call",
since the loop to keep the procedure from exiting requires a wait
statement to allow time to elapse, which is not allowed inside a
subprogram for synthesis.

Andy
>
> > since you can't declare one
> > outside the procedure and outside of a process, but you could use an
> > inout signal parameter that remembers the value from one invocation
> > to the next.
> >
> > Keep in mind that a concurrent procedure call is really inside an
> > implied process, with "wait on" list equal to all the in or inout
> > parameters in the procedure call. When the procedure exits and
> > re-enters when the implied process triggers again, the internal
> > variables are reset to their initial conditions (implied or explicit
> > in their declarations).

>
> I think you missed the fact that I added an endless loop in the
> procedure. By doing so, the procedure never exits, hence the value of
> the local variable is not lost. I use this technique quite often in
> behavioural models.
>
> >> library ieee ;
> >> use ieee.std_logic_1164.all ;
> >> use ieee.numeric_std.all ;
> >>
> >> entity check is
> >> port
> >> (
> >> clk ,rst : in std_logic ;
> >> count : out std_logic_vector(3 downto 0)
> >> );
> >> end check ;
> >>
> >> architecture a of check is
> >>
> >> --- declaration of procedure ---
> >> procedure my
> >> (
> >> signal clock, reset : in std_logic ;
> >> signal co : out std_logic_vector(3 downto 0)
> >> ) is
> >> variable q : integer range 15 downto 0 ;
> >> begin

> -- Endless loop to retain value of variable <<<<<<<<<
> -- <<<<<<<<<
> >> forever: loop
> >> wait on clock, reset;
> >>
> >> if clock'event and clock = '1' then
> >> if q = 0 then
> >> q := 15 ;
> >> else
> >> q := q - 1 ;
> >> end if ;
> >> end if ;
> >>
> >> if reset = '0' then
> >> q := 15 ;
> >> end if ;
> >>
> >> co <= std_logic_vecctor(to_unsigned(q, 4)) ;
> >> end loop forever;
> >> end my ;
> >>
> >> begin
> >> my (clk,rst,count);
> >> end a;

>
> --
> Paul.



Paul Uiterlinden 09-20-2006 09:22 PM

Re: problem in procedure
 
Andy wrote:

> Paul Uiterlinden wrote:
>> Andy wrote:
>>
>> > You cannot do this with a variable,

>>
>> Yes, you can (see below).

>
> I'm assuming we are talking about synthesizable code here (e.g.
> clocks and resets)...


No. I don't like synthesizable code. All those restrictions... ;-)

> I should have said "... in a synthesizable, concurrent procedure
> call", since the loop to keep the procedure from exiting requires a
> wait statement to allow time to elapse, which is not allowed inside
> a subprogram for synthesis.


Yes, now you say it that way, I fully agree. No argument about that.

--
Paul.


All times are GMT. The time now is 12:42 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.