Hallo zusammen,
ich habe mich jetzt intensiv mit SVF beschäftigt.
Insbesondere habe ich die Spezifikation von Asset und
zahlreiche App-Notes von Xilinx studiert, da ich
(den wahrscheinlich 1000sten ;-) SVF-Player auf
FT2232H-Basis implementieren möchte.
Leider will sich mir nicht so recht erschließen,
wozu das Bitfeld SMASK gut sein soll.
WIE es benutzt werden soll, das ist klar dokumentiert.
Aber wozu es dient, das ist mir schleierhaft.
Klar, man kann daraus ablesen, welche Bits, die
in das PLD geschoben werden, von Bedeutung sind
und welche nicht. Care / don't Care
Aber welchen Einfluss hat das auf den tatsächlichen
Bitstrom, der in TDI reingeht?
Bei TDO und MASK ist mir das völlig einleutend:
Die ausgelesenen Bits und die hinter TDO stehenden
Bits müssen gleich sein, soweit für das jeweilige Bit
in MASK eine 1 steht. Sonst hat es einen Fehler gegeben.
Steht eine 0 in MASK, kann man sich den Vergleich sparen
oder das Ergebnis ignorieren.
Aber was fange ich mit der Information an, dass ein
Bit, das ich über TDI einschiebe, eigentlich pupsegal ist???
Auf Null setzten? Wozu der zusätzliche Aufwand?
Und was würde es den Devices in der JTAG-chain nützen,
wenn sie wüssten, dass ein Bit, das gerade vorbeikommt,
EGAL ist? Denn das Bit auslassen, geht schließlich nicht.
Ich habe trotz intensiver Suche darauf keine Antwort gefunden.
Nur in der xapp503 von Xilinx steht erwas, das ich jedoch
für fraglich halte.
Auf Seite 9ff, Abschnitt "SVF Header and Trailer Instructions",
wird ein Beispiel gebracht, bei dem drei Devices in einer Chain
sind.
Das erste und das letzte Device werden auf Bypass geschaltet,
sodass der Datenstrom für das mittlere Device um ein
führendes und ein folgendes Bit erweitert werden muss.
Es wird dann gezeigt, dass man u.a. mittels:
1
HDR1TDI(00)SMASK(00);
vermeiden kann, die SVF-Anweisung SDR... für das mittlere Device
anpassen zu müssen.
Soweit einleutend. Auch die Erklärung "Explanation of Table 4"
ist nachvollziehbar.
Allerdings sieht man den Effekt von:
HDR 1 TDI (00) SMASK (00) ;
erst in der Zeile Expected Output, denn dort sind das erste
und das letzte AUSGELESENE Bit jeweils mit x als don't care
gekennzeichnet.
Aber müsste es dann nicht eigentlich:
1
HDR1TDI(00)TDO(00)MASK(00);
heißen? Oder von mir aus auch
1
HDR1TDI(01)TDO(00)MASK(00);
denn für alle drei Devices ist der Wert egal.
Und schließlich sind in der Definition von HDR mit
HDR length [TDI (tdi)] [TDO (tdo)] [MASK (mask)] [SMASK (smask)];
alle Felder vorgesehen. Besonders auch TDO und MASK.
Also bleibt für mich die Frage: wen, außer das menschliche Auge,
interessiert der Wert in SMASK?
Und wie muss ich SMASK im Programm berücksichtigen?
Vielen Dank
Erst einmal ein Frohes Neues Jahr!
Mittlerweile habe ich mich ein bisschen durch den Sourcecode des
libxsvf-Projektes durchgewühlt und bin in
http://svn.clifford.at/libxsvf/trunk/README fündig geworden
Zumindest scheint sich mein Verdacht zu bestätigen, dass die
SMASK-Daten, wenn überhaupt, nur für den menschlichen Leser von
Bedeutung sind
und an anderer Stelle sieht man, dass die -1 durch die SMASK-0 entsteht.
Hmmm. Bin ich der Einzige, der so etwas merkwürdig findet?
Schließlich findet sich in meinem SVF-Configfile für einen Spartan
...400A folgende Zeile:
SDR 1886624 TDI (...) SMASK (...)-, mit einer SMASK aus 471656 F's,
die weder ein Downloader, noch das FPGA, noch ich benötige, denn ich
werde sie garantiert nicht lesen ;-)
überhaupt finden sich in der SVF-Spec, die laut Footer vom 10.03.1999
stammt, eine Menge Fehler, Ungenauigkeiten und Ungereimtheiten.
Da finde ich den Satz in Wikipedia:
"Heute wird es von dem Unternehmen ASSET InterTech gepflegt"
als Scherz oder Hohn.
Und der Kater wird von so etwas auch nicht besser ;-)
SVF gibt durch die Darstellung in Hexadezimal eine Granularität von 4
Bit vor. Wenn Register nicht in diese Granularität passen, muss
angegeben werden, welche Bits der Hexadezimalzahl gültig sind. Das geht
dann mit SMASK.
Beispiel: Ein 6-Bit Register
SIR 6 TDI (ff) SMASK (3f) ;
Jetzt steht fest, das die beiden MSBs des TDI-Wertes igrnoriert werden
können und die unteren 6 LSBs übertragen werden müssen.
Üblich ist (nach meiner Erfahrung) dass der TDI-Wert LSB-aligned
angegeben wird da kann man SMASK durchaus als redundant ansehen, da die
Anzahl der zu übertragenden Bits ja angeben ist. Das ist vom Standard
AFAIK aber nicht vorgeschrieben, wer also weiß, was sich so alles "in
the wild" herumtreibt.
Edgar C. schrieb:> Hmmm. Bin ich der Einzige, der so etwas merkwürdig findet?>> Schließlich findet sich in meinem SVF-Configfile für einen Spartan> ...400A folgende Zeile:>> SDR 1886624 TDI (...) SMASK (...)-, mit einer SMASK aus 471656 F's,> die weder ein Downloader, noch das FPGA, noch ich benötige, denn ich> werde sie garantiert nicht lesen ;-)
Der Praktikant der diesen Code bei Xilinx schreiben durfte, hat die Spec
wahrscheinlich auch nicht richtig verstanden ;-)
Duke
Danke für eure Antworten.
@ Rudolf:
Das erscheint mir als Erklärung plausibel. Allerdings habe ich folgendes
Zitat aus der Spec, Seite 5 (V), als Indiz interpretiert, dass die
Scan-Daten im Hex-String right aligned sind:
"The scan data cannot specify a data string that is larger than the
specified bit length. Most Significant Bit (MSB) zeroes in the hex
string are not considered when determining if the string is
too large. The bit order for scan data follows the convention that the
least significant bit (rightmost bit)..."
Aber das ist eben nur (m)eine Interpretation.
Besser wäre m.E. eine Formulierung wie z.B.:
The scan data must be right aligned in the hex string, i.e. the
rightmost bit of the scan data must be at the rightmost position of the
hex string.
Eine Spec ist eben kein Platz für Prosa, die sich möglichst flüssig
lesen und elegant klingen soll, sondern ein Ort, der staubtrockener sein
muss, als die Wüste ;-)
@ Duke: Breitgrins
Edgar C. schrieb:> Allerdings habe ich folgendes Zitat aus der Spec, Seite 5 (V), als Indiz> interpretiert, dass die Scan-Daten im Hex-String right aligned sind:> "[...] The bit order for scan data follows the convention that the> least significant bit (rightmost bit)..."
Richtig, das hatte ich übersehen. Vergiß also meinen Ansatz von oben.
Nichtsdestotrotz sind Anwendungen für SMASK denkbar. Wenn es längere
Scheibeoperationen gibt, bei denen der Eingangswert nicht interessant
ist (SMASK also 0), kann man die Verarbeitung des SVFs beschleunigen,
weil keine TDO-Daten an den TAP-Controller übergeben werden müssen (das
kann, JTAG ist schließlich schon recht alt, bei einer RS-232 Verbindung
richtig interessant werden!). Ein Bespiel wäre z.B. ein Baustein der für
einen Programmierprozess eine Clock benötigt, aber keine Daten. RAM
löschen könnte ein anderes Beispiel sein. Ich könnte jetzt aber auch
keinen Baustein benennen, das so arbeitet (RUNTEST würde ja auch gehen).
Für Standardanwendungen ist es bestimmt nicht schlimm, wenn man SMASK
ignoriert. Sollte man sich aber merken, falls wenn doch...
Rudolph schrieb:> weil keine TDO-Daten an den TAP-Controller übergeben werden müssen (das> kann, JTAG ist schließlich schon recht alt, bei einer RS-232 Verbindung> richtig interessant werden!).
Das ist allerdings richtig. Habe ich gar nicht dran gedacht. So schnell
hat man die alten Zeiten vergessen.
> Für Standardanwendungen ist es bestimmt nicht schlimm, wenn man SMASK> ignoriert. Sollte man sich aber merken, falls wenn doch...
Naja, das schöne ist ja, dass ein 'don't care' ein 'don't care' ist ;-)
Das heißt: es ist egal, was ich im Fall von 'don't care' rüberschiebe
und solange Bits geschoben werden, muss es funktionieren.
Aber noch etwas anderes aus dieser Spec:
"RUNTEST [run_state] ... [ENDSTATE end_state];:
When an end_state is specified, it becomes the default.
When a run_state is specified, the new run_state becomes the
default end_state.
When a run_state is not specified, the default end_state
remains in effect."
Ja was denn nun, wenn end_state UND run_state angegeben ist?
Und was, wenn end_state angegeben ist, aber run_state nicht?
"libxsvf" tut übrigens folgendes:
Die Befehlzeile wird so lange nach Parametern abgescannt, bis
alle Parameter erkannt wurden und das Ende der Befehlszeile erreicht
ist.
Wird dabei u.a. ein String erkannt, der einen gültigen stable state
darstellt, dann passiert folgendes:
if (got_endstate) //Der String ENDSTATE wurde bereits gefunden
state_endrun = st; // dann wird der gerade gefundene stable state
// zum end_state
else
state_run = st; // sonst wird er zum run_state
state_run und state_endrun sind aber nur lokale Variabeln, die
nur für die aktuelle Befehlszeile gelten.
Die beiden Werte werden nicht in einen wie auch immer gearteten
Speicher für Default-Werte übernommen.
Die stable states sind übrigens:
IRPAUSE, DRPAUSE, RESET, and IDLE
Bei allen states außer RESET würde ich ja auch sagen:
es ist egal, in welchem der states die Zeit/Clocks abgewartet werden.
Aber gerade bei RESET sieht das doch anders aus. Oder wird durch RESET
nicht das JTAG-Interface initialisiert?
LG Edgar
Edgar C. schrieb:> Aber noch etwas anderes aus dieser Spec:>> "RUNTEST [run_state] ... [ENDSTATE end_state];:> When an end_state is specified, it becomes the default.> When a run_state is specified, the new run_state becomes the> default end_state.> When a run_state is not specified, the default end_state> remains in effect.">> Ja was denn nun, wenn end_state UND run_state angegeben ist?
Lies: Wenn ein run_state angegeben ist, überschreibt dieser den default
end_state, es sei den, es ist in diesem Kommando wieder ein end_state
mit angegeben.
Ob solche Konstruktionen jetzt so gebräuchlich sind, vermag ich nicht zu
sagen. Dass sich "libxsvf" nix merkt, scheint ja nicht zu schaden. Im
Zweifel einfach mal die SVFs anschauen, die man abspielen möchte und
dann beurteilen, ob man auf sowas achten muss.