problem in procedure

Discussion in 'VHDL' started by ashu, Sep 19, 2006.

  1. ashu

    ashu Guest

    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 ;
     
    ashu, Sep 19, 2006
    #1
    1. Advertising

  2. ashu

    Guest

    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
     
    , Sep 19, 2006
    #2
    1. Advertising

  3. 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, Sep 19, 2006
    #3
  4. ashu

    Andy Guest

    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.
     
    Andy, Sep 20, 2006
    #4
  5. 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.
     
    Paul Uiterlinden, Sep 20, 2006
    #5
  6. ashu

    Andy Guest

    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.
     
    Andy, Sep 20, 2006
    #6
  7. 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.
     
    Paul Uiterlinden, Sep 20, 2006
    #7
    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. Leon Shaw

    Stored Procedure Problem

    Leon Shaw, Jul 28, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    373
    Jurjen de Groot
    Jul 29, 2003
  2. ElmoWatson

    Stored Procedure/Parameter problem

    ElmoWatson, Aug 4, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    493
    Jerry
    Aug 6, 2003
  3. Bilbo
    Replies:
    3
    Views:
    427
    Bilbo
    Nov 20, 2003
  4. Mike P
    Replies:
    0
    Views:
    3,306
    Mike P
    Jun 19, 2006
  5. AlexWare
    Replies:
    2
    Views:
    761
    Paul Uiterlinden
    Oct 23, 2009
Loading...

Share This Page