6
\$\begingroup\$

In Verilog, one can conveniently use _ anywhere in binary and hexadecimal literals. For example, 8'b0101_0011 and 32'hAEBB_23AF are valid literals.

Is it possible to have $display do a similar thing? I'm trying to display a 64-bit signal in hex, which is 16 characters long and difficult to parse visually. I would like a _ every four characters to ease reading.

\$\endgroup\$

2 Answers 2

7
\$\begingroup\$

There is no automatic way to have $display do that. But you can format it yourself to do that.

For example, this will print a 64-bit value like you wanted, with a 0x prefixed to the string.

$display("0x%04h_%04h_%04h_%04h", d[63:48], d[47:32], d[31:16], d[15:0]);

In this case, it's important to print the leading zeros; that is what the 0 in 04 means.

If I were doing this and using it more than once I would also wrap it in a function.

\$\endgroup\$
1
\$\begingroup\$

If your simulator supports SystemVerilog syntax, here is a function which can be used to display integers up to 64 bits. Wider values require multiple calls to the function. The function can display values as binary, decimal or hex.

module tb;

function string fmt (longint num, string radix, int width = 1);
    // Convert integer input into a string with underscores
    // for $display.  For example: 12345 -> 12_345.
    // radix should be [d|h|b].
    // width can be used for zero-padding on the left.
    // Any x/z passed into num gets converted to 0.
    // Reals passed into num are rounded to an integer.
    // Values greater than 64-bit are truncated.
    int pos, chars;
    string str, str2, fmtstr;
    str2 = "";

    fmtstr = {"%0", $sformatf("%0d", width), radix};
    str = $sformatf(fmtstr, num);

    chars = (radix == "d") ? 3 : 4;
    pos = 0;
    for (int i = str.len()-1; i>=0; i--) begin
        pos++;
        str2 = {str.getc(i), str2};
        if (pos % chars == 0) str2 = {"_", str2};
    end

    // Remove any leading underscore
    if (str2.getc(0) == "_") begin
        str2 = str2.substr(1, str2.len()-1);
    end
    return str2;
endfunction


reg [127:0] big;
reg [ 63:0] data;

initial begin
    data = 64'hfeed1234;
    $display(fmt(data, "h"));

    $display(fmt(98765, "d"));
    $display(fmt(33, "b", 8));

    big = 128'h123456789abcdef0777788889999aaaa;
    $display({fmt(big[127:64], "h"), "_", fmt(big[63:0], "h", 16)});
end

endmodule

Output:

feed_1234
98_765
0010_0001
1234_5678_9abc_def0_7777_8888_9999_aaaa
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.