VHDL: ceiling and floor of division by two integer constants

Viewed 11234

In VHDL, I'm Looking for a way to take two integer parameters of an entity, divide one against the the other as a floating point number, and then find both the floor and ceiling of this floating point ratio, and then store it as a vhdl integer constant.

library ieee;
use     ieee.std_logic_1164.all;

entity something is
    generic(
        N: natural := 4;
        M: natural := 150
    );
    port(
        sys_clk     :in  std_logic;
        sys_rst     :in  std_logic;

        datai       :in  std_logic_vector(M-1 downto 0);
        datao       :out std_logic_vector(N-1 downto 0)
    );
end entity;


architecture rtl is something is
    --how to calculate ceiling of  M / N?
    constant ratio_ceiling :integer := integer(real(M)/real(N));

    --how to calculate floor of M / N?
    constant ratio_floor   :integer := integer(real(M)/real(N));

begin

end architecture;
2 Answers

Code:

library ieee;
use     ieee.std_logic_1164.all;
use     ieee.math_real.all;

entity something is
    generic(
        N: natural := 4;
        M: natural := 150
    );
    port(
        sys_clk     :in   std_logic;
        sys_rst     :in   std_logic;

        datai       :in   std_logic_vector(M-1 downto 0);
        datao       :out  std_logic_vector(N-1 downto 0)
    );
end entity;


architecture rtl of something is
    --how to calculate ceiling of  M / N
    constant ratio_ceiling :integer := integer(ceil(real(M)/real(N)));

    --how to calculate floor of M / N
    constant ratio_floor   :integer := integer(floor(real(M)/real(N)));

begin

    process
    begin
        report "ceil:  " & integer'image(ratio_ceiling);
        report "floor: " & integer'image(ratio_floor);
        wait;
    end process;
end architecture;

Output:

C:\something> ghdl -a --std=08 --ieee=synopsys --work=work something.vhd

C:\something> ghdl --elab-run --std=08 --ieee=synopsys something --vcd=waves.vcd --ieee-asserts=disable

something.vhd:33:12:@0ms:(report note): ceil:  38
something.vhd:34:12:@0ms:(report note): floor: 37

Not sure what your question is really, the code seems correct. If you're looking to avoid all type casting and conversions, you can use

constant ratio_ceiling : integer := (M + N - 1) / N;
constant ratio_floor   : integer := M / N;

VHDL integers will round down, so that works just fine.

Related