Subclass constraints are ANDed with every inherited constraint, except a block replaced by name. A derived class therefore narrows the solution space and never widens it.
Layer | Owner | Content and lifetime |
|---|---|---|
Legality | Protocol spec | valid_c: what the spec permits, never disabled except for error injection |
Typicality | VIP author | Soft defaults and weights, overridable per test |
Test intent | Test writer | Subclass, inline, or policy; lives for one test |
The base transaction carries only legality. Every narrower preference lives in a layer above it.
The next listing is not run in this course's checks. It is classes only, with no top module.
// not-run: classes only, no top module
class bus_txn;
rand bit [31:0] addr;
rand bit [3:0] len;
rand bit [2:0] size;
rand bit write;
constraint valid_c {
len inside {[1:15]};
size <= 3'd2;
addr % (32'd1 << size) == 0;
}
constraint typical_c {
soft len inside {[1:4]};
soft size == 3'd2;
}
endclass
class long_burst_txn extends bus_txn;
constraint intent_c { len inside {[12:15]}; }
endclass
class relaxed_txn extends bus_txn;
constraint typical_c {
soft len inside {[1:15]};
soft size == 3'd2; // repeated: the override replaces the whole block
}
endclassSoft marks a low-priority preference per expression: the solver keeps a maximal satisfiable subset against hard constraints. The same-named typical_c block replaces the whole parent block instead of ANDing. Every preference in it goes, so the override repeats soft size == 3'd2 to keep that one. That is why block granularity is the override granularity.
No DDR window or bring-up length belongs in the base: those are test intent, not legality.
A hard test constraint beats soft typicality with no ceremony and no constraint_mode call.
Block naming is the override granularity, so legality and typicality stay in separate blocks.
The hard intent wins over the soft preference for that expression. Legality still holds, so the burst stays aligned and inside bounds.
A layering failure in the base class. Tests fight over-tight hard constraints instead of overriding soft typicality.
A legality function plus a testbench that proves bias never changes the verdict.
module tb_layers;
reg [31:0] addr;
reg [3:0] len;
reg [2:0] size;
reg bias_high;
reg ok;
reg prefer;
integer problems;
// The three valid_c rules, and nothing else.
task automatic check;
begin
ok = 1;
if (len < 1 || len > 15) ok = 0;
if (size > 2) ok = 0;
if ((addr % (32'd1 << size)) != 0) ok = 0;
prefer = (bias_high && len >= 12);
end
endtask
initial begin
problems = 0;
bias_high = 0;
addr = 32'h1000; len = 4; size = 2; check; if (!ok) problems = problems + 1;
addr = 32'h1003; len = 1; size = 0; check; if (!ok) problems = problems + 1;
addr = 32'h2000; len = 15; size = 2; check; if (!ok) problems = problems + 1;
addr = 32'h3000; len = 0; size = 2; check; if (ok) problems = problems + 1;
addr = 32'h1002; len = 4; size = 2; check; if (ok) problems = problems + 1;
addr = 32'h1000; len = 4; size = 3; check; if (ok) problems = problems + 1;
bias_high = 1;
addr = 32'h1000; len = 4; size = 2; check;
if (!ok) problems = problems + 1;
if (prefer) problems = problems + 1;
addr = 32'h2000; len = 15; size = 2; check;
if (!ok) problems = problems + 1;
if (!prefer) problems = problems + 1;
if (problems == 0) $display("PASS: legality admits 3 shapes, rejects 3, bias changes none");
else $fatal(1, "FAIL: found %0d unexpected verdicts", problems);
$finish;
end
endmodule