Hallo Leute, Ich steh ein bisschen am Berg, ich hoffe jemand kann mir aus der Patsche helfen. Falls mein "Problem" keines ist, bitte ich schonmal um Entschuldigung. Als (bisher) reiner Software-Mensch bereitet mir die ganze FPGA-Geschichte einiges Kopfzerbrechen - und bis ein paar Wochen wusste ich nicht mal was VHDL ist. Ich hab ein Cyclone II Board mit 50Mhz, LEDs, SRAM, Flash und VGA-Out etc. Einige grundsätzliche Dinge (LEDs/LCD/7Segment ansteuern, VGA-Sync) hab ich unterdessen kapiert, mit Verilog komm ich auch einigermassen zurecht. Wo ich aber hänge ist beim SRAM resp. RAM allgemein. Unterdessen läuft auch meine erste 'CPU' (12Bit Adressen / 8Bit Daten)- die kann schon mal Speicherzellen lesen, schreiben, inkrementieren und JMPen. Die Daten holt er von einem normalen Single Port RAM (FGPA intern). Als "Debug-Out" benutze ich das Siebensegment-Display. Die Kommunikation RAM <-> CPU ist im Moment so gelöst, dass ich jeweils die Ram-Adresse, via Programm-Counter im CPU, setze, dann im nächsten Takt das Ram auslese, verarbeite und wieder die nächste Adresse setze. In wieweit dieser Ablauf überhaupt sinnvoll ist, kann ich (noch) nicht beurteilen. Auf jeden Fall funktioniert es soweit gut. Das (weit weit entfernte) "Endziel" ist ein kleiner Compi mit 16Bit CPU, ein paar KB ROM (FPGA-Intern), RAM (SRAM) und VGA-Ausgabe. Jetzt zum eigentlichen Problem: Ich möchte einen Teil des RAMs als Videospeicher benutzen und entsprechend über den VGA-Ausgang ausgeben. Für mich grosses, grundsätzliches Problem: Ich kann ja nicht im VGA-Modul wieder die RAM-Adresse setzen und auslesen, weil ja die CPU gerade von einer anderen Adresse liest oder schreibt. Ein Dual-Port Ram kann ich soweit ich weiss nicht verwenden, da ich eigentlich das normale SRAM (4Mbit) auf dem Board verwenden will, und nicht den FPGA-Internen Speicher (hat nur knapp 20Kbyte). Nach meiner Auffassung müsste ich jetzt den Bus 'teilen', dass jeweils abwechslungsweise CPU und VGA-Modul auf das Ram zugreifen können. Hier ist die absolute Blockade, ich hab keinen Dunst wie ich das grundsätzlich am besten angehen soll, und konnte bis jetzt auch nichts online finden (was nicht heisst dass es nicht existiert natürlich). Ich geh mal davon aus, dass ich im ganzen Aufbau einen schrecklichen/doofen Denkfehler drin habe. Aber wo? Hat jemand einen Denkanstoss/Lösungsansatz? Ach ja, ich benutze Quartus II / Verilog - wobei es mir nicht um den Code geht, sondern vor allem ums Verständnis. Vielen Dank schon mal - und sorry für den langen Post - ich hoffe jedoch meine Unklarheiten verständlich ausgedrückt zu haben :)
Damian schrieb: > Nach meiner Auffassung müsste ich jetzt den Bus 'teilen', dass jeweils > abwechslungsweise CPU und VGA-Modul auf das Ram zugreifen können. Du brauchst einen Verwalter, an den das RAM angebunden ist, und der vom VGA-Controller und von der CPU Speicheranfragen (lesen/schreiben) erhält. Und dann mußt du die Anfragen irgendwie priorisieren und ans RAM durchreichen. Du wirst sehen: allein die CPU war etwa 10% Arbeit, jetzt gehts erst richtig los... ;-)
@Damian da vllt mal ein Lösungsvorschlag den ich auch schon etwas länger verfolge, aber bisher noch nicht weiter umgesetzt habe (zumindest nicht in der Variante wie es mir vorschwebt) : Das ext. RAM wird von dem von Lothar erwähnten Verwalter angesprochen. Und zwar in der Form das du einerseits das Interface für deine CPU, andererseits aber das Interface für deine VGA-Grafik zur Verfügung stellst. Meine Idee ist dahingehend das der Verwalter auch tlw die VGA Generierung übernimmt. Und zwar in der Form das der VGA-Teil immer 4,8 oder 16 Pixel vorgesetzt bekommt, und der Verwalter in der Zwischenzeit einen oder mehrere Zugriffe der CPU übernimmt. Schematisch sieht das ganze etwa so aus : |---------|-------|----> t |8 pixel |1/2 Zug| |für VGA |riff fü| | |r CPU | Sprich, der Verwalter lässt deine CPU warten solange bis er ein 4,8,16 Pixel Paket eingelesen hat und die VGA-Grafik "ruhe" gibt und somit dann die CPU bedient werden kann. Das ganze macht deine CPU natürlich deutlich langsamer, aber es wäre ein Weg. Es gibt sicherlich noch einige andere Wege. Aber das wäre erstmal einer der denke ich halbwegs schnell umgesetzt werden kann. Aber ich als non-FPGA-Experte überlasse lieber denen das Wort die auch Ahnung davon haben. Im übrigen : Schönes Projekt. Habe mir selbst gerade erst meine erste 16bit CPU gebastelt. Habe auch schon VGA, allerdings nur Text, reicht auch erstmal, der 200'er Spartan macht schon dicke Backen :-)
Danke Lothar und Rene :) Ein paar Lichter sind aufgegangen! Aber so ganz hell ist es noch nicht... Folgende Ueberlegung: Ich beschränke meinen VGA-Output auf 1Bit - dann kann ich in einem "Rutsch" 8 Pixel (=8 Bit) aus dem Ram lesen. Wenn alle Komponenten mit 25Mhz laufen, muss somit der VGA-Teil während einem Takt lesend, die CPU während den nächsten 7 Takten lesend und schreibend auf das Ram zugreifen können. Den Priorität würd ich über ein "Bus Active" Signal vom Ram-Verwalter gegeben. Wenn Bus Active auf low geht, darf die CPU das Ram verwenden, sonst der VGA-Teil. Im Ram-Verwalter würd somit ein einfacher Counter von 0-7 bei jedem Takt hochgezählt. Bei Counter = 0 ist Bus Active High, sonst Bus Active Low. Würde sowas grundsätzlich Sinn machen? Oder wär umgekehrt (nicht ein "du darfst"-Signal vom Verwalter schicken, sondern ein "ich muss" vom Modul erhalten) besser?
Ich bin da zwar auch nicht sooo fit drin aber grundsätzlich würde ich erstmal sagen das das so klappt. Also das du für den Teil der Zeit (ich nenn es mal VGA-Zeit) die CPU pausierst, bzw Zugriffe auf den Speicher warten lässt und während der anderen 7 Takte die CPU laufen lässt. Du mußt dir nur überlegen (und da hakt es bei mir ab und an noch) das du mehr als 1 Takt für einen Lese/Schreibzugriff brauchst, bzw die Setup/Hold-zeit u.u. mehr als 1 Takt beträgt. Du musst ja auch beim wechseln zwischen Schreiben und Lesen den Datenbus erst inaktiv schalten bevor du ein Output Enable setzen kannst das das RAM die Daten ausspuckt. Da brauchst du mindestens schonmal einen Takt. Dumm ist dann nur wenn deine CPU schreiben will, und gerade wenn alles angelegt worden ist dann der VGA-Teil seinen Platz haben will. Daher mach ich das so das der Verwalter immer nur Zugriffe komplett macht und auch abgeschlossen hat, und somit der Verwalter das Grundlegende Timing bestimmt. Nur hat man dann andere Probleme ... Aber ich würde mal sagen ab hier ist Lothar eher der Ansprechpartner. So tief steck ich in VHDL auch nicht drin, bzw ich mach es mir immer etwas einfach und umschiffe Probleme meist durch Inkaufnahme mehrerer Takte. Bin also das was man nen Hobby-FPGA'ler nennt :-))
Warum murmle ich immer "Dieser Weg wird kein leicher sein" vor mich hin? Egal. Mein aktueller Stand (theoretisch erstmal, im praktischen happerts noch ein wenig): Wie gehabt möchte ich 7 Zyklen der CPU, einen dem VGA-Teil geben. Mein Board läuft mit 50Mhz, das SRam hat 20ns Zugriff. "VGAS": (VGA Sync) Ich teil den Takt auf 25Mhz und schreib jeweils ein Bit raus (Daten ab Buffer, siehe "VGA") - dieses Modul funktioniert auch schon. "VGA": Im Takt "E" wird die Ram-Adresse und Read gesetzt, im Takt "F" wird der Buffer mit 1 Byte gefüllt. "CPU": Setzt jeweils in den geraden Takten die Ram-Adresse und R/W, damit die Daten dann bei bei ungeraden Takten zur Verfügung stehen resp. geschrieben werden können - ausser im Takt E und F "ADS" = "Address Set" (+ R/W etc.) TAKT VGAS VGA CPU TAKT 0 VW0 ADS 1 CPU CPU1 2 VW1 ADS 3 CPU CPU2 4 VW2 ADS 5 CPU CPU3 6 VW3 ADS 7 CPU CPU4 8 VW4 ADS 9 CPU CPU5 A VW5 ADS B CPU CPU6 C VW6 ADS D CPU CPU7 E VW7 ADS F VGA VGA1 Somit hätte ich, in meiner Vorstellung zumindest, eine CPU, die mit 25/8*7 = ~22Mhz läuft, und könnte einen Ram-Bereich als VGA-Output (1Bit/Pixel) benutzen - super! Könnte das hinhauen oder bin ich wiedermal auf dem Holzweg? V.a. die Zugriffszeit auf das SRam (20ns).. könnte die zum Verhängnis werden?
Hallo, früher hatte ich selbe Problem. Ich habe T80 (Z80 Softcore) verwendet. Meine erste lösung war: Speicher lief mit 4-fache CPU-Frequenz. Das heisst, ich hatte mit jedem CPU-Takt zwei Speicherzugriffe. So hat es auch gut funktioniert. Dann habe ich meinen "Speicherkontroller" bisschen "intelligenter" gemacht: Z80 hat viele "Nicht-Speicherzugriff"-Zyklen (z.B. Refresh u.s.w.). In der Zeit holt mein Videokontroller die Daten aus dem Speicher. MfG aus Westerwald
um das Rad nicht neu erfinden zu müssen, bei Quartus II Web Edition steht unter den Megafunctions im Bereich Storage auch Dual Port RAM Controller zur Verfügung. Da der VGA Controller nur liest und Timinggenau sein muss und die CPU R/W Zugriffe machen muss aber ruhig mal warten kann gibt es da vielleicht schon eine schlüsselfertige Lösung. uC im FPGA mit VGA Controller ist schon dutzende Male gelöst worden und wird in den gängigen FPGA Tools als Bausteine für diverse Plattformen und Bitbreiten angeboten. Da meist "quelloffen" auch nett um das Verständnis zu fördern. Wenn mit Wishbone Interface auch sehr recyclefähig. Gruß, dasrotemopped.
Hi, fertige Lösungen sind natürlich Gold wert, aber nur was man selber gemacht hat kann man auch gut selber debuggen... Diese Zugriffssteuerung fürs RAM ist auch bekannt als Arbiter, oder Bus-Arbiter. Da gibt es sicherlich für verschiedene CPU-Busse auch schon fertige Lösungen. Es gibt wie du schon gemerkt hast auch viele Wege so eine Zugriffssteuerung umzusetzen. Du musst z.B. den Zugriff auch nicht mit einem festen zeitlichen Raster umsetzen, du könntest auch bei dem Arbiter mehrere Anforderungssignale definieren. Jeder Busteilnehmer kann dann über das Anforderungssignal den (Ram-)Bus anfordern und bekommt über ein Grant-Signal dann Bescheid, wenn er den Bus hat. Wenn der Bus nicht mehr benötigt wird, muss das Anforderungssignal natürlich wieder zurückgenommen werden. Solche Themen sollten sich über Google auch unter dem Thema "Handshaking" oder "Handshake" finden lassen. Allgemein für CPU-Design kannst du dir folgendes Buch durchlesen (von allem ein bisschen und auch recht tiefgehend): http://www.amazon.com/Computer-Architecture-Quantitative-Approach-4th/dp/0123704901 Vielleicht gibts da inzwischen auch ne neue Edition...
Vielen Dank für die vielen Inputs! Ich bin mal den einfachsten Weg gegangen - Fixe Zuordnung 3 Takte CPU - 1 Takt VGA - und es läuft! Mit 7 Takten CPU / 1 Takt VGA hängte sich das ganze noch auf, mit der Halbierung der Zugriffe klappt jetzt alles wunderbar. Jetzt hab ich mal die Basis, um meine CPU mit Befehlen zu erweitern und auch einfache Grafiken darzustellen. Im nächsten Schritt folgt dann die Umschaltung vom internen FPGA-Ram auf den SRAM-Baustein und benutzung des FGPA-Rams als ROM-Bereich. Vielen Dank nochmals für die Wegweisung :) Sobald ich was einigermassen zeigbares zusammen habe, werd ich es hier posten.
>Im nächsten Schritt folgt dann die Umschaltung vom internen FPGA-Ram auf >den SRAM-Baustein und benutzung des FGPA-Rams als ROM-Bereich. Soweit bin ich mit meinem Design auch gerade. Aber der Bootloader zickt noch rum und ich habe gerade keine Ahnung wo der Fehler sein könnte. Na ja. Aufgeschoben ist nicht aufgehoben. Evtl poste ich mein Design hier auch. Vor allem weils so schön auf ein Spartan 3 200 Board passt :-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.