The code fragment in the question doesn't appear to have anything to do with the fphdl packages directly. It doesn't depend on any types declared in any of them.
The expression gives an integer result
from frac
with frac'HIGH - base
'bits' of accuracy.
An equivalent of the original expression could be:
variable dist: integer range 0 to 23;
dist := frac'HIGH - base;
result := to_integer (SHIFT_RIGHT(frac, dist));
SHIFT_RIGHT comes from the IEEE library package numeric_std, used because frac
is an unsigned.
The canny observer might note this is the equivalent of an integer divide by power of two which tends to be supported by synthesis generally, providing more or less identical hardware.
And about here you might get the idea your statement is a multiplexer with shifted inputs that are zero filled, the whole thing subject to optimization.
Historically IEEE Std 1076.6-2004 (withdrawn) 8.6.5 Slice names provided -
For a discrete range that appears as part of a slice name, the bounds of the discrete range shall be specified directly or indirectly as static values belonging to an integer type.
Morten tell us Quartus Prime can deal with
part := (others => '0');
part(base downto 0) := frac(frac'high downto frac'high - base);
result := to_integer(part);
where base
isn't static (although you'd think it should be constrained).
For those synthesis tools that can't deal with non static discrete range the same thing can be done in a for loop depending on the loop parameter which is a constant in an unrolled loop:
part := (others => '0');
for i in part'range loop
if i = b then
part(i downto 0) := frac(frac'high downto frac'high - i);
end if;
end loop;
result := to_integer(part);
The IEEE Std 1076=2008 10.10 Loop statement tells us:
For a loop statement with a for iteration scheme, the loop parameter specification is the declaration of the loop parameter with the given identifier. The loop parameter is an object whose type is the base type of the discrete range. Within the sequence of statements, the loop parameter is a constant.
The for loop gives the same result and should produce the same hardware.