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


von Sven S. (boldie)


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

von SchöneWelt (Gast)


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:
1
signal s_signal       : std_logic;
2
signal s_signal_delay : std_logic;
3
4
begin
5
6
process(clk)
7
begin
8
  if rising_edge(clk) then
9
    s_signal_delay <= s_signal;
10
    if s_signal_delay = '0' and s_signal = '1' then -- rising edge
11
      -- code
12
    end if;
13
14
    for i in 0 to 8 loop
15
      -- code
16
    end loop;
17
  end if;
18
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ß

von Sven S. (boldie)


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

von berndl (Gast)


Lesenswert?

...sollte das nicht ein 'generate' anstatt 'loop' sein?

von Klaus F. (kfalser)


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 :
1
entity edge_detect is
2
    
3
    port (
4
        clk : in std_logic;
5
        reset : in std_logic;
6
        sig_active : out std_logic);
7
8
end edge_detect;
9
10
architecture rtl of edge_detect is
11
begin  -- rtl
12
process (clk, reset)
13
begin  -- process
14
    if reset = '1' then                 -- asynchronous reset (active low)
15
        sig_active <= '0'; 
16
    elsif rising_edge(clk) then 
17
        sig_active <= '1';
18
    end if;
19
end process;
20
end rtl;

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

von Sven S. (boldie)


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.

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.