recursive description with generate and processes

Discussion in 'VHDL' started by Joerg Ritter, Nov 21, 2003.

  1. Joerg Ritter

    Joerg Ritter Guest

    hi,
    please consider the following recusive description of a component
    calculating the flags 'a', 'p' and 'g' of an Ladner/Fisher-like adder.
    This code is working and was validated using a VHDL-Simulator.

    Lets exchange the part

    POSTPROCESSING_B:
    for i in n/2-1 downto 0 generate
    flag_out(2*i+1) <= f_rec_out(i);
    end generate;

    with a process like this

    process(f_rec_out)
    begin
    for i in n/2-1 downto 0 loop
    flag_out(2*i+1) <= f_rec_out(i);
    end loop;
    end

    This results in more then one drivers per signal for flag_out. It seems
    to be, that the process doesnt use the flag_out signal at the specific
    recursion level, instead assigns always to the port flag_out at the top
    level.
    Could anybody give a meaningful explanation ?

    Thanks
    Joerg




    library IEEE;
    library WORK;
    use IEEE.std_logic_1164.all;
    use WORK.apg_arithmetic.all;

    entity flag_comp is
    generic (n: positive);
    port
    (flag_in: in apg_vector (n-1 downto 0);
    flag_out: out apg_vector (n-1 downto 0));
    end flag_baustein;

    architecture parallel_adder of flag_comp is
    component con
    port (l, r: in apgType;
    flag_out: out apgType);
    end component;
    component flag_comp
    generic (n: positive);
    port (flag_in: in apg_vector (n-1 downto 0);
    flag_out: out apg_vector (n-1 downto 0));
    end component;
    begin
    rekursion: if n>2 generate
    signal f_rec_out,f_rec_in: apg_vector (n/2-1 downto 0);
    begin
    PREPROCESSING:
    for i in n/2-1 downto 0 generate
    CON_CELL_1: con
    port map (l => flag_in(2*i+1), r => flag_in(2*i),
    flag_out => f_rec_in(i));
    end generate;
    RECURSIVE_CELL: flag_comp
    generic map (n/2)
    port map (flag_in => f_rec_in, flag_out => f_rec_out);
    POSTPROCESSING_COMP:
    for i in n/2-2 downto 0 generate
    CON_CELL_2: con
    port map (l => flag_in(2*i+2), r => f_rec_out(i) ,
    flag_out => flag_out(2*i+2));
    end generate;
    POSTPROCESSING_B:
    for i in n/2-1 downto 0 generate
    flag_out(2*i+1) <= f_rec_out(i);
    end generate;
    flag_out(0) <= flag_in(0);
    end generate;
    stop_recursion2:
    if n=2 generate
    CON_CELL_3: con
    port map (l => flag_in(1), r => flag_in(0),
    flag_out => flag_out(1));
    flag_out(0) <= flag_in(0);
    end generate;
    stop_recursion1: if n=1 generate
    flag_out(0) <= flag_in(0);
    end generate;
    end parallel_adder;
     
    Joerg Ritter, Nov 21, 2003
    #1
    1. Advertising

  2. Joerg Ritter wrote:

    > This code is working and was validated using a VHDL-Simulator.
    >
    > Lets exchange the part
    >
    > POSTPROCESSING_B:
    > for i in n/2-1 downto 0 generate
    > flag_out(2*i+1) <= f_rec_out(i);
    > end generate;
    >
    > with a process like this
    >
    > process(f_rec_out)
    > begin
    > for i in n/2-1 downto 0 loop
    > flag_out(2*i+1) <= f_rec_out(i);
    > end loop;
    > end
    >
    > This results in more then one drivers per signal for flag_out. It seems
    > to be, that the process doesnt use the flag_out signal at the specific
    > recursion level, instead assigns always to the port flag_out at the top
    > level.
    > Could anybody give a meaningful explanation ?


    Hard to say without seeing the apg_arithmetic package.
    I looks like flag_out is in architecture scope
    in both cases. The problem may be an index overlap
    of some sort.

    Note also:
    end flag_baustein; -- syntax error


    -- Mike Treseler
     
    Mike Treseler, Nov 21, 2003
    #2
    1. Advertising

  3. Joerg Ritter

    Joerg Ritter Guest

    Mike Treseler wrote:
    enclosed please find the used apg package and the corrected code for the
    e/a flag_comp.

    >> This code is working and was validated using a VHDL-Simulator.
    >>
    >> Lets exchange the part
    >>
    >> POSTPROCESSING_B:
    >> for i in n/2-1 downto 0 generate
    >> flag_out(2*i+1) <= f_rec_out(i);
    >> end generate;
    >>
    >> with a process like this
    >>
    >> process(f_rec_out)
    >> begin
    >> for i in n/2-1 downto 0 loop
    >> flag_out(2*i+1) <= f_rec_out(i);
    >> end loop;
    >> end
    >>
    >> This results in more then one drivers per signal for flag_out. It
    >> seems to be, that the process doesnt use the flag_out signal at the
    >> specific recursion level, instead assigns always to the port flag_out
    >> at the top level.
    >> Could anybody give a meaningful explanation ?

    >
    >
    > Hard to say without seeing the apg_arithmetic package.
    > I looks like flag_out is in architecture scope
    > in both cases. The problem may be an index overlap
    > of some sort.


    as you can see in the above statements, the two loops are identically.
    One within a process, one with an generate statement.
    The first one is working, so there is no index overlap/mismatch.

    thanks
    Joerg

    -------------------------------------------------------
    library IEEE;
    library WORK;
    use IEEE.std_logic_1164.all;
    use WORK.apg_arithmetic.all;

    entity flag_comp is
    generic (n: positive);
    port
    (flag_in: in apg_vector (n-1 downto 0);
    flag_out: out apg_vector (n-1 downto 0));
    end flag_comp;

    architecture parallel_adder of flag_comp is
    component con
    port (l, r: in apgType;
    flag_out: out apgType);
    end component;
    component flag_comp
    generic (n: positive);
    port (flag_in: in apg_vector (n-1 downto 0);
    flag_out: out apg_vector (n-1 downto 0));
    end component;
    begin
    rekursion: if n>2 generate
    signal f_rec_out,f_rec_in: apg_vector (n/2-1 downto 0);
    begin
    PREPROCESSING:
    for i in n/2-1 downto 0 generate
    CON_CELL_1: con
    port map (l => flag_in(2*i+1), r => flag_in(2*i),
    flag_out => f_rec_in(i));
    end generate;
    RECURSIVE_CELL: flag_comp
    generic map (n/2)
    port map (flag_in => f_rec_in, flag_out => f_rec_out);
    POSTPROCESSING_COMP:
    for i in n/2-2 downto 0 generate
    CON_CELL_2: con
    port map (l => flag_in(2*i+2), r => f_rec_out(i) ,
    flag_out => flag_out(2*i+2));
    end generate;
    POSTPROCESSING_B:
    for i in n/2-1 downto 0 generate
    flag_out(2*i+1) <= f_rec_out(i);
    end generate;
    flag_out(0) <= flag_in(0);
    end generate;
    stop_recursion2:
    if n=2 generate
    CON_CELL_3: con
    port map (l => flag_in(1), r => flag_in(0),
    flag_out => flag_out(1));
    flag_out(0) <= flag_in(0);
    end generate;
    stop_recursion1: if n=1 generate
    flag_out(0) <= flag_in(0);
    end generate;
    end parallel_adder;

    -------------------------------------------------------
    library IEEE;
    library WORK;
    use IEEE.std_logic_1164.all;
    use work.apg_arithmetic.all;


    entity con is
    port (l,r : in apgType;
    flag_out : out apgType);
    end con;

    architecture verhalten of con is
    begin
    flag_out <= l + r;
    end verhalten;
    -------------------------------------------------------

    library ieee;
    package apg_arithmetic is
    type apgType is ( a , p , g );
    type apg_vector is array ( natural range <> ) of apgType;
    constant ABSORBING : apgType := a;
    constant PROPAGATING: apgType := p;
    constant GENERATING : apgType := g;

    function "+" (left_flag, right_flag: in apgType)
    return apgType;
    function stdlogic2apg (op1, op2: in std_logic)
    return apgType;
    function stdlogic2apg (op1, op2: in std_logic_vector)
    return apg_vector;
    end package apg_arithmetic;
    package body apg_arithmetic is

    function "+" (left_flag, right_flag: in apgType)
    return apgType is
    variable result: apgType;
    begin
    result:=left_flag;
    if (left_flag=PROPAGATING) then
    result:=right_flag;
    end if;
    return result;
    end;
    function stdlogic2apg (op1, op2: in std_logic)
    return apgType is
    variable result: apgType;
    begin
    if (op1 xor op2)='1' then
    result:= PROPAGATING;
    elsif (op1 and op2)='1' then
    result:= GENERATING;
    else
    result:= ABSORBING;
    end if;
    return result;
    end;
    function stdlogic2apg (op1, op2: in std_logic_vector)
    return apg_vector is
    variable result: apg_vector(op1'length-1 downto 0);
    begin
    for i in op1'range loop
    result(i):=stdlogic2apg(op1(i),op2(i));
    end loop;
    return result;
    end;
    end apg_arithmetic;
     
    Joerg Ritter, Nov 24, 2003
    #3
  4. Joerg Ritter wrote:
    > Mike Treseler wrote:
    > enclosed please find the used apg package and the corrected code for the
    > e/a flag_comp.
    >
    >>> This code is working and was validated using a VHDL-Simulator.
    >>>
    >>> Lets exchange the part
    >>>
    >>> POSTPROCESSING_B:
    >>> for i in n/2-1 downto 0 generate
    >>> flag_out(2*i+1) <= f_rec_out(i);
    >>> end generate;
    >>>
    >>> with a process like this
    >>>
    >>> process(f_rec_out)
    >>> begin
    >>> for i in n/2-1 downto 0 loop
    >>> flag_out(2*i+1) <= f_rec_out(i);
    >>> end loop;
    >>> end


    This substitution works fine for sim and synth
    as long as you don't touch the last two statements
    of the "generate rekursion" loop.

    Consider using labels on the end statements.

    -- Mike Treseler

    -----------------------------------------
    POSTPROCESSING_B:
    process(f_rec_out) begin
    for i in n/2-1 downto 0 loop
    flag_out(2*i+1) <= f_rec_out(i);
    end loop;
    end process POSTPROCESSING_B;

    -- POSTPROCESSING_B:
    -- for i in n/2-1 downto 0 generate
    -- flag_out(2*i+1) <= f_rec_out(i);
    -- end generate POSTPROCESSING_B;

    flag_out(0) <= flag_in(0);
    end generate rekursion;
    ------------------------------------------
     
    Mike Treseler, Nov 24, 2003
    #4
  5. Joerg Ritter

    Joerg Ritter Guest

    > This substitution works fine for sim and synth
    > as long as you don't touch the last two statements
    > of the "generate rekursion" loop.
    >
    > Consider using labels on the end statements.
    >
    > -- Mike Treseler
    >
    > -----------------------------------------
    > POSTPROCESSING_B:
    > process(f_rec_out) begin
    > for i in n/2-1 downto 0 loop
    > flag_out(2*i+1) <= f_rec_out(i);
    > end loop;
    > end process POSTPROCESSING_B;
    >
    > -- POSTPROCESSING_B:
    > -- for i in n/2-1 downto 0 generate
    > -- flag_out(2*i+1) <= f_rec_out(i);
    > -- end generate POSTPROCESSING_B;
    >
    > flag_out(0) <= flag_in(0);
    > end generate rekursion;
    > ------------------------------------------


    with exactly this substitution, the initialization of ActiveHDL 5.1
    fails with the error message:
    "Signal flag_out has multiple sources but is not resolved"

    the labels after end generate are optional, isn't it ?



    joerg
     
    Joerg Ritter, Nov 25, 2003
    #5
  6. Joerg Ritter wrote:

    > with exactly this substitution, the initialization of ActiveHDL 5.1
    > fails with the error message:
    > "Signal flag_out has multiple sources but is not resolved"


    It works fine on modelsim and leo.
    Submit your code to aldec.

    > the labels after end generate are optional, isn't it ?


    Yes.


    -- Mike Treseler
     
    Mike Treseler, Nov 25, 2003
    #6
  7. Joerg Ritter

    Joerg Ritter Guest

    Hi Mike,


    >> with exactly this substitution, the initialization of ActiveHDL 5.1
    >> fails with the error message:
    >> "Signal flag_out has multiple sources but is not resolved"

    >
    >
    > It works fine on modelsim and leo.
    > Submit your code to aldec.
    >
    >> the labels after end generate are optional, isn't it ?

    >
    >
    > Yes.


    you are right.
    with symphony sonata I can simulate the design. seems to be a bug in
    activeHDL of aldec.
    thanks a lot !



    >
    >
    > -- Mike Treseler
    >
     
    Joerg Ritter, Nov 26, 2003
    #7
  8. Joerg Ritter

    Jerry Guest

    Joerg Ritter <-halle.de> wrote in message news:<bq2c9b$8lk$-halle.de>...
    > Hi Mike,
    >
    >
    > >> with exactly this substitution, the initialization of ActiveHDL 5.1
    > >> fails with the error message:
    > >> "Signal flag_out has multiple sources but is not resolved"

    > >
    > >
    > > It works fine on modelsim and leo.
    > > Submit your code to aldec.
    > >
    > >> the labels after end generate are optional, isn't it ?

    > >
    > >
    > > Yes.

    >
    > you are right.
    > with symphony sonata I can simulate the design. seems to be a bug in
    > activeHDL of aldec.
    > thanks a lot !



    Sorry guys, but it is modelsim and leonardo and sonata misinterpreting VHDL.
    A: FOR..GENERATE with concurrent signal assignment IS NOT an equivalent
    of one process statement. FOR..GENERATE expands to the number of BLOCK
    statements equal the number of values in the range. Each block contains one
    concurrent signal assignment, which is equivalent of a process statement
    with one sequential signal assignment inside.
    B: Signal assignment inside the process creates driver for the LONGEST
    STATIC PREFIX of the target. Since variable is used for indexing in the
    signal assignment, the longest static prefix is the ENTIRE VECTOR, not just
    one element.
    As the result, each process created after expansion of FOR..GENERATE is
    driving entire target; so we do have multiple drivers for unresolved signal...

    Jerry
     
    Jerry, Dec 1, 2003
    #8
  9. Jerry wrote:

    > As the result, each process created after expansion of FOR..GENERATE is
    > driving entire target; so we do have multiple drivers for unresolved signal...


    In Joerg's original code, the FOR..GENERATE case worked fine.
    It was the single process loop replacement that gave him errors.

    Do you mean to say that both cases have multiple drivers?

    -- Mike Treseler
     
    Mike Treseler, Dec 1, 2003
    #9
  10. Joerg Ritter

    Joerg Ritter Guest

    > Sorry guys, but it is modelsim and leonardo and sonata misinterpreting VHDL.
    > A: FOR..GENERATE with concurrent signal assignment IS NOT an equivalent
    > of one process statement. FOR..GENERATE expands to the number of BLOCK
    > statements equal the number of values in the range. Each block contains one
    > concurrent signal assignment, which is equivalent of a process statement
    > with one sequential signal assignment inside.
    > B: Signal assignment inside the process creates driver for the LONGEST
    > STATIC PREFIX of the target. Since variable is used for indexing in the
    > signal assignment, the longest static prefix is the ENTIRE VECTOR, not just
    > one element.
    > As the result, each process created after expansion of FOR..GENERATE is
    > driving entire target; so we do have multiple drivers for unresolved signal...
    >


    the for..generate works as aspected, at least in my opinion.
    could you explain your idea in more detail ?

    thanks
    joerg
     
    Joerg Ritter, Dec 2, 2003
    #10
  11. Joerg Ritter

    Marcin Guest

    Mike,

    For..generate along with flag_out(0) <= flag_in(0); assignment it is
    still one driver for flag_out signal. Compiler elabortes it staticaly.
    Process with loop statement is dynamicaly elaborated and compiler
    assigns a new driver for flag_out, the second one is from flag_out(0)
    <= flag_in(0);

    Regards,

    Marcin

    Mike Treseler <> wrote in message news:<>...
    > Jerry wrote:
    >
    > > As the result, each process created after expansion of FOR..GENERATE is
    > > driving entire target; so we do have multiple drivers for unresolved signal...

    >
    > In Joerg's original code, the FOR..GENERATE case worked fine.
    > It was the single process loop replacement that gave him errors.
    >
    > Do you mean to say that both cases have multiple drivers?
    >
    > -- Mike Treseler
     
    Marcin, Dec 6, 2003
    #11
    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. Edward Watts
    Replies:
    6
    Views:
    3,797
    Edward Watts
    Jan 30, 2006
  2. Jeff Rodriguez
    Replies:
    23
    Views:
    1,158
    David Schwartz
    Dec 9, 2003
  3. n00m
    Replies:
    12
    Views:
    1,122
  4. vamsi
    Replies:
    21
    Views:
    2,113
    Keith Thompson
    Mar 9, 2009
  5. Marc Heiler
    Replies:
    1
    Views:
    183
    Robert Klemme
    May 24, 2009
Loading...

Share This Page