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


von Dark_Force (Gast)


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?
1
...
2
3
U0 : flipflop generic map(wide) port map (SW(wide-1 downto 0), KEY(1), X);
4
5
process(X)
6
variable count : integer := 0;
7
begin
8
  if (count = 0) then
9
    A <= X;
10
  else
11
    B <= X;
12
  end if;
13
  count := count + 1;
14
  
15
  if (count = 2) then
16
    count := 0;
17
  end if;
18
end process;
19
20
...

von Rick Dangerus (Gast)


Lesenswert?

1
variable count : integer := 0;
Warum machst Du sowas?

Verwende signale dafür!

Rick

von Dark_Force (Gast)


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!

von Rick Dangerus (Gast)


Lesenswert?

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

Hast Du eine Testbench? Simuliere das mal!

Rick

von Andreas S. (andreas) (Admin) Benutzerseite


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.

von Jörg (Gast)


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

von Dark_Force (Gast)


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?) 
?!

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

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

von Dark_Force (Gast)


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!

von Dark_Force (Gast)


Lesenswert?

Also, hab's hingekriegt:
1
...
2
signal count   :  integer  := 0;
3
...
4
process(CLK)
5
begin
6
  if(rising_edge(CLK) then
7
    if (count = 0) then
8
      A <= SW(7 downto 0);
9
      count <= 1;
10
    elsif (count = 1) then
11
      B <= SW(7 downto 0);
12
      count <= 0;
13
    end if;
14
  end if;
15
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!

von Jörg (Gast)


Lesenswert?

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

von Jörg (Gast)


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..

von Dark_Force (Gast)


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 ;)

von Andreas S. (andreas) (Admin) Benutzerseite


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

von Dark_Force (Gast)


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!

von Jörg (Gast)


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.

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.