Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.7k views
in Technique[技术] by (71.8m points)

verilog - How can I automatically scale a $display column width?

I want to $display strings in a column like in a fixed-width table. However, I don't know what the maximum column width of my strings is ahead of time.

Lets say I have an array of SystemVerilog strings (names). When I $display them, I guess at a width for the column (10), but my guess is too small:

module tb;

string names [5];

initial begin
    names = '{
        "ALU"           ,
        "COMPARATOR_3"  ,
        "MEMORY"        ,
        "FLOP"          ,
        "ram_macro_with_a_long_name"
    };

    // Display all elements of the array
    foreach (names[i]) begin
        $display("| %10s |", names[i]);
    end
end

endmodule

This is the output:

|        ALU |
| COMPARATOR_3 |
|     MEMORY |
|       FLOP |
| ram_macro_with_a_long_name |

This is the output I want:

|                        ALU |
|                 COMPARATOR |
|                     MEMORY |
|                       FLOP |
| ram_macro_with_a_long_name |

I could guess a really big number (like 100), but it might be way bigger than I need.

How can I automatically scale the width of the $display?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Loop through the array to calculate the maximum string length using the len array method. Refer to IEEE Std 1800-2017, section 6.16 String data type. Then create the format string using $sformatf.

module tb;

string names [5];
int maxlen = 0;
string fmt;

initial begin
    names = '{
        "ALU"           ,
        "COMPARATOR"    ,
        "MEMORY"        ,
        "FLOP"          ,
        "ram_macro_with_a_long_name"
    };

    // First, lets calculate the maximum string length
    foreach (names[i]) begin
        if (names[i].len() > maxlen) maxlen = names[i].len();
    end

    // Create the format which will be used by $display
    //      %%  ... double "%" is needed to create a literal "%"
    //      %0d ... this formats the maxlen number
    //      s   ... string format
    //      |   ... this is just the character I chose for the start/end of the field
    fmt = $sformatf("| %%%0ds |", maxlen);

    // Display all elements of the array
    foreach (names[i]) begin
        $display($sformatf(fmt, names[i]));
    end
end

endmodule

This is the output:

|                        ALU |
|                 COMPARATOR |
|                     MEMORY |
|                       FLOP |
| ram_macro_with_a_long_name |

Here is a runnable example on edaplayground.


That is right-justified. To get left-justified, use:

fmt = $sformatf("| %%-%0ds |", maxlen);


| ALU                        |
| COMPARATOR                 |
| MEMORY                     |
| FLOP                       |
| ram_macro_with_a_long_name |

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...