Forum: FPGA, VHDL & Co. VHDL verschiedene Takte gleichzeitig benutzen


von Cutty (Gast)


Lesenswert?

Hallo,

bin absoluter VHDL-Anfänger. Wir arbeiten mit Quartus für ein
CycloneII-Board. Es geht darum einen Leuchtpunkt zum Wandern zu bringen.
Das funktioniert soweit auch ganz gut. Es geht darum, dass der
Leuchtpunkt beim kurzen Drücken der Taste ein Feld weiter springen soll.
Beim langen Drücken der Taste, soll der Punkt erst nach 2 sek weiter
laufen. Mein Prof. meinte, dass für das kurze Drücken der Taste immer
ein schneller Takt laufen muss und wenn die Taste lange gedrückt wird,
soll sich ein Zustand durchsetzen, der sich auf einen langsameren Takt
bezieht, wobei der schnellere Takt im Hintergrund weiterläuft.
Ich habe mir das so gedacht, dass ich einer Zustandsvariable einen
bestimmten Wert zuweise (z.B. 0). Dann lasse ich in dem langsamen Takt
einen Zähler bis 2 sek hochzählen. Wenn die 2 sek erreicht sind, wird
die Zustandsvariable auf z.B. 1 gesetzt. Nur wenn die Taste gedrückt
wird UND die Zustandsvariable 1 ist, soll der Punkt nach 2 sek
weiterlaufen.
Ist das soweit richtig? Mit der programmiertechnischen Umsetzung haberts
auch bei mir. Was passiert dann mit dem Fall, dass ich nur kurz drücke?
Ich weiß nicht, wie ich den dann einbinden soll...

Ich danke euch schonmal im Voraus :)
Gruß Cutty

von andz (Gast)


Lesenswert?

Bisschen heftig für nen totalen anfägner...

glaub du musst dir erstmal klar werden, dass VHDL keine 
Programmiersprache sondern n hardwarebeschreibungssprache is...also 
zeichne erstmal nen Plan auf RTL Ebene und setzt das dann in VHDL um...

Soweit ichs vestanden habe hast du 2 zustände: einen wo der Punkt bleibt 
wo er ist und im anderen springt er eins weiter. in den zwieten zustand 
kommtst du auf 2 wege: entweder durch LOSLASSEN des tasters, oder wenn 
ein Zähler so weit hochgezählt hat das er 2sec erreicht hat.

In den ersten zustand kannst du dann normal sofort 
zurückspringen...wobei dann wenn du den taster weiterhind drückst, nach 
2sec der punkt wieder ins weitergeht...

Gruß

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Cutty schrieb:
> Es geht darum einen Leuchtpunkt zum Wandern zu bringen.
> Das funktioniert soweit auch ganz gut.
Lass doch mal sehen, wie das aussieht.

von Cutty (Gast)


Angehängte Dateien:

Lesenswert?

Hallo :)

noch zum Verständnis: Leuchtpunkt wandert auf einer 5x7 Matrix per 
Tastendruck entweder nach rechts, links, oben oder unten. bei reset 
sollen alle punkte leuchten. auf 7-segmentanzeigen werden die 
koordinaten angezeigt.

code fürs schieben des punktes ist zu finden unter "reset", "spalten" 
und "zeilen" (kommentierte textüberschrift).

gruß Cutty

von Cutty (Gast)


Lesenswert?

achso: @andz: bei kurzem drücken soll der punkt immer nur ein feld pro 
tastendruck weiterspringen, bei langem drücken soll der punkt, solange 
gedrückt wird, aller 2 sek eins weiterspringen...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

1
  process (c_in, taste_reset, taste_rechts, taste_links, taste_oben, taste_unten)
Der ist echt böse...
Denn in dem Prozess werden mehrere getaktete Konstrukte und zudem noch 
asynchron was beschrieben. In welchem Buch hast du das gesehen?

Ihr habt diesen Code nicht wirklich in Hardware laufen, oder?
Dann könnte der Synthesizer wieder mal mehr als ich ihm zutrauen 
würde...

Die Beschreibung gehört aufgeteilt in einen getakteten Prozess
1
process (c_in, taste_reset) begin
2
   if( taste_reset = '0')then 
3
  Spalte <= "11111";
4
  Zeile <= "0000000";
5
  count_Spalte <= 0;
6
  count_Zeile <= 0;  
7
   elsif rising_edge(c_in) begin
8
        if (taste_rechts = '1')then   
9
    if(count_Spalte = 4)then  count_Spalte <= 0;
10
    else        count_Spalte <= count_Spalte + 1;
11
    end if;
12
  end if;
13
  if(taste_links = '1')then
14
        :
15
  end if;
16
  if(taste_oben = '1')then
17
  :
18
  end if;
19
  if(taste_unten = '1')then
20
        :
21
  end if;
22
    end if;
23
end process;
und in einen kombinatorischen Prozess bzw. der Concurrent-Zuweisung.
1
signal count_Spalte : ...  
2
signal count_Zeile : ...  
3
4
process (count_Spalte) begin
5
  case count_Spalte is
6
        :
7
end process;  
8
process (count_Spalte) begin
9
  case count_Zeile is
10
        :  
11
end process;
Dann hast du nämlich auch noch die absolut unnötigen Variablen weg...

> Das funktioniert soweit auch ganz gut.
1
if(rising_edge(c_in) and taste_rechts = '1')
Welche Frequenz hat c_in? Wenn das der bei FPGA übliche 50MHz-Takt ist, 
dann donnerst du während einem kurzen Tastendruck von 200ms etwa 10000 
mal nach rechts...  :-o


BTW: meine VHDL-Dateien enden nicht auf *.TXT
Probier mal hier im Forum eine *.VHD-Datei anzuhängen. Du wirst 
staunen...

von Cutty (Gast)


Lesenswert?

Hallo :)

> Denn in dem Prozess werden mehrere getaktete Konstrukte und zudem noch
> asynchron was beschrieben. In welchem Buch hast du das gesehen?

das hat uns unser prof so gesagt...so viel dazu ;)...wir hatten zunächst 
nur den takt c_in im prozess,das lief auch, gab aber n haufen warnungen

> Ihr habt diesen Code nicht wirklich in Hardware laufen, oder?

yep, haben wir ^^. da sieht man mal wieder, was so alles entsteht, wenn 
man nichtwissende studenten vor so eine aufgabe stellt :)

> Welche Frequenz hat c_in? Wenn das der bei FPGA übliche 50MHz-Takt ist,
> dann donnerst du während einem kurzen Tastendruck von 200ms etwa 10000
> mal nach rechts...  :-o

ja, es sind die 50 MHz. wir haben aber noch separat einen frequenzteiler 
beschrieben. der teilt uns den takt auf 1 sek oder so runter :). hinzu 
kommt ja noch, dass die tasten noch nicht mal entprellt sind...das ist 
auch noch so ne aufgabe, die erledigt werden muss. haben schon tausend 
möglichkeiten probiert (d-ff, rs-ff, per vhdl...), aber es verändert 
sich nichts...tut immer genau dasselbe...naja.

ist es jetzt überhaupt möglich noch einen takt ins spiel zu bringen, der 
für das langsame wandern des punktes benutzt werden kann? oder ist das 
absoluter frevel? :)

vielen dank schonmal für die antworten

gruß Cutty

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> wir haben aber noch separat einen frequenzteiler
> beschrieben. der teilt uns den takt auf 1 sek oder so runter :)
D.h. der c_in ist auf 1 Hz runtergeteilt? Das wäre sehr ungünstig. 
Besser ist es, das ganze Design auf 50MHz laufen zu lassen, und nur noch 
mit Clock-Enables zu arbeiten. Was du also machen mußt, ist, einen 
wiederkehrenden Taktimpuls (der bei 50MHz dann genau 20ns lang gilt) zu 
erzeugen. So etwas also wie der clken beim Lauflicht: 
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html

> ist es jetzt überhaupt möglich noch einen takt ins spiel zu bringen, der
> für das langsame wandern des punktes benutzt werden kann? oder ist das
> absoluter frevel? :)
Du tust dir garantiert keinen Gefallen, wenn du einen zweiten Takt (also 
eine Abfrage auf rising_edge()) ins Spiel bringst.

Ein Anfängerdesign
- hat genau 1 Takt
- reagiert nur auf die steigende Flanke
- hat keinen asynchronen Reset (und schon gar keinen kombinatorischen)

Der dritte Punkt ist übrigens auch bei deinem Design problematisch. Du 
hast nur wegen der geringen Taktfrequenz noch kein Problem damit...  :-o
http://www.lothar-miller.de/s9y/categories/34-Getakteter-Prozess
http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html

von Cutty (Gast)


Lesenswert?

Hallo :)

> D.h. der c_in ist auf 1 Hz runtergeteilt? Das wäre sehr ungünstig.

was hat denn unser prof dann erzählt? das war das erste, was er sagte: 
ihr braucht einen frequenzteiler...hm...jetzt bin ich total verwirrt :)

> Du tust dir garantiert keinen Gefallen, wenn du einen zweiten Takt (also
> eine Abfrage auf rising_edge()) ins Spiel bringst.

dann hab ich jetzt absolut keinen plan, wie ich das mit dem langsamen 
laufen des leuchtpunktes machen soll...

> Ein Anfängerdesign
> - hat genau 1 Takt
> - reagiert nur auf die steigende Flanke
> - hat keinen asynchronen Reset (und schon gar keinen kombinatorischen)

das hätte uns mal jemand eher sagen sollen :).

> Der dritte Punkt ist übrigens auch bei deinem Design problematisch. Du
> hast nur wegen der geringen Taktfrequenz noch kein Problem damit...  :-o

also hab ich jetzt einen asynchronen reset im programm? ich weiß noch 
nicht mal was das ist, geschweige denn, wie ich das ändern kann :)

fazit: unser programm ist für die katz und nicht mehr zu retten? :)
vielen dank schonmal für die antworten

gruß Cutty

von D. I. (Gast)


Lesenswert?

am besten du kaufst dir erstmal das buch vhdl-synthese von reichardt und 
lernst im selbststudium. Das was ihr machen müsst ist nicht schwer, aber 
man muss schon etwas Bescheid wissen was man eigentlich tut

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> fazit: unser programm ist für die katz und nicht mehr zu retten? :)
Nein, das geht nach ein paar Aufräumarbeiten schon, du mußt nur erst mal 
die Taktung auf Clock-Enables umstellen. Und dann ein Konzept für diese 
Clock-Enables aufstellen.

BTW: Das mit dem Buch ist nicht die schlechteste Idee... ;-)

von Cutty (Gast)


Lesenswert?

Hallo :)

danke für die antworten...das problem ist nur: bis zum 01.07. muss das 
fertig sein. dieses forum war mein allerletzter ausweg so kurz vor 
schluss :)
im grunde genommen funktioniert es...nur halt nicht besonders schön. das 
kommt dann einfach in die doku mit rein und dann ist jut. ich hab nach 
den ganze eskapaden keine lust mehr, mich ausgiebig mit vhdl zu 
beschäftigen :)
ich glaub der prof hats uns versaut ;)
ich probier das auf jeden fall mit den clock enables...

gruß Cutty

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Ich hätte das (basierend auf dem Originalansatz) in etwa so wie im 
Anhang gelöst... ;-)

von Cutty (Gast)


Lesenswert?

Hallo :)

das nenn ich mal ein schönes Programm :)
wenn ich jetzt aber beim reset folgendes einfügen will (zum aufleuchten 
lassen aller leds):

Zeile<="0000000";
Spalte<="11111";

bringt er eine fehlermeldung: Error (10028): Can't resolve multiple 
constant drivers for net "Spalte[4]" at Schieberegister.vhd(198)

warum nur für spalte und nicht für zeile?

gruß Cutty

von Cutty (Gast)


Lesenswert?

achso, noch eine frage:
1
process begin -- Schieberegister zum Einsynchronisieren und für Flankenerkennung
2
     wait until rising_edge(clk);
3
    resetsr <= resetsr(1 downto 0) & taste_reset; -- Schieberegister
4
    usr <= usr(1 downto 0) & taste_unten;
5
    osr <= osr(1 downto 0) & taste_oben;
6
    rsr <= rsr(1 downto 0) & taste_rechts;
7
    lsr <= lsr(1 downto 0) & taste_links;
8
end process;

hier werden mit einem Verkettungsoperator, wenn ich mich richtig 
informiert habe, felder angelegt, mit dem Inhalt des rechten Operanden, 
gefolgt von dem Inhalt des linken Operanden. wozu dient das?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> wozu dient das?
Das ist die Beschreibung eines Scheiberegisters, in das von rechts der 
Tasterpegel eingetaktet wird.
Z.B. ist usr 3 Bit breit, davon werden dann die rechten 2 Bits 
genommen, um ein Bitt nach links gerückt, und der taster_unten 
dazuverknüpft.

> bringt er eine fehlermeldung: Error (10028): Can't resolve multiple
> constant drivers for net "Spalte[4]" at Schieberegister.vhd(198)
Ein Klassiker: du kannst nicht aus mehreren Prozessen auf 1 Signal 
treiben.

Mach einen Umweg und definiere statt:
1
signal count_Zeile  : integer range 0 to 6 := 0;
2
signal count_Spalte : integer range 0 to 4 := 0;
einfach einen Zustand mehr:
1
signal count_Zeile  : integer range 0 to 7 := 0;
2
signal count_Spalte : integer range 0 to 5 := 0;
Und definiere: der Wert 0 ist dein Resetwert.
Dann mußt du natürlich die Tabellen und die Zähler entsprechend 
anpassen:
1
  process begin -- Zählerverwaltung
2
     wait until rising_edge(clk);
3
    --   steigende Flanke    oder    Wiederholung aktiv
4
    if (rsr(2 downto 1)="01") or (rsr(2)='1' and repeat='1') then 
5
      if(count_Spalte = 5)then  -
6
        count_Spalte <= 1;
7
      else
8
        count_Spalte <= count_Spalte + 1;
9
      end if;
10
    end if;
11
    if (lsr(2 downto 1)="01") or (lsr(2)='1' and repeat='1') then 
12
      if (count_Spalte = 1)then 
13
        count_Spalte <= 5;
14
      else
15
         count_Spalte <= count_Spalte - 1;
16
      end if;
17
    end if;
18
    :
19
    :
20
  end process;
21
  
22
  process (count_Zeile) begin
23
    case count_Zeile is  
24
    when 0 =>  -- Resetwert
25
      Zeile <= "1111111";
26
      h<='1';
27
      i<='1';
28
      j<='1';
29
      k<='1';
30
      l<='1';
31
      m<='1';
32
      n<='1';
33
    when 1 =>
34
      Zeile <= "0111111";
35
      h<='1';
36
      i<='0';
37
      j<='1';
38
      k<='1';
39
      l<='0';
40
      m<='1';
41
      n<='1';
42
    when 2 =>
43
      Zeile <= "1011111";
44
      h<='0';
45
      i<='0';
46
      j<='1';
47
      k<='0';
48
      l<='1';
49
      m<='0';
50
      n<='0';
51
    when 3 =>
52
      Zeile <= "1101111";
53
  :
54
  :

von Cutty (Gast)


Lesenswert?

Supi, danke schön. bin jetzt erstmal nicht im labor, schreibe übers we 
an meinem bericht. ich meld mich dann nächste woche nochmal und berichte 
:)

danke danke danke fürs helfen :)))

gruß Cutty

von Cutty (Gast)


Lesenswert?

Hallo :)

es funktioniert alles super. Vielen Dank nochmal für die Hilfe. Falls 
ich noch Verständnisprobleme habe, melde ich mich wieder ^^. Ich habe in 
den paar Tagen im Forum mehr gelernt, als in 3 Monaten qualvollem 
Selbststudiums...;)

gruß
Cutty

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> als in 3 Monaten qualvollem Selbststudiums...;)
Kauf dir das Buch "VHDL-Synthese" von Reichardt/Schwarz, oder leih es 
aus.
Ich vermute sehr stark, dass du es noch nicht hast...  ;-)

von Cutty (Gast)


Lesenswert?

falls ich jemals wieder mit vhdl in kontakt komme, hab ich mir dieses 
buch auf jeden fall vorgemerkt ;)

von Cutty (Gast)


Angehängte Dateien:

Lesenswert?

Hallo :)

jetzt müssen wir dieses schöne programm auch in modelsim testen ^^
nur leider funktioniert das gar nicht...der rennt immer in einen 
undefinierten zustand bei spalte und zeile (siehe anhang)
muss ich irgendwas besonderes beachten bei modelsim?

gruß
Cutty

von Nephilim (Gast)


Lesenswert?

es könnte hilfreich sein, die signale für die tasten 
vorzuinitialisieren. dadurch sind die in der simulation nicht mehr 
unbekannt ('X') sondern vielleicht '0'. Dadurch kann die Simulation dann 
auch damit rechnen.

z.B.

signal teste_xxx : std_logic := '0';

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> jetzt müssen wir dieses schöne programm auch in modelsim testen
Zeig mal deinen Code und die zugehörige Testbench...

von Cutty (Gast)


Lesenswert?

Hallo :)

habs schon hingekriegt :)
es lag daran, dass ich den code fürs 2s tasten drücken noch drin 
hatte...
da hätte ich mich ja wulig simuliert ^^

so reicht es völlig aus und ist richtig schön geworden
danke trotzdem :)

gruß cutty

von Cutty (Gast)


Lesenswert?

ach und ich hatte vergessen, dass reset auf dem board lowaktiv 
ist...hatte somit einen völlig falschen zustand definiert ^^

von Cutty (Gast)


Lesenswert?

Hallo :)
1
process begin -- Schieberegister zum Einsynchronisieren und für Flankenerkennung
2
     wait until rising_edge(clk);
3
    resetsr <= resetsr(1 downto 0) & taste_reset; -- Schieberegister
4
    usr <= usr(1 downto 0) & taste_unten;
5
    osr <= osr(1 downto 0) & taste_oben;
6
    rsr <= rsr(1 downto 0) & taste_rechts;
7
    lsr <= lsr(1 downto 0) & taste_links;
8
end process;
warum dient dieses Schieberegister zum Einsynchronisieren und für die 
Flankenerkennung?

gruß Cutty

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> warum dient dieses Schieberegister zum Einsynchronisieren und für die
> Flankenerkennung?
Dies Schieberegister, so wie sie da stehen, dienen zuerst nur mal zum 
Eintakten/Einsynchronisieren.

Eine Flankenerkennung wird daraus, wenn irgendwo steht
1
brocess begin
2
   wait until rising_edge(clk);
3
   if usr(2 downto 1) = "10" then -- fallende Flanke (von 1 nach 0)
4
      :
5
   end if;
6
   if osr(2 downto 1) = "01" then -- steigende Flanke (von 0 nach 1)
7
      :
8
   end if;
9
end process;

> warum dient dieses Schieberegister zum Einsynchronisieren und für die
> Flankenerkennung?
Damit z.B. sowas nicht passiert:
http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html

von Cutty (Gast)


Lesenswert?

Hallo :)

ich versteh noch nicht so 100%ig, was diese CE-Verwaltung hier 
macht...*aufdemSchlauchsteh*
Bitte nochmal mit ganz einfach Worten? Danke im Voraus :).

gruß Cutty
1
process begin -- Clock-Enable-Verwaltung
2
     wait until rising_edge(clk);
3
    onesecond <= '0';
4
      repeat    <= '0';
5
    if (counter1s<50000000-1) then
6
       counter1s <= counter1s+1;
7
    else
8
       counter1s <= 0;
9
     onesecond <= '1';
10
    end if;
11
    if (onesecond='1') then
12
       if (counter2s<1) then
13
          counter2s <= counter2s+1;
14
      else
15
         repeat <= '1';
16
      end if;
17
    end if;
18
    if (untensr(2)='0' and obensr(2)='0' and rechtssr(2)='0' and linkssr(2)= '0') then -- keine Taste gedrückt
19
       counter1s <= 0;
20
       counter2s <= 0;
21
    end if;
22
     if (resetsr(2) = '0') then -- Reset betätigt
23
       counter1s <= 0;
24
       counter2s <= 0; 
25
   end if;
26
  end process;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

1
process begin -- Clock-Enable-Verwaltung
2
    wait until rising_edge(clk);    -- warten bis zur nächsten steigenden Taktflanke des FPGA-Takts
3
4
    -- hier wird aus einem 50MHz Takt ein Clock-Enable für jede Sekunde erzeugt
5
    onesecond <= '0';               -- Defaultwert
6
    if (counter1s<50000000-1) then  -- Zählerende noch nicht erreicht erreicht? 
7
       counter1s <= counter1s+1;    -- ja: dann weiterzählen
8
    else                            -- Zählerende erreicht.
9
       counter1s <= 0;              -- Zähler zurücksetzen
10
       onesecond <= '1';            -- Defaultwert vom Enalbe mit '1' überschreiben
11
    end if;
12
13
    -- Hier das Repeat-Signal nach 2 Sekunden Tastendruck erzeugt
14
    repeat    <= '0';               -- Defaultwert für Repeat-Signal
15
    if (onesecond='1') then         -- wieder eine Sekunde vergangen?
16
       if (counter2s<1) then        -- Zähler für Enable 2 Sekunden prüfen
17
          counter2s <= counter2s+1; -- Zählerende noch nicht erreicht: weiterzählen
18
      else                          -- Zählerende erreicht:
19
         repeat <= '1';             -- Repeat aktivieren
20
      end if;
21
    end if;
22
    
23
    -- Zähler zurücksetzen, wenn keine Taste gedrückt
24
    if (untensr(2)='0' and obensr(2)='0' and rechtssr(2)='0' and linkssr(2)= '0') then -- keine Taste gedrückt
25
       counter1s <= 0;              -- Zähler zurücksetzen
26
       counter2s <= 0;              -- --> Zähler und Repeat beginnen von vorn
27
    end if;
28
    -- Zähler zurücksetzen, wenn Reset-Taste gedrückt
29
    if (resetsr(2) = '0') then      -- Reset betätigt
30
       counter1s <= 0;              -- Zähler zurücksetzen
31
       counter2s <= 0;              -- --> Zähler und Repeat beginnen von vorn
32
   end if;
33
end process;

In einer Simulation kannst du den Ablauf schön erkennen... ;-)

von Cutty (Gast)


Lesenswert?

Hallo :)

habe das quartus-projekt hinter mir und wollte nur nochmal DANKE sagen 
für die vielen lieben Hilfestellungen. Hat mich sehr weiter 
gebracht...DANKE :)!!!

gruß
Cutty

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.