Forum: FPGA, VHDL & Co. Ich habe ein seltsames CASE - Problem :(


von Koblenzer (Gast)


Lesenswert?

Ich habe ein Problem mit CASE...

wenn ich ein asynchrones Reset benutze, funktioniert mein Design nicht.

Hier ist mein Beispiel:
1
process(CLK , nRESET)
2
begin
3
  if nRESET = '1' then
4
    state <= s1;
5
  else
6
    if rising_edge(CLK) then
7
      case state is 
8
        when s1 => 
9
          state <= s2;
10
          ram_A <= "00001" & pix_A;
11
          attr_D <= ram_D;
12
        when s2 => 
13
          state <= s1;
14
          ram_A <= "00001" & attr_A;
15
          pix_D <= ram_D;
16
      end case;
17
    end if;
18
  end if;
19
end process;

ABER! Wenn synchrones Reset... alles OK!
1
process(CLK , nRESET)
2
begin
3
  if rising_edge(CLK) then
4
    if nRESET = '1' then
5
      state <= s1;
6
    else
7
      case state is 
8
        when s1 => 
9
          state <= s2;
10
          ram_A <= "00001" & pix_A;
11
          attr_D <= ram_D;
12
        when s2 => 
13
          state <= s1;
14
          ram_A <= "00001" & attr_A;
15
          pix_D <= ram_D;
16
      end case;
17
    end if;
18
  end if;
19
end process;

warum????

von Jörg (Gast)


Lesenswert?

Dein Problem liegt ja nicht am CASE, sondern daran, dass Du
kombinatorische, sequentielle und Reset-Logik ungünstig mischt:
Geh mal davon aus, das Reset zwischen zwei Taktzyklen aktiviert
wird.

Fall 1 (state=S1):
  Reset bewirkt eigentlich nichts.

Fall 2 (state=S2):
  Reset bewirkt state<=S1, aber zu nächsten pos.Taktflanke wird
  state<=S2 gesetzt. Die Werte in ram_A,attr_D wurden aber in
  nicht zwischenzeitlich entspr. S1-Zustand angepasst.

Es gibt dann noch die Fälle, in denen Reset "fast gleichzeitig"
mit Clock-Edge erfolgen..


Vieleicht besser:
1
-- state, next_state: same type!!
2
3
process(CLK , nRESET)
4
begin
5
  if nRESET = '1' then
6
    state <= s1;
7
  else
8
    if rising_edge(CLK) then
9
      state <= next_state;
10
    end if;
11
  end if;
12
end process;
13
14
15
process(state,pix_A,attr_A,ram_D)
16
begin
17
  case state is
18
    when s1 => next_state <= S2;
19
               ram_A      <= "00001" & pix_A;
20
               attr_D     <= ram_D;
21
22
    when s2 => next_state <= S1;
23
               ram_A      <= "00001" & attr_A;
24
               pix_D      <= ram_D;
25
  end case;
26
end process;

Jetzt ist Asynchronität von Reset von der der synchronen
NextState-Logik getrennt, ausserdem werden alle Werte korrekt
gesetzt, vorausgesetzt, pix_A,attr_A,ram_D sind ebenfalls
zusammen mit state synchron.

von die ??? (Gast)


Lesenswert?

Verwirrung: Ist dein nRESET nun low- oder high-aktiv?

Bin kein VHDL-Crack, aber zwei Dinge sind mir aufgefallen:

1/  else
      if
          -->
               elsif

2/  Synchroner Reset: nRESET aus Sensivitätsliste entfernen.

von Koblenzer (Gast)


Lesenswert?

Danke für Eure Hilfe!

@ Jörg
Habe deinen Beispiel gerade ausprobiert... es geht nicht.
Habe das gleiche Problem wie früher, mit asynchronem Reset.
Ich sehe nur müll auf dem Bildschirm (es ist ein Retro-Computer)

eigentlish brauche ich in diesem Fall gar keinen Reset.
Deswegen habe ich ganz ohne ausprobiert. Es geht auch nicht :(

Ich verwende ISE WebPack 10.1 und Spartan-3AN Board
von Digilent (mit nachgerüstetem SRAM).

Was noch sehr interessant ist..
ich habe auch mit if..then ausprobiert (mit und ohne Reset)
Es geht ohne probleme...

Alle FSM-Beispiele aus Internet sind mit asynchronem Reset...
bei mir geht nicht...

Ich bin zwar zufrieden, das es endlich läuft...
möchte aber gerne wissen, warum es so nicht funktioniert?????

von Jörg (Gast)


Lesenswert?

Ich benutze in meiner Freizeit ein Spartan3E, ebenfalls WebPack 10.1.
Habe gerade mal ein einfaches Programm (LED-Lichterkette) inkl.
Reset-Logik ausprobiert, es lief ohne Probleme/wie erwartet.

Der von mir verwendete Rahmen für FSM (Sequentielle und kombinatorische
Logik getrennt) verwende ich eigentlich in all meinen (keineren bis
mittelgrossen) Projekten, ist auch in vielen aktuellen Büchern zum
Thema VHDL zu finden.

Kann nur noch vermuten, dass Du Deinen Reset-Taster nicht entprellt
hast oder im umgebenden Code vieleicht irgendein Problem bzgl.
async. Zurücksetzen liegt. Falls Du (wie ich) keinen Logik-Analyzer
zur Verfügung hast, mach doch einfach mal folgendes:

  Füge deinem Projekt ein DCM-Modul hinzu, das z.B. auf 1/8 Deines
  Takts runtertaktet, so kannst Du "willkürlich" an allen möglichen
  Stellen Reset in einer Test-Benchmark setzen. Vieleicht passiert ja
  dann was ungewöhnliches in einem Simulationslauf, was Dein Problem
  erklärt.


P.S. hast Du mal im "Static Timing Report" geschaut, ob 133MHz als
max. Frequenz unterschritten wird? Kannst Du Dein Projekt mal nur mit
50MHz laufen lassen und schauen, ob es funktioniert?

von Koblenzer (Gast)


Lesenswert?

Vielleicht lieg es an meinem Videokontroller???
Videokontroller stellt 2 Adresset zur verfügung: pix_A und attr_A
und wartet 7 takten, dann liest der 2 Register - pix_D und attr_D
Speicherkontroller arbeitet mit doppelte Frequenz und hat 4 States.
Das heisst, der hat genug Zeit um pix_D und attr_D zu holen.
Mein ZX Spectrum-Klone läuft seit Herbst 2007.
Es ist ein ZX-Spectrum 128K mit AY und TR-DOS (Disketten-Images werden
von SD-Karte gelesen. Dafür verwende ich ATMega32)
Jetzt wollte ich meine VHDL-Code sauber machen und verbessern, um
diese zu veröffentlichen.
Dabei sind mir viele Dinge aufgefallen... Wie z.B. mein 
Speicherkontroller.
Jetzt habe ich alles rausgeschmissen... unterstützung von 128K, AY, PS/2
Tastatur u.s.w.
nur T80 + ROM + SRAM gelassen um festzustellen, warum es nicht geht.
Ich weiss nicht was ich falsch mache.
Schon 2 Tage lese ich hier alle Threads, wo es um CASE, STATE MACHINES,
SRAM, synchron/asynchron RESET u.s.w
Kann leider mein Fehler nicht finden :(

Deswegen meine Frage:
Wie wird in der Praxis ein Speicherkontroller gemacht??? So dass CPU
und Videokontroller SRAM-Speicher teilen können???
Und was noch wichtiger ist, wie macht man sowas, wenn Videokontroller
mit anderen Frequenzen als CPU läuft???
Das brauche ich für VGA-unterstützung.

wenn nötig, quelltexte folgen Morgen.. ist Zeit zum schlafen :)

von Koblenzer (Gast)


Lesenswert?

Frühe waren in meinem Design ClockEnable-Signale so:
1
CLK     -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
2
3
RAM  __----____----____----____----____----__
4
5
VIDEO   __--------________--------________------

Habe gerade folgendes ausprobiert...
ClockEnable für RAM um 90 Grad verschoben:
1
CLK     -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
2
3
RAM  ____----____----____----____----____----
4
5
VIDEO   __--------________--------________------

Und jetzt läuft es!!!
Mit synchronem und asynchronem Reset und ganz ohne Reset auch!
Warum? ist mir immer noch nicht ganz klar.
Vielleicht kann jemand mir paar Tipps zum Thema "CLOCK" geben???
Verschiedene Teile meines Designs verwenden eigene
Frequenzen (Clock Enable für CLK),
z.B.
CPU - 3.5MHz,
Video - 7MHz,
RAM - 14MHz,
CLK - 56MHz.

von Koblenzer (Gast)


Lesenswert?

Sorry, mein Fehler... noch mal:

Vorher:
1
CLK   -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
2
3
RAM   __----____----____----____----____----__
4
5
VIDEO __--------________--------________------

Jetzt so:
1
CLK   -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
2
3
RAM   ____----____----____----____----____----
4
5
VIDEO __--------________--------________------

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.