Forum: FPGA, VHDL & Co. Can't infer registers


von Stefan (Gast)


Lesenswert?

Hallo zusammen,
ich habe eine Frage:

Ich möchte einen Prozess abhängig machen vom Zustand meiner FSM und 
einem Clock Event...

Wenn die SM in dem Zustand : Warten spring soll iCounter zurückgesetzt 
werden.

Wenn der Zustand lesen der SM ist soll Werte von Data_Bus in ein 
Register geschrieben werden.

Jedoch sagt Quartus mir : Can't infer registers...

Kann mir da jemand helfen ?
1
Lesen_Pro:    process(IFCLK, Zustand)
2
            begin
3
            
4
            if Zustand = warten then
5
               iCounter2 <= 0;
6
            elsif IFCLK='1' and IFCLK'event then
7
              if Zustand = lesen then
8
                RX_BUFFER(RX_COUNTER)<=DATA_BUS;
9
               iCounter2 <=RX_COUNTER+1;
10
              end if;
11
            else 
12
                iCounter2 <=RX_COUNTER;            
13
            end if;
14
            RX_COUNTER<=iCounter2;
15
16
17
            end process Lesen_Pro;


Vielen Dank

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


Lesenswert?

Formatieren wir das mal erst schön, und machen Nummern dazu:
1
Lesen_Pro:
2
process (IFCLK, Zustand) begin
3
    if Zustand = warten then  -- (1)
4
       iCounter2 <= 0;
5
    elsif IFCLK='1' and IFCLK'event then  -- (2)
6
       if Zustand = lesen then
7
          RX_BUFFER(RX_COUNTER)<=DATA_BUS;
8
          iCounter2 <=RX_COUNTER+1;
9
       end if;
10
    else                                  -- (3)
11
       iCounter2 <=RX_COUNTER;            
12
    end if;
13
14
   RX_COUNTER <= iCounter2;        -- (4)
15
end process Lesen_Pro;
(1) Naja, das kann arg ins Auge gehen: ein Asynchroner Reset...
(2) Jetzt kommt der getaktete Teil des Prozesses. Der Name IFCLK deutet 
darauf hin, dass du in anderen Teilen deines Designs nohc andere Takte 
hast. Da wirst du später noch lustige Effekte erleben...
(3) Jetzt wirds krass: Wenn keine steigende Taktflanke da ist soll 
dieser Teil ausgeführt werden. Weil aber per Definition die Dauer einer 
Taktflanke = 0 ist, sollte dieser Teil an und für sich immer ausgeführt 
werden. Das kann so niemals gehen, so eine Beschreibung wirst du 
nirgends finden.
(4) Und zum guten Schluss wird zum Ende des Prozesses dem RX_COUNTER ein 
Wert zugewiesen. Weil ein Prozess laut VHDL-Definition in 
Nullkommanichts (Durchlaufzeit = 0) von oben her abgearbeitet wird, gilt 
zum Schluss nur diese Zuweisung.

Zur Bewertung:
(1) ist sehr schlechter Designstil.
(2) kann man so machen, wenn das der einzige Takt ist, oder andere 
Taktdomänen einsynchronisiert werden.
(3) kann in einem FPGA nicht implementiert werden.
(4) macht alles Vorhergehende unnötig.

So, fertig gemacht :-/
Jetzt wieder Aufbauarbeit. Wie wärs damit:
1
process (IFCLK) begin
2
    if rising_edge(IFCLK) then  
3
       if (Zustand = warten) then  
4
          RX_COUNTER <= 0;
5
       elsif (Zustand = lesen) then
6
          RX_BUFFER(RX_COUNTER) <= DATA_BUS;
7
          RX_COUNTER <= RX_COUNTER+1;
8
       else                              -- eigentlich unnötig
9
          RX_COUNTER <= RX_COUNTER;      -- dito      
10
       end if;                               
11
    end if;
12
end process;

Mein Tipp:
Du solltest echt mal ein gutes Buch zum Thema lesen.

von Stefan (Gast)


Lesenswert?

Hallo  Lothar ,

vielen Dank für die Tipps,
ein gutes Buch habe ich [naja fast durch](
"VHDL Synthese") ... jetzt versuche ich praxis zu sammeln. Gibt es noch 
etwas besseres?


Ich habe das ganze etwas anders gelöst...

Dein Prozess spring "nur an" wenn der "IFCLK" kommt.

Ich muss aber beim Zustandswechsel von "warten" "lesen" meinen "Pointer" 
zurücksetzten. Wenn ein "IFCLK" kommt und der zustand "lesen" aktiv ist 
sollen die Werte in einen Puffer geschrieben werden.
1
process(IFCLK, Zustand)
2
  begin
3
   if Zustand = warten then
4
       RX_COUNTER <= 0;
5
   
6
   elsif IFCLK='1' and IFCLK'event then
7
      if (Zustand = lesen) then                 
8
         RX_BUFFER(USB_RX_COUNTER)<=USB_DATA_BUS;
9
         USB_RX_COUNTER <=USB_RX_COUNTER+1;
10
      end if;
11
   end if;

Ist der Code immer noch "schrecklich"....

zum thema mehrere Clocks... naja auf der einen Seite geht was mit Speed 
1 rein und auf der anderen seite mit Speed 2 raus... deshalb die 
verschiedenen CLK...

Und wie ist die Syntax fpr

von Stefan (Gast)


Lesenswert?

<<zu schnell gedrückt
...

Vielen Dank nochmals :)

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


Lesenswert?

>    if Zustand = warten then
>       RX_COUNTER <= 0;
Immer noch schlechter und unsicherer Stil.

Dein Zustand bildet sich u.U. aus mehreren Flip-Flops, die schalten 
nicht alle genau gleichzeitig. Und dahinter kommt jetzt eine Logik, die 
diese Abfrage macht. Nach dieser Logik können beim Umschalten des 
Zustands kurze Spikes auftauchen, die du mit dieser Beschreibung direkt 
auf den asynchronen Reset-Eingang deiner FFs legst.
Fazit: etwas wärmer, oder kälter, oder ein anderes FPGA
--> u.U ist der Spike lang genug um dir deine State-Machine 
zurückzusetzen.
Das passiert dann einmal in der Stunde, einmal am Tag oder einmal in der 
Woche und zwar nur im Winter oder im Sommer... Du siehst, das kann dir 
einige graue Haare bescheren.

Sieh dir mein Beispiel an.
Das ist komplett synchron, da kann nichts schiefgehen.


> zum thema mehrere Clocks... auf der einen Seite geht was mit Speed 1
> rein und auf der anderen seite mit Speed 2 raus...
Und dazwischen knirschts kräftig im Gebälk, weil die Datenübergabe 
wieder asynchron ist. In FPGA-Designs gibt es (im Idealfall) genau einen 
Masterclock (z.B. 50MHz), dieser Takt geht an alle FFs, alles andere 
wird über Clock-Enables gemacht.

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


Lesenswert?

> jetzt versuche ich praxis zu sammeln. Gibt es noch etwas besseres?
Nein. Besser als Praxis ist nur noch mehr Praxis.

Aber versuchs mal mit was ganz einfachem:
- ein Lauflicht
- eine serielle Schnittstelle
- eine Uhr
- Ansteuern eines Modellbau-Servos über die obige Schnittstelle
- Anschluss einer PC-Tastatur
- Ansteuern eines VGA-Monitors (z.B. die Uhrzeit ausgeben)

Das sind kleine Einzelaufgaben, die einiges an Lernpotential haben, du 
mußt sie natürlich selber beschreiben. Nicht einfach irgendwo Code 
herholen, denn wichtig ist nicht das Kopieren, sondern das Kapieren 
;-)

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.