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!.html
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html
http://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 | variable time_step : integer := 0;
|
3 | begin
|
4 | wait until rising_egde(clk50MHz);
|
5 | if(sw = '1') then
|
6 | :
|
7 | :
|
Oder ein wenig traditioneller eben so:
1 | player : process (clk50MHz)
|
2 | variable time_step : integer := 0;
|
3 | begin
|
4 | if rising_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.