Hallo,
ich habe ein Riesenproblem! Ich simuliere meine VHDL-Dateien mit
ModelSim und es wird ein Signal nicht gesetzt, obwohl es eigentlich der
Fall sein sollte. Hier zunächst meine VHDL-Beschreibung:
1
libraryIEEE;
2
3
useIEEE.std_logic_misc.all;
4
5
useIEEE.std_logic_1164.all;
6
7
8
9
entityctrlis
10
11
port(
12
13
PC_ENABLE:outstd_logic;
14
15
PC_MODE:outstd_logic;
16
17
RST:instd_logic;
18
19
CLK:instd_logic;
20
21
mem_req:outstd_logic;
22
23
irq_adr_switch:outstd_logic_vector(1downto0);
24
25
PC_bakup:outstd_logic
26
27
);
28
29
endctrl;
30
31
32
33
architectureverhaltenofctrlis
34
35
typestate_typeis(start,fetch0,fetch1,decode);
36
37
signalstate:state_type;
38
39
signalinterrupted:std_logic;
40
41
begin
42
43
44
process(RST,CLK)
45
46
begin
47
48
if(RST='1')then
49
50
interrupted<='0';
51
52
state<=start;
53
54
endif;
55
56
endprocess;
57
58
59
60
process(state)
61
62
begin
63
64
casestateis
65
66
whenstart=>
67
68
mem_req<='0';
69
70
whenfetch0=>
71
72
irq_adr_switch<="00";
73
74
PC_MODE<='1';
75
76
PC_ENABLE<='1';
77
78
whenfetch1=>
79
80
PC_bakup<='1';
81
82
interrupted<='1';
83
84
whendecode=>
85
interrupted<='0';
86
87
whenothers=>null;
88
89
endcase;
90
91
endprocess;
92
93
endverhalten;
Das Problem ist nun folgendes: Von außen wird ein Reset angestoßen, so
dass RST=1 ist, dann sollte aber interrupted auf 0 gestzt werden.
(oberer Prozess will das so) Es bleibt aber undefiniert! Das lustige:
Die darauffolgende Zeile state <= start; wird richtig ausgeführt, hatte
testweise mal state <= decode drin und funktioniert.
Es wird aber nocht lustiger: Lasse ich die Zeile mit interrupted in
decode, fetch1 weg (unterer Prozess) wird interrupted dann doch wieder
richtig gesetzt bei einem Reset.
WTF?! Bitte dringend um Hilfe!
Wo hast du gesehen, dass man aus 2 Prozessen auf 1 Signal treiben kann?
Nirgends?
Warum tust du es dann trotzdem?
Bei der Synthese würde dir ein "Multiple Source Signal" gemeldet werden.
Die Simulation versucht, den Konflikt entsprechend der
Auflösungsfunktion eines std_logic zu lösen, kommt dabei aber leider nur
auf 'U', nicht auf 'X', was richtiger wäre...
Ein 'X' (= Konflikt) würdest du bekommen, wenn das Signal initialisiert
würde:
Naja,
ich dachte eigentlich das funktioniert soweit. Wo genau ist denn das
Problem, ich kann in verschiedenen Prozessen nicht ein und dasselbe
Signal setzen? Unabhängig davon ob dieses Signal gleichzeitig von beiden
Prozessen gesetzt wird bzw,. nacheinander gesetzt wird?
Danke schon mal für die Erleuchtung! ;]
Unnormaley schrieb:> Wo genau ist denn das> Problem, ich kann in verschiedenen Prozessen nicht ein und dasselbe> Signal setzen? Unabhängig davon ob dieses Signal gleichzeitig von beiden> Prozessen gesetzt wird bzw,. nacheinander gesetzt wird?
Ist dir klar, dass du mit VHDLHardware beschreibst?
Was ist ein Signal? Erst mal nur eine Leitung (**). Und was passiert bei
der Hardware, wenn du 2 Treiber auf 1 Leitung schaltest?
Richtig: ein Kurzschluss.
Und dieser Kurzschluss geht nur dann unbeschadet ab, wenn beide Signale
den selben Pegel haben, oder einer der Pegel so schwach ist, dass er
unbeschadet "niedergeknüppelt" werden kann.
(**) Ein Signal kann auch ein Speicherelement sein, das vereinfacht die
Sache aber keinesfalls, denn der zu speichernde wert muss dann ja auch
aus den anliegenden Eingangswerten "ausgeknobelt" werden.
> Danke schon mal für die Erleuchtung! ;]
Mein Tipp: lies das Buch VHDL-Synthese von Reichardt&Schwarz, und dir
wird ein ganzer Kronleuchter aufgehen...
Unnormaley schrieb:> Wo genau ist denn das>> Problem, ich kann in verschiedenen Prozessen nicht ein und dasselbe>> Signal setzen?
Die Zeit! Je nachdem wann das ModelGesimmse was tut, wird der Prozess a
oder b gewinnen, wenn es ein echter Konflikt ist. Das Ganze hängt dann,
wie ich schon gesehen habe, auch noch von der Nutzung der Optimierungen
beim Compilieren von ModelSim ab.
Also:
Entweder, du kannst es funktionell managen, dass die prozesse so laufen,
dass rein timingtechnisch die signale korrekt gesetzt werden
oder
du löst die Problematik durch korrektes synthesefähiges oder
synthesenahes VHDL auf sodass immer und zu jder Zeit immer nur eine
einzige klare Definition für jedes Signal vorliegt.
Zum X-ten male meine These:
VHDL Programme NICHT wie C Programme ereignisgetrieben von vorne
ansetzen (also es passiert was, was passiert wohl dann?)
sondern "von hinten", also ALLE Ausgänge abklappern und für alle
Betriebsfälle die komplette Funktion hinterlegen.
Weltbester FPGA Pongo schrieb im Beitrag #2724624:
> Das Ganze hängt dann, wie ich schon gesehen habe, auch noch von der> Nutzung der Optimierungen beim Compilieren von ModelSim ab.
Hört sich nach einer "Urban Legend" an. Kannst du da mal einen kleinen
Dreizeiler schreiben, der so ein Problem aufzeigt?
In dem gezeigten Beispiel ist nichts, was nicht allein mit dem Lesen der
VHDL-Dokumentation zu erklären ist. Und das trotz Konflikt (= 'X') ein
'U' übrigbleit, das ist (eigentlich) ein Fehler in der Spezifikation.
Das wurde vor kurzem im
Beitrag "Re: Seriell-Parallel-Wandlung mit VHDL" angesprochen...