Forum: FPGA, VHDL & Co. Variablenfehler


von VHDL-Neuling (Gast)


Lesenswert?

Ich bin blutiger Anfänger in Sachen VHDL und bekomme bestimmt die 
Schelten um die Ohren gehauen. Ich versuche mich aber trotzdem mal, in 
der Hoffnung, dass ja jeder mal ganz klein angefangen hat :)

Ich möchte einfach nur einen Block programmieren, der am Anfang (bei 0) 
für einen Takt einen Highpegel ausgibt (SOP) und am Ende (bei 4095) 
ebenfalls für einen Takt einen Highpegel (EOP) ausgibt. Wenn EOP 
ausgegeben wurde, soll es wieder von vorne losgehen.

Folgendes habe ich mir zusammengeschrieben:
1
architecture Aufbau of counter is
2
3
begin
4
5
  process(CLK)
6
  shared VARIABLE i: integer :=0;
7
  begin
8
9
    start:FOR i IN 0 TO 4095 LOOP
10
        IF (CLK'event and CLK='1') THEN
11
          IF (i=0) THEN
12
            EOP <= '0'; -- end of packet 'last packet'
13
            SOP <= '1'; -- start of packet 'new packet'
14
          ELSIF (i=1) THEN
15
            SOP <= '0';
16
          ELSIF (i=4095) THEN
17
            EOP <= '1';
18
            i := 0;
19
            NEXT start;
20
          END IF;
21
        ELSE
22
        i:=i+1;
23
        END IF;        
24
      END LOOP;
25
      
26
  end process;
27
end architecture;

Jetzt bekomme ich immer die Fehlermeldung, dass i eine "variable or 
aggregate" sein muss. Habe jetzt soviel gelesen und komme einfach nicht 
weiter. Daher hoffe ich auf eure professionellen Ratschläge :)

Vielen Dank schonmal im Voraus
Lars

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>    start:FOR i IN 0 TO 4095 LOOP
Diese For-Schleife macht in VHDL nicht das, was du z.B. von Basic oder C 
her kennst.

So geht es eher:
1
architecture Aufbau of counter is
2
signal i: integer :=0;
3
4
begin
5
  process(CLK) begin
6
        if rising_edge(clk) then        -- <-- besser so
7
--        IF (CLK'event and CLK='1') THEN -- mit einer steigenden Flanke
8
          i <= i+1;                     -- den Zähler erhöhen
9
          IF (i=0) THEN
10
            EOP <= '0'; -- end of packet 'last packet'
11
            SOP <= '1'; -- start of packet 'new packet'
12
          ELSIF (i=1) THEN
13
            SOP <= '0';
14
          ELSIF (i=4095) THEN
15
            EOP <= '1';
16
            i <= 0;
17
          END IF;
18
        END IF;        
19
  end process;
20
end architecture;

Sieh dir mal ein Buch zu dem Thema an.
Mein Tipp: VHDL-Synthese von Reichardt/Schwarz
In dem wird nicht VHDL erklärt (wie in so vielen anderen). Es werden 
explizit VHDL-Templates für die Synthese vorgestellt und abgehandelt.

von VHDL-Neuling (Gast)


Lesenswert?

Danke für die rasendschnelle Antwort! Ich hatte die FOR-Schleife aus 
einem Tutorial, daher dachte ich dass diese so funktioniert.
1
architecture Aufbau of counter is
2
signal i: integer :=0;
3
4
begin
5
  process(CLK) begin
6
start:   if rising_edge(clk) then        -- <-- besser so
7
--        IF (CLK'event and CLK='1') THEN -- mit einer steigenden Flanke
8
          i <= i+1;                     -- den Zähler erhöhen
9
          IF (i=1) THEN
10
            EOP <= '0'; -- end of packet 'last packet'
11
            SOP <= '1'; -- start of packet 'new packet'
12
          ELSIF (i=2) THEN
13
            SOP <= '0';
14
          ELSIF (i=4096) THEN
15
            EOP <= '1';
16
            i <= 0;
17
            NEXT start;
18
          END IF;
19
        END IF;        
20
  end process;
21
end architecture;
22
-- Funktionsweise
23
--           SOP                 SOP
24
-- __________|-|_________________|-|_______
25
-- _______|-|_________________|-|_________
26
--        EOP                 EOP
27
--            1..          ..4096 1..

So ich hab mal die Funktionsweise beschrieben und die Indizes geändert, 
da es ja jetzt keine If-Abfrage mit "=0" mehr geben kann.

Funktioniert das "NEXT" denn so? Es soll ja sofort wieder vorne 
angefangen werden.

Gruß,
Lars

von Der Besucher (Gast)


Lesenswert?

Gute Lösung. Ich würde es noch etwas optimieren.
VHDL Neuling: rising_edge(clk) besagt schon, das zu jeder steigenden 
flanke der clock alles innerhalb der if-anweisung ausgeführt wird.
NEXT ist nur für das vorzeitige verlassen eines schleifendurchlaufes. 
hat hier irgendwie gar nix zu suchen.

Der Besucher
1
architecture Aufbau of counter is
2
signal i: std_logic_vector(11 downto 0) := (others => '0');
3
4
begin
5
  process(CLK) begin
6
        if rising_edge(clk) then
7
         -- defaultanweisungen 
8
          i <= i+1;   -- den Zähler erhöhen
9
          EOP <= '0'; -- end of packet 'last packet'
10
          SOP <= '0';
11
          -- ende defaultanweisungen
12
          IF (i=0) THEN
13
            SOP <= '1'; -- start of packet 'new packet'
14
          ELSIF (i=4095) THEN
15
            EOP <= '1';
16
          --  i <= 0; -- kann man jetzt weglassen (Ausnutzung des überlaufs)
17
          END IF;
18
        END IF;        
19
  end process;
20
end architecture;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ach richtig, das ist ungünstig:
1
signal i: integer :=0;
denn damit werden 32 Bit für den Zähler verwendet.

Besser wäre so:
1
signal i: integer range 0 to 4095 :=0;


@ Der Besucher
Ich würde das nicht mit std_logic_vector machen, weil dann je nach LIB 
das nicht geht:
1
ELSIF (i=4095) THEN

Beim Zähler mit  integer range 0 to 4095  wird (genau wie beim Vektor) 
auch ein ordinärer Überlauf synthetisiert.


EDIT:
> Ich hatte die FOR-Schleife aus einem Tutorial,
> daher dachte ich dass diese so funktioniert.
Für die Simulation wäre diese Schleife durchaus tauglich. Aber auf 
einen programmierbaren Baustein bekommst du das nicht implementiert.

von Der Besucher (Gast)


Lesenswert?

> @ Der Besucher
> Ich würde das nicht mit std_logic_vector machen, weil dann je nach LIB
> das nicht geht:
>
> ELSIF (i=4095) THEN

Stimmt, funktioniert dann nicht wenn man nicht die richtigen LIBs 
verwendet.
Ich sehe nur den Vorteil, das man sofort ein Gefühl für die Bitbreiten 
bekommt, und damit später für die vewendeten Zählerflipflops. Aber 
sicherlich geschmackssache.

Der Besucher

von VHDL-Neuling (Gast)


Lesenswert?

Vielen Dank!

Die "Besucher"-Variante hat mich schon etwas beeindruckt, da muss man 
erstmal drauf kommen. ;)

Aber damit ihr mir nicht in unerreichte Fachsimpeleien entschwindet, 
habe ich mal noch eine Anfängerfrage:

Ich erzeuge aus dem Quelltext ein HDL-Design-File, baue das in mein 
Design ein und programmiere dann mein Cyclone III-Board. Da ist es doch 
egal welche Variante ich benutze, oder? (mit vector oder mit range)

Lars :o)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> das man sofort ein Gefühl für die Bitbreiten
> bekommt, und damit später für die vewendeten Zählerflipflops.
Das stimmt allerdings ...

@  VHDL-Neuling
Merksatz:
Über den Daumen gepeilt gilt
       1,000 = 10 Bit = 10 Zählerflipflops
   1,000,000 = 20 Bit = 20 Zählerflipflops
1000,000,000 = 30 bit = 30 Zählerflipflops
  integer    = 32 Bit = 32 Zählerflipflops

von VHDL-Neuling (Gast)


Lesenswert?

Ah ok! Vielen vielen Dank! Ihr habt mir super geholfen und ich hab 
einiges gelernt.

Ich werde mich wieder melden ;o)

Gruß vom Lars

von VHDL-Neuling (Gast)


Lesenswert?

Mir ist doch noch etwas aufgefallen:

Gibt es hierbei überhaupt jemals ein i=0? Wird das i nicht schon beim 
ersten Durchlauf vor der Abfrage auf 1 erhöht?
1
if rising_edge(clk) then
2
         -- defaultanweisungen 
3
          i <= i+1;   -- den Zähler erhöhen
4
          EOP <= '0'; 
5
          SOP <= '0';
6
          -- ende defaultanweisungen
7
          IF (i=0) THEN
8
            SOP <= '1'; -- start of packet
9
          ELSIF (i=4095) THEN
10
            EOP <= '1'; -- end of packet
11
          --  i <= 0; -- kann man jetzt weglassen (Ausnutzung des überlaufs bei 'range 0 to 4095')
12
          END IF;
13
END IF;

von Der Besucher (Gast)


Lesenswert?

@VHDL-Neuling
Löse dich bitte von der "sequentiellen Denkweise". Innerhalb des 
getakteten Processes werden alle Signalezuweisungen parallel ausgeführt.
So greift man noch auf den alten Wert von i zu (also 0).

Gab es da nicht vor ein paar Tagen eine Anmerkung, das solche Dinge 
uninteressant für Einsteiger sind ;)

Der Besucher

von Der L. (vhdl-neuling)


Lesenswert?

Ok, ich werde mich lösen. Ich finde solche Dinge ziemlich interessant :)

Danke, Lars

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Gab es da nicht vor ein paar Tagen eine Anmerkung, das solche Dinge
> uninteressant für Einsteiger sind ;)
Das war im Beitrag "Re: Zwei Fragen zu VHDL"

Ohne weiteren Kommentar  ;-)

von Der L. (vhdl-neuling)


Lesenswert?

Ich möchte jetzt, dass dieses "Hochzählen" nur passiert, wenn ein 
weiteres Eingangssignal high ist. Ist das so machbar?
1
if rising_edge(clk) then
2
  
3
  if (SIGNAL='1') then -- NEU
4
5
6
         -- defaultanweisungen 
7
          i <= i+1;   -- den Zähler erhöhen
8
          EOP <= '0'; 
9
          SOP <= '0';
10
          -- ende defaultanweisungen
11
          IF (i=0) THEN
12
            SOP <= '1'; -- start of packet
13
          ELSIF (i=4095) THEN
14
            EOP <= '1'; -- end of packet
15
          END IF;
16
17
   END IF; -- NEU
18
19
END IF;


Vor allem: Wenn das Signal high war und während des Hochzählens low 
wird, bricht er dann das Zählen ab?

Lars

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

> if rising_edge(clk) then
das sagt deinem Design: bei der steigenden Taktflanke tue etwas.
D.h. was danach passiert ist dem Prozess egal, der Zustand zur 
Steigenden Flanke wird durch Speicherelemente "eingefroren".
Ich würde ein Signal nicht SIGNAL nene, das ist ein schlüsselwort und 
man kommt schnell durcheiander.
Du würdest in C ja auch einen Integervariable nicht int nenen in der 
Art:
1
int int;
2
int = 0;
das gibt nur durcheinander :)

von Der L. (vhdl-neuling)


Lesenswert?

Stimmt :)

Ich wollte das eigentlich auch nicht Signal nennen, nur hier damit jeder 
schnell sieht was ich meine.

Also verstehe ich das richtig und es wäre besser, wenn ich die Abfragen 
umdrehe?

Also:
1
if (Eingang='1') then
2
  if rising_edge(clk) then
3
 .........
4
  end if;
5
end if;

So würde das Hochzählen doch erst beginnen, wenn der Eingang gesetzt 
ist?!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Der Lars wrote:
>
1
> if (Eingang='1') then
2
>   if rising_edge(clk) then
3
>  .........
4
>   end if;
5
> end if;
6
>
>
> So würde das Hochzählen doch erst beginnen, wenn der Eingang gesetzt
> ist?!

Hast du sowas schon mal in einem Buch (oder sonstwo) gesehen?
Wenn dann so:
1
 if rising_edge(clk) then
2
   if (Eingang='1') then
3
     .........
4
   end if;
5
 end if;
Das ist ein FF mit Enable.

von Der L. (vhdl-neuling)


Lesenswert?

Nein, das entsprang meinem eigenen Hirn :)

Tut mir leid, wenn ich manchmal "blöde" Fragen stelle, aber mich in die 
FPGA-Programmierung reinzudenken, fällt mir noch etwas schwer.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> aber mich in die FPGA-Programmierung reinzudenken,
> fällt mir noch etwas schwer.
Du mußt nur im Hinterkopf haben, dass sich deine Beschreibung auf die 
Baugruppen eins FPGAs abbilden lassen muß. Und dort gibt es (grob 
gesagt) nur Logik und FFs (und Latches, yeah).

>  das entsprang meinem eigenen Hirn :)
Deine Beschreibung beschreibt zwar ein grundsätzlich anderes Verhalten, 
sie würde aber von den Designtools in meine umgesetzt werden.
Siehe dort: http://www.lothar-miller.de/s9y/categories/6-Clock-Enable
Allerdings würde dann die Umsetzung nicht mehr zu deiner Denkweise 
passen, und das kann ein böses Erwachen geben...

von Der L. (vhdl-neuling)


Lesenswert?

Danke!

Ich komme mit jedem hilfreichen Beitrag weiter in meiner Denkweise ;0)

von Klugscheisser (Gast)


Lesenswert?

@ Lothar Miller

Ich habe zu dem Problem, wie ein FF beschrieben werden sollte noch eine 
Frage:
Du hast ja auch auf Deine Webseite verwiesen und dort drei Varianten 
aufgeschrieben.

Du sagst abschliessend, das nur die erste (erst clock, dann enable) 
verwendet werden sollte, da die anderen überraschend seien.

Nimm mal an, das ich Überraschungen liebe und auch anderen gerne welche 
bereite (auch dem FPGA): Gibt es technische Gründe, warum die anderen 
Varianten nicht genommen werden sollten? Wenn ich Dich recht verstehe 
sind sie doch funktional aquivalent?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Gibt es technische Gründe, warum die anderen
> Varianten nicht genommen werden sollten?
1.) Die Design-Tools sind zwar schon recht gut, aber für solche 
Beschreibungen noch nicht optimiert.
Ergo: Nur wenn man sich an die Standard-Schreibweise hält, kann man 
auch Standard-Ergebnisse erwarten.

2.) Bei diesen wirklich simplen Beispielen kann immer nur 1 Signal als 
Takt-Enable beschrieben werden. Das oben beschriebene einfache Beispiel 
mag ja so noch aufgehen, aber schon bei diesem (nicht viel 
komplizierteren) Fall geht es in die Hose:
1
 if rising_edge(clk) then
2
   if    (Eingang1='1') then
3
       .........
4
   elsif (Eingang2='1') then
5
       .........
6
   elsif (Eingang3='1') then
7
       .........
8
   end if;
9
 end if;

Wie würdest du das mit dieser anderen Clock-Enable Schreibweise 
ausdrücken?


Na also: wenn schon so etwas einfaches nicht mehr geht, warum sollte man 
sich so eine Schreibweise angewöhnen?

von Klugscheisser (Gast)


Lesenswert?

Bitte verzeihe mir, wenn ich auf eine sichtlich um Klärung bemühte 
Antwort Deinerseits doch noch mal rückfragen möchte:

>> Gibt es technische Gründe, warum die anderen
>> Varianten nicht genommen werden sollten?
>1.) Die Design-Tools sind zwar schon recht gut, aber für solche
>Beschreibungen noch nicht optimiert.
>Ergo: Nur wenn man sich an die Standard-Schreibweise hält, kann man
>auch Standard-Ergebnisse erwarten.

Soweit ich erkennen kann ersetzt Du hier den Grund "überraschend" durch 
"Design-Tools nicht geeignet" aber auch durch "nicht-Standard".

Welche Tools können die fragliche Schreibweise (mit Enable erst nach 
Clock) nicht? Welchem Standard entspricht diese Schreibweise nicht?

Stimmen wir eingentlich soweit überein, das all drei Schreibweisen, ein 
FF mit Enable beschreiben?


Mit Deinem Beispiel kann ich in der Form nichts anfangen. Mehrere Enable 
anstelle eines hört sich für mich erstmal nach einem "oder" zwischen 
mehreren Enable an. Dein Beispiel aber suggeriert, das je nach gewähltem 
Enabel verschiedene Aktionen erfolgen sollen, also sowas wie verschieden 
FFs die an dem selben Takt hängen. Das würde man (ich) sowieso als 
verschiedene Entitäten schreiben und nicht als eine. Was meinst Du dazu?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Bitte verzeihe mir ...
Deine Bitte sei dir gewährt  ;-)

> Mehrere Enable anstelle eines hört sich für mich erstmal nach
> einem "oder" zwischen mehreren Enable an.
Nein, wie aus der Beschreibung hervorgeht, sind es mehrere Enable 
innerhalb eines getakteten Prozesses. Machen wir an mein Beispiel noch 
etwas Speck und lassen den Prozess auch mal was tun (nicht viel, aber 
wenigstens irgendwas):
1
signal counter : unsigned (3 downto 0);
2
  :
3
process (clk) begin
4
  if rising_edge(clk) then
5
    if    (Eingang1='1') then
6
       counter <= "0011";
7
    elsif (Eingang2='1') then
8
       counter <= "1011";
9
    elsif (Eingang3='1') then
10
       counter <= "1001";
11
    end if;
12
  end if;
13
end process;


Wie könntest du dir jetzt eine Beschreibung mit "aussenliegenden" Enable 
vorstellen?

Einfach auf mehrere Prozesse aufteilen? So etwa:
1
signal counter : unsigned (3 downto 0);
2
  :
3
  :
4
process (clk) begin
5
  if (Eingang1='1') then
6
    if rising_edge(clk) then
7
       counter <= "0011";
8
    end if;
9
  end if;
10
end process;
11
12
process (clk) begin
13
  if (Eingang2='1') then
14
    if rising_edge(clk) then
15
       counter <= "1011";
16
    end if;
17
  end if;
18
end process;
19
20
process (clk) begin
21
  if (Eingang3='1') then
22
    if rising_edge(clk) then
23
       counter <= "1001";
24
    end if;
25
  end if;
26
end process;
Ja, sowas gibt den berühmten Multisource-Fehler :-(

Dann also in einem Prozess und die Enable verodert?
Also so:
1
signal counter : unsigned (3 downto 0);
2
  :
3
process (clk) begin
4
  if (Eingang1='1' or Eingang2='1' or Eingang3='1') then
5
     if rising_edge(clk) then
6
       :
7
       :
8
     end if; 
9
  end if;
10
end process;
Ist da in etwa dein Vorschlag?


Damit ist nichts gewonnen, denn innerhalb des Prozesses müsste für die 
Zuweisung jetzt noch einmal unterschieden werden. Dann wird daraus also:
1
process (clk) begin
2
  if (Eingang1='1' or Eingang2='1' or Eingang3='1') then
3
    if rising_edge(clk) then
4
       if    (Eingang1='1') then
5
          counter <= "0011";
6
       elsif (Eingang2='1') then
7
          counter <= "1011";
8
       elsif (Eingang3='1') then
9
          counter <= "1001";
10
       end if;
11
    end if;
12
  end if;
13
end process;

> Welchem Standard entspricht diese Schreibweise nicht?
Sie entspricht nicht dem Quasi-Industrie-Standard, den die 
Synthesetools verwenden und umsetzen können.

Ich habe dieses Wort Standard extra kursiv geschlagen, damit man nicht 
z.B. den VHDL-Standard meint. Ich kann hier mit einem kleinen 
VHDL-Dreizeiler etwas beschreiben, das zwar problemlos simuliert aber 
garantiert nicht in ein FPGA implementiert werden kann.

Nehmen wir z.B. nur mal das hier:
1
   counter <= "1001" after 2000 ms;
Vollkommen VHDL-konform. Derzeit nicht implementierbar.

von Der Praktiker (Gast)


Lesenswert?

Aus langjähriger Erfahrung: Synthese-Tools sind doof !

Gut - nicht vollkommen doof, aber doof !

Wenn Du 'gute' Ergebnisse haben willst, solltest Du Deinen Dialekt
so 'einfach' wie möglich gestalten: je mehr Menschen auf dieser Welt
ein FlipFlop mit Reset und Clock-Enable EXAKT gleich beschreiben,
desto größer ist die Wahrscheinlichkeit, daß alle SW-Bugs die DIESE
Beschreibung betreffen, bereits gefunden wurden.

Je exotischer dein 'Style' desto größer die Wahrscheinlichkeit,
daß DU derjenige bist, der auf einen Bug aufmerksam werden wird !!!

Also: "Standard" haiß hier nicht IEEE oder so was, sondern,
"Was die meisten Anwender verwenden"

von Klaus F. (kfalser)


Lesenswert?

> Sie entspricht nicht dem Quasi-Industrie-Standard, den die
> Synthesetools verwenden und umsetzen können.

Es gibt schon einen offiziellen Standard : IEEE 1076.6.
Niemand beruft sich aber explizit darauf (jedenfalls wäre es mir bis 
jetzt nie aufgefallen), und so schnell nachschauen kann man darin auch 
nicht, weil man ihn bezahlen muß.

von Klugscheisser (Gast)


Lesenswert?

@ Lothar Miller

Also, ich möchte wirklich gerne verstehen, was es damit (mit meiner 
ursprünglichen Frage) auf sich hat.

Es würde mir helfen, wenn Du bitte meine nachfolgende Zusammenfassung 
der Fragestellung und meine Wiedergabe Deiner Antwort lesen würdest und 
sie (falls sie richtig ist) kurz bestätigst.

Die ursprüngliche Frage bezog sich darauf, ob das enable innerhalb oder 
ausserhalb der clk-Abfrage sein darf oder nicht. Soweit ich auch Deinen 
Text auf Deiner Webseite gelesen habe sind beide bzw. drei Varianten 
funktional äquivalent und werden mit dem Tool das Du dazu verwendet hast 
auch äquivalent synthetisiert. Soweit so gut.

Nun hast Du geschrieben, das die Varianten mit enable ausserhalb 
"überraschend" bzw. "nicht-Standard" wären. Das wollte ich hinterfragen.

Wenn ich Deine zweite Antwort nun richtig verstehe, das meintest Du 
nicht, das diese anderen Schreibweisen einem Standard widersprechen, 
sondern vielmehr "unüblich" sind und Du (aus Erfahrung begründete) 
Zweifel hast, das diese grundsätzlich die äquivalente Funktion ergeben. 
(Die kursive Hervorhebung habe ich leider nicht so verstanden.).

Ist das so richtig?

Wenn Du mir bitte noch die Bemerkung erlaubst, ist mir durchaus klar, 
das Dein Beispiel eine andere Beurteilung erfordert. Ich hatte ja auch 
gesondert daruf hingewiesen das Dein Beispiel (vom 27.01.2009 00:46) aus 
meiner Sicht nur dann Sinn macht, wenn in den if-zweigen 
unterschiedliche Aktionen erfolgen.

Stimmst Du mir zu, wenn ich behaupte, das der Vergleich der drei 
Alternativen nur dann Sinn macht, wenn innerhalb der IF-Abfragen auch 
nur Aktionen erfolgen die sich mit der übergeordneten Bedingung 
vertragen (sich also z.B. gleichermaßen synthetisieren lassen)?

Du aber hast mit Deinem Beispiel (noch mehr in der zweiten Antwort) eine 
Variante eröffnet, die sich, auch nach meinen Kenntnisstand, nicht mit 
allen drei Varianten verträgt.

Ich meine aber Deinem Beispiel zumindest soviel entnehmen zu dürfen, das 
es sich im Sinne einer inkrementellen Bearbeitung der Beschreibung 
anbietet, die enable-Bedingung nach innen zu legen, weil es dann 
einfacher ist, weitere Bedingungen ohne überflüsse Schreibarbeit 
hinzuzufügen. (Und weil es "üblicher" ist).

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Ist das so richtig?
FULL ACK


> Stimmst Du mir zu, wenn ich behaupte, das der Vergleich der drei
> Alternativen nur dann Sinn macht, wenn innerhalb der IF-Abfragen auch
> nur Aktionen erfolgen die sich mit der übergeordneten Bedingung
> vertragen (sich also z.B. gleichermaßen synthetisieren lassen)?
## Ich bin mir nicht sicher ob ich den Kern deiner Frage erfasst habe 
:-/
## Aber hier ein Antwortversuch  ;-)

Ich meine, das Problem ist eher, dass genau dieser Sonderfall in der 
Praxis kaum vertreten ist: Enable-Signale, die als eine einzige 
If-Abfrage innerhalb eines getakteten Prozesses verwendet werden.

Also sowas z.B. stellt in der Praxis (in seiner Schlichtheit) den 
Ausnahmefall dar:
1
if (Enable='1') then
2
   if rising_edge(clk) then
3
      cnt<=cnt+1;
4
   end if;
5
end if;


Wenn ich das Original von Lars mal nehme und die Punkte durch eine 
Up-Down-Zähler-Funktion ersetze, wie sieht dann das Enable für jedes 
einzelne Zähler-FF aus?
1
if (Enable='1') then          -- enable counter
2
  if rising_edge(clk) then
3
     if   (up='1') then       -- enable up
4
        cnt<=cnt+1;
5
     elsif(dn='1') then       -- enable down
6
        cnt<= cnt-1;
7
     end if;
8
  end if;
9
end if;
Ein Counter-Enable ausserhalb und zwei Richtungs-Enable innerhalb des 
Taktes? Kann das synthetisiert werden?
Das müsste man erst mal ausprobieren...

Üblicherweise wird es aber so geschrieben:
1
if rising_edge(clk) then
2
  if (Enable='1') then
3
     if   (up='1') then
4
        cnt<=cnt+1;
5
     elsif(dn='1') then
6
        cnt<= cnt-1;
7
     end if;
8
  end if;
9
end if;
Und das wird klappen, weil es jeder so (oder annähernd so) macht.

von daniel (Gast)


Lesenswert?

dumme Frage meinerseits ...

@Lothar
1
if rising_edge(clk) then
2
  if (Enable='1') then
3
     if   (up='1') then
4
        cnt<=cnt+1;
5
     elsif(dn='1') then
6
        cnt<= cnt-1;
7
     end if;
8
  end if;
9
end if;

ist da nicht ein Latch drin?
Flanke geht hoch, up ist 0, dn ist 0
da cnt in der synchronen Umgebung zugewiesen wird,
wird es DFF, aber genaugenommen müsste doch im
oberen Fall Signal von Q auf D zurückgeführt werden.
bzw nicht auf D, sondern auf CE, um Q einzufrieren.
Der Takt hämmert ja am clock Eingang ständig und
würde andere Werte reinschieben.

grüsse.

ps:
1
if rising_edge(clk) and enable='1' then
2
3
end if;

gibt es auch noch

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

daniel wrote:
> ist da nicht ein Latch drin?
> Flanke geht hoch....
Nein, ein Latch ist per Definition kein getaktetes Bauelement. Deshalb 
können in einem vollständig synchronen Prozess keine Latches entstehen.
Das nachfolgende wäre ein Latch (wird aus Versehen auch gern gemacht):
1
if (clk='1') then  -- hier fehlt das 'event
2
   if (enable='1') then
3
      if   (up='1') then
4
         cnt<=cnt+1;
5
      elsif(dn='1') then
6
         cnt<=cnt-1;
7
      end if;
8
   end if;
9
end if;
Und als kleines Gimmick gibts hier auch noch eine kombinatorische 
Schleife. In diesem Fall einen Zähler, der mit maximaler Geschwindigkeit 
hoch- oder runterzählt wenn die Rahmenbedingungen stimmen (z.B. clk, 
enable, up = '1')    :-o


> ps:
>
1
> if rising_edge(clk) and enable='1' then
2
> 
3
> end if;
4
>
> gibt es auch noch
Ja, wurde von mir schon untersucht und dort am Rande angeführt:
Beitrag "Re: Variablenfehler"   ;-)

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.