¿Puede una aserción concurrente de VHDL hacer referencia al atributo LAST_EVENT?

3

Estoy tratando de usar una aserción concurrente en una declaración de entidad para imponer una restricción mínima de ancho de pulso. Todo funciona como se espera si uso una aserción secuencial dentro de un proceso pasivo:

testest.vhdl

entity testcase is
    port(clk: in bit);
begin
    check: process is
    begin
        -- Require at least 10ns between clock edges
        assert clk'delayed'last_event >= 10 ns;
        wait on clk;
    end process check;
end entity testcase;

-- Keep the compiler happy
architecture empty of testcase is
begin
end architecture empty;

testcase_testbench.vhdl

entity testcase_testbench is
end entity testcase_testbench;

architecture bench of testcase_testbench is
    signal clk: bit;
begin
    dut: entity work.testcase(empty) port map(clk => clk);

    stimulus: process is
    begin
        -- Valid low and high pulses
        clk <= '0';
        wait for 10 ns;
        clk <= '1';
        wait for 10 ns;
        -- Confirm that we're timing events, not transactions
        clk <= '1';
        wait for 5 ns;
        -- Now send a short pulse to make the assertion fire        
        clk <= '0';
        wait for 5 ns;
        -- Assertion should fire here, at 30ns
        clk <= '1';
        wait;
    end process stimulus;
end architecture bench;

Construir y probar:

$ ghdl -a testcase.vhdl
$ ghdl -a testcase_testbench.vhdl
$ ghdl -e testcase_testbench
$ ghdl -r testcase_testbench
testcase.vhdl:6:16:@30ns:(assertion error): Assertion violation

Sin embargo, si trato de usar una aserción concurrente, recibo un error del compilador de ghdl:

testest2.vhdl

entity testcase2 is
    port(clk: in bit);
begin
    check: assert clk'delayed'last_event >= 10 ns;
end entity testcase2;

Intentar analizar:

$ ghdl -a testcase2.vhdl
canon_extract_sensitivity: cannot handle IIR_KIND_LAST_EVENT_ATTRIBUTE (testcase2.vhdl:4:34)

******************** GHDL Bug occured ****************************
Please report this bug on http://gna.org/projects/ghdl
GHDL release: GHDL 0.33 (20150921) [Dunoon edition]
Compiled with GNAT Version: 4.8
In directory: /home/simon/vhdl/
Command line:
/usr/bin/ghdl1-llvm -P/usr/lib/ghdl/v93/std/ -P/usr/lib/ghdl/v93/ieee/ -c -o testcase2.o testcase2.vhdl
Exception TYPES.INTERNAL_ERROR raised
Exception information:
Exception name: TYPES.INTERNAL_ERROR
Message: errorout.adb:63
Call stack traceback locations:
0x4978f2 0x4f055b 0x4f0350 0x4f2513 0x4f4806 0x5597df 0x5afbba 0x46eef6 0x433013 0x7f64f836082e 0x432450 0xfffffffffffffffe
******************************************************************
ghdl: compilation error

Recibo el mismo error si muevo la aserción concurrente al cuerpo de la arquitectura, o si acorto la expresión a clk'last_event >= 10 ns . Otras expresiones como clk'event o clk'delayed = '1' compilan bien, incluso si son un tanto inútiles.

Soy bastante nuevo en VHDL, pero tengo entendido que mis dos casos de prueba deberían ser equivalentes. Si no lo son, ¿por qué no? Y si lo son, ¿por qué se quejó Ghdl del segundo?

    
pregunta Simon Brady

1 respuesta

3

Gracias por hacer el esfuerzo de hacer un MCVE adecuado. Mi compilación de ghdl-0.34dev hace lo mismo, por lo que claramente hay un error de ghdl aquí.

Si el comportamiento es legal, esto debería funcionar, y si es ilegal, ghdl debería salir limpiamente con una descripción del error.

En cambio, ghdl no se bloquea, ha identificado un defecto, un caso en el que "no puede manejar el atributo LAST_EVENT" (aplicado a otro atributo) y se apaga con diagnósticos.

Dejaré abierta la pregunta de si una buena lectura del LRM determina su legalidad real o no ...

Es raro poner algo más allá de los genéricos y los puertos en la entidad, a diferencia de la arquitectura ... No puedo decir que alguna vez lo haya visto en el código de producción, por lo que está en el pasto alto, aunque es una cosa válida para hacer.

En cualquier caso, mover esta afirmación a la arquitectura produce el mismo error, por lo que ese no es el problema.

Por lo tanto, lo informé en el sitio de desarrollo de ghdl como enlace y actualizaré mi respuesta con cualquier evolución.

EDITAR: ahora se ha probado una solución para este problema y se enviará a github después de una prueba de regresión completa.

SIN EMBARGO: debido a una sutileza en afirmaciones concurrentes, las dos formas no son equivalentes.

ghdl -r testcase_testbench
testcase.vhd:7:9:@30ns:(assertion error): Assertion violation

ghdl -r testcase_testbench
testcase2.vhd:4:5:@10ns:(assertion error): Assertion violation
testcase2.vhd:4:5:@25ns:(assertion error): Assertion violation
testcase2.vhd:4:5:@30ns:(assertion error): Assertion violation

En el primer caso, el proceso se activa en clk según lo solicitado. Elimine la "espera" y ponga clk en la lista de sensibilidad, y hace lo mismo.

Sin embargo, en Testcase2, Assert concurrente es equivalente a un proceso de lista de sensibilidad, pero la lista de sensibilidad es clk'delayed .

Como Tristán señala en el informe de problemas (el mismo enlace que arriba) , clk'delayed está activo en más de un ciclo delta a 10 ns, y por lo tanto falla la prueba (¡porque el último evento es 0 ns entre ellos!) Ponga clk'delayed en la lista de sensibilidad para el proceso Testcase y vea.

Como señala "diogratia", un ejemplo similar en "La Guía del diseñador de VHDL" (Peter Ashenden) tiene un cambio simple a Testcase2 para evitar el problema: restringir el Asignación de eventos a clk ...

entity testcase2 is
    port(clk: in bit);
begin
    check: assert (not clk'event) or clk'delayed'last_event >= 10 ns;
end entity testcase2;

architecture empty of testcase2 is
begin
end architecture empty;

EDIT 2: a partir de commit b42069e esto se ha corregido en ghdl-0.34dev. Si su solución utilizando un proceso no satisface sus necesidades, puede actualizar a esta versión, pero esto significa construir ghdl desde la fuente.

    
respondido por el Brian Drummond

Lea otras preguntas en las etiquetas