vectores libro español ejemplos bloqueante asignacion always verilog system-verilog

libro - verilog bloqueante



¿Cómo interpretar las asignaciones de bloqueo versus no bloqueo en Verilog? (6)

Estoy un poco confundido acerca de cómo se interpretan las asignaciones de bloqueo y no bloqueo cuando se trata de dibujar un diagrama de hardware. ¿Tenemos que inferir que una asignación sin bloqueo nos da un registro? Entonces, de acuerdo con esta afirmación, c <= a+b , c sería un registro correcto, pero no a y b?

module add (input logic clock, output logic[7:0] f); logic[7:0] a, b, c; always_ff @(posedge clock) begin a = b + c; b = c + a; c <= a + b; end assign f = c; endmodule


Definitivamente es un poco difícil entender las diferencias entre las asignaciones de bloqueo y no bloqueo inicialmente. Pero sin miedo, hay una práctica regla general:

Si desea inferir lógica combinada con un bloque always , use asignaciones de bloqueo ( = ). Si desea una lógica secuencial, use un bloque always sincronizado con asignaciones sin bloqueo ( <= ). Y trata de no mezclar los dos.

Su código anterior probablemente no sea el mejor ejemplo. Sin saber qué estructura de sumador / flip-flop estaba tratando de construir, existe el peligro de tener rutas de retroalimentación combinadas (que son malas). Y como no tienes buses de entrada, ¡esencialmente estás tratando de construir a , b & c de la nada!

Pero para responder a su pregunta, cualquier variable asignada dentro de un bloque clocked always inferirá un flip-flop, a menos que se le asigne mediante el operador de bloqueo ( = ) y se use como un tipo de variable local.

module add ( input clock, input [7:0] in1, input [7:0] in2, output logic [7:0] f1, f2, f3, f4, f5 ); // f1 will be a flipflop always_ff @(posedge clock) begin f1 = in1 + in2; end // f2 will be a flipflop always_ff @(posedge clock) begin f2 <= in1 + in2; end // f3 will be a flipflop // c1 will be a flipflop logic [7:0] c1; always_ff @(posedge clock) begin c1 <= in1 + in2; f3 <= c1 + in1; end // f4 will be a flipflop // c2 is used only within the always block and so is treated // as a tmp variable and won''t be inferred as a flipflop logic [7:0] c2; always_ff @(posedge clock) begin c2 = in1 + in2; f4 = c2 + in1; end // c3 will be a flipflop, as it''s used outside the always block logic [7:0] c3; always_ff @(posedge clock) begin c3 = in1 + in2; end assign f5 = c3 + in1; endmodule

Una gran razón para seguir la regla general y no mezclar asignaciones de bloqueo y no bloqueo dentro de un bloque always , es que mezclar sus asignaciones puede causar serias faltas de simulación entre RTL sims y gate-sims / hardware real. El simulador verilog trata = y <= bastante diferente. Las asignaciones de bloqueo significan ''asignar el valor a la variable de inmediato en este instante''. Las asignaciones sin bloqueo significan ''averiguar qué asignar a esta variable y almacenarla para asignarla en el futuro''. Un buen documento para leer para comprender mejor esto es: También vea: http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf


La sabiduría convencional de Verilog lo tiene todo mal. No hay problema con el uso de asignaciones de bloqueo para una variable local . Sin embargo, nunca debe usar asignaciones de bloqueo para la comunicación sincrónica, ya que esto no es determinista.

Una asignación sin bloqueo dentro de un bloque siempre sincronizado siempre inferirá un flip-flop, según lo dictado por la semántica.

Si una asignación de bloqueo dentro de un bloque siempre sincronizado infiere un flip-flop o no depende completamente de cómo se usa. Si es posible que la variable se lea antes de ser asignada, se deducirá un flip-flop. De lo contrario, esto es como una variable temporal y dará como resultado cierta lógica combinatoria.



Solo quiero agregar a la respuesta de Jan Decaluwe. Parece que hay muy poco código en la naturaleza que realmente usa lo que Jan Decaluwe describe, aunque es absolutamente correcto. Mezclar declaraciones de bloqueo y no bloqueo es ahora un tabú, gracias a Mr.Cummings.

El problema es que la mayoría de los lugares evitan el uso de declaraciones de bloqueo para las variables locales y hay muy poco código en el espacio de búsqueda inmediata de Google que busca da un ejemplo de cómo se hace. El único lugar donde encontré el estilo de codificación mencionado por Jan es el código ganador en este artículo . Y esto, me encontré accidentalmente


Tuve un momento difícil sobre esto también.

Pero, en primer lugar, debe comprender que el bloqueo o bloqueo no tiene nada que ver con la creación de un bloqueo / ff.

Por su diferencia, podrías entenderlo simplemente (al comienzo) en este punto: i. Si usa el bloqueo, las oraciones posteriores no podrían ejecutarse hasta que el bloque asignó un valor asignado a la LHS, ya que lo que cambió a LHS podría actualizarse y usarse si se usa la variable. Sin embargo, para no bloquear, no bloquea la siguiente oración como paralelo con la siguiente oración (en realidad, el cálculo de RHS debe hacerse primero, pero no importa, ignóralo cuando confundas). El LHS no cambia / no se actualiza para la ejecución de este tiempo (se actualiza la próxima vez cuando el bloque siempre se vuelve a activar). Y después de la oración, use el valor anterior, tal como se actualizó al final del ciclo de ejecución.

a = 0; b= 0; a = 1; b = a; --> output a = 1, b = 1; a = 0; b= 0; a <= 1; b = a; --> output a = 1, b = 0;

Un punto clave es encontrar si en tu código (siempre bloquear) hay cualquier variable de caso no asignada, pero podría suceder. Si no le pasa valor y ese caso ocurre, entonces se crea latch / ff para mantener el valor.

Por ejemplo,

always @(*) begin if(in) out = 1; else out = 0; end --> this end without latch/ff always @(*) begin if(in) out = 1; end --> this end with one latch/ff to keep value when in = 0, as it might happen and you didn''t assign value to out as in=1 do.

Lo siguiente también podría crear pestillo / ff:

always @(*) begin if(in) a = 1; else b = 1; end

-> pestillo / ffs creado para in = 1, b sin asignación, in = 0 a sin asignación.

Además, cuando detecte posedge of clk always @(posedge clk) , terminará con latch / ff. Porque, para clk, debe existir un borde negativo, y usted no hace nada, ¡se crean latch / ffs para mantener todo el valor anterior!


por favor, siempre puedes interpretar el verilog en el dominio digital, solo tienes que entender qué pasará si el mismo código que escribiste se convertirá en el nivel de la puerta, yo personalmente no sigo la regla de usar bloqueos en seq o usar bloqueos en combinaciones , esto limitará tu pensamiento. adhiérase al lado digital del código solo aquí es lo que sucederá si su código se convierte a nivel de compuerta simplemente vea que solo quiere esto

  1. primero se hará el sumador completo - entradas ayb
    1. la salida irá a flip-flop creando salida a teniendo sincronización con clk
    2. ahora, dado que la asignación se está bloqueando, entonces la nueva a se aplicará a la siguiente completa agregada que tenga esta nueva a yc como entrada, la salida de la misma irá a dffcsync para clk creando una nueva b
    3. ahora desde b = c + a; está allí, que está bloqueando la declaración así que b se actualiza a este nuevo b
    4. ahora es c <= a + b ahora lo que sucede es que se crea un sumador completo que tiene a y b como entrada que va a dff sync a clk, ahora hay otra condición como decir nuevamente a = c;
    5. luego se creará un dff teniendo el viejo c no el nuevo creado por la declaración de no bloqueo y el resultado de este dff sync para clk va a a y se actualiza

gracias, Rahul jain