mikrocontroller.net

Forum: FPGA, VHDL & Co. Zähler mit Variable funktioniert nicht


Autor: Dark_Force (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute

Bin langsam echt am verzweifeln hier :(
Ich versuch schon lange diesen Zähler zum laufen zu bringen. Und zwar 
wird auf Tastendruck KEY(1) ein Schalterarray SW(7 downto 0) eingelesen 
und in X gespeichert. Soweit so gut, funktioniert auch!
Nun soll aber beim ersten Tastendruck von KEY(1) der wert von X in A 
gespeichert werden, beim zweiten mal in B und dann wieder in A usw.
Es wird aber weder in A noch in B irgendwann mal was gespeichert und ich 
komm einfach nicht dahinter wieso. Kann mir mal jemand sagen wo mein 
Überlegungsfehler steckt?
...

U0 : flipflop generic map(wide) port map (SW(wide-1 downto 0), KEY(1), X);

process(X)
variable count : integer := 0;
begin
  if (count = 0) then
    A <= X;
  else
    B <= X;
  end if;
  count := count + 1;
  
  if (count = 2) then
    count := 0;
  end if;
end process;

...

Autor: Rick Dangerus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
variable count : integer := 0;
Warum machst Du sowas?

Verwende signale dafür!

Rick

Autor: Dark_Force (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil die erste Bedingung (if (count = 0)...) sonst eh nie erfüllt würde 
da die letzte Zuweisung an das signal count ja count+1 wäre was 1 
entsprechen würde!

Autor: Rick Dangerus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flasch.
Wenn count = 2 ist, wird die letzte Zuweisung count <= 0.

Hast Du eine Testbench? Simuliere das mal!

Rick

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> U0 : flipflop generic map(wide) port map (SW(wide-1 downto 0), KEY(1),
> X);

Keine gute Idee, beschreib lieber das Verhalten als von Hand Hardware zu 
instanziieren.

> process(X)
> variable count : integer := 0;
> begin
>   if (count = 0) then
>     A <= X;
>   else
>     B <= X;
>   end if;
>   count := count + 1;
>
>   if (count = 2) then
>     count := 0;
>   end if;
> end process;

Ich fürchte du bist völlig auf dem Holzweg. Du brauchst einen getakteten 
Prozess um zu zählen. Fang am besten mal mit den VHDL Grundregeln 
an.

Autor: Jörg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo  Dark_Force,

1. Ersetze die Variable durch ein Signal
  (sonst werden die Events ja nicht mitgezählt !!!!)

2. Wenn schon, dann ersetze "if Count = 2 then" durch
   "if Count = 1 then"

3. Ersetze den Counter durch ein Flag
   (Du brauchst ja nur 2 Zustände, spart also einen Addierer!!)

4. Agiere nur auf Rising-Edges von Key(1)
   (sonst wird ja bei jedem Key(1)-Event der Counter weitergezählt,
   ausserdem ist ein solches Verhalten -- aggieren bei beiden Edges --
   kaum synthetisierbar)

     if rising_edge(Key(1) then
       .. Dein (modifizierter) Counter-Code ...
     end if;

viel Spass

Autor: Dark_Force (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Andreas

Ist es nicht so, dass der Prozess sowieso erst bei einer Veränderung von 
X (also allg. Ausdrücke in der Sensitivity List) durchlaufen wird? Dies 
würde ja in diesem Fall bedeuten, dass der Prozess nur ausgeführt wird, 
wenn das Flipflop das Signal X verändert hat (Gewissermassen getaktet?) 
?!

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, das gilt nur für die Simulation, aber nicht für die Synthese.

Autor: Dark_Force (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, das war mir nicht bewusst! Bin immer noch am Lernen von VHDL und 
habs jetzt mal nachgeschlagen im Reference Manual. Jetzt ist's mir klar.

Ich werde mich heute Abend nochmals daran setzen und eure Vorschläge 
umsetzen. Mal schauen ob ich's hinkriege :)
Vielen Dank für eure Tipps. Sehr kompetentes Forum hier!

Autor: Dark_Force (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, hab's hingekriegt:
...
signal count   :  integer  := 0;
...
process(CLK)
begin
  if(rising_edge(CLK) then
    if (count = 0) then
      A <= SW(7 downto 0);
      count <= 1;
    elsif (count = 1) then
      B <= SW(7 downto 0);
      count <= 0;
    end if;
  end if;
end process;

- 'signal' anstatt 'variable' für counter
- FF direkt in der Top entity anstatt über component instantiation, 
dadurch konnte ich ein Flag einbauen für die Modulo-2 Funktion.
Danke nochmals für eure Tipps!

Autor: Jörg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
.. jetzt ersetze nur noch integer durch std_logic und passe Deinen Code
so an, das count ein Flag ist.

Autor: Jörg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was mir beim kurzen Überfliegen Deines Codes nur unbewust aufgefallen 
ist:
Du toggelst ja bei jedem Taktzyklus, wolltest aber eigentlich bei jedem
Key-Pressed rsp. key-Released toggeln. Entprelle doch Key per Clock und
leite dann ein Signal für Pressed/Released ab, das nur für ein Zyklus
gesetzt ist. Dann benutze in Deinem neuen Code einfach dieses 
Pressed-Flag
rsp. Released-Flag..

Autor: Dark_Force (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jürg
Was meinst du mit "code anpassen, sodass count ein flag ist"? Gibt's da 
eine spezielle definition dafür?

BTW: Da der Taster den Clock darstellt, wird auch nur bei Tastendruck 
getoggelt ;)

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dark_Force wrote:
> Hallo Jürg
> Was meinst du mit "code anpassen, sodass count ein flag ist"? Gibt's da
> eine spezielle definition dafür?

std_logic, oder integer range 0..1, was dir lieber ist.

> BTW: Da der Taster den Clock darstellt, wird auch nur bei Tastendruck
> getoggelt ;)

Böse!  VHDL Flankenerkennung

Autor: Dark_Force (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso Böse?? Ich hab ja nur dieses eine Taktsignal im ganzen System, und 
die ganze Schaltung reagiert nur auf den Tastendruck, ansonsten macht 
das System nichts! Ich seh nicht ein warum ich das System mit XX MHZ 
takten muss, nur um einen Event zu verarbeiten der vielleicht einmal pro 
5 Sekunden auftritt!

Autor: Jörg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, habe CLK für ein Clock-Signal und nicht für Key(1) interpretiert,
für CLK = Key(1) wird natürlich korrekt getoggelt.

Überarbeite Deinen Code aber trotzdem komplett. Entprelle z.B. Key(1)
und leite dabei ein Key-Pressed-Flag ab. Teste Signal je Taktzyklus
und toggle bei gesetzten Flag. Dann hast Du einen vollständig synchronen
Ablauf, der sich ohne Probleme in andere Komponenten einbinden lässt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.