Hallo zusammen,
ich arbeite mit einem XILINX Spartan 6 und bekommen bei einem scheinbar
einfachen STateMachine-Code eine Warnung, dessen grund und Ursache ich
nicht finden kann.
Die Warnung lautet:
Xst:3002 - This design contains one or more registers/latches that are
directly
incompatible with the Spartan6 architecture. The two primary causes
of this is
either a register or latch described with both an asynchronous set
and
asynchronous reset, or a register or latch described with an
asynchronous
set or reset which however has an initialization value of the
opposite
polarity (i.e. asynchronous reset with an initialization value of 1).
Könnt ihr euch einen Reim auf die Warnung machen und/oder mir sagen, was
ich anders machen sollte?
(eine Reset aller:
if reset = '1' then
state <= PART_1;
elsif (rising_edge(in_SPI_CS)) then ...
brings nicht)
Der entsprechende VHDL-Auszug lautet:
Ich hab keine Ahnung von VHDL, nur Verilog, also haut mich bitte nicht
:-)
Der Prozess "SIGNALMANIPULATION" ist doch kombinatorisch. D.h. alle
signale die sich ändern müssen in die Sensitivity list, sonst wirds ein
latch.
engineer_on_tour schrieb:> rising_edge(in_SPI_CS)
Sorgenfalten machen sich auf der Stirn breit...
Wieviele Takte hast du? Wie synchronisiertst du die Übergänge?
> bekommen bei einem scheinbar einfachen STateMachine-Code eine Warnung,> dessen grund und Ursache ich nicht finden kann.
Ich vermute stark, der Fehler liegt ausserhalb des geposteten
Codeausschnittes...
> or a register or latch described with an asynchronous set or reset> which however has an initialization value of the opposite polarity> (i.e. asynchronous reset with an initialization value of 1).> Könnt ihr euch einen Reim auf die Warnung machen...?
Das ist sowas:
1
signals:std_logic:='1';
2
3
ifreset='1'then
4
s<='0';
5
else
6
:
7
:
8
endif;
abcd schrieb:> Der Prozess "SIGNALMANIPULATION" ist doch kombinatorisch. D.h. alle> signale die sich ändern müssen in die Sensitivity list, sonst wirds ein> latch.
Falsch.
In die Sensitivliste müssen alle die Signale, die eine Änderung eines
andere Wertes bewirken. Dann berechnet der Simulator bei einer
Änderung des Wertes in der Sensitivliste die Ergebnisse des Prozesses
neu.
Der Synthese (die oben die Warnung erzeugt) schert sich einen feuchten
Kehrricht um eine unvollständige Sensitivliste. Sie erweitert diese
Leiste einfach eigenständig.
Mit der Sensitivliste kann also das Verhalten des FPGAs in keiner Weise
gesteuert werden.
user schrieb:> ich würde mal das Signal i_FIFO_DataOut genauers anschauen>> das wird aufjedenfall hier zugewiesen>> when PART_2_READ =>> int_SlaveOut <= i_FIFO_DataOut;
Wird diese Zuweisung nicht verwendet, tritt die Wranung dennoch auf.
Lothar Miller schrieb:> Ich vermute stark, der Fehler liegt ausserhalb des geposteten> Codeausschnittes...
Dann poste ich einfach mal den gesamten Code. Es handelt sich um eine
Erweiterung einer funtionierenden SPI-Slave-Instanz. Diese soll immer
mit zwei Nachrichten (Befehl + Daten) oder (Anfrage + Antwort)
angesprochen werden und je nach Befehl/Anfrage reagieren. Daher wird
nach dem ersten empfangenen Datenpaket getestet:
if int_DataRX = x"0060" then
int_s_CurrentState <= PART_2_READ;
else
int_s_CurrentState <= PART_2_WRITE;
Der komplette Code hier:
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
Seis drum...
> when PART_2_READ =>> int_SlaveOut <= i_FIFO_DataOut;> Wird diese Zuweisung nicht verwendet, tritt die Wranung dennoch auf.
Weil int_SalveOut verwendet wird. Ich hab ihn:
1
if(in_SPI_CS='1')then
2
int_DataTx<=int_SlaveOut;
3
elsifrising_edge(in_SPI_Clock)then
4
:
Ein nicht konstanter Resetwert. Sowas ist mit den Flipflops in einem
FPGA nicht möglich...
Lothar Miller schrieb:> Wichtige Regeln - erst lesen, dann posten!> Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
Aso, dann weiß ich für die Zukunft bescheid :)
Lothar Miller schrieb:> Weil int_SalveOut verwendet wird. ... Ein nicht konstanter Resetwert.
Verstehe ich das richtig (leider habe ich nicht die Zeit, in aller ruhe
VHDL zu lernen und muss es "leaning by doing" im Schnellverfahren
lernen), dass sich der Wert int_SlaveOut theoretisch während des
TX-Prozesses veränden kann und so zu diesem Fehler führt?
Anders gefragt: Wie kann ich es realisieren, dass je nach Zustand ein
anderer Wert über den MISO-Kanal gesendet wird?
engineer_on_tour schrieb:> Lothar Miller schrieb:>> Wichtige Regeln - erst lesen, dann posten!>> Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang>> Aso, dann weiß ich für die Zukunft bescheid :)>> Lothar Miller schrieb:>> Weil int_SalveOut verwendet wird. ... Ein nicht konstanter Resetwert.>> Verstehe ich das richtig (leider habe ich nicht die Zeit, in aller ruhe> VHDL zu lernen und muss es "leaning by doing" im Schnellverfahren> lernen), dass sich der Wert int_SlaveOut theoretisch während des> TX-Prozesses veränden kann und so zu diesem Fehler führt?
In Hardware denken bitte!
Die Fehlermeldung besagt, das kein Flipflop beschrieben wurde sondern
ein Latch.
Verkürzt dargestellt
Ein FF hat einen D- Eingang , dessen wert wird beim Eintreffen der
taktflanke ( rising_edge() abgespeichert und an FF-Ausgang Q
wiedergegeben.
IN VHDL beschrieben sieht das (verkürzt) so aus
1
ifrising_edge(clk)then
2
Q<=D;
Daneben hat es noch RESET/SET- Eingänge, die bewirken das unabhängig von
D die Speicherzelle auf '0' (when RESET Eingang aktiv) oder auf '1'
(when SET eingang aktiv) gesetzt wird.
in VHDL sieht das so aus:
1
IFR='1'thenQ<='0';
2
elsifS='1'thenQ<='1';
3
endif;
was du dagegen beschreibst ist kein FF (flankensensitiv) sondern ein
Latch (zustandsgesteuert) deswegen warnt dich die Synthese.
Willst du ein Latch oder ein Flipflop hier?
MfG,
engineer_on_tour schrieb:> dass sich der Wert int_SlaveOut theoretisch während des TX-Prozesses> veränden kann und so zu diesem Fehler führt?
Nein, es liegt primär daran, dass es keinen "Load"-Eingang an einem
FPGA-Flipflop gibt.
> Anders gefragt: Wie kann ich es realisieren, dass je nach Zustand ein> anderer Wert über den MISO-Kanal gesendet wird?
Entweder baust du das gesamte Design auf eine synchrone Datenübertragung
um oder du akzeptierst diese "Unsauberkeit" an dieser Stelle. Du weißt
ja, woher der Fehler kommt...
engineer_on_tour schrieb:> eine Erweiterung einer funtionierenden SPI-Slave-Instanz.
Schön, dass die funktioniert, die kommt mir bekannt vor... ;-)
Und was wurde erweitert? Trat vor der Erweiterung diese Warnung nicht
auf? Was war da anders?
Hallo Lothar,
ich habe einen Workaround gefunden und denken, damit jetzt weiter
arbeiten zu können.
Den problematischen Teil
case int_s_CurrentState is
when PART_1 =>
int_SlaveOut <= x"1234";
when PART_2_READ =>
int_SlaveOut <= i_FIFO_DataOut;
when PART_2_WRITE =>
int_SlaveOut <= x"5678";
when OTHERS =>
int_SlaveOut <= x"FFFF";
end case;
end process;
lasse ich vorläufig weg und werde diesen eventuell später anderweitig
implementieren (zumindest versuche ich es). Aber da das nicht Prio 1 ist
mache ich erst mal mit anderen Dingen weiter.
In jedem fall vielen Dank für deine Hilfe! ... So konnte ich schnell
erkennen, was der Fehler ist und mich für ein weiteres Vorgehen
entscheiden.
Hallo zusammen,
ich konnte das Problem nun auf die eigentliche SPI eingrenzen, die ein
Problem hat, sobald die zu senden Daten (i_TxData) nicht mehr konstant
sind (sondern sich je nach empfangenen Daten oder Zustand ändern
sollen).
TX:process(in_CLK)--,i_TxData,in_CS)
begin
if (in_CS='1') then
int_DataTx <= i_TxData;
elsif rising_edge(in_CLK) then
int_DataTx <= int_DataTx(16-2 downto 0) & '0';
end if;
end process;
Jetzt mache ich mich endweder auf die Suche nach einer anedren
SPI-Implementierung oder muss selber eine schreiben.
engineer_on_tour schrieb:> Hallo zusammen,>> ich konnte das Problem nun auf die eigentliche SPI eingrenzen, die ein> Problem hat, sobald die zu senden Daten (i_TxData) nicht mehr konstant> sind (sondern sich je nach empfangenen Daten oder Zustand ändern> sollen).>> TX:process(in_CLK)--,i_TxData,in_CS)> begin> if (in_CS='1') then> int_DataTx <= i_TxData;> elsif rising_edge(in_CLK) then> int_DataTx <= int_DataTx(16-2 downto 0) & '0';> end if;> end process;>> Jetzt mache ich mich endweder auf die Suche nach einer anedren> SPI-Implementierung oder muss selber eine schreiben.
Das ist IMHO keine reguläre Beschreibung eines Schieberegisters oder
eines Registers überhaupt. Da steckt genau wieder der der nichtkonstante
Reset drin. Rausstreichen aus der sensitive List bewirkt da keine
Verbesserung.
Vorschlag: Zeichne ein Blockbild deines SPI-Interfaces. Vergleiche das
mit Blockbildern anderer SPI-Interfaces und identifiziere so die
Signale:
-systemtakt
-systemreset
-parallele Daten rein/raus
-SPI serielle Daten rein
-SPI serielle Daten raus
-SPI Chipselect
-SPI bit clock
Insbesonders der Unterschied zwischen SPI bit-takt und FPGA Systemtakt
scheint dir nicht ganz bewußt zu sein.
Davon ausgehend schreibe eine Entity (portliste). Und erst dann kann man
anfangen hinter dieser Portliste ein parallel zugreifbares
Schieberegister zu beschreiben (den mehr ist SPI im Kern nicht).
MfG,
engineer_on_tour schrieb:> ich konnte das Problem nun auf die eigentliche SPI eingrenzen, die ein> Problem hat, sobald die zu senden Daten (i_TxData) nicht mehr konstant> sind.
Ja, weil die Flipflops des FPGAs (wie oben schon erwähnt) keinen
Load-Eingang haben. Aber weil dir der Grund bekannt ist kannst du die
Warnung hier ignorieren.
> Jetzt mache ich mich endweder auf die Suche nach einer anedren> SPI-Implementierung oder muss selber eine schreiben.
Mach dir die Ursache des Problems klar, dann wirst du erkennen: so
richtig einfach wird das nicht, wenn der SPI-Takt tatsächlich gleich der
Schiebetakt sein soll.
Wenn der SPI Takt hinreichend langsam ist, dann kannst du das übliche
Verfahren mit Einsynchronisieren und schnellem Masterclock (3-4 mal
höher) machen.