mikrocontroller.net

Forum: FPGA, VHDL & Co. Variablenfehler


Autor: VHDL-Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
architecture Aufbau of counter is

begin

  process(CLK)
  shared VARIABLE i: integer :=0;
  begin

    start:FOR i IN 0 TO 4095 LOOP
        IF (CLK'event and CLK='1') THEN
          IF (i=0) THEN
            EOP <= '0'; -- end of packet 'last packet'
            SOP <= '1'; -- start of packet 'new packet'
          ELSIF (i=1) THEN
            SOP <= '0';
          ELSIF (i=4095) THEN
            EOP <= '1';
            i := 0;
            NEXT start;
          END IF;
        ELSE
        i:=i+1;
        END IF;        
      END LOOP;
      
  end process;
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
architecture Aufbau of counter is
signal i: integer :=0;

begin
  process(CLK) begin
        if rising_edge(clk) then        -- <-- besser so
--        IF (CLK'event and CLK='1') THEN -- mit einer steigenden Flanke
          i <= i+1;                     -- den Zähler erhöhen
          IF (i=0) THEN
            EOP <= '0'; -- end of packet 'last packet'
            SOP <= '1'; -- start of packet 'new packet'
          ELSIF (i=1) THEN
            SOP <= '0';
          ELSIF (i=4095) THEN
            EOP <= '1';
            i <= 0;
          END IF;
        END IF;        
  end process;
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.

Autor: VHDL-Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die rasendschnelle Antwort! Ich hatte die FOR-Schleife aus 
einem Tutorial, daher dachte ich dass diese so funktioniert.
architecture Aufbau of counter is
signal i: integer :=0;

begin
  process(CLK) begin
start:   if rising_edge(clk) then        -- <-- besser so
--        IF (CLK'event and CLK='1') THEN -- mit einer steigenden Flanke
          i <= i+1;                     -- den Zähler erhöhen
          IF (i=1) THEN
            EOP <= '0'; -- end of packet 'last packet'
            SOP <= '1'; -- start of packet 'new packet'
          ELSIF (i=2) THEN
            SOP <= '0';
          ELSIF (i=4096) THEN
            EOP <= '1';
            i <= 0;
            NEXT start;
          END IF;
        END IF;        
  end process;
end architecture;
-- Funktionsweise
--           SOP                 SOP
-- __________|-|_________________|-|_______
-- _______|-|_________________|-|_________
--        EOP                 EOP
--            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

Autor: Der Besucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
architecture Aufbau of counter is
signal i: std_logic_vector(11 downto 0) := (others => '0');

begin
  process(CLK) begin
        if rising_edge(clk) then
         -- defaultanweisungen 
          i <= i+1;   -- den Zähler erhöhen
          EOP <= '0'; -- end of packet 'last packet'
          SOP <= '0';
          -- ende defaultanweisungen
          IF (i=0) THEN
            SOP <= '1'; -- start of packet 'new packet'
          ELSIF (i=4095) THEN
            EOP <= '1';
          --  i <= 0; -- kann man jetzt weglassen (Ausnutzung des überlaufs)
          END IF;
        END IF;        
  end process;
end architecture;

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

Besser wäre so:
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:
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.

Autor: Der Besucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: VHDL-Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: VHDL-Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: VHDL-Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?
if rising_edge(clk) then
         -- defaultanweisungen 
          i <= i+1;   -- den Zähler erhöhen
          EOP <= '0'; 
          SOP <= '0';
          -- ende defaultanweisungen
          IF (i=0) THEN
            SOP <= '1'; -- start of packet
          ELSIF (i=4095) THEN
            EOP <= '1'; -- end of packet
          --  i <= 0; -- kann man jetzt weglassen (Ausnutzung des überlaufs bei 'range 0 to 4095')
          END IF;
END IF;   

Autor: Der Besucher (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Der Lars (vhdl-neuling)
Datum:

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

Danke, Lars

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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  ;-)

Autor: Der Lars (vhdl-neuling)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich möchte jetzt, dass dieses "Hochzählen" nur passiert, wenn ein 
weiteres Eingangssignal high ist. Ist das so machbar?
if rising_edge(clk) then
  
  if (SIGNAL='1') then -- NEU


         -- defaultanweisungen 
          i <= i+1;   -- den Zähler erhöhen
          EOP <= '0'; 
          SOP <= '0';
          -- ende defaultanweisungen
          IF (i=0) THEN
            SOP <= '1'; -- start of packet
          ELSIF (i=4095) THEN
            EOP <= '1'; -- end of packet
          END IF;

   END IF; -- NEU

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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
int int;
int = 0;
das gibt nur durcheinander :)

Autor: Der Lars (vhdl-neuling)
Datum:

Bewertung
0 lesenswert
nicht 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:
if (Eingang='1') then
  if rising_edge(clk) then
 .........
  end if;
end if;

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Lars wrote:
>
> if (Eingang='1') then
>   if rising_edge(clk) then
>  .........
>   end if;
> end if;
> 
>
> 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:
 if rising_edge(clk) then
   if (Eingang='1') then
     .........
   end if;
 end if;
Das ist ein FF mit Enable.

Autor: Der Lars (vhdl-neuling)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Der Lars (vhdl-neuling)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!

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

Autor: Klugscheisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
 if rising_edge(clk) then
   if    (Eingang1='1') then
       .........
   elsif (Eingang2='1') then
       .........
   elsif (Eingang3='1') then
       .........
   end if;
 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?

Autor: Klugscheisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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):
signal counter : unsigned (3 downto 0);
  :
process (clk) begin
  if rising_edge(clk) then
    if    (Eingang1='1') then
       counter <= "0011";
    elsif (Eingang2='1') then
       counter <= "1011";
    elsif (Eingang3='1') then
       counter <= "1001";
    end if;
  end if;
end process;


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

Einfach auf mehrere Prozesse aufteilen? So etwa:
signal counter : unsigned (3 downto 0);
  :
  :
process (clk) begin
  if (Eingang1='1') then
    if rising_edge(clk) then
       counter <= "0011";
    end if;
  end if;
end process;

process (clk) begin
  if (Eingang2='1') then
    if rising_edge(clk) then
       counter <= "1011";
    end if;
  end if;
end process;

process (clk) begin
  if (Eingang3='1') then
    if rising_edge(clk) then
       counter <= "1001";
    end if;
  end if;
end process;
Ja, sowas gibt den berühmten Multisource-Fehler :-(

Dann also in einem Prozess und die Enable verodert?
Also so:
signal counter : unsigned (3 downto 0);
  :
process (clk) begin
  if (Eingang1='1' or Eingang2='1' or Eingang3='1') then
     if rising_edge(clk) then
       :
       :
     end if; 
  end if;
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:
process (clk) begin
  if (Eingang1='1' or Eingang2='1' or Eingang3='1') then
    if rising_edge(clk) then
       if    (Eingang1='1') then
          counter <= "0011";
       elsif (Eingang2='1') then
          counter <= "1011";
       elsif (Eingang3='1') then
          counter <= "1001";
       end if;
    end if;
  end if;
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:
   counter <= "1001" after 2000 ms;
Vollkommen VHDL-konform. Derzeit nicht implementierbar.

Autor: Der Praktiker (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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"

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht 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ß.

Autor: Klugscheisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
if (Enable='1') then
   if rising_edge(clk) then
      cnt<=cnt+1;
   end if;
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?
if (Enable='1') then          -- enable counter
  if rising_edge(clk) then
     if   (up='1') then       -- enable up
        cnt<=cnt+1;
     elsif(dn='1') then       -- enable down
        cnt<= cnt-1;
     end if;
  end if;
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:
if rising_edge(clk) then
  if (Enable='1') then
     if   (up='1') then
        cnt<=cnt+1;
     elsif(dn='1') then
        cnt<= cnt-1;
     end if;
  end if;
end if;
Und das wird klappen, weil es jeder so (oder annähernd so) macht.

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dumme Frage meinerseits ...

@Lothar
if rising_edge(clk) then
  if (Enable='1') then
     if   (up='1') then
        cnt<=cnt+1;
     elsif(dn='1') then
        cnt<= cnt-1;
     end if;
  end if;
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:
if rising_edge(clk) and enable='1' then

end if;

gibt es auch noch

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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):
if (clk='1') then  -- hier fehlt das 'event
   if (enable='1') then
      if   (up='1') then
         cnt<=cnt+1;
      elsif(dn='1') then
         cnt<=cnt-1;
      end if;
   end if;
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:
>
> if rising_edge(clk) and enable='1' then
> 
> end if;
> 
> gibt es auch noch
Ja, wurde von mir schon untersucht und dort am Rande angeführt:
Beitrag "Re: Variablenfehler"   ;-)

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.