edge detection using subprograms

Discussion in 'VHDL' started by M.Randelzhofer, Feb 5, 2005.

  1. I'm trying to simplify my vhdl code for synchronious edge detection of
    signals by using of subprograms. Unfortunately there are no examples on the
    web (or difficult to find) how sequential procedures work.

    Normally i use a sequential process to built a shift register for edge
    detection:

    process (clock)
    begin
    if (clock'event and clock ='1') then
    shift(0) <= signal ;
    shift(1) <= shift(0) ;
    end if ;
    rise <= not shift(1) and shift(0) ;
    fall <= shift(1) and not shift(0) ;
    end process;

    Now i would like to use a procedure as a subprogram, to simplify the code
    for lots of such situations.

    As i understood, functions can not be used for sequential statements, but
    procedures.

    I tried some code, but it does't work:

    procedure edge(
    signal clk,din: in STD_LOGIC ;
    signal edv: inout STD_LOGIC_VECTOR (1 downto 0)
    ) is
    begin
    if Rising_Edge(clk) then
    edv(0) <= din ;
    edv(1) <= edv(0) ;
    end if;
    end edge;

    function rise(edv: STD_LOGIC_VECTOR (1 downto 0)) return std_logic is
    begin
    return not edv(1) and edv(0) ;
    end rise ;

    function fall(edv: STD_LOGIC_VECTOR (1 downto 0)) return std_logic is
    begin
    return edv(1) and not edv(0) ;
    end fall ;

    edge(clock,clkdiv(26),ed_cd26);
    output <= rise(ed_cd26) ;

    Any hints or suggestions for working procedures ?
    Thanks in advance

    MIKE
    M.Randelzhofer, Feb 5, 2005
    #1
    1. Advertising

  2. M.Randelzhofer wrote:
    > I'm trying to simplify my vhdl code for synchronious edge detection of
    > signals by using of subprograms. Unfortunately there are no examples on the
    > web (or difficult to find) how sequential procedures work.


    Here's one way to do it:
    http://groups-beta.google.com/groups?q=vhdl ck_rising smit

    -- Mike Treseler
    Mike Treseler, Feb 5, 2005
    #2
    1. Advertising

  3. Mike Treseler, Feb 5, 2005
    #3
  4. "Mike Treseler" <> schrieb im Newsbeitrag
    news:...
    > http://groups-beta.google.com/groups?q=vhdl ck_rising urban
    >
    > is a more complete example.
    >
    > -- Mike Treseler


    Thank you very much for the examples.
    Interesting kind of variable processing, remembers me of some kind of state
    machines.
    However this doesn't simplify my code. At the end i have to explain that to
    my customers.
    Seems that a sequential 'macro' is not so easy to implement in VHDL.

    MIKE
    M.Randelzhofer, Feb 5, 2005
    #4
  5. On Sat, 5 Feb 2005 17:33:54 +0100,
    "M.Randelzhofer" <> wrote:


    >Normally i use a sequential process to built a shift register for edge
    >detection:
    >
    >process (clock)
    >begin
    > if (clock'event and clock ='1') then
    > shift(0) <= signal ;
    > shift(1) <= shift(0) ;
    > end if ;
    > rise <= not shift(1) and shift(0) ;
    > fall <= shift(1) and not shift(0) ;
    >end process;


    Many synthesis tools will reject this process,
    because the assignments to "rise" and "fall"
    are performed both on rising and on falling edges
    of the clock. Consider splitting it into two
    processes, one synchronous and one combinational.


    >Now i would like to use a procedure as a subprogram, to simplify the code
    >for lots of such situations.


    [...]

    A subprogram is called by some other sequential code, executes
    for a certain length of time, and then terminates and returns
    to its calling code.

    A process starts executing at time zero, and then runs forever
    as an independent piece of activity.

    It would make no sense to bury your process in the middle
    of another process, so equally it makes no sense to try to
    call a subprogram to do the same thing.

    The obvious way to modularise this kind of thing is by
    building an entity to contain it, and then instantiating
    the entity. However, there is another possibility that
    is sometimes neater: use a concurrent procedure. This
    is simply a way of packaging a process so that you can
    "instantiate" it, but without the extra overhead of
    defining a component and so on. However, a concurrent
    procedure effectively becomes a process, and so it would
    have the same problem that I pointed out for your
    original process - it's a synchronous process with
    combinational outputs, and therefore should not be
    described as a single process for synthesis.
    --
    Jonathan Bromley, Consultant

    DOULOS - Developing Design Know-how
    VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

    Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
    Tel: +44 (0)1425 471223 mail:
    Fax: +44 (0)1425 471573 Web: http://www.doulos.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
    Jonathan Bromley, Feb 7, 2005
    #5
  6. M.Randelzhofer wrote:

    > Thank you very much for the examples.
    > Interesting kind of variable processing, remembers me of some kind of state
    > machines.
    > However this doesn't simplify my code. At the end i have to explain that to
    > my customers.
    > Seems that a sequential 'macro' is not so easy to implement in VHDL.


    --OK I'll bite.
    --Let's get rid of the nasty variables.

    --If we clean up your example we have:
    ------------------------------------
    library ieee;
    use ieee.std_logic_1164.all;
    entity rise_fall is

    port (clock : in std_ulogic;
    serial_in : in std_ulogic;
    rise : out std_ulogic;
    fall : out std_ulogic
    );
    end entity rise_fall;

    architecture plain of rise_fall is
    signal shift : std_logic_vector(1 downto 0);
    begin
    process (clock)
    begin
    if (clock'event and clock = '1') then
    shift(0) <= serial_in;
    shift(1) <= shift(0);
    rise <= not shift(1) and shift(0);
    fall <= shift(1) and not shift(0);
    end if;
    end process;
    end architecture plain;
    --------------------------------------

    --Now, if you like, we could do
    --the rise and fall values like this

    architecture fun of rise_fall is
    signal shift : std_logic_vector(1 downto 0);
    begin
    process (clock)
    impure function rise_f (arg : std_logic_vector(1 downto 0))
    return std_ulogic is begin
    return not arg(1) and arg(0);
    end function rise_f;

    impure function fall_f (arg : std_logic_vector(1 downto 0))
    return std_ulogic is begin
    return arg(1) and not arg(0);
    end function fall_f;
    begin
    if (clock'event and clock = '1') then
    shift(0) <= serial_in;
    shift(1) <= shift(0);
    rise <= rise_f(shift);
    fall <= fall_f(shift);
    end if;
    end process;
    end architecture fun; -- --

    -- Or we could replace the rise and fall
    -- statements with procedures like this

    architecture proc of rise_fall is
    signal shift : std_logic_vector(1 downto 0);
    signal rise_s, fall_s : std_ulogic;
    begin
    process (clock)
    procedure edges(
    arg : in std_logic_vector(1 downto 0);
    signal out_rise : out std_ulogic;
    signal out_fall : out std_ulogic
    ) is
    begin
    out_rise <= not arg(1) and arg(0);
    out_fall <= arg(1) and not arg(0);
    end procedure edges;
    begin
    if (clock'event and clock = '1') then
    shift(0) <= serial_in;
    shift(1) <= shift(0);
    edges(shift, rise, fall);
    end if;
    end process;
    end architecture proc;


    -- Mike Treseler
    Mike Treseler, Feb 7, 2005
    #6
  7. M.Randelzhofer

    Jim Lewis Guest

    Mike,
    Functionally the subprogram you wrote (edge) is correct.
    In fact, I believe it is compliant with the 2004 version
    of IEEE 1076.6 the VHDL RTL Synthesis specification.

    Currently vendors have not implemented all features of
    IEEE 1076.6-2004 yet. They are waiting for you to tell them
    what is important. Your way to do this is to turn you
    example in to your vendor as a bug and let them know it
    is compliant with 1076.6-2004.

    Going further 1076.6-2004 provides coding styles for a wide
    variety of things. One of these is a portable coding
    style for a DPRAM. If this is useful to you, let your
    vendor know. I know this sounds silly at first, but think
    of it from the other side - are you going to invest in
    something if it does not bring significant value to your
    customers?

    Cheers,
    Jim Lewis
    P.S.
    You might get more utility our of your procedure if
    you used an unconstrained array. For readability,
    you also might consider renaming it something like
    ShiftReg rather than edge
    --
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Jim Lewis
    Director of Training mailto:
    SynthWorks Design Inc. http://www.SynthWorks.com
    1-503-590-4787

    Expert VHDL Training for Hardware Design and Verification
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    > I'm trying to simplify my vhdl code for synchronious edge detection of
    > signals by using of subprograms. Unfortunately there are no examples on the
    > web (or difficult to find) how sequential procedures work.
    >
    > Normally i use a sequential process to built a shift register for edge
    > detection:
    >
    > process (clock)
    > begin
    > if (clock'event and clock ='1') then
    > shift(0) <= signal ;
    > shift(1) <= shift(0) ;
    > end if ;
    > rise <= not shift(1) and shift(0) ;
    > fall <= shift(1) and not shift(0) ;
    > end process;
    >
    > Now i would like to use a procedure as a subprogram, to simplify the code
    > for lots of such situations.
    >
    > As i understood, functions can not be used for sequential statements, but
    > procedures.
    >
    > I tried some code, but it does't work:
    >
    > procedure edge(
    > signal clk,din: in STD_LOGIC ;
    > signal edv: inout STD_LOGIC_VECTOR (1 downto 0)
    > ) is
    > begin
    > if Rising_Edge(clk) then
    > edv(0) <= din ;
    > edv(1) <= edv(0) ;
    > end if;
    > end edge;
    >
    > function rise(edv: STD_LOGIC_VECTOR (1 downto 0)) return std_logic is
    > begin
    > return not edv(1) and edv(0) ;
    > end rise ;
    >
    > function fall(edv: STD_LOGIC_VECTOR (1 downto 0)) return std_logic is
    > begin
    > return edv(1) and not edv(0) ;
    > end fall ;
    >
    > edge(clock,clkdiv(26),ed_cd26);
    > output <= rise(ed_cd26) ;
    >
    > Any hints or suggestions for working procedures ?
    > Thanks in advance
    >
    > MIKE
    >
    Jim Lewis, Feb 9, 2005
    #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. Raghavendra

    Edge Detection circuit.

    Raghavendra, Oct 8, 2004, in forum: VHDL
    Replies:
    17
    Views:
    32,455
    digitalpbk
    Jun 30, 2009
  2. apurva

    false edge detection

    apurva, Aug 18, 2006, in forum: VHDL
    Replies:
    1
    Views:
    633
    Jerry Avins
    Aug 18, 2006
  3. Ferdi Smit
    Replies:
    0
    Views:
    758
    Ferdi Smit
    Oct 10, 2005
  4. denish
    Replies:
    5
    Views:
    5,580
  5. kumar9422

    edge detection using sobel

    kumar9422, May 29, 2010, in forum: VHDL
    Replies:
    0
    Views:
    1,719
    kumar9422
    May 29, 2010
Loading...

Share This Page