Bloques de procedimiento en verilog

5

Tenemos dos tipos de bloques de procedimiento en verilog: initial y always block. Las sentencias dentro de estos bloques se ejecutan secuencialmente. ¿Eso afecta el tiempo de estas señales? Por ejemplo, en el siguiente código:

initial begin
  a = 1'b0;
  b = 1'b1;
end

¿La asignación de b tendrá lugar poco tiempo después de la asignación de a? Si no, ¿cuál será la diferencia entre esto y los bloques concurrentes en verilog, es decir, asignar declaraciones?

assign a = 1'b0;
assign b = 1'b1;
    
pregunta sarthak

3 respuestas

4
  

¿Eso afecta el tiempo de estas señales?

En realidad no.

Sí, a & b se evalúan secuencialmente pero en el mismo paso de tiempo del simulador, no secuencial en términos de diseño electrónico.

initial begin
  a = 1'b0;
  b = 1'b1;
end

a y b se evalúan esencialmente en paralelo. pero su simulador no puede hacer eso, la única vez que esto necesita una consideración cuidadosa es si confía en resultados anteriores.

Los siguientes son solo ejemplos e implicarían enganches en algún caso y no deberían usarse en RTL como este.

always @(posedge clk) begin
  a = y;
  b = a; //this is b=y
end

no es lo mismo que:

always @(posedge clk) begin
  b = a;     //This is old y
  a = y;
end

Para los sistemas con reloj (que implican flip-flops) usamos el no bloqueo ( <= ) los siguientes 2 ejemplos son los mismos:

always @(posedge clk) begin
  a <= y;
  b <= a; //this is old y
end

always @(posedge clk) begin
  b <= a;     //This is old y
  a <= y;
end
    
respondido por el pre_randomize
6
initial begin
  a = 1'b0;
  b = 1'b1;
end

El bloque inicial es un mecanismo para describir cómo desea que se comporten sus señales inicialmente. Cuando se sintetizan, las herramientas utilizan estos valores como valores iniciales para cada registro. A los registros no se les asignan estos valores secuencialmente, tienen estos valores desde el principio.

En el caso de la simulación, la CPU procesa las instrucciones proporcionadas, una después de la otra

assign a = b;

Como mencioné en mi comentario, las asignaciones son una construcción sintetizable que esencialmente significa "conectar este cable a este registro / cable". En realidad, esa tarea va a terminar optimizada por las herramientas.

Con todas las asignaciones asíncronas, las implicaciones de tiempo dependerán de la longitud del cable entre 'a' y 'b'. Si se usa un mux, o se realiza cualquier otro procesamiento (por ejemplo, assign a = b + c ), también tendrá un retardo de propagación inherente. ¿Cuánto tiempo son estos en realidad? Probablemente mucho más corto que un ciclo de reloj. Sin embargo, debe tener cuidado al volverse loco con las declaraciones de asignación. Por ejemplo, esto puede causarle problemas con sus restricciones de tiempo.

assign OutputQLLParity = QLLDout[23:21]^
                        QLLDout[20:18]^
                        ...
                        QLLDout[5:3]^
                        QLLDout[2:0];

Encabezando siempre bloques.

always @(posedge clk) begin
  a <= y;
  b <= a;
end

Observe el clk en la lista de sensibilidad. Esto significa que este proceso solo se ejecutará (a falta de una palabra mejor) en el borde positivo de un reloj.

Digamos, por ejemplo, que y cambia después del flanco ascendente del reloj. Aunque y ha cambiado, a solo se actualizará en el siguiente flanco ascendente.

A no se actualiza directamente en el flanco ascendente, se actualiza un poquito después de eso (esto se llama tiempo delta). Entonces b solo cambiará en el ciclo de reloj después de eso, un ciclo de reloj después de un.

Aquí, un diagrama de tiempo útil para usted:

          _____      _____      _____      _____
clk  ____/     \____/     \____/     \____/     \____
             ________________________________________
y    _______/       
                     ________________________________
a    _______________/       
                                _____________________
b    __________________________/       

Entonces, ¿cómo se ve esto en el hardware?

No son técnicamente tipos d en la actualidad, pero da una buena idea. Se utiliza un registro cronometrado que propaga la entrada a la salida en el flanco ascendente del reloj.

simular este circuito : esquema creado usando CircuitLab

Última nota:

Ver la diferencia en las tareas. = es una asignación de bloqueo, <= no es de bloqueo.

Es posible mezclar y combinar estos en algunos casos, pero si estás empezando con esto, y en general para tu propia cordura al principio, una buena regla general es = es para asignaciones, inicial Bloques y procesos sin listas de sensibilidad *. <= para procesos con listas de sensibilidad.

* poco confuso sobre esto. No utilizo procesos combinatorios en verilog muy a menudo.

    
respondido por el stanri
0

El ejemplo que has tomado es de declaraciones de bloqueo.
Sí, inicial & Los bloques siempre son secuenciales, mientras que las declaraciones de asignación son concurrentes.
En la inicial & siempre el bloque a = 1'b0 se asignará antes de que b = 1'b1 se asigne. Considerando que en el caso de las declaraciones de asignación, un & b se asignará al mismo tiempo.

En el caso de las declaraciones no bloqueadoras "<=", si el valor asignado a a depende de b , entonces a Se asignará primero, luego b . Pero como el valor de a depende de b , el valor de a se modifica después de eso. Esto se llama simulación de eventos discretos

    
respondido por el KharoBangdo

Lea otras preguntas en las etiquetas