Hallo,
ich möchte in einem ALTERA MAX V mehrere Schieberegister unterbrinngen.
Der serielle Eingang wird über einen Low aktiven Chip Select gesteuert.
Hier der Code des Schieberegisters:
Der parallele Ausgang (par_out) soll erst aktualisiert werden, wenn die
Übertragung vorbei ist (ncs = 1).
Nun bekomme ich folgende Warnungen:
Warning (10631): VHDL Process Statement warning at
out_shift_register.vhd(32): inferring latch(es) for signal or variable
"par_out", which holds its previous value in one or more paths through
the process
Warning (335093): TimeQuest Timing Analyzer is analyzing 64
combinational loops as latches.
Warning (332060): Node: pin_ncs[0] was determined to be a clock but was
found without an associated clock assignment.
Info (13166): Latch
out_shift_register:\label_parallel_output:0:label_out_shift_register_i|p
ar_out[1] is being clocked by pin_ncs[0]
Gibt es eine Möglichkeit die Warnungen zu beheben? nCS kann ich nicht
zur clock machen, da alle Clock Eingänge schon belegt sind.
Oder kann ich die Warnungen ignorieren?
Viele Grüße
Karl
wie genau NCS funktionieren woll, weiß ich nicht. Kannst du die
Schaltung zeichnen? Willst du ein Latch, dann musst du mit der Warnung
leben, denn die mögen FPGAs in der Regel nicht.
Das elsif ist ja nicht ein reines "anderenfalls", sondern eine
Kombination aus "anderenfalls" und "wenn". Sowas wie "anderenfalls UND
wenn Folgendes zutrifft ..."
Ich würde das zur besseren Lesbarkeit so schreiben
1
ifncs='1'ornreset='0'then
2
par_out<=sreg;
3
else
4
ifrising_edge(sclk)then
5
sreg:=sreg(14downto0)&sin;
6
endif;
7
endif;
Und ... gibt es einen Grund für den asynchronen Reset? Also braucht es
den wirklich?
Ausserdem:
Karl schrieb:> Warning (10631): VHDL Process Statement warning at> out_shift_register.vhd(32): inferring latch(es) for signal or variable> "par_out", which holds its previous value in one or more paths through> the process
Also wo ist hier Zeile 32? Sonst ist die Fehlermeldung klar, par_out
wird nicht in einem getakteten Prozess zugewiesen.
Du könntest das alles takten:
Markus F. schrieb:> Klakx schrieb:>> variable sreg : std_logic_vector(15 downto 0) := x"1111";>> ...>> sreg <= RESET_WERT;>> ...>> Das paßt nicht.
ist aber VHDL-technisch nicht falsch. Gemeint war aber wohl
Markus F. schrieb:> Der mit dem Bit tantzt schrieb:>> ist aber VHDL-technisch nicht falsch.>> doch.>> signal : <=> variable : :=
Ich hatte gedacht, dass das sowieso klar ist und auch natürlich nicht
"passen" wird. Die eigentliche Frage an dich war doch, ob du überhaupt
mit einem Latch leben kannst, oder nicht? In beiden Fällen würde ich das
anders schreiben.
Wie wärs damit:
Klakx schrieb:> begin> if ncs = '1' or nreset = '0' then> par_out <= sreg;> end if;
hi,
es ist egal, ob Variable oder Signal, oder wie das if formatiert ist,
der Fehler ist, dass die Reset Zuweisung nicht konstant ist, also kein
Reset ist. Stattdessen werden Daten ohne Takt übernommen, ergo Latch.
Gustl B. schrieb:> Du könntest das alles takten:
Wäre ein korrekte, synchrone und vor allem latchfreie Version.
Karl schrieb:> nCS kann ich nicht zur clock machen, da alle Clock Eingänge schon> belegt sind.
Du kannst daraus natürlich einen lokalen Takt ohne Tektnetz an die
paar beteiligten Flipflops erzeugen.
> Der parallele Ausgang (par_out) soll erst aktualisiert werden, wenn die> Übertragung vorbei ist (ncs = 1).
Ich würde hier statt des Latches dann auch tatsächlich Flipflops
involvieren, und den Reset gleich weglassen. Der ist unnötig, weil ja
für die Daten sowieso noch ein Validierungs- und
Synchronisationsmechnismus (basierend auf dem nCS Signal) folgen muss.
Also etwa so:
http://www.lothar-miller.de/s9y/categories/26-SPI-Slave
Oder ganz ohne Prozess etwa so:
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
4
entitySPIIOis
5
Port(sclk:inSTD_LOGIC;
6
sin:inSTD_LOGIC;
7
ncs:inSTD_LOGIC;
8
par_out:outSTD_LOGIC_VECTOR(15downto0):=x"0000");
9
endSPIIO;
10
11
architectureBehavioralofSPIIOis
12
signalsreg:std_logic_vector(15downto0):=x"1111";
13
begin
14
par_out<=sregwhenrising_edge(ncs);
15
sreg<=sreg(14downto0)&sinwhenrising_edge(sclk);
16
endBehavioral;
Wenn die Daten intern verwendet werden sollen, dann müssen die Daten zum
FPGA-Mastertakt einsynchronisiert werden. Am einfacvhsten geht das über
den nCS:
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
4
entitySPIIOis
5
Port(clk:inSTD_LOGIC;
6
sclk:inSTD_LOGIC;
7
sin:inSTD_LOGIC;
8
ncs:inSTD_LOGIC;
9
par_out:outSTD_LOGIC_VECTOR(15downto0):=x"0000");
10
endSPIIO;
11
12
architectureBehavioralofSPIIOis
13
signalsreg:std_logic_vector(15downto0):=x"1111";
14
signalncssr:std_logic_vector(2downto0):="000";
15
begin
16
ncssr<=ncssr(1downto0)&ncswhenrising_edge(clk);-- ncs auf Mastertakt einsynchronisieren
17
sreg<=sreg(14downto0)&sinwhenrising_edge(sclk);-- mit lokalem sclk einschieben
18
par_out<=sregwhenncssr(2downto1)="01"andrising_edge(clk);-- auf Mastertakt synchron übernehmen
19
endBehavioral;
Karl schrieb:> Oder kann ich die Warnungen ignorieren?
Ja, denn du willst ja solche wilden Konstrukte. Wenn du dir also
bewusst bist, was da gemacht wird, kannst du die Warnungen in den Wind
schreiben...
BTW mein Tipp: verwende nicht unnötigerweise irgendwelche Variablen.
Danke für die Antwort Lothar.
Lothar M. schrieb:> Karl schrieb:>> nCS kann ich nicht zur clock machen, da alle Clock Eingänge schon>> belegt sind.> Du kannst daraus natürlich einen lokalen Takt ohne Tektnetz an die> paar beteiligten Flipflops erzeugen.
Muss ich dafür nCS im SDC-File als Clock definieren? Oder kann ich das
Signal dann für die paar beteiligten FFs als Takt benutzen. Quartus gibt
entsprechende Warnungen raus.
>> Der parallele Ausgang (par_out) soll erst aktualisiert werden, wenn die>> Übertragung vorbei ist (ncs = 1).> Ich würde hier statt des Latches dann auch tatsächlich Flipflops> involvieren, und den Reset gleich weglassen. Der ist unnötig, weil ja> für die Daten sowieso noch ein Validierungs- und> Synchronisationsmechnismus (basierend auf dem nCS Signal) folgen muss.> Also etwa so:> http://www.lothar-miller.de/s9y/categories/26-SPI-Slave
Danke! Genau das möchte ich implementieren. In dem Beispiel benutzt du
SS (entspricht meinem nCS) als Takt für ein FF. Kann das auch so gemacht
werden, wenn SS (bzw. nCS) nicht auf einen CLK Eingang am FPGA
angeschlossen ist? Und (nochmal die gleiche Frage, Sorry) muss dann SS
als Clock definiert (bei Altera im SCD File)?
> Wenn die Daten intern verwendet werden sollen, dann müssen die Daten zum> FPGA-Mastertakt einsynchronisiert werden. Am einfacvhsten geht das über> den nCS:library IEEE;> use IEEE.STD_LOGIC_1164.ALL;>> entity SPIIO is> Port ( clk : in STD_LOGIC;> sclk : in STD_LOGIC;> sin : in STD_LOGIC;> ncs : in STD_LOGIC;> par_out : out STD_LOGIC_VECTOR (15 downto 0) := x"0000");> end SPIIO;>> architecture Behavioral of SPIIO is> signal sreg : std_logic_vector(15 downto 0) := x"1111";> signal ncssr : std_logic_vector(2 downto 0) := "000";> begin> ncssr <= ncssr(1 downto 0) & ncs when rising_edge(clk); --> ncs auf Mastertakt einsynchronisieren> sreg <= sreg(14 downto 0) & sin when rising_edge(sclk); --> mit lokalem sclk einschieben> par_out <= sreg when ncssr(2 downto 1)="01" and rising_edge(clk); --> auf Mastertakt synchron übernehmen> end Behavioral;
Nicht nötig. Es ist kein weiterer Takt vorhanden. Par_out geht direkt
auf FPGA Outputs.
> Karl schrieb:>> Oder kann ich die Warnungen ignorieren?> Ja, denn du willst ja solche wilden Konstrukte. Wenn du dir also> bewusst bist, was da gemacht wird, kannst du die Warnungen in den Wind> schreiben...>> BTW mein Tipp: verwende nicht unnötigerweise irgendwelche Variablen.
Wo verwende ich unnötige variablen? Weil sreg eine Variable und kein
Signal ist?
Danke Karl
Karl schrieb:> Kann das auch so gemacht werden, wenn SS (bzw. nCS) nicht auf einen CLK> Eingang am FPGA angeschlossen ist?
Bei Xilinx CPLDs geht genau dieses Design ohne Fehlermeldung durch. Bei
FPGAs bekommt man zu hören, dass für Takte doch besser ein Takteingang
zu verwenden wäre, aber wie gesagt: für solche räumlich begrenzte
Schieberegister kann so ein Takt auch ruhig mal per Routing verdrahtet
werden.
> Wo verwende ich unnötige variablen?
Du verwendest keine "unnötigen Variablen", sondern du verwendest
"unnötigerweise Variablen". Das ist ein elementarer Unterschied... ;-)
> Weil sreg eine Variable und kein Signal ist?
Jepp.
Stell einfach mal deinen mentalen Default bei VHDL auf "Signal". Und
verwende Variablen nur dort, wo sie für Beschrechungszwischenschritte
wirklich nötig sind. Du tust dir langfristig einen Gefallen.
Lothar M. schrieb:> Karl schrieb:>> Kann das auch so gemacht werden, wenn SS (bzw. nCS) nicht auf einen CLK>> Eingang am FPGA angeschlossen ist?> Bei Xilinx CPLDs geht genau dieses Design ohne Fehlermeldung durch. Bei> FPGAs bekommt man zu hören, dass für Takte doch besser ein Takteingang> zu verwenden wäre, aber wie gesagt: für solche räumlich begrenzte> Schieberegister kann so ein Takt auch ruhig mal per Routing verdrahtet> werden.
Beim Altera Max V (Altera führt den unnter CPLDs) bekommte ich leider
eine entsprechende Warnung, dass nCS keine Clock ist.
Aber was ist genau die Folge davon ein normales Signal als Clock zu
verwenden?
>> Wo verwende ich unnötige variablen?> Du verwendest keine "unnötigen Variablen", sondern du verwendest> "unnötigerweise Variablen". Das ist ein elementarer Unterschied... ;-)>> Weil sreg eine Variable und kein Signal ist?>> Jepp.> Stell einfach mal deinen mentalen Default bei VHDL auf "Signal". Und> verwende Variablen nur dort, wo sie für Beschrechungszwischenschritte> wirklich nötig sind. Du tust dir langfristig einen Gefallen.
Warum tue ich mir damit einen gefallen? Ich finde Variablen deutlich
übersichtlicher.
Danke Karl
Karl schrieb:> Warum tue ich mir damit einen gefallen?> Ich finde Variablen deutlich übersichtlicher.
Das größte Manko: du kannst eine Variable nicht in die Sensitivliste
eines Prozesses aufnehmen. Und das ist bei speichernden Variablen
schlecht. Aber wiederum nur, wenn sie Latches bilden.
Siehe den Klassiker:
Beitrag "Variable vs Signal"> Ich finde Variablen deutlich übersichtlicher.
Warum? Wofür?
Etwa nur, weil sie ihren Wert "gleich ändern" und du sie "von C kennst"?
> Beim Altera Max V (Altera führt den unnter CPLDs) bekommte ich leider> eine entsprechende Warnung, dass nCS keine Clock ist.> Aber was ist genau die Folge davon ein normales Signal als Clock zu> verwenden?
Es wird nicht über ein dediziertes Taktnetz verteilt und hat deshalb
einen größeren Skew. Aber diesen Skew kannst du bei einer handvoll
Flipflops getrost ignorieren...
Lothar M. schrieb:> Das größte Manko: du kannst eine Variable nicht in die Sensitivliste> eines Prozesses aufnehmen. Und das ist bei speichernden Variablen> schlecht. Aber wiederum nur, wenn sie Latches bilden.
In einem Synchronen Design steht in der Sensitivliste bei mir eh immer
nur reset und clock.
> Siehe den Klassiker:> Beitrag "Variable vs Signal"
sollte ich mir vielleicht mal reinziehen :-)
>> Ich finde Variablen deutlich übersichtlicher.> Warum? Wofür?> Etwa nur, weil sie ihren Wert "gleich ändern" und du sie "von C kennst"?
NEIN. Weil ich die Variable sreg im URSPRÜNGLICHEM Beispiel NUR in dem
einen Process brauche!
>> Beim Altera Max V (Altera führt den unnter CPLDs) bekommte ich leider>> eine entsprechende Warnung, dass nCS keine Clock ist.>> Aber was ist genau die Folge davon ein normales Signal als Clock zu>> verwenden?> Es wird nicht über ein dediziertes Taktnetz verteilt und hat deshalb> einen größeren Skew. Aber diesen Skew kannst du bei einer handvoll> Flipflops getrost ignorieren...
Damit kann ich in der Tat leben.
Karl schrieb:> Weil ich die Variable sreg im URSPRÜNGLICHEM Beispiel NUR in dem einen> Process brauche!
Du hast hiermit "hinten rum" meinen C-Programmierer-Verdacht bestätigt,
denn diese Denkweise ist die typische "Funktionsaufruf mit lokalen
Variablen"-Strategie.
Wie gesagt: lass dich auf Signale ein. Es lohnt sich. ;-)