¿Cómo interpretar las asignaciones de locking versus no locking en Verilog?

Estoy un poco confundido acerca de cómo se interpretan las asignaciones de locking y no locking cuando se trata de dibujar un diagtwig de hardware. ¿Tenemos que inferir que una asignación sin locking 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 locking y no locking inicialmente. Pero sin miedo, hay una práctica regla general:

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

Su código anterior probablemente no sea el mejor ejemplo. Sin saber qué estructura de sumdor / 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 locking ( = ) 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 locking y no locking 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 locking significan 'asignar el valor a la variable de inmediato en este instante'. Las asignaciones sin locking 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 locking para una variable local . Sin embargo, nunca debe usar asignaciones de locking para la comunicación sincrónica, ya que esto no es determinista.

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

Si una asignación de locking 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 locking y no locking es ahora un tabú, gracias a Mr.Cummings.

El problema es que la mayoría de los lugares evitan el uso de declaraciones de locking 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 encoding 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 locking o locking no tiene nada que ver con la creación de un locking / ff.

Por su diferencia, podrías entenderlo simplemente (al comienzo) en este punto: i. Si usa el locking, 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 lockings en seq o usar lockings 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 sumdor 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 statement 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 statement de no locking y el resultado de este dff sync para clk va a a y se actualiza

gracias, Rahul jain

Puedo responder a tu pregunta, pero creo que un trabajo sería lo mejor para esto, así que te recomiendo que leas este artículo de Clifford Cummings. Va a aclarar todas sus dudas y, además, fortalecerá su comprensión de verilog.

http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA_rev1_2.pdf

    Intereting Posts