Hallo zusammen, meine Frage als FPGA-Neuling: Für den Betrieb eines FPGA benötigt man einen Quarz zur Taktgenerierung. Bei vielen VHDL-Modellen (z.B. Beschreibung eines RAM-Controllers) benötigt man nun ein Clock-Signal. Woher bekommt das CLK-Signal. Generiert man es mittels einer VHDL-Beschreibung eines Clockgenerators oder greift man auf den physikalischen Takt des Quarzes zurück (falls dies der Fall sein sollte, wie realisiert man dies). Falls man ein VHDL-Clockgenerators benutzt, kennt einer einen Code dafür bzw. einen Link ? Wie kann man sich das alles vorstellen. Danke
Praktisch wird ja am FPGA ein Clock anliegen. Für die Simulation des VHDL-Codes nimmst Du ein VHDL-Modell, das z.B. genau dieselbe Taktfrequenz wie Dein "echter" Quarzoszillator generiert. VHDL-Code für 10 MHz-Oszillator : GEN_CLK : process begin while true loop clk <= '0'; wait for 50 ns; clk <= '1'; wait for 50 ns; end loop; end process; Den Code platzierst Du in einer Testbench, z.B. tb.vhd Darin wird Dein FPGA-Component instanziiert plus evt. ein Stimuli-Component oder Du schreibst die Erzeugung der Stimulis direkt ins File tb.vhd. Hoffe das hilft weiter.
OK, für die Simulation habe es verstanden. Aber wie sieht es in meiner realen Schaltung aus. Nehmen wir an ich benötige für irgendein SRAM einen Takt von 20 MHz (nur Annahme) und mein FPGA wird von außen mit einem 40 Mhz-Oszillator betrieben. Wie komme ich zu meinem Takt von 20Mhz ? Kann ich dann in einem VHDL-Code auf irgendeinen Pin zugreifen, an dem die 40Mhz-Oszillator anliegen, und mir mittels eines Frequenzteilers dann den benötigten Takt bauen ? Sorry, bestimmt ist die Vorstellung komplett falsch, aber ich bin Anfänger ;-) HILFE....(Danke)
ne mann teilt den tackt im code durch tacktteiler. ist schon richtig was du gesagt hast. zb: if rising_edge(clk) then clk_halb <= not clk_halb; end if; das wäre der takteiler. ein einfacher t-flipflop bin auch anfänger. hab aber schon einiges programmiert. momentan experementiere ich mit diesem modelsim herum um meine funkuhr zu testen. mfg
korrekt, also ein externer Takt, der z.B. an Pin 1 anliegt kann durch einen Teiler wie im obigen Bsp. heruntergeteilt werden. Man muß hier nur aufpassen, wenn man nachher beide Takte verwenden will (wie im Beispiel 40MHz /20MHz). Diese beiden Takte sind dann nicht mehr synchron! Eine sichere Variante ist z.B. den heruntergeteilten Takt nur als Clock-Enable Signal zu verwenden und trotzdem alle Register mit dem schnellen Takt (z.B. 40MHz) zu takten: process(clk) begin if rising_edge(clk) then -- Taktteiler / 2 half_clk_q <= not half_clk_q; -- Typ boolean if half_clk_q then -- glob. Enable für gesamte folgende Logik case SRAM_STATE is when IDLE => ... end if; end if; end process; In den Timing-Constraints kann man nun die Laufzeit Register-Register für alle FFs, die das "langsame" Enable-Signal haben verdoppeln, da sich ihre Ausgänge ja nur noch mit der halben Frequenz ändern können. Falls vorhanden, kann auch eine DLL oder PLL im FPGA verwendet werden. Da speist man einfach den externen Takt ein, legt in den Eigenschaften der PLL/DLL die Multiplikatoren/Teiler fest und erhält am Ausgang die neue Taktfrequenz. Vorteil: alle Takte am Ausgang der PLL sind synchron. Um keine Probleme durch asynchrone Takte zu bekommen, die vielleicht auch nur Temperatur-abhängig auftreten und schwer zu finden sind, würde ich empfehlen, mit so wenig Takten wie möglich zu arbeiten, wenns geht nur 1 Takt und evt. dazu Clock-Enable-Signale verwenden.
aha den weiß ich ja auch gleich mehr. ich habe jetzt mehrer zähler.(soll ne uhr werden) die bekommen alle jeweils von der vorgängerstufe ihren tackt. also wäre es jetzt besser wenn ich das mit clock enable mache. na den schreib ich mal um. danach muss ich erst mal die simulation schreiben. danke. mfg
so hab den ganzen code umgeschrieben. jetzt kommen aber diese beiden fehlermeldungen ------------- WARNING:Xst:1988 - Unit <dcf_uhr>: instances <Mcompar__n0640>, <Mcompar__n0370> of unit <LPM_COMPARE_5> and unit <LPM_COMPARE_4> are dual, second instance is removed WARNING:Xst:1988 - Unit <dcf_uhr>: instances <Mcompar__n0369>, <Mcompar__n0189> of unit <LPM_COMPARE_3> and unit <LPM_COMPARE_2> are dual, second instance is removed ------------- kannst du damit was anfangen? weil da steht ja keine zeile oder wie das signal oder die variable heißt. noch was anderes: jetzt ist die maximum frequenz von 80mhz auf 20 gefallen. muss ich da jetzt noch was in die ucf datei schreiben, von wegen welche sigale schnell sein müssen oder so. mfg
mal noch was anderes. mir ist grad aufgefallen das er aus meinen zählern jetzt addierer und subtrahierer gemacht hat. ist das normal?? oder fehlt mir ne libary. hab momentan diese drinne: use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.STD_LOGIC_SIGNED.ALL; mfg
mir ist grad mal durch probieren aufgefallen, das wenn ich mit einer variable einen zähler machen will, wird daraus ein adierer aber mit einem signal bleibt es ein zähler. kann mir das einer erklären????
@FPGA-User... ich habe noch ein paar Fragen zu deinem Beitrag: Kannst du mir das mit den Clock Enable genauer erklären ? Ich brauche doch ein vollständiges Clock-Signal, z.B. um ein SRAM anzusteuern. Hast du noch einen anderen Beispiel-Code, in dem das ersichtlicher wird. (z.B. mit externer Clock-Pin-Zuweisung, Pll und/oder Clock_Enable). Nett wäre auch ein Beispiel von so einer PLL-Realisierung in VHDL ? Hast du so etwas ? So ganz nebenbei was ist ein DLL ? Außerdem könntest du mir das mit den Timing-Constraints und den Laufzeit Registern noch erklären. Habe da null Peilung...(wäre echt nett). Kann man einen externen Takt (z.B. von einem Oszillator) an einen beliebigen Input-Pin des FPGAs legen ? Ich habe in Datenblättern gesehen, dass der FPGA einen speziellen Takt-Eingang hat, ähnlich dem eines Microcontrollers. Kann ich also sagen, ich kann in meinem VHDL-Code sagen: clk <= P1 ??? (kann ich mir gar nicht vorstellen, aber vielleicht...) ? Braucht es dazu noch andere Einstellungen (z.B. in den Constraint-Dateien, in denen glaub ich die Pin-Zuweisungen gemacht werden) oder muss man den entspr. Pin speziell als Takt-Pin definieren ??? Sorry, für meine (dummen) Fragen.... @jonny.... ich würde einfach einen eigenen Beitrag im Forum erstellen. Da bekommst du schneller geholfen ;-)
naja habsch gedacht da fpgh-user ja anscheinend viel weiß kann mann ihn gleich auch noch fragen, da gleiches thema. externer tackt: ich habe meine cpld´s die ich programmiert habe über einen oszilator verbunden. angeschlossen werd der tackt an den gclk pins. das sind globale clock pins die im ganzen cpld, fpgh verfügbar sind. kann schnell drauf zugegriffen werden. tackt: sein beispiel ist doch ganz ok. --------------- process(clk) begin if rising_edge(clk) then -- Taktteiler / 2 half_clk_q <= not half_clk_q; -- Typ boolean ----------------------- als erstes erstellste das enable signal. ds ist hier ein einfacher tackteiler. bei jeder zweiten tacktflanke von clk ist half_clk_q true. ----------------------- if half_clk_q then -- glob. Enable für gesamte folgende Logik ======================= das enable signal fragst du dann einfach noch mal ab. wenn half_clk_q jetzt true ist und steigende flanke von clk, dann kann/können die logic/flipflop´s die dahinter geschaltet sind was machen. das ist ja bloß jede 2te flanke von clk. case SRAM_STATE is when IDLE => ... end if; end if; end process; ---------------- _ _ _ _ ____| |_| |_| |_| |_| |_| |_ <-- clk __ ___ __ ____| |___| |___| |___ <-- half_clk_q | | | 2ter tacktimpuls half_clk_q wird low 1ter tackimpuls half_clk_q wird high | | | hier bekommt die darauf folgende logic ihren tacktimpuls. durch die low high flanke von clk und dem noch high sein von half_clk_q hast du einen kurzen impuls für die darunter ligende logic. das mit dem timing hab ich auch noch nicht verstanden, habe es aber schon in einer ucf datei gesehen. mfg
also die obige Erklärung mit graf. Darstellung von Johnny ist schon super - das dürfte ja jetzt klar sein. Anstelle half_clk_q kann man natürlich auch ein Counter-Signal nehmen mit CLK-Frequenz/10 o.ä. Eine DLL ist übrigens eine Delay-Locked-Loop, darunter kann man sich eine digital einstellbare Verzögerungsleitung vorstellen. Gibts in einigen XILINX-FPGA-Typen, wird zur Taktaufbereitung verwendet. Völlig anderes Prinzip als PLL, aber am Ende bekommt man seine Takte phasenstabil zu einem Input-Takt, mit veränderter Frequenz, wenn man will größer oder kleiner, so wie bei einer PLL auch. Hier mal ein Beispiel für eine PLL im FPGA. Bei ALTERA benutzt man zum generieren den sog. "Mega Wizard Plugin Manager", den man von der graf. Oberfl. aufruft, dort wird werden Name und Parameter eingegeben, am Ende spuckt das Teil ein paar Files aus. Im VHDL wird dann zuerst ein component deklariert, (steht in einem von den generierten Files) z.B.: component pll1 PORT ( inclock : IN STD_LOGIC; clock0 : OUT STD_LOGIC; clock1 : OUT STD_LOGIC ); end component; und in der architecture dann instanziiert : architecture blabla of example is begin ... pll1_inst : pll1 port map ( inclock => clk, clock0 => clk_0, clock1 => clk_2x ); .. end; in dem Beispiel waren die Parameter so eingestellt, dass inclock der globale 33 MHz-Takt des FPGAs ist (an einem globalen Clock-Pin, der eine PLL treiben kann), clk_0 ist ein Ausgang mit 33 MHz und clk_2x hat 66 MHz. Ich nutze im Design clk_0 und clk_2x. Da beide Takte synchron sind, muss ich mir bei der Übergabe von Daten ziwschen Registern, die mit 33 und 66 MHz getaktet sind nur wenig Gedanken machen (vorausgesetzt ich arbeite immer mit rising_edge(clk) : FF 33 MHz -> FF 66 MHz : Laufzeit muss <= 15 ns sein FF 66 MHz -> FF 33 MHz : Laufzeit muss <= 15 ns sein Das sollte die Software aber schon selbst erkennen und evt. Timing-Probleme melden. Dafür muss man m.E. keine Constraints mehr setzen. Zu Timing-Constraints und UCF-File später was.
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.