Representation Clauses: Bits, Sizes & Layout

Control data layout precisely: enumeration representation clauses ('Enum_Rep, 'Enum_Val), record representation clauses with bit ranges and Bit_Order, Size, Alignment, Component_Size and Pack aspects, and attributes 'Position, 'First_Bit, 'Last_Bit and 'Object_Size — the tools for device registers and binary protocols.

Most languages leave data layout to the compiler or force you into manual bit masking. Ada lets you write normal, strongly typed records and then state exactly where each component lives, down to the bit. The compiler checks that the layout is consistent and generates the shifting and masking for you, so a hardware register becomes a record with named, typed fields.

Enumeration Representation

'for Command use (Reset => 16#01#, Start => 16#10#, Stop => 16#80#);' assigns internal codes to enumeration literals (they must increase). The logical positions ('Pos) stay 0, 1, 2 — loops and 'Succ still work — while the stored representation matches the protocol. Command'Enum_Rep (Stop) returns the code (128) and Command'Enum_Val (16#10#) converts a code back to the literal (raising Constraint_Error for invalid codes; check with 'Valid after unchecked input).

• for T use (Lit => Code, ...); — codes must be increasing. • 'Pos unchanged; 'Enum_Rep / 'Enum_Val convert to/from codes.

Record Representation Clauses

'for Status_Register use record Ready at 0 range 0 .. 0; Mode at 0 range 2 .. 3; Channel at 1 range 0 .. 7; end record;' places each component at a storage-unit offset ('at N', in bytes) and a bit range within it. Bit_Order (System.Low_Order_First or High_Order_First) defines how bit numbers are counted, which matters for portability between little- and big-endian machines; the Scalar_Storage_Order aspect (GNAT and Ada 2022-era practice) additionally controls byte order. Component types must fit their bit ranges (Mode_Type with Size => 2). 'Position, 'First_Bit and 'Last_Bit query the actual layout.

• Component at Byte_Offset range First_Bit .. Last_Bit; • Bit_Order / Scalar_Storage_Order for endianness. • 'Position, 'First_Bit, 'Last_Bit report the layout.

Size, Alignment, Pack and Component_Size

The Size aspect gives the size in bits ('with Size => 16'); 'Size reports it (for types, the minimum bits needed, which may exclude trailing padding — 'Object_Size gives the size of stand-alone objects). Alignment constrains addresses. Pack asks for minimal storage (Boolean arrays drop from 8 bits to 1 bit per element), and Component_Size => 4 packs 4-bit elements. Without clauses, the compiler inserts padding for alignment: a record of 1-byte, 4-byte and 1-byte components occupies 9 bytes of data plus padding. Representation clauses must appear before the type is frozen (before objects are declared or it is used).

• Size / Object_Size / Alignment aspects and attributes. • Pack and Component_Size for dense arrays. • Clauses must precede freezing of the type.

Code Examples

The register value 16#A359#: byte 0 = Ready (bit 0 = 1) + Mode Sleep (2 → bits 2–3) + Counter 5 (bits 4–7) = 16#59#, byte 1 = Channel 16#A3#. Packing reduces 32 Booleans from 256 to 32 bits. Sizes are those of GNAT on x86-64 Windows. Output: Command'Size = 8, Stop'Enum_Rep = 128, Enum_Val (16#10#) = START Status_Register'Size = 16 bits Mode at bits 2 .. 3, Channel'Position = 1 Raw register = 16#A359# Bool_Array'Size = 256, Packed_Bools'Size = 32, Nibbles'Size = 16 Plain'Size = 72 bits (padding for alignment), Plain'Alignment = 4, B'Position = 4

Reg := Reg or Shift_Left (Mode_Bits, 2); -- manual masks everywhere

Reg.Mode:= Sleep; -- record with a representation clause Let the compiler generate the masking from a typed layout.

for Command use (Start => 16#10#, Reset => 16#01#, ...);

for Command use (Reset => 16#01#, Start => 16#10#, Stop => 16#80#);

Codes must increase in the order of the literals.

X: Status_Register; for Status_Register use record... -- after an object declaration -- give representation clauses right after the type declaration

Declaring an object freezes the type; later clauses are illegal.

What does Command'Enum_Rep (Stop) return with 'for Command use (..., Stop => 16#80#)'? A. 2 B. 128 C. 80 D. 3 B. 128 (verified).

In 'Mode at 0 range 2 .. 3', what is 0? A. Bit offset B. Storage-unit (byte) offset C. Alignment D. Priority

Which aspect stores a Boolean array with one bit per element? A. Volatile B. Pack C. Atomic D. Inline

Does an enumeration representation clause change 'Pos? A. Yes B. No, positions stay 0, 1, 2,... C. Only for the first literal D. Only with Pack Trace the representation example.

Real output: Command'Size = 8, Stop'Enum_Rep = 128, Enum_Val (16#10#) = START Status_Register'Size = 16 bits Mode at bits 2 .. 3, Channel'Position = 1 Raw register = 16#A359# Bool_Array'Size = 256, Packed_Bools'Size = 32, Nibbles'Size = 16 Plain'Size = 72 bits (padding for alignment), Plain'Alignment = 4, B'Position = 4

with Ada.Text_IO; use Ada.Text_IO;
with Interfaces;  use Interfaces;
with System;
with Ada.Unchecked_Conversion;

procedure L58_Repr is
   --  Enumeration representation clause: explicit codes (e.g. a hardware protocol)
   type Command is (Reset, Start, Stop);
   for Command use (Reset => 16#01#, Start => 16#10#, Stop => 16#80#);
   for Command'Size use 8;

   --  Record layout down to the bit: a 16-bit status register
   type Mode_Type is (Idle, Run, Sleep, Fault) with Size => 2;
   type Status_Register is record
      Ready   : Boolean;
      Error   : Boolean;
      Mode    : Mode_Type;
      Counter : Unsigned_8 range 0 .. 15;
      Channel : Unsigned_8;
   end record
     with Size => 16, Bit_Order => System.Low_Order_First;

   for Status_Register use record
      Ready   at 0 range 0 .. 0;
      Error   at 0 range 1 .. 1;
      Mode    at 0 range 2 .. 3;
      Counter at 0 range 4 .. 7;
      Channel at 1 range 0 .. 7;
   end record;

   function To_Bits is new Ada.Unchecked_Conversion (Status_Register, Unsigned_16);

   --  Packing and component size
   type Bool_Array is array (0 .. 31) of Boolean;
   type Packed_Bools is array (0 .. 31) of Boolean with Pack;
   type Nibbl
…