How can I format a dynamic array of bits (or more correctly, logics) as a string, e.g., for UVM's convert2string? For example, I would like to convert
logic vdyn[];
...
vdyn = new [16] ('{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1});
to the string 0097
.
I thought the following would work (the #
are just to delimit the string for readability):
fmt = $sformatf("#%%%0dh#", (vdyn.size-1)/4 + 1); // "#%4h#"
vstr = $sformatf(fmt, { >> {vdyn}});
but it returns # x#
, at least in Questa 10.3d (I suspect this is a bug - I'd be interested if it works on other simulators).
I tried converting it to a packed array first, but that runs into other problems. Without a size constraint on the result, the source value always gets left-justified in the destination variable, e.g.:
logic [63:0] v64;
...
v64 = {>> {vdyn}}; // 64'h0097000000000000
There's no way to print out just the part I want without using variable-size slices. The following works, but it requires that I know the size of the array at compile time:
v64 = 16'({>> {vdyn}}); // 64'h0000000000000097
The best thing I've found is the following "double-reverse" (note that I'm using <<
here, not >>
):
v64 = {<< {vdyn}}; // 64'he900000000000000
v64 = {<< {v64}}; // 64'h0000000000000097
vstr = $sformatf(fmt, v64); // #0097#
It seems kind of hokey to have to do this, though. By the way, combining the first two statements into one doesn't work:
v64 = {<< {{<< {vdyn}}}}; // 64'hZ900000000000000
(v64[63]
is z
for some reason). Again, I suspect this is a bug in Questa 10.3d.
Try casting a slice of the array and loop through. For example an 4 entry slice that is cast to a 4-bits value. A slize can be done with the -:
or +:
operator (See IEEE Std 1800-2012 § 7.4.3 Operations on arrays and § 7.4.6 Indexing and slicing of arrays)
vstr = "";
for(int i=vdyn.size()-1; i>=0; i-=4) begin
vstr = $sformatf("%h%s", 4'({>>{vdyn[i -: 4]}}), vstr);
end
vstr = $sformatf("#%s#", vstr); // user formatting
The 4
s in the code can be changed to something else depending how much leading 0 or a non-power-of-two formatting is desired, but it must be a numeric constant
I tried your code on some other simulators. vstr = $sformatf(fmt, { >> {vdyn}});
sometimes gave me compiling errors. Casting the array to something bigger than its expected max size seems to work
fmt = $sformatf("#%%%0dh#", (vdyn.size-1)/4 + 1); // "#%4h#"
vstr = $sformatf(fmt, 128'({ >> {vdyn}})); // works iff 128>=vdyn.size