Hallo Gemeinde, bin VHDL-Anfänger, und habe mir nach dem obligatorischen Blinker nun etwas -für mich - kompliziertes ausgesucht. Ich möchte einem xc9572 folgendes beibringen: 1) Daten mit hoher Geschwindigkeit (>50MHZ) von einem AD-Wandler lesen und in einem SRAM speichern. 2) Wenn das SRAM voll ist, die Daten langsam, also mit einem eigenem Clock-Eingang , an einen AVR ausgeben. Meine Hauptproblem bei der Geschichte ist nun der Adresszähler des SRAM. Diesen muss ich ja bei meinem Ansatz - je nachdem ob ich grade Daten ins RAM schreibe oder auslese mit unterschiedlicher Geschwindigkeit - oder besser gesagt mit verschiedenen Clocks - takten. Ich muss also irgendwie eine Art Clock-Select( bzw. 2x Clock-Enable) für den Zähler machen, richtig ? Nebenbei muss auch CE und OE des SRAMs passend geschaltet werden. Nach vielen Experimenten habe ich nun das Handtuch geworfen. Kurz: WIE GEHT DAS, verdammt nochmal ;-) Hat jemand ein Code-Beispiel ? ps: Bin auch für gänzlich andere Lösungsansätze offen :-) Ich habe auch mit zwei Zählern und output-enable experementiert, aber das braucht so viel Logik, dass es nicht mehr in den CPLD passt. lg, Frank
Ok. Dann mach doch erstmal ein paar kleinere Probleme draus: 1. beliebige Konstante per SPI vom AVR einlesen und vom CPLD ausgeben 2. den ADC auslesen und Wert statt der Konstante verwenden 3. statt der Konstante/dem ADC eine SRAM-Zelle auslesen 4. kompletten SRAM einlesen (da sollten zufällige Werte kommen) 5. den ADC-Wert ins SRAM schreiben (und den Adresszähler erhöhen) Jeden dieser Schritte solltest Du auch gut mit einer Testbench nachvollziehen können. Rick
http://www.discovercircuits.com/C/comp-interf9.htm Die erste Schaltung mit dem Dual Ported RAM .. Da sind auch Interfaces für dein Problem drin . bis unten Threads durchlesen. CPLD -RAM von XECESS mit VIRTEX (Uni Projekte) Notfalls nimst du 2 XC95XX Bausteine. (1 als ADDR-Counter + Log) (2ter als Bidir 245 I/O) Gruss Holger.
Fuer Schaltungen mit verchiedenen Taktdomainen sind an der Schnittstelle FIFO sehr hilfreich. Verwende doch statt des XC95XL einen kleinen XC3SE. Da hast Du viel mehr Moeglichkeiten.
Hallo Gemeinde, danke für die Tips. Mir ist vorhin ein Gedanke gekommen. Da der vom AVR kommende Takt ja eine halbe Größenordnung niedriger als die 50 Mhz ist, gibt es wohl eine überraschend einfache Lösung. Ein Multiplexer für das Taksignal des Adresszählers.
1 | process (clock,cpu_clk) begin |
2 | if rising_edge(clock) then |
3 | if STATE = WRITE_RAM then |
4 | clk_int <= clock; |
5 | else
|
6 | clk_int <= cpu_clk; |
7 | end if; |
8 | end if; |
9 | end process; |
10 | |
11 | process (clk_int, reset,STATE,adr) begin |
12 | if reset = '1' or STATE=RESET_ADR then |
13 | adr <= (others => '0'); |
14 | elsif rising_edge(clk_int) then |
15 | adr <= adr + 1; |
16 | end if; |
17 | |
18 | ram_adr <= adr; |
19 | |
20 | end process; |
STATE kommt von einer Statusmaschine die den groben Ablauf steuert, clock das 50 Mhz-Takt, cpu_clk der vom AVR kommende Takt, clk_int der aus dem Multiplexer kommende Takt der dann vom Adresszähler benutzt wird. Ram_adr ist der Ausgabeport. "cpu_clk" wird also mit clock synchronisiert. Das erzeugt ein wenig Jitter, das ist aber egal, denke ich. Cpu_clk wird nicht höher als 1 Mhz werden, nehme ich an. Die Daten gebe ich später dann 8-Bit parallel mit der cpu_clk an den AVR weiter. Im Modelsim scheint der Kram zu funktionieren, leider habe ich noch keine Hardware um das ganze wirklich testen zu können. Kann das so funktionieren, oder seht Ihr VHDL-Spezialisten da Fallstricke ? Dann habe ich noch eine Frage zum SRAM. Ich werde ein 61256 benutzen, kann ich da WE einfach die Ganze Zeit bis das Ram voll ist, auf 1 lassen ? lg, Frank
1. So wie Du das machen willst geht das nicht, da Du clock mit seiner eigenen steigenden Flanke abtastest. Besser ist ein einfacher Multiplexer:
1 | process (clock,cpu_clk) begin |
2 | if STATE = WRITE_RAM then |
3 | clk_int <= clock; |
4 | else
|
5 | clk_int <= cpu_clk; |
6 | end if; |
7 | end process; |
Beim Umschalten kann zwar ein zusätzlicher Impuls erzeugt werden, aber Du kannst ja den Adresszähler auch erst nach dem Umschalten resetten. 2. WE kann nicht ständig an Masse bleiben, soweit ich mich erinnere werden mit der Fallenden Flanke die Adresse und mit der steigenden Flanke die Daten übernommen. Gruß Jörg
Hallo Jörg der zusätzliche Impuls stört nicht. Deine Lösung ist sogar noch einfacher, vielen Dank ! Hm, Deine Erklärung zu WE macht auch Sinn, aus dem Timingdiagramm im Datenblatt wird das nicht so deutlich, aber "es passt". Danke sehr !
Das ist schlechter Stil und sollte spätestens bei der Synthese eine Warnung geben, weil Logik im Takt erzeugt wird. Sowas sollte man sich nicht angewöhnen. Besser über eine FSM (die ja schon angedeutet ist) lösen!
Ja, es gibt eine Warnung, ich dachte man könne sie Ignorieren. Wie gesagt, ich finde keine bessere Lösung... wie würde Ihr das denn konkret Lösen ? Wie ich das in der (schon vorhandenen) FSM abhandeln könnte, kann ich mir momentan nicht vorstellen... Oder eine eigene FSM ? wie sähe das aus ? Ich stehe echt auf dem Schlauch... lg, Frank
Noch eine Info: Die Umschaltung zwischen den Taktquellen findet nur kurz nach dem Reset statt, der erste Takt vom AVR kommt erst lange nach dem Reset. lg, Frank
Im Anhang mal mein aktueller Code ... Ist nicht besonders lang :-) lg, Frank
Ich hab mein letztes VHDL schon vor einiger Zeit geschrieben, daher bitte ich Fehler zu verzeihen. Die Idee solle aber klar sein. Es gibt hier einige Artikel zum Thema VHDL, z.B. VHDL Flankenerkennung. Schau da mal rein. Außerdem lies bitte ein Buch zum Thema. Deine sensitivity lists sind zum Teil grausam. Bei Hardwarebeschreibung geht es nicht nur darum, VHDL hacken zu können, es geht viel mehr um das Design an sich. Und dafür gibt es relativ strikte Design-Rules
1 | process (clk50) |
2 | begin
|
3 | if rising_edge(clk50) then |
4 | strobe_old <= strobe; |
5 | if (strobe_old = '0' and strobe = '1') or state = write_ram then |
6 | adr <= adr + 1; |
7 | end if; |
8 | end if; |
9 | end process; |
Hallo Karl, vielen Dank für Deine Idee mit dem Strobe, sie hat mir wirklich weitergeholfen. Zu den Sensivity-Lists: Du hast bestimmt recht :-) Ich komme halt aus der Software-Ecke und muss mich erst noch besser in das ganze Hineindenken. Aber grade deswegen vielen Dank für den Hinweis. Habe auch den Trigger nun anders realisiert und benötige weniger Logikzellen. Na dann kann ich ja jetzt ans Routen und an das AVR-Programm gehen. lg, Frank
Schön, so etwas zu lesen. Der Wink war auch nicht böse gemeint, nur ein gut gemeinter Rat. Eine gewisse Eigeninitiative freut mich besonders. Weiter so!
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.