Hallo zusammen, ich bin neu in der FPGA/VHDL-Welt (und entsetzt, wie viel Wissen und Verständnis sich in einem Berg aus "Informationen" verbigt). Nach ersten kleineren Programmiererfolgen wollte ich nun die Clock-Erzeugung meines Spartan 6 MicroBoard (LX9 - Package CSG324) in Betrieb nehmen und habe dafür den Clock Wizard der XILINX-ISE zu Hilfe genommen. Nach meinem Verständnis erzeugt dieser Wizard vorgefertigten VHDL-Code, den man dann Verwenden kann. Nur das I/O-Panning muss noch manuell vorgenommen werden. Geplant war meinerseits die Instanz einer PLL zu verwenden/erzeugen, um einfach mal einen beliebige Clock aus meinem Eingangs-Takt 100 MHz zu erzeugen und auszugeben. Später möchte ich so in verschiedenen entitys unterschiedliche Taktraten erzeugen können. 1. Frage: Ist dieses Vorgehen korrekt? Leider erhalte ich nach dem Pin-Planning (durch PlanAhead unterstützt) im "Implement Design"-Prozess immer folgende drei Fehlermeldungen (genauer Wortlaut ganz unten):Place 1205, Place 1136, Pack 1654 Was nützt ein Wizard, wenn er Code ausspuckt, der nicht funktioniert? ^^ ... daher meine 2. Frage : Ist dies vielleicht ein bekannter oder leicht zu behebender Fehler? Was machte ich faksch oder sollte ich anders machen? Falls für die Beantwortung weitere Informationen nötig sein sollten reiche ich diese natürlich sofort nach. In jedem Fall wäre ich für eine hilfreiche Antwort sehr dankbar! Fehlercode: _________________________________________________________ ERROR:Place:1205 - This design contains a global buffer instance, <clkout1_buf>, driving the net, <CLK_OUT1_OBUF>, that is driving the following (first 30) non-clock load pins off chip. < PIN: CLK_OUT1.O; > This design practice, in Spartan-6, can lead to an unroutable situation due to limitations in the global routing. If the design does route there may be excessive delay or skew on this net. It is recommended to use a Clock Forwarding technique to create a reliable and repeatable low skew solution: instantiate an ODDR2 component; tie the .D0 pin to Logic1; tie the .D1 pin to Logic0; tie the clock net to be forwarded to .C0; tie the inverted clock to .C1. If you wish to override this recommendation, you may use the CLOCK_DEDICATED_ROUTE constraint (given below) in the .ucf file to demote this message to a WARNING and allow your design to continue. Although the net may still not route, you will be able to analyze the failure in FPGA_Editor. < PIN "clkout1_buf.O" CLOCK_DEDICATED_ROUTE = FALSE; > ERROR:Place:1136 - This design contains a global buffer instance, <clkout1_buf>, driving the net, <CLK_OUT1_OBUF>, that is driving the following (first 30) non-clock load pins. < PIN: CLK_OUT1.O; > This is not a recommended design practice in Spartan-6 due to limitations in the global routing that may cause excessive delay, skew or unroutable situations. It is recommended to only use a BUFG resource to drive clock loads. If you wish to override this recommendation, you may use the CLOCK_DEDICATED_ROUTE constraint (given below) in the .ucf file to demote this message to a WARNING and allow your design to continue. < PIN "clkout1_buf.O" CLOCK_DEDICATED_ROUTE = FALSE; > ERROR:Pack:1654 - The timing-driven placement phase encountered an error.
Nee, ganz so einfach ist das nicht. Der Spartan 6 hat ziemlich begrenzte Clocking Ressourcen, beliebig viele PLLs gehen nicht, da die auch physisch auf dem Chip vorhanden sein müssen. Auch gehen nicht alle Teiler und Vervielfacher einzustellen. Schau dir mal den Clocking User Guide an, das ist zwar ziemlich viel für einen Anfänger, aber gerade beim Clocking muss man echt wissen, wie der FPGA da arbeitet. Ganz abgesehen davon, steht ja auch da, was das Problem ist: Du gehst mit dem Takt auf ein Nicht-Takt-Netz (dein Ausgang) und das klappt nicht bei Xilinx. Und es steht sogar was du machen sollst: Ein ODDR FlipFlop instanziieren, das den Takt an einen Ausgang des FPGA weiterleitet.
:
Bearbeitet durch User
Vielen Dank für diese schnelle Antwort! Die begrenzte Clocking Ressourcen machen mir erst mal keine Sorgen, solange ich überhaupt mal Clock-Signale erzeugen und ausgeben kann. Was ich bisher weiter verstanden habe (oder glaube verstanden zu haben) ist, dass es ein FPGA-interntes Clock-Signal-Netz gibt, auf das die PLL sein Ausgangssignal gibt. Von diesem internen Netz komme ich nicht so ohne weiteres auf einen IO-Pin. Frage 1 dazu: Könnte ich das interne Clock-Netzwerk-Signal zu einer weiteren entity leiten und dort nutzen oder von dort an einen IO-Pin ausgeben? Frage 2: Wie lege ich einen ODDR-FlipFlop an, um das Signal direkt auszugeben (und was tut diese FlipFlop)? Seite 224 von http://www.xilinx.com/support/documentation/sw_manuals/xilinx13_4/spartan6_hdl.pdf gibt zwar ein generelles Template an, doch wie kann ich dieses auf meine konkrete Situation anpassen? Verstehen und Ändern fällt mir hoffentlich leichter, wenn überhaupt mal irgendwas klappt. Ich wäre daher über einen Lösungsansatz sehr dankbar! p.s.: Der Clock Wizard hat das Ausgangssignal wie folgend formuliert: -- Output buffering ------------------------------------- clkf_buf : BUFG port map (O => clkfb, I => clk2x); clkout1_buf : BUFG port map (O => clk_out1_internal, I => clk2x); CLK_OUT1 <= clk_out1_internal;
engineer_on_tour schrieb: > Was ich bisher weiter verstanden habe (oder glaube verstanden zu haben) > ist, dass es ein FPGA-interntes Clock-Signal-Netz gibt, auf das die PLL > sein Ausgangssignal gibt. Von diesem internen Netz komme ich nicht so > ohne weiteres auf einen IO-Pin. Korrekt. Dein FPGA-internes Clock-Signal liegt auf 'speziellen' Draehtchen im FPGA. Die gehen erstmal nur zu den einzelnen Logikelementen, nicht nach draussen... > > Frage 1 dazu: Könnte ich das interne Clock-Netzwerk-Signal zu einer > weiteren entity leiten und dort nutzen oder von dort an einen IO-Pin > ausgeben? Erster Teil vor dem ODER: Ja! Genau dazu ist das Clock-Netzwerk da! Dieser Takt ist fuer jedes Logikelement, bestehend aus Look-Up-Table und FFs verfuegbar. Nach deinem ODER: Den Takt auf einen Ausgangspin zu geben, das ist wieder etwas spezielles. Da muessen dann auch die Draehte auf dem Chip vorhanden sein... > > Frage 2: Wie lege ich einen ODDR-FlipFlop an, um das Signal direkt > auszugeben (und was tut diese FlipFlop)? Seite 224 von > http://www.xilinx.com/support/documentation/sw_manuals/xilinx13_4/spartan6_hdl.pdf > gibt zwar ein generelles Template an, doch wie kann ich dieses auf meine > konkrete Situation anpassen? So ein ODDR nimmt dein Signal (evtl. einen Takt, falls die Routing-Resourcen das erlauben) und gibt es am Pin einfach aus... Probier doch einfach mal 'Logik'! Du nimmst deinen internen Takt (siehe Punkt 1), machst damit etwas (im einfachsten Fall einen Zaehler oder sowas), und gibst ein Bit deines Zaehlers aus. Also nicht das Taktnetz, sondern ein daraus abgeleitetes Signal aus einem Logikflipflop... Dann sollte das Verhalten eines FPGA klar werden...
super! .... dann probier ich das (morgen früh leider erst) mal aus ... mal sehen, wie ich an den "internen Takt" der PLL ran komme. Bisher habe ich einfach die außen anliegende Clock als Eingangssignal einer entity genutzt, runter geteilt und konnte was machen (z.B. LED toggeln). Mal sehen, wie ich an das Signal des internen Clock-Netzwerks ran komme und wie/ob ich die PLL-Instanz dazu noch umbauen muss (bisher weiß ich noch nicht sooo genau, was der Wizard da für Code ausgespuckt hat bzw. wo das Signal hin geht und wie ich da wieder in ner anderen entity ran komme)
Das ist eigentlich recht einfach. Wenn du von einem externen Eingang am FPGA auf das Taktnetz willst, musst du einen IBUFG nehmen. Erzeugst du die PLL mit dem CoreGenerator, wird das automatisch gemacht. Nach der PLL muss jedes Taktsignal erst durch einen BUFG um auf das Taktnetzwerk zu kommen. Diesen Takt (nach dem BUFG) kannst du dann Chip-weit verwenden, um FlipFlops, BlockRAMs usw. zu takten. Also am CLK Eingang der FlipFlops anschließeb bzw. mit rising_edge() beschreiben. as geht natürlich auch in alle Module (entities) rein. Willst du das Clock Signal aber mal direkt und ohne herunterteilen ausgeben, dann geht das sinnvoll nur über ein ODDR Register ausgeben, wie das angeschlossen wird, steht ja sogar in der MAP Fehlermeldung oben.
klingt einfach ... mal sehen wie das in der Praxis aussieht ... mein Versuch VHDL "mal eben" an einem Tag zu lernen ist jedenfalls mindestens auf den zweiten Tag verlängert ;) ODDR oder BUFG sind nach meinem jetzigen Verständnis Funktionen aus der XILINX-Library und nichts, was man selber schreiben muss. Satt dessen werden diese Komponenten innerhalb einer entity instanziiert (ähnlich des PLL-Codes), richtig?
Ja, das sind Hardware-Elemente auf dem FPGA, die durch das Instanziieren verdrahtet werden. Du wirst noch sehr sehr viel mehr Tage benötigen für VHDL :)
engineer_on_tour schrieb: > > ODDR oder BUFG sind nach meinem jetzigen Verständnis Funktionen aus der > XILINX-Library und nichts, was man selber schreiben muss. Satt dessen > werden diese Komponenten innerhalb einer entity instanziiert (ähnlich > des PLL-Codes), richtig? ODDR: ja muss instanziiert werden BUFG: nicht ganz, bei Verwendung von Komponenten wie der PLL o.ä ja. Bei getaktete Prozessen in synthesefähigem Code macht das die FPGA-synthese-tool chain meist selbst. Wenn z.B. hier der CLK pin über einen FPGA-Pin ohne PLL zu so einem Prozess käme: [vhdl] name:process(CLK) -- Select input address begin if(rising_edge(CLK)) then reg <= red2 oder sonstewas usw [\vhdl]
Hallo zusammen, ich bin heute sehr gut weiter gekommen und habe durch ein gutes pdf (http://astro.uni-tuebingen.de/groups/electronics/VHDL.pdf) nun auch etwas besser verstanden, wie man ein (zumindest etwas) komplexeres VHDL-Projekt aufzieht. Vielen Dank an dieser Stelle noch mal für eure guten Tipps und Erklärungen! Ich bin jetzt soweit, dass ich eine componente habe, entity cCLOCK_PLL is port( CLK : in std_logic; CLK_PLL : out std_logic ); end cCLOCK_PLL; an der ein Clock-Signal von außen anliegt. Dieses wird innerhalb der componente in einer instanzierten PLL genutzt. Das Ausgangssignal der componente ist (bzw. soll sein) ein FPGA-internes Clock-Signal "CLK_PLL_SIG", dass zu anderen components weiter geleitet wird. Das Ausgangssignal "CLK_PLL : out std_logic" wird nur innerhalb der Schaltung über das interne Signal "signal CLK_PLL_SIG : std_logic;" mit der Zuweisung "CLK_PLL => CLK_PLL_SIG" genutzt. Christian R. Schrieb: "Diesen Takt (nach dem BUFG) kannst du dann Chip-weit verwenden". Das war mein Ziel. Die Fehler treten jedoch immer noch auf und sind nur durch ein ODDR2-Register (habe noch nicht geschafft, dieses in Betrieb zu nehmen, da ich gehofft hatte, dies umgehen zu können) zu vermeiden. clkout1_buf : BUFG port map (O => CLK_PLL, -- verursacht den Fehler!!! I => clkout0); Muss ich in jedem Fall ein ODDR2-Regiter instanzieren oder funktioniert die FPGA-interne Verbreitung der durch die PLL erzeugten Signals doch noch mal anders?
Ich habe noch drei kurze, sich daran anschließende Fragen zu ODDR2(falls es keine andere und elegante(re) Methode gibt, dass PLL-Signal FPGA-intern zu verwenden/verbreiten): Meine Konfiguration des ODDR" sieht so aus: Q => CLK_PLL, -- 1-bit output data C0 => clkout0, -- 1-bit clock input C1 => (not clkout0), -- 1-bit clock input CE => '1', -- 1-bit clock enable input D0 => '0', -- 1-bit data input (associated with C0) D1 => '1', -- 1-bit data input (associated with C1) R => '0', -- 1-bit reset input S => '0' -- 1-bit set input 1. Benötige ich den BUFG noch, wenn ich ein ODDR2 nutze? 2. Das invertierte Clocksignal an C1 des ODDR2 wollte ich so generieren: C1 => (not clkout0) Dann kommt folgende Warnung: WARNING:HDLCompiler:946 - "C:\Users\uidg3368\Test7\clock-Komponente.vhd" Line 112: Actual for formal port c1 is neither a static name nor a globally static expression Muss ich wirklich ein extra Signal einführen, dieses invertieren und kann dieses dann erst auf C1 geben? (notclkout0 <= not clkout0;) 3. Den Code bekomme ich synthetisiert, doch dann erscheint folgender Error und ich komme nicht weiter: ERROR:Pack:2531 - The dual data rate register "ClockGeneration/ODDR2_inst" failed to join the "OLOGIC2" component as required. The output signal for register symbol ClockGeneration/ODDR2_inst requires general routing to fabric, but the register can only be routed to ILOGIC, IODELAY, and IOB. Habt ihr ne Idee, was da los ist?
Das ODDR ist nur für extern. Intern brauchst und darfst du das natürlich nicht. Wenn du die PLL mit dem Core Generator erzeugt hast, kannst du dort gleich einstellen, dass der BUFG reingebaut wird, dann darfst du keinen zweiten mehr dran machen.
DAS war der entscheidende Hinweiß :D ich hab den BUFG raus geschmissen und es geht ... ich kann das Signal jetzt intern weiter verwenden :D Bei Zeiten werd ich "PLL -> BUFG -> ODDR2 -> Direkt raus" auch noch mal testen .... aber da ich nur interne Signale brauche reicht mir diese Lösung erst mal. VIELEN Dank!
Hallo zusammen, ich hab eine sich hierran anschließende Frage: Wenn ich statt der PLL die vom ClockWizard generierte DCM_SP-Instanz verwenden möchte (immer noch nur intern!) treten wieder Place:1205,1136 und Pack:1654-Error-Meldungen auf. Welche Buffer sind bei der internen DCM-Verwendung notwenig, die für die PLL nicht benötigt werden?
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.