Ich wollte einen Zähler implementieren aber habe komisches Verhalten:
Wenn ich die Komponente mit der breite 4 benutze erwarte ich, dass
stelle mit jedem Takt hochzählt bis es bei 3 wieder auf 0 gesetzt wird.
Leider zählt er bis über 3 hinaus und ich finde die Ursache dafür nicht.
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
4
-- arithmetic functions with Signed or Unsigned values
-- Hier soll weitere Logik folgen (und die Zuweisung auf counter), mit der Benutzung von desc. Aber erst muss das Zählen unter Einhaltung des Grenzen funktionieren.
39
stelle<=stelle+1;
40
41
report"desc ist "&bit'image(desc)severityerror;
42
report"stelle ist "&integer'image(stelle)severityerror;
Christian Q. schrieb:> ich finde die Ursache dafür nicht
Bei mir ist 2^4 = 16.
Wenn er nur von 0 bis 3 zählen soll, reichen auch zwei Bit als
Zählerbreite.
Duke
Christian Q. schrieb:> stelle <= stelle + 1;
In einem Prozess "gewinnt" die letzte Zuweisung an ein Signal. Und
während des Prozesses behält das Signal seinen Anfangszeit. Deshalb
zählt der Zähler einfach weiter.
Der vorhergehende Reset ist wird also einfach "überschrieben"... ?
Die einfachste Lösung war es gerade Variablen für desc und stelle zu
benutzen. Somit funktioniert der code, wie ich erwartet habe. Leider
nicht synthetisierbar - wie ich es lösen kann nur mit Signalen sehe ich
nicht.
Christian Q. schrieb:> Leider nicht synthetisierbar
Warum nicht?
> wie ich es lösen kann nur mit Signalen sehe ich nicht.
1. Zähle zuerst hoch und mach dahinter deine Resetgeschichte.
Oder
2. Zähle in einem "else" hoch.
Bitte ändere den Code erstmal so, dass Du die zwei genannten Punkte
berücksichtigst.
1. Zusammenhang zwischen Bitbreite und Wertebereich. Stichwort
Logarithmus bzw. Potenz
2. Die letzte Zuweisunge gewinnt!
Dann zeige uns den Code mit einer minimalen Testbench, falls das Problem
damit nicht gelöst ist.
Christian Q. schrieb:> elsif stelle = 0 then> stelle <= 0;> desc <= '0';> end if;
Bei diesem selbstverriegelnden "Hänger" könnte es ohne das nachfolgende
Hochzählen sogar sein, dass die Toolchain die stelle und desc hart auf 0
setzt und niemals ändert...
Lothar M. schrieb:>> Leider nicht synthetisierbar> Warum nicht?
Soweit ich weiß sind Variablen nicht synthetisierbar.
Theor schrieb:> 1. Zusammenhang zwischen Bitbreite und Wertebereich. Stichwort> Logarithmus bzw. Potenz
Ich möchte einen "Zeiger" auf die aktuelle Stellen des counters haben,
da dies eine Besonderheit des Zähleverhaltens ist, die sich somit gut
lösen lässt.
Theor schrieb:> 2. Die letzte Zuweisunge gewinnt!
Hier habe ich noch Probleme: Ich habe versucht stelle nur einmalig pro
Durchlauf zu setzen, damit auch nur eine und somit die letzte Zuweisung
gewinnen kann. Ich kann nicht im fall stelle = 0 die stelle erhöhen, da
counter(stelle=0) gesetzt werden soll - andererseits muss ich stelle
verändern damit er nicht in dem Zweig hängt bzw. immer wieder
hineinläuft.
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
4
-- Uncomment the following library declaration if using
5
-- arithmetic functions with Signed or Unsigned values
report"stelle ist "&integer'image(stelle)severityerror;
55
endif;
56
endif;
57
endprocess;
58
59
out_o<=counter;
60
61
endBehavioral;
1
LIBRARYieee;
2
USEieee.std_logic_1164.ALL;
3
4
-- Uncomment the following library declaration if using
5
-- arithmetic functions with Signed or Unsigned values
6
--USE ieee.numeric_std.ALL;
7
8
ENTITYcounterTbIS
9
ENDcounterTb;
10
11
ARCHITECTUREbehaviorOFcounterTbIS
12
13
-- Component Declaration for the Unit Under Test (UUT)
14
15
COMPONENTcounter
16
generic(breite_i:positive);
17
PORT(
18
clk_i:INstd_logic;
19
reset_i:INstd_logic;
20
out_o:OUTstd_logic_vector(0to3)
21
);
22
ENDCOMPONENT;
23
24
--Inputs
25
signalclk_i:std_logic:='0';
26
signalreset_i:std_logic:='0';
27
28
--Outputs
29
signalout_o:std_logic_vector(0to3);
30
31
-- Clock period definitions
32
constantclk_i_period:time:=10ns;
33
34
BEGIN
35
36
-- Instantiate the Unit Under Test (UUT)
37
uut:counter
38
genericmap(breite_i=>4)
39
PORTMAP(
40
clk_i=>clk_i,
41
reset_i=>reset_i,
42
out_o=>out_o
43
);
44
45
-- Clock process definitions
46
clk_i_process:process
47
begin
48
clk_i<='0';
49
waitforclk_i_period/2;
50
clk_i<='1';
51
waitforclk_i_period/2;
52
endprocess;
53
54
55
-- Stimulus process
56
stim_proc:process
57
begin
58
59
reset_i<='1';
60
waituntilrising_edge(clk_i);
61
waitfor2ns;
62
assert(out_o="0000")report"0. Reset hat falsche Initialausgabe"severityerror;
63
reset_i<='0';
64
65
waituntilrising_edge(clk_i);
66
waitfor2ns;
67
assert(out_o="1000")report"1. ist nicht 1000"severityerror;
68
69
waituntilrising_edge(clk_i);
70
waitfor2ns;
71
assert(out_o="1100")report"2. ist nicht 1100"severityerror;
72
73
waituntilrising_edge(clk_i);
74
waitfor2ns;
75
assert(out_o="1110")report"3. ist nicht 1110"severityerror;
76
77
waituntilrising_edge(clk_i);
78
waitfor2ns;
79
assert(out_o="1111")report"4. ist nicht 1111"severityerror;
80
81
waituntilrising_edge(clk_i);
82
waitfor2ns;
83
assert(out_o="0111")report"5. ist nicht 0111"severityerror;
84
85
waituntilrising_edge(clk_i);
86
waitfor2ns;
87
assert(out_o="0011")report"6. ist nicht 0011"severityerror;
88
89
waituntilrising_edge(clk_i);
90
waitfor2ns;
91
assert(out_o="0001")report"7. ist nicht 0001"severityerror;
92
93
waituntilrising_edge(clk_i);
94
waitfor2ns;
95
assert(out_o="0000")report"8. ist nicht 0000"severityerror;
96
97
waituntilrising_edge(clk_i);
98
waitfor2ns;
99
assert(out_o="1000")report"9. ist nicht 1000"severityerror;
100
101
reset_i<='1';
102
waituntilrising_edge(clk_i);
103
waitfor2ns;
104
assert(out_o="0000")report"10. Reset hat keine Wirkung"severityerror;
105
reset_i<='0';
106
107
report"Ende der TB"severityfailure;
108
wait;
109
endprocess;
110
111
END;
1
at 15 ns(1): Error: Richtungsänderung auf asc
2
at 15 ns(1): Error: stelle ist 0
3
at 25 ns(1): Error: stelle ist 1
4
at 35 ns(1): Error: stelle ist 2
5
at 45 ns(1): Error: stelle ist 3
6
at 55 ns(1): Error: Richtungsänderung auf desc
7
at 55 ns(1): Error: stelle ist 4
8
INFO: Simulator is stopped.
stelle wird wieder größer als 3 und der Simulator schmiert wohl ab, beim
Zugriff auf counter(4), was er jedoch nur mit "INFO: Simulator is
stopped." kenntlich macht.
Christian Q. schrieb:> der Simulator schmiert wohl ab
Der hat einfach nur angehalten....
> Soweit ich weiß sind Variablen nicht synthetisierbar.
Prinzipiell ging das schon immer...
Ob die Verwendung von Variablen sinnvoll ist, das kommt ganz auf die
spezielle Anweisung an.
Siehe den Klassiker Beitrag "Variable vs Signal"> at 15 ns(1): Error: Richtungsänderung auf asc> at 15 ns(1): Error: stelle ist 0> at 25 ns(1): Error: stelle ist 1> at 35 ns(1): Error: stelle ist 2> at 45 ns(1): Error: stelle ist 3> at 55 ns(1): Error: Richtungsänderung auf desc> at 55 ns(1): Error: stelle ist 4> INFO: Simulator is stopped.
Warum textest du dir so den Bildschirm voll? Sieh doch einfach die
Waveform an, dann kannst du den Verlauf und die Transitionen mit einem
Blick erfassen.
Lothar M. schrieb:> Warum textest du dir so den Bildschirm voll? Sieh doch einfach die> Waveform an, dann kannst du den Verlauf und die Transitionen mit einem> Blick erfassen.
Das war als Hilfe für den interessierten Leser hier gedacht... hätte ich
es nicht geschrieben hätte jemand gefragt wo denn das Problem sei.
Also gut. Anhand der Asserts sieht man, was Du erwartest.
Das Signal 'stelle' soll wohl die jeweils in einem Takt zu verändernde
Stelle in counter indizieren. Eine vollständige verbale Beschreibung
solltest Du bei künftigen Aufgaben immer erstellen.
Es bleibt zum einen die Tatsache, dass Du berücksichtigen musst, dass
immer die letzte Zuweisung Wirkung hat, aber auch eine andere, die sich
gewissermaßen daraus ergibt: Nämlich, dass bei jedem erneuten
Durchlaufen des Prozesses (wenn man das mal so betrachten will) der
jeweils vorherige Wert eines Signal wirksam ist. Oder anders
betrachtet, löst erst die Taktflanke eine Veränderung der Signale aus,
und zwar im wesentlichen die Veränderung aller Signale gleichzeitig.
Du aber gehst augenscheinlich davon aus, dass etwaige im Text
vorhergehende Zuweisungen in nachfolgenden schon geschehen sind.
An dieser Stelle muss man dann doch mal auf einen beliebten Fehler
hinweisen. Mit VHDL beschreibst man Strukturen und keine Abläufe.
Ergo kannst Du das nicht so sehen, dass eine Sequenz von Anweisungen
durchlaufen wird.
Etwas deutlicher wird das, wenn Du Dir mal die Register und
Logikstruktur im RTL-Viewer anschaust.
Überlege Dir das bitte und versuche es dann noch einmal.
Noch eine Bemerkung: Es gibt verschiedene Punkte, die einen dazu
verführen können, die Beschreibung einer Entity als die eines Vorganges
zu betrachten. Ich weiß nicht, was es bei Dir konkret ist, aber hüte
Dich davor, wie vor der heissen Herdplatte.
Habe möglichst immer das Bild vor Augen, wie bei der jeweiligen
Taktflanke die jeweiligen Signale in dem Moment stehen, dass sie eine
Logikschaltung durchlaufen und das das Zeit kostet, so das deren
Veränderung immer erst nach dieser Zeit gültig sind.
Das gilt auch für Signale, die textlich (d.h. im VHDL-Code) nach aussen
hin nicht sichtbar sind. Dennoch kann man sie als "rückgeführte" Signale
in die Logik betrachten. Die brauchen auch Zeit, bis sie mit neuen
Werten gültig sind.
Christian Q. schrieb:> Ich habe absolut keine Ahnung wie ich solch eine Logik anders> beschreiben kann.
Das ist bedauerlich, aber ein Zustand dem Du abhelfen kannst.
Lies bitte meine zwei vorherigen Beiträge und folge den Ratschlägen, Dir
eine verbale Beschreibung des Ablaufs und eine Skizze der Struktur zu
erstellen. Schau Dir die Ausgabe des RTL-Viewers an, die sich aus Deinem
obigen Code ergibt.
Dann stelle bitte gezielte Fragen zu dem was Du nicht verstehst.
Christian Q. schrieb:> Ich habe absolut keine Ahnung wie ich solch eine Logik anders> beschreiben kann.
Du musst zuerst wissen, was du willst und brauchst. Male dir eine (von
mir aus auch virtuelle) Skizze bzw. einen Schaltplan. Und dann
beschreibe mit der Beschreibungssprache VH-Description-Language das, was
du da vor dir hast: ein Lauflicht.
Im FPGA selbst gibt es nur Flipflops und LUT/Logik, die miteinander
verdrahtet werden. Jede deiner Beschreibungen muss dich auf diese
Elemente abbilden lassen. Wenn es nicht klappt, dann gibt der
Synthesizer Fehler aus.
Und wenn es geklappt hat sieh dir den RTL Schaltplan des Synthesizers an
und versuche zu erkennen, wie deine Beschreibung in Hardware umgesetzt
wird. Hat der Synthesizer deine Beschreibung verstanden und in die
gewünschte Hardware umgesetzt?
Als Tipp: dieser Lernprozess braucht wochenlange Übung.
Nimm dir mal Zeile für Zeile das Blinklicht und das Lauflicht durch:
http://www.lothar-miller.de/s9y/archives/80-Hello-World!.htmlhttp://www.lothar-miller.de/s9y/archives/61-Lauflicht.html
Spiele damit herum, ändere Kleinigkeiten und sieh, was passiert.
Christian Q. schrieb:> Ich habe absolut keine Ahnung wie ich solch eine Logik anders> beschreiben kann.
Ist dein Ziel das, was du da in der Waveform siehst?
Dann sieht die Lösung so aus: ein Zähler, der bei Erreichen des oberen
Zählerwerts zurückgesetzt wird. Und ebenfalls bei Erreichen des oberen
Zählerwerts wird das Flag umgeschaltet, das sagt, ob die Bits gesetzt
oder zurückgesetzt werden sollen:
Danke für die Lösung. Das Problem war ein Denkfehler in den ich mich
versteift habe, das desc Flag jeweils an beiden Rändern zu setzen statt
es nur einem Rand zu flippen. Somit eliminiert sich der Fall stelle = 0,
der mir Probleme gemacht hat:
Christian Q. schrieb:> Hier habe ich noch Probleme: Ich habe versucht stelle nur einmalig pro> Durchlauf zu setzen, damit auch nur eine und somit die letzte Zuweisung> gewinnen kann. Ich kann nicht im fall stelle = 0 die stelle erhöhen, da> counter(stelle=0) gesetzt werden soll - andererseits muss ich stelle> verändern damit er nicht in dem Zweig hängt bzw. immer wieder> hineinläuft.
Das Wellenform-Diagramm stimmt mit meiner Erwartung überein.
So wie ich es gestern verstanden hatte ginge mein Problem nicht so zu
lösen, da ich alles umstrukturieren und den Ansatz komplett ändern
müsse. Gut, dass es wohl doch geht und ich dieses bestimmte Problem so
lösen kann. Dass ich nicht alles in eine Entity packe sondern in mehrere
und diese mit Signalen verbinde war mir klar aber hier konnte ich solch
eine Trennung nicht sinnvoll herausfinden.
Christian Q. schrieb:> Danke für die Lösung. Das Problem war ein Denkfehler in den ich mich> versteift habe, das desc Flag jeweils an beiden Rändern zu setzen statt> es nur einem Rand zu flippen. Somit eliminiert sich der Fall stelle = 0,> der mir Probleme gemacht hat:
Naja. Aus dem Code war ersichtlich, dass desc keine Richtung angibt,
also nicht etwa "descend" bedeuten sollte, sondern das inverse des
Wertes, auf den die durch Stelle indizierten Bits zu setzen waren. (Hier
mal der Tip, wirklich sprechende Signalnamen zu verwenden).
Deswegen mein Rat, zunächst eine verbale Beschreibung zu erstellen.
Ich hätte auch ganz direkt darauf eingehen können, habe das aber aus
didaktischen Gründen nicht getan. Auch weil ich Dich anregen wollte,
tatsächlich auch analytische Fehlerbeschreibungen zu liefern.
> Christian Q. schrieb:>> Hier habe ich noch Probleme: Ich habe versucht stelle nur einmalig pro>> Durchlauf zu setzen, damit auch nur eine und somit die letzte Zuweisung>> gewinnen kann. Ich kann nicht im fall stelle = 0 die stelle erhöhen, da>> counter(stelle=0) gesetzt werden soll - andererseits muss ich stelle>> verändern damit er nicht in dem Zweig hängt bzw. immer wieder>> hineinläuft.
Ja. Da hast Du tatsächlich einen Schritt in die richtige Richtung getan.
Nur eben nicht zu Ende gedacht. Wiederrum bestand die Möglichkeit, Dir
das direkt zu sagen, aber ich habe es nicht getan, damit Du selbst
darauf kommst.
> Das Wellenform-Diagramm stimmt mit meiner Erwartung überein.
Gut.
> So wie ich es gestern verstanden hatte ginge mein Problem nicht so zu> lösen, da ich alles umstrukturieren und den Ansatz komplett ändern> müsse. Gut, dass es wohl doch geht und ich dieses bestimmte Problem so> lösen kann. Dass ich nicht alles in eine Entity packe sondern in mehrere> und diese mit Signalen verbinde war mir klar aber hier konnte ich solch> eine Trennung nicht sinnvoll herausfinden.
Was Du verstanden hattest, hättest Du früher schreiben sollen (ich nehme
an, Du beziehst Dich auf meine Antwort). Ich meine das nicht irgendwie
übel sondern als sachliche Kritik. :-)
Du schriebst aber: "Ich habe absolut keine Ahnung wie ich solch eine
Logik anders beschreiben kann."
Es blieb offen, in welcher Hinsicht Du "anders" meintest.
Ich habe den Satz so gedeutet, dass er sich direkt auf meinen bezog. Von
einer anderen Struktur habe ich aber nichts geschrieben (deswegen hielt
ich es für unwahrscheinlich, dass Du das meintest). Ich habe davon
geschrieben, Dir bestimmte Dinge im zeitlichen Ablauf vor Augen zu
halten. Ich hatte mir vorgestellt, dass Du Dir die Zuweisungen noch
einmal anschaust und wann sie wirksam werden. Nicht, dass Du die
Beschreibung völlig anders strukturierst.
Das wäre auf weitere Widersprüche im Konzept hinausgelaufen, soviel ist
klar. Aber wie gesagt, ich wollte Dich nicht allzu direkt darauf
hinweisen, sondern Dir selbst den Lerneffekt bescheren. Man lernt
nämlich aus Fehlern eine ganze Menge.
Allerdings ist es richtig, dass es auch andere Lösungen gibt. Das ist
oft so.
Du könntest das Ding z.B. als Schieberegister betrachten. Das ist eine
hübsche Übungsaufgabe.
Dann entfällt das Signal Stelle und das ganz benötigt weniger Resourcen.
Die Hauptfrage wäre, welcher Bitwert wird jeweils links eingeschoben?
Kann man diesen Wert (oder sein inverses) aus einem Bit des
Schieberegisters ableiten?
Oder Du könntest es als Zähler betrachten, bei der sich der neue
Zählerstand aus einer Kombinatorik des alten ergibt.
Vielleicht probierst Du das ja mal.
Jedenfalls noch viel Erfolg und alles Gute. :-)
Theor schrieb:> Was Du verstanden hattest, hättest Du früher schreiben sollen (ich nehme> an, Du beziehst Dich auf meine Antwort).
Mein Fehler.. Was man wirklich weiß ist im Lernprozess meistens noch
nicht ganz klar.
Theor schrieb:> Du könntest das Ding z.B. als Schieberegister betrachten. Das ist eine> hübsche Übungsaufgabe.
Christian Q. schrieb:> Theor schrieb:>> Was Du verstanden hattest, hättest Du früher schreiben sollen (ich nehme>> an, Du beziehst Dich auf meine Antwort).>> Mein Fehler.. Was man wirklich weiß ist im Lernprozess meistens noch> nicht ganz klar.
Ich meinte damit, wie Du meine Antwort verstanden hattest. Was ihre
Aussage war. Das bezog sich nicht auf den Stand Deines Lernprozesses.
:-)
> Theor schrieb:>> Du könntest das Ding z.B. als Schieberegister betrachten. Das ist eine>> hübsche Übungsaufgabe.>>
1
counter<=(notcounter(breite-1))&counter(0to
2
>breite-2);
>> Unter der Annahme breite > 1
Ja. Gut. Und so schnell. :-) Prima.