Hallo VHDL-Profis, im besonderen bei kombinatorischen Prozessen kann ich den Sinn der Sensitivity List nicht nachvollziehen. Man kann zwar gebetsmühlenartig nachlesen, dass der Prozess nur auf Änderung der spezifizierten Signale reagiert. Das kann ich bei einer reinen Kombinatorik aber nicht nachvollziehen. Schließlich werden hier alle benutzten Signale quasi kontinuierlich und gleichzeitig verarbeitet. Dient die Sensitivity List etwa nur dazu, dem Simulator entscheidende Hinweise zu liefern? Immerhin läßt sich das Simulationsergebnis mit der Sensitivity List beeinflussen, auch im positiven Sinne. Aber in einer parallel arbeitenden realen Hardware? Gibt es erhellende Beispiele?
Du verwechselst Ursache und Wirkung ;-) Die Kombinatorik ist nur ein Sonderfall aller möglichen Beschreibungen in einem Prozess. Du weisst, dass es so sein soll, in der Sprache gibt man es dann durch alle Eingangssignale in der Sensitivitylist an. Warum sollte man für sowas Spezialregeln einführen, es gibt auch Fälle (gerade bei Testbenches) wo man eben nicht auf alles reagieren will und eine implizite Speicherung wünscht. Sicher ist die Sensitivitylist eine Hilfe für den Simulator, unbedingt nötig ist sie aber nicht, man weiss ja statisch, was im Prozess abgefragt wird... Sie ist in erster Linie einfach ein Sprachelement, um auf bestimmte Events zu triggern und nicht auf alles.
Weiterhin wurde VHDL ursprünglich zur Simulation geschrieben. Nicht aber um Hardware zu synthetisieren. Die allermeisten Synthesetools, zumindest die die ich kenne, ignorieren die Sensitivity-Liste. Bestenfalls geben sie noch eine Warnung aus. Sie interpretieren sozusagen den VHDL-Code nicht richtig. In der Simulation sieht das freilich ganz anders aus. Es kann also sein, dass wenn man nicht sorgfältig mit den Einträgen in der Sensitivity-Liste umgeht, die Simulation andere Ergebnisse liefert als die Synthese in Hardware umsetzt. Im Zuge komplexer FPGA-Designs passiert es mir immer mal wieder, dass bei Änderungen oder Erweiterungen die Sensitivity-Liste nicht korrekt nachgezogen wurden. Bisher ist das aber in der Simulation aufgeflogen, da diese nicht die gewünschten Ergebnisse brachten. Die Fehlersuche an dieser Stelle ist aber oft mühsig. Zum Glück ist der Fehler bisher nicht erst im Design aufgetreten, denn dann wird die Fehlersuche schnell zur Katastrophe. Hat jemand schon mal ein kleines Tool gefunden, mit dem man VHDL-Code auf solche Dinge untersuchen kann? Es wäre doch praktisch diese Dinge über eine Batchdatei automatisch von Zeit zu Zeit (oder vor der Simulation) untersuchen zu lassen.
>Hat jemand schon mal ein kleines Tool gefunden, mit dem man VHDL-Code >auf solche Dinge untersuchen kann? Je nach Simulator-Variante gibt es ein Compile-Häkchen für die Option "Synthesis Check". Dadurch werden unvollständige Sensitivitätslisten aufgedeckt. Gruß, SuperWilly
@Matthias G.: > Hat jemand schon mal ein kleines Tool gefunden, mit dem man VHDL-Code > auf solche Dinge untersuchen kann? Naja, klein nicht, sicher auch nicht billig und der Check der Sensitivity List ist auch nicht der Hauptzeck der Software: http://www.onespin-solutions.com/ Duke
der emacs-Editor kamm die Sensitivity-List zumindest automatisch updaten
Ok, ich scheine demnach zumindest nicht völlig auf dem Holzweg zu sein :-) Die Sensitivity List ist demnach hauptsächlich ein Funktionsverhinderer, statt (in seltenen Fällen und nur in der Simulation?)Funktionserweiterung ;-). Wie funktioniet ein automatischer Update der Sensitivity List? Werden einfach alle Signale, die geprüft oder zugewiesen werden, eingetragen?
Gummibärchen schrieb: > Hallo VHDL-Profis, > > im besonderen bei kombinatorischen Prozessen kann ich den Sinn der > Sensitivity List nicht nachvollziehen. Man kann zwar gebetsmühlenartig > nachlesen, dass der Prozess nur auf Änderung der spezifizierten Signale > reagiert. Das kann ich bei einer reinen Kombinatorik aber nicht > nachvollziehen. Schließlich werden hier alle benutzten Signale quasi > kontinuierlich und gleichzeitig verarbeitet. Ja, aber die Signale werden hier als zeitdiskrete Binäre Signale modelliert > > Dient die Sensitivity List etwa nur dazu, dem Simulator entscheidende > Hinweise zu liefern? Immerhin läßt sich das Simulationsergebnis mit der > Sensitivity List beeinflussen, auch im positiven Sinne. Aber in einer > parallel arbeitenden realen Hardware? Gibt es erhellende Beispiele? Ja, die Simulator arbeitet "event driven", also ereignis gesteuert. Zitat aus "Handbuch der Electronic Design Automatisation": ... ältere simulatoren berechnetetn die signalwerte einer digitalschaltung f. jeden schaltungsknoten in Abhängigkeit. von der zeit. Dies führte zu sehr hohen Simulationszeiten. Die heute verwendeten ereignisgesteuerten Simulatoren simulieren nur dan den neuen Signalwert, wenn eine Signaländerung am Bauelementeeingang erfolgt ist. .... Alle Ereignisse werden für jeden werden ... in einer Ereignisliste ... protokolliert. ..." In der sens. list stehen nun genau die Signale, deren Änderungen events sind. Gruß
Schrotty schrieb:
> der emacs-Editor kamm die Sensitivity-List zumindest automatisch updaten
Den wunderknaben habe ich mal soeben installiert und habe das mal
ausprobiert. Funktioniert "fast" fehlerfrei. Mal abgesehen davon, dass
er Kommentare weg schmeißt und die Sensitivity-List neu sortiert.
Aber bedienbar ist der Editor erst mal nicht. Da ist erst mal alles
anders (zumindest voreingestellt). Überzeugt hat mich der nicht. Da ist
mir mein Ultraedit viel angenehmer. Aber danke für den Tip.
Matthias G. schrieb: > Aber bedienbar ist der Editor erst mal nicht. Es sei denn, man kennt ihn. ;-) > Da ist erst mal alles > anders (zumindest voreingestellt). Genauso geht das einem Emacs-Nutzer, wenn er plötzlich seine Texte in so einem Primitiv-Ding wie dem Editor dieser Webbrause hier editieren muss... Tja, alles eine Frage des Standpunkts und der Gewöhnung. ;-) (Den VHDL-Modus vom Emacs habe ich mir allerdings noch nicht angesehen, werde ich mal tun.)
> Den VHDL-Modus vom Emacs habe ich mir allerdings noch nicht angesehen, > werde ich mal tun. Solltest du. Mit dem Stutter-Mode schreibt es sich wirklich sehr schnell. Auch der Speedbar zum Navigieren in den diversen Entities ist recht praktisch.
Hier ist ein reduziertes Beispiel, welches mein aktuelles Problem darstellt. Eigentlich sollte "vom Fleck weg" in 'result' und 'inst_literal' der Wert 0x01 stehen. Tut es aber nicht. Momentan befasse ich mich nur mit der Simulation, denn, wenn die schon nicht tut, was sie soll. Im Singlestep wird beim Loslaufen der Prozess durchlaufen, aber die Zuweisungen tun nix!? Und hier der Code. Was das insgesamt sein soll, kann man erkennen ;-)
1 | library ieee; |
2 | use ieee.std_logic_1164.all; |
3 | use ieee.numeric_std.all; |
4 | |
5 | entity pic_testbench is |
6 | end entity pic_testbench; |
7 | |
8 | architecture bhv of pic_testbench is |
9 | |
10 | component pic is |
11 | port( clk : in std_logic; |
12 | sigout : out std_logic); |
13 | end component; |
14 | |
15 | signal clk : std_logic := '1'; |
16 | signal sigout : std_logic; |
17 | |
18 | begin
|
19 | dut : pic |
20 | port map ( |
21 | clk => clk, |
22 | sigout => sigout); |
23 | |
24 | clk <= not clk after 10.0 ns; |
25 | end architecture; |
1 | library ieee; |
2 | use ieee.std_logic_1164.all; |
3 | use ieee.numeric_std.all; |
4 | |
5 | entity pic is |
6 | port( clk : in std_logic; |
7 | sigout : out std_logic); |
8 | end pic; |
9 | |
10 | architecture behavioral of pic is |
11 | |
12 | constant rom_depth : integer := 2; |
13 | constant rom_size : integer := 2**rom_depth; |
14 | |
15 | subtype t_byte is unsigned (7 downto 0); |
16 | subtype t_inst is unsigned (13 downto 0); |
17 | subtype t_rom_address is unsigned (rom_depth-1 downto 0); |
18 | type t_rom is array (0 to rom_size-1) of t_inst; |
19 | |
20 | signal rom : t_rom := ( |
21 | "11000000000001", |
22 | "00000100000000", |
23 | others => "00000000000000"); |
24 | |
25 | signal pc : t_rom_address := to_unsigned(0,rom_depth); |
26 | signal inst : t_inst := "00000000000000"; |
27 | signal inst_literal : t_byte := "00000000"; |
28 | signal result : t_byte := "00000000"; |
29 | |
30 | begin
|
31 | process (rom,pc) |
32 | begin
|
33 | inst <= rom(to_integer(pc)); |
34 | inst_literal <= inst(7 downto 0); |
35 | result <= inst_literal; |
36 | end process; |
37 | |
38 | end behavioral; |
Signalzuweisungen werden nicht nicht sofort ausgeführt, sondern erst beim Verlassen des Prozesses. Schreib inst_literal <= inst(7 downto 0); result <= inst_literal; ausserhalb des prozesses und es funzt. Schau dir mal als beispiel für instruction fetch einen anderen prozessor in VHDL an (opencores).
Hm ja, stimmt, da hat es funktioniert, aber ich dachte, es ist strukturierter, wenn ich alles in einen Prozess packe. Das faszinierende ist, dass die Zuweisung in der Simulaion nie stattfindet, siehe Screenshot. 'result' bleibt auf 0x00. Aber folgende Beobachtungen: Wenn ich alle Signale in die Sensitivity List schreibe, funktioniert alles wie erwartet. Im Singlestep wird der Prozess am Anfang dreimal durchlaufen, bis alle Signale ihre endgültigen Werte erreicht haben. Das hängt aber sicherlich mit den Interna des Simulators zusammen.
Jörg Wunsch schrieb: > Genauso geht das einem Emacs-Nutzer, wenn er plötzlich seine Texte in > so einem Primitiv-Ding wie dem Editor dieser Webbrause hier editieren > muss... Müssen muss man gar nichts -- vorausgesetzt man nimmt "Den Richtigen Browser". https://addons.mozilla.org/en-US/firefox/addon/4125 Für größere Kommentare wird dann einfach "Der Richtige Editor" verwendet. Gruß Marcus
Gummibärchen schrieb: > Hm ja, stimmt, da hat es funktioniert, aber ich dachte, es ist > strukturierter, wenn ich alles in einen Prozess packe. Das faszinierende > ist, dass die Zuweisung in der Simulaion nie stattfindet, siehe > Screenshot. 'result' bleibt auf 0x00. Aber folgende Beobachtungen: Die Zuweisung findet statt, da aber der selbe Wert eingeschrieben wird, sieht man dies nicht. Lasse doch den Erstwert weg, oder verwendet einen anderen als 0, dann siehst du die Zuweisung: signal inst_literal : t_byte ; signal result : t_byte ; (wobei ich mir nicht sicher bin, ob das mit deinem Typ funktioniert, besser is da std_logig, da gibt es den Zustand U wie Unassigned (nicht zugewiesen). Aber du kannst es auch mit unterschiedlichen Startwerten "sichtbar" machen: signal inst_literal : t_byte := "10000000"; signal result : t_byte "00001000"; Gruß > > Wenn ich alle Signale in die Sensitivity List schreibe, funktioniert > alles wie erwartet. > > Im Singlestep wird der Prozess am Anfang dreimal durchlaufen, bis alle > Signale ihre endgültigen Werte erreicht haben. Das hängt aber sicherlich > mit den Interna des Simulators zusammen.
Dieser Prozess wird bei Änderung von rom oder pc neu berechnet.
1 | process (rom,pc) |
2 | begin
|
3 | inst <= rom(to_integer(pc)); |
4 | inst_literal <= inst(7 downto 0); |
5 | result <= inst_literal; |
6 | end process; |
Während des kompletten ersten Durchlaufs haben inst und result immer noch den alten Wert. Erst nach dem Durchlauf werden die dabei berechneten Werte an die Signale zugewiesen. Du könntest das also auch so schreiben:
1 | process (rom,pc) |
2 | begin
|
3 | result <= inst_literal; |
4 | inst_literal <= inst(7 downto 0); |
5 | inst <= rom(to_integer(pc)); |
6 | end process; |
Dann würde dir das Verhalten klarer ;-) Jetzt hat sich also nach dem ersten durchlauf nur inst geändert, weil sich pc oder rom geändert haben. Somit müsste jetzt der Prozess für inst_literal nochmal durchgerechnet werden. Und danach für result nochmal. Das wird er aber nicht, weil diese beiden Signale in der Sensitivliste fehlen. Klarer Fall von unvollständiger Sensitivliste. Und schon wieder verhält sich die simulation anders als die Realität... Bei einem kombinatorischen Prozess gehört jedes Signal, das eine Änderung eines der Endwerte haben (und damit die Neuberechnung nötig machen) kann, in die Sensitivliste. >> Wenn ich alle Signale in die Sensitivity List schreibe, funktioniert >> alles wie erwartet. Das dürfte jetzt klar sein ;-) Warum schreibst du so simple kombinatorische Zuweisungen nicht einfach concurrent? Dann bist du die ganze Sensitivlistenverwalterei los...
1 | :
|
2 | :
|
3 | signal inst_literal : t_byte := "00000000"; |
4 | signal result : t_byte := "00000000"; |
5 | |
6 | begin
|
7 | inst <= rom(to_integer(pc)); |
8 | inst_literal <= inst(7 downto 0); |
9 | result <= inst_literal; |
10 | end behavioral; |
>> Sicher ist die Sensitivitylist eine Hilfe für den Simulator, unbedingt >> nötig ist sie aber nicht, man weiss ja statisch, was im Prozess >> abgefragt wird... Gerade für den Simulator ist die Sensitivliste das alleinige Merkmal, nach der ein Prozess neu berechnet wird. Die Liste und vor allem deren Vollständigkeit ist zwingend nötig für ein korrektes Simulationsergebnis. Sieh dir nur mal das (klitzekleine) Beispiel bei mir an: http://www.lothar-miller.de/s9y/archives/16-Takt-im-Prozess.html Es geht mir dabei nicht um einen Takt, sondern um die Tatsache, dass die (mittlere) Beschreibung nur dann richtig (kombinatorisch) simuliert wird, wenn auch inp mit in die Liste aufgenommen wird. Wenn nicht, ist das Simulationsergebnis schlichtweg falsch und passt nicht zur real implementierten Schaltung... Denn dem Synthesizer ist die Sensitivliste schnuppe. Der gibt eine passende Info zu einem fehlenden Signal aus, und weiter gehts.
Ich glaube ich hab's verstanden. Lothar's Satz war der entscheidende: "Erst nach dem Durchlauf werden die dabei berechneten Werte an die Signale zugewiesen" Deswegen durchläuft der Einzelschritt des Simulators den Prozess auch drei mal. >Warum schreibst du so simple kombinatorische Zuweisungen nicht einfach >concurrent? Dann bist du die ganze Sensitivlistenverwalterei los... Ich dachte, wenn ich alles in dem Prozess mache, der es benötigt, ist es strukturierter. Aber für einen Newbie wie mich ist Strukturiertheit wohl noch relativ :-) Auf jeden Fall funktioniert jetzt alles wie es soll. Vielen Dank an alle!
> Die Simulation ist immer richtig. > Falsch ist die Hardware. Verallgemeinerungen sind immer schlecht ;-)
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.