Forum: FPGA, VHDL & Co. Procedure Beispiele


von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Mir ist aufgefallen, dass ich bis jetzt keine Procedure nutze.


In allen meinen Bücher wird die procedure nicht weiter behandelt.

Mir fehlt hier noch ein Aufhänger für den Einsatz. Vielleicht hätte ich 
mit Proceduren meine Probleme einfacher lösen können.

Hat/Kennt jemand Beispielcodes mit Proceduren?

Ist zur Rrweiterung meines VHDL Horizontes.

von Klaus F. (kfalser)


Lesenswert?

Procedures sind wie bei "normalen" Programmiersprachen nur nützlich, um 
wiederkehrende Operationen zusammenzufassen.
z.B. in Testbenches das Schreiben auf ein Register
1
    procedure write2Register ( 
2
        regNr     : in integer;
3
        value     : in std_logic_vector(31 downto 0);
4
        signal BusClk    : in std_logic;
5
        signal BusEnable : inout std_logic;
6
        signal BusWen    : inout std_logic_vector(3 downto 0);
7
        signal BusData   : inout std_logic_vector(31 downto 0);        
8
        signal BusAddr   : inout std_logic_vector(31 downto 0)
9
        ) is
10
        constant base_addr : UNSIGNED(31 downto 0) := X"8130_0000"; 
11
   begin
12
        wait until BusClk = '1';
13
        BusEnable <= '1';
14
        BusWen    <= "1111";
15
        BusAddr   <= std_logic_vector(base_addr + regNr * 4);
16
        BusData   <= value;
17
        wait until BusClk = '1';
18
        BusEnable <= '0';
19
        BusWen    <= "0000";
20
        wait until BusClk = '1';        
21
   end write2Register ;

und die Verwendung in einem Stimulus Prozess.
Ist halt kürzer und übersichtlicher, als wenn man das setzen der CS, der 
Adresse und der Daten jedesmal neu hinschreiben würde.
1
   -- Stimulus process
2
3
   stim_proc: process
4
   begin    
5
      -- hold reset state for 100ms.  
6
     rst <= '1';
7
     wait for clk_period*5;  
8
     rst <= '0';
9
                
10
     write2Register ( 0, X"00000000", clk, enable, wen, din, addr); 
11
        
12
     wait for 2 ms;
13
     write2Register ( 3, X"00001234", clk, enable, wen, din, addr); 
14
     write2Register ( 4, X"00000000", clk, enable, wen, din, addr);       
15
     wait;
16
17
   end process;

von berndl (Gast)


Lesenswert?

Hallo Rene,

wie Klaus schon oben bemerkt hat... Speziell fuer TBs sind procedures 
und functions genial, z.B. um komplexe write/hwrite Sequenzen nur einmal 
hinschreiben zu muessen, um z.B. Testdaten zu generieren und auch gleich 
die Ergebnisse zu berechnen, um 'ne CRC in der TB parallel zur HW 
berechnen und abzuchecken, und eben auch um das FPGA zu stimulieren...

Ich habe ueblicherweise TBs, bei denen ueber 1000 Zeilen procedures in 
einem package sind. Im eigentlichen Test ist es dann nur der Aufruf per 
copy+paste, Aenderungen/Erweiterungen muss ich nur an einer Stelle 
machen, ...

In Designs setze ich es normalerweise nie ein, nur in TBs. Parameter aus 
der Laufzeit sind dann auch ueblicherweise Variablen um dieses daemliche 
'wait for...' in den TBs vermeiden zu koennen.

von Sigi (Gast)


Lesenswert?

Prozeduren sind nicht nur in TBs sinnvoll/hilfreich, sie
können auch in ganz "normalen" Komponenten nützliche
Arbeit übernehmen.

Einfaches Beispiel (Generics und FSM/Startzustand):
Je nach Generic-Wert wird ein Startwert (vor)berechnet
und dem Zustands-Signal zugeordnet (in Decl oder in der
Automatenlogik).

Zum Syntax: Prozedure-Argumente können CONSTANT, VARIABLE,
SIGNAL oder unbestimmt sein, sie können in,out,inout etc.
sein und beliebige Typen annehmen:

procedure tbbMapItemGet
(
         h : inout whatever;  -- unbestimmt
variable v : inout whatever;
constant c : in    whatever;
signal   s : out   whatever
)
is
begin
  v := h;
  h <= dontknow;
  s <= c;
end;

von berndl (Gast)


Lesenswert?

Sigi schrieb:
> Prozeduren sind nicht nur in TBs sinnvoll/hilfreich, sie
> können auch in ganz "normalen" Komponenten nützliche
> Arbeit übernehmen.

Hast natuerlich recht mit der Aussage. Ich bin noch so auf dem Trichter: 
Procedures/Functions machen einen Design komplex/kompliziert, eine TB 
machen sie dagegen richtig einfach. Im grossen und ganzen ist das meine 
Erfahrung...

von berndl (Gast)


Lesenswert?

moechte es auch gerne noch etwas weiter praezisieren...

Im Design bringt es dir eine Reduzierung der 'LOC', aber eine weitere 
Abstraktionsebene. Das ist nicht einfach zu durchschauen, wenn man ein 
.vhd vor den Latz geballert kriegt (und dann noch ohne exzessives 
kommentieren...).

In der TB gehe ich einfach mal davon aus, dass man den Sprachumfang von 
VHDL auch ausnutzt.

Ist also m.M. nach ein zweischneidiges Schwert...

von Gustl B. (-gb-)


Lesenswert?

Wo ist denn der Unterschied zwischen Procedure und Component?

Also kann ich das was ich sonst in ein Component schreibe auch als 
Procedure schreiben ohne was zu verändern am Inhalt? Sprich ist eine 
Component eine Procedure, aber sie steht eben in einer eigenen anderen 
vhdl Datei?

von Klaus F. (kfalser)


Lesenswert?

Gustl Buheitel schrieb:
> Wo ist denn der Unterschied zwischen Procedure und Component?

Was vielleict Verwirrung stiftet, ist dass man eine Procedure als
concurrent statement schreiben kann und dass sie dann wie ein Prozess
wirkt.

Aber allgemein ist eine Procedure einfach nur eine Sequenz von 
Zuweisungen/Anweisungen, die zusammengefasst werden und IN einem Prozess 
verwendet werden.
Eine Component ist hingegegen ein "Schaltungsteil", der selbst Prozesse 
beinhaltet.
Um es vielleicht primitiv auszudrücken:
- Eine Component existiert die ganze Zeit und die Signale die in die 
Component hinein- und herausgehen sind immer die selben.
- Eine (nicht concurrent) procedure ist hingegen einfache nur eine 
(parametrierbare) Zusammenfassung von Anweisungen.
Procedures sind für die Synthese vielleicht mit Vorsicht zu geniesen,
das sie der Compiler möglicherweise nicht korrekt umsetzt.
Habe sie jedefalls nie verwendet.
>
> Also kann ich das was ich sonst in ein Component schreibe auch als
> Procedure schreiben ohne was zu verändern am Inhalt? Sprich ist eine
> Component eine Procedure, aber sie steht eben in einer eigenen anderen
> vhdl Datei?

Nein, da eine Component wie gesagt unterschiedliche Prozesse beinhalten
kann, IN einer Procedure können hingegen keine Prozesse auftreten.
Eine concurrent instantierte Procedure ergibt hingegen EINEN Prozess.

von Sigi (Gast)


Lesenswert?

Im Prinzip kann man eine Komponente und eine Prozedur anlegen
und alle weiteren "Komponenten" als Prozeduren definieren,
bzw. deren Unterkomponenten wiederum als Prozeduren etc.
Das macht aber (fast)kein Mensch, also lass es lieber.

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


Lesenswert?

René D. schrieb:
> Vielleicht hätte ich mit Proceduren meine Probleme einfacher lösen
> können.
Welche Probleme?

> Hat/Kennt jemand Beispielcodes mit Proceduren?
Ich verwende Prozeduren wie die Anderen ebenfalls (fast) ausschließlich 
in TB. Dort darf man endlich mal die restlichen 95% von VHDL 
verwenden...

Hier z.B. die Prozedur in einer TB für einen ISA-Buszyklus:
1
  type direction is (READ_ACCESS, WRITE_ACCESS);
2
  constant isaclk: time := 125 ns;  
3
4
  procedure ISABusCycle(signal a  : in std_logic_vector(19 downto 0); 
5
              signal dir : in direction;
6
              signal di :  in std_logic_vector(7 downto 0); 
7
              signal do :  out std_logic_vector(7 downto 0); 
8
9
              signal sd : INOUT std_logic_vector(7 downto 0); 
10
              signal sa : OUT std_logic_vector(19 downto 0);
11
              signal bale : OUT std_logic;
12
              signal aen : OUT std_logic;
13
              signal nr : OUT std_logic;
14
              signal nw : OUT std_logic) is
15
  begin
16
       wait for 1 ns;
17
    sa    <= a;
18
    nw    <= '1';
19
    nr    <= '1';
20
    aen   <= '0';
21
    bale  <= '1';
22
    do    <= (others=>'Z');
23
    if(dir = WRITE_ACCESS) then sd <= di;
24
    else            sd <= (others=>'Z');
25
    end if;
26
    wait for isaclk/2;
27
    bale  <= '0';
28
    wait for isaclk/2;
29
    if(dir = WRITE_ACCESS) then nw <= '0';
30
    else                        nr <= '0';
31
    end if;
32
    wait for isaclk/2;
33
    do    <= sd;
34
    nw    <= '1';
35
    nr    <= '1';
36
    wait for isaclk/2;
37
    sa    <= (others=>'0');
38
    wait for 1 ns;
39
  end procedure;
40
:
41
:
42
      dir  <= WRITE_ACCESS;
43
      dwr  <= X"5A";
44
      addr <= X"D0001";
45
      ISABusCycle(addr,dir,dwr,drd, sd,sa,bale,aen,nsmemr,nsmemw);

Oder das Senden eines Bytes über die serielle Schnitte:
1
   procedure tx_char (signal txpin: out std_logic; txdata : in character; baudrate : in integer) is
2
   constant bittime : time := (integer(1000000000.0/real(baudrate))) * 1 ns; -- in ns
3
   variable c : std_logic_vector(7 downto 0); 
4
   begin
5
      c := std_logic_vector(to_unsigned(character'pos(txdata),8));
6
      txpin <= '0'; -- Startbit
7
      wait for bittime;
8
      for i in 0 to 7 loop
9
         txpin <= c(i);
10
         wait for bittime;
11
      end loop;
12
      txpin <= '1'; -- Stopbit
13
      wait for bittime;
14
   end tx_char;
15
:
16
:
17
:
18
PROCESS BEGIN
19
      tx_char(RXD, 'H', 9600);
20
      tx_char(RXD, 'a', 9600);
21
      tx_char(RXD, 'l', 9600);
22
      tx_char(RXD, 'l', 9600);
23
      tx_char(RXD, 'o', 9600);
24
      tx_char(RXD, ' ', 9600);
25
      tx_char(RXD, 'W', 9600);
26
      tx_char(RXD, 'e', 9600);
27
      tx_char(RXD, 'l', 9600);
28
      tx_char(RXD, 't', 9600);
29
      tx_char(RXD, '!', 9600);
30
      wait; -- will wait forever
31
END PROCESS;

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Lothar Miller schrieb:
> René D. schrieb:
>> Vielleicht hätte ich mit Proceduren meine Probleme einfacher lösen
>> können.
> Welche Probleme?

Manchmal muss man erkennen dass man ein Problem hat.
Ich will effektiver arbeiten. Und dafür muss ich auch neue Weg ins 
Augenlicht nehmen.
Ich arbeite alleine und brauche Infos ob dies oder das was für mich 
wäre. Dafür nutze ich das Forum as Diskussionspartner.
Aktuelle will ich mein Ethernet verbessern.

Eine Frage die zu Proceduren noch hatte, hat Klaus Falser (kfalser) 
eantwortet. Ob ich auch Processe gruppieren kann? Antwort ist nein.

Ich habe meist mehrer Prozesse die zusammengehören.
Prozess 1 erkennt einen Zustand meldet es an Prozess 2, der die State 
Maschine ist und Prozess 3 schaltet die Outputs. Dazwischen sind noch 
Signal.
Ja das ist ein Componet. Doch die Schreiberei und die Pflege eines 
Components ist wieder mit overhead. Da dache es gibt noch eine Vorstufe 
so dazwischen.

Was aber bei den bisherigen Beiträgen mir auf gefallen ist, das Thema 
Testbench ist auch nicht sonderlich ideenreich in der Literatur gewesen.

von Klaus L. (hmpf)


Lesenswert?

René D. schrieb:
> Ja das ist ein Componet. Doch die Schreiberei und die Pflege eines
> Components ist wieder mit overhead. Da dache es gibt noch eine Vorstufe
> so dazwischen.

Dazwischen gibts noch
1
 block

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Klaus L. schrieb:
> René D. schrieb:
>> Ja das ist ein Componet. Doch die Schreiberei und die Pflege eines
>> Components ist wieder mit overhead. Da dachte ich, es gibt noch eine Vorstufe
>> so dazwischen.
>
> Dazwischen gibts noch
1
 block

Oh daran habe ich noch gar nicht gedacht. Mehr als das es block gibt 
habe ich noch nicht gewusst. Geschweige mal Block in einem VHDL code 
vorgefunden.

von Klaus F. (kfalser)


Lesenswert?

René D. schrieb:
> Ja das ist ein Componet. Doch die Schreiberei und die Pflege eines
> Components ist wieder mit overhead.

Naja, soviel Overhead auch wieder nicht.
Und auch in einem Software Design würde niemand auf eine Modularisierung 
verzichten, nur weil man in dem Unterprogramm die Parameterliste
schreiben muss.

René D. schrieb:
>> Dazwischen gibts noch block
> Oh daran habe ich noch gar nicht gedacht. Mehr als das es block gibt
> habe ich noch nicht gewusst. Geschweige mal Block in einem VHDL code
> vorgefunden.

Und man sollte dies auch ganz schnell wieder vergessen!
Von der Synthese werden sie nicht unterstützt und für Testbenches nicht
benötigt, weil das Treiben eines Signales aus mehreren quellen vom 
Package
ieee.std_logic_1164 gelöst wird.

Quelle :
http://vhdl.renerta.com/source/vhd00012.htm

von Klaus L. (hmpf)


Lesenswert?

Klaus Falser schrieb:
> Und man sollte dies auch ganz schnell wieder vergessen!
> Von der Synthese werden sie nicht unterstützt

Stimmt nicht.

Klaus Falser schrieb:
> für Testbenches nicht
> benötigt, weil das Treiben eines Signales aus mehreren quellen vom
> Package
> ieee.std_logic_1164 gelöst wird.

Hier sehe ich keinen Zusammenhang zwischen Blocks und resolved Signalen.

von Duke Scarring (Gast)


Lesenswert?

Klaus Falser schrieb:
> Und man sollte dies auch ganz schnell wieder vergessen!
> Von der Synthese werden sie nicht unterstützt und für Testbenches nicht
> benötigt,
Häh?!
Ich nehme BLOCK.
Zwar relativ selten, aber wenn, dann vor allem für synthetisierbaren 
Code...

Duke

von Klaus F. (kfalser)


Lesenswert?

Klaus L. schrieb:
> Hier sehe ich keinen Zusammenhang zwischen Blocks und resolved Signalen.

Weil sie, soweit ich das verstanden habe, ursprünglich zusammen mit dem
"guard" Ausdruck dazu gedacht waren, tristate Signale zu modellieren, 
indem man die Driver ein- und ausschalten konnte.
Mit IEEE1164 hat man dafür einen anderen Weg über resolved Signals
standardisiert.

Duke Scarring schrieb:
> Häh?!
> Ich nehme BLOCK.
> Zwar relativ selten, aber wenn, dann vor allem für synthetisierbaren
> Code...

Dann erklär mir bitte einmal wozu man sie braucht.
Bis jetzt habe ich sie halt nicht vermisst.

: Bearbeitet durch User
von Da D. (dieter)


Lesenswert?

Klaus Falser schrieb:
> Dann erklär mir bitte einmal wozu man sie braucht.
> Bis jetzt habe ich sie halt nicht vermisst.

Einfach nur zum Strukturieren. Um zusammmengehörende Sachen innerhalb 
einer Architecture zusammen zu gruppieren, und um nur lokal innerhalb 
eines Blocks benötigte Signale auch nur dort deklarieren zu müssen.

Zugegebenermaßen benutze ich die Blöcke auch selten. Aber hin und wieder 
nutze ich sie doch in komplexeren, synthetisierbaren Modulen.

von Duke Scarring (Gast)


Lesenswert?

Klaus Falser schrieb:
> Dann erklär mir bitte einmal wozu man sie braucht.

Da Dieter schrieb:
> Einfach nur zum Strukturieren.
Der Erklärung von Dieter kann ich nichts weiter hinzufügen.

Duke

von Hanni (Gast)


Lesenswert?

>Einfach nur zum Strukturieren. Um zusammmengehörende Sachen innerhalb
>einer Architecture zusammen zu gruppieren,

Jep, vor allem in Modelsim entstehen so aufklappbare "Sub-Module". Sehr 
übersichtlich

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Lothar Miller schrieb:
> René D. schrieb:
>> Vielleicht hätte ich mit Proceduren meine Probleme einfacher lösen
>> können.
> Welche Probleme?

>> Hat/Kennt jemand Beispielcodes mit Proceduren?
Vielen Dank für eure Beispiele. Lothar hat auch hier wieder ausgefeilte 
Lösungen parat.
Ich habe nun meine erste Procedure im Einsatz und will diese auch ins 
Forums stellen.

1
  subtype by_te is character;
2
  type f_byte is file of by_te;
3
 
4
  procedure hexfile (signal CLK : in std_logic;
5
                        signal data     : out std_logic_vector (7 downto 0);
6
                        signal valid    : out std_logic;
7
                        constant filename   : in string) is
8
                         
9
  file in_file: f_byte open read_mode is filename;
10
  variable a           : character; 
11
  begin
12
    valid<='0';
13
14
     while (not endfile(in_file)) loop
15
        wait until CLK='1';
16
        valid <='1';
17
    read(in_file,a);
18
        data<=std_logic_vector(to_unsigned(character'pos(a),8));
19
      end loop;
20
    wait until CLK='1';
21
    valid <='0';  
22
    file_close(in_file);
23
   end hexfile;
1
  PROCESS
2
   BEGIN
3
      wait for 400 ns;
4
      hexfile(phy_rx_clk,rxdata,rxvalid,"arp_request.hex");
5
      wait for 1.4 us;
6
      hexfile(phy_rx_clk,rxdata,rxvalid,"arp_request.hex");
7
      wait; -- will wait forever
8
  END PROCESS;

Ich kann sagen, bei mehrfachem Hexfile lesen sieht die Testbench 
deutlich übersichtlicher aus.

von VHDL anfänger (Gast)


Lesenswert?

Kannst du den Type innerhalb der Procedure definieren?
Dann wäre alles gekapselt. Nur als Frage.

von Duke Scarring (Gast)


Lesenswert?

VHDL anfänger schrieb im Beitrag #3571893:
> Kannst du den Type innerhalb der Procedure definieren?
Ja, das ist möglich.
Im gewählten Beispiel wurde der Datentyp sicher noch an anderer Stelle 
benötigt.

Duke

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.