2017-06-25 5 views
0

J'ai besoin de connecter un module de configuration (fonctionnant à une horloge plus lente) à un opérateur qui fonctionne à une vitesse plus élevée. La réponse standard semble être une FIFO mais j'ai pensé que je trouverais une solution plus simple qui consomme moins de ressources - avec l'inconvénient d'avoir une latence beaucoup plus élevée. Avantage pour moi est que je n'ai pas besoin de régénérer FIFO IP pour chaque taille de données possible. Dans la simulation RTL, cela semble fonctionner (je rencontre des problèmes en utilisant une post-synthèse non liée à la question).Traverser le domaine de l'horloge pour modifier les données de façon très rare

je suis absent quelque chose ou est le bon code suivant:

module fifo_int#(// This is bad name. I haven't come up with better yet 
    parameter type DATA = logic [31:0] 
    )(
    input logic rst, 
    input logic clk_in, 
    input DATA din, 
    input logic clk_out, 
    output DATA dout 
    ); 
    DATA dreg; 

    enum logic [1:0] { 
     IN, 
     STABLE, 
     WAIT_OUT 
    } in_state; 
    enum logic [1:0] { 
     WAIT_IN, 
     WRITE, 
     INV 
    } out_state; 
    logic in_output[3], out_output[3]; 
    initial begin 
     in_state <= IN; 
     out_state <= WAIT_IN; 
     for (int i = 0; i < 3; i++) begin 
      in_output[i] <= 0; 
      out_output[i] <= 0; 
     end 
    end 
    always @(posedge clk_in) 
    begin 
     case (in_state) 
     IN: begin 
      dreg <= din; 
      in_state <= STABLE; 
     end 
     STABLE: begin 
      in_state <= WAIT_OUT; 
      in_output[0] <= ~in_output[0]; 
     end 
     WAIT_OUT: begin 
      in_state <= (in_output[0] == out_output[2]) ? IN : WAIT_OUT; 
     end 
     endcase 
     out_output[1] <= out_output[0]; 
     out_output[2] <= out_output[1]; 
    end 
    always @(posedge clk_out) 
    begin 
     case (out_state) 
     WAIT_IN: begin 
      out_state <= (in_output[2] == out_output[0]) ? WAIT_IN : WRITE; 
     end 
     WRITE: begin 
      dout <= dreg; 
      out_state <= INV; 
     end 
     INV: begin 
      out_output[0] <= ~out_output[0]; 
      out_state <= WAIT_IN; 
     end 
     endcase 
     in_output[1] <= in_output[0]; 
     in_output[2] <= in_output[1]; 
    end 
endmodule 
+0

Les horloges sont-elles synchrones? Voici un lien qui explique les bases du passage de domaine d'horloge: http://www.eetimes.com/document.asp?doc_id=1279906 –

+0

@TudorTimi Non. Merci pour le lien - je ne l'ai pas encore lu mais je le ferai. –

+0

Certaines vagues du côté lent et comment vous voulez que le côté rapide fonctionne serait utile pour mieux comprendre le problème. Par exemple, comment votre côté rapide sait-il quand commencer à traiter les données? –

Répondre

0

Si vos horloges sont asynchrones, vous allez avoir besoin de synchronisation.

Pour les horloges synchrones, puisque votre côté lent est celui qui produit les données, vous n'avez besoin d'aucune mise en mémoire tampon. Les données sont de toute façon maintenues stables pour plusieurs cycles d'horloge (rapides), vous n'avez donc pas vraiment besoin de logique entre les domaines.