variablev_bcnt:integerrange0toBITS-1:=0;--integer rang 0 bis BITS;
31
variablevcnt_stbbit:integerrange0to1:=STOPBIT;--anzahl der stopbits
32
begin
33
ifRESET='1'then
34
l_mstate<=IDLE;--set the machine to start.
35
v_counter:=0;-- reset v_counter
36
l_ready<='1';--set ready to not ready for new data i am in the process.
37
elsifNDATA='1'andl_ready='1'then--new data?
38
l_databit<=databit;--nur bei reset zuweisen
39
l_mstate<=START;
40
l_ready<='0';
41
elsifBCLK'eventandBCLK='0'then
42
ifv_counter=0then
43
v_counter:=CLK_MUL-1;
44
casel_mstateis
45
whenIDLE=>null;
46
l_mstate<=IDLE;--set the machine to start.
47
whenSTART=>
48
l_obit<='0';
49
l_mstate<=SEND;
50
v_bcnt:=BITS-1;
51
vcnt_stbbit:=STOPBIT;
52
whenSEND=>
53
l_obit<=l_databit(0);
54
l_databit<='0'&l_databit(BITS-1downto1);
55
ifv_bcnt=0then
56
l_mstate<=STOP;
57
else
58
v_bcnt:=v_bcnt-1;
59
endif;
60
whenSTOP=>
61
l_obit<='1';
62
ifvcnt_stbbit=0then
63
l_mstate<=IDLE;
64
l_ready<='1';--ready for new data
65
else
66
vcnt_stbbit:=vcnt_stbbit-1;
67
endif;
68
endcase;
69
else
70
v_counter:=v_counter-1;
71
endif;
72
endif;
73
endprocessP1;
74
75
PO:process(l_obit,l_ready)
76
begin
77
READY<=l_ready;
78
DO<=l_obit;
79
endprocessPO;
80
endSTRUCT;
So die Entwicklungsumgebung erzählt mir in der Timequest Analyzer, dass
das Signal "CONTROL:RS232CNT|RS232_RX:RS232RX|l_mstate.IDLE~1" eine
clock ist. Jetzt meine Frage warum sollte das eine Clock sein? Den
Zusammenhang verstehe ich nicht.
Bitte helft mir fürs Verständnis!
Vielen Dank
Ein von beiden Anweisung ist definitiv überflüssig.
Ich würde die Zuweisung an l_mstate weglassen.
2.
1
process(BCLK,RESET,databit,NDATA,l_ready)
Deine Sensitivity-Liste ist genauso unübersichtlich, wie Dein Code.
Ich versuche in meinen Designs (zu 98% gelingt das auch) nur mit CLK zu
arbeiten. Das sind sogenannte synchrone Designs.
In Einzelfällen kommt dann noch ein (asynchroner) Reset dazu.
3.
variablev_bcnt:integerrange0toBITS-1:=0;--integer rang 0 bis BITS;
3
variablevcnt_stbbit:integerrange0to1:=STOPBIT;--anzahl der stopbits
Für die gestellte Aufgabe sind das definitiv zu viele Variablen.
Hier nochmal kurz und prägnant von Lothar postuliert:
Beitrag "Re: VHDL - For-Schleife"
1
Ein Design (insbesondere ein Anfängerdesign) hat genau 1 Takt,
2
der immer auf dieselbe Flanke aktiv ist.
3
Es gibt keinen (und schon gar keinen asynchronen) Reset.
4
Externe Signale werden über 2 Flipflops einsynchronisiert.
5
Jede Abweichung von diesen Regeln muß fundiert begründet werden können.
Versuch mal Deinen Code dahingehend umzuschreiben...
Duke
MALGUCKEN schrieb:> Erstmal der Code:library ieee;>> P1: process(BCLK,RESET,databit,NDATA,l_ready)> variable v_counter: integer range 0 to CLK_MUL := 0; --integer> variable v_bcnt: integer range 0 to BITS-1 := 0; --integer rang 0 bis> BITS;> variable vcnt_stbbit: integer range 0 to 1 := STOPBIT; --anzahl der> stopbits> begin> if RESET='1' then> l_mstate <= IDLE; --set the machine to start.> v_counter := 0; -- reset v_counter> l_ready <= '1'; --set ready to not ready for new data i am in the> process.> elsif NDATA = '1' and l_ready = '1' then --new data?> l_databit <= databit; --nur bei reset zuweisen> l_mstate <= START;> l_ready <= '0';> elsif BCLK'event and BCLK='0' then> if v_counter=0 then> v_counter := CLK_MUL-1;> case l_mstate is> when IDLE => null;> l_mstate <= IDLE; --set the machine to start.
...schnipp
> else> v_counter := v_counter - 1;> end if;> end if;> end process P1;
Dein process ist sehr eigenwillig beschrieben. in eine sebsitixity list
gehört nur Takt und asynchroner reset, das elsif twischen reset und takt
ist auch nicht schön.
Vorschlag: Zeichne ein Blockbild es uarts aus shift Register,
Steuerung-fsm, bitzähler. für jede der drei Komponenten schreibst du
einen eigenen process.
ifRESET='1'then-- asynchroner Reset muss Taktsynchron inaktiv werden!
2
....
3
elsifNDATA='1'andl_ready='1'then-- NIEMALS Kombinatorik im Reset!!!
4
....
5
elsifBCLK'eventandBCLK='0'then
Ganz, ganz böse Sache: asynchroner und kombinatorischer Reset. Das
Design wird niemals stabil laufen: ein einziger Glitch und ein paar FF
der SIO werden zurückgesetzt. Und zwar jedesmal irgendwelche Anderen...
BTW:
Hi danke für eure Anregung.
Ich habe bezüglich eurer Antworten ein paar Fragen um als Anfänger etwas
Wissen ab zu stauben ;)
1. Ihr meint in der senstiv liste des Prozessen gehören nur CLK und
RESET.
Ist es nicht so, dass der Compiler (Syntesewerkzeug) eh alle
gelesenen Signal nachträglich in diese Liste einfügt?
2. Ihr fragt nach den CLKs
Ich erzeuge eine BCLK aus dem CLK in Form eines Zählers, welche mir dann
einen CLK erzeugt, welche ca. 12mal Schneller als die Baud rate ist.
Angenommen dies ist falsch und ich benutze nur die CLK dann muss ich ja
in dem RS Block selber immer mit zählen was die Variablenanzahl noch
erhöht und zum andern den Code noch unübersichtlicher gestaltet.
Die einzige Lösung die mir in den Sinn kommt (keine Erfahrung) ist
dieser schritt wie er in einigen Diskussionsthreads angesprochen wird.
1
....
2
beginprocess(CLK)
3
variablev_ch_bclk:bit:='1';
4
begin
5
ifCLK'eventandCLK='1'then
6
ifv_ch_blk/=BCLKandBCLK='1'then
7
......
8
v_ch_blk:=BCLK;
9
else
10
v_ch_blk:=BCLK;
11
endif;
12
endif;
13
endprocess;
Vormal ist das eine Flanken wechsle Erkennung welche synchron mit dem
TAKT läuft.
Vielen Dank :)
MALGUCKEN schrieb:> 1. Ihr meint in der senstiv liste des Prozessen gehören nur CLK und> RESET. Ist es nicht so, dass der Compiler (Syntesewerkzeug) eh alle> gelesenen Signal nachträglich in diese Liste einfügt?
Nein. Er ignoriert die Sensitivliste komplett und meldet bestenfalls
mit einer Info, dass die Simulation nicht merh zur generierten Hardware
passt und somit falsch ist.
> 2. Ihr fragt nach den CLKs Ich erzeuge eine BCLK aus dem CLK in Form> eines Zählers, welche mir dann einen CLK erzeugt, welche ca. 12mal> Schneller als die Baud rate ist.
Dacht ichs mir doch...
So werden keine Takte erzeugt. Arbeite mit 1 einzigen Takt im
gesamten Design. Und wenn du langsamere "Untertakte" brauchst, dann
arbeitest du ausschließlich mit Clock-Enables. So wie dort der "Takt"
für das Lauflicht erzeugt und über clken weitergegeben wird:
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html
Hallo Lothar Miller,
danke für deine Antworten. Ich habe es jetzt zu einer Takt enable
Schaltung umgestellt. In der tat taucht jetzt in den Timings das Problem
nicht mehr auf. Eine frage habe ich noch. ich frage jetzt den Reset nach
dem clk event ab. Als der Code sieht nun wie folgt aus. (Immer noch
etwas chaotisch)
Lothar M. schrieb:> Übrigens: nur Schulen arbeiten mit "bit". Der Rest der Welt nimmt> std_logic...
:D ja und in dem Buch wird ein ganzes Kapitel über Vor- und Nachteile
von std_logic und bit verschwendet. Die Grundaussage war, das man bit
verwenden soll wenn man std_logic nicht benötigt. Wo und Nachteile?
Lothar M. schrieb:> Und wenn NDATA ein externer (und damit meist asynchroner) Eingang ist,> dann muss der natürlich auch einsynchronisiert werden.
Tut mir leid da komme ich nicht mit. Ich habe deinen Beitrag gelesen und
die Links dazu. Dort steht nur, das die reset nach dem clk event folgen
soll. Meinst du mit "einsynchronisiert", dass das Signal extern auch mit
clk event erzeugt werden soll? Oder soetwas:
MALGUCKEN schrieb:> Lothar M. schrieb:>> Übrigens: nur Schulen arbeiten mit "bit". Der Rest der Welt nimmt>> std_logic...>> :D ja und in dem Buch wird ein ganzes Kapitel über Vor- und Nachteile> von std_logic und bit verschwendet. Die Grundaussage war, das man bit> verwenden soll wenn man std_logic nicht benötigt. Wo und Nachteile?
Falls du jemals auf die Idee kommen solltest, einen VHDL Simulator zu
verwenden, dann wuerde der dir mit 'std_logic(_vector)' wunderschoen
Konflikte und nicht initialisierte Signale anzeigen. Und das ist beim
entwickeln ein Riesenvorteil. Frueher hat man mal wegen der
Laufzeit/Rechenleistung darueber rumdiskutiert, ist aber heute kein
Thema mehr...
Und uebrigens: Warum diese komplett unnoetigen Variablen? Die
Nebeneffekte von Variablen ggue. Signalen sind dir hoffentlich bekannt?
MALGUCKEN schrieb:> Lothar M. schrieb:>> Und wenn NDATA ein externer (und damit meist asynchroner) Eingang ist,>> dann muss der natürlich auch einsynchronisiert werden.>> Tut mir leid da komme ich nicht mit. Ich habe deinen Beitrag gelesen und> die Links dazu. Dort steht nur, das die reset nach dem clk event folgen> soll. Meinst du mit "einsynchronisiert", dass das Signal extern auch mit> clk event erzeugt werden soll?
Ein in VHDL beschriebener asynchroner Reset ist jetzt erstmal nix
verwerfliches, der mag ja in deiner Chiparchitektur besser implementiert
sein als ein synchroner. Ausserdem sichert er dich gegen Fehlfunktion
ab, falls mal der Takt gar nicht loslaeuft (Quartz kaputt, PLL laeuft
nicht an, ...)
ABER: Wenn du den Reset 'deaktivierst', dann must du auch dafuer sorgen,
dass innerhalb eines Taktes ALLE daran haengenden Flipflops das
deaktivieren 'sehen'. Sonst laeuft evtl. ein Zaehler falsch los (z.B.
Bit(0) sieht den weggehenden Reset erst einen Takt spaeter) oder eine
State-Machine steht im Wald...
Und deine Toolchain kann dir in diesem Fall nur helfen, wenn der Reset
'synchron' weggenommen wird, ansonsten ist raten angesagt...
berndl schrieb:> Und uebrigens: Warum diese komplett unnoetigen Variablen? Die> Nebeneffekte von Variablen ggue. Signalen sind dir hoffentlich bekannt?
Die Nebeneffekte von Variablen sind mir leider nicht bekannt. und ja
signal verwende ich auch. Bitte erklären
Danke
MALGUCKEN schrieb:> Die Nebeneffekte von Variablen sind mir leider nicht bekannt. und ja> signal verwende ich auch. Bitte erklären
Eine Variable kannst du ja nur in einem sequenziellen, getakteten
'process' verwenden. Sie nimmt einen ihr zugewiesenen Wert sofort an.
Falls du aber diese Variable 'vorher' im Prozess schon abfragst, dann
ist das der Ausgang eines Flipflops, also einen Takt spaeter. Und das
kann ganz schoen verwirrend sein...
Ein Signal, das in einem 'process' verwendet wird, aendert seinen Wert
erst, wenn du am 'end process;' ankommst, d.h. im ganzen Prozess hat das
Signal den gleichen Wert. De facto also immer ein Flipflop.
Falls du sowas wie eine Variable brauchst (Zwischenergebnis einer
Berechnung oder sowas), dann kannst du das auch als Signal ausserhalb
eines Prozesses mit sogenannten 'concurrent' Anweisungen machen, also
z.B. "a <= '1' when xy = '0' else '0';" Das wirkt dann wie eine Variable
in einem Prozess sofort. Die Gefahr bei Variablen ist dann noch
zusaetzlich, dass sie laufzeitkritische Berechnungen gut verschleiern.
All das hat mich dazu gefuehrt, Variablen nur fuer ganz bestimmte Zwecke
zu benutzen und ansonsten auf 'concurrent' Anweisungen zu setzen. Dein
Code wird dadurch eindeutiger weil klar ist: Isses ein FF oder isses ein
Netz irgendwo in der Logik.
berndl schrieb:> Eine Variable kannst du ja nur in einem sequenziellen, getakteten> 'process' verwenden. Sie nimmt einen ihr zugewiesenen Wert sofort an.> Falls du aber diese Variable 'vorher' im Prozess schon abfragst, dann> ist das der Ausgang eines Flipflops, also einen Takt spaeter. Und das> kann ganz schoen verwirrend sein...
Gmpf, Korrektur...
Eine Variable kannst du ja nur in einem sequenziellen 'process'
verwenden. Sie nimmt einen ihr zugewiesenen Wert sofort an. Falls du
aber diese Variable 'vorher' im Prozess schon abfragst, dann ist das der
Ausgang eines Flipflops/Latches, also einen Takt/Zustand spaeter. Und
das kann ganz schoen verwirrend sein...
MALGUCKEN schrieb:> in dem Buch
In welchem?
MALGUCKEN schrieb:> Die Nebeneffekte von Variablen sind mir leider nicht bekannt. und ja> signal verwende ich auch. Bitte erklären
Siehe den Beitrag "Variable vs Signal"berndl schrieb:> Ein Signal, das in einem 'process' verwendet wird, aendert seinen Wert> erst, wenn du am 'end process;' ankommst, d.h. im ganzen Prozess hat das> Signal den gleichen Wert. De facto also immer ein Flipflop.
Das hat mit Flipflop aber nichts zu tun. Das Signal verhält sich auch in
einem rein kombinatorischen Prozess so.
Ob Flipflops involviert sind, sieht man am 'event (gern auch versteckt
im rising_edge() o.ä.).
Lothar M. schrieb:> Siehe den Beitrag "Variable vs Signal"
Danke fuer den Link, den hatte ich gesucht, aber gerade nicht auf dem
Radar...
Schoen waere ja, wenn VHDL 'lokale' Signaldefinitionen im Prozess
unterstuetzen wuerde (also z.B.
1
hugo:process
2
signalxy:std_logic:='0';
3
begin
4
....
5
endprocess;
Dann waere den 'lokale Variablen' Befuerwortern viel Wind aus den Segeln
genommen...
Lothar M. schrieb:> MALGUCKEN schrieb:>> in dem Buch> In welchem?
Das bleibe ich schuldig Sitz im Zug ISBN kommt später nach.
Zu den variablen. Sehe ich das richtig das ihr empfehlt das alle
variablen als signale geschrieben werden sollten? Aber macht das den
code nicht noch unübersichtlicher? Wenn ich neben den normalen Signalen
Zähler Signale usw. Habe?
Meine andere Frage mit den ndata blieb offen zwecks Synchronisation.
berndl schrieb:> ABER: Wenn du den Reset 'deaktivierst', dann must du auch dafuer sorgen,> dass innerhalb eines Taktes ALLE daran haengenden Flipflops das> deaktivieren 'sehen'. Sonst laeuft evtl. ein Zaehler falsch los (z.B.> Bit(0) sieht den weggehenden Reset erst einen Takt spaeter) oder eine> State-Machine steht im Wald...> Und deine Toolchain kann dir in diesem Fall nur helfen, wenn der Reset> 'synchron' weggenommen wird, ansonsten ist raten angesagt...
Aber wie soll ich das anstellen wenn reset auf der linken oberen Seite
des FPGAs erzeugt wird und meine Schaltung rechts unten liegt, dann habe
ich da kein Einfluss. Das muss doch das Synthese tool sicherstellen das
meine Signale zum CLK event da sind.
MALGUCKEN schrieb:> Aber wie soll ich das anstellen wenn reset auf der linken oberen Seite> des FPGAs erzeugt wird und meine Schaltung rechts unten liegt, dann habe> ich da kein Einfluss. Das muss doch das Synthese tool sicherstellen das> meine Signale zum CLK event da sind.
Wenn deine Reset Schaltung links/oben liegt, du aber das deaktivieren
des Resets ueber mehrere getaktete Flipflops machst, dann kann dein Tool
ueblicherweise diese 'mehrere getakteten FFs' duplizieren und mit ein
paar Taktzyklen Latenz das auf jeden Ort auf dem Chip verteilen. Und
zwischen zwei FFs kann deine Toolchain auch wunderbar berechnen, ob dein
Timing noch zu halten ist.
Sollte also damit (Takte hinzufuegen, pipelineing, ...) kein Problem
sein, weil: Wann die Schaltung aus dem Reset rauskommt, das kann ja wohl
nicht an ein paar mal 10 Nanosekunden abhaengen...
MALGUCKEN schrieb:> Das muss doch das Synthese tool sicherstellen das meine Signale zum CLK> event da sind.
Du sagst der Toolchain, wie schnell du es haben willst. Und die probiert
dann, deine Anforderungen zu erfüllen und sagt es, wenn es nicht
klappt...
Guten Abend,
ich war noch das Buch schudig welches ich verwende:
VHDL-Synthese: Entwurf digitaler Schaltungen und Systeme.
ISBN: 978-3486716771
Lothar M. schrieb:> Du sagst der Toolchain, wie schnell du es haben willst. Und die probiert> dann, deine Anforderungen zu erfüllen und sagt es, wenn es nicht> klappt..
OK so weit bin ich noch nicht vorgedrungen. Ich denke das ist der
nächste Schritt.
Vielen Dank an alle für die sehr guten Anregungen.
berndl schrieb:> Schoen waere ja, wenn VHDL 'lokale' Signaldefinitionen im Prozess> unterstuetzen wuerde (also z.B.hugo :
Signale können 'lokal' innerhalb eines block-Statements definiert
werden:
Duke Scarring schrieb:> Signale können 'lokal' innerhalb eines block-Statements definiert> werden:
ups, danke! Das hab' ich in der freien Wildbahn noch nie gesehen und es
waere schoener, wenn das zwischen process und begin ginge, aber besser
als nix
hmmmm, bei Google mit "vhdl block statement" finde ich immer nur
Erwaehnungen von 'concurrent' statements...
Kann ich in ein "block" statement auch einen "process" reinpacken?
Muss ich bei Gelegenheit mal probieren...
berndl schrieb:> block-Statements [...] freien Wildbahn
In meinem aktuellen Projekt kommen ca. 50 entitys vor. Ein einer davon
verwende ich 'block'.
In VHDL-Beispielen aus dem Netz und in Lehrbüchern wird oft die
kritische Codegröße gar nicht erreicht, um ein block-Statement
einzusetzen.
Duke