Générer une horloge en FPGA sur des primitives

En lisant les fiches techniques sur les FPGA, vous pouvez trouver des signes sur leurs fréquences de fonctionnement ... Mais



non, l'histoire commence en 2015, lorsque je me suis familiarisĂ© avec les FPGA. Dans mes premiers travaux simples, j'ai formĂ© l'horloge dont j'avais besoin Ă  partir du compteur et alimentĂ© toute la logique de celui-ci (naturellement, Ă  condition que j'aie besoin de l'horloge plus lente qu'elle n'Ă©tait alimentĂ©e au FPGA, par exemple UART et SPI). Naturellement, ils m'ont poursuivi pour cela, mais j'avais une simple excuse «mais ça marche!», Et tout a vraiment fonctionnĂ©. Depuis, la pensĂ©e s'est glissĂ©e dans ma tĂȘte: "D'oĂč puis-je obtenir le signal de synchronisation?"



Il n'y a pas beaucoup d'options pour que les sources prennent un lambeau. Soit prendre à partir d'un certain ClockWizard basé sur PLL ou MMCM, ou le former à partir d'un compteur, ou immédiatement à partir de la jambe, pour ainsi dire, à une seule extrémité. Et si nous prenions le signal d'horloge généré par la primitive FPGA?



Dans le cadre de cet article, j'ai dĂ©cidĂ© de considĂ©rer trois options: un multiplexeur (MUXF7), une table de vĂ©ritĂ© (LUT1) et court-circuiter les jambes du FPGA Ă  elles-mĂȘmes.



Dans le cas d'un multiplexeur, la sortie est envoyée au signal de commande et les signaux d'entrée sont tirés vers 0 et 1.



image


Dans le cas de LUT, nous court-circuitons la sortie sur l'entrée et définissons la table de vérité inverseuse. Lors de la fourniture de "1", sortie zéro et lors de la fourniture de "0", sortie un.



image


Dans le cas du GPIO, tout y est simple, le signal de sortie est affecté à l'inverse du signal d'entrée:

attribuer s2 = ~ s1;


Le but de l'expérience: générer une fréquence de trois maniÚres et la mesurer.

Nous mesurerons la fréquence aux dépens des compteurs. Il y aura 4 compteurs: trois pour chaque option et un compteur de base, par rapport auquel tout sera compté. Et nous regarderons ces compteurs via ChipScope.



Et voici le code complet du module:
module gen_clk(
    input clk_base,
    input s1, //gpio
    output s2 //gpio
    );

//  - 
assign s2 = ~s1;
wire clk_gpio = s1;
reg [31:0] cnt_gpio = 0;
 (* MARK_DEBUG="true" *) reg [31:0] cnt_gpio_buf = 0;
always@(posedge clk_gpio)
begin 
    if(cnt_gpio[2:0]==3'd0) cnt_gpio_buf<=cnt_gpio; 
    cnt_gpio <= cnt_gpio + 1'b1;
end

//  
wire clk_mux;
MUXF7 MUXF7_inst
(
    .O(clk_mux),
    .I0(1'b1),
    .I1(1'b0),
    .S(clk_mux)
);
reg [31:0] cnt_mux = 0;
 (* MARK_DEBUG="true" *) reg [31:0] cnt_mux_buf = 0;
always@(posedge clk_mux)
begin 
    if(cnt_mux[2:0]==3'd0) cnt_mux_buf<=cnt_mux; 
    cnt_mux <= cnt_mux + 1'b1;
end
//   
wire clk_lut;
LUT1#(
    .INIT(2'b01)
)
LUT1_inst(
    .O(clk_lut),
    .I0(clk_lut)
);
reg [31:0] cnt_lut = 0;
 (* MARK_DEBUG="true" *) reg [31:0] cnt_lut_buf = 0;
always@(posedge clk_lut)
begin 
    if(cnt_lut[2:0]==3'd0) cnt_lut_buf<=cnt_lut; 
    cnt_lut <= cnt_lut + 1'b1;
end
//         
 (* MARK_DEBUG="true" *) reg [31:0] cnt_base = 'd0;        
always@(posedge clk_base)
begin
    cnt_base <= cnt_base + 1'b1;
end    
   
endmodule




Voici un schéma du projet. Les primitives sont encerclées et les flÚches indiquent le signal qui sera entré dans le ChipScope pour l'analyse de fréquence:



image




Partie pratique J'ai



trois planches Ă  ma disposition:



  1. Kit d'Ă©valuation KC705



    image


  2. Kit d'Ă©valuation ML507



    image


  3. Carte chinoise Spartan-6 XC6SLX16



    image


    Regarder vers l'avant
    Pour l'avenir, je dirai que le dernier conseil n'a pas eu un résultat normal.





Et donc maintenant les résultats réels



Kintex-7:



Depuis que le projet a commencĂ© Ă  ĂȘtre fait pour lui, le projet n'a pas Ă©tĂ© Ă©crit entiĂšrement en une seule fois, mais par Ă©tapes. Tout d'abord, j'ai connectĂ© une LUT, ajoutĂ© des signaux au dĂ©bogage et commencĂ© Ă  regarder.



Le compteur de base est cadencĂ© Ă  200 MHz, il n'est donc pas difficile de calculer la frĂ©quence des horloges gĂ©nĂ©rĂ©es sur le butin, combien de fois le compteur delta du compteur de butin est le delta du compteur de base en mĂȘme temps, autant de fois sa frĂ©quence. Dans ce cas: la frĂ©quence gĂ©nĂ©rĂ©e par le butin est de 381,55 MHz.



image


Maintenant, nous allons ajouter un multiplexeur au projet, et par analogie avec un butin, nous allons calculer la fréquence pour celui-ci, et pour le butin (aprÚs tout, quelque chose doit changer).



image


La premiĂšre chose qui attire un coup d'Ɠil est Ă  quel point le comptoir claque. Cela affecte la frĂ©quence Ă©norme du multiplexeur, mais en gĂ©nĂ©ral, il est clair que le compteur augmente, ce qui signifie qu'il peut Ă©galement ĂȘtre pris et comptĂ©. Finalement:



  • FrĂ©quence du multiplexeur: 5953,89 MHz
  • FrĂ©quence de butin (modifiĂ©e): 379,98 MHz


Eh bien, à la fin, ajoutons une boucle fermée d'une paire GPIO au projet. La carte KC705 possÚde des connecteurs SMA J13 et J14. Ici, je les ai fermés avec un conducteur d'environ 10 cm de long.



  • FrĂ©quence GPIO: 90,59 MHz
  • FrĂ©quence du multiplexeur: 12994,13 MHz
  • FrĂ©quence du butin: 380,18 MHz


Remplaçons, par souci d'expérience, le conducteur par un plus long, j'ai un fil deux fois plus long. En conséquence, la fréquence est tombée à 85,29 MHz.



A ce stade de l'expĂ©rience, on peut constater que la frĂ©quence de fonctionnement des primitives dans les FPGA n'est pas la mĂȘme. Dans le cas oĂč il n'y avait qu'un seul butin, le synthĂ©tiseur a choisi le butin le plus rapide et a construit un circuit autour de celui-ci, puis lorsque le multiplexeur a Ă©tĂ© ajoutĂ©, le synthĂ©tiseur a essayĂ© de trouver cette super position oĂč le butin et le multiplexeur fonctionnent le plus rapidement possible, et ce sont d'autres Ă©lĂ©ments et frĂ©quences qui sont dĂ©jĂ  plus lents. Lorsque des broches externes ont Ă©tĂ© ajoutĂ©es, tout le projet sur un cristal a Ă©tĂ© fondamentalement dĂ©placĂ© sur ces jambes et le projet a commencĂ© Ă  ĂȘtre synthĂ©tisĂ© sur des Ă©lĂ©ments proches, pour une raison quelconque, Ă  cet endroit, les frĂ©quences du butin et du multiplexeur ont sensiblement augmentĂ©, mais n'oubliez pas que dans le contexte de tout cela, au projet un ChipScope d'une profondeur de 1024 et un bus de donnĂ©es de 64 Ă  128 est connectĂ© (il change de projet en projet). Passons maintenant au tableau suivant.



Virtex-5:



Je ne suis pas allé jusqu'au bout avec le tableau précédent, j'ai immédiatement ajouté les 3 options pour générer une cape et j'ai regardé dans ChipScope ce qui s'était passé.



image


La figure montre deux étiquettes X et O. Outre leurs valeurs dans les colonnes, le format des nombres est décimal non signé. Il est à noter que le compteur de base compte désormais à 100 MHz. Et donc le résultat:



  • FrĂ©quence GPIO: 96,34 MHz
  • FrĂ©quence du multiplexeur: 614,41 MHz
  • FrĂ©quence de butin: 5761,1 MHz


On peut voir que sur cette carte, le butin s'est avĂ©rĂ© plus rapide que le multiplexeur, et que la frĂ©quence des broches s'est avĂ©rĂ©e plus Ă©levĂ©e que sur la premiĂšre carte, peut-ĂȘtre parce que j'ai connectĂ© les deux broches non pas avec un conducteur de 10 cm, mais avec un cavalier, en consĂ©quence, la ligne de communication est devenue plus courte et la frĂ©quence Ă©tait plus Ă©levĂ©e.



Et maintenant la derniĂšre option avec une planche chinoise.



Spartan-6:



Il y a deux compteurs de base dans ChipScope, en fait c'est le mĂȘme compteur qui ne voulait tout simplement pas reconfigurer ChipScope. Dans ce projet, le compteur de base est cadencĂ© Ă  50 MHz.



image


Dans le cas de cette planche, tout s'est avĂ©rĂ© beaucoup plus compliquĂ©. PremiĂšrement, le projet ne souhaitait en aucune maniĂšre ĂȘtre synthĂ©tisĂ© sous la forme synthĂ©tisĂ©e dans les versions prĂ©cĂ©dentes. DeuxiĂšmement, Ă  la fin, j'ai dĂ» jeter la LUT, j'ai essayĂ© de la remplacer par une cinq voies, mais cela n'a pas fonctionnĂ© non plus. En gĂ©nĂ©ral, voici les rĂ©sultats:



  • FrĂ©quence GPIO: 51,77 MHz
  • FrĂ©quence du multiplexeur: 3490504 MHz
  • FrĂ©quence du butin: Ă©chec de la collecte


Les rĂ©sultats obtenus par cette carte se sont rĂ©vĂ©lĂ©s peu satisfaisants, non seulement parce que le butin ne pouvait pas ĂȘtre utilisĂ© comme un morceau, mais aussi Ă  cause de la frĂ©quence incroyablement Ă©norme du multiplexeur. En ce qui concerne le lambeau gĂ©nĂ©rĂ© sur les pattes, un conducteur d'environ 25-30 cm a Ă©tĂ© utilisĂ©, fermĂ© par un fil Ă  l'extrĂ©mitĂ©, des capacitĂ©s et inductances parasites s'y sont probablement formĂ©es, ce qui a eu leur effet sur la gĂ©nĂ©ration du lambeau.



Conclusion



En gĂ©nĂ©ral, nous avons rĂ©ussi Ă  gĂ©nĂ©rer des signaux d'horloge sur diverses primitives, et nous avons Ă©galement rĂ©ussi Ă  voir (en utilisant le Kintex-7 comme exemple) que les primitives ont une latence diffĂ©rente en fonction de leur emplacement. En mon nom personnel, je tiens Ă  ajouter que je ne considĂšre pas l'expĂ©rience rĂ©alisĂ©e comme tout Ă  fait correcte, par exemple, la largeur de bits des compteurs n'a pas Ă©tĂ© calculĂ©e, le transfert de signal de diffĂ©rents domaines d'horloge n'a pas Ă©tĂ© pris en compte (bien que j'ai fait rester le signal dans le tampon pendant plusieurs horloges), le ChipScope lui-mĂȘme devrait idĂ©alement ĂȘtre supprimĂ© et un autre moyen devrait ĂȘtre trouvĂ© analyser la frĂ©quence gĂ©nĂ©rĂ©e.



Les problÚmes rencontrés:
Vivado ISE , . :



  • set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets -of_objects [get_cells gen_clk_inst/LUT1_inst]]
  • NET «s1» CLOCK_DEDICATED_ROUTE = FALSE;





All Articles