Forum: FPGA, VHDL & Co. Scheinbar gleicher Code verursacht Unterschiedliches


von Christian P. (kron)


Lesenswert?

Hallo,

habe hier ein sonderbares Problem.
Ich werte einen 4bit-Vektor aus (TR_IN), und zwar jeweils 2 bits 
zusammen
(also bit 3 und 2 und bit 1 und 0). Dies hatte ich ursprünglich so 
gemacht:
---------------
if (TR_IN (1 downto 0) = "01") OR (TR_IN (1 downto 0) = "10") then
 tr_imp_k1_tmp <= '1';
 count_tr_of_k1 <= count_tr_of_k1 + 1;
end if;

if (TR_IN (3 downto 2) = "01") OR (TR_IN (3 downto 2) = "10") then
 tr_imp_k2_tmp <= '1';
 count_tr_of_k2 <= count_tr_of_k2 + 1;
end if;

if (TR_IN (1 downto 0) = "01") then
 ef_1 <= '1';
end if;

if (TR_IN (3 downto 2) = "01") then
 ef_2 <= '1';
end if;
----------------
Dieser Code verursachte im ganzen Projekt große Fehler.
Daraufhin habe ich nach langer Fehlersuche eine case-Anweisung daraus 
gemacht, in der alle möglichen Konstellationen von TR_IN enthalten sind:
----------------
case TR_IN is

when "0001" =>
  tr_imp_k1_tmp <= '1';
  count_tr_of_k1 <= count_tr_of_k1 + 1;
  ef_1 <= '1';
when "0010" =>
  tr_imp_k1_tmp <= '1';
  count_tr_of_k1 <= count_tr_of_k1 + 1;
when "0100" =>
  tr_imp_k2_tmp <= '1';
  count_tr_of_k2 <= count_tr_of_k2 + 1;
  ef_2 <= '1';
when "1000" =>
  tr_imp_k2_tmp <= '1';
  count_tr_of_k2 <= count_tr_of_k2 + 1;
when "0101" =>
  tr_imp_k1_tmp <= '1';
  count_tr_of_k1 <= count_tr_of_k1 + 1;
  ef_1 <= '1';
  tr_imp_k2_tmp <= '1';
  count_tr_of_k2 <= count_tr_of_k2 + 1;
  ef_2 <= '1';
when "0110" =>
  tr_imp_k1_tmp <= '1';
  count_tr_of_k1 <= count_tr_of_k1 + 1;
  tr_imp_k2_tmp <= '1';
  count_tr_of_k2 <= count_tr_of_k2 + 1;
  ef_2 <= '1';
when "1001" =>
  tr_imp_k1_tmp <= '1';
  count_tr_of_k1 <= count_tr_of_k1 + 1;
  tr_imp_k2_tmp <= '1';
  count_tr_of_k2 <= count_tr_of_k2 + 1;
  ef_1 <= '1';
when "1010" =>
  tr_imp_k1_tmp <= '1';
  count_tr_of_k1 <= count_tr_of_k1 + 1;
  tr_imp_k2_tmp <= '1';
  count_tr_of_k2 <= count_tr_of_k2 + 1;
when others =>
  null;
end case;
--------------------

Und diese Anweisung funktioniert tadellos.
Damit ist ja eigentlich alles klar und schön, nur hätte ich sehr gerne
verstanden, was an den obigen IFs falsch ist.
Sieht oder weiß da jemand was?

von Joerg W. (joergwolfram)


Lesenswert?

ich denke, es fehlen einfach die else-Zweige in den if-statements, die 
Signale werden nur gesetzt.

Jörg

von Joerg W. (joergwolfram)


Lesenswert?

Ausserdem scheint in beiden Versionen die Flankenauswertung für die 
Zähler zu fehlen (rising_edge ode so)

Gruß Jörg

von Christian P. (kron)


Lesenswert?

>ich denke, es fehlen einfach die else-Zweige in den if-statements, die
>Signale werden nur gesetzt.

Das gleiche passiert ja auch bei der Case-Anweisung.
Die Signale werden anderswo zurückgesetzt.

>Ausserdem scheint in beiden Versionen die Flankenauswertung für die
>Zähler zu fehlen (rising_edge ode so)
Das rundherum habe ich jetzt aus Platzgründen weggelassen,
ich habe nur das wesentliche reinkopiert. Wie schon geschrieben 
funktioniert
der Code mit der Case-Anweisung 100%ig.
Mich wurmt nur, dass ich nicht weiß, warum das mit den ifs nicht klappt.

von Christian P. (kron)


Lesenswert?

Hat keiner 'ne Idee?

von Fried V. (tich)


Lesenswert?

Was meckert der Compiler denn an?

von na (Gast)


Lesenswert?

Würd auch sagen, dass es an den fehlenden else liegt. Dann werden evtl. 
Latches synthetisiert. Versuchs doch einfach mal mit den else, ist ja 
nicht so aufwendig. Oder aber, du setzt in dem Prozess ganz am Anfang 
Standardwerte für die Signale, die in den ifs Werte bekommen (alle auf 0 
zum Beispiel).

von Schlumpf (Gast)


Lesenswert?

So wie es aussieht, werden in beiden Beschreibungen Laches erzeugt. Und 
das ist grundsätzlich schonmal schlecht.
Versuch entweder in allen Bedingugen alle Singale zuzuweisen oder mach 
den Prozess getaktet und register deine Signale.

von FPGA-Küchle (Gast)


Lesenswert?

Wenn keiner eine prompte Lösung hat, dann weil das problem in der 
fragestellung nicht sichtbar ist.



#Dieser Code verursachte im ganzen Projekt große Fehler.

Was sind für Dich große Fehler? Brechen die Tools ab? Ist das Verhalten 
ein anderes? Was verhält sich anders als erwartet? Ohne diese Antworten 
können wir den Code nur auf unpraktische Schreibweise durchsuchen.
Oder ich rate: Multiple sources?; X im in der simu?

#Das rundherum habe ich jetzt aus Platzgründen weggelassen,
#ich habe nur das wesentliche reinkopiert. Wie schon geschrieben
#funktioniert

Packe reinkopierten code zwischen vhdl und /vhdl in eckigen Klammern und 
benutze den Vorschaue-Button, dann sieht der Code besser aus wie hier:
1
if (TR_IN (1 downto 0) = "01") OR (TR_IN (1 downto 0) = "10") then
2
 tr_imp_k1_tmp <= '1';
3
 count_tr_of_k1 <= count_tr_of_k1 + 1;
4
end if;
5
6
if (TR_IN (3 downto 2) = "01") OR (TR_IN (3 downto 2) = "10") then
7
 tr_imp_k2_tmp <= '1';
8
 count_tr_of_k2 <= count_tr_of_k2 + 1;
9
end if;
10
11
if (TR_IN (1 downto 0) = "01") then
12
 ef_1 <= '1';
13
end if;
14
15
if (TR_IN (3 downto 2) = "01") then
16
 ef_2 <= '1';
17
end if;


Ich habe vor dem Code eine Zeile mit vhdl in [ ] geschrieben und danach 
eine mit /vhdl auch in [ ].
Und du kannst den Code in einer Datei an Deine Anfrage anhängen.

Dein Problem wird zu 50% die "Rücksetzbedingung woanders im Code" sein.
Da kommt nur Murks raus. Das muss im selben prozess stehen, es muß nicht 
unbedingt eine Else oder ein Elsif sein, aber wenn du ein FliFlop habe 
willst dann muß in einem Prozess das Setzen und das Rücksetzten 
beschrieben sein. Beispiel

1
architecture karnickel of Zauberwald is
2
 begin
3
4
process(clk_i)
5
begin
6
 if rising_edge(clk_i) then
7
   if setz_signal = '1' then
8
    beispiel_1 <= '1' 
9
   elsif ruecksetz_signal = '1' then
10
    beispiel_1 <= '0'  
11
   end if;
12
 end if;
13
end process;
14
15
16
17
--irgendwo anders, hier besipielsweise außerhalb eines prozesses
18
19
setz_signal  <= eingang1_i AND eingeang_3_i;
20
21
rücksetzsignal <= NOT eingang2_i;
22
23
end architecture;


Wohlgemerkt das Rücksetzten muss im selben prozess beschrieben sein, das 
signal das das Rücksetzen auslöst kann irgendwo anders stehen.

Die anderen 50% deines Problems, warum das case tut und das If nicht, 
ist sicherlich der Others Zweig mit dem Null. IMHO heisst das, das die 
Signale nicht vom Prozess getrieben werden, wenn die When bedingungen 
nicht erfüllt werden. Du kannst ja mal schreiben
1
when others =>  ;
2
3
--oder
4
5
when others =>
6
  dummy_signal <= '1';

Dann könnte das Case-Konstrukt genauso wirken wie das If. Oder du 
schreibst:
1
if (TR_IN (1 downto 0) = "01") then
2
 ef_1 <= '1';
3
else
4
 ef_1 <= null;  --vielleicht auch nur null
5
end if;

Aber das ist mE nur Dein verständnisproblem, dein Designproblem ist die 
"Rücksetzbedingung sonstwo". Das ist nicht C, das ist eine 
Hardware-beschreibungssprache. Und falls due ein FF willst, musst du in 
einem Prozess, setzen und Rücksetzten beschreiben, aber nicht die eine 
Hälfte in diesem Prozess und die andere in einem Zweiten. Und dann 
vielleicht noch mit unterschiedlichen Takt(-flanken) }:-0 das geht 
nicht! Aber ohne kompletten Code und Fehlerbeschreibung können wir nur 
weiter raten. Aber schau mal nach was eine null zuweisung oder null in 
VHDL tut.







von FPGA-Küchle (Gast)


Lesenswert?

Ich hab ein paar ; vergessen, auch anderswo können Tippfühler im Syntax 
stecken.

von Christian P. (kron)


Lesenswert?

Hallo,

erstmal vielen Dank für die reichlichen Antworten.
Ok, hier ist zweimal der gesamte Prozess, in dem die Anweisungen von 
oben stehen, zuerst mit IF (der "Böse"), und dann mit Case:
1
process (CLK, tr_count_del, RESET, SOA)
2
begin                                                   
3
if (RESET = '1') OR (tr_count_del = '1') OR (SOA = '0') then 
4
  tr_imp_k1_tmp <= '0';
5
  tr_imp_k2_tmp <= '0';
6
  ef_1 <= '0';                                        
7
  ef_2 <= '0';
8
  count_tr_of_k1 <= 0;
9
  count_tr_of_k2 <= 0;
10
elsif (CLK'event and CLK = '1') then                
11
  if (TR_IN (1 downto 0) = "01") OR (TR_IN (1 downto 0) = "10") then      
12
    tr_imp_k1_tmp <= '1';                            
13
    count_tr_of_k1 <= count_tr_of_k1 + 1;            
14
  end if;    
15
  if (TR_IN (3 downto 2) = "01") OR (TR_IN (3 downto 2) = "10") then
16
    tr_imp_k2_tmp <= '1';
17
    count_tr_of_k2 <= count_tr_of_k2 + 1;
18
  end if;
19
  if (TR_IN (1 downto 0) = "01") then                    
20
    ef_1 <= '1';
21
  end if;    
22
  if (TR_IN (3 downto 2) = "01") then
23
    ef_2 <= '1';
24
  end if;
25
end if; 
26
end process;
1
process (CLK, tr_count_del, RESET, SOA)
2
begin                                                   
3
if (RESET = '1') OR (tr_count_del = '1') OR (SOA = '0') then 
4
  tr_imp_k1_tmp <= '0';
5
  tr_imp_k2_tmp <= '0';
6
  ef_1 <= '0';                                        
7
  ef_2 <= '0';
8
  count_tr_of_k1 <= 0;
9
  count_tr_of_k2 <= 0;
10
  elsif (CLK'event and CLK = '1') then  
11
  case TR_IN is
12
  when "0001" =>
13
    tr_imp_k1_tmp <= '1';                          
14
    count_tr_of_k1 <= count_tr_of_k1 + 1;            
15
    ef_1 <= '1';                                    
16
  when "0010" =>
17
    tr_imp_k1_tmp <= '1';                            
18
    count_tr_of_k1 <= count_tr_of_k1 + 1;            
19
  when "0100" =>
20
    tr_imp_k2_tmp <= '1';
21
    count_tr_of_k2 <= count_tr_of_k2 + 1;
22
    ef_2 <= '1';                                    
23
  when "1000" =>
24
    tr_imp_k2_tmp <= '1';
25
    count_tr_of_k2 <= count_tr_of_k2 + 1;
26
  when "0101" =>
27
    tr_imp_k1_tmp <= '1';                            
28
    count_tr_of_k1 <= count_tr_of_k1 + 1;            
29
    ef_1 <= '1';                                    
30
    tr_imp_k2_tmp <= '1';
31
    count_tr_of_k2 <= count_tr_of_k2 + 1;
32
    ef_2 <= '1';                                    
33
  when "0110" =>
34
    tr_imp_k1_tmp <= '1';                            
35
    count_tr_of_k1 <= count_tr_of_k1 + 1;            
36
    tr_imp_k2_tmp <= '1';
37
    count_tr_of_k2 <= count_tr_of_k2 + 1;
38
    ef_2 <= '1';                                    
39
  when "1001" =>
40
    tr_imp_k1_tmp <= '1';                            
41
    count_tr_of_k1 <= count_tr_of_k1 + 1;            
42
    tr_imp_k2_tmp <= '1';
43
    count_tr_of_k2 <= count_tr_of_k2 + 1;
44
    ef_1 <= '1';                                    
45
  when "1010" =>
46
    tr_imp_k1_tmp <= '1';                            
47
    count_tr_of_k1 <= count_tr_of_k1 + 1;            
48
    tr_imp_k2_tmp <= '1';
49
    count_tr_of_k2 <= count_tr_of_k2 + 1;
50
  when others =>
51
    null;
52
  end case;
53
end if;
54
end process;

So, das sollte schonmal einige der Punkte von euch klären.
Sorry, dass ich nicht gleich den ganzen Prozess geschickt habe,
aber ich wollte nicht einen endlos langen Thread machen. :)

So, zuerst zu den Fehlern.
Also der Prozess ist Teil eines relativ großen Designs.
Keine der beiden Varianten macht beim Synthetisieren Probleme,
das Design macht auf dem FPGA Probleme, und zwar in einem
ganz anderen Teil, der diesem Prozess vorgeschaltet ist
(dort wird das TR_IN erzeugt) und auch kein Feedback von diesem
Prozess hier bekommt.

>Würd auch sagen, dass es an den fehlenden else liegt. Dann werden evtl.
>Latches synthetisiert.

>So wie es aussieht, werden in beiden Beschreibungen Laches erzeugt. Und
>das ist grundsätzlich schonmal schlecht.

Also das ganze Design ist eigentlich streng getaktet,
das TR_IN wird getaktet erzeugt und kommt so rein.
Oder verstehe ich das jetzt falsch, also Latches sind doch
NICHTtaktgesteuerte Register, oder (Wie heißen taktgesteuerte 
eigentlich)?

>Aber schau mal nach was eine null zuweisung oder null in VHDL tut.
Öhm, also in meinen Büchern steht prinzipiell "Nichts".
Also es macht nichts. Und das soll es hier ja auch.
Aber hier besteht (bei mir) durchaus noch Klärungsbedarf,
also bitte belehrt mich. :)

Habe ich das jetzt richtig verstanden, dass das ganze laufen sollte,
wenn ich bei den IFs jeweils schreibe "else NULL;" ?
Weil ich dachte, dass das sowieso nix macht, wenn da nur IF sowieso 
steht.
IF Q = '1' then A = '1' heißt doch, wenn Q 1 ist, setze A auch auf 1.
Und wenn nicht, also wenn Q nicht 1 ist, mach bitte nix.
Oder verstehe ich das falsch?

von fpgakuechle (Gast)


Lesenswert?

Hm, also Null schaltet den Signaltreiber ab, ansosnsten treibt er den 
vorhergehenden wert.

Also
(1)die bedingung zum setzten wird erfüllt dann wird eine '1' getrieben
(2)keine bedingung wird erfüllt, aber vorher war die setzbedingung wird 
erfüllt -> es wird immer noch eine '1' getrieben
(3) es wird Null gesagt (wie auch immer) dann bleibt die eins wenn kein 
andere Quelle das signal treibt, ansosonsten gewinnt das andere Signal
(4) es wird eine '1' getrieben (weil (1) oder (2) und wg. einer anderen 
bedingung wird eine '0' getrieben, dann kommt X raus.

Also Null heisst nicht das nix passiert, es heisst das von dieser stelle 
nix neues passiert (signaltreiber abgeschaltet), von anderen stellen 
kann was passieren. Wenn zwei stellen treiben dann geht es durch die 
resolution funktion also bei std_logic:

stelle 1   stelle2   Ergebnis
'1'          '0'       X
'1'           'Z'      1
'1'           '1'      1 (?), ich bion mir nicht sicher eventuell auch X
'1'           null      '1'
'0'            null    '0'
'1'            'u'     'u' oder 'X'

u heisst unassigned, also wert wurde noch nie zugewiesen, nicht zu 
wechseln mit 'X' -> unknown -unbekannt (z.B. wg. crash('1' und '0'von 
zwei Quellen ))?


#IF Q = '1' then A = '1' heißt doch, wenn Q 1 ist, setze A auch auf 1.
#Und wenn nicht, also wenn Q nicht 1 ist, mach bitte nix.
#Oder verstehe ich das falsch?

wahrscheinlich, es heisst wenn Q nicht 1 dann ÄNDERE nix also der alte 
Wert wird getrieben -> typ. VBerhalten eines FF.
Ändere Nix ist nicht da selbe wie MACH nix. Mach nix heisst Null 
(Signaltreiber abschalten).

Vielleicht kann man sagen, mach nix gibt es im FPGA nicht und daher im 
synthetisierbaren VHDL auch nicht. IM Fpga gibt es Änderen oder nicht 
ändern, aber gemacht wird immer was. (schlecht zu beschreiben das ist)


















von Christian P. (kron)


Lesenswert?

Ok, das hab ich soweit verstanden.
Mach nix heißt in dem Fall dann halt nur "lass es so, wie es ist".

Ist dann dieses null gleichzusetzen mit einer Tristate-Konstruktion,
also wie z.B. bei einem bidirektionalen Datenbus, den ich so steuere:
1
DATA_IO <= data_out when out_enable = '1' else (others => 'Z');
2
data_in <= DATA_IO;
Kann man sowas auch mit "null" machen?

Ich habe jetzt mal probehalber in der IF-Version
bei allen verzweigungen "else null;" eingefügt,
der Fehler bleibt aber der gleiche...

von Klaus Falser (Gast)


Lesenswert?

Ich glaube man muß unterscheiden zwischen dem NULL statement oder der 
NULL Zuweisung.

if Q = '1' then
   A <= '1';
else
   null;
end if;

bewirkt daß A sich nicht ändert.

Aber
if Q = '1' then
   A <= '1';
else
   A <= null;
end if;

schaltet den Driver ab. Wird nicht sehr oft verwendet, mir war die null 
Zuweisung jedenfalls unbekannt und kann für die Synthese sicher nicht 
verwendet werden.

von Klaus Falser (Gast)


Lesenswert?

Zur Ergänzung :

Das NULL statement in :

if Q = '1' then
   A <= '1';
else
   null;
end if;

ist natürlich überflüssig !!

von fpgakuechle (Gast)


Lesenswert?

Also der erste sichtbare Unterschied den ich sehe ist das Null 
statement, sonst ist alles gleich. wenn null nicht dasselbe macht wie <= 
null (warum auch); da liege ich natürlich mit meiner vermutung falsch. 
Und es kann nicht darin liegen.

Ein anderer Unterschied ist das when eigentlich mit if elsif übersetzt 
wird. Also so wie du dein If  schreibst, passt kein elsif, da sehe ich 
also (noch) kein Problem.

Sowie es klingt, verhalten sich die synthetisierten designs 
unterschiedlich,
also wird wohl der (eigentlich funktional identische) Code 
unterschiedlich übersetzt. Da könnt was im synthesereport stehen 
(Xilinx: *.syr).

von Christian P. (kron)


Lesenswert?

Naja, ich behandele das TR_IN ja schon unterschiedlich,
bei den IFs frage ich die ersten und letzten beiden Bits getrennt ab,
wogegen ich bei dem Case-Statement alle möglichen auftretenden Fälle 
abhandele.

von na (Gast)


Lesenswert?

In einem getakteten Prozess kann es nicht an Latches liegen und du 
kannst die else weglassen, das stimmt, aber das konnte man aus deinem 
ersten Post ja nicht ablesen.
Die Frage, die ich mal in den Raum stellen würde ist, ob dein Code 
überhaupt das gleiche macht? Mit den if fragst du nur den folgende Fälle 
ab, in denen was passiert:
"0101","0110","1001","1010"

Im case-statement wird z.B. auch bei "0001" was ausgeführt...? Wie das?

von na (Gast)


Lesenswert?

Achso, entschuldige, durch die einzelnen if-Anweisungen werden natürlich 
auch die anderen Fälle abgefagt.

von na (Gast)


Lesenswert?

Aber was passiert z.B bei "1101"? Bei deiner if-Anweisung kommt eine 
Zuweisung, im case nicht.

von Christian P. (kron)


Lesenswert?

Diese Konstellation wird nicht auftreten, die beiden Bitpaare von TR_IN 
können nur 00,01 oder 10 sein, nicht aber 11.

von alex (Gast)


Lesenswert?

wer glaubt's, wird selig ;)

von na (Gast)


Lesenswert?

Vielleicht solltest du mal ein paar Differenzen der 
Simulationsergebnisse posten, dann würde eine Analyse wesentlich besser 
funktionieren. Oder funktioniert die Simulation gleich und nur direkt 
der Test auf dem FPGA macht Probleme?

von Rick Dangerus (Gast)


Lesenswert?

@Christian:
>können nur 00,01 oder 10 sein, nicht aber 11

Das weißt aber nur Du und nicht der Compiler. Änder doch mal den letzten 
case -Fall, dass Du 10 und 11 zu "when others" zusammenfasst.

Rick

von Lothar (Gast)


Lesenswert?

Ich vermute mal, dass deine großen Probleme darin liegen, dass das 
Design so in etwa läuft, aber manchmal (jede Sekunde, jede Minute, jede 
Stunde, einmal am Tag) nicht so richtig tut.
Das sind die wirklich großen Probleme.

And now ladies and gentlemen, we proudly present:

-->> Der kombinatorische asynchrone Reset <<--
1
:
2
if (RESET = '1') OR (tr_count_del = '1') OR (SOA = '0') then 
3
:
Ich hatte da auch mal so ein Design, da waren in der Rücksetz-Bedingung 
so ähnliche Konstrukte. Das lief, solange die Steuerung kalt war, aber 
nach einer Stunde wars vorbei. Dann habe ich irgendwas im Code geändert, 
und dann hat sich irgendwas im Verhalten der Steuerung geändert.

1) So einen kombinatorischen Reset darf es nicht geben (es sei denn man 
liebt Probleme)
2) in die Process-Sensitivity-List gehören maximal Reset und Takt, 
besser noch: nur der Takt (Reset ist dann synchron)

Es ist eben so: wenn eines der Rücksetz-Signale z.B. von einem Zähler 
kommt und/oder sonstwoher kombinatorisch erzeugt wird, gibt es einen 
kurzen Glitch und ein paar der FFs werden zurückgesetzt (aber eben nicht 
alle und noch fieser: nicht immer die selben).

Probiers doch mal eher so:
1
process (CLK)
2
begin                                                   
3
if (rising_edge(CLK)) then                
4
  if (TR_IN (1 downto 0) = "01") OR (TR_IN (1 downto 0) = "10") then      
5
    tr_imp_k1_tmp <= '1';                            
6
    count_tr_of_k1 <= count_tr_of_k1 + 1;            
7
  end if;    
8
  if (TR_IN (3 downto 2) = "01") OR (TR_IN (3 downto 2) = "10") then
9
    tr_imp_k2_tmp <= '1';
10
    count_tr_of_k2 <= count_tr_of_k2 + 1;
11
  end if;
12
  if (TR_IN (1 downto 0) = "01") then                    
13
    ef_1 <= '1';
14
  end if;    
15
  if (TR_IN (3 downto 2) = "01") then
16
    ef_2 <= '1';
17
  end if;
18
  if (RESET = '1') OR (tr_count_del = '1') OR (SOA = '0') then 
19
    tr_imp_k1_tmp <= '0';
20
    tr_imp_k2_tmp <= '0';
21
    ef_1 <= '0';                                        
22
    ef_2 <= '0';
23
    count_tr_of_k1 <= 0;
24
    count_tr_of_k2 <= 0;
25
  end if;
26
end process;

Jetzt nur noch etwas aufpassen mit der Latency.


Lothar

von Christian P. (kron)


Lesenswert?

@Lothar: Vielen Dank für deine Antwort!
Erstmal nur ganz schnell: das "böse" Reset habe
ich doch aber auch in der anderen Variante, und dort
läuft das Design tadellos?!

von Lothar (Gast)


Lesenswert?

@Christian: Ja, wie gesagt, es läuft schon, meistens.
Aber du darfst so ein Design nicht großartig ändern (z.B. auch andere 
Zielhardware), denn sonst ändert sich das FPGA-interne Layout, damit das 
Timing und: RUMMS.

Wirklich transportabel und reproduzierbar ist nur ein komplett 
synchrones Design: alle Zustände ändern sich ausschliesslich mit dem 
Takt, einzige Ausnahme: der (oft unnötige  [aber das ist eine andere 
Sache]) externe asynchrone Reset.
Wobei ich immer auch so einen Reset erst mal synchronisiere und dann im 
FPGA intern verwende.

von Lothar (Gast)


Lesenswert?

@Christian: Hat sich schon was getan? Läuft dein Design? Ich lerne gerne 
noch dazu: Was war die Ursache für den Fehler?

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.