Ich hab in meiner architecture vor dem begin einige Funktionen
definiert, die dazu dienen ein array mit Werten aus einer Textdatei zu
initialisieren. Im Simulator läuft das einwandfrei, aber XST meckert
wenn ich das 'length Attribut einer line (nach readline()) auslesen will
und sagt mir "VHDL source expression not yet supported: 'DerefOp'.".
Wie kann ich festlegen, dass diese Funktion nicht als Komb. Logik
synthetisiert werden soll sondern nur einmal vor der Synthese zur
Berechnung der Initialwerte ausgeführt werden soll?
Daniel R. schrieb:> Im Simulator läuft das einwandfrei
Man kann 100% (naja, fast) von VHDL simulieren. Aber bestenfalls 95%
synthetisieren.
> aber XST meckert wenn ich das 'length Attribut einer line> (nach readline()) auslesen will
Das File-Handling ist nicht primäre Aufgabe eines Synthesizers. Welche
5% synthetisierbar sind, steht im Handbuch zum Synthesizer. In deinem
Fall zum XST-Users Guide.
> ein array mit Werten aus einer Textdatei zu initialisieren.
Dafür gibt es andere Wege. Hier kocht jeder seine eigene Suppe. Ich habe
ein externes C-Programm, das mir einen VHDL-Frame generiert, das Arrays
mit Werten füllt und das Ande anhängt. Letztlich bekomme ich dan eine
VHDL-Datei mit den gewünschten Werten.
Du kannst das Textfile auch parsen und als Initwerte für ein BRAM in die
Bitstromerzeugung einfließen lassen.
Lothar Miller schrieb:> Das File-Handling ist nicht primäre Aufgabe eines Synthesizers.
Richtig. Obwohl da erstaunlich viel geht...
Daniel R. schrieb:> einige Funktionen> definiert, die dazu dienen ein array mit Werten aus einer Textdatei zu> initialisieren.
Wie oft rufst Du denn Deine Funktion auf? Und an welcher Stelle?
> 'length Attribut
Laut UG627 sollte das funktionieren, offenbar aber nicht bei readline.
Vielleicht findest Du einen Workaround?
> Wie kann ich festlegen, dass diese Funktion nicht als Komb. Logik> synthetisiert werden soll sondern nur einmal vor der Synthese zur> Berechnung der Initialwerte ausgeführt werden soll?
Hier ein Beispiel aus dem UG627:
Die rom_init() Funktion ist gleich darüber definiert und wird nirgendwo
sonst aufgerufen.
Aus der Datei liest sie eine Zeile von unbekannter Länge.
Die Länge entnehme ich dann line_v'length
1
line_length_v:=line_v'length;--hier Problem
und kopiere dann entsprechend viele Zeichen in den 20 Zeichen großen
String Vector
1
read(line_v,str_line_v(1toline_length_v));
Den String Vektor gehe ich dann in einer Schleife durch und wandel jedes
Zeichen in einen std_logic_vector um.
Meckern tut XST beim Speichern der length in einer Variablen oben.
Der Unterschied zu dem Beispiel oben ist lediglich, dass die Zeilenlänge
bei mir variabel sein soll (begrenzt auf maximal 20 Zeichen). Wenn ich
die Zeilenlänge nicht angeb ist das ein Typkonflikt und erzeugt eine
Warnung. Außerdem brauch ich die Länge um die Gesamtzahl der belegten
Arrayfelder zu berechnen.
Daniel R. schrieb:> Der Unterschied zu dem Beispiel oben ist lediglich, dass die Zeilenlänge> bei mir variabel sein soll (begrenzt auf maximal 20 Zeichen).
Vielleicht hilft es die Datei zeichenweise zu lesen?
Duke
Naja, aber ich seh da nur die Funktionen:
readline() zum holen der kompletten nächsten Zeile und
read() zum auslesen der Zeile in eine Variable der passenden Größe.
Vielleicht geht es irgendwie, dass man eine Zeile zeichenweise ausliest
bis man was ungültiges zurück kriegt, aber ich wüsste jetzt nicht mit
welchen Funktionen das gehen würde.
Möglicherweise könnte man
1
procedureREAD(L:inoutLINE;VALUE:outCHARACTER;
2
GOOD:outBOOLEAN);
Immer wieder aufrufen bis GOOD = false ist (falls es da intern einen
Iterator gibt der aufs nächste Zeichen springt).
Daniel R. schrieb:> Vielleicht geht es irgendwie, dass man eine Zeile zeichenweise ausliest> bis man was ungültiges zurück kriegt
Im Anhang ist ein Stück Code, welches eine Textdatei einliest. Ich hab
das jetzt nur im Simulator getestet, aber es sollte auch im Synthesizer
funktionieren:
1
vcom test_vhdl_read.vhd
2
# Model Technology ModelSim SE-64 vcom 10.3d Compiler 2014.10 Oct 7 2014
3
# vcom -reportprogress 300 test_vhdl_read.vhd
4
# -- Loading package STANDARD
5
# -- Loading package TEXTIO
6
# -- Loading package std_logic_1164
7
# -- Loading package NUMERIC_STD
8
# -- Compiling entity test_vhdl_read
9
# -- Compiling architecture test of test_vhdl_read
Vielen Dank für die ausführliche Antwort.
Im Simulator läuft meine Lösung auch, wenn ich die line so wie in deinem
Beispiel zeichenweise einlese.
Aber im Synthesetool leider nicht!
Es lässt einfach nicht zu, dass die line-Attribute 'range oder 'length
abgefragt werden.
Frage ich 'length ab sagt XST: "VHDL source expression not yet
supported: 'DerefOp'."
Und frage ich 'range ab sagt XST: "Bad object specification in qualified
expression."
Wie auch immer, wenn ich die Attribute nicht benutze sondern mir einenn
End-Marker in jeder Zeile definier z.B. ';' dann läuft die Schleife zwar
an aber nur für 64 Iterationen. Danach kommt die Meldung "Loop has
iterated 64 times. Use "set -loop_iteration_limit XX" to iterate more."
Ich finde es unschön soeinen Parameter per Hand in die .xst Datei
schreiben zu müssen. Außerdem soll die Funktion ja gar nicht
synthetisiert werden. Kann man nicht irgendwie Sachen markieren, die
nicht synthetisiert werden sollen?
Daniel R. schrieb:> Es lässt einfach nicht zu, dass die line-Attribute 'range oder 'length> abgefragt werden.
Eigentlich schon: im XST Users Guide zur Version 14 steht:
1
VHDL Specifications
2
• Supported for some predefined attributes only:
3
– HIGHLOW
4
– LEFT
5
– RIGHT
6
– RANGE
7
– REVERSE_RANGE
8
– LENGTH
9
– POS
10
– ASCENDING
11
– EVENT
12
– LAST_VALUE
> Es lässt einfach nicht zu, dass die line-Attribute 'range oder 'length> abgefragt werden.
WIE frägst du die denn exakt ab? Im Beispiel von Duke kommt kein 'length
vor...
> Und frage ich 'range ab sagt XST: "Bad object specification in qualified> expression."
Zeig DEN Code, der diesen Fehler hervorruft. Ein 'range ist
selbstverständlich synthetisierbar. Fast jede Konvertierungsfunktion
verwendet das...
Die Funktion TO_01 in der numeric_std sieht z.B. so aus:
1
-- function TO_01 is used to convert vectors to the
2
-- correct form for exported functions,
3
-- and to report if there is an element which
4
-- is not in (0,1,h,l).
5
-- Assume the vector is normalized and non-null.
6
-- The function is duplicated for SIGNED and UNSIGNED types.
report"numeric_std.TO_01: Array Element not in {0,1,H,L}"
23
severitywarning;
24
foriinRESULT'rangeloop--- 'RANGE
25
RESULT(i):=xmap;-- standard fixup
26
endloop;
27
endif;
28
returnRESULT;
29
endTO_01;
Und die Funktion ist tadellos synthetisierbar.
> Außerdem soll die Funktion ja gar nicht synthetisiert werden.
Warum ist sie dann da drin? Die sollte dann doch eher zur Testbench nach
ausserhalb gehören....
Naja aber XST beschwert sich bei der Verwendung von 'range einer line
1
variableline_v:line;
2
begin
1
readline(rom_file,line_v);
2
forjinline_v'rangeloop--Zeile 132
Und ich krieg die Meldung:
"... line 132: Bad object specification in qualified expression.
INTERNAL_ERROR:Xst:cmain.c:3464:1.56 - Process will terminate. For
technical support on this issue, please open a WebCase with this project
attached at http://www.xilinx.com/support."
Ich umgehe das Problem dann gezwungenermaßen mit einem Trennzeichen am
Ende um die Abfrage zu vermeiden.
Oh man,
XST sagt zu meinen Initialisierungsschleifen
"Loop body will iterate zero times"
und
"Index value(s) does not match array range, simulation mismatch."
Dabei stimmt das gar nicht.
Daniel R. schrieb:> XST beschwert sich bei der Verwendung von 'range einer linevariable> readline (rom_file, line_v);> for j in line_v'range loop --Zeile 132
Nein. Der Synthesizer kann einfach nur nichts mit dynamischen Grenzen
bei einer for-Schleife anfangen. Das braucht er im restlichen Leben auch
nie...
Daniel R. schrieb:> "Loop body will iterate zero times"
Gleicher Fall: der Synthesizer kann nichts mit variablen Grenzen bei
einer for-Schleife anfangen...
Das steht aber ganz klar&deutlich im bereits des öfteren erwähnten XST
Users Guide:
1
VHDL For-Loop Statements
2
XST supports VHDL for-loop statements for:
3
• Constant bounds
4
...
Wie Lothar Miller schrieb:>>>> Welche 5% synthetisierbar sind, steht im Handbuch zum Synthesizer. In>>>> deinem Fall im XST Users Guide.
Durch die Ausgabe auf dem Display habe ich festgestellt, dass XST
anscheinend irgendwelche Fehler bei der Verwendung der TextIO Methoden
macht. Im Simulator enthält mein array alle Werte, wie gewünscht. Bei
XST nicht (da sind die verschoben und unvollständig).
Der Übersichtlichkeit halber tendiere ich nun zum erstgenannten
Vorschlag, nämlich in C++ einen Textfile-Parser zu schreiben, der eine
vhdl Datei ausspuckt, die das fertige Array bzw. spezifischen
Adressdekoder enthält.