I'm trying to define a hardware interface for two different devices that are closely related, but one has slightly more functionality than the other.
As a very simplified version of the problem, let's say:
- device A has 2 registers: R0 is unused and R1 is used
- device B has 2 registers: uses both R0 and R1
I was attempting to get fancy with code and definitions re-use with a polymorphic definition like:
Tag_Length : constant := Standard'Address_Size / System.Storage_Unit;
type A_IO is tagged record
-- RO precedes, is unused but the space is reserved
R1 : Byte;
end record;
for A_IO use record
R1 at Tag_Length + 1 range 0 .. 7;
end record;
type B_IO is new A_IO with record
R0 : Byte;
-- R1 would follow as defined by the parent record
end record;
for B_IO use record
R0 at Tag_Length + 0 range 0 .. 7;
end record;
This results in a compiler error that would make a lot of sense in most scenarios: component overlaps parent field of "B_IO" (GNAT Community 2019).
I have alternatives to this, which would involve either:
- using the same type for each device (con: device A will see components that shouldn't be visible)
- using an entirely different type, rely on Unchecked Conversion through an access type to change the view of the object when using shared code (con: will involve re-defining some of the same components multiple times)
I was wondering if there could be a viable approach without any of the mentioned cons.