You allow the compiler to choose sizes for these different type declarations, and it chooses the size of your INTEGER type according to the size of its base type (INTEGER).
You have control over the sizes of these types: if you rewrite the first ad as
type MY_TYPE is new Integer range 1..20; for MYTYPE'SIZE use 8;
you should get 8-bit MY_TYPE.
for MYTYPE'SIZE use 5;
should pack MYTYPE in 5 bits (as I understand it, the compiler is allowed to reject this with an obvious error or generate the correct code, but DO NOT accept it and create garbage.)
Why do you want to pack MYTYPE in 5 bits? One reason is that it is used as a recording component: this leaves room for three more components in one byte if they are logical and their SIZE attribute is 1!
It may look like extreme packaging, but in fact it is quite common in embedded programming, where this type of record corresponds to bits in a peripheral or I / O port. You would also specify a bit level layout in the record, as in:
type Prescale is new Integer range 1..20; for Prescale'SIZE use 5; type Timer_Ctrl_Reg is record Scale : Prescale; Up : Boolean; Repeat : Boolean; Int_En : Boolean; end record; for Timer_Ctrl_Reg use record Scale at 0 range 0 .. 4; Up at 0 range 5 .. 5; Repeat at 0 range 6 .. 6; Int_En at 0 range 7 .. 7; end record;
at indicates the offset from the record base in "storage units", usually bytes or words: range indicates the position of the bits in the storage block.
No more dodgy masking and extraction to worry!
On the other hand,
for MYTYPE'SIZE use 4;
should fail because MYTYPE has more than 16 discrete values.
source share