Das
:
ZAEHLER:PROCESS(zustand,a)
BEGIN
IF a='1' THEN
counter<=(OTHERS=>'0');
ELSIF zustand = S1 THEN --- Autsch: kombinatorische
counter<= counter+1; --- Schleife
ELSIF zustand = S2 THEN
counter<=(OTHERS=>'0');
--ELSE
:
ist eine kombinatorische Schleife. Und das funktioniert in der
Simulation nur, weil counter in der Sensitivity-List fehlt.
Ein allgemein gern gemachter Fehler.
Probier das doch mal mit der kompletten Sensitivity-List:
:
PROCESS(zustand,a,counter)
:
Dann funktioniert die Simulation nicht mehr ;-)
Im Zustand S1 wird der Zähler dauernd mit maximaler Geschwindigkeit
weitergezählt --> wir haben einen Oszillator --> die Simulation wird nie
fertig. Logisch.
Allgemein gilt:
Wenn die Beschreibung des Schieberegisters/Zählers nicht an einen Takt
sondern an einen Pegel gekoppelt ist, wie etwa:
1 | process (clk)
|
2 | begin
|
3 | if (clk='1') then
|
4 | Reg <= Reg(4 downto 0)&Input;
|
5 | end if;
|
6 | end process;
|
Dann scheint das in der Simulation zu funktionieren, weil die
Simulationsergebnisse nur durchgerechnet werden, wenn sich eines der
Signale in der Sensitivity-List ändert. Und diese Liste ist hier nicht
vollständig.
Da gehören Reg und Input auch mit rein, weil die bei clk=1 auch eine
Änderung des Ergebnisses bewirken:
1 | process (clk, Reg, Input)
|
2 | begin
|
3 | if (clk='1') then
|
4 | Reg <= Reg(4 downto 0)&Input;
|
5 | end if;
|
6 | end process;
|
Und plötzlich funktioniert auch die Simulation nicht mehr, bzw. macht
das selbe wie die reale Schaltung.
Am einfachsten umgeht man solche unnötigen Fehler, indem man
1 | if rising_edge(clk) then
|
verwendet.
>Mach es kompakt in EINEM Prozess. Dann klappts auch mit den FlipFlops.
Full Ack. Und zwar aus Erfahrung.