Forum: FPGA, VHDL & Co. 2s Complement nach fixed point


von Nils D. (Gast)


Lesenswert?

Aus meinem ADC kommen 16bit Zweierkomplement und ich möchte das in fixed 
point zur weiteren Rechnung überfüren. Ich dachte mir die fractional 
bits mit den ADC werten zu füllen, damit der Wertebereich zwischen 
-0.999 und +0.999 liegt (Nur zur Veranschaulichung). Wie handhabe ich 
das sign bit? Bei fixed point ist 0, doch zweimal belegt einmal +0 und 
-0, oder?

von Vancouver (Gast)


Lesenswert?

Nils D. schrieb:
> Bei fixed point ist 0, doch zweimal belegt einmal +0 und
> -0, oder?

Nein, du kannst auch bei Fixedpoint das 2-Komplement verwenden, das 
funktioniert genauso wie bei Integer. Der Punkt ist  ja nur gedacht. 
Wenn du in deinem Fall die ADC-Bits komplett in den Factional-Part 
verschiebst, musst du nur dafür sorgen, dass bei negativen Werten die 
Integerbits alle auf 1 gesetzt werden. Danach kannst du damit wie mit 
einem breiteren Integer weiterrechnen. Im Grund ist es das Gleiche wie 
eine vorzeichenrichtige Erweiterung der Bitbreite.

von Nils D. (Gast)


Lesenswert?

Ich habe aber keine integerbits. Ich verstehe nicht wieso es dann bei 
fixed point zahlen Oberhaupt ein extra sign bit gibt.

von Gustl B. (-gb-)


Lesenswert?

Nils D. schrieb:
> Ich habe aber keine integerbits.

Dann hast du deinen Punkt etwas zu weit links gesetzt. Die erste Stelle 
rechts neben dem Punkt hat die Wertigkeit 1/2. Da solltest du also nicht 
das Vorzeichenbit hinschieben.

Nils D. schrieb:
> Ich verstehe nicht wieso es dann bei
> fixed point zahlen Oberhaupt ein extra sign bit gibt.

Wie soll man denn sonst unterscheiden ob positiv oder negativ? Aber klar 
gibt es das auch ohne Vorzeichen, nennt sich ufixed.

Weil dein ADC aber Zweierkomplement liefert kannst du das entweder 
umwandeln, also 2**15 addieren oder eben vorzeichenbehaftet 
weitermachen.

von Nils D. (Gast)


Lesenswert?

Dennoch ist beim signed fixed point ohne integerbits also Wertebereich 
immer kleiner als +1 und größer -1 die null doppelt belegt. Nämlich alle 
fractional bits 0 und sign bit eins oder sign bit 0.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Nils D. schrieb:
> Ich verstehe nicht wieso es dann bei fixed point zahlen Oberhaupt ein
> extra sign bit gibt.
Ein sign-Bit gibt es dort genauso wenig wie bei normalen Binärzahlen im 
Zweierkomplement. Auch dort ist es so, dass eine Binärzahl, die eine 
oder mehrere(!!) führende '1'en hat, eine negative Binärzahl ist. Alle 
führenden '1'er sind also "Sign-Bits".

Nils D. schrieb:
> Dennoch ist beim signed fixed point ohne integerbits also Wertebereich
> immer kleiner als +1 und größer -1 die null doppelt belegt.
Zahlensysteme mit positiven und negativen Nullen sind schwer handhabbar 
und haben sich nicht durchgesetzt.

> Nämlich alle fractional bits 0 und sign bit eins oder sign bit 0.
Auch fixed-Point zahlen sind lediglich normale binäre Zahlen im 
Zweierkomplement. Der Dezimalpunkt bei der Fixed-Point Darstellung ist 
nur gedacht. Er existiert nicht wirklich, deshalb kann man für die 
Fixed-Point-Darstellung die selben Rechenwerke (Addierer, 
Multiplizierer) wie für normale binäre Integerzaheln verwenden.

Eine Addition eines 8-Bit Integers, der als Fixed-Point 8.0 heißen 
würde, zu einem Integer mit 8.0 ergibt einen 9.0 Wert. Eine 
Multiplikation einer 8.0 Zahl mit einer 8.0 Zahl ergibt eine 16.0 Zahl.
Analog ergibt die Addition einer 4.4 Zahl zu einer 4.4 Zahl ein 5.4 
Ergebnis. Und 4.4 multipliziert mit 4.4 ergibt ein 8.8 Ergebnis.

von Samuel C. (neoexacun)


Lesenswert?

Lothar M. schrieb:
> Zahlensysteme mit positiven und negativen Nullen sind schwer handhabbar
> und haben sich nicht durchgesetzt.

Du meinst sowas wie IEEE754? Stimmt, sieht man kaum in freier Wildbahn^^

Sorry, der musste sein. Ansonsten keine Einwände.

von Strubi (Gast)


Lesenswert?

Lothar M. schrieb:
> Ein sign-Bit gibt es dort genauso wenig wie bei normalen Binärzahlen im
> Zweierkomplement.

Das MSB ist das Sign-Bit. Den Ausfuehrungen von Vancouver zur 
Vorzeichenerweiterung ist sonst eigentlich kaum was hinzuzufuegen. 
Ausser, dass man sich noch merken kann: Wenn MSB gesetzt, gilt fuer die 
Werteinterpretation (hier also Negation): (integer) val = -( (NOT a) + 1 
), damit kommt die 0 nicht doppelt vor.

Ansonsten, wenn man keine Brunsviga-Rechenmaschine mehr zuhause hat: Die 
Blackfin Instruction Set Reference erklaert auch kurz und knapp wie's 
geht und schlaegt so manches Lehrbuch.

von Wolfgang (Gast)


Lesenswert?

Lothar M. schrieb:
> Ein sign-Bit gibt es dort genauso wenig wie bei normalen Binärzahlen im
> Zweierkomplement.

Immerhin kannst du dich darauf verlassen, dass das oberste Bit bei 
negativen Zahlen gesetzt ist und bei positiven nicht.

von Wolfgang (Gast)


Lesenswert?

Strubi schrieb:
> Das MSB ist das Sign-Bit.

Du kannst aber nicht aus einer negativen Zahl eine gleichgroße positive 
machen, indem du das MSB invertierst - und das würde man von einem 
Sign-Bit erwarten.

von Ulmer (Gast)


Lesenswert?

Lothar M. schrieb:
> Und 4.4 multipliziert mit 4.4 ergibt ein 8.8 Ergebnis.
Wie ist das bei signed? Die größte Zahl ist:

0111.1111 x 0111.1111 =>

binomisch:

1x  0111.0000 x 0111.0000 = 49
1x  0000.1111 x 0000.1111 = 225
2x  0111.0000 x 0000.1111 = 210

-> 49 + 210/16 + 225/256 = ca. 63 -> 6.8 Ergebnis.

?????

von Nils D. (Gast)


Lesenswert?

Ich will folgendes VHDL Package verwenden: 
https://github.com/enclustra/en_cl_fix

Wenn ich mir da die Beschreibung zum Format anschaue geht daraus hervor, 
dass ein auf true gesetztes sign ein explizites sign bit erzeugt: 
https://rawgit.com/enclustra/en_cl_fix/master/doc/vhdl_out/html/classen__cl__fix__pkg.html#ad13c964a4a8af4809d098578e3439240

Das steht aber im Widerspruch zu obigen Aussagen.

von Strubi (Gast)


Lesenswert?

Wolfgang schrieb:
> Du kannst aber nicht aus einer negativen Zahl eine gleichgroße positive
> machen, indem du das MSB invertierst - und das würde man von einem
> Sign-Bit erwarten.

Nicht per Definition. Das Sign-Bit sagt grundsaetzlich nichts ueber die 
Operation der Negation aus (s.o.).
So viel Verwirrung muessen wir allerdings nicht mehr stiften, da 
zumindest die VHDL-Arithmetik (im Gegensatz zu Verilog) das geradeaus 
umsetzt, also `resize(signed(a), n)` mit numeric_std-Typen macht m.W. in 
allen aktuellen Toolchains das was es soll.

Ulmer schrieb:
> -> 49 + 210/16 + 225/256 = ca. 63 -> 6.8 Ergebnis.

Probier mal die maximal/minimal moeglichen Werte (und alle 
signed/unsigned Kombinationen) durch. Da gibt's dann zwar einen grossen 
Wertebereich der 'verschenkt' ist, aber dennoch kann man keine Bits 
einsparen (Warum?).

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Samuel C. schrieb:
> Du meinst sowas wie IEEE754? Stimmt, sieht man kaum in freier Wildbahn^^
Hmpf, dumm gelaufen...  ;-)

Strubi schrieb:
> Lothar M. schrieb:
>> Ein sign-Bit gibt es dort genauso wenig wie bei normalen Binärzahlen im
>> Zweierkomplement.
> Das MSB ist das Sign-Bit.
Wenn binär 00000001 dezimal 1 ist, dann ist 10000001 demnach also -1?

Mitnichten: das MSB zeigt nur an, dass es eine negative Zahl ist. Die 
negative Zahl steckt aber im Zweierkomplement aller nachfolgenden Bits.

Ja, ich weiß, dass du das weißt, aber die Aussage, das MSB sei "das 
Vorzeichenbit" ist eben falsch.

Ulmer schrieb:
> 0111.0000 x 0111.0000 =
Sehen wir uns das mal in kleinen Schritten an:
1
Aufgabe:
2
Multipliziere die 4.4 Festkommazahl mit dem Wert 7,0 
3
mit einer 4.4 Festkommazahl mit dem Wert 7,0
4
5
1. dezimal  7,0    x    7,0    
6
2. binär 0111,0000 x 0111,0000    
7
3. Komma weg und auf bekannte zweierkomplementäre Weise multiplizieren:
8
   01110000 x 01110000 = 0011000100000000
9
4. Komma bei 8.8 wieder rein: 00110001.00000000
10
5. Umwandlung in Dezimalzahl -> Ergebnis = 49,0  q.e.d.
War ja gar nicht mal so schwierig...

Jetzt mal mit Nachkommastellen 3,33 x 7,77
1
dezimal:      3,33   x    7,77
2
--> binär: 0011,0101 x 0111,1100 
3
--> Komma raus und multiplizieren: 00110101 x 01111100 = 0001100110101100
4
--> Komma bei 8.8 wieder rein: 00011001,10101100
5
--> Ergebnis 25 Komma (172/256) = 25,672
6
--> Kontrollrechnung mit Taschenrechner = 3,33 x 7,77 = 25,874
Passt gar micht mal so schlecht bei nur 4 Nachkommastellen bei den 
Faktoren...

: Bearbeitet durch Moderator
von Strubi (Gast)


Lesenswert?

Lothar M. schrieb:
> Ja, ich weiß, dass du das weißt, aber die Aussage, das MSB sei "das
> Vorzeichenbit" ist eben falsch.

Dann sind also eine Menge IEEE-Standards falsch, was offenbar auch immer 
wieder Leute dazu bewegt, die Fixpoint-Arithmetik 'neu zu erfinden'.

Bitte Leute, nicht schon wieder an 50 Jahre alten Definitionen drehen 
und Representation mit Arithmetik vermischen. Siehe oben zur Negation.

von Vancouver (Gast)


Lesenswert?

Nils D. schrieb:
> Wenn ich mir da die Beschreibung zum Format anschaue geht daraus hervor,
> dass ein auf true gesetztes sign ein explizites sign bit erzeugt:

Auf der ersten Github-Seite steht wörtlich:

"""
The fixed point number format used in this library is defined as 
follows:

[s, i, f]

s: true = Signed number (two's complement), false = Unsigned number i: 
Number of integer bits f: Number of fractional bits
"""

Du kannst also über den s-parameter auswählen, ob du mit signed oder 
unsigned-Werten arbeiten willst. Von einem expliziten Vorzeichenbit 
steht da nichts.

von Vorn N. (eprofi)


Lesenswert?

Beim 2er-Komplement gibt es keine doppelte 0, nur +0.
Der Wertebereich ist daher unsymmetrisch.
0x8000 ist -1,000, das kann man nicht Vorzeichenwechseln ohne Überlauf.
0x7FFF ist +0,99996948

Beim 1er-Komplement gibt es die doppelte 0.
Bei vielen ADC kann man auswählen, ob das Ergebnis links- oder 
rechtsbüncig im Register stehen soll. Bei linksbündig braucht man 
wahrscheinlich gar nichts schieben / füllen.

von Vancouver (Gast)   19.05.2022 21:02
> Danach kannst du damit wie mit einem breiteren Integer
> weiterrechnen. Im Grund ist es das Gleiche wie eine
> vorzeichenrichtige Erweiterung der Bitbreite.
Genau. Zum vorzeichenrichtigen Schieben gibt es den ROR-Befehl, der 
sign-extension macht (im Gegensatz zum LSR logical shift right).

: Bearbeitet durch User
von Strubi (Gast)


Lesenswert?

Vorn N. schrieb:
> Genau. Zum vorzeichenrichtigen Schieben gibt es den ROR-Befehl, der
> sign-extension macht (im Gegensatz zum LSR logical shift right).

Das wird ja immer besser. Abgesehen davon, dass im FPGA bei 
Sign-Extension sowieso nicht 'geschoben' wird, rotiert obiger Befehl in 
allen mir bekannten Architekturen das LSB wieder beim MSB (Carry) herein 
(Vermutlich meintest du ASR).

von Jürgen S. (engineer) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Passt gar micht mal so schlecht bei nur 4 Nachkommastellen bei den
> Faktoren...
Sein Problem ist hier eher nicht die Nachkommastelle, sondern:

Vorn N. schrieb:
> Beim 2er-Komplement gibt es keine doppelte 0, nur +0.
> Der Wertebereich ist daher unsymmetrisch.
Das ist er entscheidende Punkt!

Ulmer schrieb:
>> Und 4.4 multipliziert mit 4.4 ergibt ein 8.8 Ergebnis.
> Wie ist das bei signed? Die größte Zahl ist:
>
> 0111.1111 x 0111.1111 =>

Das ist das Problem beim Zweierkomplement: Die negativste Zahl ist eben 
der voll ausgelastete Vektor - bei einer 4.4 -256.0/-16.0 und wenn man 
die quadriert, kommt eben auch ein voll ausgelasteter Vektor bei raus. 
Wegen diesem einen "Problembär" braucht es dann größere Bruttovektoren.

Daher beschränke ich bei meinen Rechnungen in VHDL die negativen Zahlen 
immer auf -(n-1); hier also -127 = - (15 + 15/16) = 11111110; und komme 
mit geringeren Vektoren aus, was sich dann durch das gesamte Design 
fortsetzt.

Besonders beim Quadrieren und der Verwendung von Multiplizierern ist das 
Vorteilhaft, weil man schon beim Einspeisen in den Multiplier ein Bit 
weiter links arbeiten kann, wenn man es richtig macht, vorbehandelt und 
nur in einem Quadranten arbeitet. Bei einem echten signed MUL kann man 
dann zumindest 2 Bits wegschneiden. Bei einer Approximation mit X8 + X6 
... konnte ich so mal ein Viertel der Multiplizierer einsparen und mit 
Vorbehandlung und Schätzrundung nochmal ein paar weitere 10%.

Ich habe mir eine Library gebaut, mit der ich z.B. Magnitude aus (X*X + 
Y*Y) berechnen kann und die auch den Fall der IQ-Prozessierung 
behandelt, wo funktionell nicht irgendwelche Quadrate rauskommen können 
sondern die Summe limitiert ist und nochmal ein Bit wegfällt.

Wenn man das gleiche mit HLS aus C oder mit MATLAB-VHDL Coder baut, wird 
es signifikant größer!

von Duke Scarring (Gast)


Lesenswert?

Jürgen S. schrieb:
> Wenn man das gleiche mit HLS aus C oder mit MATLAB-VHDL Coder baut, wird
> es signifikant größer!
Ja, das ist der Nachteil. Dafür muß man dort auch signifikant weniger 
drüber nachdenken. Die Denkhilfe lassen sich die Hersteller in Form von 
Lizenzen und größeren FPGA bezahlen ;-)

von Martin S. (strubi)


Lesenswert?

Jürgen S. schrieb:
> Wenn man das gleiche mit HLS aus C oder mit MATLAB-VHDL Coder baut, wird
> es signifikant größer!

Es gibt sonst schon einige clevere HLS-Konzepte (allerdings basierend 
auf C++ oder Python-Datentypen) die nur die effektiv notwendigen Bits 
nutzen.
Mit Derivaten von den `intbv` aus dem MyHDL-Fundus (explizite 
min/max-Grenzen) kann man das recht schoen optimieren. Lesbare HDL gibt 
das allerdings nur bedingt aus. Leider wirft MyHDL nur im Rahmen der 
eingebauten Simulation Fehler beim Ueberschreiten, also statische 
Verifikation liegt nicht drin.
Die Bit-Sparerei bringt aber nur wirklich was, wenn man die 
Instanzierung nicht komplett dem Vendor-Mapping-Tool ueberlaesst und 
massenweise Multiplier explizit per Logikprimitiven nachbaut.

von Jürgen S. (engineer) Benutzerseite


Lesenswert?

Duke Scarring schrieb:
> Die Denkhilfe lassen sich die Hersteller in Form von
> Lizenzen und größeren FPGA bezahlen ;-)
Das kann aber ganz schön ins Negative gehen, wenn man Stückzahlen baut 
und wie gesagt bläht das design nicht nur in der Größe auf, sondern wird 
auch langsamer zu takten sein und nicht immer gibt es noch eine 
schnellere Version mit 10% Aufpreis.

Und ich finde auch den Denkaufwand so arg nicht.

Ich habe gerade mal geschaut: Mein aktueller Yamaha-mäßiger 
FM-Synthesizer verkettet bis zu 4/8 Funktionen des Typs y = (a*sin(b * 
phi)) wobei phi selber aus einer solchen Vorschrift bezogen wird. Da ich 
das bei mir inzwischen mit der Casio-mäßigen PD-Distorsion kopple, also 
noch eine Phasenvektor-MUL mit einbeziehe, habe ich mehrere MULs 
parallel und kann durch geschicktes- und richtiges Runden/Abschneiden je 
Zyklus 3 Bit einsparen - bei praktisch gleicher Qualität (der jeweilige 
Rest wird nicht genau ausgerechnet und kriecht aus den Tiefen der 
genauer behandelten Bits hervor, sondern wird statistisch gerundet).

Wenn ich das stringent durchziehe sind das 12 Bit weniger 
Auflösungsbedarf. Der Einfachheit halber spare ich nur 8 Bit, habe aber 
an der Stelle der höchsten Auflösung nicht 18+18+18+18 = 72, sondern nur 
64 Bit momentane Auflösung für den primären Phasenvektor. Das macht 
schon einen tüchtigen Unterschied, wenn an auf den ein Vibrato addieren 
will und dies dann mehr FFs nach sich ziehen würde. Die CC-Zahl für den 
loop ist per se schon kleiner, was dazu führt, dass ich mit derselben 
Architektur mehr Stimmen schaffe oder selbige um geschätzt 40% höher 
abtasten kann, was sie technisch gesehen besonders in den Höhen genauer 
macht, wenn dy/dt in der Nähe der Taktrate kommt. Ich kann im Weiteren 
mit einem viel einfacheren Restglied bei Iterationen und Integration 
arbeiten.

Natürlich ist damals ein Haufen Zeit reingeflossen, der sich auch nicht 
wirklich rechnet, aber wenn man das Dingens einmal hat, dann ist es ewig 
besser ... :-)

von Jürgen S. (engineer) Benutzerseite


Lesenswert?

Martin S. schrieb:
> Es gibt sonst schon einige clevere HLS-Konzepte (allerdings basierend
> auf C++ oder Python-Datentypen) die nur die effektiv notwendigen Bits
> nutzen.

Die Frage ist, was man da wieder an Drum-Herum-Aufwand hat, um es zu 
beschreiben. Ich tipple bei mir einfach die Daten und Ranges ins Excel 
und kopiere mir den Code raus. Dabei kann ich mir aussuchen, wie ich 
runde und verrausche. Mir ist kein HLS- oder MATLAB-Funktion bekannt, 
die da den richtigen Rauschpegel ausrechnen kann (Spektrum und 
Amplitude) und das auch noch automatisch trimmt.

Ich hatte hier ja mal ein Beispiel gebracht, wie sich das ausgehen kann:
Beitrag "Re: Rauschleistung eines Netzwerks"

von Martin S. (strubi)


Lesenswert?

Jürgen S. schrieb:
> Die Frage ist, was man da wieder an Drum-Herum-Aufwand hat, um es zu
> beschreiben. Ich tipple bei mir einfach die Daten und Ranges ins Excel
> und kopiere mir den Code raus

Na man schreibt es einfach hin (in Python), z.B. die erwaehnte 'Power':
1
...
2
  a, b = [ Signal(self.wiretype(min=-127, max=128)) for _ in range(2) ]
3
4
  res = pipelined(Signal(self.wiretype(auto = True)))
5
6
  wirings = [
7
    a <= data[0],
8
    b <= data[1]
9
  ]
10
11
  p_ma = a * a
12
  p_mb = b * b
13
  p_sum = p_ma + p_mb
14
15
  @self.pipeline(en, valid)
16
  def worker():
17
    res.next = p_sum

Der Kniff steckt im `wiretype`, welcher intern Buch ueber die Bitbreiten 
fuehrt. Entsprechend laesst sich auf truncated MUL, andere 
Rundungsoptionen, etc. umschalten.
Dediziertes Trimmen geht allerdings nur semi-automatisch, da muss die 
Pipeline explizit notiert werden.
Die Synthese (via yosys) inferiert dann entsprechend abgeschnittene 
Multiplier/Akkumulatoren. In HDL ist das dann allerdings eine unlesbare 
resize()/Slice-Orgie.

Excel ist fuer mich aus mehreren Gruenden keine Option, aber einer davon 
waere schon das manuelle Starten/umkopieren (apropos Aufwand..)

von Signalisierer (Gast)


Lesenswert?

Martin S. schrieb:
> Die Synthese (via yosys) inferiert dann entsprechend abgeschnittene
> Multiplier/Akkumulatoren. In HDL ist das dann allerdings eine unlesbare
> resize()/Slice-Orgie.
Mal ausprobiert was bei den unterschiedlichen Ansätzen heraus kommt?
Das viele resize wäre mir jetzt z.B. komplett Wurscht.

Jürgen S. schrieb:
> Mir ist kein HLS- oder MATLAB-Funktion bekannt,
> die da den richtigen Rauschpegel ausrechnen kann
Wozu muß das verrauscht werden?

von Martin S. (strubi)


Lesenswert?

Signalisierer schrieb:
> Martin S. schrieb:
>> Die Synthese (via yosys) inferiert dann entsprechend abgeschnittene
>> Multiplier/Akkumulatoren. In HDL ist das dann allerdings eine unlesbare
>> resize()/Slice-Orgie.
> Mal ausprobiert was bei den unterschiedlichen Ansätzen heraus kommt?
> Das viele resize wäre mir jetzt z.B. komplett Wurscht.
>

Da gibt's hier ne grosse Testbench, Auszug:
1
        -- ======= Test 9 =======
2
        s0 <= "1000001";
3
        s0 <= "1000001";
4
        wait for 1 ns;
5
        q2 <= (signed(s0) * signed(s0));
6
        wait for 1 ns;
7
        print("[9] eval:" & " " & str(3969) & " " & "-- q = " & " " & "0x"& hstr(unsigned(q2)));
8
        assert (q2 = "00111110000001")
9
            report "Failed for q2 <= MUL(SGN(<s0>), SGN(<s0>))" severity failure;
10
        -- ======= Test 10 =======
11
        s0 <= "1000000";
12
        s0 <= "1000000";
13
        wait for 1 ns;
14
        q2 <= (signed(s0) * signed(s0));
15
        wait for 1 ns;
16
        print("[10] eval:" & " " & str(4096) & " " & "-- q = " & " " & "0x"& hstr(unsigned(q2)));
17
        assert (q2 = "01000000000000")
18
            report "Failed for q2 <= MUL(SGN(<s0>), SGN(<s0>))" severity failure;

Die (9) ist der Fall mit der intbv()-beschraenkung '[-63, 64)'.

Da sieht man die ueberfluessigen Bits, die optimierende Bitvector-Klasse 
dimensioniert dann das Resultat entsprechend, wenn ein Quadrat erkannt 
wird.

VHDL ist hier noch einigermassen lesbar, fuer unterschiedlich grosse 
Multiplikatoren wirds v.a. bei Verilog wuest, wie sowas:
1
        qs <= $signed(u0 * { {3{u1[4]}} , u1} /* RS */ ) /* implicit */  /* resize 12 -> 13 */ ;

Gucke aber in die HDL kaum noch rein.

von Frank O. (Gast)


Lesenswert?

Martin S. schrieb:
> Leider wirft MyHDL nur im Rahmen der
> eingebauten Simulation Fehler beim Ueberschreiten, also statische
> Verifikation liegt nicht drin.
Das wäre für manche Anwendungsfälle aber ein Killer. Wir machen z.B. 
sehr viel formale Verifikation und Qualifizierung von Code und brauchen 
da verlässlichen output.

> Die Bit-Sparerei bringt aber nur wirklich was, wenn man die
> Instanzierung nicht komplett dem Vendor-Mapping-Tool ueberlaesst und
> massenweise Multiplier explizit per Logikprimitiven nachbaut.
Das wäre ein Killer in Sachen Produktivität. Wer tut sich denn so etwas 
heute noch an? Ich wäre froh gewesen, in meiner Zeit eine Hochsprache 
gehabt zu haben, mit der man VHDL erzeugen hätte können.

Martin S. schrieb:
> Gucke aber in die HDL kaum noch rein.
Das ist natürlich ein Kriterium, dass man es nicht mehr verifizieren 
muss. Die Frage ist, wie gut man die Verifikation nach oben auf die 
höhere Erzeugerebene verschieben kann und wie verlässlich das ist. Die 
Sache ist nämlich die, dass es Bereiche gibt, wo die VHDL mit einem 4 
Augen-Prinzip gesichtet wird / werden muss.

Theoretisch wäre es möglich, sich auf das myHDL oder Python zu beziehen, 
wenn die Übersetzung ausreichend gesichert ist, aber diesbezüglich haben 
wir ständig ein Problem, ModelSIMs CODE-COVERAGE mit ins Spiel zu 
bringen, das unsere Kunden oft verlangen, wenn automatische 
Code-Erzeuger aktiv waren.

von Martin S. (strubi)


Lesenswert?

Frank O. schrieb:
> Martin S. schrieb:
>> Leider wirft MyHDL nur im Rahmen der
>> eingebauten Simulation Fehler beim Ueberschreiten, also statische
>> Verifikation liegt nicht drin.
> Das wäre für manche Anwendungsfälle aber ein Killer. Wir machen z.B.
> sehr viel formale Verifikation und Qualifizierung von Code und brauchen
> da verlässlichen output.
>

Spannendes Thema. Da gibt's allerdings mehrere Baustellen. 
Grundsaetzlich geht das mit Python-Generatoren sehr produktiv 
vonstatten, d.h. eine Verarbeitungs-Sequenz (linear oder als Pipeline 
ausgerollt) laesst sich als HDL-Modell mit den Ergebnissen der 
eingeschleiften, goldenen Referenz (Octave-Modell oder auf Basis 
intbv-Fixpunkt-Arithmetik) schrittweise oder sonst induktiv im 
V*-HDL-Transfer verifizieren.
Leider gibt's bei MyHDL einige harte Grenzen, die von anderen 
Python-Generatorenkonzepten (n/migen) theoretisch einfacher zu handhaben 
waeren. Leider musste ich den dritten Weg gehen (ein ausgeartetes 
Experiment mit HLS auf MyHDL-Kompatibilitaet biegen).
Kann man auch mit spielen (siehe 
Beitrag "HDL in Python / MyHDL die Zweite (unfertig)"). Am besten mit dem 
'verilog' Branch.

>> Die Bit-Sparerei bringt aber nur wirklich was, wenn man die
>> Instanzierung nicht komplett dem Vendor-Mapping-Tool ueberlaesst und
>> massenweise Multiplier explizit per Logikprimitiven nachbaut.
> Das wäre ein Killer in Sachen Produktivität. Wer tut sich denn so etwas
> heute noch an? Ich wäre froh gewesen, in meiner Zeit eine Hochsprache
> gehabt zu haben, mit der man VHDL erzeugen hätte können.
>

Vor 10 Jahren ging das im Prinzip schon mit MyHDL, leider nur zu Fuss, 
da die Hierarchie eines komplexen Designs geflacht wird und u.U. eine 
Menge redundante Funktionen erzeugt werden. Das bekam man schon mal vom 
Kunden um die Ohren gehauen. Das sieht jetzt anders aus.

> Martin S. schrieb:
>> Gucke aber in die HDL kaum noch rein.
> Das ist natürlich ein Kriterium, dass man es nicht mehr verifizieren
> muss. Die Frage ist, wie gut man die Verifikation nach oben auf die
> höhere Erzeugerebene verschieben kann und wie verlässlich das ist. Die
> Sache ist nämlich die, dass es Bereiche gibt, wo die VHDL mit einem 4
> Augen-Prinzip gesichtet wird / werden muss.
>

Von Seiten yosys gibt es einige spannende Verifikationsansaetze, die ich 
jetzt mal als robust bezeichnen wuerde. Die Frage ist schlussendlich, 
was der Kunde akzeptiert. Hier in der Umgebung schwierig, da wird auf 
Schaumschlaegerei mehr Wert gelegt als auf Beweise.
Meine Ansprueche an Verifikation sind vordergruendig klein, d.h. es muss 
bis auf Primitiven-level runter verifizierbar richtig rechnen, und es 
darf nicht irgendwo haengen bleiben, wenn ein Bit kippt oder boesartiger 
Laufzeit-Code injiziert wird.

> Theoretisch wäre es möglich, sich auf das myHDL oder Python zu beziehen,
> wenn die Übersetzung ausreichend gesichert ist, aber diesbezüglich haben
> wir ständig ein Problem, ModelSIMs CODE-COVERAGE mit ins Spiel zu
> bringen, das unsere Kunden oft verlangen, wenn automatische
> Code-Erzeuger aktiv waren.

Coverage kann man schon auch elegant mit Python machen. Die Frage ist, 
wie man die Coverage-Beweise auf die HDL-Ausgabe uebertraegt, ohne 
nochmal extra alles durch Modelsim spulen zu muessen. Bei ersten 
Experimenten habe ich schlicht den V*-Transfer uebersprungen und die 
direkt synthetisierte RTL auf Primitiven-Level mit Hilfe der yosys-Tools 
verifiziert.

von Jürgen S. (engineer) Benutzerseite


Lesenswert?

Frank O. schrieb:
> Das wäre für manche Anwendungsfälle aber ein Killer. Wir machen z.B.
> sehr viel formale Verifikation und Qualifizierung von Code und brauchen
> da verlässlichen output.
Ich meine, dass gerade bei der formalen Verifikation möglich sein 
müsste, das auf einer höheren Abstraktionsebene /-sprache zu leisten.

Martin S. schrieb:
> Die Frage ist schlussendlich,
> was der Kunde akzeptiert. Hier in der Umgebung schwierig, da wird auf
> Schaumschlaegerei mehr Wert gelegt als auf Beweise.
:-) Das kenne ich. Allerdings kommt man kaum umhin, wenn ein Kunde eine 
hauseigene Verifikationsstrategie hat, der man folgen muss. Oft kommt es 
auch vom Kunden des Kunden und man hat gar keinen Einfluss. Gleichwohl 
haben solche Verfahren über die Zeit gute Chance, sich zu etablieren.

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.