Forum: FPGA, VHDL & Co. Wir bauen ein Dual Port Ram


von A. N. (netbandit)


Lesenswert?

Hallo,

nachdem ich mich etwas in VHDL eingearbeitet habe möchte ich nun nach
zahlreichen kleineren Testaufbauten und -Beispielen etwas sinnvollen
machen.

Für eines meiner Projekte benötige ich einen Dual Port Ram. Ich habe
hier schnelle SRAMs rumliegen und wollte per VHDL eine Logik davor
basteln.
Dabei sollen beide Ports zeitlich versetzt auf den Ram zugreifen. Der
Controller wird von "außen" wie ein ganz normales Ram mit größeren
Zugriffszeiten angesteuert.
Folgenden Zustanndautomaten hab ich mir dabei gedacht:

Zustand 1:
===========
Kontrollbits <= 0
Adressbits <= 0
Datenbits <= 0
Rammodus <= 0
Zustand <= Zustand 4

wenn Port0./WE = 0 (schreibzugriff)
  Adressbits <= Port0.Adressbits
  Datenbits <= Port0.Datenbits
  Rammodus <= 1
  Zustand = Zustand 2

wenn Port0./OE = 0 (lesezugriff)
  Adressbits <= Port0.Adressbits
  Rammodus <= 2
  Zustand = Zustand 2

Zustand 2
=========
Kontrollbits <= Port0.Kontrollbits
Zustand = Zustand 3

Zustand 3
=========
Zustand <= Zustand 4
wenn Rammodus = 1 (lesen)
  Port0.Datenbits <= Datenbits

Zustand 4:
===========
Kontrollbits <= 0
Adressbits <= 0
Datenbits <= 0
Rammodus <= 0
Zustand <= Zustand 1

wenn Port1./WE = 0 (schreibzugriff)
  Adressbits <= Port1.Adressbits
  Datenbits <= Port1.Datenbits
  Rammodus <= 1
  Zustand = Zustand 5

wenn Port1./OE = 0 (lesezugriff)
  Adressbits <= Port1.Adressbits
  Rammodus <= 2
  Zustand = Zustand 5

Zustand 5
=========
Kontrollbits <= Port1.Kontrollbits
Zustand <= Zustand 6

Zustand 6
=========
Zustand <= Zustand 1
wenn Rammodus = 1 (lesen)
  Port1.Datenbits <= Datenbits


So weit so gut. Nun takte ich das ganze mit 66MHz (ca. 15ns) und habe
somit nach dem 6. Zustand 90ns gebraucht.
Das heißt, das jedes der Port-Signale mind. 90 ns Anliegen muß, damit
sie von der Logik berücksichtigt werden können. Oder habe ich da einen
Denkfehler?
Seht ihr eine Möglichkeit das ganze zu beschleunigen ohne den Takt noch
höher zu wählen oder ist dieser Zustandsautomat schon (Zeit)effizient?
Ich meine in speziellen Fällen (kein Portzugriff oder Schreibzugriff)
könnte man verschiedene Zustände auslassen, aber im Fall der Fälle
müssen wohl alle Zustände durchquert werden.

Vielleicht hat ja jemand das ganze schonmal gemacht und die eine oder
andere Erfahrung damit gesammelt.

von Klaus F. (kfalser)


Lesenswert?

Du solltest deinen Kontroller umbauen auf Handshake Signale (Request und
Acknowledge), damit Du weisst wann Dein Lese/Schreibvorgang gültig
verarbeitet worden ist oder Dich von außen auf die Zustände
synchronisieren.

Ansonsten mußt Du noch länger warten und bekommst sogar noch Fehler.
Angenommen Du möchtest Port 1 lesen und dein Kontroller ist gerade im
Zustand 4, hat meinetwegen das WE Signal vorgefunden und startet einen
Schreibzyklus.
In der Zwischenzeit legst Du neue Signale an, im Zustand 5 bekommt das
RAM sogar noch die neuen, wahrscheinlich falschen Kontrollbits.

Also :
Zustand  5 -> 6 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6

ergibt mindestens 8 Zyklen.

Grüße
Klaus

von A. N. (netbandit)


Lesenswert?

Hi Klaus,

danke erstmal für deine Antwort. Leider kann ich den Controller nicht
auf Handshake umbauen, das wäre von anfang an die beste Lösung gewesen.
Aber es sollen z.b. zwei AVR so drauf zugreifen als wäre es ein stink
normaler Ram, ohne softwaremäßige Klimmzüge.

Ich denke du meinst das mit dem Fehler so: Wenn die Anforderung
schonmal bearbeitet wurde, aber beim nächsten Durchgang immernoch
existiert. (Weil der µC langer als 90ns darauf zugreift) dann wird eine
neue Anforderung eingeleitet, da der Controller nicht erkennt, das er
sie schonmal bearbeitet hat.
Das wäre ja nicht so schlimm allerdings kann man davon ausgehen, dass
die Anforderung nun genau in diesem Moment umschaltet (weil die
Zugriffszeit abgelaufen ist) und somit Bockmist bei raus kommt.

Ich habe gestern ide State Maschine programmiert und mache nun bei
Rammodus keine unterscheidung mehr ob gelesen oder geschrieben wird.
Dafür gibt es nun RAM_Modus0 und RAM_Modus1, welche ein einem zugriff
der jeweiligen Ports gesetzt werden.
Eine neuer Zugriff wird erst dann erfolgen wenn RAM_Modus0/1 gelöscht
sind, was nur dann passiert wenn PortX.OE und WE auf 1 ist.

Damit wird eine schonmal abgearbeitete Anforderung nicht nochmal
wiederholt und Fehler sollten nun nicht mehr auftauchen.

Ich werde das ganze heute mal durch ModelSim jagen.

von A. N. (netbandit)


Lesenswert?

So jetzt sieht es im ModelSim doch nach was aus :)
Aber aus dem 8 Zuständen wurden 10, damit das Daten bzw. Adressword
nach dem Abschalten von RAM_OE / RAM_WE noch etwas anliegt. Ansonnsten
könnte es eventuell Probleme mit dem Speichern der Daten geben glaube
ich.

Also habe ich jetzt immerhin eine "Zugriffszeit" von 160ns am Port
bei einem Takt von 66MHz. Ein AVR mit 3 Wait States müsste das packen,
aber an sich habe ich mir das besser vorgestellt. Zumal das ganze nun
45 Register "schluckt".

Ich habe das ganze bis jetzt nur in ModelSim getestet und werde es in
den nächsten Tagen auf einen CPLD umprogrammieren.
Es gibt dich auch die Möglichkeit das Timingsverhaltes des CPLDs bei
der Simulation zu beachten.
Das dürfte ja dann die Post Fit Simulation sein. Leider funktionirt die
bei mir nicht richtig. Ich kann zwar eine Post Fit Simulation meines
Dual Port Ram entity machen, doch bentzt er dann das Top Model mit der
Simulationsansteuerung nicht.

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.