Traversing Access types in Modelsim

S

steven

Guest
Hi,

I have a testbench in which I am using access types to form a linked list.

e.g.

type MyType ;
myAccess is access MyType ;
type MyType is record
Data : integer ;
Next : myAccess ;
end record ;

signal MyObject : MyType
etc.

Is it possible to traverse the linked list interactively in the ModelSim 5.7
simulator?

If I

examine MyObject
{0 [20E00F8]}

How do I examine the object at address 20E00F8?

Thanks,

Steven
 
steven wrote:

I have a testbench in which I am using access types to form a linked list.

type MyType ;
myAccess is access MyType ;
type MyType is record
Data : integer ;
Next : myAccess ;
end record ;

signal MyObject : MyType
etc.

Is it possible to traverse the linked list interactively in the ModelSim 5.7
simulator?
Modelsim can display structured constants,
but not a dynamic structure like a linked list.

It's possible to write procedures to insert,
delete, or read list items, and use them in your simulation.
Modelsim just records what happens when
a simulation is run. Looking at waveforms
is viewing history, not making it.

If the simulation does dereference a
list item and assign that value to a signal
or variable, then you can observe that value.

If I examine MyObject
{0 [20E00F8]}

How do I examine the object at address 20E00F8?
Your testbench would have to dereference it
for you by name.

In a vhdl simulation, the only interesting thing
about viewing pointer addresses, is that this allows
you to verify that references are passed
correctly or change at the right time.

For example,
a model might use a input buffer rx_dat_ptr of

type buf_ptr_t is access unsigned;

to handle a packet of unknown size.

You might want to transfer the packet to another
buffer of the same type at just the right time like this:

rx_dat_ptr := new unsigned'(ex_dat_ptr.all);

-- Mike Treseler
 
moogyd@yahoo.co.uk (steven) wrote in message news:<f50c77ef.0308210739.4032e0c5@posting.google.com>...
Hi,

I have a testbench in which I am using access types to form a linked list.

e.g.

type MyType ;
myAccess is access MyType ;
type MyType is record
Data : integer ;
Next : myAccess ;
end record ;

signal MyObject : MyType
etc.

Is it possible to traverse the linked list interactively in the ModelSim 5.7
simulator?

If I

examine MyObject
{0 [20E00F8]}

How do I examine the object at address 20E00F8?

Thanks,

Steven
Thanks for the input Mike.

I actually carried on looking at the problem, and managed to traverse
the linked list as follows.

examine MyObject
#{0 [20E0108]}
examine MyObject.NextPacket
#{0 [20E0128]}
examine MyObject.NextPacket.NextPacket
#{0 [20E0148]}
examine MyObject.NextPacket.NextPacket.NextPacket
#{0 [20E0168]}

I can put this into a tcl loop and dump entire the linked list.

Thanks,

Steven
 
steven wrote:

Thanks for the input Mike.

I actually carried on looking at the problem, and managed to traverse
the linked list as follows.
....

examine MyObject.NextPacket.NextPacket.NextPacket

#{0 [20E0168]}

I can put this into a tcl loop and dump entire the linked list.
Interesting.
Consider posting your example and script.

-- Mike Treseler
 
steven wrote:

I have a simple example.
. . .
set Node LinkedList.head
while {[string compare [examine $Node] NULL] != 0} {
echo [examine $Node]
set Node $Node.NextNode
}

This loops around examining Nodes until we reach the end of the linked
list (indicated by NULL next field).
OK, let's try it:

VSIM 1> vsim -c play;run 1
VSIM 2> do linklist.tcl
# LinkedList.head
# {[40274018] {0} {[40274028] }}
# {[40274028] {1} {[40274038] }}
# {[40274038] {2} {[40274048] }}
# {[40274048] {3} {[40274058] }}
# {[40274058] {4} {[40274068] }}
# {[40274068] {5} {[40274078] }}
# {[40274078] {6} {[40274088] }}
# {[40274088] {7} {[40274098] }}
# {[40274098] {8} {[402740A8] }}
# {[402740A8] {9} {[402740B8] }}
# {[402740B8] {10} {NULL}}
VSIM 3>

cool!

To demonstrate how to do something similar
in vhdl, I have added a process "main"
to your testbench (now named linklist).

This version uses your init procedure, then
outputs a list element to the console and
to a signal named listwave every 10 ns.
You can view listwave using the command:
add wave *
before running.

-- Mike Treseler

-------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.NUMERIC_STD.all;

-- By Steven (moogyd)
-- Main process by Mike Treseler Tue Aug 26 11:11:12 2003
entity linklist is
end linklist;

--
architecture behav of linklist is

-- Define node
type Node_t; -- Forward declaration
type Ptr_t is access Node_t;
type Node_t is record
Id : integer;
NextNode : Ptr_t;
end record Node_t;

-- Define Linked list tye
type LinkedList_t is record
Count : integer;
Head : Ptr_t;
end record LinkedList_t;

constant NumElements_c : integer := 10;
shared variable LinkedList : LinkedList_t; --:= (0,NULL) ;
signal listwave : unsigned(7 downto 0);

procedure initialize is
variable NextNode : Ptr_t;
variable CurrNode : Ptr_t;
begin -- procedure initialize
CurrNode := new Node_t;
CurrNode.id := 0;
LinkedList.Head := CurrNode;
for i in 1 to NumElements_c loop
NextNode := new Node_t;
CurrNode.NextNode := NextNode;
CurrNode := NextNode;
CurrNode.Id := i;
end loop;
CurrNode.NextNode := null; -- End of List
end procedure initialize;

begin

main : process
variable LastNode : Ptr_t;
variable CurrNode : Ptr_t;
begin
initialize;
LastNode := LinkedList.head;
assert LastNode.Id = 0 report "wrong list" severity error;
gen_wave : while true loop
CurrNode := LastNode.NextNode;
exit gen_wave when CurrNode = null;
listwave <= to_unsigned(CurrNode.Id, listwave'length);
wait for 10 ns;
report integer'image(CurrNode.Id);
LastNode := CurrNode;
end loop gen_wave;
wait;
end process main;
end behav;
 
Mike Treseler <mike.treseler@flukenetworks.com> wrote in message news:<3F4BA655.7040509@flukenetworks.com>...
steven wrote:

I have a simple example.
. . .
set Node LinkedList.head
while {[string compare [examine $Node] NULL] != 0} {
echo [examine $Node]
set Node $Node.NextNode
}

This loops around examining Nodes until we reach the end of the linked
list (indicated by NULL next field).

OK, let's try it:

VSIM 1> vsim -c play;run 1
VSIM 2> do linklist.tcl
# LinkedList.head
# {[40274018] {0} {[40274028] }}
# {[40274028] {1} {[40274038] }}
# {[40274038] {2} {[40274048] }}
# {[40274048] {3} {[40274058] }}
# {[40274058] {4} {[40274068] }}
# {[40274068] {5} {[40274078] }}
# {[40274078] {6} {[40274088] }}
# {[40274088] {7} {[40274098] }}
# {[40274098] {8} {[402740A8] }}
# {[402740A8] {9} {[402740B8] }}
# {[402740B8] {10} {NULL}}
VSIM 3

cool!

To demonstrate how to do something similar
in vhdl, I have added a process "main"
to your testbench (now named linklist).

This version uses your init procedure, then
outputs a list element to the console and
to a signal named listwave every 10 ns.
You can view listwave using the command:
add wave *
before running.

-- Mike Treseler

-------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.NUMERIC_STD.all;
SNIP

begin

main : process
variable LastNode : Ptr_t;
variable CurrNode : Ptr_t;
begin
initialize;
LastNode := LinkedList.head;
assert LastNode.Id = 0 report "wrong list" severity error;
gen_wave : while true loop
CurrNode := LastNode.NextNode;
exit gen_wave when CurrNode = null;
listwave <= to_unsigned(CurrNode.Id, listwave'length);
wait for 10 ns;
report integer'image(CurrNode.Id);
LastNode := CurrNode;
end loop gen_wave;
wait;
end process main;
end behav;
Mike,

I had something similar (not as elegant) to check the initialization.
The tcl loop was needed to work out why the code didn't work at
various points through a simulation.

I believe that in verilog, I could have called a verilog task from the
testbench interactively at the simulator prompt. I don't think that
this capability is available in VHDL.

Steven
 
"Jonathan Bromley" <jonathan.bromley@doulos.com> wrote in message news:<biho02$itp$1$8302bc10@news.demon.co.uk>...
"Mike Treseler" <mike.treseler@flukenetworks.com> wrote in
message news:3F4BA655.7040509@flukenetworks.com...
steven wrote:
. . .
set Node LinkedList.head
while {[string compare [examine $Node] NULL] != 0} {
echo [examine $Node]
set Node $Node.NextNode
}

This loops around examining Nodes until we reach the end of the linked
list (indicated by NULL next field).

OK, let's try it:
[snip results]
cool!

It's a neat script, but I put it to you that it
is distinctly uncool. The fact that we can't traverse
the dynamic structure *from the information returned
by the [examine] command* is a significant flaw in
ModelSim's debugger and we should be putting
pressure on them to fix it. It's absurd that
the record's field name must be hard-coded into
the script.

--

Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
Just a small point. The describe command is available within modelsim
in order to identify the field names and types within a record.

VSIM> describe linkedlist.head
# Access type
# Record [2 fields]
# Field #1 "id" =>
# Scalar (-2147483648 to 2147483647)
# Field #2 "nextnode" =>
# Access type
#

Steven
 

Welcome to EDABoard.com

Sponsor

Back
Top