Forum: FPGA, VHDL & Co. Vergleichsalgorithmus gibt seltsames Ergebnis aus


von Black Friday (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
ich kämpfe immer noch mit der Einarbeitung in VHDL.
Ich habe eine Art Vergleicher programmiert, der nur den größten Wert
eines 12-Bit-Musters ausgeben soll.
Im Moment zähle ich testweise den Eingang von 000000000000 bis
000000001111 hoch, es sollte also auch 000000001111 ausgegeben werden
(und zwar beim Zählerstand 000000000000).
Statt dessen bekomme ich immer 000000001000 ausgegeben (siehe Anhang).
Sieht zufällig jemand meinen Fehler? Ich habe schon x-mal alle
Möglichkeiten durchgespielt und komme immer zu dem Ergebnis, dass der
Code eigentlich so funktionieren müsste.

Hier mein Code und im Anhang das Ergebnis:
library IEEE;
use IEEE.std_logic_1164.all;  -- defines std_logic types
use IEEE.std_logic_unsigned.all;


entity jc2_top is
    port (
    eing : in STD_LOGIC_VECTOR (11 downto 0) := "000000000000";
     Q : out STD_LOGIC_VECTOR (11 downto 0) := "000000000000"
         );
end jc2_top;

architecture jc2_top_arch of jc2_top is
signal QIN : STD_LOGIC_VECTOR (11 downto 0) := "000000000000";
signal QOLD : STD_LOGIC_VECTOR (11 downto 0) := "000000000000";
signal anf : std_logic := '1';
begin


process (eing)
begin
       QIN <= eing;

     if (QOLD < QIN) THEN
        QOLD <= QIN;
        anf <= '0';
        Q <= "000000000000";
     elsif (QOLD > QIN) THEN
        Q <= QOLD;
        if ((QIN = "000000000000") and (anf = '0')) THEN
            QOLD <= "000000000000";
            anf <= '1';
        end if;
    else
    end if;

end process;

end jc2_top_arch;

von TheMason (Gast)


Lesenswert?

als erstes brauchst du einen clock, ohne den hast du asynchrones
verhalten und damit würde dein design nicht das tun was es tun soll..
bau einen clock und einen reset ein.
im reset setzt du deinen QOLD auf den kleinstmöglichen wert
(vorzugsweise 0) und den vergleich auf größer machst du immer mit der
steigenden flanke.
dann solltest du deinen 12-bit eingang mehrfach einclocken (um auch
nicht irgendwelche undefinierten zustände zu erhalten) wenn du denn
entsprechend resourcen frei hast. arbeitest du mit einem cpld ?!
wenn ja kannst du das mehrfache einclocken auch sein lassen (braucht
platz)

mal ein vorschlag wie ich sowas angehen würde (in einem fpga) :

...
signal eing_z1 : std_logic_vector (11 downto 0);
signal eing_z2 : std_logic_vector (11 downto 0);
signal eing_z3 : std_logic_vector (11 downto 0);
...

  if res = '1' then
     eing_z1 <= (others => '0');
     eing_z2 <= (others => '0');
     eing_z3 <= (others => '0');

  elsif clk'event and clk = '1' then
    eing_z1 <= eing;
    eing_z2 <= eing_z1;
    eing_z3 <= eing_z2;

    ...
    ...

  end if;

mit eing_z3 kannst du dann arbeiten.

hoffe ich konnte dir helfen

von Dirk (Gast)


Lesenswert?

Hallo,

@TheMason

>dann solltest du deinen 12-bit eingang mehrfach einclocken (um auch
>nicht irgendwelche undefinierten zustände zu erhalten) wenn du denn
>entsprechend resourcen frei hast. arbeitest du mit einem cpld ?!
>wenn ja kannst du das mehrfache einclocken auch sein lassen (braucht
>platz)

Widerspricht du Dir nicht in deinen Saetzen? Muss man nun das Signal
"mehrfach einclocken" oder nicht und vorallendingen was meinst du mit
"mehrfach einclocken) ???

Gruß,
Dirk

von SiO2 (Gast)


Lesenswert?

@themason Was genau bringt das mit mehreren Zaehlern? Wo koennen den
undefinierte Zustaende zusammenkommen? wenn ich einen Zaehler nutze
muss der doch laufen, und nicht erst der x'te dahinter.

von Black Friday (Gast)


Lesenswert?

Danke schon mal für eure Antworten, das Ganze soll wirklich in einen
CPLD. Die Logik soll (und muss) später unabhängig von einer Taktquelle
funktionieren. Ich sehe auch keine Vorteile (eher Nachteile), wenn ich
das taktsynchron löse.
Mein Problem wird sicher durch irgendeinen blöden Fehler hervorgerufen,
den ich auch nach stundenlanger Fehlersuche nicht finde.

von TheMason (Gast)


Lesenswert?

@all

von TheMason (Gast)


Lesenswert?

vertippt ..

@all

hab mich da etwas blöd ausgedrückt ja ...
ich wusste nicht ob er den zählerstand von außen erzeugt um mit dem
design etwas zu vergleichen, oder ob das design selbst einen zähler
bilden soll.
mit dem mehrfach einclocken macht man ja wenn man signale verarbeiten
möchte die einen anderen takt haben als das eigentliche design.
von daher hab ich mich ein bissl verrannt ...
hätte vielleicht fragen sollen ob das ganze innen cpld laufen soll

von Dirk (Gast)


Lesenswert?

>hätte vielleicht fragen sollen ob das ganze innen cpld laufen soll

Waere es bei einem FPGA nicht so?

Gruß,
Dirk

von Xenu (Gast)


Lesenswert?

>Mein Problem wird sicher durch irgendeinen blöden Fehler
>hervorgerufen, den ich auch nach stundenlanger Fehlersuche nicht
>finde.

Der blöde Fehler liegt darin, dass du keine Register benutzt.

>Ich sehe auch keine Vorteile (eher Nachteile), wenn ich
>das taktsynchron löse.

Dann solltest Du Dich mal in die Grundlagen der Digitaltechnik
einarbeiten.

Du versuchst doch in Deinem Code etwas zu speichern.
Wie willst Du das vernünftig ohne Takt machen?

von Black Friday (Gast)


Lesenswert?

Die Schaltung funktioniert jetzt. Danke für die Hilfe!
Ich habe eure Tips befolgt und lese den Eingang jetzt synchron ein. Als
Taktquelle verwende ich im Moment den Takt eines zweiten CPLD, der mir
momentan die Eingangssignale erzeugt.
Das Problem lag höchstwahrscheinlich darin, dass mindestens eine der
FLanken des Eingangssignals minimal verschoben zu den anderen war.
Mein Problem ist nur, dass in der späteren Anwendung sich die
Eingangssignale in unregelmäßigen Abständen ändern.
Gäbe es nicht doch eine Möglichkeit, das Problem Asynchron zu lösen?

P.S. wes ist mit "Der blöde Fehler liegt darin, dass du keine Register
benutzt" gemeint? Die Bitvektoren stellen doch im Prinzip Register dar,
oder?

von Xenu (Gast)


Lesenswert?

>Die Bitvektoren stellen doch im Prinzip Register dar, oder?

Nein, sondern Latches (pegelgesteuerte Flip-Flops).

von Axel (Gast)


Lesenswert?

Einen Bus kannst Du so nicht einsynchronisieren. Was TheMason da
geschrieben hat ist Quatsch. Du musst irgendwoher ein Signal haben,
welches Dir anzeigt, dass der Wert auf dem Bus gültig ist und Du den
nun auswerten kannst.

Der Grund, warum Dein Code nicht funktioniert, ist, dass Du mit Deinem
Code Daten speicherst, was wohl so nicht gedacht ist. Also baut Deine
Logik da Latche ein und nichts geht.

Wenn Du ohne Takt arbeiten willst, versuch mal Deine Schaltung ohne
"Process" aufzubauen, da ist die Gefahr geringer, dass Du Dir
irgendwo Latche einfängst.

Also z. B.

TARGET <= VALUE_1 when CONDITION_1 else
                    VALUE_2 when CONDITION_2 else
                    . . .
                    VALUE_n;

Gruss
Axel
PS: Allerdings habe ich noch nicht verstanden, was Du eigentlich machen
willst.

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.