tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.module TopModule (
input logic clk,
input logic rst,
input logic [3:0] req,
input logic lock,
output logic [3:0] grant,
output logic grant_valid
);
// Circular-queue arbiter state.
// ptr : position to begin scanning (just past the last winner)
// held : a locked hold is active from a previous granted cycle
// held_id : the requester the hold is nailed to
logic [1:0] ptr;
logic held;
logic [1:0] held_id;
// next-state
logic [1:0] ptr_n;
logic held_n;
logic [1:0] held_id_n;
// Scan up from ptr, wrapping 3->0, granting the first asker.
logic found;
logic [1:0] winner;
always_comb begin
found = 1'b0;
winner = 2'b00;
for (int i = 0; i < 4; i = i + 1) begin
if (!found && req[ptr + i[1:0]]) begin
found = 1'b1;
winner = ptr + i[1:0];
end
end
end
// Outputs (Mealy) and next state.
always_comb begin
grant = 4'b0000;
grant_valid = 1'b0;
ptr_n = ptr;
held_n = 1'b0;
held_id_n = held_id;
if (held) begin
if (req[held_id]) begin
// Held requester keeps asking: grant stays nailed to it.
grant = 4'b0001 << held_id;
grant_valid = 1'b1;
ptr_n = held_id + 2'd1;
if (lock) begin
// Lock still high: hold continues.
held_n = 1'b1;
held_id_n = held_id;
end else begin
// Lock dropped: this cycle still owned, sharing resumes next.
held_n = 1'b0;
end
end else begin
// Held requester dropped its req: dead air, hold is over.
// Counts as served; sharing resumes just past it.
grant = 4'b0000;
grant_valid = 1'b0;
held_n = 1'b0;
ptr_n = held_id + 2'd1;
end
end else begin
// Normal arbitration by the start rule.
if (found) begin
grant = 4'b0001 << winner;
grant_valid = 1'b1;
ptr_n = winner + 2'd1;
if (lock) begin
// Lock high on a granted cycle latches this winner.
held_n = 1'b1;
held_id_n = winner;
end
end else begin
// No asker: idle keeps your place (lock with no grant does nothing).
grant_valid = 1'b0;
ptr_n = ptr;
end
end
end
always_ff @(posedge clk) begin
if (rst) begin
// Synchronous: clear any hold, restart the order.
ptr <= 2'd0;
held <= 1'b0;
held_id <= 2'd0;
end else begin
ptr <= ptr_n;
held <= held_n;
held_id <= held_id_n;
end
end
endmodule
cat > tb_sanity.sv <<'EOF'
module tb;
logic clk=0, rst, lock;
logic [3:0] req;
logic [3:0] grant;
logic grant_valid;
TopModule dut(.clk,.rst,.req,.lock,.grant,.grant_valid);
always #5 clk=~clk;
task step; @(posedge clk); #1; $display("req=%b lock=%b -> grant=%b gv=%b", req,lock,grant,grant_valid); endtask
initial begin
rst=1; req=0; lock=0; @(posedge clk); #1;
rst=0;
$display("-- all four forever (expect 0,1,2,3,0):");
req=4'b1111; lock=0;
step; step; step; step; step;
$display("-- lone requester 2 keeps winning:");
req=4'b0100; step; step;
$display("-- lock hold on req1: latch then nail while lock high:");
req=4'b1111; lock=1; step; // grants someone, latches
step; step; // nailed to that winner
$display("-- drop lock, req still high (owns cycle then resume):");
lock=0; step; step;
$display("-- dead air: hold then held req goes low:");
req=4'b1111; lock=1; step; // latch a winner w
// now drop that winner's req: need to know w; just drop all but keep others
lock=1; req=4'b1111; step; // nailed
$finish;
end
endmodule
EOF
iverilog -g2012 -o sim dut.sv tb_sanity.sv && vvp simdut.sv:26: sorry: constant selects in always_* processes are not currently supported (all bits will be included). -- all four forever (expect 0,1,2,3,0): req=1111 lock=0 -> grant=0010 gv=1 req=1111 lock=0 -> grant=0100 gv=1 req=1111 lock=0 -> grant=1000 gv=1 req=1111 lock=0 -> grant=0001 gv=1 req=1111 lock=0 -> grant=0010 gv=1 -- lone requester 2 keeps winning: req=0100 lock=0 -> grant=0100 gv=1 req=0100 lock=0 -> grant=0100 gv=1 -- lock hold on req1: latch then nail while lock high: req=1111 lock=1 -> grant=1000 gv=1 req=1111 lock=1 -> grant=1000 gv=1 req=1111 lock=1 -> grant=1000 gv=1 -- drop lock, req still high (owns cycle then resume): req=1111 lock=0 -> grant=0001 gv=1 req=1111 lock=0 -> grant=0010 gv=1 -- dead air: hold then held req goes low: req=1111 lock=1 -> grant=0010 gv=1 req=1111 lock=1 -> grant=0010 gv=1 tb_sanity.sv:26: $finish called at 146 (1s) [stdout] dut.sv:26: sorry: constant selects in always_* processes are not currently supported (all bits will be included). -- all four forever (expect 0,1,2,3,0): req=1111 lock=0 -> grant=0010 gv=1 req=1111 lock=0 -> grant=0100 gv=1 req=1111 lock=0 -> grant=1000 gv=1 req=1111 lock=0 -> grant=0001 gv=1 req=1111 lock=0 -> grant=0010 gv=1 -- lone requester 2 keeps winning: req=0100 lock=0 -> grant=0100 gv=1 req=0100 lock=0 -> grant=0100 gv=1 -- lock hold on req1: latch then nail while lock high: req=1111 lock=1 -> grant=1000 gv=1 req=1111 lock=1 -> grant=1000 gv=1 req=1111 lock=1 -> grant=1000 gv=1 -- drop lock, req still high (owns cycle then resume): req=1111 lock=0 -> grant=0001 gv=1 req=1111 lock=0 -> grant=0010 gv=1 -- dead air: hold then held req goes low: req=1111 lock=1 -> grant=0010 gv=1 req=1111 lock=1 -> grant=0010 gv=1 tb_sanity.sv:26: $finish called at 146 (1s)
module TopModule (
input logic clk,
input logic rst,
input logic [3:0] req,
input logic lock,
output logic [3:0] grant,
output logic grant_valid
);
// Circular-queue arbiter state.
// ptr : position to begin scanning (just past the last winner)
// held : a locked hold is active from a previous granted cycle
// held_id : the requester the hold is nailed to
logic [1:0] ptr;
logic held;
logic [1:0] held_id;
// next-state
logic [1:0] ptr_n;
logic held_n;
logic [1:0] held_id_n;
// Rotate req so that rr[i] corresponds to actual requester (ptr+i) mod 4.
logic [3:0] rr;
always_comb begin
case (ptr)
2'd0: rr = req;
2'd1: rr = {req[0], req[3:1]};
2'd2: rr = {req[1:0], req[3:2]};
default: rr = {req[2:0], req[3]};
endcase
end
// Priority scan on the rotated vector: first asker starting just past
// the last winner, wrapping 3 -> 0.
logic found;
logic [1:0] rel;
logic [1:0] winner;
always_comb begin
found = |rr;
if (rr[0]) rel = 2'd0;
else if (rr[1]) rel = 2'd1;
else if (rr[2]) rel = 2'd2;
else rel = 2'd3;
winner = ptr + rel;
end
// Whether the currently held requester is still asking (index-safe).
logic req_held;
assign req_held = req[held_id];
// Outputs (Mealy) and next state.
always_comb begin
grant = 4'b0000;
grant_valid = 1'b0;
ptr_n = ptr;
held_n = 1'b0;
held_id_n = held_id;
if (held) begin
if (req_held) begin
// Held requester keeps asking: grant stays nailed to it.
grant = 4'b0001 << held_id;
grant_valid = 1'b1;
ptr_n = held_id + 2'd1;
if (lock) begin
// Lock still high: hold continues.
held_n = 1'b1;
held_id_n = held_id;
end else begin
// Lock dropped: this cycle still owned, sharing resumes next.
held_n = 1'b0;
end
end else begin
// Held requester dropped its req: dead air, hold is over.
// Counts as served; sharing resumes just past it.
grant = 4'b0000;
grant_valid = 1'b0;
held_n = 1'b0;
ptr_n = held_id + 2'd1;
end
end else begin
// Normal arbitration by the start rule.
if (found) begin
grant = 4'b0001 << winner;
grant_valid = 1'b1;
ptr_n = winner + 2'd1;
if (lock) begin
// Lock high on a granted cycle latches this winner.
held_n = 1'b1;
held_id_n = winner;
end
end else begin
// No asker: idle keeps your place (lock with no grant does nothing).
grant_valid = 1'b0;
ptr_n = ptr;
end
end
end
always_ff @(posedge clk) begin
if (rst) begin
// Synchronous: clear any hold, restart the order.
ptr <= 2'd0;
held <= 1'b0;
held_id <= 2'd0;
end else begin
ptr <= ptr_n;
held <= held_n;
held_id <= held_id_n;
end
end
endmodule
cat > tb2.sv <<'EOF'
module tb;
logic clk=0, rst, lock;
logic [3:0] req;
logic [3:0] grant;
logic grant_valid;
TopModule dut(.clk,.rst,.req,.lock,.grant,.grant_valid);
always #5 clk=~clk;
// drive inputs just after edge; sample outputs just before next edge
task automatic cyc(input [3:0] r, input l, input string note);
req=r; lock=l; #8; // settle within the cycle, before posedge at +?
$display("%-40s req=%b lock=%b | grant=%b gv=%b", note, req, lock, grant, grant_valid);
@(posedge clk);
endtask
initial begin
rst=1; req=0; lock=0; @(posedge clk);
rst=0;
cyc(4'b1111,0,"all4 #1 (exp grant0)");
cyc(4'b1111,0,"all4 #2 (exp grant1)");
cyc(4'b1111,0,"all4 #3 (exp grant2)");
cyc(4'b1111,0,"all4 #4 (exp grant3)");
cyc(4'b1111,0,"all4 #5 (exp grant0)");
cyc(4'b0100,0,"lone2 (exp grant2)");
cyc(4'b0100,0,"lone2 (exp grant2)");
cyc(4'b0000,0,"idle (exp gv=0, keep place ptr=3)");
cyc(4'b1000,0,"only3 (exp grant3, ptr was 3)");
// lock/hold: next winner after ptr=0 among 1111 is 0; latch it
cyc(4'b1111,1,"lock latch (exp grant0, held)");
cyc(4'b1111,1,"held nailed (exp grant0)");
cyc(4'b1111,1,"held nailed (exp grant0)");
cyc(4'b1111,0,"lock drop, req0 hi (exp grant0, owns)");
cyc(4'b1111,0,"resume just past (exp grant1)");
// dead air: latch a winner then drop its req
cyc(4'b1111,1,"lock latch (exp grant2, held)");
cyc(4'b1011,1,"held req2 low -> dead air (exp gv=0)");
cyc(4'b1011,1,"resume, lock still hi, re-latch (exp grant3)");
$finish;
end
endmodule
EOF
iverilog -g2012 -Wall -o sim2 dut.sv tb2.sv && echo "=== compiled clean ===" && vvp sim2dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:39: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:39: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:39: sorry: constant selects in always_* processes are not currently supported (all bits will be included). === compiled clean === all4 #1 (exp grant0) req=1111 lock=0 | grant=xxxx gv=1 all4 #2 (exp grant1) req=1111 lock=0 | grant=xxxx gv=1 all4 #3 (exp grant2) req=1111 lock=0 | grant=xxxx gv=1 all4 #4 (exp grant3) req=1111 lock=0 | grant=xxxx gv=1 all4 #5 (exp grant0) req=1111 lock=0 | grant=xxxx gv=1 lone2 (exp grant2) req=0100 lock=0 | grant=xxxx gv=1 lone2 (exp grant2) req=0100 lock=0 | grant=xxxx gv=1 idle (exp gv=0, keep place ptr=3) req=0000 lock=0 | grant=0000 gv=0 only3 (exp grant3, ptr was 3) req=1000 lock=0 | grant=xxxx gv=1 lock latch (exp grant0, held) req=1111 lock=1 | grant=xxxx gv=1 held nailed (exp grant0) req=1111 lock=1 | grant=0000 gv=0 held nailed (exp grant0) req=1111 lock=1 | grant=xxxx gv=1 lock drop, req0 hi (exp grant0, owns) req=1111 lock=0 | grant=0000 gv=0 resume just past (exp grant1) req=1111 lock=0 | grant=xxxx gv=1 lock latch (exp grant2, held) req=1111 lock=1 | grant=xxxx gv=1 held req2 low -> dead air (exp gv=0) req=1011 lock=1 | grant=0000 gv=0 resume, lock still hi, re-latch (exp grant3) req=1011 lock=1 | grant=xxxx gv=1 tb2.sv:36: $finish called at 175 (1s) [stdout] dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:25: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:39: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:39: sorry: constant selects in always_* processes are not currently supported (all bits will be included). dut.sv:39: sorry: constant selects in always_* processes are not currently supported (all bits will be included). === compiled clean === all4 #1 (exp grant0) req=1111 lock=0 | grant=xxxx gv=1 all4 #2 (exp grant1) req=1111 lock=0 | grant=xxxx gv=1 all4 #3 (exp grant2) req=1111 lock=0 | grant=xxxx gv=1 all4 #4 (exp grant3) req=1111 lock=0 | grant=xxxx gv=1 all4 #5 (exp grant0) req=1111 lock=0 | grant=xxxx gv=1 lone2 (exp grant2) req=0100 lock=0 | grant=xxxx gv=1 lone2 (exp grant2) req=0100 lock=0 | grant=xxxx gv=1 idle (exp gv=0, keep place ptr=3) req=0000 lock=0 | grant=0000 gv=0 only3 (exp grant3, ptr was 3) req=1000 lock=0 | grant=xxxx gv=1 lock latch (exp grant0, held) req=1111 lock=1 | grant=xxxx gv=1 held nailed (exp grant0) req=1111 lock=1 | grant=0000 gv=0 held nailed (exp grant0) req=1111 lock=1 | grant=xxxx gv=1 lock drop, req0 hi (exp grant0, owns) req=1111 lock=0 | grant=0000 gv=0 resume just past (exp grant1) req=1111 lock=0 | grant=xxxx gv=1 lock latch (exp grant2, held) req=1111 lock=1 | grant=xxxx gv=1 held req2 low -> dead air (exp gv=0) req=1011 lock=1 | grant=0000 gv=0 resume, lock still hi, re-latch (exp grant3) req=1011 lock=1 | grant=xxxx gv=1 tb2.sv:36: $finish called at 175 (1s)
iverilog -V | head -1
cat > probe.sv <<'EOF'
module probe(input logic [3:0] req, input logic [1:0] p, output logic [3:0] o1,o2,o3,o4, output logic b);
// part select in always_comb
always_comb begin
case(p)
2'd0: o1 = req;
2'd1: o1 = {req[0], req[3:1]};
default: o1 = 4'b0;
endcase
end
// continuous assign part select
assign o2 = {req[2:0], req[3]};
// dynamic bit index in assign
assign b = req[p];
// shift in always
always_comb o3 = 4'b0001 << p;
// part select feeding priority in always
always_comb begin
if (req[0]) o4 = 4'd1; else o4 = 4'd2;
end
endmodule
EOF
iverilog -g2012 -Wall -o probe probe.sv 2>&1 | head; echo "rc=$?"Icarus Verilog version 12.0 (stable) () Unable to get version from "/usr/lib/aarch64-linux-gnu/ivl/ivlpp -V" Unable to get version from "/usr/lib/aarch64-linux-gnu/ivl/ivl -V -C"/tmp/ivrlh35bc73e7" -C"/usr/lib/aarch64-linux-gnu/ivl/vvp.conf"" probe.sv:3: sorry: constant selects in always_* processes are not currently supported (all bits will be included). probe.sv:3: sorry: constant selects in always_* processes are not currently supported (all bits will be included). probe.sv:17: sorry: constant selects in always_* processes are not currently supported (all bits will be included). rc=0 [stdout] Icarus Verilog version 12.0 (stable) () Unable to get version from "/usr/lib/aarch64-linux-gnu/ivl/ivlpp -V" Unable to get version from "/usr/lib/aarch64-linux-gnu/ivl/ivl -V -C"/tmp/ivrlh35bc73e7" -C"/usr/lib/aarch64-linux-gnu/ivl/vvp.conf"" probe.sv:3: sorry: constant selects in always_* processes are not currently supported (all bits will be included). probe.sv:3: sorry: constant selects in always_* processes are not currently supported (all bits will be included). probe.sv:17: sorry: constant selects in always_* processes are not currently supported (all bits will be included). rc=0
cat > probe2.sv <<'EOF'
module probe2(input logic [3:0] req, output logic hit0, hit2);
// does select-in-always give WRONG results?
always_comb hit0 = req[0];
// clean: select in assign
assign hit2 = req[2];
endmodule
module tb;
logic [3:0] req; logic hit0,hit2;
probe2 d(.*);
initial begin
for (int k=0;k<16;k++) begin req=k; #1;
$display("req=%b req[0]=%b(always) req[2]=%b(assign)", req, hit0, hit2);
end
end
endmodule
EOF
iverilog -g2012 -o p2 probe2.sv 2>/dev/null && vvp p2req=0000 req[0]=0(always) req[2]=0(assign) req=0001 req[0]=1(always) req[2]=0(assign) req=0010 req[0]=0(always) req[2]=0(assign) req=0011 req[0]=1(always) req[2]=0(assign) req=0100 req[0]=0(always) req[2]=1(assign) req=0101 req[0]=1(always) req[2]=1(assign) req=0110 req[0]=0(always) req[2]=1(assign) req=0111 req[0]=1(always) req[2]=1(assign) req=1000 req[0]=0(always) req[2]=0(assign) req=1001 req[0]=1(always) req[2]=0(assign) req=1010 req[0]=0(always) req[2]=0(assign) req=1011 req[0]=1(always) req[2]=0(assign) req=1100 req[0]=0(always) req[2]=1(assign) req=1101 req[0]=1(always) req[2]=1(assign) req=1110 req[0]=0(always) req[2]=1(assign) req=1111 req[0]=1(always) req[2]=1(assign) [stdout] req=0000 req[0]=0(always) req[2]=0(assign) req=0001 req[0]=1(always) req[2]=0(assign) req=0010 req[0]=0(always) req[2]=0(assign) req=0011 req[0]=1(always) req[2]=0(assign) req=0100 req[0]=0(always) req[2]=1(assign) req=0101 req[0]=1(always) req[2]=1(assign) req=0110 req[0]=0(always) req[2]=1(assign) req=0111 req[0]=1(always) req[2]=1(assign) req=1000 req[0]=0(always) req[2]=0(assign) req=1001 req[0]=1(always) req[2]=0(assign) req=1010 req[0]=0(always) req[2]=0(assign) req=1011 req[0]=1(always) req[2]=0(assign) req=1100 req[0]=0(always) req[2]=1(assign) req=1101 req[0]=1(always) req[2]=1(assign) req=1110 req[0]=0(always) req[2]=1(assign) req=1111 req[0]=1(always) req[2]=1(assign)
module TopModule (
input logic clk,
input logic rst,
input logic [3:0] req,
input logic lock,
output logic [3:0] grant,
output logic grant_valid
);
// Circular-queue arbiter state.
// ptr : position to begin scanning (just past the last winner)
// held : a locked hold is active from a previous granted cycle
// held_id : the requester the hold is nailed to
logic [1:0] ptr;
logic held;
logic [1:0] held_id;
// next-state
logic [1:0] ptr_n;
logic held_n;
logic [1:0] held_id_n;
// Rotated request: rr[i] is requester (ptr + i) mod 4. All bit selection
// is done in continuous assigns (safe indexing).
logic [3:0] rr;
assign rr[0] = req[ptr];
assign rr[1] = req[ptr + 2'd1];
assign rr[2] = req[ptr + 2'd2];
assign rr[3] = req[ptr + 2'd3];
// Priority scan on the rotated vector: first asker starting just past the
// last winner, wrapping 3 -> 0.
logic found;
logic [1:0] rel;
logic [1:0] winner;
assign found = |rr;
assign rel = rr[0] ? 2'd0 : rr[1] ? 2'd1 : rr[2] ? 2'd2 : 2'd3;
assign winner = ptr + rel;
// Whether the currently held requester is still asking.
logic req_held;
assign req_held = req[held_id];
// Outputs (Mealy) and next state. Uses only scalars / whole vectors and
// shifts -- no bit-select of req inside the process.
always_comb begin
grant = 4'b0000;
grant_valid = 1'b0;
ptr_n = ptr;
held_n = 1'b0;
held_id_n = held_id;
if (held) begin
if (req_held) begin
// Held requester keeps asking: grant stays nailed to it.
grant = 4'b0001 << held_id;
grant_valid = 1'b1;
ptr_n = held_id + 2'd1;
if (lock) begin
// Lock still high: hold continues.
held_n = 1'b1;
held_id_n = held_id;
end else begin
// Lock dropped: this cycle still owned, sharing resumes next.
held_n = 1'b0;
end
end else begin
// Held requester dropped its req: dead air, hold is over.
// Counts as served; sharing resumes just past it.
grant = 4'b0000;
grant_valid = 1'b0;
held_n = 1'b0;
ptr_n = held_id + 2'd1;
end
end else begin
// Normal arbitration by the start rule.
if (found) begin
grant = 4'b0001 << winner;
grant_valid = 1'b1;
ptr_n = winner + 2'd1;
if (lock) begin
// Lock high on a granted cycle latches this winner.
held_n = 1'b1;
held_id_n = winner;
end
end else begin
// No asker: idle keeps your place (lock with no grant does nothing).
grant_valid = 1'b0;
ptr_n = ptr;
end
end
end
always_ff @(posedge clk) begin
if (rst) begin
// Synchronous: clear any hold, restart the order.
ptr <= 2'd0;
held <= 1'b0;
held_id <= 2'd0;
end else begin
ptr <= ptr_n;
held <= held_n;
held_id <= held_id_n;
end
end
endmodule
iverilog -g2012 -Wall -o sim2 dut.sv tb2.sv 2>&1 | grep -v "Unable to get version"; echo "=== end compile output ==="; vvp sim2
=== end compile output === all4 #1 (exp grant0) req=1111 lock=0 | grant=0000 gv=0 all4 #2 (exp grant1) req=1111 lock=0 | grant=0000 gv=0 all4 #3 (exp grant2) req=1111 lock=0 | grant=0000 gv=0 all4 #4 (exp grant3) req=1111 lock=0 | grant=0000 gv=0 all4 #5 (exp grant0) req=1111 lock=0 | grant=0000 gv=0 lone2 (exp grant2) req=0100 lock=0 | grant=0000 gv=0 lone2 (exp grant2) req=0100 lock=0 | grant=0000 gv=0 idle (exp gv=0, keep place ptr=3) req=0000 lock=0 | grant=0000 gv=0 only3 (exp grant3, ptr was 3) req=1000 lock=0 | grant=0000 gv=0 lock latch (exp grant0, held) req=1111 lock=1 | grant=0000 gv=0 held nailed (exp grant0) req=1111 lock=1 | grant=0000 gv=0 held nailed (exp grant0) req=1111 lock=1 | grant=0000 gv=0 lock drop, req0 hi (exp grant0, owns) req=1111 lock=0 | grant=0000 gv=0 resume just past (exp grant1) req=1111 lock=0 | grant=0000 gv=0 lock latch (exp grant2, held) req=1111 lock=1 | grant=0000 gv=0 held req2 low -> dead air (exp gv=0) req=1011 lock=1 | grant=0000 gv=0 resume, lock still hi, re-latch (exp grant3) req=1011 lock=1 | grant=0000 gv=0 tb2.sv:36: $finish called at 175 (1s) [stdout] === end compile output === all4 #1 (exp grant0) req=1111 lock=0 | grant=0000 gv=0 all4 #2 (exp grant1) req=1111 lock=0 | grant=0000 gv=0 all4 #3 (exp grant2) req=1111 lock=0 | grant=0000 gv=0 all4 #4 (exp grant3) req=1111 lock=0 | grant=0000 gv=0 all4 #5 (exp grant0) req=1111 lock=0 | grant=0000 gv=0 lone2 (exp grant2) req=0100 lock=0 | grant=0000 gv=0 lone2 (exp grant2) req=0100 lock=0 | grant=0000 gv=0 idle (exp gv=0, keep place ptr=3) req=0000 lock=0 | grant=0000 gv=0 only3 (exp grant3, ptr was 3) req=1000 lock=0 | grant=0000 gv=0 lock latch (exp grant0, held) req=1111 lock=1 | grant=0000 gv=0 held nailed (exp grant0) req=1111 lock=1 | grant=0000 gv=0 held nailed (exp grant0) req=1111 lock=1 | grant=0000 gv=0 lock drop, req0 hi (exp grant0, owns) req=1111 lock=0 | grant=0000 gv=0 resume just past (exp grant1) req=1111 lock=0 | grant=0000 gv=0 lock latch (exp grant2, held) req=1111 lock=1 | grant=0000 gv=0 held req2 low -> dead air (exp gv=0) req=1011 lock=1 | grant=0000 gv=0 resume, lock still hi, re-latch (exp grant3) req=1011 lock=1 | grant=0000 gv=0 tb2.sv:36: $finish called at 175 (1s)
cat > tb3.sv <<'EOF'
module tb;
logic clk=0, rst, lock;
logic [3:0] req; logic [3:0] grant; logic grant_valid;
TopModule dut(.*);
always #5 clk=~clk;
task automatic cyc(input [3:0] r, input l, input string note);
req=r; lock=l; #1; // apply inputs for this cycle, settle
$display("%-42s req=%b lock=%b | grant=%b gv=%b", note, req, lock, grant, grant_valid);
@(posedge clk); // consume the cycle
endtask
initial begin
rst=1; req=0; lock=0; #1; @(posedge clk); // synchronous reset edge
rst=0;
cyc(4'b1111,0,"all4 #1 (exp 0001)");
cyc(4'b1111,0,"all4 #2 (exp 0010)");
cyc(4'b1111,0,"all4 #3 (exp 0100)");
cyc(4'b1111,0,"all4 #4 (exp 1000)");
cyc(4'b1111,0,"all4 #5 (exp 0001)");
cyc(4'b0100,0,"lone2 (exp 0100)");
cyc(4'b0100,0,"lone2 (exp 0100)");
cyc(4'b0000,0,"idle (exp gv0, keep ptr=3)");
cyc(4'b1000,0,"only3 (exp 1000)");
cyc(4'b1111,1,"lock latch @ptr0 (exp 0001 held)");
cyc(4'b1111,1,"held nailed (exp 0001)");
cyc(4'b1111,1,"held nailed (exp 0001)");
cyc(4'b1111,0,"lock drop req0 hi (exp 0001 owns)");
cyc(4'b1111,0,"resume just past (exp 0010)");
cyc(4'b1111,1,"lock latch @ptr2 (exp 0100 held)");
cyc(4'b1011,1,"held req2 low -> dead air (exp gv0)");
cyc(4'b1011,1,"resume lock hi re-latch (exp 1000)");
cyc(4'b1011,1,"held nailed on 3 (exp 1000)");
$finish;
end
endmodule
EOF
iverilog -g2012 -Wall -o sim3 dut.sv tb3.sv 2>&1 | grep -v "Unable to get version"; vvp sim3all4 #1 (exp 0001) req=1111 lock=0 | grant=0000 gv=0 all4 #2 (exp 0010) req=1111 lock=0 | grant=0000 gv=0 all4 #3 (exp 0100) req=1111 lock=0 | grant=0000 gv=0 all4 #4 (exp 1000) req=1111 lock=0 | grant=0000 gv=0 all4 #5 (exp 0001) req=1111 lock=0 | grant=0000 gv=0 lone2 (exp 0100) req=0100 lock=0 | grant=0000 gv=0 lone2 (exp 0100) req=0100 lock=0 | grant=0000 gv=0 idle (exp gv0, keep ptr=3) req=0000 lock=0 | grant=0000 gv=0 only3 (exp 1000) req=1000 lock=0 | grant=0000 gv=0 lock latch @ptr0 (exp 0001 held) req=1111 lock=1 | grant=0000 gv=0 held nailed (exp 0001) req=1111 lock=1 | grant=0000 gv=0 held nailed (exp 0001) req=1111 lock=1 | grant=0000 gv=0 lock drop req0 hi (exp 0001 owns) req=1111 lock=0 | grant=0000 gv=0 resume just past (exp 0010) req=1111 lock=0 | grant=0000 gv=0 lock latch @ptr2 (exp 0100 held) req=1111 lock=1 | grant=0000 gv=0 held req2 low -> dead air (exp gv0) req=1011 lock=1 | grant=0000 gv=0 resume lock hi re-latch (exp 1000) req=1011 lock=1 | grant=0000 gv=0 held nailed on 3 (exp 1000) req=1011 lock=1 | grant=0000 gv=0 tb3.sv:32: $finish called at 185 (1s) [stdout] all4 #1 (exp 0001) req=1111 lock=0 | grant=0000 gv=0 all4 #2 (exp 0010) req=1111 lock=0 | grant=0000 gv=0 all4 #3 (exp 0100) req=1111 lock=0 | grant=0000 gv=0 all4 #4 (exp 1000) req=1111 lock=0 | grant=0000 gv=0 all4 #5 (exp 0001) req=1111 lock=0 | grant=0000 gv=0 lone2 (exp 0100) req=0100 lock=0 | grant=0000 gv=0 lone2 (exp 0100) req=0100 lock=0 | grant=0000 gv=0 idle (exp gv0, keep ptr=3) req=0000 lock=0 | grant=0000 gv=0 only3 (exp 1000) req=1000 lock=0 | grant=0000 gv=0 lock latch @ptr0 (exp 0001 held) req=1111 lock=1 | grant=0000 gv=0 held nailed (exp 0001) req=1111 lock=1 | grant=0000 gv=0 held nailed (exp 0001) req=1111 lock=1 | grant=0000 gv=0 lock drop req0 hi (exp 0001 owns) req=1111 lock=0 | grant=0000 gv=0 resume just past (exp 0010) req=1111 lock=0 | grant=0000 gv=0 lock latch @ptr2 (exp 0100 held) req=1111 lock=1 | grant=0000 gv=0 held req2 low -> dead air (exp gv0) req=1011 lock=1 | grant=0000 gv=0 resume lock hi re-latch (exp 1000) req=1011 lock=1 | grant=0000 gv=0 held nailed on 3 (exp 1000) req=1011 lock=1 | grant=0000 gv=0 tb3.sv:32: $finish called at 185 (1s)
cat > tb4.sv <<'EOF'
module tb;
logic clk=0, rst, lock; logic [3:0] req; logic [3:0] grant; logic grant_valid;
TopModule dut(.*);
always #5 clk=~clk;
initial begin
rst=1; req=0; lock=0; #1; @(posedge clk); rst=0;
req=4'b1111; lock=0; #1;
$display("ptr=%0d rr=%b found=%b rel=%0d winner=%0d grant=%b gv=%b",
dut.ptr, dut.rr, dut.found, dut.rel, dut.winner, grant, grant_valid);
$finish;
end
endmodule
EOF
iverilog -g2012 -o sim4 dut.sv tb4.sv 2>/dev/null && vvp sim4ptr=x rr=xxxx found=x rel=x winner=x grant=0000 gv=0 tb4.sv:10: $finish called at 6 (1s) [stdout] ptr=x rr=xxxx found=x rel=x winner=x grant=0000 gv=0 tb4.sv:10: $finish called at 6 (1s)
iverilog -g2012 -Wall -o sim4 dut.sv tb4.sv 2>&1 | grep -v "Unable to get version"
echo "--- run with more cycles ---"
cat > tb5.sv <<'EOF'
module tb;
logic clk=0, rst, lock; logic [3:0] req; logic [3:0] grant; logic grant_valid;
TopModule dut(.*);
always #5 clk=~clk;
initial begin
rst=1; req=4'b1111; lock=0;
repeat(3) @(posedge clk);
$display("after3edges rst=1: ptr=%0d held=%b rr=%b", dut.ptr, dut.held, dut.rr);
rst=0; #1;
$display("rst=0 t: ptr=%0d rr=%b found=%b winner=%0d grant=%b gv=%b",
dut.ptr, dut.rr, dut.found, dut.winner, grant, grant_valid);
@(posedge clk); #1;
$display("next: ptr=%0d grant=%b gv=%b", dut.ptr, grant, grant_valid);
$finish;
end
endmodule
EOF
iverilog -g2012 -o sim5 dut.sv tb5.sv 2>/dev/null && vvp sim5--- run with more cycles --- after3edges rst=1: ptr=0 held=0 rr=1111 rst=0 t: ptr=1 rr=1111 found=1 winner=1 grant=0010 gv=1 next: ptr=2 grant=0100 gv=1 tb5.sv:14: $finish called at 36 (1s) [stdout] --- run with more cycles --- after3edges rst=1: ptr=0 held=0 rr=1111 rst=0 t: ptr=1 rr=1111 found=1 winner=1 grant=0010 gv=1 next: ptr=2 grant=0100 gv=1 tb5.sv:14: $finish called at 36 (1s)
cat > tb.sv <<'EOF'
module tb;
logic clk=0, rst, lock; logic [3:0] req; logic [3:0] grant; logic grant_valid;
TopModule dut(.*);
always #5 clk=~clk;
int errors=0;
// apply inputs on negedge; outputs valid through the next posedge (which consumes them)
task automatic cyc(input [3:0] r, input l, input [3:0] eg, input egv, input string note);
@(negedge clk); req=r; lock=l; #1;
if (grant!==eg || grant_valid!==egv) begin
errors++;
$display("MISMATCH %-38s req=%b lock=%b | grant=%b(exp %b) gv=%b(exp %b)",
note, req, lock, grant, eg, grant_valid, egv);
end else
$display("ok %-38s req=%b lock=%b | grant=%b gv=%b", note, req, lock, grant, grant_valid);
endtask
initial begin
rst=1; req=0; lock=0;
@(negedge clk); @(posedge clk); // reset applied on this edge, rst deasserted at negedge next
// round-robin
cyc(4'b1111,0,4'b0001,1,"all4 #1");
cyc(4'b1111,0,4'b0010,1,"all4 #2");
cyc(4'b1111,0,4'b0100,1,"all4 #3");
cyc(4'b1111,0,4'b1000,1,"all4 #4");
cyc(4'b1111,0,4'b0001,1,"all4 #5 wrap");
// lone requester keeps winning
cyc(4'b0100,0,4'b0100,1,"lone2 a");
cyc(4'b0100,0,4'b0100,1,"lone2 b");
// idle keeps place (ptr stays at 3, since last winner was 2)
cyc(4'b0000,0,4'b0000,0,"idle");
cyc(4'b1000,0,4'b1000,1,"only3 -> grant3");
// ptr now 0. lock latch on winner 0
cyc(4'b1111,1,4'b0001,1,"lock latch @0");
cyc(4'b1111,1,4'b0001,1,"held nailed 0");
cyc(4'b0001,1,4'b0001,1,"held, only 0 asks");
cyc(4'b1111,1,4'b0001,1,"held nailed 0 again");
// drop lock while req0 still high: owns this cycle, then resume
cyc(4'b1111,0,4'b0001,1,"lock drop, 0 owns");
cyc(4'b1111,0,4'b0010,1,"resume -> grant1");
// lock latch on winner 2 (ptr now 2)
cyc(4'b1111,1,4'b0100,1,"lock latch @2");
cyc(4'b1111,1,4'b0100,1,"held nailed 2");
// held req2 goes low while lock high -> dead air
cyc(4'b1011,1,4'b0000,0,"dead air (req2 low)");
// resume just past dead winner (ptr=3), lock still high re-latches 3
cyc(4'b1011,1,4'b1000,1,"re-latch @3");
cyc(4'b1011,1,4'b1000,1,"held nailed 3");
// held 3 drops on the cycle lock also drops -> still dead air
cyc(4'b0011,0,4'b0000,0,"dead air on lock-drop cycle");
// resume just past 3 -> ptr0; grant0
cyc(4'b0011,0,4'b0001,1,"resume -> grant0");
// lock with no grant does nothing (no req)
cyc(4'b0000,1,4'b0000,0,"lock no grant");
if (errors==0) $display("\nALL PASS"); else $display("\n%0d ERRORS", errors);
$finish;
end
endmodule
EOF
iverilog -g2012 -Wall -o sim dut.sv tb.sv 2>&1 | grep -v "Unable to get version"; vvp simok all4 #1 req=1111 lock=0 | grant=0001 gv=1 MISMATCH all4 #2 req=1111 lock=0 | grant=0001(exp 0010) gv=1(exp 1) MISMATCH all4 #3 req=1111 lock=0 | grant=0001(exp 0100) gv=1(exp 1) MISMATCH all4 #4 req=1111 lock=0 | grant=0001(exp 1000) gv=1(exp 1) ok all4 #5 wrap req=1111 lock=0 | grant=0001 gv=1 ok lone2 a req=0100 lock=0 | grant=0100 gv=1 ok lone2 b req=0100 lock=0 | grant=0100 gv=1 ok idle req=0000 lock=0 | grant=0000 gv=0 ok only3 -> grant3 req=1000 lock=0 | grant=1000 gv=1 ok lock latch @0 req=1111 lock=1 | grant=0001 gv=1 ok held nailed 0 req=1111 lock=1 | grant=0001 gv=1 ok held, only 0 asks req=0001 lock=1 | grant=0001 gv=1 ok held nailed 0 again req=1111 lock=1 | grant=0001 gv=1 ok lock drop, 0 owns req=1111 lock=0 | grant=0001 gv=1 MISMATCH resume -> grant1 req=1111 lock=0 | grant=0001(exp 0010) gv=1(exp 1) MISMATCH lock latch @2 req=1111 lock=1 | grant=0001(exp 0100) gv=1(exp 1) MISMATCH held nailed 2 req=1111 lock=1 | grant=0001(exp 0100) gv=1(exp 1) MISMATCH dead air (req2 low) req=1011 lock=1 | grant=0001(exp 0000) gv=1(exp 0) MISMATCH re-latch @3 req=1011 lock=1 | grant=0001(exp 1000) gv=1(exp 1) MISMATCH held nailed 3 req=1011 lock=1 | grant=0001(exp 1000) gv=1(exp 1) MISMATCH dead air on lock-drop cycle req=0011 lock=0 | grant=0001(exp 0000) gv=1(exp 0) ok resume -> grant0 req=0011 lock=0 | grant=0001 gv=1 ok lock no grant req=0000 lock=1 | grant=0000 gv=0 10 ERRORS tb.sv:54: $finish called at 241 (1s) [stdout] ok all4 #1 req=1111 lock=0 | grant=0001 gv=1 MISMATCH all4 #2 req=1111 lock=0 | grant=0001(exp 0010) gv=1(exp 1) MISMATCH all4 #3 req=1111 lock=0 | grant=0001(exp 0100) gv=1(exp 1) MISMATCH all4 #4 req=1111 lock=0 | grant=0001(exp 1000) gv=1(exp 1) ok all4 #5 wrap req=1111 lock=0 | grant=0001 gv=1 ok lone2 a req=0100 lock=0 | grant=0100 gv=1 ok lone2 b req=0100 lock=0 | grant=0100 gv=1 ok idle req=0000 lock=0 | grant=0000 gv=0 ok only3 -> grant3 req=1000 lock=0 | grant=1000 gv=1 ok lock latch @0 req=1111 lock=1 | grant=0001 gv=1 ok held nailed 0 req=1111 lock=1 | grant=0001 gv=1 ok held, only 0 asks req=0001 lock=1 | grant=0001 gv=1 ok held nailed 0 again req=1111 lock=1 | grant=0001 gv=1 ok lock drop, 0 owns req=1111 lock=0 | grant=0001 gv=1 MISMATCH resume -> grant1 req=1111 lock=0 | grant=0001(exp 0010) gv=1(exp 1) MISMATCH lock latch @2 req=1111 lock=1 | grant=0001(exp 0100) gv=1(exp 1) MISMATCH held nailed 2 req=1111 lock=1 | grant=0001(exp 0100) gv=1(exp 1) MISMATCH dead air (req2 low) req=1011 lock=1 | grant=0001(exp 0000) gv=1(exp 0) MISMATCH re-latch @3 req=1011 lock=1 | grant=0001(exp 1000) gv=1(exp 1) MISMATCH held nailed 3 req=1011 lock=1 | grant=0001(exp 1000) gv=1(exp 1) MISMATCH dead air on lock-drop cycle req=0011 lock=0 | grant=0001(exp 0000) gv=1(exp 0) ok resume -> grant0 req=0011 lock=0 | grant=0001 gv=1 ok lock no grant req=0000 lock=1 | grant=0000 gv=0 10 ERRORS tb.sv:54: $finish called at 241 (1s)
sed -i 's| @(negedge clk); @(posedge clk); // reset applied on this edge, rst deasserted at negedge next| @(negedge clk); @(posedge clk); @(negedge clk); rst=0; // reset applied, then deassert away from edge|' tb.sv iverilog -g2012 -Wall -o sim dut.sv tb.sv 2>&1 | grep -v "Unable to get version"; vvp sim
ok all4 #1 req=1111 lock=0 | grant=0001 gv=1 ok all4 #2 req=1111 lock=0 | grant=0010 gv=1 ok all4 #3 req=1111 lock=0 | grant=0100 gv=1 ok all4 #4 req=1111 lock=0 | grant=1000 gv=1 ok all4 #5 wrap req=1111 lock=0 | grant=0001 gv=1 ok lone2 a req=0100 lock=0 | grant=0100 gv=1 ok lone2 b req=0100 lock=0 | grant=0100 gv=1 ok idle req=0000 lock=0 | grant=0000 gv=0 ok only3 -> grant3 req=1000 lock=0 | grant=1000 gv=1 ok lock latch @0 req=1111 lock=1 | grant=0001 gv=1 ok held nailed 0 req=1111 lock=1 | grant=0001 gv=1 ok held, only 0 asks req=0001 lock=1 | grant=0001 gv=1 ok held nailed 0 again req=1111 lock=1 | grant=0001 gv=1 ok lock drop, 0 owns req=1111 lock=0 | grant=0001 gv=1 ok resume -> grant1 req=1111 lock=0 | grant=0010 gv=1 ok lock latch @2 req=1111 lock=1 | grant=0100 gv=1 ok held nailed 2 req=1111 lock=1 | grant=0100 gv=1 ok dead air (req2 low) req=1011 lock=1 | grant=0000 gv=0 ok re-latch @3 req=1011 lock=1 | grant=1000 gv=1 ok held nailed 3 req=1011 lock=1 | grant=1000 gv=1 ok dead air on lock-drop cycle req=0011 lock=0 | grant=0000 gv=0 ok resume -> grant0 req=0011 lock=0 | grant=0001 gv=1 ok lock no grant req=0000 lock=1 | grant=0000 gv=0 ALL PASS tb.sv:54: $finish called at 251 (1s) [stdout] ok all4 #1 req=1111 lock=0 | grant=0001 gv=1 ok all4 #2 req=1111 lock=0 | grant=0010 gv=1 ok all4 #3 req=1111 lock=0 | grant=0100 gv=1 ok all4 #4 req=1111 lock=0 | grant=1000 gv=1 ok all4 #5 wrap req=1111 lock=0 | grant=0001 gv=1 ok lone2 a req=0100 lock=0 | grant=0100 gv=1 ok lone2 b req=0100 lock=0 | grant=0100 gv=1 ok idle req=0000 lock=0 | grant=0000 gv=0 ok only3 -> grant3 req=1000 lock=0 | grant=1000 gv=1 ok lock latch @0 req=1111 lock=1 | grant=0001 gv=1 ok held nailed 0 req=1111 lock=1 | grant=0001 gv=1 ok held, only 0 asks req=0001 lock=1 | grant=0001 gv=1 ok held nailed 0 again req=1111 lock=1 | grant=0001 gv=1 ok lock drop, 0 owns req=1111 lock=0 | grant=0001 gv=1 ok resume -> grant1 req=1111 lock=0 | grant=0010 gv=1 ok lock latch @2 req=1111 lock=1 | grant=0100 gv=1 ok held nailed 2 req=1111 lock=1 | grant=0100 gv=1 ok dead air (req2 low) req=1011 lock=1 | grant=0000 gv=0 ok re-latch @3 req=1011 lock=1 | grant=1000 gv=1 ok held nailed 3 req=1011 lock=1 | grant=1000 gv=1 ok dead air on lock-drop cycle req=0011 lock=0 | grant=0000 gv=0 ok resume -> grant0 req=0011 lock=0 | grant=0001 gv=1 ok lock no grant req=0000 lock=1 | grant=0000 gv=0 ALL PASS tb.sv:54: $finish called at 251 (1s)
rm -f tb.sv tb2.sv tb3.sv tb4.sv tb5.sv tb_sanity.sv probe.sv probe2.sv sim sim2 sim3 sim4 sim5 p2 probe && ls -la /app
total 12 drwxrwxrwx 1 root root 4096 Jul 5 01:17 . drwxr-xr-x 1 root root 4096 Jul 5 01:08 .. -rw-r--r-- 1 root root 3577 Jul 5 01:15 dut.sv [stdout] total 12 drwxrwxrwx 1 root root 4096 Jul 5 01:17 . drwxr-xr-x 1 root root 4096 Jul 5 01:08 .. -rw-r--r-- 1 root root 3577 Jul 5 01:15 dut.sv
No file changes, the agent left the workspace untouched.
TEST dut_present: PASS (/app/dut.sv exists)
TEST dut_forbidden: PASS (no forbidden constructs)
TEST dut_elaborates: PASS (DUT elaborates standalone)
TEST dut_compiles: PASS (compiled with held-back reference/testbench)
TEST simulation_completed: PASS (Mismatches: 0 in 4583 samples)
TEST reference_equivalence: PASS (all 4583 samples matched reference)
{"score": 1.000000, "results_file": "/tmp/h2t-grader-home.on7gpY/runtime/cb_verifier_401-18346-3248-27931_401/results.jsonl"}Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_110528fc8758473c. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_110528fc8758473c · verifier authoritative; classifier explanatory.