2017-08-07 8 views
1

J'essaie d'interfacer un module avec une FIFO asynchrone générée par le générateur Xilinx CORE. Cependant, j'ai observé que les données fournies au port d'entrée d'AFIFO (bien que correct) commencent à apparaître sur dout après une latence de 6-7 cycles d'horloge. Doit on s'y attendre? Ou est-ce que je fais quelque chose de mal? Ce que je suis en train de faire est d'affirmer la broche write_enable de AFIFO, fournir les données d'entrée, puis affirmer la broche read_enable au cycle suivant. Mais le problème de la latence existe toujours. Toute aide est appréciée.Lire après écriture latence dans FIFO asynchrone?

EDIT: Je joins une partie de mon code.

always @ (posedge clk1, posedge rst)//faster clock domain 
begin 
    if (rst) 
     wr_en<= 1'b 0; 

    else 
     begin 
      if (data_wrt) 
       begin 
       wr_en<= 1'b 1;       
       end 
      else 
       wr_en<= 1'b 0; 
     end 
end 
always @ (negedge clk2, posedge rst)//slower clock domain 
    begin 
     if (rst) 
      rd_en<= 1'b 0; 

     else 
      begin 
       if (wr_en) 
        begin 
        rd_en<= 1'b 1;        
        end 
       else 
        rd_en<= 1'b 0;    
      end 

    end 
AFIFO AFIFO1(//AFIFO module instantiation 
    .din(data_in), 
    .rd_clk(clk2), 
    .rd_en(rd_en), 
    .rst(reset), 
    .wr_clk(clk1), 
    .wr_en(wr_en), 
    .dout(data_out), 
    .empty(empty), 
    .full(full) 
    ); 

AFIFO Input Output

AFIFO2

+1

un fragment de code? – Serge

+0

Si votre 'clk2' est plus lent que' clk1', votre flip flop 'rd_en' pourrait manquer certains des signaux d'activation (dans le bloc' if (wr_en) '). –

+0

Alors que dois-je faire? – Candy

Répondre

2

Quelle est la relation d'horloge? En supposant que vous voyez la latence dans les cycles 6-7 clk1 (horloge rapide), cela semble être quelque chose que vous attendez selon la relation d'horloge clk1/clk2. Cela dit, le point d'une FIFO asynchrone est habituellement d'agir comme un synchroniseur d'un domaine d'horloge à un autre. Le domaine d'horloge d'écriture (clk1) écrira des données à l'AFIFO tant qu'il n'est pas plein. Le domaine d'horloge de lecture (clk2) lira les nouvelles données tant que l'AFIFO n'est pas vide. Ce que vous faites ici rompt cet usage. Vous utilisez wr_en qui est généré par clk1 pour contrôler rd_en qui est cadencé par clk2. Alors maintenant wr_en est utilisé dans les deux domaines d'horloge et provoquera metastability. Donc, en bref, vous n'utilisez pas correctement AFIFO. Essayez plutôt de laisser votre logique clk2 toujours définie rd_en lorsque AFIFO est !empty.

+0

J'ai téléchargé une capture d'écran de mes simulations avec AFIFO. – Candy

+0

Un certain nombre de choses semblent un peu étranges dans cette image.D'abord je dirais que le retard que vous voyez est beaucoup plus grand que ce à quoi je m'attendais. Six cycles d'horloge lents semblent excessifs. Cela peut être quelque chose qui est contrôlable dans le générateur FIFO. Deuxièmement, 'empty' et' data_out' ne semblent pas synchrones avec clk2, mais ils sont plutôt retardés de 1/4 de cycle. Cela peut toutefois être un retard simulé, et aussi une partie du générateur FIFO. Enfin, vous continuez d'activer 'rd_en' quand il ne devrait pas être activé. 'rd_en' ne devrait jamais être haut tant que' empty' est haut. – Hida

+0

J'ai aussi téléchargé la seconde capture d'écran dans laquelle rd_en est activé quand AFIFO est! Vide. Maintenant, je me trompe de première valeur à data_out !! Avec les avertissements suivants lorsque je simule: Erreur: C: /Xilinx/verilog/src/simprims/X_RAMB16_S36_S36.v (2655): $ setup (posedge DIA [1] &&& dia_enable: 127784 ps, posture CLKA: 127972 ps, 484 ps); # Heure: 127972 ps Itération: 3 Instance: /tb/uut/\AFIFO1/BU2/U0/grf.rf/mem/gbm.gbmg.gbmga.ngecc.bmg/blk_mem_generator/valid.cstr/ramloop[0]. ram.r/v2_noinit.ram/dp36x36.ram \ – Candy

2

Je pense que vous voulez transformer certaines données synchrones en clk1 en synchrones avec clk2 par une FIFO asynchrone. Tout d'abord, vous n'avez pas besoin d'échantillonner le signal synchrone de clk1 directement par clk2. Comme utiliser wr_en qui est généré par clk1 pour contrôler rd_en qui est cadencé par clk2.Il provoquera la métastabilité. FIFO est toujours utilisé pour résoudre le problème de la métastabilité. Donc, pas besoin de faire comme le second bloc toujours.

Donc, le problème est de savoir comment utiliser FIFO asynchrone correctement. Vous devriez lire le guide du produit générateur Xilinx FIFO comme PG057.Vous devriez connaître la théorie et la méthode d'utilisation de FIFO. Sinon, vous aurez beaucoup de mal quand vous utilisez FIFO.

Mon conseil est ci-dessous. Pour l'opération d'écriture, vous devez utiliser à la fois le signal almost_full et full pour éviter les débordements. Vous pouvez le voir dans PG057 figure 3-2. Vous devez utiliser almost_full, car si wr_en est continu, alors le signal complet est 1 clock plus lent à aviod overflow . Pour une opération de lecture, vous devez utiliser à la fois le signal almost_empty et le signal vide, pour la même raison. Ensuite, vous pouvez transformer la zone d'horloge correctement.

Pardonnez mon anglais.