¡Ayuda! Bucle verilog! Las siguientes señales forman un bucle combinatorio

0

Estoy tratando de completar una tarea usando Verilog, los detalles no son muy importantes, excepto que debe ser un diseño combinatorio. Desafortunadamente, me estoy topando con lo que supongo es que el hardware se atasca en un bucle infinito: las siguientes señales forman un bucle combinatorio:

the following signal(s) form a combinatorial loop: _n0112, GND_2_o_GND_2_o_mux_66_OUT<1>, mode[2]_GND_2_o_equal_75_o, mode<1>, ran0, mode[2]_GND_2_o_equal_75_o_mmx_out.

Aquí está mi código (sé que está desordenado y se puede hacer mejor, estoy trabajando en ello):

module seven_seg(
input [3:0] a,
input [3:0] b,
input [3:0] c,
input [3:0] d,
input [1:0] mux,
output [6:0] out,
output an0,
output an1,
output an2,
output an3
);

 wire [6:0] x;
 wire [6:0] y;
 wire [6:0] i;
 wire [6:0] j;
 reg [2:0] mode = 3'b000;
 reg ran0;
 reg ran1;
 reg ran2;
 reg ran3;

parameter zero  = 7'b1000000;
parameter one       = 7'b1001111;
parameter two       = 7'b0010010;
parameter three = 7'b0000110;
parameter four      = 7'b1001100;
parameter five      = 7'b0100100;
parameter six       = 7'b0100000;
parameter seven = 7'b0011111;
parameter eight = 7'b0000000;
parameter nine      = 7'b0000100;
parameter ten       = 7'b0001000;
parameter eleven    = 7'b0000000;
parameter twelve    = 7'b0110001;
parameter thirteen= 7'b0000001;
parameter fourteen= 7'b0110000;
parameter fifteen   = 7'b0111000;

assign c = 4'b0001;
assign d = 4'b0000;

assign x = (a == 4'b0000) ? zero :
(a == 4'b0001) ? one :
(a == 4'b0010) ? two :
(a == 4'b0011) ? three :
(a == 4'b0100) ? four :
(a == 4'b0101) ? five :
(a == 4'b0110) ? six :
(a == 4'b0111) ? seven : 
(a == 4'b1000) ? eight : 
(a == 4'b1001) ? nine : 
(a == 4'b1010) ? ten : 
(a == 4'b1011) ? eleven : 
(a == 4'b1100) ? twelve : 
(a == 4'b1101) ? thirteen : 
(a == 4'b1111) ? fourteen : fifteen;

assign y = (b == 4'b0000) ? zero :
(b == 4'b0001) ? one :
(b == 4'b0010) ? two :
(b == 4'b0011) ? three :
(b == 4'b0100) ? four :
(b == 4'b0101) ? five :
(b == 4'b0110) ? six :
(b == 4'b0111) ? seven : 
(b == 4'b1000) ? eight : 
(b == 4'b1001) ? nine : 
(b == 4'b1010) ? ten : 
(b == 4'b1011) ? eleven : 
(b == 4'b1100) ? twelve : 
(b == 4'b1101) ? thirteen : 
(b == 4'b1111) ? fourteen : fifteen;

always @(*)
begin
    if(mux == 2'b00)
        if(mode == 3'b000)
            mode = 3'b001;
        else if(mode == 3'b010)
            mode = 3'b011;
        else mode = 3'b000;
    else if(mux == 2'b01)
        mode = 3'b000;
    else if(mux == 2'b10)
        mode = 3'b010;
    else //if(mux == 2'b11)
        mode = 3'b100;
end

always @(*)
begin

    if(mode == 3'b000)
        begin
            ran0 = 0;
            ran1 = 1;
            ran2 = 1;
            ran3 = 1;
        end
    else if(mode == 3'b001)
        begin
            ran0 = 1;
            ran1 = 0;
            ran2 = 1;
            ran3 = 1;
        end
    else if(mode == 3'b010)
        begin
            ran0 = 1;
            ran1 = 1;
            ran2 = 0;
            ran3 = 1;
        end
    else if(mode == 3'b011)//011
        begin
            ran0 = 1;
            ran1 = 1;
            ran2 = 1;
            ran3 = 0;
        end
    else 
        begin
            ran0 = 0;
            ran1 = 0;
            ran2 = 0;
            ran3 = 1;
        end
end

assign an0 = ran0;
assign an1 = ran1;
assign an2 = ran2;
assign an3 = ran3;


assign out = x;

endmodule

Así que creo que entiendo el problema, tiene que ver con este bloque:

always @(mux)
begin
    if(mux == 2'b00)
        if(mode == 3'b000)
            mode = 3'b001;
        else if(mode == 3'b010)
            mode = 3'b011;
        else mode = 3'b000;
    else if(mux == 2'b01)
        mode = 3'b000;
    else if(mux == 2'b10)
        mode = 3'b010;
    else //if(mux == 2'b11)
        mode = 3'b100;
end

El sintetizador termina poniendo 'modo' en la lista de sensibilidad por alguna razón, y creo que es por eso que termina en un bucle. Agradecería más información sobre lo que está pasando aquí.

¡Gracias!

    
pregunta user3474353

2 respuestas

2

Ya sea que la sitúes en la lista de sensibilidad o no, la variable de modo depende de la variable de modo. Vea donde lo señalo abajo.

Imagina que estás intentando hacer ese hardware. ¿Cómo haces que funcione? Recuerda que aquí no hay reloj, así que tendrías que crear un bucle combinatorio, ¿no?

always @(mux)
begin
    if(mux == 2'b00)
        if(mode == 3'b000)       <----  HERE
            mode = 3'b001;
        else if(mode == 3'b010)  <----- HERE
            mode = 3'b011;
        else mode = 3'b000;
    else if(mux == 2'b01)
        mode = 3'b000;
    else if(mux == 2'b10)
        mode = 3'b010;
    else //if(mux == 2'b11)
        mode = 3'b100;
end

Recorra el diseño para comprender qué hace esto en la situación en la que mux comienza en 2'b01 y luego pasa a 2'b00. Cuando mux = 2'b01, modo = 3'b000. Luego, cuando mux va a 2'b00, observa que el modo es 3'b000, y cambia el modo a 3'b001. Entonces ve inmediatamente que mux es 2'b00 y el modo es 3'b001 y cambia el modo a 3'b000, luego ve que mux es 2'b00 y el modo es 3'b000 y cambia el modo a 3'b001. Este es un bucle combinatorio.

A un lado, permítanme explicar qué es exactamente la lista de sensibilidad. Originalmente, verilog fue diseñado como un lenguaje de modelado. La lista de sensibilidad era una forma de decir las dependencias del simulador. Esto ayudó a reducir el procesamiento innecesario al permitir que el simulador no mirara el código de cada bloque siempre para determinar si necesitaba ejecutarlo.

Sin embargo, hoy en día verilog se usa principalmente para inferir lógica, por lo que la lista de sensibilidad realmente no es tan útil como lo fue. La herramienta de síntesis mirará el código y determinará que olvidó algo. No puedes engañarlo al no ponerlo en la lista. Es es una dependencia de acuerdo con su lógica y la herramienta de síntesis lo tratará como tal. Probablemente incluso te haya dado una advertencia de que lo has olvidado.

    
respondido por el caveman
0

Su código no coincide con su gráfico (incompleto). Aquí hay una forma de tabla que muestra explícitamente las transiciones faltantes.

Mode\Mux    2'b00   2'b01   2'b10   2'b11
3'b000     3'b001  3'b000  3'b010  3'b100
3'b001     3'b001  3'b000  3'b010  3'b100
3'b010     3'b011  3'b000  3'b010  3'b100
3'b011     3'b011  3'b000  3'b010  3'b100
3'b100       ?       ?        ?    3'b100

Por ejemplo, tienes Modo = 2'b00, Mux = 3'b011 y 3'b000, que es donde tienes un bucle combinatorio.     

respondido por el caveman

Lea otras preguntas en las etiquetas