Ich habe eine schnelle Uhr und einen Schalter namens "bereit". Wenn der Schalter umgelegt wird (bereit geht auf HIGH), möchte ich, dass der Ausgang pcEn einen Impuls erzeugt, der nur einen Taktzyklus dauert. pcEn wird nur dann einen weiteren Impuls ausgeben, wenn ready das nächste Mal wieder auf HIGH geht.
Der folgende Code simuliert korrekt, ist aber leider nicht synthetisierbar. Beachten Sie, dass Platz eine wichtige Überlegung ist, daher habe ich mich gefragt, ob es möglich ist, dies ohne Verwendung einer Zustandsmaschine (die viele Logikelemente verwendet) zu implementieren.
module control
(
output logic pcEn,
input clock, ready
);
always_ff @(negedge clock)
pcEn <= 1'b0;
always_ff @(posedge ready)
pcEn <= 1'b1;
endmodule
Meine übliche Technik besteht darin, einen zweistufigen Synchronisierer zu implementieren, um die asynchrone Eingabe in den Zeitbereich der Uhr zu bringen, und dann ein weiteres Flip-Flop als Flankendetektor zu verwenden. Abhängig von der Logik, die Sie in der letzten Anweisung verwenden, können Sie steigende Flanken, fallende Flanken oder beides erkennen.
module control
(
output logic pcEn,
input clock, ready
);
reg r1, r2, r3;
always @(posedge clock) begin
r1 <= ready; // first stage of 2-stage synchronizer
r2 <= r1; // second stage of 2-stage synchronizer
r3 <= r2; // edge detector memory
end
pcEn <= r2 && !r3; // pulse on rising edge
endmodule
Die übliche Formation für Toggle-to-Pulse ist in etwa so
module flip (output logic pcEn, input clock, input ready);
reg state;
always_ff @(posedge clock)
state <= ready;
assign pcEn = state != ready;
endmodule
Wenn ready
es extern angesteuert wird, lohnt es sich, es zu bereinigen, um es zuerst mit einer Taktflanke mit einer einzelnen Registerstufe auszurichten. Das Zurücksetzen ist nicht erforderlich. Wenn Sie den Ausgang zählen möchten , müssen Sie auch das Schalterprellen adressieren .
Um den Kommentar von Daves anzusprechen: geändert, um den Ausgang pcEn zu registrieren und bei steigender Flanke auszulösen.
module flip (output reg pcEn, input clock, input ready);
reg state;
always_ff @(posedge clock) begin
state <= ready;
pcEn <= state != ready && ready;
end
endmodule
ready
richtig. Es besteht die Möglichkeit von Setup/Hold-Time-Verletzungen am letzten Flip-Flop, wodurch es in einen metastabilen Zustand versetzt wird.Dies scheint Xilinx zu empfehlen, was nicht allzu weit von Dave Tweeds entfernt ist:
(* ASYNC_REG = "TRUE" *) reg state;
(* ASYNC_REG = "TRUE" *) reg statemeta;
reg reloadRegmeta = 1'b0;
# -> for negative edge assign pcEn = state | (~reloadRegmeta);
assign pcEn = state && (~reloadRegmeta);
always @(posedge S_AXI_ACLK) begin
statemeta <= ready;
state <= statemeta;
reloadRegmeta <= state;
end
shuckc
geft
shuckc
geft
Martin Thomson