Verilog Bloqueo mixto y asignación no bloqueada

1

Me gustaría hacer tres preguntas sobre el bloqueo & asignación no bloqueante.

La primera pregunta es que cómo funcionan las instrucciones de bloqueo y no bloqueo cuando se combinan .

siguiendo el libro "FPGA_Prototyping_By_Verilog_Examples" dice que

  

Cuando se activa un bloque siempre, las expresiones del lado derecho de las asignaciones sin bloqueo se evalúan al comienzo del paso de tiempo.

Basándome en la declaración anterior sobre una declaración de no bloqueo, he esperado que el siguiente bloque siempre requiera dos relojes para asignar el valor de a & b al q0, pero el libro dice que puede hacerlo en un solo reloj ciclo.

always @(posedge clk)
begin
  abO  =  a & b ;  
  qO  <=  abO; 
end 

A primera vista, he pensado que el valor de ab0 (RHS de asignación sin bloqueo) se almacenará en algún lugar antes de que se ejecute siempre el bloque y se use en q0 < = ab0 ; . Por lo tanto, asumí que el valor de ab0 se estimará en el primer ciclo de reloj y el valor estimado de ab0 se asignará a q0 en el segundo flanco ascendente del reloj.

Así que mi pregunta es, cuando el valor de RHS de las declaraciones no bloqueantes se decide cuando se usan con las declaraciones bloqueadoras. Si se determina independientemente de la declaración de bloqueo, por favor hágamelo saber.

La segunda pregunta es ¿Cómo afectan el hardware real las declaraciones de no bloqueo y bloqueo?

He leído muchos artículos que dicen que las asignaciones de no bloqueo y bloqueo no tienen ningún efecto en la síntesis, sino solo en la simulación. Si se trata solo de la simulación, ¿cómo funciona realmente el hardware para ejecutar las instrucciones dentro del bloque siempre? ¿Ejecuta secuencialmente las instrucciones una por una como el código C?

Por lo que sé, la regla básica es

  • use la asignación de no bloqueo en el circuito secuencial.
  • usa la asignación de bloqueo en el circuito de la comunidad.

Sin embargo, parece que el uso de la asignación de no bloqueo en el circuito combinacional y la asignación de bloqueo en el circuito secuencial son todos legítimos y están permitidos o incluso mezclados.

Por lo tanto, mi última pregunta es ¿Cuál es la ventaja de mezclar dos asignaciones o qué tipo de casos hay para usar asignación no bloqueante en el circuito combinatorio y < fuerte> bloqueo de asignación en circuito secuencial ?

    
pregunta JaeHyuk Lee

1 respuesta

1

Los artículos que dicen "no bloqueos y asignaciones de bloqueo no tienen ningún efecto en la síntesis, pero solo en lo que respecta a la simulación " son incorrectos . Es cierto que hay ciertos casos en los que elegir cualquiera de los operadores de asignación no afecta al hardware sintetizado, pero hay casos en los que hace una diferencia.

Uno debe darse cuenta de que el código que escribe se ejecuta en orden serial dentro de un bloque begin/end independientemente de si representa un circuito secuencial o combinacional. Tanto las herramientas de simulación como las de síntesis deben implementar el comportamiento que especifique.

Puede modelar circuitos secuenciales y combinatorios con solo asignaciones de bloqueo (de hecho, las asignaciones sin bloqueo fueron una adición posterior al lenguaje Verilog). Puede determinar si el código representa un tipo particular de circuito observando el orden de las asignaciones a las variables de LHS con respecto a cuándo se usan las mismas variables en la RHS.

always @(posedge clk)begin
    ab  =  a & b & q0;  
    q0  =  ab; 
  end 

Debido a que ab aparece en una instrucción de asignación de bloqueo antes de aparecer en la RHS, se considera combinacional (escritura antes de lectura). Y el valor de ab se actualiza inmediatamente antes de ejecutar la siguiente instrucción. Y como q0 aparece en el RHS antes de aparecer en el LHS, se considera secuencial (lectura antes de escribir).

Pero si agregamos otro bloque siempre que usa ab en el RHS, ese uso se considera secuencial.

always @(posedge clk) begin
        c = ab;  
      end 

Ahora ab representa la lógica secuencial en ese bloque porque el otro bloque se ejecuta en un borde del reloj, muestreando los valores de a y b . Pero ahora tenemos una condición de carrera de simulación porque aunque el orden de ejecución dentro de un bloque begin/end es serial, no hay una ordenación definida entre diferentes bloques always activados por el mismo borde del reloj. No se sabe si el segundo always block tiene el valor actualizado de ab desde el primer bloque always .

La asignación no bloqueante resuelve esta condición de carrera de simulación de carrera demorando la asignación LHS hasta después de todo lo que se suponía que debía ejecutarse en el mismo paso de tiempo. Si cambiamos la asignación a ab en el primer bloque always a:

always @(posedge clk)begin
    ab  <=  a & b & q0; // NBA
    q0  =  ab; 
  end  

Ahora se garantiza que el segundo bloque always tiene el valor "antiguo" de ab . Pero esto también afecta a la declaración que la sigue en el mismo bloque. Ahora asignó el valor "antiguo" de ab a q0 . Así que ahora se necesitan dos ciclos de reloj para que el valor llegue a q0 .

    
respondido por el dave_59

Lea otras preguntas en las etiquetas