www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Problem im vhdl code


Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Forenmitglieder,


ich habe wiedermal ein Problem und komme nicht weiter. Vielleicht fällt 
jemandem der Fehler im code auf.

Um was es geht. Ich taste ein analoges Signal mit einem AD Wandler ab. 
Ich möchte zwei sachen von Analogen Signal erkennen.

1. Die fallende Flanke von Signal ( gelöst über ein Schmitt Trigger dank 
euch :))

2. Die maximale Amplitude vom Signal. (Funktioniert auch so weit)

Folgende Einschränkungen:

Ich möchte nicht auf jedes eingangssignal reagieren, sondern wenn ein 
Signal bzw. seine fallende Flanke erkannt wurde wird eine Sperrzeit von 
1 millisekunde, in der Zeit reagiert das System nicht auf den Eingang.
Funktioniert auch so weit.

Mein Problem ist bei der Ampliuden erkennung. Ich muss den Wert der 
Maximalen Amplituden erkennung wieder auf Null setzten. Meine Idee war 
es wenn die Totzeit beginnt den gespeicherten Wert der Amplitude wieder 
auf null zu setzten so das beim Nächsten ankommenden Signal die 
Amplituden erkennung wieder von Anfang losgeht und ich es für jedes 
Signal unabhängig mache.

Hier mal der Code , wenn jemand was auffällt wäre ich sehr dankbar!
----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    12:54:46 11/30/2009 
-- Design Name: 
-- Module Name:    EINGANGS_REGISTER - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.std_logic_unsigned.all; 
use IEEE.NUMERIC_STD.ALL;


---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
-------------------------------------------------------------------------------
entity Flanken_Detektierung_AD_Wandler  is
    Port ( 
        Eingang_Flanken_Detektierung_AD_Wandler          : in   STD_LOGIC_vector (11 downto 0);
           Clk_20Mhz_Flanken_Detektierung                 : in   STD_LOGIC;
           Analoge_Maximale_Amplitude_AD_Wandler           : out STD_LOGIC_vector (11 downto 0);
        Analoge_Flanke_wurde_erkannt_vom_AD_Wandler       : out  std_logic);
       
        
          
end Flanken_Detektierung_AD_Wandler ;


architecture Behavioral of Flanken_Detektierung_AD_Wandler  is
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
Signal Flanken_Detektierung_Zwischenpuffer                   : STD_LOGIC_vector (11 downto 0):="000000000000";
Signal Schmitt_Trigger_Level                            : unsigned (11 downto 0);
Signal cnt                                           : integer range  0 to 20000 ;
signal zustand,Enable_Trigger                             : std_logic;
sIGNAL Flanke_Erkannt,output_enable                       : std_logic:='0'; 
Signal Maximal_Analog_Amplitude                           : STD_LOGIC_vector (11 downto 0):="000000000000";          
Signal Aktuelle_Analoge_Amplitude                         : STD_LOGIC_vector (11 downto 0):="000000000000";          
Signal Amplitude_Zwischenspeicher                         : STD_LOGIC_vector (11 downto 0):="000000000000";          

begin
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------  
  
  --------------SCHIEBEREGISTER-------------
  ------------------------------------------ 
  Schieben :process (Clk_20Mhz_Flanken_Detektierung )
    begin
      if falling_edge (Clk_20Mhz_Flanken_Detektierung ) then
        Flanken_Detektierung_Zwischenpuffer <= Eingang_Flanken_Detektierung_AD_Wandler ;
        Aktuelle_Analoge_Amplitude       <=  Flanken_Detektierung_Zwischenpuffer;
        if Enable_Trigger = '0' then                            --  WENN FLANKE ERKANNT WIRD DIE MAXIMALE ERKANNTE AMPLITUDE WIEDER AUF NULL GESETZT
          Maximal_Analog_Amplitude <= "000000000000";                --  
        else
          if Aktuelle_Analoge_Amplitude > Maximal_Analog_Amplitude then
            Maximal_Analog_Amplitude <= Aktuelle_Analoge_Amplitude;
          else
            Maximal_Analog_Amplitude <= Maximal_Analog_Amplitude ;
          end if;
        end if;
    end process Schieben ;
  ------------------------------------------
      
  --------------------------------- FLANKEN ERKENNUNG ------------------------------------------------------
  ----------------------------------------------------------------------------------------------------------
  ----------------------------------------------------------------------------------------------------------
  
  --------------SIGNALZUWEISUNG-------------
  Analoge_Flanke_wurde_Erkannt_vom_AD_Wandler <=output_enable;
  Schmitt_Trigger_Level <=unsigned(Flanken_Detektierung_Zwischenpuffer);
  ------------------------------------------
  
  --------------TOTZEITERKENNUNG------------
  Totzeit:process(Clk_20Mhz_Flanken_Detektierung )
  begin
  if falling_edge(Clk_20Mhz_Flanken_Detektierung ) then
    if Flanke_Erkannt = '1' then
      output_enable <= '1';
      Enable_Trigger <='0';          -- BEI ERKANNTER ANALOGEN FLANKE WIRD TRIGGER AUF NULL GESTELLT 
      cnt<=0;                    
    elsif cnt <= 19999 then            -- HIER TOTZEIT FUER 1 msek, KEINE REAKTION AUF EINGANGSSIGNAL 
      output_enable  <= '1';          -- 
      Enable_Trigger <= '0';
      cnt <=cnt+1;
    else
      output_enable  <= '0';
      Enable_Trigger <= '1';          -- BEIM ÜBERLAUF VON CNT IST TRIGGER WIEDER AUF 1, SOMIT WIRD 
    end if;                      -- AUF FALLENDE FLANKE GESCHAUT;WENN SIE ERKANNT IST WIRD TRIGGER AUF
  end if;                        -- 0 GESETZT FÜR DIE TOTZEIT VON 8399 STELLEN
  end process Totzeit;
  ------------------------------------------

  --------------SCHMITT-TRIGGER-------------
  ------------------------------------------ 
   Trigger: process (Clk_20Mhz_Flanken_Detektierung )
   begin
      if falling_edge(Clk_20Mhz_Flanken_Detektierung ) then
      Flanke_Erkannt <= '0';                
       if Enable_Trigger ='1' then                      
        if (Schmitt_Trigger_Level > "101001100101")  then    -- OBERE SCHWELLE HIER 65% VOM AD BEREICH
          zustand <= '1';
        end if;
        if (Schmitt_Trigger_Level < "011001100110")  then    -- UNTERE SCHWELLE HIER 40%  VOM AD BEREICH  
          zustand <= '0';
          if zustand = '1' then
            Flanke_Erkannt <= '1';    -- ANALOGE FLANKE ERKANNT WENN SCHWELLE_UNTEN WIEDER UNTERSCHRITTEN 
          end if;
        end if;
      end if;
      end if;  
  end process Trigger;
  ----------------------------------------------
  Analoge_Maximale_Amplitude_AD_Wandler  <=Maximal_Analog_Amplitude;
  
  

end Behavioral; 

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das schmeisst Du erstmal raus:
> USE ieee.std_logic_unsigned.all;

Und dann macht es sich sehr gut, wenn Du noch die Testbench mitlieferst.

Duke

Autor: Igor (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

sorry wusste nicht so genau wie ich das simulieren soll, jetzt bench 
dabei.

>Das schmeisst Du erstmal raus:
> USE ieee.std_logic_unsigned.all;

Was kann es für Fehler verursachen?


Gruß

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> USE ieee.std_logic_unsigned.all;
Was kann es für Fehler verursachen?


z.B. diesen hier:
$ vlib work
$ vcom *.vhd

Model Technology ModelSim XE III vcom 6.2g Compiler 2007.02 Feb 22 2007
-- Loading package standard
-- Loading package std_logic_1164
-- Loading package std_logic_arith
-- Loading package std_logic_unsigned
-- Loading package numeric_std
-- Compiling entity flanken_detektierung_ad_wandler
-- Compiling architecture behavioral of flanken_detektierung_ad_wandler
** Error: ad.vhd(71): Subprogram '>' is ambiguous. Suitable definitions exist in packages 'std_logic_1164' and 'std_logic_unsigned'.
** Error: ad.vhd(71):    (Use the '-explicit' option to disable the previous error check.)

Dein Modul läßt sich gar nicht compilieren :-/

Duke

Autor: Duke Scarring (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Definiere sowas vom Typ unsigned:
 Signal Maximal_Analog_Amplitude : STD_LOGIC_vector (11 downto 0):="000000000000";
Dann kannst Du damit auch sinvoll rechnen und vergleichen.

Im Anhang mal das gefixte Modul. Ob der Simuli der Testbnech sinnvoll 
ist, kann ich nicht entscheiden. Anererseits sieht die Simulation 
prinzipiell nicht ganz schlecht aus.

Duke

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

sorry der Fehler lag im Code hatte erst gesendet ohne zu komplieren
  Schieben :process (Clk_20Mhz_Flanken_Detektierung )
    begin
      if falling_edge (Clk_20Mhz_Flanken_Detektierung ) then
        Flanken_Detektierung_Zwischenpuffer <= Eingang_Flanken_Detektierung_AD_Wandler ;
        Aktuelle_Analoge_Amplitude       <=  Flanken_Detektierung_Zwischenpuffer;
        if Enable_Trigger = '0' then                            --  WENN FLANKE ERKANNT WIRD DIE MAXIMALE ERKANNTE AMPLITUDE WIEDER AUF NULL GESETZT
          Maximal_Analog_Amplitude <= "000000000000";                --  
        else
          if Aktuelle_Analoge_Amplitude > Maximal_Analog_Amplitude then
            Maximal_Analog_Amplitude <= Aktuelle_Analoge_Amplitude;
          else
            Maximal_Analog_Amplitude <= Maximal_Analog_Amplitude ;
          end if;
        end if;
    end if; -- HIER WAR DER FEHLER HATTE END IF VERGESSEN :( SORRY
end process Schieben ;


Hm... also kein Fehler gefunden?

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if Enable_Trigger = '0' then      --  WENN FLANKE ERKANNT

In der Simulation ist der ständig 0, so dass auch ständig zurückgesetzt 
wird...

Duke

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja aber warum ist das so?? :)

Autor: Duke Scarring (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Dafür schaut man sich an, wo das Signal getrieben wird: im Prozess 
Totzeit
Also steckt dort die Ursache/der Fehler.

Ich habe spaßeshalber mal den elsif-Zweig abegeändert:
    elsif cnt <= 19999 then           -- HIER TOTZEIT FUER 1 msek, KEINE  
      output_enable  <= '1';          -- 
      Enable_Trigger <= '1';
      cnt <=cnt+1;

Danach sah es ganz gut aus.

Duke

P.S.: Wo darf ich die Rechnung hinschicken? ;-)

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:)

Aber so ganz verstehe ich das nicht. Ich verwende für den Schmitt 
trigger das Signal
 Enable_Trigger 
, d.h Wenn Enable_Trigger = '1' darf der Schmitt trigger loslaufen.

Wenn der Schmitt trigger eine Flanke erkannt hat, soll das 
Enable_Trigger für 1 milisekunde auf 0 gesetzt werden daher das cnt <= 
19999 Enable_Trigger = '0'....und dannach wieder auf '1' gesetzt werden.

Zusammengefasst Enable_Trigger = '1' dann ist der Schmitt Trigger 
scharf. Wenn Schmitt trigger eine Flanke erkannt hat schaltet er das 
Enable_Trigger auf 0 für eine milisekunde aus. in der Zeit können 
signale kommen werden aber nicht von schmitt trigger erkannt.


Hm?????



P.s Kann die Rechnung auf in Form von einer Schokolade gesendet werden 
:)

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat den niemand eine Idee? Ich verstehe es nicht warum in der Simulation 
das Enable_Trigger ständig auf null ist (augeschlossen von der obigen 
korrektur) da der Enable_Trigger nur nach einer erkannten flanke für 1 
msek auf null gehen soll.

Und das beste ist das es auf dem Oszi funktioniert, ich gebe ein 
kontinuierliches Rechtecksignal, und der ausgang reagiert auch immer nur 
flanken in abstand von 1 msek....

D.h in der Realität funktioniert es aber nicht in der simulation...

:(

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.