Hallo
Ich bin nun endlich einmal dazu gekommen, ein wenig mit meinem FPGA
Board zu spielen. Nun möchte ich eine einfache Schaltung, die einen
Rotary switch einliest und die Leds durchschaltet.
Nur leider habe ich einen Fehler beim synthetisieren (Simulation hat
geklappt).
1
entity QuadratureDecoder is
2
Port ( A : in STD_LOGIC;
3
B : in STD_LOGIC;
4
Sector : out STD_LOGIC_VECTOR (7 downto 0));
5
end QuadratureDecoder;
6
7
architecture Behavioral of QuadratureDecoder is
8
9
signal count : std_logic_vector(2 downto 0) := "000";
10
11
begin
12
13
process(A, B)
14
begin
15
if rising_edge(A) then
16
if B = '0' then
17
count <= std_logic_vector(unsigned(count) + 1);
18
else
19
count <= std_logic_vector(unsigned(count) - 1);
20
end if;
21
elsif falling_edge(A) then
22
if B = '0' then
23
count <= std_logic_vector(unsigned(count) - 1);
24
else
25
count <= std_logic_vector(unsigned(count) + 1);
26
end if;
27
elsif rising_edge(B) then
28
if A = '0' then
29
count <= std_logic_vector(unsigned(count) - 1);
30
else
31
count <= std_logic_vector(unsigned(count) + 1);
32
end if;
33
elsif falling_edge(B) then
34
if A = '0' then
35
count <= std_logic_vector(unsigned(count) + 1);
36
else
37
count <= std_logic_vector(unsigned(count) - 1);
38
end if;
39
end if;
40
end process;
41
42
with count select
43
Sector <= "00000001" when "000",
44
"00000010" when "001",
45
"00000100" when "010",
46
"00001000" when "011",
47
"00010000" when "100",
48
"00100000" when "101",
49
"01000000" when "110",
50
"10000000" when "111",
51
"XXXXXXXX" when others;
52
53
end Behavioral;
1
line 44: Signal count cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.
Kann mir jemand weiterhelfen?
Nebenbei: Wie wird normalerweise ein flankengetriggertes Modul aufgebaut
(mehrere Eingänge und unterschiedliche Flankten), oder soll dies über
Pegel gelöst werden und einzig einen Clock verwenden?
Besten Dank,
Patrick
nein, liest erstmal was rising edge macht.
das brauchst du EINMAL, ein Prozess innen drin die typischen Abfragen
nach Pegeln und nicht nach Flanken - siehe die einschlägigen
Beispielprojekte
Ich weiss nicht. Wie soll ich es sagen, ohne das Lothar Miller mir die
Ohren abreisst - aber sagen will ich es doch:
Es ist richtig, dass die erhältlichen FPGAs keine Dual-Edge-Flip-Flops
als Einheiten enthalten. Aber so etwas lässt sich in VHDL durchaus
synthetisierbar beschreiben in dem man es mit zwei Flip-Flops - äh -
sozusagen emuliert.
Mit den Suchbegriffen "Dual Edge FF VHLD" erhält man z.B. folgende
interessante Links:
http://www.ralf-hildebrandt.de/publication/pdf_dff/pde_dff.pdf
und
http://asicdigitaldesign.wordpress.com/2007/07/31/the-double-edge-flip-flop/
(nebst weiteren)
Bitflüsterer schrieb:> Dual-Edge-Flip-Flops
Naja, Dual-Edge ist nun nicht Dual-Clock. Ein FF mit 2 Takteingängen
also.
Oder, wenn man sich den VHDL Code ganz oben ansieht, sogar
Dual-Edge-Dual-Clock-FFs...
Lothar Miller schrieb:> Bitflüsterer schrieb:>> Dual-Edge-Flip-Flops> Naja, Dual-Edge ist nun nicht Dual-Clock. Ein FF mit 2 /Takteingängen/> also.> Oder, wenn man sich den VHDL Code ganz oben ansieht, sogar> Dual-Edge-Dual-Clock-FFs...
Richtig. Meine armen Ohren ...
Bitflüsterer schrieb:> Habe noch 'ne Nase. :-)
Wenn unbedingt sein muss... ;-)
> das sind dann eben zwei Dual-Edge-FFs
Und wie verschaltest du die count FFs hier:
Lothar Miller schrieb:> Patrick B. schrieb:>> (ist wie gesagt mein erstes VHDL Programm)> Warum heißt VHDL VHDL und nicht VHPL?
Wie nennt man den das? Skript, File, Hardware...?
Nur so aus Neugierde: Wie werden bei einem MCU solche Peripherieteile
realisiert? Wenn man es auf Flankengetriggert einstellt, wird das nur
pseudomässig umgesetzt oder werden da wirkich die Flanken ausgewertet.
Letzeres würde dann ja zu einer Asynchronität führen.
Habe mein Teil gestern noch auf ein ähnliches System (alles nür über
einzelne Rising_edge und Falling_edge Funktionen) umgeschrieben, wie
diese (habe ich vom Lothars Seite):
1
process (A,B) begin
2
if rising_edge(A) then
3
if (B='1') then p<=p+1;
4
else p<=p-1; end if;
5
end if;
6
if falling_edge(A) then
7
if (B='0') then p<=p+1;
8
else p<=p-1; end if;
9
end if;
10
if rising_edge(B) then
11
if (A='0') then p<=p+1;
12
else p<=p-1; end if;
13
end if;
14
if falling_edge(B) then
15
if (A='1') then p<=p+1;
16
else p<=p-1; end if;
17
end if;
18
end process;
Gleicher Fehler wie mit if-elsif Konstrukt.
Sehe gerade überhaupt nicht, was so nicht laufen soll.
Besten Dank, Gruss
Patrick B. schrieb:> Lothar Miller schrieb:>> Patrick B. schrieb:>>> (ist wie gesagt mein erstes VHDL Programm)>> Warum heißt VHDL VHDL und nicht VHPL?> Wie nennt man den das? Skript, File, Hardware...?
Hardware DESCRIPTION Language
Hardware BESCHREIBUNG ssprache
Ich habe also kein VHDL Programm, sondern eine VHDL Beschreibung. Ich
habe auch nicht einen Prozessor mit VHDL programmiert (fällt dir was
auf: womit werden Prozressoren i.A. programmiert?), sondern ich habe mit
VHDL einen Prozessor beschrieben.
> Sehe gerade überhaupt nicht, was so nicht laufen soll.
Hast du mit aller Gewalt meinen Link und alle Posts ignoriert?
Es gibt nirgends auf der Welt solche Bautsteine, die du da beschreibst!
> Habe mein Teil gestern noch auf ein ähnliches System (alles nür über> einzelne Rising_edge und Falling_edge Funktionen) umgeschrieben, wie> diese (habe ich vom Lothars Seite):
Und was steht dort dann auch?
1
Leider taugt dieser Quadraturdecoder wegen der Flankenauswertungen
2
nur für die Simulation. Denn in einem programmierbaren Baustein gibt
3
es kein Flipflop, das zwei Takteingänge hat, die sowohl auf die
4
steigende wie auch die fallende Flanke reagieren könnten.
Taugt nur für die Simulation bedeutet, dass du das zwar simulieren
kannst, aber nicht auf irgendeine Hadware bekommst. Merke: bestenfalls
5% von VHDL können tatsächlich auf Hardware abgebildet werden. Aber 100%
können simuliert werden...
> Nur so aus Neugierde: Wie werden bei einem MCU solche Peripherieteile
realisiert?
So, wie es auf meiner HP ein paar Zeilen weiter unten gemacht ist: mit 1
einzigen Mastertakt. Der muss nur ausreichend schnell sein. Und auf
diesen Takt werden die Eingangssignale einsynchonisiert...
Es wird niemals auf ein Eingangssignal, das evtl. auch noch prellen
oder überschwingen kann, ein rising_edge() oder ein falling_edge()
abgefragt. Eine Flankenerkennung macht man wieder mit dem "Mastertakt":
erst einsynchonisieren und dann eine Flankenauswertung:
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisierenhttp://www.lothar-miller.de/s9y/categories/18-Flankenerkennung
Sieh dir diese beiden Links genau an. Damit kannst du 90% aller
Anfängerfehler umgehen...
Lothar Miller schrieb:> Bitflüsterer schrieb:>> Habe noch 'ne Nase. :-)> Wenn unbedingt sein muss... ;-)>>> das sind dann eben zwei Dual-Edge-FFs> Und wie verschaltest du die count FFs hier:>
1
>ifrising_edge(A)then
2
>count<=...
3
>elsiffalling_edge(A)then
4
>count<=...
5
>elsifrising_edge(B)then
6
>count<=...
7
>elsiffalling_edge(B)then
8
>count<=...
9
>
Ich habe leider kein ISE hier und kann das nicht ausprobieren. Aber
meine Idee dazu wäre, jeweils einen Abwärts- und einen Aufwärtszähler zu
benutzen, deren Differenz am Ende gebildet wird. Auch würde am Ende
keine Sequenz von ifs in der gezeigten Form dastehen. Eher zwei
Prozesse.
Lothar, ich weiß, solche theoretischen Einwände sind schwer
ernstzunehmen. Wenn Du sagen willst, das es überhaupt nicht geht, auch
nicht emuliert und mit Gebeten zum Spaghettimonster, nehme ich das mal
unter Vorbehalt so an.
Bitflüsterer schrieb:> Aber meine Idee dazu wäre, jeweils einen Abwärts- und einen> Aufwärtszähler zu benutzen, deren Differenz am Ende gebildet wird.
Das ergäbe einen recht glitchigen "Zählerstand", der zu nichts und
niemandem synchron ist. Mir wäre nicht wohl dabei...
> Lothar, ich weiß, solche theoretischen Einwände sind schwer> ernstzunehmen. Wenn Du sagen willst, das es überhaupt nicht geht, auch> nicht emuliert und mit Gebeten zum Spaghettimonster, nehme ich das mal> unter Vorbehalt so an.
Du wirst sicher auch in einem FPGA etwas hinbekommen, das irgendwie so
oder so ähnlich etwas macht. Aber "funktioneren" würde ich das nicht
nennen. Und die Not ist doch nicht groß, weil es ja Verfahren gibt, die
100% zuverlässig arbeiten.
Bitflüsterer schrieb:> Lothar Miller schrieb:>> Bitflüsterer schrieb:>>> Habe noch 'ne Nase. :-)>> Wenn unbedingt sein muss... ;-)>>>>> das sind dann eben zwei Dual-Edge-FFs>> Und wie verschaltest du die count FFs hier:>>> if rising_edge(A) then>> count <= ...>> elsif falling_edge(A) then>> count <= ...>> elsif rising_edge(B) then>> count <= ...>> elsif falling_edge(B) then>> count <= ...>>> Ich habe leider kein ISE hier und kann das nicht ausprobieren. Aber> meine Idee dazu wäre, jeweils einen Abwärts- und einen Aufwärtszähler zu> benutzen, deren Differenz am Ende gebildet wird. Auch würde am Ende> keine Sequenz von ifs in der gezeigten Form dastehen. Eher zwei> Prozesse.>> Lothar, ich weiß, solche theoretischen Einwände sind schwer> ernstzunehmen. Wenn Du sagen willst, das es überhaupt nicht geht, auch> nicht emuliert und mit Gebeten zum Spaghettimonster, nehme ich das mal> unter Vorbehalt so an.
aehm, wenn ich mal einfach so davon ausgehe, dass der Drehgeber mit
seinen Flanken weit langsamer als der FPGA-Takt ist: Was ist denn so
schwer daran, eine gescheite Flankenerkennung mit dem FPGA-Takt zu bauen
und dieses +1 oder -1 dann entsprechend auszuwerten?
Damit waerst du innerhalb des FPGA voll synchron.
Bei deinem Vorschlag wuerdest du mit einem externen Pseudotakt Register
setzen/veraendern. Diese Register musst du aber erstmal aufwendig in
deine FPGA-Taktdomaene einsynchronisieren. Merkst was? Aus einem
Pseudotakt machst du auf einmal eine Synchronisierung von z.B. 16
Registerbits (count).
Welche der beiden Moeglichkeiten ist denn da einfacher? Vermutlich doch
die, die nur mit einer Leitung am Eingang zu tun hat, oder? Oder willst
du ernsthaft behaupten, du musst das Flankensignal auf die Nanosekunde
genau abtasten?
variable Up, Down : std_logic := '0'; -- Lokale Variable
32
begin
33
if rising_edge(Clk) then
34
Up := '0';
35
Down := '0';
36
37
-- Zustäde
38
case state is
39
when Z00 => if DecoderInputStable = "01" then
40
state <= Z01;
41
Up := '1';
42
elsif DecoderInputStable = "10" then
43
state <= Z10;
44
Down := '1';
45
end if;
46
when Z01 => if DecoderInputStable = "11" then
47
state <= Z11;
48
Up := '1';
49
elsif DecoderInputStable = "00" then
50
state <= Z00;
51
Down := '1';
52
end if;
53
when Z11 => if DecoderInputStable = "10" then
54
state <= Z10;
55
Up := '1';
56
elsif DecoderInputStable = "01" then
57
state <= Z01;
58
Down := '1';
59
end if;
60
when Z10 => if DecoderInputStable = "00" then
61
state <= Z00;
62
Up := '1';
63
elsif DecoderInputStable = "11" then
64
state <= Z11;
65
Down := '1';
66
end if;
67
end case;
68
69
-- Zählen
70
if Up = '1' then
71
count <= std_logic_vector(unsigned(count) + 1);
72
end if;
73
if Down = '1' then
74
count <= std_logic_vector(unsigned(count) - 1);
75
end if;
76
end if;
77
end process;
78
79
-- Variable ausgeben
80
with count select
81
Sector <= "00000001" when "000",
82
"00000010" when "001",
83
"00000100" when "010",
84
"00001000" when "011",
85
"00010000" when "100",
86
"00100000" when "101",
87
"01000000" when "110",
88
"10000000" when "111",
89
"XXXXXXXX" when others;
Beim simulieren habe ich aber keine Signale mehr. Sobald ich den Prozess
mit dem clk und den Teil mit dem Einsynchronisieren auskommentiere, dann
sehe ich zumindest wieder Pegel.
Mhm, das ganze ist irgendwie eine eigene Welt. Habe mitlerweile viel
Erfahrung mit MCUs (8Bit, DSP, 16Bit, 32Bit, ARM), aber hier habe ich
das Gefühl, als hätte ich nicht den Hauch einer Ahnung.
@Lothar
Sorry, hab wohl nicht alles gelesen. Aber ist eine interessante Seite,
die ich gerne mal durchlese.
MFG
Patrick B. schrieb:> Mhm, das ganze ist irgendwie eine eigene Welt. Habe mitlerweile viel> Erfahrung mit MCUs (8Bit, DSP, 16Bit, 32Bit, ARM), aber hier habe ich> das Gefühl, als hätte ich nicht den Hauch einer Ahnung.
Ja MCU in C-Programmieren ist keine Grundlage für FPGA-Entwicklung.
Was du brauchst ist ein Grundverständniss in digitaler
Schaltungstechnik.
MfG,
Patrick B. schrieb:> eim simulieren habe ich aber keine Signale mehr.
Häng doch mal den Code und die Testbench hier ran. Dann kann man es
selber simulieren und nachvollziehen.
Duke
Patrick B. schrieb:> -- Einsynchronisieren der asynchronen Eingangssignale> process begin> DecoderInputUnstable <= (B, A);> DecoderInputStable <= DecoderInputUnstable;> end process;
Da wird nichts einsynchronisiert, weil kein Takt (=Flipflop) beteiligt
ist. Eigentlich muss der Simulator hier rummeckern, weil nichts in der
Sensitivliste steht und auch kein wait im Prozess vorkommt.