Hice un simple contador ascendente de 0 a 9 usando Verilog. La salida son 4 LED que se encienden cuando su bit correspondiente es 1. El código se sintetiza bien, pero en la FPGA, solo un LED se enciende y se apaga repetidamente. Los otros tres LED no se encienden 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 iluminan cuando se prueban individualmente. El reloj se ha ajustado para que su período sea de alrededor de 2 segundos.
Por favor, ayúdame. Gracias.
Revisé el módulo contador. Aquí están todos los archivos que usé:
arriba.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
contador.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
mostrar.v
module display( input wire[3:0] inumber, output wire [3:0] LEDs);
assign LEDs[3:0] = inumber[3:0];
endmodule
superior.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;
Hubo un problema con el módulo superior. No declaré el cable que se usa para conectar el módulo de visualización y 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 encienden correctamente según cada estado ahora.
Supongo que el problema puede estar en el uso cur_state
y next_state
sin índices. Intentar
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]
en todas partes y cambio =
a <=
en la segunda always
construcción.
El objetivo se puede lograr mediante 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ó; lo primero que debe hacer es asignar LEDs[3:0]
y 4'b1111
ver si todos los LED están encendidos.
La siguiente posible causa del problema es always @(*) begin
que se activa con el cambio de cualquier cable de entrada para la always
construcción de contenido. El único evento que ocurre cuando emite reinicio y cur_state
cambia a 0, y por lo tanto cur_state
se convierte en 4'b0001 y mantiene este valor.
Actualización 1: Entonces tienes LSB funcionando, otros 3 bits no funcionan. Probó 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:
simplificar 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 verificar 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
considerar lo que sucede reset
durante la prueba. ¿Estás seguro de que es constante bajo? Alternativamente, elimínelo de la configuración:
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
vea si no funciona también.
intente usar otros LED:
always @ (posedge clock) begin cur_state[3:1] <= cur_state[3:1] + 3'b001; end
always @(*)
. Puede conservar dos módulos, pero no debería haber necesidad de complicar el primer módulo con dos construcciones always. La implementación debe ser lo más concisa y legible posible: este es un objetivo de cualquier lenguaje de programación, incluido Verilog.always @(*)
parece que no realiza lo que quiere de él. RTFM sobre lo que hace y, lo más importante, cuándo.always
En mi opinión, su condición actual debería causar que no se puedan hacer coincidir los operandos en la condición con los bordes correspondientes en el control de evento adjunto del error de construcción siempre. También explique cómo no funciona ahora.
makoto
AyudanteRey
makoto
AyudanteRey
makoto
AyudanteRey
greg
LEDs[3]
es el único que se enciende. Si ese es el caso, intente reducir la velocidad de su reloj a 1/4 de su frecuencia actual. Si eso no funciona, vuelva a verificar el mapeo en su top.ucfgreg
or posedge reset
para que sea un reinicio síncrono. Dudo que la asincronía sea el problema, creo que la frecuencia del reloj es probablemente el problema.