Forum: FPGA, VHDL & Co. Zähler aus zwei Clock-Quellen speisen


von Frank B. (frank_b) Benutzerseite


Lesenswert?

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

von Rick Dangerus (Gast)


Lesenswert?

Wo soll der Takt für 2. herkommen?

Rick

von Frank B. (frank_b) Benutzerseite


Lesenswert?

Ich hatte die Idee, ihn vom  AVR per Pin-toggle erzeugen zu lassen.

von Rick Dangerus (Gast)


Lesenswert?

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

von Holger (Gast)


Lesenswert?

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.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

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.

von Frank B. (frank_b) Benutzerseite


Lesenswert?

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

von Joerg W. (joergwolfram)


Lesenswert?

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

von Frank B. (frank_b) Benutzerseite


Lesenswert?

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 !

von Karl (Gast)


Lesenswert?

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!

von Falk B. (falk)


Lesenswert?


von Frank B. (frank_b) Benutzerseite


Lesenswert?

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

von Frank B. (frank_b) Benutzerseite


Lesenswert?

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

von Frank B. (frank_b) Benutzerseite


Lesenswert?

Im Anhang mal mein aktueller Code ...
Ist nicht besonders lang :-)

lg, Frank

von Frank B. (frank_b) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hat nicht geklappt. Hier ist er nun aber :-)

lg, Frank

von Karl (Gast)


Lesenswert?

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;

von Frank B. (frank_b) Benutzerseite


Lesenswert?

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

von Karl (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.