Conditional Generates

Discussion in 'VHDL' started by Andy, Jun 12, 2006.

  1. Andy

    Andy Guest

    Hello All,

    I've a question with regards to conditional generates. I'm using a 'for
    generate' to interconnect an array of signals. I'm then using the index
    of this generate to set the connectivity of the array.

    The following is an example to demonstrate the problem (A complete
    example module is described below). It seems that 'Method One' should
    work, as x-1 is only used when x>0. However, Modelsim complains about
    the indexing being out of range. If, however, I use method Two,
    everything is OK.

    VectorNextLogic : for x in 0 to 7 generate
    begin

    -- Method One (doesn't work)
    dataVector(x) <= dIn(x) xor dataVector(7) when (x=0) else
    dIn(x) xor dataVector(x-1);

    -- Method Two (does work)
    BitConnect0 : if (x=0) generate
    begin
    dataVectorNext(x) <= dIn(x) xor dataVector(7);
    end generate;

    BitConnect1 : if (x>0) generate
    begin
    dataVectorNext(x) <= dIn(x) xor dataVector(x-1);
    end generate;

    end generate;

    I'm guessing that 'Method One' is not legal/valid VHDL, but would like
    to know for sure. Also, is 'method Two' the only available approach to
    this problem? It seems far more prone to error, and in the real module
    in which I need to do this, it would require a great deal more code.

    Any help/advice/comments much appreciated.
    Many Thanks
    Andy


    References:
    http://groups.google.co.uk/group/co...read/thread/e66302c5b11aa0c1/50ee70d2b0aa9287

    For Module:

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

    entity Test is
    port ( clk : in std_logic;
    nReset : in std_logic;
    dIn : in std_logic_vector(7 downto 0);
    dOut : out std_logic_vector(7 downto 0));
    end Test;

    architecture General of Test is

    signal dataVectorNext : std_logic_vector(7 downto 0);
    signal dataVector : std_logic_vector(7 downto 0);

    begin

    dOut <= dataVector;

    process (clk)
    begin

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

    if (nReset='0') then
    dataVector <= (others => '0');

    else
    dataVector <= dataVectorNext;

    end if;
    end if;
    end process;

    VectorNextLogic : for x in 0 to 7 generate
    begin

    -- Method One (doesn't work)
    dataVector(x) <= dIn(x) xor dataVector(7) when (x=0) else
    dIn(x) xor dataVector(x-1);

    -- Method Two (does work)
    BitGen0 : if (x=0) generate
    begin
    dataVectorNext(x) <= dIn(x) xor dataVector(7);
    end generate;

    BitGen1 : if (x>0) generate
    begin
    dataVectorNext(x) <= dIn(x) xor dataVector(x-1);
    end generate;

    end generate;

    end General;
    Andy, Jun 12, 2006
    #1
    1. Advertising

  2. Andy

    KJ Guest

    Doesn't directly address the question about the generate but

    -- Method Three (might work)
    dataVector(x) <= dIn(x) xor dataVector((x-1) mod 8);

    KJ
    KJ, Jun 12, 2006
    #2
    1. Advertising

  3. Andy

    Andy Guest

    KJ wrote:
    > Doesn't directly address the question about the generate but
    >
    > -- Method Three (might work)
    > dataVector(x) <= dIn(x) xor dataVector((x-1) mod 8);
    >
    > KJ
    >

    KJ,

    Thanks for the pointer. That's a trick I've used before when working
    with arrays that wrap around. Very handy when doing things like cellular
    Automata. But in this case that doesn't happen.

    What interests me more is that, x-1 when x=0 should never need to be
    calculated, so an out of range 'should' never occur.

    Cheers
    Andy
    Andy, Jun 12, 2006
    #3
  4. Mike Treseler, Jun 13, 2006
    #4
  5. On Mon, 12 Jun 2006 20:51:01 +0100, Andy
    <> wrote:

    > It seems that 'Method One' should
    >work, as x-1 is only used when x>0. However, Modelsim complains about
    >the indexing being out of range. If, however, I use method Two,
    >everything is OK.
    >
    >VectorNextLogic : for x in 0 to 7 generate
    >begin
    >
    > -- Method One (doesn't work)
    > dataVector(x) <= dIn(x) xor dataVector(7) when (x=0) else
    > dIn(x) xor dataVector(x-1);
    >
    > -- Method Two (does work)
    > BitConnect0 : if (x=0) generate
    > begin
    > dataVectorNext(x) <= dIn(x) xor dataVector(7);
    > end generate;
    >
    > BitConnect1 : if (x>0) generate
    > begin
    > dataVectorNext(x) <= dIn(x) xor dataVector(x-1);
    > end generate;
    >
    >end generate;


    I believe ModelSim is right here. The conditional signal assignment
    works not only with constants but also with any expression as the
    conditional, so "datavector(x-1)" is part of the overall expression;
    I know that (x=0) is a constant expression, but that's an
    optimisation issue. Effectively, one pass of your generate
    loop gets re-written as

    dataVector(0) <= dIn(0) xor dataVector(7) when (TRUE) else
    dIn(0) xor dataVector(-1);

    and the error is manifest long before anyone gets to deciding
    that the second branch is unused.

    I agree that your "Method 2" is tiresome; VHDL's
    lack of "else" on "if...generate" is pretty painful here.

    I guess the example you've posted is a simplified version of what
    you're really trying to do, so you need a reasonably robust fix.
    How about the following...

    G: for x in dataVector'range generate
    datavector(x) <= dIn(x) xor dataVector( index_shuffle(x) );
    endgenerate;

    where "index_shuffle" is a function that takes the integer
    value x and returns the modified index you want. Now all
    the messy complexity can be pushed into the function.
    What's more, you can avoid any compiler warnings
    by declaring the function so that its return value is of
    type "dataVector'range", so the body of the generate
    statement cannot possibly have any out-of-range access.

    hth
    --
    Jonathan Bromley, Consultant

    DOULOS - Developing Design Know-how
    VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

    Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
    Jonathan Bromley, Jun 13, 2006
    #5
  6. Andy wrote:

    > I've a question with regards to conditional generates.


    Jonathan has provided excellent answers, as usual,
    but I have another question for anyone interested.

    What is a possible upside to generating processes
    and wiring them up vs. using some array
    type and declaring some variables to be
    updated every clock in a single processs?

    So far, I have:

    1. A generate could drive a tri-state pin interface.
    2. ?

    The generate loop works and is very popular,
    but it is also very tedious on the edges
    and in the wiring.

    -- Mike Treseler
    Mike Treseler, Jun 13, 2006
    #6
  7. On Tue, 13 Jun 2006 11:06:18 -0700, Mike Treseler
    <> wrote:

    >What is a possible upside to generating processes
    >and wiring them up vs. using some array
    >type and declaring some variables to be
    >updated every clock in a single processs?
    >
    >So far, I have:
    > 1. A generate could drive a tri-state pin interface.


    And, in general, it's rather easier to control what
    drivers you're creating when using generate.
    Sometimes that matters. Most times, though,
    there's an easier way around it. I'm not as
    completely convinced as Mike of the virtues of
    big single-process designs - I was brought up on
    Occam and CSP, so my instinct is to decompose
    a design into blocks that communicate in a
    well-structured way - but for anything
    algorithmic, software-like processes are IMHO
    something that's worth striving for.

    > 2. ?


    My standard answer to that always used to be
    "because generates allow you to describe variable-
    sized structures, and allow you to declare the variable-
    sized interconnects between the parts of those structures".
    For Verilog, this would be completely true, I think. But
    in VHDL we have the delights of dynamically-elaborated
    subprograms - the variables in a function are manufactured
    only when the function is called - and this does pretty
    much everything you need for building funny-shaped
    hardware: trees, jagged arrays and the like. Any
    interconnect that gets unnecessarily declared will
    in due course be optimised away by synthesis. So
    my views on this are increasingly aligned with Mike's.

    However, you may well be confronted with existing
    design fragments that are structured as components
    or processes, and you need to create groupings of
    those things. In such a case, generate provides an
    easy way out.

    >The generate loop works and is very popular,
    >but it is also very tedious on the edges
    >and in the wiring.


    It's hard to disagree.
    --
    Jonathan Bromley, Consultant

    DOULOS - Developing Design Know-how
    VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

    Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
    Jonathan Bromley, Jun 13, 2006
    #7
  8. Jonathan Bromley wrote:

    > I was brought up on
    > Occam and CSP, so my instinct is to decompose
    > a design into blocks that communicate in a
    > well-structured way -


    You are ahead of your time.
    At some high level, communication becomes
    serial and very well-structured. It used
    to be cross-country. Buses like
    PCIe make it happen at a few centimeters.
    I have no doubt this will become
    a canned, on-chip "buffer" someday.

    > but for anything
    > algorithmic, software-like processes are IMHO
    > something that's worth striving for.


    That's a software-like thread
    describing *parallel* hardware.
    The point is to get the outputs
    I really want without mentioning
    every wire and mux involved.

    A vhdl process is a fantastic virtual
    machine with registers arranged
    and updated however I like.
    Synthesis maintains this illusion
    by unwinding procedures, arrays, and loops
    without complaint. Simulation lets me
    take a test drive before actual
    construction has even begun.

    > However, you may well be confronted with existing
    > design fragments that are structured as components
    > or processes, and you need to create groupings of
    > those things. In such a case, generate provides an
    > easy way out.


    That's a fine list item 2.
    There is plenty of working code around
    that I prefer to leave in the black box.

    Thanks for the reply.

    -- Mike Treseler
    Mike Treseler, Jun 13, 2006
    #8
  9. Andy

    KJ Guest

    "Mike Treseler" <> wrote in message
    news:...
    > Andy wrote:
    >


    > What is a possible upside to generating processes
    > and wiring them up vs. using some array
    > type and declaring some variables to be
    > updated every clock in a single processs?
    >
    > So far, I have:
    >
    > 1. A generate could drive a tri-state pin interface.
    > 2. ?
    >

    This is pretty much along the same lines as Jonathon's earlier reply, but
    generated processes would seem to fit in better when the 'other' things in
    the architecture don't fit into that single clocked process model (i.e. the
    'other' things being components that need to be instantiated and
    combinatorial equations). One example that I've used several times is
    needing a bank of fifos for some purpose. Overall control of that bank
    tends to be in a clocked process but the actual read and write controls into
    the fifos tend to be combinatorial since they tend to involve combinatorial
    gating with the full/empty status bits out of the instantiated fifos.

    So you end up needing combinatorial equations to connect the process to the
    instantiated component so why not put all of that inside of the same single
    generate block instead of putting a single process with a for loop and the
    'other' stuff inside the still needed anyway generate block?

    Then again, even your #1 item about tri-states is just another example of
    something that doesn't fit into the clocked process model.

    If the code for the architecture of the entity's required function does fit
    nicely into the single clocked process model though I agree with you that it
    is generally better to use the for loops inside the single
    process...although I might tend to break them up into several basically
    identical processes with loops, but that's just me.

    KJ
    KJ, Jun 14, 2006
    #9
  10. On Tue, 13 Jun 2006 14:00:54 -0700, Mike Treseler
    <> wrote:

    >Jonathan Bromley wrote:
    >
    >> I was brought up on
    >> Occam and CSP, so my instinct is to decompose
    >> a design into blocks that communicate in a
    >> well-structured way -

    >
    >You are ahead of your time.
    >At some high level, communication becomes
    >serial and very well-structured. It used
    >to be cross-country. Buses like
    >PCIe make it happen at a few centimeters.
    >I have no doubt this will become
    >a canned, on-chip "buffer" someday.


    Someday? How about Transputer Links, vintage 1975?
    Now that's an idea that was ahead of its time (and, in
    fairness, ahead of the technological capabilities that
    would have made it genuinely useful). Bromley's
    First Law of Technology Business asserts that any
    technology product is certain to fail in the marketplace
    if it meets the following three criteria:

    1) It is technically competent and founded on valid theory.
    2) It is ahead of its time by more than 2 years.
    3) It is British in origin.

    SERDES I/Os on modern FPGAs do a nice job, but it
    would be good if they had a handshaking protocol
    layered on top of them so that you could use them
    easily for synchronisation. I'm sure lots of people
    do exactly that for themselves, already.
    --
    Jonathan Bromley, Consultant

    DOULOS - Developing Design Know-how
    VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

    Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
    Jonathan Bromley, Jun 15, 2006
    #10
    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. bigdipper_gary
    Replies:
    1
    Views:
    927
    Mike Treseler
    Jan 5, 2004
  2. Vaclav Jedlicka

    asp:form generates invalid code

    Vaclav Jedlicka, Jul 22, 2003, in forum: ASP .Net
    Replies:
    6
    Views:
    395
    Tian Min Huang
    Jul 23, 2003
  3. Andrzej Wegrzyn
    Replies:
    2
    Views:
    722
    John Saunders
    Aug 18, 2003
  4. Peter Afonin
    Replies:
    0
    Views:
    493
    Peter Afonin
    Aug 30, 2003
  5. Alec S.
    Replies:
    10
    Views:
    10,142
    Alec S.
    Apr 16, 2005
Loading...

Share This Page