Merge pull request #852 from larsclausen/vvp-string-vpi
vvp: Handle null-bytes in a conistent way when reading through VPI
This commit is contained in:
commit
08f2c88fcf
|
|
@ -0,0 +1,4 @@
|
|||
Const Positive yes
|
||||
Const Negative NO
|
||||
Var Positive yes
|
||||
Var Negative NO
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
first..last first,last last..first
|
||||
(a)..(c) (a,b,c) (c)..(a)
|
||||
(a )..(c ) (a,b,c) (c )..(a )
|
||||
sumsqr(3,4) = 25
|
||||
sumsqr(5,12) = 169
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
module test;
|
||||
reg expected = 1;
|
||||
initial begin
|
||||
$display("Const Positive %s", 1 ? "yes" : "NO");
|
||||
$display("Const Negative %s", !1 ? "yes" : "NO");
|
||||
$display("Var Positive %s", expected ? "yes" : "NO");
|
||||
$display("Var Negative %s", !expected ? "yes" : "NO");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// Check that null-bytes are handled consistently between string literals,
|
||||
// number literals and signals of all kinds, especially when formatting as a
|
||||
// string.
|
||||
|
||||
module test;
|
||||
|
||||
reg failed = 1'b0;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val != exp) begin \
|
||||
$display("FAILED(%0d): Expected '%0s', got '%0s'.", `__LINE__, exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
reg [255:0] s;
|
||||
reg [31:0] x;
|
||||
reg [31:0] y[1:0];
|
||||
wire [31:0] z;
|
||||
wire [31:0] w;
|
||||
|
||||
assign z = "\000a\000b";
|
||||
assign w = 32'h00610062;
|
||||
|
||||
initial begin
|
||||
$sformat(s, ":%x:%0x:%s:%0s:", "\000a\000b", "\000a\000b", "\000a\000b", "\000a\000b");
|
||||
`check(s, ":00610062:610062: a b:a b:")
|
||||
$sformat(s, ":%x:%0x:%s:%0s:", 32'h00610062, 32'h00610062, 32'h00610062, 32'h00610062);
|
||||
`check(s, ":00610062:610062: a b:a b:")
|
||||
|
||||
x = "\000a\000b";
|
||||
$sformat(s, ":%x:%0x:%s:%0s:", x, x, x, x);
|
||||
`check(s, ":00610062:610062: a b:a b:")
|
||||
|
||||
x = 32'h00610062;
|
||||
$sformat(s, ":%x:%0x:%s:%0s:", x, x, x, x);
|
||||
`check(s, ":00610062:610062: a b:a b:")
|
||||
|
||||
y[0] = "\000a\000b";
|
||||
$sformat(s, ":%x:%0x:%s:%0s:", y[0], y[0], y[0], y[0]);
|
||||
`check(s, ":00610062:610062: a b:a b:")
|
||||
|
||||
y[1] = 32'h00610062;
|
||||
$sformat(s, ":%x:%0x:%s:%0s:", y[1], y[1], y[1], y[1]);
|
||||
`check(s, ":00610062:610062: a b:a b:")
|
||||
|
||||
$sformat(s, ":%x:%0x:%s:%0s:", z, z, z, z);
|
||||
`check(s, ":00610062:610062: a b:a b:")
|
||||
|
||||
$sformat(s, ":%x:%0x:%s:%0s:", w, w, w, w);
|
||||
`check(s, ":00610062:610062: a b:a b:")
|
||||
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// Check that the empty string "" is equivalent to 8'h00
|
||||
|
||||
module test;
|
||||
|
||||
reg failed = 1'b0;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val != exp) begin \
|
||||
$display("FAILED(%0d): Expected '%0s', got '%0s'.", `__LINE__, exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
reg [47:0] s;
|
||||
reg [7:0] x;
|
||||
wire [7:0] y;
|
||||
|
||||
assign y = "";
|
||||
|
||||
initial begin
|
||||
`check("", 8'h00);
|
||||
`check($bits(""), 8);
|
||||
|
||||
$sformat(s, ":%s:%0s:", "", "");
|
||||
`check(s, ": ::");
|
||||
|
||||
x = 8'h00;
|
||||
$sformat(s, ":%s:%0s:", x, x);
|
||||
`check(s, ": ::");
|
||||
|
||||
$sformat(s, ":%s:%0s:", y, y);
|
||||
`check(s, ": ::");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -355,6 +355,7 @@ br_gh782e normal ivltests
|
|||
br_gh782f normal ivltests
|
||||
br_gh788 normal,-gno-io-range-error,-Wno-anachronisms ivltests gold=br_gh788.gold
|
||||
br_gh793 normal ivltests
|
||||
br_gh827 normal ivltests gold=br_gh827.gold
|
||||
br_ml20150315 normal ivltests gold=br_ml_20150315.gold
|
||||
br_ml20150321 CE ivltests
|
||||
br_mw20171108 normal ivltests
|
||||
|
|
@ -1646,6 +1647,8 @@ string9 normal ivltests gold=string9.gold
|
|||
string10 normal ivltests gold=string10.gold
|
||||
string11 normal ivltests gold=string11.gold
|
||||
string12 normal ivltests
|
||||
string13 normal ivltests
|
||||
string14 normal ivltests
|
||||
supply1 normal ivltests
|
||||
supply2 normal ivltests
|
||||
switch_primitives normal ivltests gold=switch_primitives.gold
|
||||
|
|
|
|||
|
|
@ -512,8 +512,6 @@ static void emit_number_as_string(ivl_net_const_t net_const)
|
|||
val |= (bits[idx-bit] == '1') ? 1 << (7-bit) : 0x00;
|
||||
}
|
||||
|
||||
/* Skip any NULL bytes. */
|
||||
if (val == 0) continue;
|
||||
/* Print some values that can be escaped. */
|
||||
if (val == '"') fprintf(vlog_out, "\\\"");
|
||||
else if (val == '\\') fprintf(vlog_out, "\\\\");
|
||||
|
|
|
|||
|
|
@ -346,13 +346,9 @@ static void remove_two_chars(char* str)
|
|||
void emit_string(const char* string)
|
||||
{
|
||||
char *buffer = strdup(string);
|
||||
char *bptr = buffer;
|
||||
char *cptr;
|
||||
fprintf(vlog_out, "\"");
|
||||
/* Prune any leading escaped NULL bytes. */
|
||||
while ((bptr[0] == '\\') && (bptr[1] == '0') &&
|
||||
(bptr[2] == '0') && (bptr[3] == '0')) bptr += 4;
|
||||
for (cptr = bptr; *cptr; cptr += 1) {
|
||||
for (cptr = buffer; *cptr; cptr += 1) {
|
||||
if (*cptr == '\\') {
|
||||
/* Replace any \011 with \t */
|
||||
if ((cptr[1] == '0') && (cptr[2] == '1') &&
|
||||
|
|
@ -381,7 +377,7 @@ void emit_string(const char* string)
|
|||
} else cptr += 3;
|
||||
}
|
||||
}
|
||||
if (*bptr) fprintf(vlog_out, "%s", bptr);
|
||||
if (*buffer) fprintf(vlog_out, "%s", buffer);
|
||||
free(buffer);
|
||||
fprintf(vlog_out, "\"");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ int __vpiStringConst::vpi_get(int code)
|
|||
{
|
||||
switch (code) {
|
||||
case vpiSize:
|
||||
return strlen(value_)*8;
|
||||
return value_len_ * 8;
|
||||
|
||||
case vpiSigned:
|
||||
return 0;
|
||||
|
|
@ -121,7 +121,7 @@ void __vpiStringConst::vpi_get_value(p_vpi_value vp)
|
|||
{
|
||||
unsigned uint_value;
|
||||
p_vpi_vecval vecp;
|
||||
unsigned size = strlen(value_);
|
||||
unsigned size = value_len_;
|
||||
char*rbuf = 0;
|
||||
char*cp;
|
||||
|
||||
|
|
@ -131,9 +131,22 @@ void __vpiStringConst::vpi_get_value(p_vpi_value vp)
|
|||
vp->format = vpiStringVal;
|
||||
// fallthrough
|
||||
case vpiStringVal:
|
||||
cp = value_;
|
||||
rbuf = (char *) need_result_buf(size + 1, RBUF_VAL);
|
||||
strcpy(rbuf, value_);
|
||||
vp->value.str = rbuf;
|
||||
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
// Ignore leading null-bytes and replace other null-bytes with space.
|
||||
// The LRM is not entirely clear on how null bytes should be handled.
|
||||
// This is the implementation chosen for iverilog.
|
||||
if (*cp)
|
||||
*rbuf++ = *cp;
|
||||
else if (rbuf != vp->value.str)
|
||||
*rbuf++ = ' ';
|
||||
|
||||
cp++;
|
||||
}
|
||||
*rbuf = '\0';
|
||||
break;
|
||||
|
||||
case vpiDecStrVal:
|
||||
|
|
|
|||
|
|
@ -635,6 +635,8 @@ static void vec4_get_value_string(const vvp_vector4_t&word_val, unsigned width,
|
|||
|
||||
if (char_val != 0)
|
||||
*cp++ = char_val;
|
||||
else if (cp != rbuf)
|
||||
*cp++ = ' ';
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < nchar ; idx += 1) {
|
||||
|
|
@ -645,8 +647,13 @@ static void vec4_get_value_string(const vvp_vector4_t&word_val, unsigned width,
|
|||
if (val == BIT4_1)
|
||||
char_val |= 1 << bdx;
|
||||
}
|
||||
// Ignore leading null-bytes and replace other null-bytes with space.
|
||||
// The LRM is not entirely clear on how null bytes should be handled.
|
||||
// This is the implementation chosen for iverilog.
|
||||
if (char_val != 0)
|
||||
*cp++ = char_val;
|
||||
else if (cp != rbuf)
|
||||
*cp++ = ' ';
|
||||
}
|
||||
|
||||
*cp = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue