   -- One entity inside the design where we can do high level programming -----
   entity Example_2 is
        port (AE, BE : in Unsigned;
              CE : out Unsigned);
   end Example_2

   architecture Example_2_RTL of Example_2 is

      signal XE : Unsigned;
      -- Modulo 1024 unsigned
      signal YE1 : Modulo_Unsigned with Size => 10;
      -- Modulo 3000 unsigned
      signal YE2 : Modulo_Unsigned range 0 to 2999;
      -- Not allowed ! : modulo numbers need to have their size or range
      -- explicitely defined !
      signal Illegal : Modulo_Unsigned;

   begin

      XE := AE * BE;
      -- Explicit cast is mandatory
      YE1 := Modulo_Unsigned (XE + AE);
      YE2 := YE1 + Modulo_Unsigned (BE);
      -- Arithmetic operators could be overloaded to avoid explicit casts in this case
      CE := (Unsigned (YE1) * AE) / (Unsigned (YE2) * BE);

   end Example_2_RTL;


   -- Entity that interfaces the previous entity to an external one --------
   entity Top is
        port (A, B : in Bit_Vector (8 downto 0);
              C : out Bit_Vector (23 downto 0);
   end Top

   architecture Top_RTL of Top_RTL is
      -- The range restriction will allow extra optimizations as AE and BE will
      -- inherit the range restriction which makes possible to encode
      -- XE in 17 bits instead of 18.
      signal AT, BT : Unsigned range 0 to 299;
      signal CT : Unsigned;
   begin

      AT'Bits <= A; -- AT'Size matches A'Length
      BT'Bits <= B; -- BT'Size matches B'Length

      Example_2_Inst : entity Work.Example_2 port map (AE => AT,
                                                       BE => BT,
                                                       CE => CT);

      -- Now we need to assign CT into C, knowing that CE'Size is the minimum
      -- needed size for all the operations that resulted in CE.
      -- There are different cases depending on the requirements :
      -- a) CE'Size must equal C'Length :
         -- When not explicitely set by the user, size and range properties for
         -- a signal are calculated only from the expressions that set the value
         -- of the signal. Then CT'Size = CE'Size as C'Length has no effect on it.
         -- So we could just write :
         C <= CT'Bits;
         -- and an error will raise in case of a length mismatch
      -- b) CE'Size <= C'Length required
         C <= (CT'Bits'Range => CT'Bits,
                      others => '0');
      -- c) Anything is fine :
         C <= Resize (CT'Bits, C'Length);


   end Top_RTL;
