Re: Packed struct/union amendments proposal


Subject: Re: Packed struct/union amendments proposal
From: Steven Sharp (sharp@cadence.com)
Date: Wed Jul 24 2002 - 15:57:56 PDT


>I'm only worried about which bits line up where for this argument, actual
>storage can be something different.
>
>> And aside from this, I don't think the modified text says anything that the
>> original text doesn't already cover.
>
>Not quite, it states that the (virtual) storage model is big-endian for all
>data types.

In terms of which bits line up or overlay, it is already fully specified.
The statement that the first member in a structure is most significant is
enough to do that. The only possible meaning of that statement is that
the first member overlays the most significant bits of the whole packed
union when treated as a vector. The left end of any range on packed arrays
is also the most significant. The most significant bit of an integer type
is defined by mathematics. The "virtual" storage model is already defined
to be big-endian, though the physical storage order is not specified.

>> typedef struct packed {
>> byte byte1;
>> byte byte2;
>> byte byte3;
>> byte byte4;
>> } bytes;
>>

>If we modify the union:
>
> typedef union packed {
> bit [31:0] word;
> byte [3:0] byte_slice;
> bytes slice;
> int b32;
> } mem_word;
>
>and then do:
>
> mem_word.b32 = 32h'12345678;
>
>what's the value of slice.byte1?

It is 8'h12. The specification states that the first member of a packed
struct is the most significant, and that is byte1. That means it overlays
the most significant byte of the packed union mem_word. So does the most
significant byte of b32, which gets assigned the most significant byte of
32h'12345678, which is 8'h12. So slice.byte1 is 8'h12. So are byte_slice[3]
and word[31:24], each of which is most significant, and thus overlay the
most significant byte of the packed union mem_word. This is based purely
on the spec and is independent of the endianness of the host machine.

What part of this do you think is not specified?

Note that none of this specifies the storage order in the actual host
memory. We don't know whether byte1 is stored at a higher or lower
address in memory than byte2. That is machine and/or implementation
dependent. However, it doesn't matter unless you have some way of
determining the actual memory address of a particular member.

>As I said before the reason for wanting this stuff defined is that we have
>testbenches that generate data for simulated embedded processors that don't
>address their data the same way the simulation host does, and I want to
>avoid error prone `ifdef BIG_ENDIAN...`else code.

As long as it is all defined in the HDL, it will always work the same way,
independent of host machine architecture. If you aren't trying to access
the data through a C model, or getting the addresses of members of packed
structs through some new HDL pointer mechanism, the code should be portable
without `ifdefs.

>> It is not clear whether this means that each 2-state
>> member is also treated as 4-state.
>
>You can do it that way, but it's guaranteed to be less efficient. Also
>automatically treating Xs/Zs as 0 seems like a realy bad idea to me.
>( Should've proposed striking that paragraph too :-) ).

Presumably the user accepts responsibility for that when they decide to
union together 2-state and 4-state types. We can forbid this, or define
what it means. The spec has done the latter. We can discuss whether this
is a good idea, but it is a separate issue. Incidentally, with the usual
4-state encoding, treating Z as 0 and X as 1 would be more efficient. It
would avoid the need for any actual work in converting from 4-state to
2-state. It can even be rationalized as a reasonable mapping, with a
little effort.

Steven Sharp
sharp@cadence.com



This archive was generated by hypermail 2b28 : Wed Jul 24 2002 - 15:59:34 PDT