www.mikrocontroller.net

Forum: FPGA, VHDL & Co. for loop VHDL mit Flankentriggerung lässt sich nicht übersetzen.


Autor: Sven S. (boldie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich arbeite mich gerade in VHD ein, um ein CPLD XC9536CL zu 
programmieren. Ich möchte von einem Vektor jeweils bei einer steigenden 
Flanke dies zwischenspeichern. Um das ganze nicht 8 (der Vekotr ist 7 
downto 0) mal schreiben zu müssen, wollte ich die for Schleife 
einsetzen.

Das ganze funktioniert nicht, und ich bekomme folgende Fehlermeldung, 
aus der ich auch mit google nicht schlau wurde:

Line 74. Value i is not static.
Line 72. Actual associated with Formal signal is not a static signal 
name. (LRM 2.1.1.2)
-->

Wenn ich die Zeilen 72 und 74 auskommentiere, dann funktioniert es, 
allerdings natürlich nicht so, wie ich es gerne hätte.

process( SPDIFIn )
begin
  for i in 0 to 7 loop
    if rising_edge( SPDIFIn(i) ) then -- line 72
    SPDIFActive(i) <= '1';
    end if; --line 74
  end loop;
end process;

Kann mir jemand einen Tip geben, wie man das effizient schreibt, ohne 
die Zeilen 8 mal zu schreiben? Meines Wissens wird ja so eine for loop 
sozusgane geunrollt und dann sollte das ja gehen. So wie es geht, wenn 
ich die Zeilen auskommentiere.

* Boldie

Autor: SchöneWelt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend,

also du darfst rising_edge nicht für jedes x beliebige Signal verwenden, 
sondern nur für clocks. Eine Edge Detection bekommst du bei vorhanden 
clock so hin:
signal s_signal       : std_logic;
signal s_signal_delay : std_logic;

begin

process(clk)
begin
  if rising_edge(clk) then
    s_signal_delay <= s_signal;
    if s_signal_delay = '0' and s_signal = '1' then -- rising edge
      -- code
    end if;

    for i in 0 to 8 loop
      -- code
    end loop;
  end if;
end process;

Sprich, du musst dein Asynchrones/Synchrones Signal in eine Clock Domain 
eintakten, und dann mit einem FlipFlop verzögern. Wenn das Signal vor 
und nach dem FlipFlop verschieden sind hast du eine steigende/fallende 
Flanke an diesem Signal

das Konstrukt mit For Loop stimmt! Wenn du mein Beispiel mit 
std_logic_vector verwendest sollte es synthetisierbar sein (ohne 
rising_edge)

Gruß

Autor: Sven S. (boldie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

normalerweise taktet man das ein, das stimmt. Vielleicht sollte ich 
genauer beschreiben, was ich vor habe:

Ich möchte eine Signaldetektion haben, die mir angibt, ob ein Signal 
aktiv ist. Hierfür möchte ich einen realtiv langsamen Gruntakt verwenden 
(ca. 1 kHz oder noch geringer) um Signale zu erkennen, die flexibel in 
der Taktrate (1 - 15 MHz) sind. Ich möchte allerdings den CPLD nicht 
unbedingt so hoch takten, da ich den Takt für nichts andere benötige und 
nur wissen möchte, ob ein Signal aktiv ist oder nicht.

Dafür reicht es mir ja, wenn ich mit einem FF auf eine Flanke vom Signal 
triggere und das dann mittels eines weiteren FF einsynchronisiere und 
gleichzeitig das EingangsFF per asynchronen Reset zurücksetzte. So wie 
man eine Spike-Detektion baut. Die Idee wollte ich wie hier umsetzten: 
http://www.lothar-miller.de/s9y/categories/19-SpikePuls

Nur ist mir nicht ganz klar, warum man das nicht in eine for Schleife 
reinbauen kann.

Grüße

Autor: berndl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...sollte das nicht ein 'generate' anstatt 'loop' sein?

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum es jetzt genau nicht geht, könnte ich jetzt auf die schnelle auch 
nicht sagen, aber die Fehlermeldungen verweisen auf die Sprachreferenz 
selbst.
Mit generate sollte es aber gehen :
Zuerst einen einzelnen Detektor konstruieren :
entity edge_detect is
    
    port (
        clk : in std_logic;
        reset : in std_logic;
        sig_active : out std_logic);

end edge_detect;

architecture rtl of edge_detect is
begin  -- rtl
process (clk, reset)
begin  -- process
    if reset = '1' then                 -- asynchronous reset (active low)
        sig_active <= '0'; 
    elsif rising_edge(clk) then 
        sig_active <= '1';
    end if;
end process;
end rtl;

und dann 8 solche Detektoren erzeugen
detectors: for i in 0 to 7 generate
       detect: edge_detect
        port map (
            clk    => SPDIFin(i),
            reset  => Reset(i),
            sig_active => SPDActive(i));
end generate dd;

Autor: Sven S. (boldie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!

Ja, so funktioniert das, allerdings muss man dann in der architecture 
noch eine component vom edge_detect deklarieren, das verstehe ich zwar 
nicht so ganz, was das soll, dass ich eine component in der anderen 
architecture machen muss, aber es geht.

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.