Forum: FPGA, VHDL & Co. SPI Slave, Problem mit Latches


von Tobias S. (tryan)


Lesenswert?

Hallo,

ich habe einen SPI Slave in VDHL Programmiert, funktioniert auch soweit 
ganz gut.

Das Takt von dem SPI ist nicht synchron mit dem Systemtakt.

Leider gibt es bei folgernder Funktion die Warnung vor Latches.
1
----------------------------------------------      
2
 -- Parallel-Eingänge --> MISO
3
----------------------------------------------  
4
 process (Spi_CLK,SPI_EN,Spi_MISO_En,SPI_Data_In_Buffer)   
5
  begin
6
    if ((Spi_MISO_En='1')) then
7
      SPI_Data_MISO <= SPI_Data_In_Buffer;
8
    elsif (Spi_CLK'event and Spi_CLK='1')  then     
9
      SPI_Data_MISO <= SPI_Data_MISO(30 downto 0) & '0'; -- wird MISO aktualisiert
10
      end if;
11
  end process;
12
Spi_MISO_Out <= SPI_Data_MISO(31) when SPI_EN='1' else '0';


Gibt es evtl. eine andere Möglichkeit diese Funktion aufzubauen, sodass 
keine Latches entstehen?

Viele Grüße Tobias

von Christian R. (supachris)


Lesenswert?

Tobias S. schrieb:
> Gibt es evtl. eine andere Möglichkeit diese Funktion aufzubauen, sodass
> keine Latches entstehen?

Klar, mit einem höheren Takt als den Schiebetakt die Signale 
einsynchronisieren.

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


Lesenswert?

Tobias S. schrieb:
> Leider gibt es bei folgernder Funktion die Warnung vor Latches.
Das ist keine Funktion. Und da gibt es auch kein Latch. Und es ist 
zuviel in der Sensitivliste. Und in der ersten if-Abfrage sind 4 
Klammern zuviel...

> die Warnung vor Latches.
Welche Signale werden denn angemahnt?

> Spi_MISO_Out <= SPI_Data_MISO(31) when SPI_EN='1' else '0';
Sollte da nicht eher
1
 ... else 'Z';
stehen? Denn wenn der Ausgang nicht aktiv ist, dann sollte er beim SPI 
hochohmig sein...

Und was machen denn diese vielen Enables, wo jedes irgendwas anderes 
enabled?

: Bearbeitet durch Moderator
von Tobias S. (tryan)


Lesenswert?

Hallo,

danke für die antworten.

Es wird angemahnt, das "Spi_MISO_Out" Latches erzeugt.

"Warning (13004): Presettable and clearable registers converted to 
equivalent circuits with latches. Registers power-up to an undefined 
state, and DEVCLRn places the registers in an undefined state."

Einsynchronisieren würde ich ungern, da der SPI Takt 33Mhz beträgt. Und 
der Systemtakt 25Mhz.

Vielen Danke für eure Hilfe

Tobias

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


Lesenswert?

Tobias S. schrieb:
> Es wird angemahnt, das "Spi_MISO_Out" Latches erzeugt.
Von wem? Wer ist der Hersteller dieses Tools?

> Spi_MISO_Out <= SPI_Data_MISO(31) when SPI_EN='1' else '0';
Ich kann da kein Latch erkennen...

> and DEVCLRn places the registers in an undefined state.
Undefined nach PowerUp? Ist das Actel/Microsemi?

Tobias S. schrieb:
> Einsynchronisieren würde ich ungern, da der SPI Takt 33Mhz beträgt.
> Und der Systemtakt 25Mhz.
Ich würde wetten du könntest es nicht mal, ohne dass sich Herr Shannon 
im Grabe umdrehen würde...

: Bearbeitet durch Moderator
von pks (Gast)


Lesenswert?

Lothar Miller schrieb:
> Und in der ersten if-Abfrage sind 4
> Klammern zuviel...

Ich seh nur 2 zuviel. Aber das ist wohl eine Frage des Geschmacks...

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


Lesenswert?

pks schrieb:
> Aber das ist wohl eine Frage des Geschmacks..
Nicht unbedingt. Was liest sich da besser:
1
  if rising_edge(clk) then ...   -- if ganz ohne Klammer
2
 
3
  if (rising_edge(clk)) then ... -- if mit 2 Klammern

: Bearbeitet durch Moderator
von Da D. (dieter)


Lesenswert?

pks schrieb:
> Lothar Miller schrieb:
>> Und in der ersten if-Abfrage sind 4
>> Klammern zuviel...
>
> Ich seh nur 2 zuviel. Aber das ist wohl eine Frage des Geschmacks...

Da erkennt man die C-Programmierer... Da muss man um die Bedingung eine 
Klammer machen, in VHDL braucht man es nicht. Und die Lesbarkeit erhöht 
so eine Klammer an der Stelle auch nicht. Höchstens dadurch, dass das 
aussehen des Codes wieder dem gewohnten Bild aus anderen Sprachen 
entspricht...

von Tobias S. (tryan)


Lesenswert?

Hallo,

ja Ihr habt recht... Ich komme aus der C ecke. ;)

Also ich Arbeite mit Quartus 2 Version 13.0.1.
Und der FPGA ist der Cyclone IV.

Vielen Danke für eure Unterstützung.

Viele Grüße Tobias

von Valko Z. (hydravliska)


Lesenswert?

Werden Spi_MISO_En, Spi_CLK und SPI_Data_in_Buffer in den gleichen 
Taktdomäne generiert?!

Du übernimmst die Daten asynchron(Spi_MISO_En) zum Takt (Spi_CLK). Woher 
kommt der Spi_MISO_En?

SPI_Data_in_Buffer - sind das Pins oder irgendein Register?!

Gruss

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


Lesenswert?

Zapalko schrieb:
> ...?...?...?
Am einfachsten wäre es offenbar, die VHDL-Datei hier anzuhängen... ;-)

von Tobias S. (tryan)


Lesenswert?

Hallo,

Das "SPI_Data_in_Buffer" ist ein Register.

"Spi_MISO_En" ist ein Signal das mir sagt, das Daten in 
"SPI_Data_in_Buffer" übergeben wurden.


Viele grüße Tobias

von pks (Gast)


Lesenswert?

Da Dieter schrieb:
> Da erkennt man die C-Programmierer... Da muss man um die Bedingung eine
> Klammer machen, in VHDL braucht man es nicht.
Ist mir bekannt. Und ich schreibe VHDL fast so lang wie C.
> Und die Lesbarkeit erhöht
> so eine Klammer an der Stelle auch nicht.
Find ich schon. Aber wie gesagt...Geschmackssache. Ich bevorzuge 
generell , auch in C, etwas "luftigen" code. Also im Zweifelsfall lieber 
mehr Klammern, leere Zeilen, Umbrüche,...  In C finde ich z.B.
if()
{
}
deutlich lesbarer als das verbreitete
if(){
}

Aber das ist wohl OT :-)

von Tobias S. (tryan)


Angehängte Dateien:

Lesenswert?

Hallo,

anbei ist der VHDL Code,

aber ich möchte schon mal vorwarnen.
Das ist mein erstes VHDL bzw. FPGA Projekt und es fehlen noch Kommentare 
usw.

Also bitte nicht gleich schlagen...und wer keine Lust hat sich ein 
Amateure Projekt sich anzuschauen, bitte nicht das VHDL öffnen ;)

Viele Grüße Tobias

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


Lesenswert?

1
  if (State_counter=8) then
FSM werden in VHDL aber anders gemacht...

Hier sind ein paar Latches:
1
  if (SPI_EN='0') then
2
      State_counter<=0;
3
      Adr_Ready<='0';
4
      Data_Ready<='0';
5
      Adr_Data_Out<=x"00";
6
      SPI_Data_OUT <=x"00000000";
7
      CRC_Data<=x"0000000000";
8
  end if;
Oder doch nicht? Du hast mich jetzt genauso durcheinander gebracht wie 
den Synthesizer. Das hier ist z.B. ziemlich, naja, unüblich:
1
process(CLK,SPI_EN,State_counter,Data_buffer)
2
begin    
3
  if(CLK'event and CLK='1') then
4
     if (SPI_EN='1') then -- was sollte SPI_EN denn sonst sein ausser '0'
5
       :
6
     end if;    
7
  end if;    
8
  
9
  if (SPI_EN='0') then    -- ein Wolf im Schafspelz: der Reset hat einen anderem Namen bkommen
10
    :
11
  end if;
12
13
end process;

Bitte integer Bereiche sinnvoll einschränken. Sonst findest du einen 
Überlauf hier nie:
1
signal State_counter : integer := 0;

Und der ist auch nicht schlecht:
1
      State_counter<=15;
Da wird ein Zustand zugewiesen, der aber sonst nirgends auftaucht...

Und deine Idents bringen mich ganz durcheinander:
1
    if ((State_counter=12))then  
2
      Spi_MISO_En<='0';
3
      State_counter<=13;
4
      end if;
Das end if hier gehört m.E. zwei Leerzeichen Richtugn Zeilenanfang, denn 
es gehört zum if und schließt dieses gleichberechtigt ab.

Ich würde sagen, dass dich der Synthesizer mit seiner Warnung einfach 
darauf hinweist, dass du mal die Synthese-Guidelines (das Handbuch zum 
Synthesizer) mal genauer anschauen solltest...

: Bearbeitet durch Moderator
von Lattice User (Gast)


Lesenswert?

Ein kleiner Kommentar zu dem Ausschnitt aus dem ersten Posting
1
----------------------------------------------      
2
 -- Parallel-Eingänge --> MISO
3
----------------------------------------------  
4
 process (Spi_CLK,SPI_EN,Spi_MISO_En,SPI_Data_In_Buffer)   
5
  begin
6
    if ((Spi_MISO_En='1')) then
7
      SPI_Data_MISO <= SPI_Data_In_Buffer;
8
    elsif (Spi_CLK'event and Spi_CLK='1')  then     
9
      SPI_Data_MISO <= SPI_Data_MISO(30 downto 0) & '0'; -- wird MISO aktualisiert
10
      end if;
11
  end process;

Das beschreibt D-FlipFlops mit einem asynchronen Reset. Nur ist der 
Resetwert variabel statt statisch.
Ich kenne den Altera jetzt zwar nicht, aber bei Lattice gibt es ein 
deartiges FF nicht. Die FFs haben zwar einen asynchronen Set/Reset 
Eingang, aber ob Set oder Reset wird durch ein Configbit statisch 
festgelegt.

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


Lesenswert?

Lattice User schrieb:
> Nur ist der Resetwert variabel statt statisch.
Was man nicht alles falsch machen kann...   :-o

von Tobias S. (tryan)


Lesenswert?

Hallo,

danke für eure Hilfe.

Ich werde versuchen die Fehler zu überarbeiten...

Viele Grüße Tobias

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


Lesenswert?

Tobias S. schrieb:
> Ich werde versuchen die Fehler zu überarbeiten...
Der gefällt mir... :-D
Aber eigentlich wäre es besser, die Fehler nicht zu überarbeiten, 
sondern zu entfernen.


BTW: das mit dem sauberen Taktdomänenübergang ist mir in deinem Code 
derzeit auch noch ziemlich schleierhaft.

: Bearbeitet durch Moderator
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.