Hi guten Tag,
ich habe hier ein System Verilog Code für eine Hashfunktion. Ich habe
den Code aus C übernommen. Leider komme ich nicht weiter. In ModelSim
hat es geklappt mit der Simulation. In Quartus lässt sich der "Code"
aber nicht "compilieren".
Hier die Fehlermeldung aus Quartus:
1
Error: Quartus Prime Analysis & Synthesis was unsuccessful. 1 error, 24 warnings
2
Error: Peak virtual memory: 630 megabytes
3
Error: Processing ended: Sun Jul 28 23:45:53 2019
4
Error: Elapsed time: 00:00:18
5
Error: Total CPU time (on all processors): 00:00:43
6
Error (293001): Quartus Prime Full Compilation was unsuccessful. 3 errors, 24 warnings
Interessant ist hier zum Beispiel: Peak virtual memory mit 630 MB.
Wahrscheinlich ist in dem Code etwas , was zu viel Speicher beansprucht
für einen FPGA.
Evtl. ist das mit der For Schleife nicht so gut gelöst, siehe unten.
Hier der Code bis zur wahrscheinlichen Fehlerquelle:
1
module sha1(
2
);
3
// ##### Variablen
4
int unsigned m; // anzahl msg bits
5
int unsigned mp; // anzahl padded msg bits
6
int unsigned k; // anzahl 0 en
7
int unsigned anzBloecke =2;
8
int unsigned anzWoerter;
9
//int unsigned testarray [4000:0] ;
10
int unsigned test [0:15] = '{'h61626380,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'h00000018};
11
int unsigned a;
12
int unsigned b;
13
int unsigned c;
14
int unsigned d;
15
int unsigned e;
16
17
int unsigned H0='h67452301;
18
int unsigned H1='hefcdab89;
19
int unsigned H2='h98badcfe;
20
int unsigned H3='h10325476;
21
int unsigned H4='hc3d2e1f0;
22
23
int unsigned H0save='h67452301;
24
int unsigned H1save='hefcdab89;
25
int unsigned H2save='h98badcfe;
26
int unsigned H3save='h10325476;
27
int unsigned H4save='hc3d2e1f0;
28
int unsigned Wj[80]; // Parameter muss für jeden Block M neu berechnet werden
29
//##### Funktionen
30
function int add(input int s1,s2);
31
add = s1+s2;
32
$display("beste leben");
33
endfunction
34
//# Rotate Left x = variable n = rotationen
35
function int unsigned rotl(input int unsigned x,n);
36
rotl=((x << n) | (x >> (32 - n)));
37
endfunction
38
39
//## f1...f4
40
function int unsigned f1(input int unsigned b,c,d);
41
f1=((b & (c)) | ((~b) & d));
42
endfunction
43
44
function int unsigned f2(input int unsigned b,c,d);
45
f2= (b ^ c ^ d);
46
endfunction
47
48
function int unsigned f3(input int unsigned b,c,d);
49
f3= ((b & c) | ((b & d) | (c & d)));
50
endfunction
51
52
function int unsigned f4(input int unsigned b,c,d);
53
f4= (b ^ c ^ d);
54
endfunction
55
56
57
58
// es soll hier eine Nachricht erwartet werden die in einem int unsigned array kommt. jedes wort/ Element hat dabei 32 Bit
59
// Padding algorithm
60
61
initial begin
62
63
// # Padding, Die Nachricht wird nun gepadded:
64
// # die gepaddete Nachricht besteht aus:
65
// # Nachrichtenlänge = m
66
// # Leangeninformation = m64
67
// # Ein Bit am Ende der Nachricht = 1
68
// # Auffüllen damit vielfaches von 512 = k
69
k = 512 - ((m + 1 + 64) % 512);// # Berechnung von k = anzahl von anzuhängenden "0"-Bits damit die gepaddedet Nachricht ein Vielfaches von 512 ist
mp = anzBloecke * 512; // Anzahl Bits nach padding
72
anzWoerter = anzBloecke * 16;
73
74
// füge an stelle m+1 die 1 hinzu
75
76
// füge k nullbits hinzu
77
// fürge 64 bits mit der information der leange hinzu
Hier an dieser Stelle wird es problematisch:
1
for( int r=0; r<1; r++) begin// sha1 4 Rounds for each Block
2
3
for(int i = 0; i<16;i++) begin // Wj: im betreffenden Block r werden zuerst 16 Wj Wert 0...15 herausgelesen für Wj
4
Wj[i] = test[(r*16)+i]; // r = aktueller block bei r = 0 wörter: 0...15 lesen, bei r = 1 => 16...31 usw. öletzter block und element bzw. letztes wort: bei 3 *16 +15 =>48...63
5
end
Vielleicht sieht jemand ja sofort den Fehler, weil er einfach
offensichtlich ist :D
Danke !
Bliad B. schrieb:> Hier die Fehlermeldung aus Quartus:Error: Quartus Prime Analysis &> Synthesis was unsuccessful. 1 error, 24 warnings> Error: Peak virtual memory: 630 megabytes> Error: Processing ended: Sun Jul 28 23:45:53 2019> Error: Elapsed time: 00:00:18> Error: Total CPU time (on all processors): 00:00:43> Error (293001): Quartus Prime Full Compilation was unsuccessful. 3> errors, 24 warnings
Das ist (höchstwahrscheinlich) nicht der eigentliche Fehler. Such'
weiter vorne. Ich würde (Schuß ins Blaue) vermuten, deine
Schleifen-Maxima sind nicht konstant.
Verilog sieht zwar (ein bißchen) aus wie C, ist aber keins.
Dir ist klar, wie HDLs for-Schleifen in Hardware umsetzen?
Anscheinend nicht.
Schleifen werden durch die HDL vollständig ausgerollt. D.h. - so wie
geschrieben - passiert alles, was in der Schleife ablaufen soll, in der
Hardware-Umsetzung parallel und innerhalb eines einzigen Taktes.
Falls Du das überhaupt zum Laufen bekommst, wird die maximale
Taktfrequenz höchstwahrscheinlich unterirdisch sein.
Bliad B. schrieb:> Vielleicht sieht jemand ja sofort den Fehler
Du berechnest den Wert mit jedem Takt in einer riesengroßen
kombinatorischen Schaltung.
> Wahrscheinlich ist in dem Code etwas , was zu viel Speicher beansprucht> für einen FPGA.
Er bekommt die Tabelle, die für das Aufdröseln der Funktion in
Kombinatorik nötig wäre, nicht ins RAM. Und weil du parallel auf das
Array zugreifst, kann er das nicht in einen speicherblock packen,
sondern muss jedes Bit mit einzelnen Flipflops aus den Funktionsblöcken
nachbilden. Vermutlich ist dafür dann das FPGA schon zu klein, denn
schon die beiden Arrays (test und Wj) brauchen zusammen über 3000
Flipflops.
Vom testarray mal gar nicht zu reden...
Fazit: um das Ganze tatsächlich ins FPGA zu bekommen, musst du die
Hash-Funktion so umarbeiten, dass er Takt für Takt einen Wert nach dem
anderen bearbeitet.
Lothar M. schrieb:> Er bekommt die Tabelle, die für das Aufdröseln der Funktion in> Kombinatorik nötig wäre, nicht ins RAM.
das ist zwar einigermassen wahrscheinlich, aber nicht unbedingt gesagt.
Für diejenigen, die Quartus nicht kennen: die o.a. "Fehlermeldung" ist
die ganz normale Quartus "Fertigmeldung". Also kein Fehler.
Und daß Quartus mal 630 MB Hauptspeicher braucht, ist auch völlig normal
(bzw. eher wenig).
Die Tatsache, daß bereits nach 18 Sekunden abgebrochen wird, spricht
eher dafür, daß - zusätzlich zur schon diskutierten Problematik - noch
irgendwo ein Syntaxfehler steckt. So wahnsinnig viel kann Quartus da
nämlich noch nicht gemacht haben...
Dein Code beschreibt einen Algorithms, keine Struktur. Deswegen
funktioniert er im Simulator, geht aber nicht durch die Synthese. Hast
du dir Gedanken darum gemacht, wie das spätere Hardwaredesign auf
RTL-Ebene aussehen soll?
Es gibt keinen Takt, keinen Reset, keine Register. Dein Modul hat zudem
keine Eingänge und keine Ausgänge... wie soll das Design an seine Daten
kommen und wo soll es die Ergebnisse hinliefern? Selbst wenn die
Synthese durchlaufen würde, käme der Optimizer korrekterweise zu dem
Schluss, dass ein Design, das keine Daten bekommt, nichts zu tun hat und
würde es komplett wegoptimieren.
Auch wenn es nervt, ich sage es nochmal: Um HDL zu verstehen, musst Du
etwas über Digitaldesign lernen. Wenn du mal eine LED zum Blinken oder
einen Zähler zum Zählen gebracht hast, wirst Du verstehen, warum dein
Design nicht mal ansatzweise funktionieren kann.
wenn man dann noch folgendes hinzufügt kommt auf jeden fall mal ein
fehler
1
for( int r=0; r<anzBloecke; r++)begin
2
end //endfor
3
end
Error (10119): Verilog HDL Loop Statement error at synthtest.sv(82):
loop with non-constant loop condition must terminate within 250
iterations
Ist also schon mal ein guter Hinweis :D
werden mal weitermachen !
komischf finde ich aber, dass ich das weiter oben im code bekannt
gegeben habe, dass anzbloecke =2 ist !
warum hat das tool dann solche Angst, dass es 250 wird ?
Bliad B. schrieb:> bekannt gegeben habe
Mit einer Variablen, die Werte von −2.147.483.648 bis +2.147.483.647
annehmen könnte.
Mach mal eine Konstante draus.