Forum: FPGA, VHDL & Co. CPLD Counter


von Thomas Werthwein (Gast)


Lesenswert?

Hallo,

ich bin gerade dabei mich in VHDL einzuarbeiten, da ich einen CPLD 
(Xilinx XC2C64A) programmieren möchte. Meine erste Aufgabe ist es einen 
Zähler zu implementieren, der sowohl positive als auch negative 
Zählerstände haben kann.
Bei meiner aktuellen Version liefert die Simulation mit ISim genau das 
erwartete Ergebnis. Wenn ich das Programm in den CPLD flashe Zählt der 
Zähler leider nur bis zur 0 runter und verwirft dann alle weiteren 
negativen Zählschritte, positive Zählschritte werden aber weiterhin 
akzeptiert.
Die Aufgabe des Zählers ist es ein Signal welches nur in Differenzwerten 
von +-1 vorliegt zu rekonstruieren.
Ich habe leider gerade überhaupt keinen Ansatz um das Problem zu lösen.


zuletzt habe ich folgenden Code verwendet:
1
library ieee;
2
    use ieee.std_logic_1164.all;
3
   use IEEE.numeric_std.all;
4
   use IEEE.std_logic_signed.all;
5
6
entity up_down_counter is
7
  port (
8
    cout    :out std_logic_vector (7 downto 0);-- Output of the counter
9
    up_down :in  std_logic;                    -- up_down control for counter
10
    clk     :in  std_logic;                    -- Input clock
11
    reset   :in  std_logic                     -- Input reset
12
  );
13
end entity;
14
15
architecture rtl of up_down_counter is
16
    signal count :signed (7 downto 0);
17
begin
18
    process (clk, reset) begin
19
        if (reset = '1') then
20
            count <= to_signed(0,8);
21
        elsif (falling_edge(clk)) then
22
            if (up_down = '1') then
23
                count <= count + to_signed(1,8);
24
            else
25
                count <= count + to_signed(-1,8);
26
            end if;
27
        end if;
28
    end process;
29
   cout(0) <= count(0);
30
   cout(1) <= count(1);
31
   cout(2) <= count(2);
32
   cout(3) <= count(3);
33
   cout(4) <= count(4);
34
   cout(5) <= count(5);
35
   cout(6) <= count(6);
36
   cout(7) <= count(7);
37
 end architecture;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas Werthwein schrieb:
 use IEEE.numeric_std.all;
 use IEEE.std_logic_signed.all;
Entweder, oder. Aber nie zusammen!
Siehe Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete" incl. der darin 
enthaltenen Links...

> Zählt der Zähler leider nur bis zur 0 runter und verwirft dann alle
> weiteren negativen Zählschritte,
Das ist kurios...
> positive Zählschritte werden aber weiterhin akzeptiert.
Auch über den positiven Überlauf (01111111) hinaus?

BTW1:
Ich würde zum Zählen einen Integer mit range -128 to 127 nehmen, dann 
wäre die Rechnung klarer und bräuchte nicht so viele Casts und 
Konvertierungen...

BTW2:
   cout(0) <= count(0);
   cout(1) <= count(1);
   cout(2) <= count(2);
   cout(3) <= count(3);
   cout(4) <= count(4);
   cout(5) <= count(5);
   cout(6) <= count(6);
   cout(7) <= count(7);
Das ginge kürzer so:
   cout <= count;

von Dieter (Gast)


Lesenswert?

Thomas Werthwein schrieb:
> Wenn ich das Programm in den CPLD flashe Zählt der
> Zähler leider nur bis zur 0 runter und verwirft dann alle weiteren
> negativen Zählschritte, positive Zählschritte werden aber weiterhin
> akzeptiert.

Du kommst aus der Software Ecke?
Denk nochmal nach, wie realisiere ich negative Werte in Hardware?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Es ist dem 8-Bit-Zähler schnurzegal, ob er signed oder unsigend ist. Er 
zählt vorwärts so
1
:
2
:
3
1111 1011
4
1111 1100
5
1111 1101
6
1111 1110
7
1111 1111
8
0000 0000
9
0000 0001
10
0000 0010
11
0000 0011
12
0000 0100
13
:
14
:
Und rückwärts zählt er so:
1
:
2
:
3
0000 0100
4
0000 0011
5
0000 0010
6
0000 0001
7
0000 0000
8
1111 1111
9
1111 1110
10
1111 1101
11
1111 1100
12
1111 1011
13
:
14
:

Und ob er vorwärts dann 252, 253, 254, 255, 0, 1, 2, 3, 4
oder                     -4,  -3,  -2,  -1, 0, 1, 2, 3, 4
zählt, das ist nur eine Frage der Visualisierung für den Betrachter...

von Bronco (Gast)


Lesenswert?

Noch ein Tip:
Wenn Du planst, irgendwann mal auf FPGAs umzusteigen, solltest Du Dir 
anstatt einem asynchronen Reset
1
    process (clk, reset) begin
2
        if (reset = '1') then
3
            count <= to_signed(0,8);
4
        elsif (falling_edge(clk)) then
5
            if (up_down = '1') then
6
                count <= count + to_signed(1,8);
7
            else
8
                count <= count + to_signed(-1,8);
9
            end if;
10
        end if;
11
    end process;
lieber gleich den synchronen Reset angewöhnen
1
    process (clk) begin
2
        if (rising_edge(clk)) then
3
            if (reset = '1') then
4
                count <= to_signed(0,8);
5
            else
6
               if (up_down = '1') then
7
                   count <= count + to_signed(1,8);
8
               else
9
                   count <= count + to_signed(-1,8);
10
               end if;
11
           end if;
12
        end if;
13
    end process;

Siehe auch hier:
http://www.mikrocontroller.net/articles/Reset_f%C3%BCr_FPGA/CPLD

von Schlumpf (Gast)


Lesenswert?

Sehr eigenartig....
Kannst du sicherstellen, dass das signal up_down zum Zeitpunkt der 
Taktflanke stabil ist?

von Dr. Schnaggels (Gast)


Lesenswert?

>Wenn ich das Programm in den CPLD flashe Zählt der
>Zähler leider nur bis zur 0 runter und verwirft dann alle weiteren
>negativen Zählschritte, positive Zählschritte werden aber weiterhin
>akzeptiert.

Wie stellst du das eigentlich fest?

von Schlumpf (Gast)


Lesenswert?

Auch, wenn es ein wenig 'oft topic' ist.
Über das Thema synchrone oder asynchrone Resets lässt sich trefflich 
streiten.
Meiner Meinung nach ist die sauberste Lösung, in der Beschreibung der 
Register einen asynchronen Reset zu verwenden und den externen Reset 
zentral zu synchronisieren.
Dabei synchronisiert man aber nur die Flanke, die den Reset inaktiv 
schaltet. Das Aktivieren des Reset bleibt asynchron.
Vorteil:
Die Synthese kennt den Phasenbezug zum Takt und sorgt dafür, dass der 
Reset mit der Flanke des Taktes an den Registern definiert inaktiv ist.
Es wird der GSR verwendet.
Der eigentliche Reset kann auch ohne das Vorhandensein eines Taktes 
ausgeführt werden.
Vermutlich ist das Ganze auch etwas ressourcenschonender.

Aber wie gesagt, das ist vermutlich eine Diskussion, die hier etwas fehl 
platziert ist

von Thomas Werthwein (Gast)


Angehängte Dateien:

Lesenswert?

Schlumpf schrieb:
> Sehr eigenartig....
> Kannst du sicherstellen, dass das signal up_down zum Zeitpunkt der
> Taktflanke stabil ist?

Das ist sichergestellt, da up_down um einiges lansamer ist als das 
Taktsignal. Ich hänge mal einen Screenshot von dem gecapturten Signal 
an. Es handelt sich um ein 3bit quantisiertes Sinussignal. Hier kann man 
deutlich erkennen, das die obere Halbwelle bis auf die Glitches richtig 
aussieht. Die erste hälfte der unteren Halbwelle fehlt dann. Ab dem 
Minimum des Sinus wird wieder Aufwärts gezählt, somit erhalte ich 
nachher einen Sinus mit Offset.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas Werthwein schrieb:
> Die erste hälfte der unteren Halbwelle fehlt dann.
Richtig, die müsste eigentlich von oben hereinkommen...
Aber hast du den Zähler auch einmal manuell getestet und getaktet und 
vor allem den Überlauf in positiver Richtung mal untersucht?

Kannst du auch einfach nur die 8 Zählerbits darstellen, ganz ohne 
dezimale Interpretation vom Logikanalyzer? Dann stören auch die Glitches 
nicht mehr so...

von Thomas Werthwein (Gast)


Lesenswert?

Lothar Miller schrieb:
> Thomas Werthwein schrieb:
>> Die erste hälfte der unteren Halbwelle fehlt dann.
> Richtig, die müsste eigentlich von oben hereinkommen...
> Aber hast du den Zähler auch einmal manuell getestet und getaktet und
> vor allem den Überlauf in positiver Richtung mal untersucht?
>
> Kannst du auch einfach nur die 8 Zählerbits darstellen, ganz ohne
> dezimale Interpretation vom Logikanalyzer? Dann stören auch die Glitches
> nicht mehr so...

Nur die Zählerbits kann ich gerade nicht darstellen, da ich dafür meinen 
Matlabcode mit dem ich den Logicanalyzer auslese verändern müsste um das 
zu erreichen.

Den Überlauf nach oben habe ich gerade getestet, indem ich den up_down 
Anschluss konstant auf 3,3V gesetzt habe. Auch hier gibt es einen 
merkwürdigen Effekt. Der Counter Springt von 63 nach -128.

von Schlumpf (Gast)


Lesenswert?

Und wenn du eine neue Aufzeichnung machst, kannst du vielleicht auch 
gleich den Takt und das Richtungssignal mit darstellen?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Wie schnell ist denn das Taktsignal?

von Schlumpf (Gast)


Lesenswert?

Das klingt alles sehr dubios. Und dubiose Effekte haben erfahrungsgemäß 
ihre Ursache oftmals in Glitches oder Setupzeitverletzungen... Daher 
wäre ein Oszi-Bild deiner Signale hilfreich, auch wenn es nur dabei 
hilft, so was auszuschließen.

von Thomas Werthwein (Gast)


Lesenswert?

Lothar Miller schrieb:
> Wie schnell ist denn das Taktsignal?

Das ist nicht fest, da ich in einem zeitkontinierlichen System arbeite. 
Den kürzesten abstand zwischen zwei Clocksignalen hat der Sinus beim 
Nulldurchgang und beträgt ca. 600us.

von Schlumpf (Gast)


Lesenswert?

Erkläre uns bitte mal, woher der Takt kommt und wie das Richtungssignal 
generiert wird und und in welchem Phasenbezug dieses zum Takt steht

von Thomas Werthwein (Gast)


Angehängte Dateien:

Lesenswert?

Das Signal wird in Matlab erzeugt und ensteht so, daß immer dann wenn 
das Signal eine Quantisierungsstufe überschreitet diese angenommen wird. 
Dadurch werden auch immer nur Differenzen um +-1 erreicht. Das ganze 
nennt sich Deltamodulation. Dieses so gewonnene Signal wird durch einen 
Lecroy Arbstudio Patterngenerator auf den CPLD geschickt und mit einem 
Mixed Signal Oszi ausgewertet.

Hier mal ein Screenshot vom Oszi.

von Schlumpf (Gast)


Lesenswert?

Oder anderesrum gefragt: um wieviel Zeit eilt das Richtungssignal der 
negativen Flanke von clock voraus?

von Thomas Werthwein (Gast)


Lesenswert?

Da hab ich mich wohl eben vertippt ich meinte 60us nicht 600 us.

von Thomas Werthwein (Gast)


Lesenswert?

Schlumpf schrieb:
> Oder anderesrum gefragt: um wieviel Zeit eilt das Richtungssignal der
> negativen Flanke von clock voraus?

ca 40ns.

Wenn das mein Problem ist würde ich mich Fragen warum das ganze im 
positiven bereich dann funktioniert ohne das etwas falsch erkannt wird.

von Schlumpf (Gast)


Lesenswert?

Ich muss gleich los, aber prüfe doch mal einfach sicherheitshalber nach, 
ob beim Wechsel des Richtungssignals die nächste fallende Flanke des 
Taktes garantiert eine vernünftige Zeit später kommt. Also mindestens 
zweistellige Nanosekunden

von Schlumpf (Gast)


Lesenswert?

Die Frage ist berechtigt. Aber wenn man totlal im Dunkeln tappt, schaut 
man halt einfach mal an jder möglichen Ecke nach. 40ns ist nicht gerade 
reichlich, aber sollte ausreichen... so, ich bin dann mal weg. Viel 
Erfolg noch

von Thomas Werthwein (Gast)


Lesenswert?

Ich habe den Code gestern Abend noch verändert, was aber zunächst 
keinerlei Einfluss auf das Ergebnis hatte.

Heute habe ich mir das ISE Projekt nochmal genauer angeschaut und 
festgestellt, dass ich die LVCMOS18 gewählt hatte, obwohl ich LVCMOS33 
benötige. Ausserdem hatte ich den Reset Pin mit 5V betrieben, ich hoffe 
ich habe damit nichts kaputt gemacht.
Nachdem ich diese Einstellungen geändert habe läuft der Zähler nun 
richtig über die Obere Grenze von +127 nach -128 und umgekehrt über die 
untere Grenze. Soweit schonmal ein Erfolg.


Leider habe ich immer noch ein Problem. Der Zählschritt von 0 nach -1 
wird falsch ausgeführt. Hier werden immer 2 anstatt 1 abgezogen. Ich 
erhalte nun einen Sinus der sich treppenförmig nach unten entwickelt und 
erst dann einen konstanten Verlauf hat sobald der die Maxima des Sinus 
die -1 nicht mehr überschreiten.
1
library ieee;
2
    use ieee.std_logic_1164.all;
3
  use ieee.numeric_std.all;
4
   
5
6
entity up_down_counter is
7
  port (
8
    cout    :out std_logic_vector (7 downto 0);-- Output of the counter
9
    up_down :in  std_logic;                    -- up_down control for counter
10
    clk    :in  std_logic;                    -- Input clock
11
    reset    :in  std_logic                     -- Input reset
12
  );
13
end entity;
14
15
architecture rtl of up_down_counter is
16
    signal count :integer range -128 to 127;
17
begin
18
    process (clk, reset) begin
19
        if (reset = '1') then
20
            count <= 0;
21
        elsif (falling_edge(clk)) then
22
            if (up_down = '1') then
23
                count <= count + 1;
24
            else
25
                count <= count - 1;
26
            end if;
27
        end if;
28
    end process;
29
   cout <= std_logic_vector(to_signed(count, 8));
30
31
 end architecture;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas Werthwein schrieb:
> Leider habe ich immer noch ein Problem. Der Zählschritt von 0 nach -1
> wird falsch ausgeführt. Hier werden immer 2 anstatt 1 abgezogen. Ich
> erhalte nun einen Sinus der sich treppenförmig nach unten entwickelt und
> erst dann einen konstanten Verlauf hat sobald der die Maxima des Sinus
> die -1 nicht mehr überschreiten.
???
Wie kann man sich das als Zahlenreihe in etwa vorstellen?

von Schlumpf (Gast)


Lesenswert?

Ich glaube, es wäre vom Verständnis einfacher, wenn du dich nicht immer 
auf die Auswirkungen auf den Sinusverlauf beziehst, sondern einfach mal 
nur das Verhalten des Zählers darstellst.
So wie ich es verstehe, zählt er jetzt um den Nullpunkt herum 
folgendermaßen:

down: 3, 2, 1, 0, -2, -3
up: -3, -2, -1, 0, 1, 2, 3

ist das richtig?

von Thomas Werthwein (Gast)


Lesenswert?

Schlumpf schrieb:
> Ich glaube, es wäre vom Verständnis einfacher, wenn du dich nicht immer
> auf die Auswirkungen auf den Sinusverlauf beziehst, sondern einfach mal
> nur das Verhalten des Zählers darstellst.
> So wie ich es verstehe, zählt er jetzt um den Nullpunkt herum
> folgendermaßen:
>
> down: 3, 2, 1, 0, -2, -3
> up: -3, -2, -1, 0, 1, 2, 3
>
> ist das richtig?

 Ja genau.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Das Problem liegt in deiner Hardware, nicht in der VHDL-Beschreibung. 
Mach mal ein Foto von deinem Aufbau. Fehlen da Blockkondensatoren am 
CPLD?

Allerdings sehe ich den bereits erwähnten up_down auch noch als kritisch 
an. Kann es sein, dass dieser asynchrone Eingang zeitgleich mit einem 
Zählimpuls kommt? Oder kommt der garantiert immer mindestens 30ns 
früher oder später?

Thomas Werthwein schrieb:
> Schlumpf schrieb:
>> Sehr eigenartig....
>> Kannst du sicherstellen, dass das signal up_down zum Zeitpunkt der
>> Taktflanke stabil ist?
> Das ist sichergestellt, da up_down um einiges lansamer ist als das
> Taktsignal.
Es kommt nicht auf die Häufigkeit an. Leicht unterschiedliche 
Laufzeiten reichen für eine Fehlfunktion aus:
http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html

von Thomas Werthwein (Gast)


Lesenswert?

Lothar Miller schrieb:
> Das Problem liegt in deiner Hardware, nicht in der VHDL-Beschreibung.
> Mach mal ein Foto von deinem Aufbau. Fehlen da Blockkondensatoren am
> CPLD?
>

http://dangerousprototypes.com/docs/CoolRunner-II_CPLD_breakout_board
Ich habe dann einfach Pfostenleisten an die Anschlüsse gelötet und CPLD 
sowie oszilloskop direkt verbunden. Reset löse ich über einen Taster 
aus.


> Allerdings sehe ich den bereits erwähnten up_down auch noch als kritisch
> an. Kann es sein, dass dieser asynchrone Eingang zeitgleich mit einem
> Zählimpuls kommt? Oder kommt der garantiert immer mindestens 30ns
> früher oder später?

Ich erzeuge das Signal so, dass der Zählimpuls immer 40ns später als der 
Richtungswechsel erfolgt. Da die einzelnen Zählimpulse je nach Frequenz 
mindestens einige 100ns auseinander liegen sollte das mit dem vorher 
generell kein Problem sein.

>
> Thomas Werthwein schrieb:
>> Schlumpf schrieb:
>>> Sehr eigenartig....
>>> Kannst du sicherstellen, dass das signal up_down zum Zeitpunkt der
>>> Taktflanke stabil ist?
>> Das ist sichergestellt, da up_down um einiges lansamer ist als das
>> Taktsignal.
> Es kommt nicht auf die Häufigkeit an. Leicht unterschiedliche
> Laufzeiten reichen für eine Fehlfunktion aus:
> http://www.lothar-miller.de/s9y/archives/64-State-...

Mein Problem ist, daß ich kein Taktsignal zur verfügung stellen kann. Da 
das eingangssignal in späteren Versuchen zeitkontinierlich erzeugt wird 
und schlichtweg kein Taktsignal zum Synchronisieren zur verfügung steht.

Bei einem Einfachen Zähle kann ich mir die Problematik jetzt auch nicht 
so genau erklären, da ein Synchroner Zähler auch nur den Takt als 
Zählsignal hernehmen würde und ansonsten (bis auf reset) kein bezug zum 
Tak hergestellt wird. Oder irre ich mich hier?

mit freundlichem Gruß

Thomas Werthwein

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas Werthwein schrieb:
>> Leicht unterschiedliche Laufzeiten reichen für eine Fehlfunktion aus:
>> http://www.lothar-miller.de/s9y/archives/64-State-...
> Mein Problem ist, daß ich kein Taktsignal zur verfügung stellen kann. Da
> das eingangssignal in späteren Versuchen zeitkontinierlich erzeugt wird
> und schlichtweg kein Taktsignal zum Synchronisieren zur verfügung steht.
Es geht mir da nicht darum, dass du ein synchrones Design haben musst, 
sondern darum, dass die Richtungsumschaltung an jedes einzelne 
Flipflop geführt wird. Und wenn du dort Laufzeitunterschiede hast, dann 
sehen einzelne FFs u.U. noch die "alte" Richtung, die anderen schon die 
"neue"...

> Ich erzeuge das Signal so, dass der Zählimpuls immer 40ns später als der
> Richtungswechsel erfolgt.
Soweit ok. Und diese Zeit hast du auch am CPLD-Pin?

> Da die einzelnen Zählimpulse je nach Frequenz mindestens einige 100ns
> auseinander liegen sollte das mit dem vorher generell kein Problem sein.
Die nachfolgenden Zählimpulse sind für diese Richtungsumschaltung eh' 
egal.

von Thomas Werthwein (Gast)


Lesenswert?

Lothar Miller schrieb:
> Soweit ok. Und diese Zeit hast du auch am CPLD-Pin?

Die Zeit habe ich durch Messungen am Oszilloskop bestätigen können.

von Schlumpf (Gast)


Lesenswert?

Lothar Miller schrieb:
> Es geht mir da nicht darum, dass du ein synchrones Design haben musst,
> sondern darum, dass die Richtungsumschaltung an jedes einzelne
> Flipflop geführt wird. Und wenn du dort Laufzeitunterschiede hast, dann
> sehen einzelne FFs u.U. noch die "alte" Richtung, die anderen schon die
> "neue"...

Ich vermute auch sowas in der Art.

Wobei ein CPLD eigentlich flott genug sein sollte, dass innerhalb von 
40ns das Richtungssignal an allen Registern stabil anstehen sollte.
Und so wie ich es verstehe, behält das Richtungssignal auch seinen 
Zustand bei, bis "kurz vor" dem nächsten Taktimpuls.

@ Thomas:
Kannst du das Richtungssignal testhalber noch früher erzeugen? Also mal 
z.B. 80ns vor dem Takt?
Nur um mal zu sehen, ob der Effekt dann verschwindet.

Deine Pfostenleisten und Zuleitungen könnten dir deine Signale auch 
etwas "versaubeuteln".  Aber wenn du sicher bist, dass die Signale mit 
40ns Verzögerung auch so am CPLD ankommen, dann sollte das eigentlich 
funktionieren.
Ggf hast du auch bedingt durch Reflexionen auf der Leitung einen 
"Zappler" auf dem Takt, der eine Doppelzählung auslösen könnte.

von Schlumpf (Gast)


Lesenswert?

noch was:
Hat der CPLD dedizierte CLK-Pins? Wenn ja, dann solltest du den Takt 
auch auf diese legen.
Ggf könnte auch ein Schmitt-Trigger vor dem CLK-Pin des CPLD hilfreich 
sein.

von Thomas Werthwein (Gast)


Lesenswert?

> @ Thomas:
> Kannst du das Richtungssignal testhalber noch früher erzeugen? Also mal
> z.B. 80ns vor dem Takt?
> Nur um mal zu sehen, ob der Effekt dann verschwindet.

Ich habe jetzt sogar über 200ns dazwischen, das Problem besteht leider 
nach wie vor

> Deine Pfostenleisten und Zuleitungen könnten dir deine Signale auch
> etwas "versaubeuteln".  Aber wenn du sicher bist, dass die Signale mit
> 40ns Verzögerung auch so am CPLD ankommen, dann sollte das eigentlich
> funktionieren.
> Ggf hast du auch bedingt durch Reflexionen auf der Leitung einen
> "Zappler" auf dem Takt, der eine Doppelzählung auslösen könnte.

Wie könnte ich solche Reflexionen verhindern?

Schlumpf schrieb:
> noch was:
> Hat der CPLD dedizierte CLK-Pins? Wenn ja, dann solltest du den Takt
> auch auf diese legen.
> Ggf könnte auch ein Schmitt-Trigger vor dem CLK-Pin des CPLD hilfreich
> sein.

Der CPLD hat 3 Pins die  als GCK gekennzeichnet sind. Ich habe das 
Signal jetzt einmal auf einen solchen Pin gelegt, das hat aber leider 
auch keine Abhilfe gebracht.

Wie baue ich einen Schmitttrigger ein?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas Werthwein schrieb:
> Wie baue ich einen Schmitttrigger ein?
Wie sieht das Signal direkt am CPLD-Pin aus?

von Thomas Werthwein (Gast)


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> Thomas Werthwein schrieb:
>> Wie baue ich einen Schmitttrigger ein?
> Wie sieht das Signal direkt am CPLD-Pin aus?

D8 ist clock
D9 ist updown

1 = clk Signal mit Tastkopf direkt am pin des CPLDs aufgenommen

von Thomas Werthwein (Gast)


Lesenswert?

Die Spitzen treten nicht auf, wenn ich den Schirm des Tastkopfes nicht 
mit der Masse des Messaufbaus verbinde

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas Werthwein schrieb:
> 1 = clk Signal mit Tastkopf direkt am pin des CPLDs aufgenommen
Hoppla...
Warum ist das alles so eigenartig "digital"?
Kannst du das Signal mal analog anschauen und posten?

> Die Spitzen treten nicht auf, wenn ich den Schirm des Tastkopfes nicht
> mit der Masse des Messaufbaus verbinde
Das ist bedenklich...  :-o
Du hast da doch irgendeine Potentialverschleppung.

von Thomas W. (shal)


Angehängte Dateien:

Lesenswert?

So jetzt beide Signale analog aufgezeichnet. Ohne verbundenen Schirm.

von Schlumpf (Gast)


Lesenswert?

Thomas Werthwein schrieb:
> Die Spitzen treten nicht auf, wenn ich den Schirm des Tastkopfes nicht
> mit der Masse des Messaufbaus verbinde

Das klingt aber böse nach Schlamperei und einem Masseproblem zwischen 
deinem Board und dem Rest des Systems.

Die Register in deinem CPLD reagieren auf Zappler im 
Subnanosekundenbereich. Da nützt es wenig, wenn du ein Analogbild mit 
220n/div postest. Wenn auf den Flanken was drauf ist, was den Takt 
beeinflusst, dann siehst du das in der Auflösung nicht. Und schon gleich 
zweimal nicht, wenn du die Masse vom Tastkopf nicht angeschlossen hast.

Mein Vorschlag:
Bring erstmal dein Masseproblem in Ordung. Solange das nicht passt, ist 
dein um 40ns voreilendes Richtungssignal eher nur theoretischer Natur.

von Thomas W. (shal)


Lesenswert?

Ich frage mich, wo mien Masseproblem herkommt. Ich habe die Massen auf 
einem Steckbrett miteinander verbunden.

Dort laufen die Massen von

-Stromversorgung CPLD
-Signalgenerator
-Digitalteil des Mixed Signal Oszilloskops
-Die Abschirmung des Tastkopfes

zusammen

Ich habe alle Masseleitungen noch mal kontrolliert und die Messung bei 
angeschlossener Abschirmung wiederholt. Jetzt treten die Spitzen nicht 
mehr auf. Das Problem besteht weiterhin.

von Schlumpf (Gast)


Lesenswert?

Wenn das Masse Problem jetzt gelöst ist, kannst ja nochmal eine 
neueMessung machen.
Einmal, wo man den Abstand des Richtungssignals vom Takt sieht (am 
besten mit infinite persistance aufnehmen) und eine weiter Messung, wo 
man die Flanke des Taktes hochauflösend sieht.

von Schlumpf (Gast)


Lesenswert?

Ach ja, falls verfügbar, Messe die Flanke mit einem schnelleren Oszi. 
Wenn ich richtig informiert bin, ist bei dem, welches du gerade hast, 
bei 100 MHz Schluss. Das könnte beim Finden von störenden Reflexionen 
ein wenig knapp werden.

von Thomas W. (shal)


Angehängte Dateien:

Lesenswert?

Ein schnelleres Osziloskop habe ich leider nicht zur Verfügung. Bei 
maximaler Auflösung sieht die Flanke meines Erachtens nach sauber aus.
Die Messung wurde direkt mit den Tastköpfen des Oszilloskops auf den 
jeweiligen Anschlüssen des CPLDs ausgeführt.
Die Abstandsmessung mit Persistance konnte ich nun auch durchführen.

Vielen Dank für den bisherigen Input.

von Thomas W. (shal)


Lesenswert?

Was ich bisher noch nicht bedacht habe. Was ist für meinen Fall (Die 
unbenutzten Pinne des CPLD hängen frei) die beste Konfiguration?
Ich habe hier Keeper/Pullup/Ground/Float zur Auswahl. Die aktuelle 
Konfiguration entspricht der Voreinstellung Keeper.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas Werthwein schrieb:
> Die aktuelle Konfiguration entspricht der Voreinstellung Keeper.
Das passt schon, du musst nur einen definierten Pegel an den Pins haben. 
Also auf keinen Fall Eingänge floaten lassen...

von Thomas W. (shal)


Lesenswert?

Lothar Miller schrieb:
> Thomas Werthwein schrieb:
>> Die aktuelle Konfiguration entspricht der Voreinstellung Keeper.
> Das passt schon, du musst nur einen definierten Pegel an den Pins haben.
> Also auf keinen Fall Eingänge floaten lassen...

Und das habe ich aktuell nicht und hoffte das umgehen zu können. Alle 
unbenutzten Pins hängen aktuell frei in der Luft. Dann werde ich mal nen 
paar Strippen ziehen und alle unbenutzen Pins auf GND setzen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas Werthwein schrieb:
> Und das habe ich aktuell nicht
Trotz "Keeper"?
Sollte nicht sein. Denn der Keeper ist eine schwache Mitkopplung über 
z.B. 100kOhm und sorgt durchaus für GND oder Vcc am Eingangspin...

von Thomas W. (shal)


Lesenswert?

Lothar Miller schrieb:
> Thomas Werthwein schrieb:
>> Und das habe ich aktuell nicht
> Trotz "Keeper"?
> Sollte nicht sein. Denn der Keeper ist eine schwache Mitkopplung über
> z.B. 100kOhm und sorgt durchaus für GND oder Vcc am Eingangspin...

Ich habe das nicht gemessen, ich meinte nur, dass die unbenutzten Pins 
unbeschaltet sind. ich habe die Pins nun mal mit dem Osziloskop 
angeschaut und festgestellt, daß diese alle auf GND Potenzial liegen.

von Schlumpf (Gast)


Lesenswert?

Die Flanken sehen eigentlich ganz OK aus. Was mich nur etwas wundert, 
ist die Zeitskala des Bildes. Sagtest du nicht, dass du zwischen den 
beiden Flanken 40ns hast. Wenn ich die Angabe oben mit 27ns/ richtig 
interpretiere, dann wären das ja sogar ca. 200ns. Nicht, dass das ein 
Problem wäre, im Gegenteil, aber es erstaunt mich gerade ein wenig.

von Schlumpf (Gast)


Lesenswert?

Ich muss gestehen, dass ich langsam ein wenig ratlos bin. Was auf jeden 
Fall aber kein Schaden ist, und vom Aufwand überschauba wäre, vor dem 
Takt Eingang des CPLD einen Schmitt-Trigger zu spendieren, falls du in 
der Bastelkiste eine rum liegen hast. ich glaube zwar selber nicht mehr 
so recht dran, dass es an der Qualität der Flanke liegt, aber dann 
kannst mit Sicherheit davon ausgehen, dass die Flanke passt.

von Schlumpf (Gast)


Lesenswert?

Ich hab grad das Datenblatt über flogen und da sieht es so aus, als 
könne man jeden Eingang auch als Schmitt-Trigger konfigurieren. Mach das 
doch mal für das Takt- und Richtungssignal. Im Moment der Taktflanke 
hast du auf dem Richtungssignal einen deutlichen Überschwinger. Ist der 
Eingang als 3.3V Input konfiguriert, geht der definierte Low-Bereich nur 
bis 0,8V. Da ist der Überschwinger nicht mehr sooooo weit von weg. Das 
kannst du auf jeden Fall 'entspannen', wenn du die Eingänge als ST 
konfigurierst.

von Thomas W. (shal)


Lesenswert?

Das mit dem Schmitttrigger habe ich auch getestet, mir aber nicht 
allzuviel davon Versprochen, da der Wechsel von 0 nach -1 nicht mit 
einer Flanke des Updown Signals in verbindung steht. Es hat leider auch 
keine Verbesserung gebracht.

Aktuell habe ich eine Ausnahme in den VHDL Code eingebaut, die den 
Zustandwechsel von 0 nach -1 abfängt und dann -1 in den Zählerstand 
schreibt.
Das funktioniert tatsächlich. Schön ist deutlich anders und ich bin auch 
eher unglücklich mit der Lösung, aber ich muss langsam mal zu einem 
Ergebnis kommen.
1
library ieee;
2
   use ieee.std_logic_1164.all;
3
   use IEEE.numeric_std.all;
4
5
entity up_down_counter is
6
  port (
7
    cout    :out std_logic_vector (7 downto 0);-- Output of the counter
8
    up_down :in  std_logic;                    -- up_down control for counter
9
    clk     :in  std_logic;                    -- Input clock
10
    reset   :in  std_logic                     -- Input reset
11
  );
12
end entity;
13
14
architecture rtl of up_down_counter is
15
    signal count :signed (7 downto 0);
16
begin
17
    process (clk, reset) begin
18
        if (reset = '1') then
19
            count <= to_signed(0,8);
20
        elsif (falling_edge(clk)) then
21
            if (up_down = '1') then
22
                count <= count + to_signed(1,8);
23
            else
24
                if (count = "00000000") then
25
                   count <= "11111111"; 
26
                else
27
                   count <= count + to_signed(-1,8);
28
               end if;
29
            end if;
30
        end if;
31
    end process;
32
   cout(0) <= count(0);
33
   cout(1) <= count(1);
34
   cout(2) <= count(2);
35
   cout(3) <= count(3);
36
   cout(4) <= count(4);
37
   cout(5) <= count(5);
38
   cout(6) <= count(6);
39
   cout(7) <= count(7);
40
 end architecture;

von Schlumpf (Gast)


Lesenswert?

Hmm, wenn es hilft, dann ist es ja gut, aber schön ist es wirklich 
nicht.
Ne Erklärung für das Verhalten habe ich leider auch nicht.

Aber versuch doch mal spasseshalber folgendes:
Statt
1
count <= count + to_signed(-1,8);
folgendes:
1
count <= count - to_signed(1,8);

von Lattice User (Gast)


Lesenswert?

Ich tippe auf Groundbounce.

Wenn sich alle Ausgänge von 0 auf 1 ändern, wird die Masse kurz etwas 
hochgezogen und es passiert Böses.
Abhilfe: Anständige Groundplane, ein Steckbrett ist da alles andere als 
gut.

Man könnte auch probieren die kapazitive Last an den Ausgängen durch 
Serienwiderstände zu reduzieren (33 -100 Ohm).

von Thomas W. (shal)


Lesenswert?

Lattice User schrieb:
> Ich tippe auf Groundbounce.
>
> Wenn sich alle Ausgänge von 0 auf 1 ändern, wird die Masse kurz etwas
> hochgezogen und es passiert Böses.
> Abhilfe: Anständige Groundplane, ein Steckbrett ist da alles andere als
> gut.
Das Breakoutboard für den CPLD besitzt eine Groundplane, diese ist über 
ein Steckbrett mit den anderen Masseleitungen verbunden.

> Man könnte auch probieren die kapazitive Last an den Ausgängen durch
> Serienwiderstände zu reduzieren (33 -100 Ohm).

Das mit den Serienwiderständen werde ich mal testen, frage mich aber ob 
das Sinn macht, wenn der Eingang des Logiganalyzers 100kOhm 
Eingangsimpedanz hat.

von Lattice User (Gast)


Lesenswert?

Thomas Werthwein schrieb:

>
> Das mit den Serienwiderständen werde ich mal testen, frage mich aber ob
> das Sinn macht, wenn der Eingang des Logiganalyzers 100kOhm
> Eingangsimpedanz hat.

Die 100 kOhm gelten für DC.
AC sieht es ganz anders aus, und da spielt vor allem auch das Kabel eine 
Rolle.

von Bernd S. (Gast)


Lesenswert?

wenn du tatsächlich Problem mit dem GND hast (und zumindest hast du ein 
messtechnisches Problem mit dem GND), dann solltest du dir ein besseres 
Oszi mit besserem Tastkopf besorgen und den GND des Tastkopfes extrem 
kurz direkt neben dem Signal an einen GND am CPLD verbinden.

Die langen GND-"Pigtails", die übliche Oszi-Tastköfpfe haben sind extrem 
anfällig, dass du auf dem Oszi nur Mist siehst, also eingekoppelte 
Störungen siehst. Die GND-Verbindung für den Tastkopf ist mit das 
wichtigste beim Messen, vor allem wenn es um Störungen geht.

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
Noch kein Account? Hier anmelden.