Función de ancho de entero estándar en VHDL

2

Me encuentro usando una función que devuelve la cantidad de bits necesarios para representar mucho un valor entero en mis diseños.

Defino esta función en cada uno de mis módulos:

function int_width(value: integer) return integer is
begin
    return integer(floor(log2(real(value))));
end function;

Ejemplo de uso:

entity vga_sync is
    generic(
        TOTAL_WIDTH: integer := 800;
        TOTAL_HEIGHT: integer := 525;
        -- [...]
    port(
    -- [...]
    );
end vga_sync;

architecture arch of vga_sync is
    signal horizontal_counter: unsigned(int_width(TOTAL_WIDTH) downto 0);
    signal vertical_counter: unsigned(int_width(TOTAL_HEIGHT) downto 0);
    -- [...]
end arch;

Me parece que es un problema común. ¿Hay una función estándar en VHDL para hacer esto? ¿Debo usar siempre un número suficientemente grande (es decir, siempre de 32 bits) sin firma en estos casos?

    
pregunta Xion345

1 respuesta

4

En primer lugar, debe extraer esta función en un paquete VHDL y usar estos paquetes en sus módulos. Así que solo se declara una vez. Las funciones de un paquete también se pueden usar en la definición de la entidad.

VHDL no tiene una función integrada para acortar su función.

Segundo, tu cálculo no es correcto. El número de bits necesarios para codificar las combinaciones N siempre es mayor o igual que log2(N) . Por lo tanto, debe redondear hacia arriba ( ceil(...) ) no hacia abajo ( floor(...) ). Debido a que los vectores de bits están indexados a cero, el límite superior es log2(N)-1 .

Una función log2 basada en enteros que realiza automáticamente un redondeo se puede definir de la siguiente manera:

function log2ceil(arg : positive) return natural is
    variable tmp : positive     := 1;
    variable log : natural      := 0;
begin
    if arg = 1 then return 0; end if;
    while arg > tmp loop
        tmp := tmp * 2;
        log := log + 1;
    end loop;
    return log;
end function;

Fuente: PoC.utils paquete

Ejemplo:

signal vertical_counter: unsigned(log2ceil(TOTAL_HEIGHT) - 1 downto 0);
    
respondido por el Paebbels

Lea otras preguntas en las etiquetas