Hay poco sintáctica problemas con este código, pero en general no está lejos y va a ser una manera útil en la distinción entre synthesisable y no synthesisable - que realmente no es lo que usted está esperando!
1) El puerto mapa
port(therm : inout std_logic_vector(6 downto 0); -- thermometer code
bin : out std_logic_vector(2 downto 0); -- binary code
i : integer range 0 to 7);
Puntos a tener en cuenta aquí:
therm
y bin
tienen un modo y a un tipo; i
tiene sólo un tipo. Como bin
es sólo una copia de i
usted realmente no necesita tanto en la lista de puertos. Usted puede declarar i
internamente como una señal, o incluso en el proceso como una variable.
bin
representa un número sin signo. Así que el buen estilo es hacerlo sin signo; o, incluso, Entero, y transmitir más de la intención del diseño para el lector. Ambos son perfectamente synthesizable. Entero puede dar un entero de 32 bits, por lo tanto, hacer bin : out natural range 0 to 7;
y obtendrá un 3 bits entero sin signo! La lección aquí es que si usted está haciendo un montón de innecesario tipo de conversiones, PARADA: creo, y usted tendrá que encontrar una manera de utilizar el tipo de sistema en lugar de luchar contra ella.
therm
ha sido declarado "inout
" pero es realmente una entrada para el proceso. (El hecho de que está modificando internamente es un detalle de implementación, que REALMENTE no desea exponer la versión modificada para el mundo exterior!) De hecho, "inout
" no hace realmente lo que piensa. Su propósito real es sólo para los buses de datos y similares, donde usted comunicarse en ambos sentidos en la misma señal. Si usted la utiliza como eres, entonces lo que sea que impulsa el valor original en therm
seguirá unidad therm
, y modificado los valores de los conflictos con que se produzcan "X
", es decir, el valor desconocido (O en el hardware real, posiblemente se sobrecaliente y se queme!).
Para eliminar i
, hacer bin
sin signo o un subtipo de los recursos Naturales, y hacer therm
de entrada.
2) Usted necesita una copia local de therm
puede modificar. Declarar de forma local como una señal.
architecture behavioral_g of therm2bin_g is
therm_int : std_logic_vector(6 downto 0);
begin
Y i
debe ser declarado localmente. Podría ser una señal demasiado, pero vamos a hacer una variable en el proceso de cambio.
golden : process(therm)
variable i : integer := 0;
-- yes, it is important to initialise it!
begin
3) El bucle.
En primer lugar, debemos copiar la entrada en el interior de la señal, entonces podemos modificar en el bucle.
therm_int <= therm;
while (therm_int /= "00000000") loop
therm_int <= therm_int srl 1;
i := i + 1;
end loop;
Para simplificar, se podría hacer therm_int sin firmar y escribir while therm_int /= 0 loop
(perdiendo el tonto de estilo C paréntesis en el proceso)
Hay otro problema aquí. Pensar en un proceso como un pequeño programa en C (pero sin algunos de C tonto "características") - de las variables de trabajo más bien como esperaba PERO las señales son esencialmente diseñado para la comunicación entre procesos en paralelo en un sistema de procesamiento. Si usted piensa en C términos, el equivalente más cercano es un tubo abierto en stdout y bucle de nuevo en stdin! Usted puede escribir en una tubería, pero no pasa nada hasta que un chorro de agua...
En VHDL, el color sólo ocurrirá cuando el proceso se suspende a sí mismo. Como está escrito, no puede suspender a sí mismo hasta que el bucle termina y llega a "end process
". Y no puede terminar el bucle hasta "therm_int = 0
". Y no puede cambiar el valor visto en therm_int
hasta que se suspende ... esto es un bucle infinito.
Para entender por qué VHDL señales de trabajar de esta manera, ver este Q&A
La manera más simple de la ronda de esto es hacer therm_int
otra variable de proceso y el uso de la variable de asignación :=
en lugar de la asignación de señal <=
.
Y ahora debería funcionar.
4) la Síntesis.
Pero lo que no synthesisable al respecto?
Sólo esto: Se utiliza un while
bucle en lugar de un for
de bucle!
Pensar que por un momento: no se puede prever, en general, el número de ciclos que una while
bucle va a tomar. Para la síntesis, que significa que usted tiene que generar una desconocida cantidad de hardware!
Pero se puede colocar un límite superior en las iteraciones, y generar hardware para atender a que el límite superior. De hecho, una for
bucle automáticamente es limitada, y las herramientas de síntesis puede manejar eso.
Para escribir el bucle como
therm_int <= therm;
for j in therm_int'range loop
if therm_int /= 0 then
therm_int := therm_int srl 1;
i := i + 1;
end if;
end loop;
y sintetizarla.
Notas : for j in therm_int'range loop
; la razón por la j? Así no queremos ocultar su i
variable!
Y tenga en cuenta que therm_int'range
automáticamente equivale a (6 downto 0)
o sin embargo usted declaró therm_int
. Este bombproofs el código en contra de los cambios en el tamaño de therm_int
o accidental desbordamientos de búfer. Es un pequeño ejemplo de lo que quiero decir utilizando el tipo de sistema en lugar de luchar contra ella.
Mientras estamos en ello, vamos a eliminar el cambio, el cual es innecesario!
for j in therm_int'reverse_range loop
if therm_int (j) = '1' then
i := j; -- last assignment is most significant '1' bit
end if;
end loop;
Como está escrito, este reunirán para generar suficiente hardware para implementar la tarea en un solo ciclo de reloj. En general, lo que llevaría a más lentos ciclos de reloj, y se desea ración de la obra (tal vez una sola iteración del bucle por reloj). Pero esa es otra historia...