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.
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.
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:
Partie pratique J'ai
trois planches Ă ma disposition:
- Kit d'Ă©valuation KC705
- Kit d'Ă©valuation ML507
- Carte chinoise Spartan-6 XC6SLX16
Regarder vers l'avantPour 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.
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).
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é.
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.
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;