Error de VHDL (se esperaba una expresión simple)

Soy nuevo en VHDL y tengo un problema con mi código que parece que no puedo solucionar. Se supone que debemos hacer esto utilizando la asignación de señal seleccionada o la búsqueda en la tabla. El mío es una especie de combinación de los dos, ya que se supone que debemos usar entradas que no sucederán.

Básicamente, se supone que el código da la misma salida para la entrada de complemento a 2 o el binario compensado. Entonces, por ejemplo, el número decimal 7 es "1111" en binario compensado y "0111" en complemento a 2. Ambos formularios deberían generar una salida de "1111100000" según el valor del interruptor oe ('1' para binario compensado, '0' para complemento a 2).

He depurado mi código tanto como he podido en este nivel y no entiendo qué estoy haciendo mal.

Active-HDL actualmente me está dando errores en las líneas 48 y 55. Recibo dos errores de "expresión simple esperada".

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity pitch_decoder_2 is

    port(d, c, b, a : in  std_logic;
         ob         : in  std_logic;
         led        : out std_logic_vector(9 downto 0));

end pitch_decoder_2;

architecture myarch of pitch_decoder_2 is

    type tbl is array (15 downto 0) of std_logic_vector(9 downto 0);

    constant table : tbl := (
        "1111100000",                   --  7
        "1111100000",                   --  6
        "1111100000",                   --  5
        "1111100000",                   --  4
        "0111100000",                   --  3
        "0011100000",                   --  2
        "0001100000",                   --  1
        "0000100000",                   --  0
        "0000110000",                   -- -1
        "0000111000",                   -- -2
        "0000111100",                   -- -3
        "0000111110",                   -- -4
        "0000111111",                   -- -5
        "0000111111",                   -- -6
        "0000111111",                   -- -7
        "0000111111");                  -- -8

    signal input : std_logic_vector(3 downto 0);
    signal tmp   : std_logic_vector(2 downto 0);
begin
    input <= std_logic_vector' (d, c, b, a);
    tmp   <= std_logic_vector' (c, b, a);

    with input select

        led <= table(to_integer(unsigned(d & tmp)))
        when "0000" | "0001" | "0010" | "0011" |
        "0100" | "0101" | "0110" | "0111" |
        "1000" | "1001" | "1010" | "1011" |
        "1100" | "1101" | "1110" | "1111"
        and ob = '1',

        table(to_integer(unsigned(not d & tmp)))
        when "0000" | "0001" | "0010" | "0011" |
        "0100" | "0101" | "0110" | "0111" |
        "1000" | "1001" | "1010" | "1011" |
        "1100" | "1101" | "1110" | "1111"
        and ob = '0',

        "----------" when others;

end myarch;

Además, si tiene algún consejo sobre cómo puedo mejorar el código manteniendo las instrucciones de la tarea, no dude en sugerir cualquier cosa.

como nota al margen: no usaría las qualified_expressionexpresiones (por ejemplo tmp <= std_logic_vector' (c, b, a);). Mantenga a, b, c y d como señales diferentes. No los pegue juntos en un nuevo tipo de tipo.
Los números de línea ayudarían.

Respuestas (3)

with input select 
    led <= table(to_integer(unsigned(d & tmp)))
    when "0000" | "0001" | "0010" | "0011" |
         "0100" | "0101" | "0110" | "0111" |
         "1000" | "1001" | "1010" | "1011" |         
         "1100" | "1101" | "1110" | "1111"
         and ob = '1',
    ...

El error de sintaxis se produce en la cláusula "y" que no forma parte de una lista de opciones de "selección" válida.

Sin embargo, tenga en cuenta que la expresión "cuando" es equivalente a ignorar la "entrada" por completo, por lo que

 with ob select 
     led <= table(to_integer(unsigned(d & tmp))) when '1',
     ...

Puede tener la idea errónea de que especificar explícitamente todas las combinaciones de valores '0' y '1' para "entrada" excluyó cualquier valor de entrada que contenga 'X', 'U', '-', etc. (de estos símbolos, solo uno es un "no me importa").

De hecho, en simulación puede funcionar; sin embargo, un poco de reflexión mostrará que no hay una primitiva de hardware sintetizable que pueda hacerlo de manera confiable y, a menos que esté escribiendo un banco de pruebas, este es sin duda el enfoque completamente incorrecto y el error de sintaxis simple es el menor de sus problemas.

EDITAR: aquí hay una forma (no probada) que usa tanto una tabla como una asignación de señal seleccionada, usando don't cares para reducir el tamaño de la tabla. Puede ser posible alguna simplificación adicional.

architecture myarch of pitch_decoder_2 is

        type tbl is array (3 downto -4) of std_logic_vector(9 downto 0);

        constant table : tbl := (  
        "0111100000",  --  3
        "0011100000",  --  2
        "0001100000",  --  1
        "0000100000",  --  0
        "0000110000",  -- -1
        "0000111000",  -- -2
        "0000111100",  -- -3
        "0000111110"); -- -4

        signal sel : signed(3 downto 0);

begin

        sel   <= (d xor ob) & c & b & a;

        with sel select led <=
           "1111100000" when "01--",
           table(to_integer(sel)) when "00--" | "11--",
           "0000111111" when "10--",
           "----------" when others;

end myarch;
Entonces, sé que en un diseño de hardware real, no debería obtener 'X', 'U' o '-', pero no entiendo cómo no especificar todas las entradas binarias posibles descarta esas combinaciones al compilar.
Además, reemplacé esas cosas con su versión simplificada y sigo recibiendo el mismo error en las líneas 44 y 45. pastebin.com/Qe9ZvC5s
el enlace de pastebin no es mi versión
elimine esto: cuando ob = '0', "----------" cuando otros;
¿El nuevo enlace de pastebin en mi comentario anterior?
sí... sus valores seleccionados son expresiones booleanas, no valores std_logic

Creo que podría estar un poco confundido acerca de cómo funcionan los operadores "|", "y" y "=", y su precedencia relativa. Tal vez ayude agregar algunos paréntesis para aclarar su significado.

Tienes todas las combinaciones posibles de inputen el when, por lo que puedes eliminar ese código. Lo que queda es 'if ob='1' o '0'`

led <= table(to_integer(unsigned(d & tmp))) when ob = '1' else table(to_integer(unsigned(not d & tmp)));

Tenga en cuenta que ya no hay ob = '0'. Una señal es o '1 o '0'. (Está bien, esto no es cierto, pero podrías captar la idea...). Entonces, si no es '1', es '0'.

Aunque esto funcionará, no satisface la restricción establecida, que es usar una asignación de señal seleccionada. Esta es una asignación de señal condicional.