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


von Jens (Gast)


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

von Cpt (Gast)


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

von Xenu (Gast)


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.

von Jens (Gast)


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

von Xenu (Gast)


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 ...)

von Xenu (Gast)


Lesenswert?

Ach ja, noch etwas:

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

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.