Hallo zusammen
Ich schreibe seit circa einem Semester an der Universität VHDL, doch
werde ich das gefühl nicht los, dass ich teils eher schlecht als recht
latches verhindere. Bisher habe ich die Werte, welche geändert werden in
eine next_"variablenname" zischengespeichert und erst beim clock die
daten gespeichert daher konnte ich dies relativ gut umgehen.
Leider hat dies bei folgendem Code nicht geklappt und alle signale und
variablen erzeugen latches,daher die frage wie löse ich die Latches für
folgende variablen und signale:
1
signal time_stamp : integer:=0;
2
signal next_time_stamp : integer:=0;
3
-- Begin Architecture
4
-------------------------------------------
5
begin
6
7
timer : process (all)
8
variable prescaler_counter: integer:=0;
9
variable next_prescaler_counter: integer:=0;
10
variable speed: integer := 168;
11
12
begin
13
if(sw = '1') then
14
next_prescaler_counter := prescaler_counter + 1;
15
next_time_stamp <= time_stamp +1;
16
17
if(rising_edge(step_i)) and (prescaler_counter<speed) then
18
prescaler_counter := next_prescaler_counter;
19
note_flag <= '0';
20
elsif(prescaler_counter = speed) then
21
prescaler_counter := 0;
22
note_flag <= '1';
23
time_stamp <= next_time_stamp;
24
end if;
25
else
26
prescaler_counter := 0;
27
time_stamp<= 0;
28
note_flag <= '0';
29
end if;
30
end process timer;
Funktionsbeschreib: Step ist ein clock der heruntergeteilt werden muss.
Pro clock wird der prescaler um 1 erhöht bis halt der teilerwert 168
erreicht wird und dann wird bis zum nächsten puls das flag Note_flag
gesetzt und der timestamp um 1 erhöht um einen zähler zu haben mit
enstsprechendem takt.
Danke im voraus für eure Antworten
Da ich eigentlich beschäftigt bin, nur eine kurze Antwort: Du solltest
rein kombinatorische und taktabhängige Signale nicht in einem Prozess
haben.
(Mindestens) einen Prozess für kombinatorische Signale und (mindestens)
einen rein taktabhängigen Prozess (von einem asynchronen Reset eventuell
abgesehen). Dann wird es übersichtlicher.
Dominic K. schrieb:> Ich schreibe seit circa einem Semester an der Universität VHDL, doch> werde ich das gefühl nicht los, dass ich teils eher schlecht als recht> latches verhindere.
Lass mich raten: du hast vorher C (oder sonst eine prozedurale
Programmiersprache) programmiert und verwendest das dabei Gelernte jetzt
für VHDL?
Das geht schief, denn du wendest dabei die völlig falsche Denkweise an.
Dominic K. schrieb:
Mich wundert, dass der das überhaupt zu irgendwas synthetisiert. Wo hast
du diesen "gegatet-kombinatorisch-getakteten" Beschreibungsstil
gefunden?
Dominic K. schrieb:> Funktionsbeschreib: ....
Wie würdest du das in Hardware mit Zählern, vergleichern und Registern
machen? Kannst du dafür eine Schaltplanskizze aufmalen?
> Step ist ein clock der heruntergeteilt werden muss.
Dieser Step wird aber niemals im FPGA als Taktquelle verwendet!
Takte sind in einem FPGA etwas ganz besonderes, denn sie werden auf dem
Taktnetz an die angschlossenen Flipflops verteilt.
In einem Anfängerdesign (und in einem einfah zu wartenden
Forgeschrittenendesign) gibt es nur 1 Takt, der kommt vom
Quarzoszillator und der hat so ca. 50..100MHz.
Also ist dieser Step lediglich ein ganz normales Signal, das im FPGA
erzeugt und auf dessen Änderung im FPGA reagiert wird.
Ein Tipp: diese mit (all) abgekürzte Sensitivliste ist was, das Anfänger
nicht verwenden sollten. Denn es verleitet dazu, sich keine Gedanken zum
Design zu machen. Schreibe in die Sensitivliste mal nur die Signale, von
denen du meinst, dass sie dort drin nötig sind. Oft gibt das dann den
Impuls bei der Fehlersuche...
BTW: löse die Aufgabe ohne Variablen. Du brauchst sie hier sicher nicht.
Denn Variablen sind für dich "false friends", weil du den Namen von C
her kennst und meinst, in VHDL würden die das selbe machen.
Siehe den Beitrag "VHDL variable vs signal" und den darin
enthaltenen Link auf Beitrag "Variable vs Signal"
Ich habe bisher in der tat Java, assembler und C programmiert :D aber
versuche mich dazu zu zwingen meine denkweise umzuschalten auch wenn ich
parallel zur Hardware description language auch programmiersprachen
schreibe.
Mein grund für die Variablen war die Hoffnung die Schaltung weniger
komplex zu machen weil diese ja nur lokal im Prozess sind und nicht wie
ein signal übergreifend. Ich brauche lediglich das note_flag um zu
wiesen, ob ein überlauf da ist und denn stamp um einen zähler zu haben,
welcher zählt wie viele zyklen durch sind.
anliegend eine skizze wie ich das ganze als logik aufbauen würde aber
halt sehr vereinfacht und hilft mir zumindest nicht um latches los zu
werden.
ein besseres Beispiel wäre wohl folgendes Beispiel wo die
Note_on,note,velocity und velocity_cache als latches gemacht werden. Der
einzige case welchen ich nicht abdecke ist wenn sw 1 ist aber timestamp
nicht gleich time_cache aber dort darf ich denn wert halt nicht ändern.
Wie würdet ihr das lösen?
Dominic K. schrieb:> anliegend eine skizze wie ich das ganze als logik aufbauen würde
Ja, aber wie gesagt: step_in ist kein Takt. Du musst was Anderes
ausdenken, dein einziger Takt im ganzen Design Takt ist der
Quarzoszillator am Takteingang des FPGAs.
Dominic K. schrieb:> ein besseres Beispiel wäre wohl folgendes Beispiel wo die> Note_on,note,velocity und velocity_cache als latches gemacht werden.
Ja, klar, wenn ein nicht getakteter, kombinatorischer Prozess etwas
speichern muss, dann kann der Synthesizer dafür nur Latches nehmen. Und
Latches sind nicht gefährlich, weil sie Latches sind, sondern weil sie
auf jeden Glitch reagieren, wenn einer der beiden Signale hier seinen
Wert ändert:
> if(time_stamp = time_cache) then
Denn wenn time_stamp bisher binär 01111111 war und dann auf 1000000
hochzählt, dann können da für ein paar ps alle möglichen
Bitkombinationen (11001001, 01010101, 10011001, 10101100 oder sonstwas)
auftreten. Und der Vergleicher glitcht dann von sich aus auch noch und
zackdiebohne hast du da ungewollt Werte abgespeichert. Ja, es kann sogar
sein, dass je nach Dauer des Latchglitches wegen Laufzeiten und je nach
Energiegehalt dann nur einzelne Bits von note_on, note und velocity mit
"neuen" Werten gespeichert werden.
Also: wenn schon ein Latch, dann nur dort, wo du sicher sein kannst,
dass das Ansteuersignal niemals glitcht und ausreichend lange anliegt.
Das allein wäre schon schlimm genug, aber das hier ist natürlich der
Schenkelklopfer, der dir im echten Leben blitzartig das Genick bricht:
> time_step := time_step + 1;
Mein Glückwunsch!
Du hast die kombinatorsche Schleife entdeckt:
http://www.lothar-miller.de/s9y/archives/42-Kombinatorische-Schleifen.html
Weil dieses ungetaktete Hochzählen in einer if-Abfrage versteckt ist,
sieht der Synthesizer das nicht und meldet nur ein Latch.
BTW: nimms mir nicht krumm, aber du bist das Paradebeispiel, warum ich
meinen Praktikanten immmer einbläue, dass sie nicht programmieren,
sondern Hardware beschreiben und es deshalb nicht VH-P-L, sondern
VH-D-L heißt.
Siehe hier im Forum die jeweils ewig langen Diskussionen, ob VHDL nun
formell eine Programmiersprache sei oder auch nicht.
Das Fazit dabei: wahrscheinlich ist es eine Programmiersprache, weil
alle Kriterien für ein Programmiersprache erfüllt sind.
Allerdings ist "VHDL fürs FPGA" eben nicht "VHDL im Gesamten". Das sieht
eher so aus wie dort skizziert:
Beitrag "Re: vhdl synthetisiarbar machen"
Und dann muss man natürlich wissen, welchen Teil des "gesamten und
simulierbaren VHDL" man tatsächlich als "synthetisierbares VHDL"
verwenden kann und wie man das hinschreiben muss, dass der Synthesizer
kapiert, was man will. Wie das aussehen muss, steht übrigens im
Handbuch/User-Guide zum Synthesizer.
Nur mal zum Abgleich des Kenntnistandes: hast du die üblichen
Trainingseinhaiten mit Blinklicht und Lauflicht selber erfolgreich in
Simulation und Synthese erledigt? Hast du selbst eine simple serielle
Schnittstelle (Midi ist das ja auch) durchdacht und realisiert? Ist dir
das Prinzip der Taktung von FPGAs und das Steuern von Submodulen per
Clock-Enables usw. bekannt?
http://www.lothar-miller.de/s9y/archives/80-Hello-World!.htmlhttp://www.lothar-miller.de/s9y/archives/61-Lauflicht.htmlhttp://www.lothar-miller.de/s9y/categories/42-RS232
Mein Tipp: schreibe alles, was getaktet ist, in einen Prozess. Und alles
nebenläufig (concurrent), was Kombinatorik ist. Dann steht in jedem
Prozess nur der clk im der Sensitivliste, oder besser noch: du hast gar
keine Sensitivliste und verwendest stattdessen ein wait until
rising_edge(clk); im Prozess:
http://www.lothar-miller.de/s9y/archives/16-Takt-im-Prozess.html
Aber wie gesagt: es lohnt sich, das Manual zum Synthesizer anzusehen.
Dominic K. schrieb:> Wie würdet ihr das lösen?
Bei mir würde der Prozess etwa so beginnen:
1
player:process
2
variabletime_step:integer:=0;
3
begin
4
waituntilrising_egde(clk50MHz);
5
if(sw='1')then
6
:
7
:
Oder ein wenig traditioneller eben so:
1
player:process(clk50MHz)
2
variabletime_step:integer:=0;
3
begin
4
ifrising_egde(clk50MHz)then
5
if(sw='1')then
6
:
7
:
Damit hätte ich schon mal hundertprozentig sicher ein synchrones Design
ohne Latches.
Natürlich kommen dann andere Effekte wie z.B. Latency auf, aber die
musst du sowieso beachten und abschätzen, ob sie an der jeweiligen
Stelle weh tun.
Danke für die Inputs werde mir diese heute abend genauer anschauen. Ich
nehme dir das keines falls übel. Mir ist sehr wohl bewusst, dass ich von
programmiersprachen vorgeorägt bin und mein eigentliches Problem der
übergang zur Hardware description language ist. Daher ist die
Fragenstellung auch so offen, da mir bewusst ist das sehr viel noch am
basteln bin