Múltiples salidas de LED en FPGA usando Verilog

2

Hice un contador simple de 0 a 9 con Verilog. La salida es de 4 LED que se encienden cuando su bit correspondiente es 1. El código se sintetiza bien, pero en el FPGA, solo un LED se enciende y apaga repetidamente. Los otros tres LEDs no se iluminan en absoluto. Aquí está mi código:

module counter(
   input wire clock,
   input wire reset,

   output wire [3:0] o_number
);

reg [3:0] cur_state;
reg [3:0] next_state;

always @(posedge clock or posedge reset) begin
   if (reset) cur_state <= 4'b0;
   else 
    cur_state <= next_state;
end

// Next state function
always @(*) begin
   if (cur_state == 4'b1001) next_state = 4'b0000;
   else next_state = cur_state + 4'b0001;
end

 // Output function
assign o_number = cur_state;

endmodule

module display(
   input wire [3:0] inumber,

   output wire [3:0] LEDs
);

assign LEDs = inumber;

endmodule

Ninguno de los LED está roto, ya que todos se encienden cuando se prueban individualmente. El reloj se ha ajustado por lo que su período es de alrededor de 2 segundos.

Por favor, ayúdame. Gracias.

Revisé el módulo contador. Aquí están todos los archivos que utilicé:

top.v

module top ( input wire clock, input wire reset, output wire [3:0] LEDs);
counter c1 (.clock(clock), .reset(reset), .o_number(number));
display d1 (.inumber(number), .LEDs(LEDs));
endmodule

counter.v

module counter ( input wire clock, input wire reset, output wire [3:0] o_number);
reg [3:0] cur_state;
always @ (posedge clock or posedge reset) begin
    if (reset) cur_state[3:0] <= 4'b0000;
    else begin
        if (cur_state[3:0]==4'b1001) cur_state[3:0] <= 4'b0000;
        else cur_state[3:0] <= cur_state[3:0] + 4'b0001;
    end
end
assign o_number[3:0]=cur_state[3:0];
endmodule

display.v

module display( input wire[3:0] inumber, output wire [3:0] LEDs);
assign LEDs[3:0] = inumber[3:0];
endmodule

top.ucf

NET "LEDs[0]" LOC = K12;
NET "LEDs[1]" LOC = P14;
NET "LEDs[2]" LOC = L12;
NET "LEDs[3]" LOC = N14;

NET "clock" LOC = T9;
NET "reset" LOC = L14;
    
pregunta HelperKing

2 respuestas

3

Hubo un problema con el módulo superior. No declaré el cable que se utiliza para conectar la pantalla y el módulo contador.

Aquí está el top.v revisado:

module top ( input wire clock, input wire reset, output wire [3:0] LEDs);
wire [3:0] number;
counter c1 (.clock(clock), .reset(reset), .o_number(number));
display d1 (.inumber(number), .LEDs(LEDs));
endmodule

Los LED se iluminan correctamente de acuerdo con cada estado ahora.

    
respondido por el HelperKing
1

Creo que el problema puede estar en el uso de cur_state y next_state sin índices. Intenta

always @(posedge clock or posedge reset) begin
    if (reset) cur_state[3:0] <= 4'b0;
    else begin
        cur_state[3:0] <= next_state[3:0];
end

always @(*) begin
    if (cur_state[3:0] == 4'b1001) next_state[3:0] <= 4'b0000;
    else next_state[3:0] <= cur_state[3:0] + 4'b0001;
end

y

assign o_number[3:0] = cur_state[3:0];

y

assign LEDs[3:0] = inumber[3:0];

Tenga en cuenta que agrego [3:0] a todas partes y que cambia = a <= en la segunda construcción always .

El objetivo se puede lograr con una configuración mucho más simple:

module counter(
input wire clock,
input wire reset,
output wire [3:0] LEDs
);

reg [3:0] cur_state;
wire reset_n=~reset;
assign LEDs[3:0] = cur_state[3:0];

always @(posedge clock or negedge reset_n) begin
    if (!reset_n) cur_state[3:0] <= {4{1'b0}};
    else begin
        if (cur_state[3:0] == 4'b1001) cur_state[3:0] <= {4{1'b0}};
        else cur_state[3:0] <= cur_state[3:0] + 4'b1;
    end
end

Actualización: No ayudó, entonces lo primero que hizo fue simplemente asignar LEDs[3:0] con 4'b1111 y ver si todos los LED están encendidos.

La siguiente posible causa del problema es always @(*) begin , que se activa al cambiar cualquier cable de entrada para la construcción de contenido always . El único evento que ocurre cuando se emiten reinicios y cur_state cambia a 0, por lo que cur_state se convierte en 4'b0001 y mantiene este valor.

Actualización 1: Así que tienes LSB funcionando, otros 3 bits no funcionan. Comprobó que todos los LED están encendidos cuando escribe 4'b1111 en los cables de los LED. Creo que el código es correcto, hay algo más que está mal. Considera lo siguiente:

  • simplifica el cambio de decimal a hexadecimal. En este caso, solo tendrá cur_state[3:0] <= cur_state[3:0] + 4'b1; sin ninguna condición que compruebe el estado # 10

    always @ (posedge clock or posedge reset) begin if (reset) cur_state[3:0] <= 4'b0000; else cur_state[3:0] <= cur_state[3:0] + 4'b0001; end

  • considere lo que sucede con reset durante la prueba. ¿Estás seguro de que es constante bajo? Alternativamente, elimínelo de la configuración en absoluto:

    always @ (posedge clock) begin cur_state[3:0] <= cur_state[3:0] + 4'b0001; end

  • sintetice mi código anterior con solo un módulo y reset_n para ver si no funciona también.

  • intenta usar otros LEDs:

    always @ (posedge clock) begin cur_state[3:1] <= cur_state[3:1] + 3'b001; end

respondido por el Anonymous

Lea otras preguntas en las etiquetas