Hallo, mich würde mal im Allgemeinen interessieren wie man in Verilog die PLLs eines FPGAs anspricht bzw. wo etwas darüber zu finden ist. Ich möchte nämlich aus einem Referenztakt heraus mir mehrere Takte für verschiedene Module erzeugen, da ich mit mehreren verschiedenen Takten arbeiten muss. Ich weiß, dass sowas über die PLLs möglich ist, aber ich habe noch nichts aufschlüssiges darüber gefunden bzw. Beispiele dazu gesehen. Würde mich freuen wenn mir jemand helfen kann.
Xilinx CoreGen Altera MegaWizard Dort die Komponente erzeugen und einbinden
Stichwort: DCM (Digital Clock Management) Die Anzahl der verfügbaren DCM varriert nach FPGA Typ. Ein Blick in das Datenblatt des FPGA sollte dir da Klarheit verschaffen ;-) Ansonsten kannst du Takte auch noch mittels T-FlipFlop oder Zählern teilen.
Marten V. schrieb: > Ansonsten kannst du Takte auch noch mittels T-FlipFlop oder Zählern > teilen. Ja, und das vergessen wir gleich mal wieder. Denn so ein "Takt" wird dann mit "normalen" Verdrahtungsressourcen und entsprechndem Skew kreuz&quer im FPGA verteilt. Die Xilinx Tools sagen dazu diplomatisch "This is no good design practice"... ;-)
Hallo, danke schonmal vorab für die Antworten. Aber irgendwie komm ich auf diese Weise nicht unbedingt weiter. Ich möchte mal etwas konkreter werden: Habe hier ein ML505-Evalboard von Xilinx mit nem Virtex-5 LX50T drauf. Dieses Board hat fest integrierte Takte drauf, welche 27, 33, 100 und differenziell 200MHz betragen. Nun habe ich schon einige Module geschrieben, die ich brauche und in der Testbench mit virtuellem Taktmanagement schon funktionsfähig gemacht. Was ich aber jetzt für eine Synthetisierung brauche ist aus einem der vorhandenen Referenztakte einen Takt von GENAU 6,952 MHz zu erzeugen und davon brauch ich dann hier und da noch einige vielfache... ich weiß jedoch nicht wie ich es schaffe das ganze auf so nen krummen Wert zu teilen. Habe mich jetzt bisschen auch durch den Corgen durchgeschlagen, aber was ich hier so an Optionen finde macht mich irgendwie nicht glücklich. Da dieser für das Clock Management immer ganze Zahlen zum teilen verlangt und auch bestimmte Grenzen aufweist und im Grunde genommen erzeugt er mir auch nur eine HDL-Datei, die ich einbinden muss.. das heißt ich werd wahrscheinlich selber was schreiben müssen - ich hätte halt nur gern die passende Referenz dazu - so eine Art DCM/PLL Tutorial in der sowas schon mal in einem Beispiel codiert wird, damit ich mir ein Bild davon machen kann.
Veribro schrieb: > Aber irgendwie komm ich auf diese Weise nicht unbedingt weiter. Dann hat offenbar noch Information gefehlt... Veribro schrieb: > brauche ... einen Takt von GENAU 6,952 MHz Tja, das wirst du aus den vorhandenen Takten (erst mal) nicht schaffen. Mir fällt da auf Anhieb kein Multiplikaotr&Teilerpärchen ein, der aus einem der genannten Takte genau die 6952kHz macht. > und davon brauch ich dann hier und da noch einige vielfache... Das ist jetzt aber bedenklich... Sag doch einfach mal, wofür du diesen Takt brauchst. Und sag auch, ob der z.B. im Bereich von 5ns jittern darf (das wäre der Kehrwert von 200MHz)...
Lothar Miller schrieb: > Sag doch einfach mal, wofür du diesen Takt brauchst. Für ein DVB-C Basisband (schreibt eine in Deutschland festgelegte Norm von 6,952 MSym/s vor) - d.h. ich werd nach meinem vorletzten Modul auf jeden Fall mit 6,952 MHz takten müssen. Für das IQ-Basisband am Ausgang selbst wird dann der halbe Takt davon verwendet. > Und sag auch, ob der z.B. im Bereich von 5ns jittern darf (das wäre der > Kehrwert von 200MHz)... Wäre eigentlich nicht so toll, weil ich ein möglichst schönes Signal erzielen möchte, aber ich wäre froh wenn der Ansatz dafür da wäre den gewünschten Takt zu generieren.
Veribro schrieb: > aber ich wäre froh wenn der Ansatz dafür da wäre den > gewünschten Takt zu generieren. Dann probier mal diesen DDFS Ansatz:
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
4 | |
5 | entity CLKdiv is |
6 | Port ( clk : in STD_LOGIC; |
7 | co : out STD_LOGIC); |
8 | end CLKdiv; |
9 | |
10 | architecture Behavioral of CLKdiv is |
11 | signal presc : unsigned (31 downto 0) := (others=>'0'); |
12 | signal cdiv : std_logic; |
13 | |
14 | -- evtl. nötig, wenn die Synthese den neuen Takt nicht selber erkennt
|
15 | -- attribute buffer_type: string;
|
16 | -- attribute buffer_type of cdiv: signal is "bufg";
|
17 | |
18 | begin
|
19 | process begin |
20 | wait until rising_edge(clk); |
21 | presc <= presc+149293063; -- (2**32/(200000000/6952000)) |
22 | end process; |
23 | |
24 | process begin |
25 | wait until rising_edge(clk); |
26 | cdiv <= presc(31); -- das MSB wird zum neuen Takt |
27 | end process; |
28 | |
29 | co <= cdiv; |
30 | end Behavioral; |
Damit hast du bei 200MHz Eingangstaktfrequenz einen Ausgangstakt co von 6951999,9 Hz... ;-) Allerdings bleibt dir da wie erwähnt der Jitter von 5ns.
vielen vielen Dank Lothar, das hat mir einiges an Erkenntnis gebracht, ich werde mir diesen Codeschnipsel mal zu Herzen nehmen und schauen wie ich jetzt an die ganze Sache rangehe.
5 ns Phasenjitter ist für ein analoges Signal komplett unbrauchbar. Wenn du keinen passenden Oszillator montieren möchtest (oder eben eine fractional-N PLL), so kannst du quasi nur das Eingangs- und Ausgangssignal resamplen. Z.B. den ADC/DAC mit 20 MHz laufen lassen und intern die Zwischenpunkte mit 6,952 MHz errechnen z.B. mit einem Farrow-Interpolator.
Hallo, ja ich habe leider auch feststellen dürfen, dass ich mit obriger Methode nicht an mein Ziel komme. Hat jemand denn Erfahrung wie man auf dem ML505 bestückt mit einem Virtex-5 XC5VLX50T von Xilinx die PLL über die DCMs über eine HDL anspricht? Ich weiß nur, dass da noch ein IDT genannter Clock Management Chip drauf ist, aber ich hab ehrlich gesagt keinerlei Ahnung über welche Prozeße ich den anspreche. Kann es sein, dass ich über die HDL hinaus andere Algorithmen anwenden muss bzw. über irgendein bestimmtes Tool die PLL ansteuere - weil so wie ich das verstehe kann ich mit einer HDL nur reine Bit2Bit-Übertragungen machen, aber mir fallen keine konkreten speziellen PLL-Befehle oder dementsprechende Libraries bzw. Befehle dafür ein die ich aufrufen muss...
Veribro schrieb: > Hat jemand denn Erfahrung wie man auf dem ML505 bestückt mit einem > Virtex-5 XC5VLX50T von Xilinx die PLL über die DCMs über eine HDL > anspricht? Ja, einfach das Datenblatt zu den DCM und die Templates nehmen... Beitrag "VHDL code to infere DCM" Aber wie gesagt: auch wenn du die DCM instantiiert bekommst (das ist gar nicht so schwer), du wirst immer noch das Problem haben, dass keiner deiner Takte mit den verfügbaren Teilern für die gewünschte Zielfrequenz taugt. Ich hatte das schon im Beitrag "Re: Mehrere Takte aus Referenztakt teilen (PLL)" angedeutet. Fazit: schließ einfach einen passenden Takt (oder was vielfaches davon) extern an.
Hab mich jetzt doch mal aufgerauft mich ein wenig mit dem Coregenerator zu befassen und ich denke ich bin mit den Funktionen die er mir liefert einigermaßen glücklich geworden. Finde es nur merkwürdig, dass ich kaum einer Verilog-Referenz Aufrufbeispiel um solche Funktionen zu generieren angegeben sind. Habe bis jetzt noch nichts sinnvolles gefunden, was mir die genaue Funktionsweise von den in core-gen erzeugten Funktionen PLL_ADV, BUFG usw. anzeigt. Aber wenn es nicht anders geht muss ich mich wohl damit beglücken... danke für die zahlreichen Antworten
Hallo, ich hab zur Zeit Probleme mit der Synthetisierung meiner per PLLs erzeugten Takte. Naja eigentlich scheitert das ganze erst beim "Translation"-Prozeß, die nach der Synthese bei der Implementierung folgt. Und zwar habe ich ja 3 PLLs nutzen müssen um alle 6 Takte zu erhalten die ich brauche. Habe aus einem Referenztakt von 200 MHz in der ersten PLL meine beiden Takte 27,808 und 6,952 MHz generiert. Und nun nutze ich die 27,808 MHz für PLL2 und PLL3 um damit meine anderen 4 Takte zu erzeugen. Die Modulaufrufe sehen dann ungefähr so aus (wobei ich ja die PLL-Module im Core Generator erzeugt habe): dvb_c_clk clock(.CLKIN1_N_IN(ref_clk_n), //200MHz Reference clock negativ .CLKIN1_P_IN(ref_clk_p), //200MHz Reference clock positiv .RST_IN(reset), .CLKOUT0_OUT(clk_up), //13.904MHz 2*baseband symbol clock .CLKOUT1_OUT(samp_clk)); //27.808MHz upsampled clock [verilog]dvb_c_clk_qam1632 clock2(.CLKIN1_IN(samp_clk), //27.808MHz reference clock from PLL1 .RST_IN(reset), .CLKOUT0_OUT(clk_si16), //3.476MHz clock for 16qam .CLKOUT1_OUT(clk_si32)); //4.345MHz clock for 32qam dvb_c_clk_qam64128 clock3(.CLKIN1_IN(samp_clk), //27.808MHz reference clock from PLL1 .RST_IN(reset), .CLKOUT0_OUT(clk_si64), //5.214MHz clock for 64qam .CLKOUT1_OUT(clk_si128)); //6.083MHz clock for 128qam[/verilog] Wenn ich eben versuche diese zu implementieren bekomme ich folgende Fehlermeldungen: ERROR:NgdBuild:770 - IBUFG 'clock2/CLKIN1_IBUFG_INST' and BUFG 'clock/CLKOUT1_BUFG_INST' on net 'clk_out_OBUF' are lined up in series. Buffers of the same direction cannot be placed in series. ERROR:NgdBuild:462 - input pad net 'clk_out_OBUF' drives multiple buffers: pin I on block clock2/CLKIN1_IBUFG_INST with type IBUFG, pin I on block clock3/CLKIN1_IBUFG_INST with type IBUFG, pin I on block clk_out_OBUF with type OBUF ERROR:NgdBuild:924 - input pad net 'clk_out_OBUF' is driving non-buffer primitives: pin O on block clock/CLKOUT1_BUFG_INST with type BUFG ERROR:NgdBuild:947 - input pad net 'clk_out_OBUF' is driving non-input buffer(s): pin O on block clock/CLKOUT1_BUFG_INST with type BUFG Mir gehen auch wirklich die Ideen langsam aus, habe nämlich entsprechend dem Datenblatt die PLL-Ausgänge als globale Buffer definiert und auch sonst eigentlich mich an den Regeln gehalten. Aber anscheinend scheitert es daran, dass ich den Ausgang der einen PLL als Eingang für die andere nutze - obwohl das laut Datenblatt legitim ist. Ich hoffe jemand kann mir noch einen Rat geben.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.