Forum: FPGA, VHDL & Co. Wie Takt in VHDL umschalten?


von Sebastian (Gast)


Lesenswert?

Hi,

ich würde gern den Takt für einen Prozess umschalten. Es dreht sich
dabei um einen BCD-Zähler der mit 1Hz rückwärts laufen soll (Timer).
Den würde ich aber auch gern per Tastendruck hochzählen lassen, und das
nicht nur mit 1Hz sondern mit höheren Takt.
Als Anfänger (bin ich) würde man die zwei Taktsignale ja einfach mit
ein paar Gattern und dem Taster verknüpfen, was aber laut einiger
Tutorials nicht so "schön" sei. Deshalb wollte ich mal nachfragen wie
ihr sowas handhabt?

Gruß,
Sebastian

von T.M. (Gast)


Lesenswert?

In einigen FPGAs gibt es sogenannte BUFGMUX, die haben 2 Clockeingänge,
zwischen denen man umschalten kann. Sie müssen mit einem Template
instanziiert werden, musst du mal nachschauen, ob es sowas in deinem
FPGA gibt (User Guide)


T.M.

von chris (Gast)


Lesenswert?

das gibts glaube ich auch als ip.
nutze also den Core generator falls  du mit der xilink ise arbeitest.
Stichwort DCM =Digial Clock Manager
  Chris

von Sebastian (Gast)


Lesenswert?

ich habe zwar ein Spartan 3 Starterkit, aber wollte die Hardware
eigentlich in einem CPLD (XC9572XL) unterbringen. Das soll eine kleine
Zeitschaltuhr mit Minuten und Sekunden werden. Ich dachte mir das ich
diesmal keinen AVR verwende um etwas VHDL zu üben.
Einbauen wollte ich:
- 3x 7-Segmentanzeigen
- 3x Taster (Reset, Set, Start)
- 1x 32.768kHz Quarz

Gibt es da nicht noch andere Lösungen? Ich weiß ja nicht ob was
vernünftiges dabei raus kommt, wenn ich den Zähler mit dem schnelleren
Takt betreibe und vor das ENABLE-Signal eine zusätzliche Logik hänge.
Die könnte dann abhängig vom Tastersignal (entprellt) den 1Hz Takt
zuführen und gleichzeitig das UP_DOWN-Signal betätigen.

Gruß,
Sebastian

von Sven Johannes (Gast)


Lesenswert?

Moin...

das enable Signal zu schalten ist (eigentlich) der einzige richtige
Weg. Takte sind in den FPGA immer eine eigene Welt und sollten
tunlichst nicht mit Logik vermischt werden. Das Timing ist danach sogut
wie erledigt.

--
 SJ

von Sebastian (Gast)


Lesenswert?

wie "klug" ist es, wenn ich den BCD-Zähler so gestalte das er ladbar
ist. Dann könnte ich eine Variable in einem seperaten Prozess
hochzählen lassen und beim Loslassen des Tasters den BCD-Zähler mit dem
neuen Wert laden. Braucht halt mehr FFs und evtl. wäre nicht mehr alles
synchron.

Sebastian

von schlumpf (Gast)


Lesenswert?

Arbeite nur mit deinem Systemtakt!!!
Die FFs des Zählers sollten alle mit dem Systemtakt arbeiten.
Für die langsameren Zeitbasen (hoch und abwärstzählen) beschreibst du
dir Frequenzeiteiler. Die Ausgangssignale dieser führst du kombiniert
mit der Tasterstellung auf deinen Zähler. Allerdings nicht als Takt,
sondern als Enable für das hoch- oder runterzählen.. Dann biste perfekt
synchron und hast keine Probleme.

prinzip:
if SysCLK'event and SysCLK = '1' then
  if Taste = 1 and DivCLK1 = 1 then count <= count - 1
  elsif Taste = 0 and DivCLK2 = 1 then count <= count + 1
  else count <= count;
  end if;
end if;

PS: Code ist so natürlich syntaktisch nicht richtig!

von schlumpf (Gast)


Lesenswert?

Nur zur Info, fall es dich interessiert:

Ich beschreibe synchrone Desings immer in 2 Prozessen. Ein Prozess
beschreibt nur die Register. Dafür spendiere ich pro register zwei
Signale, wobei eines den Eingang und das andere den Ausgang beschreibt.
(Registername_in, Registername_q)
Dann beschreibe ich in dem einen Prozess nur das Verhalten aller
Register, sowohl beim Flankenübergang von CLK als auch beim Reset.
Hier werden nur die Ausgänge der Register beschrieben!

if reset = '0' then
  register1_q <= '0';
  register2_q <= '0';
elsif clk'event and clk = '1' then
  register1_q <= register1_in;
  register2_q <= register2_in;
end if;

im anderen Prozess wird die Kombinatorik beschriben, die auf die
Eingänge der Register wirkt. Hier gibt es keine verknüpfungen mit dem
Systemtakt mehr (nix clk'event)

z.B.
register1_in <= A and B;
...

Vorteil: du musst dir keine Gedanken mehr über synchronität machen, da
es autoamtisch synchron wird. Und das ganze bleibt schön
übersichtlich.
Man kann sich darüber streiten, da es ein bisschen mehr code ist, aber
gerade bei größeren Projekten bin ich bis jetzt immer sehr gut damit
gefahren.

von Sebastian (Gast)


Lesenswert?

@all

Danke für die Antworten!


@schlumpf

deine Beschreibung schaut, soweit ich das beurteilen kann, nach einer
brauchbaren Lösung aus. Ich muß das aber erstmal sacken lassen, bevor
ich deine Anregungen sinnvoll einsetzen kann.
Ich verwende ein eigenes Modul, welches mir 1Hz und 128Hz aus den
32,768kHz erzeugt. Soll ich dann die 128Hz oder die 32,768kHz als
Systemtakt nehmen? Die 128Hz wollte ich für das Multiplexen der
Anzeigen und das Entprellen der Taster verwenden. Bei der Frequenz wäre
es auch möglich noch ein paar Anzeigen dazu zu nehmen (z.B. bei einer
Uhr: HH:MM:SS).


Sebastian

von Jürgen Schuhmacher (Gast)


Lesenswert?

Du nimmst indirekt den Eingangstakt des FPGA als Systemtakt, also einige
MHZ. Die erzeugst Du aus den 32 über ein PLL. Die Untertakte würde ich
als enables formulieren. Ein MUX schaltet dies enables um, und dein
Zähler sieht nur eines davon.

von Sebastian (Gast)


Lesenswert?

Also ungefähr so:
1
signal MUX :    bit_vector(1 downto 0);
2
signal ENABLE : bit;
3
4
MUX <= TASTE & RUN;
5
6
case MUX is
7
  when "01"   => ENABLE <= CLK_1HZ;
8
  when "10"   => ENABLE <= CLK_128HZ;
9
  when others => ENABLE <= "0";
10
end case;
11
12
process (SysCLK)
13
begin
14
  if (SysCLK = '1' and SysCLK'event) then
15
    if (TASTE = '1' and ENABLE = '1') then
16
      count <= count - 1;
17
    elsif (TASTE = '0' and ENABLE = '1') then
18
      count <= count + 1;
19
    else
20
      count <= count;
21
    end if;
22
  end if;
23
end process;

oder?
Sehe ich das richtig, dass der Zähler jetzt nicht mit einem 1Hz
hochzählt? Wenn ja, wie bekomme ich das in den Griff?
PLL hab ich leider nicht zur Verfügung, will ja die Schaltung in nen
kleinen CPLD unterbringen.

Sebastian

von schlumpf (Gast)


Lesenswert?

Nimm doch deine 32 kHz als Systemtakt.
Der systemtakt bestimmt ja nur, wie oft du deine Abfrage durchläufst.
also, wie oft deine internen Register einen Takt erhalten.
Ob das FF dann schaltet oder auch nicht, hängt ja lediglich von deinen
Eingangssignalen ab (Taste und ENABLE)

Generiere dir einen Zeitbasis für´s Runterzählen und Raufzählen, die
immer nur einen Impuls von 1 Systemtakt Länge bringt und sonst auf Null
ist. Also z.B auf 32000 zählen und dann mit 00000 laden. Und immer wenn
der Zähle rauf 0000 steht, dann gibst du über einen Vergleicher einen
Impuls aus.
Dieser ist die Zeitbasis für deine langsame Geschwindikeit.

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
Noch kein Account? Hier anmelden.