Reputation: 307
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
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
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