Proceso de entrada/salida de asignación de señal

Inside_process : process(clk) 
begin
    if clk='1' and clk'event then
        signal1 <= signalin; 
        signal2 <= signal1;
    end if;
Out_signal <= signal1 and (not signal2);
end process Inside_process;

end rtl; 

contra

Outside_process : process(clk) 
begin
    if clk='1' and clk'event then
        signal1 <= signalin; 
        signal2 <= signal1;
    end if;

end process Outside_process;
Out_signal <= signal1 and (not signal2);
end rtl;

Veo que en algunos códigos, las asignaciones de señales se realizan dentro de los procesos y, a veces, un poco antes, end rtl;en este caso, rtl es arquitectura. A veces se asignan muchas señales fuera del proceso, a veces muchas. En el ejemplo anterior, no recibo ningún error de síntesis y mi circuito funciona con ambas versiones. Entonces, no entiendo cuál es la diferencia entre ellos, además, algunas señales no se pueden asignar en el proceso, ¡tienen que estar afuera y marcan la diferencia! ¿Por qué algunos pueden ser asignados en proceso y otros no? ¿Por qué a veces no hace la diferencia? Además, ¿con qué frecuencia se asignan las señales fuera del proceso, cada flanco ascendente del reloj? ¿Cada quinto flanco ascendente del reloj? ¿Cómo se decide? ¿De qué sirve asignar una señal fuera de los procesos? Si voy a asignar una señal fuera de un proceso suelo hacerlo antesend rtl;(la última línea). Noté que tampoco duele hacer esto entre 2 procesos, por lo que no tiene que ser justo antes de la última línea, también puede estar en el medio.

Si debo dar un ejemplo de asignación de señal en proceso que da un error:

d3 <= r4  when (sn(3)='1') else d2;

Código completo de la línea de error

Mensaje de error: error de análisis, CUÁNDO inesperado, esperando PUNTO Y COMA.

Hay un punto y coma en realidad. Pero cuando esta línea se saca del proceso, funciona. No entiendo como, si alguien me puede iluminar me alegro.

¿También en VHDL debo declarar los procesos en mayúsculas, las señales en minúsculas o todo en mayúsculas? ¿Hay un uso común y una disciplina? Por ejemplo, ¿no se recomienda en Java que las variables comiencen con mayúsculas? Si hay un uso común como este para VHDL, ¿puedo obtener un enlace para eso?

El proceso se llama cuando hay un cambio en la señal clk, por lo que la salida solo se actualizará en uno de esos intervalos si se escribe desde dentro del proceso. Si actualiza la salida fuera de un proceso, de forma asíncrona, la actualización tendrá lugar tan pronto como (+tpd) se modifique al menos una de las señales a la derecha de la asignación.
¿Cuál es la diferencia? La lista de sensibilidad.
@ user34920 tpd: ¿retraso de propagación de tiempo? Entonces, si una de las señales en la línea de asignación externa se actualiza en cada ciclo de reloj, esto significa que la señal asignada a la izquierda también se actualizará en cada ciclo de reloj. ¿Esto va a ser asíncrono? Me parece que puede ser sincrónico si las señales se actualizan de acuerdo con algunas condiciones específicas.
@Anarkie tpd = sí, sin embargo, para fines de simulación, puede decir que las salidas del proceso se actualizan juntas después de que toda la parte interna se evaluó en 0 tiempo. En su ejemplo, parece que la señal 1 y la señal 2 se actualizan solo dentro del proceso, por lo que cuando el proceso las actualiza, la asignación asíncrona se realiza ya que dichas señales están en su lado derecho. Si tiene algún otro lugar que cambie la señal 1 o la señal 2, Out_signal podría actualizarse independientemente del flanco ascendente de la señal clk según lo dicte el proceso.
los procesos cronometrados infieren flip flops. Consulte aquí electronics.stackexchange.com/a/114786/16047

Respuestas (3)

Solo se permiten sentencias secuenciales dentro de una sentencia de proceso. Una parte de declaración de arquitectura se compone de cero o más declaraciones concurrentes. rtl parece ser el nombre de la arquitectura y una declaración de proceso es una declaración concurrente.

Observe en su código de referencia que tiene problemas con:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity circularshift is  port (
        sn     : in  std_logic_vector(5 downto 1);  -- number of rotate steps
        di     : in  std_logic_vector(32 downto 1);  -- data in 
        encdec : in std_logic ;                  -- enc or dec 
        do     : out std_logic_vector(32 downto 1)   -- data out
    );
end circularshift;

architecture Behavioral of circularshift is
    signal d0 : std_logic_vector(32 downto 1);
    signal d1 : std_logic_vector(32 downto 1);
    signal d2 : std_logic_vector(32 downto 1);
    signal d3 : std_logic_vector(32 downto 1);
    signal d4 : std_logic_vector(32 downto 1);
    signal r1 : std_logic_vector(32 downto 1);
    signal r2 : std_logic_vector(32 downto 1);
    signal r4 : std_logic_vector(32 downto 1);
    signal r8 : std_logic_vector(32 downto 1); 
    signal d5  : std_logic_vector(32 downto 1);
    signal r16 : std_logic_vector(32 downto 1); 
begin 
p1 : process (encdec)
begin

if  encdec <= '1' then

    r1  <= d0(32-1  downto 1) & d0(32);
    r2  <= d1(32-2  downto 1) & d1(32 downto 32-1);
    r4  <= d2(32-4  downto 1) & d2(32 downto 32-3);
    r8  <= d3(32-8  downto 1) & d3(32 downto 32-7); 
    r16 <= d4(32-16 downto 1) & d4(32 downto 32-15); 
    d0 <= di;
    d1 <= r1  when (sn(1)='1') else d0;
    d2 <= r2  when (sn(2)='1') else d1;
    d3 <= r4  when (sn(3)='1') else d2;
    d4 <= r8  when (sn(4)='1') else d3; 
    d5 <= r16 when (sn(5)='1') else d4; 
    do <= d5; 
else
    r1  <= d0(1) & d0(32 downto 2 );
    r2  <= d1(2  downto 1) & d1(32 downto 3);
    r4  <= d2(4  downto 1) & d2(32 downto 5);
    r8  <= d3(8  downto 1) & d3(32 downto 9); 
    r16 <= d4(16 downto 1) & d4(32 downto 17); 
    d0 <= di;
    d1 <= r1  when (sn(1)='1') else d0;
    d2 <= r2  when (sn(2)='1') else d1;
    d3 <= r4  when (sn(3)='1') else d2;
    d4 <= r8  when (sn(4)='1') else d3; 
    d5 <= r16 when (sn(5)='1') else d4; 
    do <= d5; 

end if;

end process;
end Behavioral;


-- I'm getting the following Error messages for my code posted below. (I'm using the xilinx 8.1.03i and modelsim )
-- When I run check syntax, the following is displayed:
-- Compiling vhdl file "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" in Library work.
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 38. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 39. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 40. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 41. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 42. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 49. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 50. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 51. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 52. parse error, unexpected WHEN, expecting SEMICOLON
-- ERROR:HDLParsers:164 - "C:/Xilinx/rcc2/rc5pi/circularshift.vhd" Line 53. parse error, unexpected WHEN, expecting SEMICOLON

Que la línea sobre la que preguntas en tu pregunta es la línea 54:

        d3 <= r4  when (sn(3)='1') else d2;

Y que esta es una asignación de señal concurrente y, sin embargo, aparece en una declaración de proceso (el dominio de las declaraciones secuenciales).

La forma de esto es una 'asignación de señal condicional', que se ha agregado a las asignaciones de señal secuencial por IEEE Std 1076-2008 (10.5.3 Asignaciones de señal condicional, § 10 se titula Declaraciones secuenciales).

Y de esto podemos inferir que mientras Modelsim es compatible con el estándar VHDL de 2008, su XST no lo es (los mensajes de error de la forma 'ERROR:HDLParsers:' son mensajes XST).

Si y cuándo Xilinx apoyaría la síntesis de instrucciones de asignación de señales condicionales dentro de un proceso (como asignación de señales secuenciales) es una cuestión de versiones y/o política. No hay una diferencia particular en la dificultad de la síntesis para respaldarlo, mientras que representa un cambio significativo en el analizador.

VHDL no distingue entre mayúsculas y minúsculas, excepto en identificadores extendidos y literales de caracteres.

De IEEE Std 1076-2008 15.2 Juego de caracteres:

Los únicos caracteres permitidos en el texto de una descripción VHDL (excepto dentro de los comentarios—ver 15.9, y dentro del texto tratado especialmente debido al efecto de las directivas de herramientas—ver 15.11) son los caracteres gráficos y los determinantes de formato. Cada carácter gráfico corresponde a un código único del conjunto de caracteres codificados de ocho bits ISO (ISO/IEC 8859-1:1998) y está representado (visualmente) por un símbolo gráfico.

carácter_gráfico_básico ::=
letra_mayúscula | dígito | carácter_especial | carácter_espacial

carácter_gráfico ::=
carácter_gráfico_básico | minúsculas_letra | otro_personaje_especial

carácter_básico ::=
carácter_gráfico_básico | format_effector

El conjunto de caracteres básico es suficiente para escribir cualquier descripción, que no sea una declaración de PSL, una directiva de PSL o una unidad de verificación de PSL.

Y 15.4 Identificadores:

Todos los caracteres de un identificador básico son significativos, incluido cualquier carácter de subrayado insertado entre una letra o dígito y una letra o dígito adyacente. Los identificadores básicos que difieren solo en el uso de letras mayúsculas y minúsculas correspondientes se consideran iguales.

apéndice

Muchas gracias por la respuesta, ¿qué tal Inside_process vs Outside_process? Out_signal <= señal1 y (no señal2); Out_signal se asigna una vez dentro y una vez fuera, pero el resultado no cambia, el circuito aún funciona, ¿no hay advertencias? Entonces, ¿es esta una asignación secuencial o concurrente? Si es concurrente, ¿cómo puede estar dentro del proceso, si es secuencial, cómo puede estar fuera del proceso? – Anarkie hace 6 horas

Hay una diferencia obvia entre los dos procesos. El que tiene la asignación de señales concurrentes ( Outside_process) mostrará Out_signalel cambio inmediatamente después de la actualización de cambios para las señales signal1y signal2porque la asignación de señales concurrentes tendrá un proceso equivalente que contiene una declaración de asignación de señales secuenciales y una lista de sensibilidad equivalente que contiene signal1y signal2. (Cada señal que aparece en el lado derecho de una declaración de asignación de señal).

El proceso Inside_processsolo tiene clken la lista de sensibilidad, lo que significa que en la simulación Out_signalse asignará en el próximo clk'EVENT, un retraso aparente de medio reloj porque las asignaciones a sus dos señales de registro de desplazamiento son visibles en el próximo ciclo delta.

Consulte esta respuesta de stackoverflow El ciclo de simulación de VHDL , así como este: Retrasos inesperados con el registro VHDL .

Curiosamente, es probable que ambos se sinteticen de manera idéntica porque la lista de sensibilidad se ignorará o se actualizará (se supone que incluye signal1y signal2en Inside_process). Es probable que cualquier suposición aparezca en las advertencias.

La elaboración delega una descripción de diseño en declaraciones de bloque (manteniendo la jerarquía), declaraciones de proceso y llamadas a funciones. Todas las sentencias concurrentes tienen una sentencia de proceso equivalente, potencialmente dentro de sentencias de bloque (o sentencias de bloque anidadas). En el caso de declaraciones de asignación de señales simples, hay poca diferencia observable entre la asignación de señales dentro o fuera de un proceso (excepto la lista de sensibilidad que en este caso está incompleta para Inside_process).

Se elaborará una especificación de diseño antes de la simulación y también como predicado para la síntesis.

Por cierto, fácil de arreglar... si todavía quieres todo dentro de un proceso, puedes usar 'caso'
@user34920 En realidad, el LRM nos dice que el proceso equivalente para una asignación de señal condicional concurrente se compone de una estructura de instrucción if. El proceso equivalente para una declaración de asignación de señal seleccionada concurrente se compone de una declaración de caso. Sí, sus declaraciones de casos sutiles también se pueden expresar en estructuras de declaraciones if (con un seguidor garantizado else), pero todos los modelos se delegan en procesos, llamadas a funciones y declaraciones de bloques (que implican estructura/localidad) canónicamente para la simulación.
@DavidKoontz Muchas gracias por la respuesta, ¿qué tal el Inside_processvs Outside_process? Out_signal <= signal1 and (not signal2); Out_signalse asigna una vez dentro y una vez fuera, pero el resultado no cambia, el circuito sigue funcionando, ¿no hay advertencias? Entonces, ¿es esta una asignación secuencial o concurrente? Si es concurrente, ¿cómo puede estar dentro del proceso, si es secuencial, cómo puede estar fuera del proceso?

Las versiones Inside_processy Outside_processse comportan de manera diferente. Si ambos diseños funcionan, es más que nada suerte, porque en este caso Out_signalsimplemente se retrasa medio ciclo de reloj cuando se declara dentro del proceso.

proceso_dentro

Out_signalse asigna cuando se activa el proceso, que en este caso ocurre en los flancos ascendentes y descendentes de clk. En el flanco ascendente, tomará los valores anteriores de signal1/ signal2, pero en el flanco descendente los alcanzará. Entonces se comporta como un flip flop de doble filo.

Proceso_externo

Out_signalse asigna continuamente, por lo que tan pronto como signal1/ signal2se actualicen en el proceso cronometrado, Out_signalse actualizará.

Comportamiento general

Si el resto del circuito está completamente sincronizado con el flanco ascendente de clk, entonces el comportamiento general podría 'parecer' el mismo, pero tenga en cuenta que no producirán la misma implementación física y la versión será más lenta ( Inside_processporque solo tiene medio ciclo de reloj para actualizar Out_signal) y usar más/diferentes recursos (debido a cómo termina implementándose la funcionalidad flip flop de doble borde).

Simulación

Una simulación simple ilustra el retraso de 'medio ciclo de reloj':

ingrese la descripción de la imagen aquí

Creo que ambas versiones deberían producir el mismo resultado de síntesis. Las herramientas de síntesis no solo evalúan las señales en la lista de sensibilidad. El retraso de 'medio ciclo de reloj' aparecerá en la simulación.

Un enfoque más limpio que asignaría la señal dentro de un proceso podría verse así:

Inside_process_1 : process(clk) 
begin
    if clk='1' and clk'event then
        signal1 <= signalin; 
        signal2 <= signal1;
    end if;

end process;

Inside_process_2 : process(signal1, signal2) 
begin
    Out_signal <= signal1 and (not signal2);
end process;

end rtl;