Support dynamic array elements in std::randomize (#6896)
This commit is contained in:
parent
6abfaf23a5
commit
97d5844f2e
|
|
@ -184,6 +184,8 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
exprp = arrselp->fromp();
|
exprp = arrselp->fromp();
|
||||||
} else if (const AstStructSel* const strselp = VN_CAST(exprp, StructSel)) {
|
} else if (const AstStructSel* const strselp = VN_CAST(exprp, StructSel)) {
|
||||||
exprp = strselp->fromp();
|
exprp = strselp->fromp();
|
||||||
|
} else if (const AstCMethodHard* const methodp = VN_CAST(exprp, CMethodHard)) {
|
||||||
|
exprp = methodp->fromp();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -359,6 +361,9 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
||||||
} else if (AstStructSel* const structSelp = VN_CAST(exprp, StructSel)) {
|
} else if (AstStructSel* const structSelp = VN_CAST(exprp, StructSel)) {
|
||||||
exprp = structSelp->fromp();
|
exprp = structSelp->fromp();
|
||||||
continue; // Skip StructSel, continue traversing
|
continue; // Skip StructSel, continue traversing
|
||||||
|
} else if (AstCMethodHard* const methodp = VN_CAST(exprp, CMethodHard)) {
|
||||||
|
exprp = methodp->fromp();
|
||||||
|
continue;
|
||||||
} else if (AstVarRef* const varrefp = VN_CAST(exprp, VarRef)) {
|
} else if (AstVarRef* const varrefp = VN_CAST(exprp, VarRef)) {
|
||||||
randVarp = varrefp->varp();
|
randVarp = varrefp->varp();
|
||||||
varrefp->user1(true);
|
varrefp->user1(true);
|
||||||
|
|
|
||||||
|
|
@ -6781,12 +6781,18 @@ class WidthVisitor final : public VNVisitor {
|
||||||
// IEEE 1800-2023 (18.12) limits args to current scope variables.
|
// IEEE 1800-2023 (18.12) limits args to current scope variables.
|
||||||
// Verilator accepts this for compatibility with other simulators.
|
// Verilator accepts this for compatibility with other simulators.
|
||||||
continue;
|
continue;
|
||||||
} else if (VN_IS(exprp, VarRef) || VN_IS(exprp, ArraySel) || VN_IS(exprp, StructSel)) {
|
}
|
||||||
|
if (VN_IS(exprp, VarRef) || VN_IS(exprp, ArraySel) || VN_IS(exprp, StructSel)) {
|
||||||
// Valid usage
|
// Valid usage
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
argp->v3error("Non-variable arguments for 'std::randomize()'.");
|
|
||||||
}
|
}
|
||||||
|
if (const AstCMethodHard* const methodp = VN_CAST(exprp, CMethodHard)) {
|
||||||
|
if (methodp->method() == VCMethod::ARRAY_AT
|
||||||
|
|| methodp->method() == VCMethod::ARRAY_AT_WRITE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argp->v3error("Non-variable arguments for 'std::randomize()'.");
|
||||||
}
|
}
|
||||||
if (nullp) nullp->v3error("'std::randomize()' does not accept 'null' as arguments.");
|
if (nullp) nullp->v3error("'std::randomize()' does not accept 'null' as arguments.");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ typedef struct {int x;} struct_t;
|
||||||
class inner_class;
|
class inner_class;
|
||||||
logic [3:0] c;
|
logic [3:0] c;
|
||||||
logic [3:0] d[2];
|
logic [3:0] d[2];
|
||||||
|
logic [3:0] dyn[];
|
||||||
struct_t s;
|
struct_t s;
|
||||||
endclass
|
endclass
|
||||||
|
|
||||||
|
|
@ -20,9 +21,11 @@ endclass
|
||||||
|
|
||||||
module t;
|
module t;
|
||||||
initial begin
|
initial begin
|
||||||
|
int x = 2;
|
||||||
test_class example;
|
test_class example;
|
||||||
example = new;
|
example = new;
|
||||||
example.b = new;
|
example.b = new;
|
||||||
|
example.b.dyn = new[3];
|
||||||
|
|
||||||
// Simple array element access
|
// Simple array element access
|
||||||
repeat (5) begin
|
repeat (5) begin
|
||||||
|
|
@ -83,6 +86,12 @@ module t;
|
||||||
if (example.b.d[1] < 2 || example.b.d[1] > 6) $stop;
|
if (example.b.d[1] < 2 || example.b.d[1] > 6) $stop;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// Nested object with dynamic array: obj.b.dyn[x]
|
||||||
|
repeat (5) begin
|
||||||
|
if (std::randomize(example.b.dyn[x]) with {example.b.dyn[x] inside {[1 : 3]};} == 0) $stop;
|
||||||
|
if (example.b.dyn[x] < 1 || example.b.dyn[x] > 3) $stop;
|
||||||
|
end
|
||||||
|
|
||||||
// Nested object with struct: obj.b.s.x
|
// Nested object with struct: obj.b.s.x
|
||||||
repeat (5) begin
|
repeat (5) begin
|
||||||
if (std::randomize(example.b.s.x) with {example.b.s.x inside {[7 : 9]};} == 0) $stop;
|
if (std::randomize(example.b.s.x) with {example.b.s.x inside {[7 : 9]};} == 0) $stop;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue