Hallo,
ich bin noch relativ neu im Thema VHDL und habe offenbar ein Problem mit
der IF Anweisung. Mein Erzeugter Code sieht folgendermaßen aus:
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL ;
USE IEEE.STD_LOGIC_UNSIGNED.ALL ;
ENTITY ampel IS
PORT (r: OUT STD_LOGIC;
ge: OUT STD_LOGIC;
g: OUT STD_LOGIC;
q_a: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
stsig: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
clk: IN STD_LOGIC);
END ampel;
ARCHITECTURE behav OF ampel IS
BEGIN
p1 : PROCESS (clk, stsig)
BEGIN
IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN
ELSIF (stsig<="0000") THEN r<='0'; ge<='0'; g<='0';
ELSIF (stsig<="0001") THEN r<='1'; ge<='0'; g<='0';
ELSIF (stsig<="0010") THEN r<='1'; ge<='1'; g<='0';
ELSIF (stsig<="0011") THEN r<='0'; ge<='0'; g<='1';
ELSIF (stsig<="0100") THEN r<='0'; ge<='1'; g<='0';
ELSIF (stsig<="0101" AND q_a<="1001") THEN r<='0'; ge<='1'; g<='0';
ELSIF (stsig<="0101" AND q_a<="0000") THEN r<='0'; ge<='0'; g<='0';
END IF;
END PROCESS p1 ;
END behav;
Dieser funktioniert soweit auch in der Simulation mit ModelSim bis auf
die letzten beiden ELSIF-Anweisungen in denen das g-Signale je nach Wert
des q_a Signals umgeschalten werden soll. Das Problem ist das "g"
einfach auf '1' bleibt und das Umschalten nicht funktioniert (siehe
Anhang Bild)....
Folgende Force File verwende ich:
force clk 0 0 ns, 1 100 ns -repeat 200 ns;
force stsig 2#0000 0;
force stsig 2#0001 500;
force stsig 2#0010 1000;
force stsig 2#0011 1500;
force stsig 2#0100 2000;
force stsig 2#0000 2400;
force stsig 2#0101 3000;
force q_a 2#0000 0;
force q_a 2#1001 3000;
force q_a 2#0000 3500;
force q_a 2#1001 4000;
force q_a 2#0000 4500;
Hat evtl. jemand eine Idee woran das liegen könnte? Offenbar
funktioniert die "AND"-Verknüpfung innerhalb der ELSIF nicht!?
Vielen Dank!
LG K.
von demhier mal abgesehen
-----------------------------------------------------------
IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN
???? und was machst du mit der clock hier ????
ELSIF (stsig<="0000") THEN r<='0'; ge<='0'; g<='0';
-----------------------------------------------------------
hast du eine if abfrage kleiner =, wie soll das so funktionieren?
probiers mal mit einem case statment in der clock
also
if rising_edge(clk) then
case xy is
when "0000" =>
r<='1';
when "" =>
when others =>
end case;
end if;
@dden
Also wenn ich deine antwort richtig verstehe meinst du mit "kleiner ="
das: "<="...
ich verstehe aber in diesem fall eine Wertzuweisung für Signalpegel (<=)
darunter....
diese Zeile:
"IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1')"
soll sicherstellen das immer wenn clk-signal von low auf high wechselt
das darunter stehende abgearbeitet werden soll...
das gibt funktioniert auch alles wie geschrieben mein prob liegt hier:
ELSIF (stsig<="0101" AND q_a<="1001") THEN r<='0'; ge<='1'; g<='0';
ELSIF (stsig<="0101" AND q_a<="0000") THEN r<='0'; ge<='0'; g<='0';
...thx...
also das deine simulation funktioniert liegt daran das du stsig mit in
die sensitive liste aufgenommen hast, das mit dem clk ist heutzutage ein
eher seltenes konstrukt, da du die IEEE.STD_LOGIC_1164 eingebunden hast
nutze doch einfach die rising_edge funktion.
Und sowas hier kann nicht funktionieren
IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN
>>>> hier ist die clk action <<<<
ELSIF xxx then
end if;
In einer IF THEN abfrage kannste nix zuweisen!
dden schrieb:> von demhier mal abgesehen> -----------------------------------------------------------> IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN> ???? und was machst du mit der clock hier ????
Andere schreiben rising_edge() statt dessen...
dden schrieb:> Und sowas hier kann nicht funktionieren> IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN> >>>> hier ist die clk action <<<<> ELSIF xxx then
Das ist auch schlichtweg falsch, denn in der eigentlichen Taktabfrage
wird nichts gemacht:
1
IF(clk'EVENTANDclk'LAST_VALUE='0'ANDclk='1')THEN
2
-- nichts zu tun hier?
3
ELSIF(stsig<="0000")THENr<='0';ge<='0';g<='0';
4
ELSIF(stsig<="0001")THENr<='1';ge<='0';g<='0';
Das erste elsif sollte wohl ein if sein...
Kaffeetasse schrieb:> Folgende Force File verwende ich:
Du kannst doch VHDL. Warum schreibst du nicht einfach eine
herstellerunabhängige Testbench, statt diese krude ModelSim
Force-Geschichte zu nehmen?
Leute, nehmt bitte die [ vhdl ] und [ /vhdl ] Tags um den VHDL Quelltext
(ohne die Leerzeichen in den Klammern), dann wird der VHDL-Text sinnvoll
formatiert und eingefärbt.
@dden
das heist "<=" ist falsch? könnte man da stattdessen schreiben
stsig="XXXX"???
ich hatte angedacht die ganzen ELSIF-Funktionen als "clk action" zu
schreiben... das geht also auch nicht ???
ich hab meien code jz so abgeändert:
ARCHITECTURE behav OF ampel IS
BEGIN
p1 : PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN
ELSIF (stsig="0000") THEN r<='0'; ge<='0'; g<='0';
ELSIF (stsig="0001") THEN r<='1'; ge<='0'; g<='0';
ELSIF (stsig="0010") THEN r<='1'; ge<='1'; g<='0';
ELSIF (stsig="0011") THEN r<='0'; ge<='0'; g<='1';
ELSIF (stsig="0100") THEN r<='0'; ge<='1'; g<='0';
ELSIF (stsig="0101" AND q_a="1001") THEN r<='0'; ge<='1'; g<='0';
ELSIF (stsig="0101" AND q_a="0000") THEN r<='0'; ge<='0'; g<='0';
END IF;
END PROCESS p1 ;
END behav;
jz simuliert es zumindest so wie es soll - also es funktioniert...
ist das fachlich trotzdem falsch???
zum clk, meinst du so:
RISING_EDGE(clk) THEN XXX ???
...thx...
Sorry Lothar,
wollte im zweiten Bsp. eigentlich ausdrücken das das mit dem elsif nicht
funktionieren kann und in die if rising_edge(clk) kein else welcher form
auch immer darf.
Trotzdem hat er eine eher unlogische abfrage von stsig.
Nochmal mein vorschlag stattdessen:
vhdl
if rising_edge(clk) then
case stsig is
when "0000" =>
r<='1';
when "0101" =>
if q_a="0000" then
r<='0';
ge<='0';
g<='0';
elsif q_a="0101" then
r<='0';
ge<='1';
g<='0';
end if;
when others =>
end case;
end if;
/vhdl
Deine ganzen Zuweisungen "funktionieren" nur, wenn gerade keine
steigende Flanke auf dem Taktsignal ist..
Lothar hat´s ja auch schon gesagt. Du schreibst:
Wenn steigende Taktflanke, dann mache NICHTS und sonst mache diese
ganzen anderen ELSIFs.
Denke nicht, dass du mit deinem Code genau das ausdrücken wolltest, was
ich oben hingeschrieben habe :-)
dden schrieb:> deine simulation ist falsch und bildet nicht die wirklichkeit ab.
Du weisst doch gar nicht, was seine "Wirklichkeit" ist? Also was er
beschreiben wollte....
Die Simulation bildet genau das ab, was er beschrieben hat.
Sein Problem ist, dass er seinen Prozess nur mit "clk" in der
Sensitivity-List "triggert". Daher reagiert der Prozess nur bei Änderung
von Clock.
Seine ganzen Zuweisungen macht er aber nur dann, wenn der Takt gerade
KEINE STEIGENDE FLANKE aufweist.
Alles, was bei den ELSIFs zugewiesen wird, wird also immer nur dann
zugewiesen, wenn eine fallende Taktflanke auftritt.
Das ist eine total krautige Darstellung und wahrscheinlich nichtmal
synthetisierbar. Jedenfalls entsteht dabei kein Register.
so käme man der Sache schon näher (ohne Korrektur sonstiger "unüblicher"
Beschreibungsweisen:
Kaffeetasse schrieb:> oki ich verstehe glaube wo das prob lag -> die erste elsif muss ein if sein, dann müsste es stimmen!
Korrekt. Allerdings hast du eher ein grundlegendes Problem: du
programmierst anstatt Hardware zu beschreiben. Nun ist VHDL aber
eine Beschreibungssprache, keine Programmiersprache. Du musst dir also
eine Hardware vorstellen, und die dann mit VHDL beschreiben. Hast du
eine Vorstellung, wie deine Hardware aussieht, und was bei der Synthese
herauskommen muss? Nein? Dann sieh dir ab&zu mal den RTL-Schaltplan
deiner Beschreibung an...
> so geändert...
Noch die Leerzeichen in den eckigen Klammern der [ vhdl ] Tags weg, und
den Code sinnvoll und übersichtlich eingerückt, dann passt das.
naja ich denke er wollte die werte gleichwertig entsprechend stsig bei
steigender Flanke übernehmen.
Und ich würde sagen das die simulation so wie es im ersten posting stand
faktisch einen kombinatorischen prozess sieht da die if clk abfrage ja
immer flasch ist ausser wenn eine steigende flanke kommt und er auch auf
veränderung von stsig triggert.
@ Lothar
wasn da nicht ordentlich eingrückt ??
Davon mal abgesehen das es ein unvollständiges Beispiel sein sollte, um
ihm mal grob die Richtung zu zeigen.
@dden
ich glaueb mit dem einrücken war mein post gemeint...
die simulation so wie es im ersten beitrag steht war dahingehend falsch
das immer bei fallender flanke die "clk action" war - so wie @Schlumpf
meinte glaube ich...
jetzt ist die reaktion, wie es soll, auf steigender clk-flanke...
thx für die erläuterungen...