1 kleines VHDL Rätsel

OP #7611857
Lesenswert?

Unter welchen Umständen sind concurrent Zuweisungen wie

1
a <= b when c = '1' else d;

innerhalb eines getakteten Prozesses, also innerhalb des

1
if rising_edge(clock) then
2
  *hier*
3
end if;

erlaubt?

Bonuspunkte gibt es für die Begründung, weil ich die selber noch nicht kenne (-:

#7611924
Lesenswert?

Markus F. schrieb:

Einzige Voraussetzung ist VHDL 2008 Unterstützung. (Zumindest) ältere Quartus-Versionen z.B. können das (wegen eben unvollständiger VHDL 2008 Implementierung) nicht.

Richtig. Das kam alles mit VHDL2008. Der Support dafür sieht aber i. d. R. schlecht aus. Die Asic Synthesen können sowas zum Beispiel gar nicht. Da kann man schon froh sein, wenn VHDL93 halbwegs funktioniert.

Schön zu sehen, dass so etwas immerhin von den FPGA Toolings (teilweise) unterstützt wird.

#7611969
Lesenswert?

Markus F. schrieb:

Du siehst falsch. Das geht schon immer.

1
dcnxt_shell> read_vhdl flop.vhd 
2
Loading vhdl file '/tmp/tmp.czjuGaFtUy/flop.vhd'
3
Running PRESTO HDLC
4
Warning: Can't read link_library file 'your_library.db'. (UID-3)
5
Compiling Entity Declaration FLOP
6
Compiling Architecture RTL of FLOP
7
Error:  /tmp/tmp.czjuGaFtUy/flop.vhd:20: An if statement containing a clock event has an illegal else branch and is not supported for synthesis. (ELAB-928)
8
Error:  /tmp/tmp.czjuGaFtUy/flop.vhd:20: An if statement containing a clock event has an illegal else branch and is not supported for synthesis. (ELAB-928)
9
Error:  /tmp/tmp.czjuGaFtUy/flop.vhd:20: An if statement containing a clock event has an illegal else branch and is not supported for synthesis. (ELAB-928)
10
*** Presto compilation terminated with 3 errors. ***
11
Error: Can't read 'vhdl' file '/tmp/tmp.czjuGaFtUy/flop.vhd'. (UID-59)
12
No designs were read
13
dcnxt_shell>

flop.vhd sieht so aus:

1
library ieee;
2
use ieee.std_logic_1164.all;
3

4
entity flop is
5

6
  port (
7
    clk : in  std_logic;
8
    d   : in  std_logic;
9
    q   : out std_logic);
10

11
end entity flop;
12

13
architecture rtl of flop is
14
  signal q_reg : std_logic;
15
begin  -- architecture rtl
16

17
  -- Signal needed due to VHDL'93. Not necessary in VHDL2008
18
  q <= q_reg;
19

20
  q_reg <= d when rising_edge(clk) else q_reg;
21

22
end architecture rtl;
Gast #7612374
Lesenswert?

Für mich ist das hier relevant:

1
you can carefuly use block statement and when sequential needed use guarded. I've asked my colleagues who have huge background in FPGA design and they told that block is kinda anachronism, almost nobody use it, but it still in standard to give some choice for designers.
#7612458
Lesenswert?

Interessehalber nachgehakt:

  1. Gilt das hier gesagte auch für verkettete with/select/when- bzw. when/else-Konstrukte vs. case/is/when im Prozess?
  2. Den else-Zweig beim if kann man als einzelne Zuweisung auch vor das if-Statement setzen:
1
  b <= '1';
2
  ...
3
  if a = '1' then
4
    b <= '0';
5
  end if;

Gibt es das außerhalb der Prozesse auch, also z. B. when ohne else?

Persönliche Seite #7622253
Lesenswert?

Mampf F. schrieb:

Ich habe es mir so gemerkt, dass in Prozessen "if" und außerhalb Prozessen "when".

Die Sache wird dann spannend, wenn sich die IFs und WHENs funktionell überlappen und es echte exklusive IF-ELSE sind, bzw wie verschachtelt sie sind. Als Beispiel könnte man auf die ersten 3 Bits eines Verktors checken und parallel noch auf die ersten 2. Das ergibt einen parallelen Konstrukt, der einen Vorrang braucht um eindeutig aufgelöst zu werden. Dann gilt nämlich die Reihenfolge der Codierung und das noch im Bezug auf das Auftreten von Signalen. Besonders in der Simulation macht sich das dann bemerkbar. Wenn z.B. eine FSM läuft, die an zwei Stellen zeitversetzt auf kombinatorische Signale prüft, dann würde eine Änderung von Signalen zwischen den beiden Abfragen zu einem varianten Ergebnis führen. Je nachdem, wie man die Process-Liste ausführt, bekommt man z.B. 3 mögliche Verhaltensfälle, von denen 2 nichts mit dem gemein haben, was der synthetisierte Code macht.

Beitrag #7622616 wurde von einem Moderator gelöscht.
#7638701
Lesenswert?

Also, check’s mal: Wenn du in VHDL abgehen willst und so a <= b when c = '1' else d; direkt im Prozess droppen willst, dann ist das klar machbar. Aber das musst du außerhalb von den krassen if-Statements machen, die auf den Clock abfahren, weißt du?

Hier mal ein Beispiel, wie das fresh aussehen könnte:

process(clock) begin if rising_edge(clock) then -- Hier kommen die getakteten Moves end if;

-- Und hier ballerst du die concurrent Zuweisung rein, easy. a <= b when c = '1' else d; end process;

Die Sache ist die: Concurrent Zuweisungen sind wie die Party, die nebenan abgeht, während du in deinem Zimmer chillst. Die laufen parallel und jucken sich nicht daran, was in deinem sequentiellen Flow abgeht. Also kannst du die einfach nebenbei laufen lassen, solange sie nicht in den if-Statement-Vibe reinkrachen, der auf den Clock reagiert. Voll logisch, oder?

Persönliche Seite #7645138
Lesenswert?

Gerda M. schrieb:

process(clock) begin if rising_edge(clock) then -- Hier kommen die getakteten Moves end if;

-- Und hier ballerst du die concurrent Zuweisung rein, easy. a <= b when c = '1' else d; end process;

Die Sache ist die: Concurrent Zuweisungen sind wie die Party, die nebenan abgeht,

Da sehe ich keinen Sinn drin. Das "a <= b when c = '1' else d;" gehört raus aus dem process statement, wenn nicht irgendwelche Abhängigkeiten nötig sind. Soweit sie sinnvoll sind, um die Simulation zu optimieren, gehört das in einen eigenen Prozess, wo die SENS-Liste von (nur) diesen Signalen abhängig ist.

Hier steckt auch wieder ein wenig die Strategie mancher Entwickler drin, dass man alle getakteten Signale in einen process stopfen kann/sollte/darf. Davon halte ich sehr wenig!

Ich tendiere lieber zu einer Einzelbeschreibung der relevanten Ausgangssignale mitsamt dem Managment dessen, was dafür nötig ist. Das vereinfacht die Verschachtelungen bei IF-THENs und auch eventuell WHENs.

Das Ziel sollte Übersichtlichkeit sein und nicht das Ausreizen von Codierungs-Optionen. Weil immer viel historisches mitgeschleppt wird, herrscht bei VHDL eine große Redundanz und ein Wildwuchs bei der Möglichkeit, exakt Dasselbe zu beschreiben, dass es angezeigt ist, das zu simplifizieren und zu vereinheitlichen.

VHDL Rätsel

Wenn bei solchen Beschreibungen "gerätselt" werden muss und man die Simulation braucht, um einen Konstrukt zweifelsfrei und vollständig zu verstehen, ist er fehl am Platze.

VHDL ist eine Bauanleitung für eine virtuelle Elektronik und solche Anleitungen sollten klar formuliert sein, damit sie gut und effektiv überprüfbar sind. Das ist bei wachsender Schaltungskomplexität zunehmend wichtiger und in vielen Branchen, in denen Code gereviewd werden muss und Standards zu erfüllen hat, einfach unerlässlich. Es hat niemand etwas davon, wenn ein Entwickler perfektionierte und selten genutzte Konstrukte benutzt, die ihm Zeit ersparen, sehr elegant sind, von anderen aber nur durch Analyse verstanden werden. Am Ende muss man X Kommentare und Doku nachrüsten, was jeden Vorteil einer möglichen Zeiteinsparung pulverisiert.

Auch in Sachen Code-Pflege ist es viel einfacher und durchsichtiger, wenn beim Vergleich zweier eingecheckter Versionen nicht an allenmöglichen Stellen aufgeblusterte und immer komplizierter werdende FSMs und Prozesse auftauchen, sondern das einmal Gemachte in Ruhe bleibt und neue Funktionen wirklich einfach nur zu einigen neuen Prozessen und Zeilen führen, die im Compare-Fenster direkt aufpoppen. Die Compare-Funktion profitiert massiv davon, wenn Code entsprechend blockorientiert erstellt wurde. Auch lassen sich solche nachgerüsteten Code-Fragmente viel einfacher per COPY und PASTE in andere Projekte verfrachten und alter Code manuell nachpflegen. Das Automerge bei gleichzeitiger Codebearbeitung von zwei Leuten funktioniert dann auch unfallfreier.

OP #7645264
Lesenswert?

J. S. schrieb:

Das "a <= b when c = '1' else d;" gehört raus aus dem process statement, wenn nicht irgendwelche Abhängigkeiten nötig sind.

Darum geht es nicht. Es ging mir nur um die Tatsache, dass solche concurrent Zuweisungen möglich sind - und zwar nicht nur in einem Prozess, sondern auch in dem getakteten Teil vom Prozess. Das war mir neu, scheint aber standardkonform zu sein. Man kann jetzt also statt

1
process(clock)
2
begin
3
if rising_edge(clock) then
4
   if c = '1' then
5
      a <= b;
6
   else
7
      a <= d;
8
   end if;
9
end if;
10
end process;

ganz einfach

1
process(clock)
2
begin
3
if rising_edge(clock) then
4
   a <= b when c = '1' else d;
5
end if;
6
end process;

schreiben.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren