www.mikrocontroller.net

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


Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Joerg Wolfram (joergwolfram)
Datum:

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

Jörg

Autor: Joerg Wolfram (joergwolfram)
Datum:

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

Gruß Jörg

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat keiner 'ne Idee?

Autor: Fried Vissel (tich)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was meckert der Compiler denn an?

Autor: na (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Schlumpf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: FPGA-Küchle (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
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;



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

architecture karnickel of Zauberwald is
 begin

process(clk_i)
begin
 if rising_edge(clk_i) then
   if setz_signal = '1' then
    beispiel_1 <= '1' 
   elsif ruecksetz_signal = '1' then
    beispiel_1 <= '0'  
   end if;
 end if;
end process;



--irgendwo anders, hier besipielsweise außerhalb eines prozesses

setz_signal  <= eingang1_i AND eingeang_3_i;

rücksetzsignal <= NOT eingang2_i;

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
when others =>  ;

--oder

when others =>
  dummy_signal <= '1';



Dann könnte das Case-Konstrukt genauso wirken wie das If. Oder du 
schreibst:
if (TR_IN (1 downto 0) = "01") then
 ef_1 <= '1';
else
 ef_1 <= null;  --vielleicht auch nur null
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.







Autor: FPGA-Küchle (Gast)
Datum:

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

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht 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:
process (CLK, tr_count_del, RESET, SOA)
begin                                                   
if (RESET = '1') OR (tr_count_del = '1') OR (SOA = '0') then 
  tr_imp_k1_tmp <= '0';
  tr_imp_k2_tmp <= '0';
  ef_1 <= '0';                                        
  ef_2 <= '0';
  count_tr_of_k1 <= 0;
  count_tr_of_k2 <= 0;
elsif (CLK'event and CLK = '1') then                
  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;
end if; 
end process;
process (CLK, tr_count_del, RESET, SOA)
begin                                                   
if (RESET = '1') OR (tr_count_del = '1') OR (SOA = '0') then 
  tr_imp_k1_tmp <= '0';
  tr_imp_k2_tmp <= '0';
  ef_1 <= '0';                                        
  ef_2 <= '0';
  count_tr_of_k1 <= 0;
  count_tr_of_k2 <= 0;
  elsif (CLK'event and CLK = '1') then  
  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;
end if;
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?

Autor: fpgakuechle (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)


















Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht 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:
DATA_IO <= data_out when out_enable = '1' else (others => 'Z');
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...

Autor: Klaus Falser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Falser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zur Ergänzung :

Das NULL statement in :

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

ist natürlich überflüssig !!

Autor: fpgakuechle (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: na (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: na (Gast)
Datum:

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

Autor: na (Gast)
Datum:

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

Autor: Christian Peters (kron)
Datum:

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

Autor: alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wer glaubt's, wird selig ;)

Autor: na (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Rick Dangerus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 <<--
:
if (RESET = '1') OR (tr_count_del = '1') OR (SOA = '0') then 
:
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:
process (CLK)
begin                                                   
if (rising_edge(CLK)) then                
  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;
  if (RESET = '1') OR (tr_count_del = '1') OR (SOA = '0') then 
    tr_imp_k1_tmp <= '0';
    tr_imp_k2_tmp <= '0';
    ef_1 <= '0';                                        
    ef_2 <= '0';
    count_tr_of_k1 <= 0;
    count_tr_of_k2 <= 0;
  end if;
end process;

Jetzt nur noch etwas aufpassen mit der Latency.


Lothar

Autor: Christian Peters (kron)
Datum:

Bewertung
0 lesenswert
nicht 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?!

Autor: Lothar (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar (Gast)
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.