FriendFX
FriendFX

Reputation: 3079

How to concatenate a byte with a string in SystemVerilog

In ModelSim, the following code works just fine:

string r;
string s;
// ...assign some string to s...
integer i;
r = "";
for (i=s.len()-1; i>=0; i=i-1) begin
    if (s[i] != "\n") begin
        r = {s[i], r};
    end
end

In Aldec Riviera, this causes a compilation error Incompatible types at assignment: .r<string> <- s[i]<byte>.

Reading the SystemVerilog LRM, I can see that the curly braces seem to be only supported to concatenate strings, not bytes. So either ModelSim is not as strict with the LRM or it implicitly converts the s[i] byte to a one-character string (which seems sensible in this context). In Riviera, it looks like I have to convert the byte s[i] to a one-character string manually. What is the most efficient and concise solution (if possible without having to introduce a temporary variable)?

Upvotes: 1

Views: 15795

Answers (4)

Joniale
Joniale

Reputation: 585

Here a small example of code:

First, an example to create a byte dynamic array from a string. The dynamic array of bytes contains the ASCII CODE number representation of each character. The advantage is that this can be for example be randomized but strings cannot be randomized.

(created doing e.g.

for(i=0;i<stringvar.len(); i++) begin 
byte_din_array = {byte_din_array ,stringvar[i]}; //stringvar[i] will return empty byte if  the index would be beyond the string length
//The advantage of using stringvar[i] instead of stringvar.atoi(i) is that 
//the string can have all ASCII characters and not just numbers.
//Disadvantage is that the byte contains the ASCII CODE "number" 
//representation of the character and that is not human readable
end

).

Here is the example to convert the dynamic array of bytes back in a concatenated string. You may have used the previous dynamic array to be partly randomized (with constraints) inside an xfer or changed in post_randomize.

function string convert_byte_array2string(byte stringdescriptionholder[]);
    automatic string temp_str="";
    automatic byte byte_temp;
    automatic string str_test;
    for ( int unsigned i = 0; i<stringdescriptionholder.size(); i++)  begin
        i=i;//debug breakpoint
        byte_temp = stringdescriptionholder[i];
        str_test = string'(byte_temp); //the "string cast" will convert the numeric ASCII representation in a string character
        temp_str = {temp_str,str_test};
    end
    return temp_str;
endfunction

Upvotes: 0

MayurKubavat
MayurKubavat

Reputation: 371

Use atobin()/bintoa() functions for conversion between ASCII and Binary. Then you can use concatenation operator "{}" with either string/binary values.

Upvotes: 0

user597225
user597225

Reputation:

You're right, ModelSim is accepting invalid code. The spec explicitly defines the types involved with indexing and assignments.

A single character of a string variable is of type byte.

...

Values of integral type can be assigned to a string variable, but require a cast.

The spec further details the result of the concatenation operator based on the operands:

Each operand can be a string literal or an expression of string type.

Using the cast:

string r;
string s;
// ...assign some string to s...
integer i;
r = "";
for (i=s.len()-1; i>=0; i=i-1) begin
    if (s[i] != "\n") begin
        r = {string'(s[i]), r};
    end
end

Upvotes: 3

jclin
jclin

Reputation: 2559

I'm not sure about the following code is 100% OK in the simulator Aldec Riviera, because I try both yours and mine are ok in VCS. If you need to return string type of s, you may try the string method substr().

for (i=s.len()-1; i>=0; i=i-1) begin
    if (s[i] != "\n") begin
        r = {s.substr(i,i), r};
    end
end

Upvotes: 1

Related Questions