Hallo
Ich habe da mal eine Frage bezüglich der 62xxx Ram's (Genau 628512)
Ich möchte ohne µC Daten speichern und wieder abspielen.
nur der ablauf der WE & OE ist mir etwas unklaar
Das Datenblatt sagt
CS WE OE
H X X Deselected High-Z Standby
L H H Output Disabled High-Z Active
L H L Read Data Out Active
L L X Write Data In Active
Also WE auf L Schreiben WE H OE L Lesen.
Nun die unklaarheit ich lege Daten und Adresse an und muss dann einmal
WE L und wieder H setzen ? damits abgespeichert ist?
oder WE L Lassen daten anlegen und die Adresse weiterzählen?
Beispiel ich habe meinen Zähler 4040 dieser zählt die Adressen. Nur wo
schließe ich WE an ? an den Takt?
Liebe grüße
Steve N schrieb:> oder WE L Lassen daten anlegen und die Adresse weiterzählen?
Keine gute Idee. Die Adressleitungen werden nicht präzise und exakt zum
gleichen Zeitpunkt ihren Zustand ändern, sondern unterschiedlich lange
dafür brauchen. Damit wird also während des "Weiterzählens" nicht nur
die ursprüngliche und die Folgeadresse anliegen, sondern auch noch
irgendwas anderes. Das wird zwar nur kurzzeitig der Fall sein, aber das
wird ausreichen, um auch Speicherbereiche zu überschreiben, die Du nicht
überschreiben willst.
Also:
/WE erst dann aktivieren, wenn Adressen & Daten stabil anstehen. Dann
/WE wieder deaktivieren, und erst danach Adressen und Daten verändern.
> Beispiel ich habe meinen Zähler 4040 dieser zählt die Adressen. Nur wo> schließe ich WE an ? an den Takt?
Kann man so machen.
Der 4040 ist übrigens ein Ripple-Counter, d. h. während der Einstellzeit
liegen seine Ausgänge auf undefinierten Pegeln.
Der Einsatz von Monoflops, die die Reihenfolge der Signale exakt
einzuhalten helfen, ist angebracht.
Habe in meiner Jugend einen Temperaturlogger nur mit einem parallelen
AD-Wandler, CMOS Logik Bausteinen und einem Zeropower RAM aufgebaut. Die
über mehrere Tage gesammelten Temperaturwerte wurden dann via LPT-Port
zum DOS-PC übertragen.
Heute macht man sowas mit einem Raspberry Model B.
Raspberry gut und schön. Nur möchte ich einfach mal ohne Prozessoren &
co was bauen um das besser zu verstehen :)
Ripple-Counter Na toll da fängt es doch schon an. Ich habe versucht über
den Letzen Bit vom Counter einen Flipflop zu schalten und mich gewundert
warum das zu fehlern führt.
Wie kann es sein das ich Problemlos zwei 4040 hintereinander schalten
kann?
Genau wie du möchte ich einen Temp & Spannungslogger bauen.
Die Idee einen 555 als Taktgeber, Dann den den Zähler für die Ram
Adressen, Temp und Spannung jeweils einen ADC und ins Ram.
Für meinen Flashplayer habe ich damals 8 bit Synchronzähler genommen:
http://www.schoeldgen.de/images/flashplayer.jpg
Ich befürchte nur, das es den 74AS867 nicht mehr ohne weiteres gibt.
Allerdings sind 4-bit Zähler gang und gäbe, du brauchst bloss doppelt so
viele.
Wenn du noch einen alten Z80 rumliegen hast, könntest du den als
Adresszähler nehmen, indem du an seine Datenleitungen hart ein NOP
codierst. Er wird an den Adressleitungen brav hochzählen.
Matthias Sch. schrieb:> Ich befürchte nur, das es den 74AS867 nicht mehr ohne weiteres gibt.> Allerdings sind 4-bit Zähler gang und gäbe, du brauchst bloss doppelt so> viele.
Den '590 gibts auch noch.
> Wenn du noch einen alten Z80 rumliegen hast, könntest du den als> Adresszähler nehmen, indem du an seine Datenleitungen hart ein NOP> codierst. Er wird an den Adressleitungen brav hochzählen.
Nette Idee. Für passende WE/OE Signale sorgt er auch noch.
Steve N schrieb:> Wie kann es sein das ich Problemlos zwei 4040 hintereinander schalten> kann?
Es ist kein Problem, beliebig viele 4040er hintereinander zu schalten,
macht der intern ja auch nicht anders. Es ist nur ein Problem, mit all
den schönen Ausgängen etwas anzufangen ohne lange genug zu warten bis
sie bis zum letzten Ausgang durchgerippelt haben.
Wenn du also 4040er als Adresszähler verwenden willst, dann warte nach
dem Takt so lange bis der stabile Zustand erreicht ist und aktiviere
erst dann WE.
Steve N schrieb:> ich lege Daten und Adresse an und muss dann einmal> WE L und wieder H setzen ? damits abgespeichert ist?
Ja.
> Beispiel ich habe meinen Zähler 4040 dieser zählt die Adressen. Nur wo> schließe ich WE an ? an den Takt?
An einen Impuls der inmitten des Takts kommt, damit Adressen (und Daten)
vorher stabil sind und nachher stabil bleiben.
Was ist an set-up und hold times im Datenblatt so schwer zu verstehen?
Ja, du musst das passende Signal erst mal mjt Aufwand erzeugen.
...ich hänge mich mal hier rein, da ich so ein ähnliches Problem habe:
Ich habe ein externes Schreibsignal, nennen wir es mal IOWR (I/O Write).
(Jaja, immer noch 8086...)
Momentan setzte ich ich den MW-Pin am SRAM händisch per AVR:
H-L-H und das verbraucht bei 20Mhz knapp 200ns (4x50ns, eher mehr). Laut
Datenblatt brauche ich aber nur >55ns (twp).
Kennt jemand eine Schaltung (oder einen Namen dafür, Tante Google kenne
ich), die mir auf eine H-L Flanke ein kurzes H-L-H -Signal (55...100ns)
generiert?
Theoretisch könnte der TO auch diese Schaltung nutzen um aus dem
Taktsignal das WE-Signal zu erzeugen. (Solange eine halbe Periode des
Taktes größer als 55ns ist...ich denke mal 100ns = Periode 200ns =5 Mhz)
Mirko
MirkoB schrieb:> Kennt jemand eine Schaltung (oder einen Namen dafür, Tante Google kenne> ich), die mir auf eine H-L Flanke ein kurzes H-L-H -Signal (55...100ns)> generiert?
Das wäre ein Monoflop. So etwas kann mit einem 74xx123 aufgebaut werden,
als zeitbestimmender Kondensator sind nur wenige pF erforderlich.
Allerdings: Wozu? Du steuerst ein SRAM mit einem AVR anscheinend von
Hand an -- AVRs aber haben auch ein Speicherinterface und können das
selber machen, und das geht dann komplett ohne Monoflops und ist
Größenordnungen schneller als der handgedengelte Speicherzugriff, weil
auf der Softwareseite das genauso wie das interne RAM angesprochen
werden kann.
A. K. schrieb:> Für passende WE/OE Signale sorgt er auch noch.
Hehehe, leider lässt er ja sein eigenes WR inaktiv,beim NOP ist ja nix
zu tun - aber RD liefert mit ein bisschen verodern dann das geeignete WE
und ein CS.
MaWin schrieb:>> Beispiel ich habe meinen Zähler 4040 dieser zählt die Adressen. Nur wo>> schließe ich WE an ? an den Takt?>> An einen Impuls der inmitten des Takts kommt, damit Adressen (und Daten)> vorher stabil sind und nachher stabil bleiben.> Was ist an set-up und hold times im Datenblatt so schwer zu verstehen?> Ja, du musst das passende Signal erst mal mjt Aufwand erzeugen.
Geht auch mit zwei 4040:
Diese kaskadieren, den /WE aus Q0 erzeugen, /CS auf low hängen, die
Adressen sind dann Q1...
Damit kommen erst die Adressen, /WE wird gleich low und die Daten werden
normalerweise mit der steigenden Flanke dann übernommen, danach rippeln
die anderen Adressen. Sollte mit den Th auch passen. Muss man nur am
4040 die doppelte Frequenz machen.
rgds
Steve N schrieb:> Genau wie du möchte ich einen Temp & Spannungslogger bauen.
Die RAM-Adressierung ist aber nur ein ganz kleiner Teil der gesamten
Ablaufsteuerung.
Du willst ja die Aufzeichnung zu einer bestimmten Zeit beginnen, beenden
und irgendwo hin in eine bestimmten Format über ein bestimmtes Protokoll
ausgeben.
Ohne MC wird das ein ganz schönes IC-Grab und völlig unflexibel bist Du
obendrein.
old man schrieb:> Heute macht man sowas mit einem Raspberry Model B.
Wäre mir 1000-fach oversized, aber eine MC-Lösung ist schon der
sinnvolle Weg.
Rufus Τ. Firefly schrieb:> Das wäre ein Monoflop. So etwas kann mit einem 74xx123 aufgebaut werden,> als zeitbestimmender Kondensator sind nur wenige pF erforderlich.
Vielen Dank! Monoflop und 74xx123 war das Suchwort. Im Datenblatt (NXP)
steht ja alles dazu drin.
Rufus Τ. Firefly schrieb:> Allerdings: Wozu? Du steuerst ein SRAM mit einem AVR anscheinend von> Hand an -- AVRs aber haben auch ein Speicherinterface und können das
Das das wozu: 8086 auf AVR emuliert mit externem ISA-Bus.
Das Projekt ist zu groß um es in diesem Beitrag komplett zu beschreiben,
aber vielleicht wirds mal einen Artikel im Wiki geben.
Aktueller Stand ist der, dass ein paar x86 Befehle bereits
funktionieren. (Hauptsächlich NOP und JMP zum testen... :) )
Register, Pointer ect. sind breits implementiert und die Berechnung der
(realen) Speicherzelle aus Offset und Segment scheint auch zu gehen.
Der Bus ist bei mir gemultiplext. 24 Adressleitungen (4 Reserve für 286)
+ 16 Datenleitungen
Alles klassisch mit 2x 74HCT245 für die Daten , 3x 74HCT573 für die
Adressen und 1x 74HCT573 für die Bussteuersignale. (MR MWR IOR /
IOWR + andere - Soll im Vollausbau einen kompletten 16 Bit ISA-Bus
ergeben)
Belegt momentan am AVR 2 Ports für den Bus + Pins für die Ansteuerung.
(=20..22 I/Os habe es gerade nicht hier)
Bisher habe ich die Signale für den SRAM händisch am AVR erzeugt, was
aber eigentlich Quatsch ist, da ich ja bereits mit MWR bzw. MR einen
Schreib oder Lesewunsch geäußert habe. Mit meiner händischen Ansteuerung
erreiche ich ca. 300...600 kB/s je nach Schreib/Lesestrategie.
Grund ist der, dass mir die I/O Pins am AVR ausgehen und ich allerdings
noch ein paar für die serielle Schnittstelle /SD-Card und
Interruptsteuerung benötige....
Mirko
Matthias Sch. schrieb:> Hehehe, leider lässt er ja sein eigenes WR inaktiv,beim NOP ist ja nix> zu tun - aber RD liefert mit ein bisschen verodern dann das geeignete WE> und ein CS.
Eben.
Wenn man den so aufgebauten "Zähler" anhalten will, dann kann man dafür
möglicherweise den HALT Opcode an Stelle des NOPs verwenden. Der HALT
Befehl bleibt nämlich nicht einfach stehen, sondern führt eine stete
Folge von M1 Zugriffen auf ebendiesen HALT Opcode durch. Also quasi ein
NOP ohne PC-Inkrementierung. Ich weiss nur grad nicht, ob man da wieder
rauskommt indem man wieder einen NOP draus macht, oder ob man dafür doch
die Interrupt-Leitung braucht.
A. K. schrieb im Beitrag #3164715:
> Das sieht dann vom Timing her genauso aus wie beim> NOP, nur tritt er auf der Stelle.
Gute Idee, ich weiss nicht genau, ob der Zilog Z80 'fully static' ist
(die TMPZs von Toshiba waren das), dann könnte man ihm auch den Takt
abklemmen. HLT wäre 0x76, NOP ist 0x00. Einen Reset Pin hat er auch -
alles was der Siedler braucht, und eine Single-Chip Lösung.
Matthias Sch. schrieb:> Gute Idee, ich weiss nicht genau, ob der Zilog Z80 'fully static' ist
Ist er. "Although static by design, testing guarantees ...".
MirkoB schrieb:> Momentan setzte ich ich den MW-Pin am SRAM händisch per AVR:> H-L-H und das verbraucht bei 20Mhz knapp 200ns (4x50ns, eher mehr). Laut> Datenblatt brauche ich aber nur >55ns (twp).
Ein OUT Befehl benötigt nur 1 Takt. Wenn man also die Daten im Register
schon parat hat, dann kommt man auf 50ns runter. Mit CBI/SBI Befehlen
kommt man auf 100ns.
A. K. schrieb:> Ein OUT Befehl benötigt nur 1 Takt. Wenn man also die Daten im Register> schon parat hat, dann kommt man auf 50ns runter. Mit CBI/SBI Befehlen> kommt man auf 100ns.
Ich zitiere mal aus dem Quellcode: (Funktion RAM mit NOP-90h füllen)
----
LDI temp4,$90
OUT PortA,temp4 ;Ausgabe D08-D16 auf PortA
OUT PortC,temp4 ;Ausgabe D00-D07 auf PortC
CBI DDE ;Daten liegen auf Datenbus an
NOP
NOP
CBI MWC ;2 Takte
NOP ;Zeit für PortBx -> PinBx (CBI 2 Takte)
NOP ;Schreibimpuls liegt
NOP ;auf low für 100ns
SBI MWC
SBI DDE ;Datenlatch Tristate
SBI ALE ;Adresslatch Tristate
----
Ich sehe hier mit den OUT Befehlen keine Optimierungsmöglichkeit. Ich
muss ja die zu schreibenden Daten auch erst in das Register bekommen,
was auch mind. 1 Takt dauert... Nach kurzen Rechnen sind es 2+3+2 = 7
Takte = 350 ns
An der Stelle komme ich erstmal nicht weiter. Ich möchte also alle
Bussignale wie oben auf einen 74x573 geben und den einmalig triggern.
Aus Bussignalen generiere ich dann die restlichen Signale.
(Datenrichtung 74x245, Ausgang Adressbuss, etc.).
Mir fehlt eben nur der Gedankenanstoß um aus dem Schreibsignal (xWR)
einen kurzen Sdchreibimpuls für WR zu generieren.
Ich weiß, dass es CLPDs gibt, aber ich will die evtl. Nachbauschwelle
nicht zu hoch legen. :)
Mirko
PS: Das ist ein Wochenende-Schlechtwetter-Feierabendprojekt...es kann
sich also noch viele Monde hinziehen. :)
MirkoB schrieb:> Ich zitiere mal aus dem Quellcode: (Funktion RAM mit NOP-90h füllen)
Die Daten müssen nicht schon ewig vorher anliegen. 25ns vor WR 0=>1
reicht aus. Die NOPs vor WE 1=>0 sind somit überflüssig.
WE 1=>0 zu 0=>1 muss bim 55ns Typ mindestens 40ns betragen. Das ist ein
Takt. Bei CBI/WBI direkt hinter einander sind es bereits 100ns. Auch
hier sind die NOPs überflüssig.
Eine Funktion, die den ganzen Speicher mit 0x90 füllt, kann also im Kern
so aussehen:
Vorbedingungen:
- 0x90 auf DatenPorts legen
- rB und rC passend vorbereiten
out addrPortL, rA ;1 Takt, unteres Adressbyte
inc rA ;1 Takt
out ctrlPort, rB ;1 Takt, WE 1=>0
out ctrlPort, rC ;1 Takt, WE 0=>1
out addrPortL, rA ;1 Takt
inc rA ;1 Takt
out ctrlPort, rB ;1 Takt, WE 1=>0
out ctrlPort, rC ;1 Takt, WE 0=>1
... n-mal unrolling ...
> Ich sehe hier mit den OUT Befehlen keine Optimierungsmöglichkeit. Ich> muss ja die zu schreibenden Daten auch erst in das Register bekommen,> was auch mind. 1 Takt dauert... Nach kurzen Rechnen sind es 2+3+2 = 7> Takte = 350 ns
Ich komme auf 4,x Takte = etwas über 100ns pro Schreibvorgang. Lesen ist
etwas komplizierter, aber OUTs überholen sich nicht.
Ich gebe zu, dass mein momentaner Stand seeeehr viel
Optimierungspotential hat. Grundsätzlich ging es mir bei dem obrigen
Stand auch nur um die ersten Tests für die Umsetzbarkeit des Projektes.
Die 90h-Funktion ist ein Copy&Paste aus der normalen Schreibfunktion,
nur festkodiert ohne Optimierung. NochmalNachgewühlt
---
WriteRAM:
ldi temp1,$FF ;DDRA -> Alle auf Ausgang
out DDRA,temp1
ldi temp1,$FF ;DDRC -> Alle auf Ausgang
out DDRC,temp1
SBI MWC ;Memory Write auf Highpegel
SBI ALE ;Adresslatch Tristate
SBI ALL ;Adresslatch A00-A15 auf
SBI ALH ;Adresslatch A16-A19 auf
SBI MWC
LDS temp1, Adr0 ;Schreibadresse -> Arbeitsregister
LDS temp2, Adr1
LDS temp3, Adr2
OUT PortC,temp3 ;Ausgabe A16-19 auf PortC
CBI ALH ;Adresslatch verriegeln
OUT PortA,temp2 ;Ausgabe A08-A16 auf PortA
OUT PortC,temp1 ;Ausgabe A00-A07 auf PortC
CBI ALL ;Adresslatch verriegeln
CBI ALE ;Adressen liegen auf Adressbus an
SBI DDR ;Datenlatch CPU -> Speicher
LDS temp1, DataL ;Daten -> Arbeitsregister
LDS temp2, DataH
OUT PortA,temp2 ;Ausgabe D08-D16 auf PortA
OUT PortC,temp1 ;Ausgabe D00-D07 auf PortC
CBI DDE ;Daten liegen auf Datenbus an
CBI MWC ;Schreibimpuls auf
NOP
SBI MWC ;fallende Flanke
SBI DDE ;Datenlatch Tristate
SBI ALE ;Adresslatch Tristate
ret
---
Ein NOP zwischen CBI MWC und SBI MWC war notwendig, da die Zeit (>45ns
lt Datenblatt) ohne das NOP zu kurz war.
In meinem neuen Layout liegen sämtliche Steuersignale jetzt auf einem
Latch. Dieser wird ganz oben ebenfalls über LDI temp4,BusCtrl geladen
und ebenso rausgeschrieben.
Im Prinzip soll dann per SBI BLE (BusLatchEnable) dieser die restlichen
Signale (ALE, DT/R, DEN, INTA sowie MR, MWC, IOR, IOWC) ausgeben.
Problematisch bei dem Layout ist, dass es nicht möglich ist das WRC
zeitverzögert zu erzeigen, da der "Bus Controller"-Latch an Port A
hängt, dort aber die Daten zum schreiben anliegen. Das MWC muss also
zeitverzögert als Impuls eigenständig erzeugt werden.
Alle Bussignale direkt am ATMega zu erzeugen ist auch eine Lösung, aber
mir gehen beim 1284 langsam die Pins aus... und die "großen" laufen nur
mit 16 Mhz.
Wie gesagt, dass ist ein reines Hobbyprojekt und wie man im Forum lesen
kann, gärt das auch schon länger als ein Jahr.
(Und ich freue mich schon wie eine Schneeprinzessin, dass interne
Register/Segmentnachbildung sowie die 6-Byte Pipline des 8086
funktioniert... :) Achja...und ins BIOS springt er auch schon)
I/O Schreibzugriffe auf Massenspeicher sollen intern auf eine SD-Card
(per SPI) umgeleitet werden. Die Textausgabe soll ebenfalls als VT100
Terminal über die serielle Schnittstelle realisiert werden.
(Momentan läuft hierrüber die Debug-Ausgabe) Mir bleiben also an PortB 4
Pins und an PortD 6 Pins übrig.
Ein paar für Tastatur sowie Interrupt-Eingang werden auch noch
benötigt...
Also noch viel Arbeit.
Mirko
MirkoB schrieb:> Ein NOP zwischen CBI MWC und SBI MWC war notwendig, da die Zeit (>45ns> lt Datenblatt) ohne das NOP zu kurz war.
Das finde ich interessant, denn zwischen den Aktionen durch CBI und SBI
liegen doch bereits 2 Takte, also 100ns bei 20MHz.
A. K. schrieb:> Das finde ich interessant, denn zwischen den Aktionen durch CBI und SBI> liegen doch bereits 2 Takte, also 100ns bei 20MHz.
Ich habe im Debugger folgendes im Einzelschrit ausgeführt.
Pfeil stand auf dem ersten Befehl, Cycle Counter reset
CC Befehl PORTB PINB
0 CBI MWC 1 1
2 NOP 0 1
3 SBI MWC 0 0
5 NOP 1 0
6 NOP 1 1
0 CBI MWC 1 1
2 SBI MWC 0 1
4 NOP 1 0
5 NOP 1 1
Also dürften am Pin selbst ohne NOP nur 50ns der Impuls anliegen.
Offenbar ist das bei meiner Lochraster-Fädeldraht-Variante eher
suboptimal.
Mirko
MirkoB schrieb:> 0 CBI MWC 1 1> 2 NOP 0 1> 3 SBI MWC 0 0> 5 NOP 1 0> Also dürften am Pin selbst ohne NOP nur 50ns der Impuls anliegen.
Bei mir ist 5-2 immer noch 3, also mit NOP 150ns und ohne 100ns. Du
musst die Taktzyklen zählen, nicht die Befehle.
A. K. schrieb:> Bei mir ist 5-2 immer noch 3, also mit NOP 150ns und ohne 100ns. Du> musst die Taktzyklen zählen, nicht die Befehle.
Du hast Recht.
Ich habe mir mal schnell was zurecht gesteckt und mit dem Oszi
nachgesehen:
CBI und SBI hintereinander erzeugen einen 100ns Impuls bei 20Mhz. Mit
NOP 150ns.
Trotz alle dem gehen mir die I/O Pins am AVR aus...vielleicht kann ich
aber was über einen 74x959 am Hardware SPI tricksen. 8 Bit sind 16
Takte.
Ist vielleicht doch eine Überlegung wert...
Mirko