Ich verwende Verilog in Lattice Diamond IDE mit einem Lattice MachXO2 7000HE Breakout Board.
Ich habe einen einfachen Zähler mit einem Grenzwerteingang gebaut, der einen Taktausgang mit variabler Periode erzeugt. Es funktioniert für sich genommen gut, aber wenn ich zwei Instanzen dieses Moduls hinzufüge und sie in Reihe schalte (um die Frequenz zweimal zu skalieren), erhalte ich ein seltsames Ergebnis auf dem FPGA. Die Simulation scheint jedoch das zu zeigen, was ich vom Code erwartet hatte.
Hier ist das oberste Modul:
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
Und hier ist die Testbench für meine Simulation:
`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
Hier ist die Simulationsausgabe:
Und die Scope-Ausgabe:
ch1 - fpga_clock
ch2 - cnt1_clock
ch3 - cnt2_clock
ch4 - cnt2_counter[1]
Kanal 3 ( cnt2_clock ) sollte die doppelte Periode von cnt2_counter[1] haben , wie es in der Simulationsausgabe steht. Stattdessen ist es, wie Sie sehen können, ein Burst von Flanken mit höherer Frequenz, wo die einzelne Flanke sein sollte. Ich bin jetzt schon eine Weile dabei. Was vermisse ich?
Lassen Sie mich auch das Schema hinzufügen:
Danke schön!
########## Mit zusätzlichen Bildern bearbeitenScope-Ausgabe mit cnt2_counter[0]
ch1 - fpga_clock
ch2 - cnt1_clock
ch3 - cnt2_counter[0]
ch4 - cnt2_counter[1]
Sie verwenden eine generierte Uhr. Dies ist normalerweise auf einem FPGA nicht ratsam, da es sehr sorgfältig durchgeführt werden muss, um Störungen zu vermeiden und sicherzustellen, dass ein Timing-Schließen möglich ist. Es sieht so aus, als ob Sie einige Störungen auf cnt1_clock bekommen, die die zweite Instanz vermasseln. Versuchen Sie es mit Clock Enables und sehen Sie, was passiert.
Außerdem sollte fpga_clock ein Eingang und kein Ausgang in Ihrem Top-Modul sein.
Wie soll das funktionieren?
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
Vielleicht meinst du:
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
Anonym
amfast
Vance
CapnJJ
amfast
amfast
CapnJJ
Vance
amfast
amfast
Vance