Reputation: 3079
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
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
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
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
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