programonkey
programonkey

Reputation: 307

How to access VHDL signal attributes in ModelSim via TCL?

I am developing a CPU in VHDL. I am using ModelSim for simulation and testing. In the simulation script I load a program from a binary file to the instruction memory. Now I want to automatically check if the program fits into memory and abort simulation if it doesn't. Since the memory is basically an array of std_logic_vectors, all I would have to do is read the corresponding signal attribute for use in a comparison. My problem is: How do I access a VHDL signal attribute in TCL inside ModelSim?

The closest I have gotten so far is to use the describe command:

describe sim/:tb:uut:imem:mem_array

which prints something like

# Array(0 to 255) [length 256] of
#   Array(31 downto 0) [length 32] of
#     VHDL standard subtype STD_LOGIC

Now, of course I could parse the length out of there via string operations. But that would not be a very generic solution. Ideally I would like to have something like this:

set mem_size [get_attribute sim/:tb:uut:imem:mem_array'length]

I have searched stackoverflow, googled up and down and searched through the commands in the command reference manual, but I could not find a solution. I am confident there must be a rather easy solution and I just lack the proper wording to successfully search for it. To me, this doesn't look overly specific and I am sure this could come in hand on many occasions when automating design testing. I am using version 10.6.

I would be very grateful if an experienced ModelSim user could help me out.

Upvotes: 2

Views: 1896

Answers (2)

programonkey
programonkey

Reputation: 307

So, I actually found an easy solution. While further studying of the command reference manual brought to light that it is only possible to access a few special signal attributes and length is not one of them, I noticed that ModelSim automatically adds a size object to its object database for the memory array. So I can easily use

set ms [examine sim/:tb:uut:imem:mem_array_size]

to obtain the size and then check if the program fits. This is just perfect for me, elegant and easy.

Upvotes: 3

suoto
suoto

Reputation: 479

Disclaimer: I'm not a Tcl expert, so there's probably a more optimized solution out there.

There's a command called examine that you can use to get the value of obejcts.

I created a similar testbench here with a 256 x 32 array, the results were

VSIM> examine -radix hex sim/:tb:uut:imem:mem_array
# {32'hXXXXXXXX} {32'hXXXXXXXX} {32'hXXXXXXXX} {32'hXXXXXXXX} {32'hXXXXXXXX} ...

This is the value of sim/:tb:uut:imem:mem_array at the last simulation step (i.e., now).

The command return a list of values for each match (you can use wildcards), so in our case, it's a list with a single item. You can get the depth by counting the number of elements it returns:

VSIM> llength [lindex  [examine sim/:tb:uut:imem:mem_array] 0]
# 256

You can get the bit width of the first element by using examine -showbase -radix hex, which will return 32'hFFFFFFFF, where 32'h is the part you want to parse. Wrapping that into a function would look like

proc get_bit_width { signal } {
    set first_element [lindex [lindex [examine -radix hex -showbase $signal] 0] 0]
    # Replace everything after 'h, including 'h itself to return only the base
    return [regsub "'h.*" $first_element ""]
}

Hope this gives some pointers!

Upvotes: 3

Related Questions