VHDL verschiedene Takte gleichzeitig benutzen

Gast #1758113
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
Gast #1758137
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ß
Gast #1758338
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
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #1758382
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...
Gast #1758533
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
Moderator (Firma: Titel) Persönliche Seite #1758547
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
Gast #1758622
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
Gast #1758670
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
Gast #1758789
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
Gast #1759034
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
Gast #1759044
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?
Moderator (Firma: Titel) Persönliche Seite #1759058
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
  :
Gast #1762909
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
Gast #1765092
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
Angehängte Dateien:
Gast #1765104
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';
Gast #1765221
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
Gast #1773498
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
Moderator (Firma: Titel) Persönliche Seite #1773606
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
Gast #1773698
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;
Moderator (Firma: Titel) Persönliche Seite #1773888
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... ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren