Wenn man in einem Befehl die Daten und Signale an den Ports anlegt und gleich im nächsten Befehl die Werte vom RAM einlesen möchte funktioniert das nicht, das die Zugriffszeit der RAMs (1 Befehl = 4 Takte = 50 ns < 55 ns Zugriffszeit Ram) unterschritten wird. Im der folgenden Testsequenz (suchen eines Wertes im eRam) habe ich an der entsprechenden Stelle zuerst ein nop eingefügt damit es funktioniert. Jetzt ist dieser Befehl auskommentiert, da ich einfach eine andere notwendige Operation eingeschoben hab, aber man sollte das im Hinterkopf behalten.
Quellen hab ich angehängt, enthalten ist noch eine Routine, welche einen wählbaren rRAM-Bereich mit einem Wert füllt. Das ganze luft in einer Cog und wird zu Testzwecken über einen kleinen Spin-Kommandozeileninterpreter gesteuert. Zum Testen einfach mal im gestarteten Interpreter folgende Sequenz eingeben:
Code: Alles auswählen
start - startet den code in der cog
run 1 - led an (um mal zu testen ob die cog läuft :)
run 2 - led aus
- bereiche füllen
ph 1 0 ffff 1 0 - parameter setzen
pv - parameter anzeigen
run 3 - füllt ffff bytes b adresse 0 mit 01 in bank 1
ed - anzeige ram ab 0
run 3 0 ff 1 0 - kommando mit parametern
run 3 - setzt kommando bei nächsten block fort
usw.
Code: Alles auswählen
cmd4 'parameter einlesen -----------------------------------------------
mov A, PAR 'adresse der parameter nach reg-a
add A, #4
rdlong P1, A 'P1 := startadresse
add A, #4
rdlong P2, A 'P2 := anzahl der bytes
add A, #4
rdlong P3, A 'P3 := testwert
and P3, M_DAT 'testwert maskieren
add A, #4
rdlong P4, A '0 - bank 1; 1 - bank 2
'bus umschalten ---------------------------------------------------
mov OUTA, M_INAKTIV 'bussignale inaktiv setzen
mov DIRA, DIR_IN 'bus auf eingabe setzen
'bank auswählen ----------------------------------------------------
mov C, M_R2RD 'bank 2 auswählen
cmp P4, #1 wz 'bank 1 oder 2?
if_z jmp #cmd4_a '
mov C, M_R1RD 'bank 1 auswählen
cmd4_a
'hwt-adr latchen --------------------------------------------------
mov A, P1 'adresse holen
shr A, #3 'adr-hwt zurechtschieben
and A, M_LATCH 'latchbits ausmaskieren
mov B, A 'copy a --> b
or A, M_AL 'A bussignale zufügen (al aktiv)
mov OUTA, A 'wert latchen
'nop 'zeit für latch
or B, M_INAKTIV 'B bussignale zufügen (al inaktiv)
mov OUTA, B 'strobe für latch abschalten
'nwt-adr schreiben wert lesen---------------------------------------
' direkt aufeinanderfolgend selektieren und auslesen überschreitet
' die zugriffsgeschwindigkeit für den ram
' 1 befehl = 4 takte = 50 ns < 55 ns zugriffszeit ram
' also muß zwischen adresse anlegen und daten auslesen ein befehl
' eingeschoben werden
mov A, P1 'adresse holen
shl A, #8 'adr-nwt zurechtschieben
and A, M_ADR 'adressbits ausmaskieren
mov B, A 'copy a --> b
or A, C 'A bussignale zufügen (ram1/2 read)
mov OUTA, A 'wert ausgeben
'nop 'zeit für ram
or B, M_INAKTIV 'B bussignale zufügen (inaktiv)
mov D, INA 'daten einlesen
and D, M_DAT 'daten maskieren
mov OUTA, B 'bus inaktiv
'datenvergleich ----------------------------------------------------
cmp D, P3 wz 'vergleich mit testwert
if_z jmp #cmd4_b '<> testwert --> schleife beenden
'schleife ----------------------------------------------------------
add P1, #1 'adr := adr + 1
djnz P2, #cmd4_a 'nächste zelle bis p2 = 0
'kommando ende -----------------------------------------------------
cmd4_b mov DIRA, HBeat 'bus wieder inaktiv bis auf hbeat
mov A, PAR 'adresse der parameter nach reg-a
add A, #4
wrlong P1, A 'endadresse --> P1
add A, #4
wrlong P2, A 'anzahl --> P2
add A, #12
wrlong D, A 'gefundenen wert --> P5
jmp #cmdend
'------------------------------------------------------------------------------------------
cmdx
jmp #cmdend
' +------------------------- al
' |+------------------------ /prop2
' hbeat --------+ ||+----------------------- /prop1
' clk -------+| |||+---------------------- /ram2
' /wr ------+|| ||||+--------------------- /ram1
' /hs -----+||| ||||| +--------- a0..a10
' |||| ||||| |
' |||| |||||-----------+ -------- d0..d7
HBeat long %00000001_00000000_00000000_00000000 'hbeat-led
DIR_IN long %00000111_11111111_11111111_00000000 'maske: dbus-eingabe
DIR_OUT long %00000111_11111111_11111111_11111111 'maske: dbus-ausgabe
M_INAKTIV long %00000100_01111000_00000000_00000000 'bus inaktiv
M_R1WR long %00000000_01110000_00000000_00000000 'ram1/wr aktiv
M_R2WR long %00000000_01101000_00000000_00000000 'ram2/wr aktiv
M_R1RD long %00000100_01110000_00000000_00000000 'ram1/wr aktiv
M_R2RD long %00000100_01101000_00000000_00000000 'ram2/wr aktiv
M_AL long %00000100_11111000_00000000_00000000 'al aktiv
M_LATCH long %00000000_00000000_11111111_00000000 'maske adr-latch
M_ADR long %00000000_00000111_11111111_00000000 'maske adr-nwt
M_DAT long %00000000_00000000_00000000_11111111 'maske daten
Bei solchen Blockoperationen ist Pasm ca. um den Faktor 100 schneller als Spin, das kann man auch gut an der Füllroutine messen.
- Ram löschen Spin: 55 Sekunden
- Ram löschen Pasm: 0,5 Sekunden
(Zeit für eine RAMBank)
"Ob Sie denken, dass Sie es können, oder ob Sie denken, dass Sie es nicht können - in beiden Fällen haben Sie recht." Henry Ford