Is Partial Record Assignment Possible?

Discussion in 'VHDL' started by Sudoer, Aug 6, 2010.

  1. Sudoer

    Sudoer Guest

    I often use records within records, or records within records within
    records, ad nausea. It's nice that I can currently do the following:

    A.A.A <= X;
    A.A.B <= Y;
    A.A.C <= Z;

    However, there's a lot of repetition in my code, so I often prefer the
    following:

    A <= ( A => ( A => X,
    B => Y,
    C => Z ) );

    The benefit is more noticeable with long and descriptive names for the
    elements, but the problem is that if my intention is to set only the
    A, B, and C leaf elements and leave any others unchanged it doesn't
    seem possible. Is there anything in the 2002 or 2008 standard that
    allows this, is there any reason this shouldn't be allowed, or is it
    time that I propose an overloaded use of the keyword unaffected, or
    another keyword all together (unchanged/same/handsoff?)

    A <= ( A => ( A => X,
    B => Y,
    C => Z,
    D => UNAFFECTED ) );

    A <= ( A => ( A => X,
    B => Y,
    C => Z,
    OTHERS => UNAFFECTED ) );

    Obviously it would be useful for slices as well.

    Since I haven't been able to play with 2008 yet, I'm wondering if left-
    side aggregates (not sure what they're called) would also simplify the
    above. Thanks!
    Sudoer, Aug 6, 2010
    #1
    1. Advertising

  2. Sudoer

    Sudoer Guest

    On Aug 6, 3:33 pm, Brian Drummond <>
    wrote:
    > On Fri, 6 Aug 2010 10:34:38 -0700 (PDT), Sudoer <>
    > wrote:
    >
    >
    >
    >
    >
    > >I often use records within records, or records within records within
    > >records, ad nausea. It's nice that I can currently do the following:

    >
    > >A.A.A <= X;
    > >A.A.B <= Y;
    > >A.A.C <= Z;

    >
    > >However, there's a lot of repetition in my code, so I often prefer the
    > >following:

    >
    > >A <= ( A => ( A => X,
    > >                    B => Y,
    > >                    C => Z ) );

    >
    > >The benefit is more noticeable with long and descriptive names for the
    > >elements, but the problem is that if my intention is to set only the
    > >A, B, and C leaf elements and leave any others unchanged it doesn't
    > >seem possible.

    >
    > Funny, I would have expected
    >
    > A.A <= ( A => X,
    >                     B => Y,
    >                     C => Z );
    > or even
    >
    > A.A <= (X,Y,Z) ;
    >
    > to do the job.
    >
    > - Brian


    Me too - in fact that was what I tried first. However, I get the
    following error when using XST:

    ERROR:HDLCompiler:790 - "*REDACTED*" Line 78: Some record elements are
    missing in this aggregate of A_TYPE

    Perhaps this is an XST thing and not a VHDL thing? Can anyone else get
    the above to work using different synthesis software?
    Sudoer, Aug 6, 2010
    #2
    1. Advertising

  3. Sudoer

    Sudoer Guest

    On Aug 6, 5:34 pm, Rob Gaddi <> wrote:
    > On 8/6/2010 2:28 PM, Sudoer wrote:
    >
    >
    >
    >
    >
    > > On Aug 6, 3:33 pm, Brian Drummond<>
    > > wrote:
    > >> On Fri, 6 Aug 2010 10:34:38 -0700 (PDT), Sudoer<>
    > >> wrote:

    >
    > >>> I often use records within records, or records within records within
    > >>> records, ad nausea. It's nice that I can currently do the following:

    >
    > >>> A.A.A<= X;
    > >>> A.A.B<= Y;
    > >>> A.A.C<= Z;

    >
    > >>> However, there's a lot of repetition in my code, so I often prefer the
    > >>> following:

    >
    > >>> A<= ( A =>  ( A =>  X,
    > >>>                     B =>  Y,
    > >>>                     C =>  Z ) );

    >
    > >>> The benefit is more noticeable with long and descriptive names for the
    > >>> elements, but the problem is that if my intention is to set only the
    > >>> A, B, and C leaf elements and leave any others unchanged it doesn't
    > >>> seem possible.

    >
    > >> Funny, I would have expected

    >
    > >> A.A<= ( A =>  X,
    > >>                      B =>  Y,
    > >>                      C =>  Z );
    > >> or even

    >
    > >> A.A<= (X,Y,Z) ;

    >
    > >> to do the job.

    >
    > >> - Brian

    >
    > > Me too - in fact that was what I tried first. However, I get the
    > > following error when using XST:

    >
    > > ERROR:HDLCompiler:790 - "*REDACTED*" Line 78: Some record elements are
    > > missing in this aggregate of A_TYPE

    >
    > > Perhaps this is an XST thing and not a VHDL thing? Can anyone else get
    > > the above to work using different synthesis software?

    >
    > Ahhh, THAT old problem.  The process in which you assign any elements of
    > an aggregate signal (record, array, etc) has to be the one in which you
    > assign all of the elements of it.
    >
    > --
    > Rob Gaddi, Highland Technology
    > Email address is currently out of order


    Well, that too is annoying, but I'm not quite seeing how that's
    related to the behavior I'm taking exception to today. I simply do not
    want to change the values of some elements in a record, only
    sometimes, and when assigning to the whole record. Frequently this
    will happen in some case statement - for some when's I want to assign
    some values, and for others I want to assign other values. If I assign
    to individual elements of a record I have no issue, but when I try to
    assign to the record itself it requires that I provide a value for
    every element.

    I'll admit right now that what I'm asking for here is pure swizzle-
    stick syntax sugar, but the difference between a language like C++ or
    Ada and a language like BF is exactly pure swizzle-stick syntax sugar
    (who needs named variables anyway?) I've found that unmanageable code
    tends to crop up most often when I have to do a lot of copying and
    pasting - this issue alone has caused me to create a new emacs macro
    that does nothing but copy the character directly above the point
    (cursor) to the point, but I do have my macro and so I'll survive if
    no one agrees with me that this would be a nice VHDL feature in future
    standards, or if no one can point out to me how to do it in any
    existing standard...
    Sudoer, Aug 6, 2010
    #3
  4. On Fri, 6 Aug 2010 10:34:38 -0700 (PDT), Sudoer
    <> wrote:

    >I often use records within records, or records within records within
    >records, ad nausea. It's nice that I can currently do the following:
    >
    >A.A.A <= X;
    >A.A.B <= Y;
    >A.A.C <= Z;
    >
    >However, there's a lot of repetition in my code, so I often prefer the
    >following:
    >
    >A <= ( A => ( A => X,
    > B => Y,
    > C => Z ) );
    >
    >The benefit is more noticeable with long and descriptive names for the
    >elements, but the problem is that if my intention is to set only the
    >A, B, and C leaf elements and leave any others unchanged it doesn't
    >seem possible.


    How about an alias?

    alias AA: ABC_record_type is A.A;
    ...
    AA.A <= X;

    Doesn't quite do what you asked for (I don't think that's
    possible) but it does simplify the naming problem somewhat.

    Functions and procedures might be useful too:
    procedure tweakJustTheLeafParts(signal T: inout ABC_record_type) is
    begin
    T.A <= X;
    ...
    end;
    ...
    tweakJustTheLeafParts(A.A); -- does A.A.A <= X;

    Watch out for multiple drivers, though, as Rob Gaddi points out.
    --
    Jonathan Bromley
    Jonathan Bromley, Aug 6, 2010
    #4
  5. On Fri, 6 Aug 2010 10:34:38 -0700 (PDT), Sudoer
    <> wrote:

    >I often use records within records, or records within records within
    >records, ad nausea. It's nice that I can currently do the following:
    >
    >A.A.A <= X;
    >A.A.B <= Y;
    >A.A.C <= Z;
    >
    >However, there's a lot of repetition in my code, so I often prefer the
    >following:
    >
    >A <= ( A => ( A => X,
    > B => Y,
    > C => Z ) );
    >
    >The benefit is more noticeable with long and descriptive names for the
    >elements, but the problem is that if my intention is to set only the
    >A, B, and C leaf elements and leave any others unchanged it doesn't
    >seem possible.


    How about an alias?

    alias AA: ABC_record_type is A.A;
    ...
    AA.A <= X;

    Doesn't quite do what you asked for (I don't think that's
    possible) but it does simplify the naming problem somewhat.

    Functions and procedures might be useful too:
    procedure tweakJustTheLeafParts(signal T: inout ABC_record_type) is
    begin
    T.A <= X;
    ...
    end;
    ...
    tweakJustTheLeafParts(A.A); -- does A.A.A <= X;

    Watch out for multiple drivers, though, as Rob Gaddi points out.
    --
    Jonathan Bromley
    Jonathan Bromley, Aug 6, 2010
    #5
  6. Sudoer

    Sudoer Guest

    Neither aliasing nor use of a function quite capture what I want to
    do, if only because they require more code just assigning to each
    subelement now. The idea is to assign to some, but not all elements,
    without writing additional code to do so, in a single assignment
    statement. It also occurs to me that this could reduce the number of
    signal assignments in total (depending on how the EDA tool author
    implements it, and it at least serves as an obvious clue to the
    compiler), which is always a good thing for simulation run times. A
    very good thing.
    Sudoer, Aug 7, 2010
    #6
  7. On Sat, 7 Aug 2010 10:30:41 -0700 (PDT), Sudoer wrote:

    >The idea is to assign to some, but not all elements,
    >without writing additional code to do so, in a single assignment
    >statement.


    And, as you correctly surmise, the language has (as far
    as I know) no direct way to allow you to do that. You
    can, of course, use part of the original record in the
    aggregate expression:

    A <= (X=>55, Y=>'1', Z=>A.Z);

    but that still forces you to write out every element
    somewhere in the aggregate. I'm sure you can see why
    OTHERS=>UNCHANGED is problematic, because the aggregate
    doesn't know that it is going to be assigned to A, and
    so the aggregate can no longer be just an expression of
    the record type; it needs also to incorporate a bunch of
    "don't-write" flags. And what would be the meaning
    of OTHERS=>UNCHANGED if the aggregate were to appear
    in a context other than simple assignment?

    So your original question changes from being a
    language-syntax problem to being an application problem:
    how can you design your data (and code infrastructure)
    to do what you want in the clearest possible way?

    Your requirement is to update a set of (possibly sub-)
    record elements in the cleanest, most concise possible
    way. For a single element it's obviously very easy,
    and minimally verbose:
    R1.R2.R3.E <= value;
    But how do you plan to choose your set of record elements,
    and what drives that choice? If you have just a small
    number of distinct sets of elements, then I would argue
    that writing one "update this set" procedure per set of
    elements is by far the neatest approach. If, however,
    the set of elements you want to update is more fluid,
    then I perhaps question your choice of simple records as
    an implementation vehicle. Of course, records have the
    huge advantage of supporting elements of heterogeneous
    data type, so the choice may not be quite so simple;
    but I would still argue that the problem is one of
    data structure design.

    >It also occurs to me that this could reduce the number of
    >signal assignments in total (depending on how the EDA tool author
    >implements it, and it at least serves as an obvious clue to the
    >compiler),


    Maybe. But I don't see this as a strong argument
    in favour of adding a language feature.

    On the other hand, your arguments from code conciseness
    do seem to me to have some value. But there are many
    things that would come way higher up my VHDL wish-list.
    --
    Jonathan Bromley
    Jonathan Bromley, Aug 8, 2010
    #7
  8. On Sun, 08 Aug 2010 12:04:00 +0100, Jonathan Bromley wrote:

    >So your original question changes from being a
    >language-syntax problem to being an application problem:


    A quick postscript: You *can* use OTHERS=> in a
    record aggregate, BUT this only works if all the
    elements specified by OTHERS are of the same type.
    My guess is that this is no use to you, because
    your record elements are of various types; and
    if the record elements are all of the same type,
    then it's probably easier to use an array anyhow.
    But I thought I'd mention it because it might
    make certain approaches possible in some special
    situations.
    --
    Jonathan Bromley
    Jonathan Bromley, Aug 8, 2010
    #8
  9. Sudoer

    Sudoer Guest

    Jonathan Bromley pretty much nailed it, I was just looking for code
    clarity and conciseness, and in my case I do plan to use many variants
    in terms of which subelements I assign to. The code I started this
    topic while writing would need five different functions to do the
    partial assignments.

    Sometimes I forget that VHDL has a formal syntactic definition that
    causes even small changes like I suggested to have large consequences.
    That said, one way to do this would be to have "OTHERS =>
    UNAFFECTED" (or UNCHANGED - I'm not sure of the policy of overloading
    keywords, or of introducing keywords that are very likely to be in
    existing code...) simply mean that each element "assigned" UNAFFECTED
    would be assigned it's current value. This does away with the "bit-
    flag" problem.

    As I'm a bit of a VHDL neophyte I was more hoping an expert would
    point out that I was missing an obvious way to do this more than I was
    hoping to propose a feature which would take years to ratify, further
    years to implement, and even innumerable years to make it into
    synthesis tools.
    Sudoer, Aug 9, 2010
    #9
  10. On 8/8/2010 5:50 PM, Sudoer wrote:
    > Jonathan Bromley pretty much nailed it, I was just looking for code
    > clarity and conciseness, and in my case I do plan to use many variants
    > in terms of which subelements I assign to. The code I started this
    > topic while writing would need five different functions to do the
    > partial assignments.


    I also prefer structures with descriptive element names -- if the
    dimensions are small enough that words don't confuse the issue.
    In this case, an array of records, where the array index is a type
    enumeration, often does the trick for me.

    > As I'm a bit of a VHDL neophyte I was more hoping an expert would
    > point out that I was missing an obvious way to do this more than I was
    > hoping to propose a feature which would take years to ratify, further
    > years to implement, and even innumerable years to make it into
    > synthesis tools.


    On the other hand, a question without an obvious answer is interesting.

    -- Mike Treseler
    Mike Treseler, Aug 9, 2010
    #10
  11. On Aug 9, 1:50 am, Sudoer wrote:
    > one way to do this would be to have "OTHERS => UNAFFECTED"
    > simply mean that each element "assigned" UNAFFECTED
    > would be assigned it's current value. This does away with the "bit-
    > flag" problem.


    As we all agree, this discussion is academic anyway, but....

    It doesn't "do away with" any such problem. In a simple
    assignment TARGET:=(some aggregate), the notion of "its current
    value" makes some sense (although it would be a new idea in
    VHDL for a right-hand-side expression to obtain values from
    an assignment target). But I'm at a loss even to guess what
    UNAFFECTED might mean in any other context - for example,
    if you were passing the aggregate to a function as an
    input argument.

    There are other peripheral problems too.
    Should the UNAFFECTED assignment cause a transaction on
    the unaffected elements of a record signal?

    I do agree, though, that it is exceedingly tedious that
    you can't write a record aggregate with only a few of
    its elements specified, leaving the others with their
    default values. In fact, that would open the door to
    some neat approaches to solving your problem. But you
    can't do it, so I won't waste my time and yours by
    describing how it might be done!

    cheers

    Jonathan Bromley
    Jonathan Bromley, Aug 9, 2010
    #11
  12. On Fri, 6 Aug 2010 10:34:38 -0700 (PDT), Sudoer
    <> wrote:

    >I often use records within records, or records within records within
    >records, ad nausea. It's nice that I can currently do the following:
    >
    >A.A.A <= X;
    >A.A.B <= Y;
    >A.A.C <= Z;
    >
    >However, there's a lot of repetition in my code, so I often prefer the
    >following:
    >
    >A <= ( A => ( A => X,
    > B => Y,
    > C => Z ) );
    >
    >The benefit is more noticeable with long and descriptive names for the
    >elements, but the problem is that if my intention is to set only the
    >A, B, and C leaf elements and leave any others unchanged it doesn't
    >seem possible.


    How about an alias?

    alias AA: ABC_record_type is A.A;
    ...
    AA.A <= X;

    Doesn't quite do what you asked for (I don't think that's
    possible) but it does simplify the naming problem somewhat.

    Functions and procedures might be useful too:
    procedure tweakJustTheLeafParts(signal T: inout ABC_record_type) is
    begin
    T.A <= X;
    ...
    end;
    ...
    tweakJustTheLeafParts(A.A); -- does A.A.A <= X;

    Watch out for multiple drivers, though, as Rob Gaddi points out.
    --
    Jonathan Bromley
    Jonathan Bromley, Jul 30, 2011
    #12
  13. On Sat, 30 Jul 2011 14:59:57 +0100, Jonathan Bromley

    ..... sent a long-dead post by mistake. Sorry, please ignore.


    >On Fri, 6 Aug 2010 10:34:38 -0700 (PDT), Sudoer
    ><> wrote:
    >
    >>I often use records within records, or records within records within
    >>records, ad nausea. It's nice that I can currently do the following:
    >>
    >>A.A.A <= X;
    >>A.A.B <= Y;
    >>A.A.C <= Z;
    >>
    >>However, there's a lot of repetition in my code, so I often prefer the
    >>following:
    >>
    >>A <= ( A => ( A => X,
    >> B => Y,
    >> C => Z ) );
    >>
    >>The benefit is more noticeable with long and descriptive names for the
    >>elements, but the problem is that if my intention is to set only the
    >>A, B, and C leaf elements and leave any others unchanged it doesn't
    >>seem possible.

    >
    >How about an alias?
    >
    > alias AA: ABC_record_type is A.A;
    > ...
    > AA.A <= X;
    >
    >Doesn't quite do what you asked for (I don't think that's
    >possible) but it does simplify the naming problem somewhat.
    >
    >Functions and procedures might be useful too:
    > procedure tweakJustTheLeafParts(signal T: inout ABC_record_type) is
    > begin
    > T.A <= X;
    > ...
    > end;
    > ...
    > tweakJustTheLeafParts(A.A); -- does A.A.A <= X;
    >
    >Watch out for multiple drivers, though, as Rob Gaddi points out.
    Jonathan Bromley, Jul 30, 2011
    #13
    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. jens
    Replies:
    1
    Views:
    664
    Mike Treseler
    Oct 6, 2005
  2. Billy
    Replies:
    2
    Views:
    500
    Billy
    Feb 1, 2006
  3. Paul B

    Partial Aggregate Assignment

    Paul B, Dec 7, 2006, in forum: VHDL
    Replies:
    4
    Views:
    584
    Paul Uiterlinden
    Dec 10, 2006
  4. Thomas Heller
    Replies:
    13
    Views:
    855
    Michele Simionato
    Feb 8, 2007
  5. J. Clifford Dyer

    Re: Partial 1.0 - Partial classes for Python

    J. Clifford Dyer, Feb 8, 2007, in forum: Python
    Replies:
    0
    Views:
    518
    J. Clifford Dyer
    Feb 8, 2007
Loading...

Share This Page