Forum: FPGA, VHDL & Co. MODELSIM assert von internen Signalen


von Matthias Krüßelin (Gast)


Lesenswert?

Hallo,

bin gerade dabei eine größere Testbench zu schreiben.
Mir ist bekannt, dass man alle Signale, auch von Komponenten
auflisten und im Wave anzeigen lassen kann.
Ist es nun möglich irgendwie darauf mittels assert(...='0')
zuzugreifen?

z.B:
1
ENTITY tb_user_logic IS
2
END tb_user_logic;
3
 
4
ARCHITECTURE behavior OF tb_user_logic IS 
5
 
6
    -- Component Declaration for the Unit Under Test (UUT)
7
 
8
    COMPONENT user_logic
9
    PORT(
10
       ...
11
       );
12
    END COMPONENT;
13
BEGIN
14
15
  -- Instantiate the Unit Under Test (UUT)
16
   uut: user_logic 
17
   PORT MAP (
18
     ...
19
     );
20
21
   clk_process :process
22
   begin
23
    Bus2IP_Clk <= '0';
24
    wait for clk_period/2;
25
    Bus2IP_Clk <= '1';
26
    wait for clk_period/2;
27
   end process;
28
 
29
   -- Stimulus process
30
   stim_proc: process
31
   begin    
32
        Bus2IP_Reset <= transport '1';
33
        -- hold reset state for 3ns.
34
        wait for clk_period*3; --totaltime: 3ns   
35
        Bus2IP_Reset <= transport '0';
36
        assert (IP2Bus_Ack='1') report "IP2Bus_Ack!=1, by RAM read Test, Addr:2" severity failure;
37
38
        wait for clk_period*3; --totaltime: 3ns   
39
        assert (???='1') report "/tb_user_logic/uut/x_motor/ready='1'" severity failure;
40
        wait;
41
   end process;
42
END
---

Wie kann ich nun also auf das Signal "ready" der Componente x_motor der 
Componente uut zugreifen???
Folgendes habe ich probiert, geht aber alles NICHT!!!:
1
assert("/tb_user_logic/uut/x_motor/ready"='1')
2
assert("/tb_user_logic/uut/x_motor.ready"='1')
3
assert(/tb_user_logic/uut/x_motor/ready='1')
4
assert(/tb_user_logic/uut/x_motor.ready"='1')
5
assert(tb_user_logic/uut/x_motor/ready='1')
6
assert(tb_user_logic/uut/x_motor.ready"='1')
7
assert(uut/x_motor/ready='1')
8
assert(uut/x_motor.ready"='1')

Vielen Dank im voraus,
Matthias Krüßelin

von Mathi (Gast)


Lesenswert?

Diese Möglichkeit gibt es in VHDL nicht. Mit einem Assert-Statement kann 
nur ein Signal innerhalb desselben Moduls überwacht werden. Deshalb 
musst Du die assert-Statements in den einzelnen Modulen "verteilen".

von Joko (Gast)


Lesenswert?

aus der ModelSim-Doku (manchmal lohnt es sich eine Doku tatsächlich):

"init_signal_spy()
The init_signal_spy() utility mirrors the value of a VHDL signal or 
Verilog register/net onto an
existing VHDL signal or Verilog register. This allows you to reference 
signals, registers, or nets
at any level of hierarchy from within a VHDL architecture (such as a 
testbench).
See init_signal_spy for complete details."

Gruß
Joko

von Matthias Krüßelin (Gast)


Lesenswert?

> Deshalb musst Du die assert-Statements in den einzelnen Modulen
> "verteilen".

"verteilen" - wie ist das gemeint?
Klar, ich kann jedes Modul separat testen.
Aber ich kann nicht in den "normalen" VHDL-Code,
also in einer erzeugten Komponente, Asserts einfügen;
wie soll das gehen?

Ist die einzige Möglichkeit benötigte Signale bis auf
die oberste Instanz durchzuschleifen?
Dann müsste ich die ganzen Components,Entity's usw. ergänzen,
was ja doch sehr aufwändig sein wird...

Modelsim kennt ja die internen Signale,
und kann diese präsentieren,
daher kann ich nicht ganz verstehen, weshalb ich aus
der Testbench nicht darauf zugreifen kann...

Vielleicht hilft ein kleines Beispiel...

Danke und Grüße
Matthias Krüßelin

von Joko (Gast)


Lesenswert?

@Matthias Krüßelin

>Ist die einzige Möglichkeit benötigte Signale bis auf
>die oberste Instanz durchzuschleifen?

Nein - siehe meine Antwort oben: genau DAS macht "init_signal_spy"

Gruß

von Joko (Gast)


Lesenswert?

Nachtrag:

>Aber ich kann nicht in den "normalen" VHDL-Code,
>also in einer erzeugten Komponente, Asserts einfügen;
>wie soll das gehen?

klar kannst Du: mit

-- synthesis translate_off
  blablabla
-- synthesis translate_on

kannst Du jede beliebigen Code für die Synthese
unsichtbar machen - der ist dann nur noch für die
Simulation relevant

Gruß

von SuperWilly (Gast)


Lesenswert?

Noch besser:

Du definierst für deine Simulation ein globales Package mit globalen
Signalen:

package global_probes is
signal probe_ls_signal_in_deep_hierarchy : std_logic;
end package;


Das Signal, das du beobachten willst, wird diesem globalen Signal
zugewiesen (in der Komponente)


--synthesis_off
probe_ls_signal_in_deep_hierarchy <= ls_signal_of_interest;
--synthesis_on


In deiner Testbench und in deiner Komponente bindest du nun das globale 
Package ein:

library work;
use work.global_probes.all;

Nun kannst du bequem in der Testbench deine Assert-Abfragen vornehmen:

assert probe_ls_signal_in_deep_hierarchy='0' ....

Gruß,
SuperWilly

von Matthias Krüßelin (Gast)


Lesenswert?

Hi,
@Joko: vielen Dank, habe Deinen Beitrag erst nach meinem Eintrag 
gelesen, sorry...

Vielen Dank für die schnelle Hilfe :-)

Grüße
Matthias Krüßelin



Nun zur Vervollständigung:

1
VHDL Syntax
2
init_signal_spy(<src_object>, <dest_object>, <verbose>, <control_state>)
3
Verilog Syntax
4
$init_signal_spy(<src_object>, <dest_object>, <verbose>, <control_state>)
5
SystemC Syntax
6
init_signal_spy(<src_object>, <dest_object>, <verbose>, <control_state>)

noch ein Beispiel:
1
LIBRARY ieee;
2
USE ieee.std_logic_1164.ALL;
3
library modelsim_lib;
4
use modelsim_lib.util.all;
5
6
ENTITY tb_user_logic IS
7
END tb_user_logic;
8
 
9
ARCHITECTURE behavior OF tb_user_logic IS 
10
 
11
    -- Component Declaration for the Unit Under Test (UUT)
12
 
13
    COMPONENT user_logic
14
    PORT(
15
       ...
16
       );
17
    END COMPONENT;
18
19
    signal x_motor_ready : std_logic := '0';
20
21
BEGIN
22
23
  -- Instantiate the Unit Under Test (UUT)
24
   uut: user_logic 
25
   PORT MAP (
26
     ...
27
     );
28
29
   -- Signal Spy Process 
30
   spy_proc: process 
31
   begin
32
    init_signal_spy("/tb_user_logic/uut/x_motor/ready", "/tb_user_logic/x_motor_ready", 1, 1);
33
    wait;
34
   end process;
35
36
37
   clk_process :process
38
   begin
39
    Bus2IP_Clk <= '0';
40
    wait for clk_period/2;
41
    Bus2IP_Clk <= '1';
42
    wait for clk_period/2;
43
   end process;
44
 
45
   -- Stimulus process
46
   stim_proc: process
47
   begin    
48
        Bus2IP_Reset <= transport '1';
49
        -- hold reset state for 3ns.
50
        wait for clk_period*3; --totaltime: 3ns   
51
        Bus2IP_Reset <= transport '0';
52
        assert (IP2Bus_Ack='1') report "IP2Bus_Ack!=1, by RAM read Test, Addr:2" severity failure;
53
54
        wait for clk_period*3; --totaltime: 3ns   
55
        assert (x_motor_ready='1') report "/tb_user_logic/uut/x_motor/ready='1'" severity failure;
56
        wait;
57
   end process;
58
END

von SuperWilly (Gast)


Lesenswert?

Vorteile der Global-Package-Variante:

1. Simulator unabhängig
2. Design-Hierarchien können beliebig verändert werden

von Martin K. (mkohler)


Lesenswert?

SuperWilly wrote:
> Du definierst für deine Simulation ein globales Package mit globalen
> Signalen:
>
> package global_probes is
> signal probe_ls_signal_in_deep_hierarchy : std_logic;
> end package;
>
> Das Signal, das du beobachten willst, wird diesem globalen Signal
> zugewiesen (in der Komponente)
> --synthesis_off
> probe_ls_signal_in_deep_hierarchy <= ls_signal_of_interest;
> --synthesis_on

Wie funktioniert das mit dem global package dann, wenn von einer 
Komponente mehrere Instanzen vorhanden sind?
Gibt es dann nicht einen Namenskonflikt?

von SuperWilly (Gast)


Lesenswert?

>Wie funktioniert das mit dem global package dann, wenn von einer
>Komponente mehrere Instanzen vorhanden sind?
>Gibt es dann nicht einen Namenskonflikt?

Wenn man die Instanz eindeutig (bspw. über ein Generic) identifizieren 
kann, so kann man in der Komponenten-Beschreibung folgendes machen:

--Beispiel: 5 Instanziierungen einer Komponente, nur das Signal in 
--Instanziierung 1 soll sichtbar gemacht werden.

p_ProbeMap: process(ls_signal_of_interest)
begin
    if gComponentNumber=1 then
       probe_ls_signal_in_deep_hierarchy <= ls_signal_of_interest;
    else
       probe_ls_signal_in_deep_hierarchy <= 'Z';
    end if;
end process p_ProbeMap;


Muss man halt entscheiden, in welchem Stadium sich das Design befindet
(bezüglich der Hierarchie), ob eine oder mehrere Instanzen einer
Komponente verwendet werden (hier könnte die "init_signal_spy"-Variante
von Vorteil sein, weil man keine Generics mitführen muss).

Gruß,
SuperWilly

von SuperWilly (Gast)


Lesenswert?

Kennt jemand das Pendant zu "init_signal_spy" in ActiveHDL von Aldec ?

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.