mikrocontroller.net

Forum: FPGA, VHDL & Co. Auswertung von Signaländerungen


Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich hab mal wieder ein Problem und bräuchte mal eure Hilfe. Ich arbeite
mit Spartan-3 von Xilinx und
möchte einen serielle Datenstrom aus 8-Bit-Worten auswerten. Genauer
soll die Signaländerung auswertet werden. Wenn
der Unterschied "Delta" zw. 2 aufeinanderfolgenden Worten größer als
"Schwelle" ist, soll sich der Ausgangswert "DataOut"
nicht ändern. Ist die Änderung < als "Schwelle", soll zum vorherigen
Ausgangswert die Änderung dazuaddiert werden.

Hab mal was geschrieben, das hinten und vorne nicht funktioniert. Wenn
ich die Entity "SchwellSchalter" als
component in ein anderes File einbinde, kommt immer die Warnung
Gated_Clock.



entity SchwellSchalter is
   Port ( clk : std_logic;
          reset: in std_logic;
          DoneIn : in std_logic;  -- Done-Flag des vorherigen Moduls
          enable : in std_logic;
          Schwelle : in std_logic_vector(7 downto 0);  -- vorgebbarer
Schwellwert
          DataIn : in std_logic_vector(7 downto 0);    -- ankommender
serieller Datenstrom
          DoneOut : out std_logic;
          DataOut : out std_logic_vector(7 downto 0));
end SchwellSchalter

architecture Behavioral of SchwellSchalter is

-- Der Typ Buffer ist ein Array aus 2 8-Bit-Worten
   type Buffer is array (1 downto 0) of std_logic_vector(7 downto 0);
   signal Puffer : Buffer;
   signal ShiftFlag : std_logic;
   signal Delta : std_logic_vector(7 downto 0);
   signal DataOut_Intern : std_logic_vector(7 downto 0);
   signal DoneOut_Intern : std_logic;

begin
   process (clk, reset, DoneIn, enable, DataIn)
   begin
      if (reset = '1') then
         Puffer <= (others => "00000000");
   ShiftFlag <= '0';
      elsif (rising_edge(clk)) then
         if (reset = '1' and enable = '1') then
      Puffer <= Puffer(0) & DataIn;
      ShiftFlag <= '1';
   else
      ShiftFlag <= '0';
   end if;
      end if;
   end process;

   process (ShiftFlag, Puffer, Delta, Schwelle)
   begin
      if (ShiftFlag <= '1') then
         Delta <= (Puffer(0) - Puffer(1));
         if (Delta < Schwelle) then
            Int_FilteredOut <= Puffer(0); -- neuen Wert ausgeben
            DataOut_Intern <= '1';
         elsif (Delta > Schwelle) then
      Int_FilteredOut <= Puffer(1); -- alten Wert ausgeben
   end if;
      elsif (ShiftFlag <= '0') then
         DataOut_Intern <= '0';
      end if;
   end process;

   DoneOut <= DataOut_Intern;
   DataOut <= DataOut_Intern;

end Behavioral;


Vielleicht kann mir ja jemand weiterhelfen. Würde mich freuen

Danke im Voraus.


Gruß
Jens

Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

"if (ShiftFlag <= '1') then
elsif (ShiftFlag <= '0') then"

Das würde ich erstmal ändern und dann nochmal schaun ... so wird der
elsif Teil wohl nicht ausgeführt da die Bedingung nie erfüllt ist. War
aber wahrscheinlich nur ein Tippfehler oder?

Cpt

Autor: Xenu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo ist "Int_FilteredOut" definiert?
Für was soll "ShiftFlag" gut sein?
"DataOut_Intern" ist ein Vektor, Du weist ihm aber einzelne Bits zu.
"Delta" und "Int_FilteredOut" stellen Latches dar (=> nicht gut).
"DoneOut" (1 Bit breit) wird "DataOut_Intern" (8 Bit breit)
zugewiesen, "DoneOut_Intern" wird nie benutzt.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Cpt,

danke für den Hinweis. War ein Schreibfehler. Funktioniert aber
trotzdem nicht.


Hallo Xenu,

die Definition von "Int_FilteredOut" ist beim posten anscheinend
irgendwie verlorengegangen. Im Quellcode bei mir steht diese Zeile aber
drin.

Hier noch mal die verbesserte Version:

entity SchwellSchalter is
   Port ( clk : std_logic;
          reset: in std_logic;
          DoneIn : in std_logic;  -- Done-Flag des vorherigen Moduls
          enable : in std_logic;
          Schwelle : in std_logic_vector(7 downto 0);  -- vorgebbarer
Schwellwert
          DataIn : in std_logic_vector(7 downto 0);    -- ankommender
serieller Datenstrom
          DoneOut : out std_logic;
          DataOut : out std_logic_vector(7 downto 0));
end SchwellSchalter

architecture Behavioral of SchwellSchalter is

-- Der Typ Buffer ist ein Array aus 2 8-Bit-Worten
   type Buffer is array (1 downto 0) of std_logic_vector(7 downto 0);
   signal Puffer : Buffer;
   signal ShiftFlag : std_logic;
   signal Delta : std_logic_vector(7 downto 0);
   signal DataOut_Intern : std_logic_vector(7 downto 0);
   signal DoneOut_Intern : std_logic;
   signal Int_FilteredOut : std_logic_vector(7 downto 0);

begin
   process (clk, reset, DoneIn, enable, DataIn)
   begin
     if (reset = '1') then
        Puffer <= (others => "00000000");
        ShiftFlag <= '0';
     elsif (rising_edge(clk)) then
        if (reset = '1' and enable = '1') then
           Puffer <= Puffer(0) & DataIn;
           ShiftFlag <= '1';
        else
           ShiftFlag <= '0';
        end if;
     end if;
   end process;

   process (ShiftFlag, Puffer, Delta, Schwelle)
   begin
      if (ShiftFlag = '1') then
         Delta <= (Puffer(0) - Puffer(1));
         if (Delta < Schwelle) then
            Int_FilteredOut <= Puffer(0); -- neuen Wert ausgeben
            DoneOut_Intern <= '1';
         elsif (Delta > Schwelle) then
            Int_FilteredOut <= Puffer(1); -- alten Wert ausgeben
            DoneOut_Intern <= '1';
         end if;
      elsif (ShiftFlag = '0') then
         DoneOut_Intern <= '0';
      end if;
   end process;

   DoneOut <= DoneOut_Intern;
   DataOut <= DataOut_Intern;

end Behavioral;


Der erste Prozess soll ein 'Moving Shift-Register' darstellen, das
immer wieder einen Wert aus einem seriellen Datenstrom einliest. Oben
fällt dabei ein Wert aus dem Puffer. ShiftFlag soll anzeigen, wann ein
neuer Wert in den Puffer geschrieben wurde. Es wird im 2. Prozess
verwendet, damit der Vergleich (Schwellwert - Delta) nur durchgeführt
wird, wenn auch ein neuer Eintrag im Puffer steht. Es sollen ja immer
die beiden Pufferwerte verglichen werden. Je nachdem ob Delta < oder >
als die vorgegebene Schwelle ist, soll der neue oder der alte Wert
ausgegeben werden. Damit soll verhindert, dass zu große
Signaländerungen auftreten.

Was meinst du mit ""Delta" und "Int_FilteredOut" stellen Latches
dar"?
Wie erkennst du das aus dem Quellcode und wie mache ich es besser?
Sind wahrscheinlich dumme Fragen aber ich bin leider noch
VHDL-Anfänger.

Gruß
Jens

Autor: Xenu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Was meinst du mit ""Delta" und "Int_FilteredOut" stellen Latches
>dar"?

Naja, sie stellen halt Latches dar.
Frei nach Gertrude Stein: "Ein Latch ist ein Latch ist ein Latch."

Wenn Du bei obigem Code noch ein paar grundsätzliche Fehler ausbesserst
und dann synthetisierst, wird Dir das auch Dein Synthesizer sagen.

Fehler Nr.1: "Buffer" ist ein reserviertes VHDL-Schlüsselwort,
Nr.2: "reset" wird zweimal auf '1' abgefragt,
Nr.3: "Int_FilteredOut" wird zwar zugewiesen, aber nicht nach aussen
geführt.

Wenn Du das ausbesserst, bekommst Du mit Xilinx Webpack u.a. folgende
Warnungen:

WARNING:Xst:737 - Found 8-bit latch for signal <Delta>.
WARNING:Xst:737 - Found 1-bit latch for signal <DoneOut_Intern>.
WARNING:Xst:737 - Found 8-bit latch for signal <Int_FilteredOut>.


>Wie erkennst du das aus dem Quellcode

Erstens sind im zweiten Prozess keine getaktete Zuweisungen vorhanden
(d.h. die Signale können keine (getakteten) Flip-Flops sein, und
zweitens kommen die Signale nicht in allen Zweigen des
if-elsif-else-Blocks vor.

>und wie mache ich es besser?

Getaktete Zuweisung (if rising_edge(clk) then ...)

Autor: Xenu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, noch etwas:

Der Wert für Delta ist nur korrekt, wenn Puffer(0) immer größer als
Puffer(1) ist.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.