Estoy usando Verilog en Lattice Diamond IDE con una placa de conexión MachXO2 7000HE de celosía.
Construí un contador básico con una entrada de límite que genera una salida de reloj de período variable. Funciona bien por sí solo, sin embargo, cuando agrego dos instancias de este módulo y las conecto en serie (para escalar la frecuencia dos veces), obtengo un resultado extraño en el FPGA. Sin embargo, la simulación parece mostrar lo que esperaba del código.
Aquí está el módulo superior:
module clock_generator (fpga_clock, cnt1_clock, cnt2_clock, cnt2_counter);
output wire fpga_clock;
output wire cnt1_clock;
output wire cnt2_clock;
output wire [7:0] cnt2_counter;
reg [7:0] default_period_1 = 8'b00000011;
reg [7:0] default_period_2 = 8'b00000011;
defparam OSCH_inst.NOM_FREQ = "2.08";
OSCH OSCH_inst(.STDBY(1'b0), .OSC(fpga_clock));
counter Counter_1_inst(.clk_in(fpga_clock), .limit_in(default_period_1), .clk_out(cnt1_clock), .cnt_out());
counter Counter_2_inst(.clk_in(cnt1_clock), .limit_in(default_period_1), .clk_out(cnt2_clock), .cnt_out(cnt2_counter));
endmodule
module counter (clk_in, limit_in, clk_out, cnt_out, rst);
input wire clk_in;
input wire [7:0] limit_in;
output reg clk_out = 1'b1;
output reg [7:0] cnt_out = 8'b00000000;
input wire rst;
always @(posedge clk_in or posedge rst) begin
if (rst) begin
clk_out <=0;
cnt_out <=0;
end else if (cnt_out == limit_in) begin
clk_out <= !clk_out;
cnt_out <= 0;
end else begin
cnt_out <= cnt_out + 1'b1;
end
end
endmodule
Y aquí está el banco de pruebas para mi simulación:
`timescale 1 ns / 1 ns
module testbench;
wire fpga_clock;
wire cnt1_clock;
wire cnt2_clock;
wire [7:0] cnt2_counter;
clock_generator dut(.fpga_clock(fpga_clock), .cnt1_clock(cnt1_clock), .cnt2_clock(cnt2_clock), .cnt2_counter(cnt2_counter));
initial begin
#1400000000
$finish;
end
endmodule
Aquí está el resultado de la simulación:
Y la salida del alcance:
ch1 - fpga_reloj
ch2 - cnt1_clock
ch3 - cnt2_clock
ch4 - contador_cnt2[1]
Y la configuración de la sonda:
El canal 3 ( cnt2_clock ) debe tener el doble del período de cnt2_counter[1] , como está en la salida de la simulación. En cambio, como puede ver, es una explosión de bordes de frecuencia más alta donde debería estar el borde único. He estado en esto por un tiempo ahora. ¿Qué me estoy perdiendo?
Permítanme agregar también el shematic:
¡Gracias!
########## Editar con imágenes adicionalesSalida de alcance con cnt2_counter[0]
ch1 - fpga_reloj
ch2 - cnt1_clock
ch3 - contador_cnt2[0]
ch4 - contador_cnt2[1]
Estás usando un reloj generado. Por lo general, esto no es recomendable en un FPGA, ya que debe hacerse con mucho cuidado para evitar fallas y garantizar que el cierre de tiempo sea posible. Parece que podría estar experimentando algunas fallas en cnt1_clock que están arruinando la segunda instancia. Intente usar las habilitaciones de reloj y vea qué sucede.
Además, fpga_clock debe ser una entrada y no una salida en su módulo superior.
¿Cómo debería funcionar esto?
always @(posedge clk_in) begin
cnt_out <= cnt_out + 1'b1;
if (cnt_out == limit_in) begin
clk_out <= !clk_out;
cnt_out <= 0;
end
end
Tal vez te refieres a:
always @(posedge clk_in) begin
cnt_out <= (cnt_out == limit_in) ? 0 : cnt_out + 1;
clk_out <= (cnt_out == limit_in) ? ~clk_out : clk_out;
end
Anónimo
amfast
Vance
CapnJJ
amfast
amfast
CapnJJ
Vance
amfast
amfast
Vance