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'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN |
2 | -- nichts zu tun hier?
|
3 | ELSIF (stsig<="0000") THEN r<='0'; ge<='0'; g<='0'; |
4 | ELSIF (stsig<="0001") THEN r<='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.
:
Bearbeitet durch Moderator
@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 :-)
so jetzt aber
1 | if rising_edge(clk) then |
2 | case stsig is |
3 | when "0000" => |
4 | r<='1'; |
5 | when "0101" => |
6 | if q_a="0000" then |
7 | r<='0'; |
8 | ge<='0'; |
9 | g<='0'; |
10 | elsif q_a="0101" then |
11 | r<='0'; |
12 | ge<='1'; |
13 | g<='0'; |
14 | end if; |
15 | when others => |
16 | |
17 | end case; |
18 | end if; |
deine simulation ist falsch und bildet nicht die wirklichkeit ab.
oki ich verstehe glaube wo das prob lag - die erste elsif muss ein if sein, dann müsste es stimmen! so geändert...
1 | ARCHITECTURE behav OF ampel IS |
2 | BEGIN
|
3 | |
4 | p1 : PROCESS (clk) |
5 | BEGIN
|
6 | |
7 | IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN |
8 | IF (stsig="0000") THEN r<='0'; ge<='0'; g<='0'; |
9 | ELSIF (stsig="0001") THEN r<='1'; ge<='0'; g<='0'; |
10 | ELSIF (stsig="0010") THEN r<='1'; ge<='1'; g<='0'; |
11 | ELSIF (stsig="0011") THEN r<='0'; ge<='0'; g<='1'; |
12 | ELSIF (stsig="0100") THEN r<='0'; ge<='1'; g<='0'; |
13 | ELSIF (stsig="0101" AND q_a="1001") THEN r<='0'; ge<='1'; g<='0'; |
14 | ELSIF (stsig="0101" AND q_a="0000") THEN r<='0'; ge<='0'; g<='0'; |
15 | END IF; |
16 | END IF; |
17 | END PROCESS p1 ; |
18 | |
19 | END behav; |
@dden: also dein code sieht auch gut aus, mit case anweisung habe ich noch nix gemacht (nur gelesen) ... deswegen noch net so richtig ran getraut^^
:
Bearbeitet durch Moderator
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:
1 | IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN |
2 | IF (stsig<="0000") THEN r<='0'; ge<='0'; g<='0'; |
3 | ELSIF (stsig<="0001") THEN r<='1'; ge<='0'; g<='0'; |
4 | ELSIF (stsig<="0010") THEN r<='1'; ge<='1'; g<='0'; |
5 | ELSIF (stsig<="0011") THEN r<='0'; ge<='0'; g<='1'; |
6 | ELSIF (stsig<="0100") THEN r<='0'; ge<='1'; g<='0'; |
7 | ELSIF (stsig<="0101" AND q_a<="1001") THEN r<='0'; ge<='1'; g<='0'; |
8 | ELSIF (stsig<="0101" AND q_a<="0000") THEN r<='0'; ge<='0'; g<='0'; |
9 | END IF; |
10 | END IF; |
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.
:
Bearbeitet durch Moderator
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...
dden schrieb: > wasn da nicht ordentlich eingrückt ?? Du warst doch gar nicht gemeint... Das da war gemeint:
1 | IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN |
2 | IF (stsig="0000") THEN r<='0'; ge<='0'; g<='0'; |
3 | ELSIF (stsig="0001") THEN r<='1'; ge<='0'; g<='0'; |
Eine Verschärfung, die jetzt noch denkbar wäre, ist dass alles vorn am Zeilenanfang beginnt:
1 | IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN |
2 | IF (stsig="0000") THEN r<='0'; ge<='0'; g<='0'; |
3 | ELSIF (stsig="0001") THEN r<='1'; ge<='0'; g<='0'; |
Oder dass die Einrückungen gar nichts mit der Struktur zu tun haben:
1 | IF (clk'EVENT AND clk'LAST_VALUE='0' AND clk='1') THEN |
2 | IF (stsig="0000") THEN r<='0'; ge<='0'; g<='0'; |
3 | ELSIF (stsig="0001") THEN r<='1'; ge<='0'; g<='0'; |
:
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.