Jump to content

Silent buffer overflow in uvm_packer


Recommended Posts

Packing more than 4KB with uvm_packer results in a silent buffer overflow.  This then causes silent data corruption on unpack.  This issue is present in both UVM 1.2 and UVM 1800.2 2020.

The attached test case was run on Questa 2020.4_2.

UVM 1800.2-2020 1.1

Commands:

gcc -m64 -fPIC -DQUESTA -g -W -shared -x c -I${QUESTA_ROOT}/include ${UVM_HOME}/src/dpi/uvm_dpi.cc -o uvm_dpi.so
qrun -sv +incdir+${UVM_HOME}/src +define+UVM_1800_2_2020 -sv_lib uvm_dpi ${UVM_HOME}/src/uvm_pkg.sv uvm_packer_buffer_overflow.sv

Errors:

# UVM_ERROR uvm_packer_buffer_overflow.sv(49) @ 0: reporter [uvm_packer_buffer_overflow] data_out[1024]:0x00000000 != data_in[1022]:0x9b387ab5
# UVM_ERROR uvm_packer_buffer_overflow.sv(49) @ 0: reporter [uvm_packer_buffer_overflow] data_out[1025]:0x00000000 != data_in[1023]:0x5d3822c4
# UVM_ERROR uvm_packer_buffer_overflow.sv(49) @ 0: reporter [uvm_packer_buffer_overflow] data_out[1026]:0x00000000 != data_in[1024]:0xc6462f4a

UVM 1.2

Command:

qrun -sv +define+UVM_1_2 uvm_packer_buffer_overflow.sv

Error:

# UVM_ERROR uvm_packer_buffer_overflow.sv(49) @ 0: reporter [uvm_packer_buffer_overflow] data_out[1024]:0x00000000 != data_in[1024]:0xc6462f4a

Test

program uvm_packer_buffer_overflow;
    import uvm_pkg::*;
    `include "uvm_macros.svh"

    initial begin
        int uvm_packer_max_bytes = 4096;
        int uvm_packer_max_dwords = uvm_packer_max_bytes / 4;
        int unsigned data_in[] = new[uvm_packer_max_dwords + 1];
        int unsigned data_out[];
        int offset;
        uvm_packer p = new();

        foreach (data_in[i]) begin
            data_in[i] = $urandom();
        end

        foreach (data_in[i]) begin
            p.pack_field_int(data_in[i], $size(data_in[i]));
        end

        `ifdef UVM_1_2
            p.set_packed_size();
            p.get_ints(data_out);
        `endif

        `ifdef UVM_1800_2_2020
            p.get_packed_ints(data_out);
            // 1800.2 2020 prepends m_pack_iter and m_unpack_iter
            offset = 2;
        `endif

        assert (data_out.size() == (data_in.size() + offset)) else begin
            `uvm_error("uvm_packer_buffer_overflow", $sformatf(
                "data_out.size:%0d != (data_in.size:%0d + offset:%0d):%0d",
                data_out.size(),
                data_in.size(),
                offset,
                data_in.size() + offset
            ))
        end

        foreach (data_out[i]) begin
            // Don't compare the following entries for UVM 1800.2 2020:
            // data_out[0]: m_pack_iter
            // data_out[1]: m_unpack_iter
            if (i < offset) continue;

            if (data_out[i] != data_in[i - offset]) begin
                `uvm_error("uvm_packer_buffer_overflow", $sformatf(
                    "data_out[%0d]:0x%x != data_in[%0d]:0x%x",
                    i,
                    data_out[i],
                    i - offset,
                    data_in[i - offset]
                ))
            end
        end
    end
endprogram

uvm_packer_buffer_overflow.sv

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...