mikrocontroller.net

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


Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?
Lesen_Pro:    process(IFCLK, Zustand)
            begin
            
            if Zustand = warten then
               iCounter2 <= 0;
            elsif IFCLK='1' and IFCLK'event then
              if Zustand = lesen then
                RX_BUFFER(RX_COUNTER)<=DATA_BUS;
               iCounter2 <=RX_COUNTER+1;
              end if;
            else 
                iCounter2 <=RX_COUNTER;            
            end if;
            RX_COUNTER<=iCounter2;


            end process Lesen_Pro;


Vielen Dank

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Formatieren wir das mal erst schön, und machen Nummern dazu:
Lesen_Pro:
process (IFCLK, Zustand) begin
    if Zustand = warten then  -- (1)
       iCounter2 <= 0;
    elsif IFCLK='1' and IFCLK'event then  -- (2)
       if Zustand = lesen then
          RX_BUFFER(RX_COUNTER)<=DATA_BUS;
          iCounter2 <=RX_COUNTER+1;
       end if;
    else                                  -- (3)
       iCounter2 <=RX_COUNTER;            
    end if;

   RX_COUNTER <= iCounter2;        -- (4)
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:
process (IFCLK) begin
    if rising_edge(IFCLK) then  
       if (Zustand = warten) then  
          RX_COUNTER <= 0;
       elsif (Zustand = lesen) then
          RX_BUFFER(RX_COUNTER) <= DATA_BUS;
          RX_COUNTER <= RX_COUNTER+1;
       else                              -- eigentlich unnötig
          RX_COUNTER <= RX_COUNTER;      -- dito      
       end if;                               
    end if;
end process;

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

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
process(IFCLK, Zustand)
  begin
   if Zustand = warten then
       RX_COUNTER <= 0;
   
   elsif IFCLK='1' and IFCLK'event then
      if (Zustand = lesen) then                 
         RX_BUFFER(USB_RX_COUNTER)<=USB_DATA_BUS;
         USB_RX_COUNTER <=USB_RX_COUNTER+1;
      end if;
   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

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<<zu schnell gedrückt
...

Vielen Dank nochmals :)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

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.