Hallo. Ich, VHDL-Beginner, versuche gerade den Ansatz für folgende Aufgabe zu finden: Aus einem Takt, z.b. 1MHz soll ein 1sec langer Takt generiert werden. So weit so gut, wie ich das mache ist mir eigentlich klar. Ich arbeite dafür mit Zählern. Die Frage die jedoch noch offen ist, wie kann ich das Einschaltverhältnis dieses Taktes verändern? Nehmen wir an, man will innerhalb von einer Sekunde 100ms ein und 900ms aus erzeugen. Wie könnte man dies realiseren, bzw. in Angriff nehmen? Fehlen euch noch Infos, dann gebt Bescheid. Habe wohl eine Denkblockade und hoffe Ihr könnt mir helfen. Schöne Grüße
Mal ein Beispiel mit wie man das über einen %-Duty Cycle Bereich lösen kann. Interessant ist hier vorallem das concurrent statement ganz am Ende. Das mit der Zeit über den Zähler bekommst sicher selbst hin. Achja : bitte den neuen Takt nur als enable nutzen und nicht direkt als Takt ;)
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
4 | |
5 | entity count is |
6 | generic( |
7 | constant length : natural := 100; |
8 | constant duty_cycle : natural := 10 -- hier 0 bis 100 % |
9 | |
10 | );
|
11 | Port( |
12 | clk : in std_logic; |
13 | clk2 : out std_logic); |
14 | end count; |
15 | |
16 | architecture Behavioral of count is |
17 | |
18 | |
19 | signal counter : integer range 1 to length; |
20 | |
21 | begin
|
22 | |
23 | process (clk) |
24 | begin
|
25 | if rising_edge(clk) then |
26 | if counter < length then |
27 | counter <= counter +1; |
28 | else
|
29 | counter <= 1 ; |
30 | end if; |
31 | end if; |
32 | end process; |
33 | |
34 | clk2 <= '1' when (counter*100) < (length *duty_cycle) else '0'; |
35 | |
36 | end Behavioral; |
Nein. Das Stichwort nennt sich : Zaehlen. Einen Zaehler fuer die Repetitionsrate. einen Zaehler fuer die Pulsbreite.
Hallo, sorry das ich mich erst jetzt wieder blicken lasse. Also ich muß sagen, das mir der Beispielcode vom Iulius sehr gut gefällt. Find ich sehr universell um ein Taktsignal zu erzeugen, ich kann ja den duty_cycle auch auf die hälfte setzen und erhalte so einen universellen Zähler, bzw Taktgenerator.(mit ein paar Anpassungen) Vielen Dank Was mir noch einfällt zu fragen: Was versteht man denn wirklich unter einem asynchronem reset? Ist es nur das taktunabhängige Rücksetzen der Speicherzellen? Asynchron bedeutet ja eigentlich das 2 Signale in ihren Änderungszeitpunkten nicht übereinstimmen und keine bekannte/konstante Zeitverschiebung aufweisen. Muß ich dazu beim Programmieren etwas spezielles beachten (bei asynchronem reset)? Ich frage doch in meiner architecture nur folgendes ab: ...begin... if reset = '0' Then oder if reset ='1' Then ... Also nur Abfrage auf high oder low aktiv, sonst doch nix - oder doch? Danke schon mal...
> Find ich sehr universell um ein Taktsignal zu erzeugen, ich kann ja den > duty_cycle auch auf die hälfte setzen und erhalte so einen universellen > Zähler, bzw Taktgenerator.(mit ein paar Anpassungen) Die Denkweise ist falsch. In einem FPGA-Design brauchst du keine 50% Takte, sondern hast (idealerweise) nur 1 Mastertakt. Alle anderen zeit- bzw. taktabhängigen Sachen werden mit Clock-Enable-Signalen gemacht, die nur 1 Mastertaktzyklus lang aktiv sind.
Hmm, da muß ich nochmal nachfragen. Nehmen wir an, ich habe einen bestimmten externen Takt (hardwareerzeugt), welchen ich innerhalb meines Systems benötige, jedoch in einer anderen Frequenz. Ich würde jetzt so vorgehen: Ich ändere mir in einem Process den externen Takt in das gewünschte innere Taktverhältnis(also 50% dutycycle). In einem zweiten (oder weiteren) Process(en) stelle ich mir aus dem externen Takt ein enable-Signal her, eben auch über das einstellbare Taktverhältnis. Für beide Processe würde ich doch nun den Code so verwenden können, wie es Iulius netterweise oben angab und so die verschieden benötigten "Takte" erzeugen. Klar das man bei dem enable-Signal dann nicht mehr von einem Takt spricht. Aber ansonsten kann ich das doch so machen, oder?
Hi, wenn du einen 'externen Takt' in deinem FPGA verwenden willst, dann tust du gut daran, den in deinen 'internen Takt' einzusynchronisieren. Also ueber ein paar FFs eintakten und sauber de-glitchen. Wenn das nicht geht (aus Timing-Gruenden), dann genau an dieser Stelle eben asynchron arbeiten und sich vorher genau ueberlegen, was da alles passieren kann! Und by the way, der Code oben hatten einen Multiplier mit Faktor *100 drin. Das kann dir eventuell die Synthese zu einem vorhandenen HW-Multiplier mappen, oder auch eine mehrfache Addition mit den Faktoren 64, 32 und 4 (alles als shift-left). Aber du solltest bei solchen Statements eben auch genau wissen, was daraus gemacht wird/werden soll. Das haengt dann sehr schnell von deiner verwendeten Zielplattform ab...
Welche Synthese soll dafür bitte einen Multiplier nutzen ? Für den Vergleich sind gerade mal 2 schlappe Lookuptables nötig, mit exakt so viel Eingängen wie man Zählerbits hat. Siehe Bild. >> wenn du einen 'externen Takt' in deinem FPGA verwenden willst, dann tust >> du gut daran, den in deinen 'internen Takt' einzusynchronisieren Ich weiß wie diese Aussage gemeint ist, aber so ist das zu allgemein. Auch ein Clock von einem Oszi ist ein externer Takt und den synchronisiert man hoffentlich nicht ein. >> Aber ansonsten kann ich das doch so machen, oder? Nein, da hat Lothar schon Recht. Intern wirst du praktisch nie ein 10% oder 50% verhältnis brauchen, sondern wenn dann toggelndes verhalten, also 'high' alle paar clockzyklen. Es kann zwar auch vorkommen, etwa wenn du bestimmte Funktionionen nur für z.b. 10% der Gesamtzeit laufen lassen willst, aber das ist extrem selten und für den Anfang meist unnötig und verwirrend. Wenn du intern einen niedrigen Takt benötigst, dann : - nimmst du z.b. eine PLL und setzt gleich den Takt runter (lohnt nur wenn große Teile/gesamte Chip damit betrieben werden) oder - gehst über einen Zähler der EINMAL(z.b. beim Überlauf) eine Eins ausspuckt die du dann als enable nutzt.
Hi, wenn ich das über einen Zähler realisiere und beim Überlauf eine 1 ausgebe, bleibt dann das Problem der Beeinflussung der Länge des enable-Signales doch aber bestehen. Wie lang liegt nach einem steigenden Flanke das enable-Signal auf High, bevor es wieder auf Low zurückkehrt? Mein derzeitiger Wissensstand sagt mir doch ,dass ich keine "wait for 100 ms" in synthetisierbare Prozesse einbinden kann. Also müsste ich, um es mit einem Zähler zu realisieren, doch den Zähler über die gesamte Periodendauer des enablesignals (Highzeit+Lowzeit) laufen lassen. So kann ich dann sagen bei Zählerstand 399 --> High und bei Zählerstand 699 --> Low, um den Zähler bei 999 letztlich zu reseten. (Alles Beispielwerte) Hoffe das ich das so richtig verstehe... Danke für die Unterstützung
Deine Denkweise ist entweder falsch oder wir reden aneinander vorbei... >> beim Überlauf eine 1 >> ausgebe, bleibt dann das Problem der Beeinflussung der Länge des >> enable-Signales das enable signal benötigt keine länge, es ist immer genau EINEN takt lang aktiv. bsp : 32mhz und zähler bis 32. alle 1µs wird ein enable erzeugt. Zusammen mit dem 32mhz clock und dem enable vom zähler ergibt das z.b. ein Flipflop das höchstens mit 1 mhz "schaltet". was du vorhast ist a) entweder ein gated clock den es zu vermeiden gilt : http://www.mikrocontroller.net/articles/Taktung_FPGA/CPLD b) eine PWM die z.b. nach der Methode in meinem ersten Post funktioniert. In jedem Fall kann ich mir nur schwer vorstellen warum man ein enable für mehrere aufeinander folgende Takte benutzen will, was Möglichkeit c) wäre. Das wäre dann eine Schaltung die z.b. 10% der Zeit full-speed läuft und 90% der zeit garnicht und ich halte es für unwarscheinlich das du sowas suchst.
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.