2012-02-09 14 views
5

He intentado escribir una máquina de estados finitos en código VHDL para un procesador simple de 16 bits que estoy implementando en una placa Altera DE1. En la Máquina de estados finitos, tengo una declaración CASE que maneja las diferentes instrucciones de 16 bits, que son traídas al FSM por un STD_LOGIC_VECTOR de 16 bits. Sin embargo, estoy teniendo un pequeño problema en el estado de decodificación donde la máquina de estados finitos decodifica las instrucciones. Una de las instrucciones es un ADD que toma dos registros como operandos y un tercero como el registro de destino. Sin embargo, también tengo una instrucción ADD que toma un registro y un valor inmediato de 5 bits como operandos y un segundo registro para el destino. Mi problema es que en la declaración CASE, necesito poder diferenciar entre las dos instrucciones ADD diferentes. Entonces, pensé que si utilizaba valores comodín como "-" o "X" en la declaración CASE, podría diferenciar entre los dos con solo dos casos en lugar de enumerar todas las posibles combinaciones de registro/valor inmediato. Por ejemplo:VHDL STD_LOGIC_VECTOR Valores comodín

CASE IR IS --(IR stands for "Instruction Register") 
     WHEN "0001------0-----" => (Go to 3-register add); 
     WHEN "0001------1-----" => (Go to 2-register/immediate value add); 
     WHEN OTHERS => (Do whatever); 
    END CASE; 

Estos no son los únicos dos instrucciones que tengo, acabo de poner estos dos para hacer este post un poco más corto. Cuando compilo y ejecuto este código, el procesador deja de ejecutarse cuando llega al estado de "decodificación". Además, Quartus da muchas, muchas advertencias que dicen cosas como "advertencia de elección VHDL en LC3FSM.vhd (37): opción ignorada que contiene meta-valor" "0001 ------ 0 -----" "" Yo soy sin saber cómo lograr esto. REALMENTE no y probablemente no necesite definir cada combinación de 16 bits, y espero que haya una forma de usar comodines en un STD_LOGIC_VECTOR para minimizar el número de combinaciones que tendré que definir.

¿Alguien sabe cómo lograr esto?

Gracias

Respuesta

1

Suponiendo que no necesita los otros bits en la instrucción, puede abrir el camino enmascarando los otros bits con un proceso de verificación previa. (¿O simplemente asegúrese de que los otros bits se restablecen cuando escribe las instrucciones?)

Esto realmente es un poco complicado.

IR suponiendo que se almacena como una variable

if IR(15 downto 12) == "0001" then 
    IR := IR_in(15 downto 12) & "0000000" & IR_in(5) & "00000"; 
else 
    IR := IR_in 
end if; 

CASE IR IS --(IR stands for "Instruction Register") 
    WHEN "0001000000000000" => (Go to 3-register add); 
    WHEN "0001000000100000" => (Go to 2-register/immediate value add); 
    WHEN OTHERS => (Do whatever); 
END CASE; 

Alternativamente asumiendo que su instrucción se piensa inteligentemente a cabo (son los primeros cuatro bits de la palabra de comando o algo por el estilo?) Que podría hacer declaraciones anidado de casos y hacer la diferenciación según sea necesario en esos sub bloques.

+0

Ajá, muchas gracias, Paul Seeb por su sugerencia. Después de que hice la pregunta ayer, pensé en usar una declaración 'CASE' para cada código de operación, y luego usar una instrucción' IF' para hacer las otras comparaciones necesarias. Sin embargo, su primer método hace que el código sea un poco más corto, así que lo utilicé. Gracias, también Mark Thompson por su sugerencia, también. –

5

Eso no se puede hacer por desgracia. De manera bastante inesperada para la mayoría de los usuarios, el operador de comparación = y la comparación case realizan una comparación literal. Esto se debe a que el tipo std_logic es solo un conjunto de caracteres, que funcionan como valores lógicos debido a la forma en que se definen otras funciones (por ejemplo, and y or).

VHDL-2008 presenta una nueva declaración de caso case? que funciona según lo esperado: deberá indicarle a su compilador que opere en modo VHDL 2008. Además, hay un operador ?= en VHDL 2008 que compara dos valores, teniendo en cuenta - s.

Si está equipado con un compilador que todavía no es compatible con VHDL 2008, presente una queja al proveedor. También hay una función std_match que le permite realizar comparaciones en revisiones anteriores de VHDL, pero nada de lo que soy consciente para hacer que la declaración case funcione de esa manera.

+1

+1 para "quejarse con el proveedor"! – Philippe

+0

Un FYI para aquellos que, como yo, que vinieron aquí después de tropezar con el mismo problema con el Xilinx ISE: ¿el nuevo "caso?" declaración (como la mayoría de las características VHDL-2008) no está presente en v14.4 (la versión actual en el momento de escribir esto) y no está claro cuándo o si estará presente en el futuro. – MartyMacGyver

+0

soporte beta para VHDL2008 'case?' Está en Vivado2014.3 ver [AR # 62005] (http://www.xilinx.com/support/answers/62005.html). Definitivamente no quiere suponer que va a funcionar (como es beta). –