Pour le pouls, nous utilisons le Pulse-Synchronizer et pour le signal de niveau, nous utilisons un synchroniseur 2-flop mais que faire si le signal peut avoir un comportement Pulse ou Level. Y a-t-il un moyen de synchroniser cela?Traversée de domaine d'horloge pour le signal d'impulsion et de niveau
Répondre
Oui, vous pouvez mais la solution doit être basée sur la largeur de l'impulsion d'entrée par rapport à l'horloge de sortie. Lorsque l'horloge de sortie est très lente et que vous avez une impulsion, vous devez ajouter un générateur d'impulsions en ligne qui fonctionne dans le domaine d'horloge d'entrée. L'étirement est défini par la largeur de bit de stretch_out ci-dessous et "DOIT" être supérieur à une horloge sur le domaine clk de sortie.
reg [3:0] stretch_out;
always @ (posedge inclk)
begin
stretch_out <= in_signal ? 4'b1111 : {stretch_out[2:0],1'b0};
end
Maintenant, vous pouvez simplement utiliser votre synchroniseur double flop.
reg [1:0] out_sync;
always @ (posedge outclk)
begin
out_sync <= {out_sync[0],stretch_out[3]};
end
Ceci devrait synchroniser un niveau et une impulsion d'un domaine rapide vers un domaine lent.
Le seul problème, c'est que vous allez ajouter plus que votre latence de flop habituelle.
Vous pouvez définir de façon asynchrone l'utilisation du signal dans le domaine de destination, synchroniser à l'aide de deux flops, puis détecter le front montant. Devrait travailler à la fois pour les impulsions courtes et les niveaux longs.
// Prevent DRC violations if using scan
wire in_signal_n = scan_mode ? 1'b1 : !signal_in;
// Following code creates a flop with both async setb and resetb
reg sig_n_async;
always @ (posedge outclk or negedge reset_n or negedge in_signal_n)
if (!reset_n)
sig_n_async <= 0;
else if (!in_signal_n)
sig_n_async <= 1;
else
sig_n_async <= 0;
// Synchronizer
reg [1:0] out_sync;
always @ (posedge outclk or negedge reset_n)
if (!reset_n)
out_sync <= 0;
else
out_sync <= {out_sync[0],sig_n_async};
// Rising edge
reg out_sync_del;
always @ (posedge outclk or negedge reset_n)
if (!reset_n)
out_sync_del <= 0;
else
out_sync_del <= out_sync[1];
wire signal_out = out_sync[1] & !out_sync_del;