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
);
// Registered arbiter state
logic [1:0] start_ptr; // position just past the last winner
logic hold; // currently latched onto a held winner
logic [1:0] hidx; // index of the held winner
// Combinational circular arbitration starting at start_ptr
logic arb_found;
logic [1:0] arb_idx;
logic [1:0] idx;
integer i;
always_comb begin
arb_found = 1'b0;
arb_idx = 2'd0;
idx = 2'd0;
for (i = 0; i < 4; i = i + 1) begin
idx = start_ptr + i[1:0];
if (!arb_found && req[idx]) begin
arb_found = 1'b1;
arb_idx = idx;
end
end
end
// Output logic (Mealy: responds to req in the current cycle)
always_comb begin
grant = 4'd0;
grant_valid = 1'b0;
if (hold) begin
// A held winner owns the cycle only while it keeps asking.
if (req[hidx]) begin
grant = (4'd1 << hidx);
grant_valid = 1'b1;
end
// else: dead air -> grant 0, grant_valid 0
end else begin
if (arb_found) begin
grant = (4'd1 << arb_idx);
grant_valid = 1'b1;
end
end
end
// Next-state
always_ff @(posedge clk) begin
if (rst) begin
start_ptr <= 2'd0; // restart the order; first all-ask -> req 0 wins
hold <= 1'b0;
hidx <= 2'd0;
end else if (hold) begin
if (req[hidx]) begin
// Held winner owns this cycle.
start_ptr <= hidx + 2'd1;
if (lock) begin
hold <= 1'b1; // stay nailed while lock stays high
hidx <= hidx;
end else begin
hold <= 1'b0; // lock dropped: resume sharing next cycle
end
end else begin
// Held req low: dead air, hold over, counts as served.
start_ptr <= hidx + 2'd1;
hold <= 1'b0;
end
end else begin
if (arb_found) begin
start_ptr <= arb_idx + 2'd1;
if (lock) begin
hold <= 1'b1; // latch this winner
hidx <= arb_idx;
end else begin
hold <= 1'b0;
end
end else begin
// Idle: keep your place.
start_ptr <= start_ptr;
hold <= 1'b0;
end
end
end
endmodule
which iverilog && cat > tb.sv <<'EOF'
module tb;
logic clk, rst, lock;
logic [3:0] req;
logic [3:0] grant;
logic grant_valid;
TopModule dut(.clk(clk),.rst(rst),.req(req),.lock(lock),.grant(grant),.grant_valid(grant_valid));
initial clk=0; always #5 clk=~clk;
task step; @(posedge clk); #1; $display("t=%0t req=%b lock=%b -> grant=%b gv=%b",$time,req,lock,grant,grant_valid); endtask
initial begin
rst=1; req=0; lock=0; @(posedge clk); #1; rst=0;
$display("-- all four forever --");
req=4'b1111; lock=0;
step; step; step; step; step; step;
$display("-- lone req2 --");
req=4'b0100; step; step;
$display("-- idle keeps place (start now past 2 ->3) --");
req=4'b0000; step;
req=4'b1111; step; // should grant 3
$display("-- lock hold on req1 --");
req=4'b1111; lock=0; step; // grant 0 (start was 0 after 3? let's see)
// establish a lock scenario fresh
rst=1; @(posedge clk); #1; rst=0;
$display("-- fresh: lock high, all ask --");
req=4'b1111; lock=1; step; // grant0 latch
step; step; // stays on 0
$display("-- drop lock, req0 still high --");
lock=0; step; // grant0 owns cycle, then resume
lock=0; req=4'b1110; step; // should grant1 (past 0)
$display("-- dead air: lock hold on 0 then req0 drops --");
rst=1; @(posedge clk);#1; rst=0;
req=4'b0001; lock=1; step; // grant0 latch
step; // stays grant0
req=4'b0010; step; // req0 low -> dead air grant0 gone: grant 0 gv 0
lock=1; req=4'b0010; step; // resume from 1, lock high latches 1
$finish;
end
endmodule
EOF
iverilog -g2012 -o sim dut.sv tb.sv && vvp sim/usr/bin/iverilog dut.sv:21: sorry: constant selects in always_* processes are not currently supported (all bits will be included). -- all four forever -- t=16 req=1111 lock=0 -> grant=0010 gv=1 t=26 req=1111 lock=0 -> grant=0100 gv=1 t=36 req=1111 lock=0 -> grant=1000 gv=1 t=46 req=1111 lock=0 -> grant=0001 gv=1 t=56 req=1111 lock=0 -> grant=0010 gv=1 t=66 req=1111 lock=0 -> grant=0100 gv=1 -- lone req2 -- t=76 req=0100 lock=0 -> grant=0100 gv=1 t=86 req=0100 lock=0 -> grant=0100 gv=1 -- idle keeps place (start now past 2 ->3) -- t=96 req=0000 lock=0 -> grant=0000 gv=0 t=106 req=1111 lock=0 -> grant=0001 gv=1 -- lock hold on req1 -- t=116 req=1111 lock=0 -> grant=0010 gv=1 -- fresh: lock high, all ask -- t=136 req=1111 lock=1 -> grant=0001 gv=1 t=146 req=1111 lock=1 -> grant=0001 gv=1 t=156 req=1111 lock=1 -> grant=0001 gv=1 -- drop lock, req0 still high -- t=166 req=1111 lock=0 -> grant=0010 gv=1 t=176 req=1110 lock=0 -> grant=0100 gv=1 -- dead air: lock hold on 0 then req0 drops -- t=196 req=0001 lock=1 -> grant=0001 gv=1 t=206 req=0001 lock=1 -> grant=0001 gv=1 t=216 req=0010 lock=1 -> grant=0010 gv=1 t=226 req=0010 lock=1 -> grant=0010 gv=1 tb.sv:35: $finish called at 226 (1s) [stdout] /usr/bin/iverilog dut.sv:21: sorry: constant selects in always_* processes are not currently supported (all bits will be included). -- all four forever -- t=16 req=1111 lock=0 -> grant=0010 gv=1 t=26 req=1111 lock=0 -> grant=0100 gv=1 t=36 req=1111 lock=0 -> grant=1000 gv=1 t=46 req=1111 lock=0 -> grant=0001 gv=1 t=56 req=1111 lock=0 -> grant=0010 gv=1 t=66 req=1111 lock=0 -> grant=0100 gv=1 -- lone req2 -- t=76 req=0100 lock=0 -> grant=0100 gv=1 t=86 req=0100 lock=0 -> grant=0100 gv=1 -- idle keeps place (start now past 2 ->3) -- t=96 req=0000 lock=0 -> grant=0000 gv=0 t=106 req=1111 lock=0 -> grant=0001 gv=1 -- lock hold on req1 -- t=116 req=1111 lock=0 -> grant=0010 gv=1 -- fresh: lock high, all ask -- t=136 req=1111 lock=1 -> grant=0001 gv=1 t=146 req=1111 lock=1 -> grant=0001 gv=1 t=156 req=1111 lock=1 -> grant=0001 gv=1 -- drop lock, req0 still high -- t=166 req=1111 lock=0 -> grant=0010 gv=1 t=176 req=1110 lock=0 -> grant=0100 gv=1 -- dead air: lock hold on 0 then req0 drops -- t=196 req=0001 lock=1 -> grant=0001 gv=1 t=206 req=0001 lock=1 -> grant=0001 gv=1 t=216 req=0010 lock=1 -> grant=0010 gv=1 t=226 req=0010 lock=1 -> grant=0010 gv=1 tb.sv:35: $finish called at 226 (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
);
// Registered arbiter state
logic [1:0] start_ptr; // position just past the last winner
logic hold; // currently latched onto a held winner
logic [1:0] hidx; // index of the held winner
// Circular arbitration: rotate req so bit0 corresponds to start_ptr,
// then pick the lowest set bit (first asker walking upward).
wire [7:0] dup = {req, req};
wire [3:0] rot = dup[start_ptr +: 4]; // rot[i] = req[(start_ptr+i) mod 4]
wire arb_found = |rot;
wire [1:0] arb_rel = rot[0] ? 2'd0 :
rot[1] ? 2'd1 :
rot[2] ? 2'd2 : 2'd3;
wire [1:0] arb_idx = start_ptr + arb_rel;
// Does the currently held requester still ask? (indexed read outside always)
wire held_asks = req[hidx];
// One-hot builders (shifts, not index selects, are safe in always_comb)
wire [3:0] arb_oh = 4'd1 << arb_idx;
wire [3:0] held_oh = 4'd1 << hidx;
// Output logic (Mealy: responds to req in the current cycle)
always_comb begin
grant = 4'd0;
grant_valid = 1'b0;
if (hold) begin
// A held winner owns the cycle only while it keeps asking.
if (held_asks) begin
grant = held_oh;
grant_valid = 1'b1;
end
// else: dead air -> grant 0, grant_valid 0
end else if (arb_found) begin
grant = arb_oh;
grant_valid = 1'b1;
end
end
// Next-state
always_ff @(posedge clk) begin
if (rst) begin
start_ptr <= 2'd0; // restart the order; first all-ask -> req 0 wins
hold <= 1'b0;
hidx <= 2'd0;
end else if (hold) begin
if (held_asks) begin
// Held winner owns this cycle.
start_ptr <= hidx + 2'd1;
if (lock) begin
hold <= 1'b1; // stay nailed while lock stays high
hidx <= hidx;
end else begin
hold <= 1'b0; // lock dropped: resume sharing next cycle
end
end else begin
// Held req low: dead air, hold over, counts as served.
start_ptr <= hidx + 2'd1;
hold <= 1'b0;
end
end else begin
if (arb_found) begin
start_ptr <= arb_idx + 2'd1;
if (lock) begin
hold <= 1'b1; // latch this winner
hidx <= arb_idx;
end else begin
hold <= 1'b0;
end
end else begin
// Idle: keep your place.
start_ptr <= start_ptr;
hold <= 1'b0;
end
end
end
endmodule
iverilog -g2012 -Wall -o sim dut.sv tb.sv && vvp sim
-- all four forever -- t=16 req=1111 lock=0 -> grant=0010 gv=1 t=26 req=1111 lock=0 -> grant=0100 gv=1 t=36 req=1111 lock=0 -> grant=1000 gv=1 t=46 req=1111 lock=0 -> grant=0001 gv=1 t=56 req=1111 lock=0 -> grant=0010 gv=1 t=66 req=1111 lock=0 -> grant=0100 gv=1 -- lone req2 -- t=76 req=0100 lock=0 -> grant=0100 gv=1 t=86 req=0100 lock=0 -> grant=0100 gv=1 -- idle keeps place (start now past 2 ->3) -- t=96 req=0000 lock=0 -> grant=0000 gv=0 t=106 req=1111 lock=0 -> grant=0001 gv=1 -- lock hold on req1 -- t=116 req=1111 lock=0 -> grant=0010 gv=1 -- fresh: lock high, all ask -- t=136 req=1111 lock=1 -> grant=0001 gv=1 t=146 req=1111 lock=1 -> grant=0001 gv=1 t=156 req=1111 lock=1 -> grant=0001 gv=1 -- drop lock, req0 still high -- t=166 req=1111 lock=0 -> grant=0010 gv=1 t=176 req=1110 lock=0 -> grant=0100 gv=1 -- dead air: lock hold on 0 then req0 drops -- t=196 req=0001 lock=1 -> grant=0001 gv=1 t=206 req=0001 lock=1 -> grant=0001 gv=1 t=216 req=0010 lock=1 -> grant=0010 gv=1 t=226 req=0010 lock=1 -> grant=0010 gv=1 tb.sv:35: $finish called at 226 (1s) [stdout] -- all four forever -- t=16 req=1111 lock=0 -> grant=0010 gv=1 t=26 req=1111 lock=0 -> grant=0100 gv=1 t=36 req=1111 lock=0 -> grant=1000 gv=1 t=46 req=1111 lock=0 -> grant=0001 gv=1 t=56 req=1111 lock=0 -> grant=0010 gv=1 t=66 req=1111 lock=0 -> grant=0100 gv=1 -- lone req2 -- t=76 req=0100 lock=0 -> grant=0100 gv=1 t=86 req=0100 lock=0 -> grant=0100 gv=1 -- idle keeps place (start now past 2 ->3) -- t=96 req=0000 lock=0 -> grant=0000 gv=0 t=106 req=1111 lock=0 -> grant=0001 gv=1 -- lock hold on req1 -- t=116 req=1111 lock=0 -> grant=0010 gv=1 -- fresh: lock high, all ask -- t=136 req=1111 lock=1 -> grant=0001 gv=1 t=146 req=1111 lock=1 -> grant=0001 gv=1 t=156 req=1111 lock=1 -> grant=0001 gv=1 -- drop lock, req0 still high -- t=166 req=1111 lock=0 -> grant=0010 gv=1 t=176 req=1110 lock=0 -> grant=0100 gv=1 -- dead air: lock hold on 0 then req0 drops -- t=196 req=0001 lock=1 -> grant=0001 gv=1 t=206 req=0001 lock=1 -> grant=0001 gv=1 t=216 req=0010 lock=1 -> grant=0010 gv=1 t=226 req=0010 lock=1 -> grant=0010 gv=1 tb.sv:35: $finish called at 226 (1s)
cat > tb2.sv <<'EOF'
module tb;
logic clk, rst, lock;
logic [3:0] req;
logic [3:0] grant; logic grant_valid;
TopModule dut(.clk(clk),.rst(rst),.req(req),.lock(lock),.grant(grant),.grant_valid(grant_valid));
initial clk=0; always #5 clk=~clk;
task step; @(posedge clk); #1;
$display("req=%b lock=%b -> grant=%b gv=%b [hold=%b hidx=%0d start=%0d]",req,lock,grant,grant_valid,dut.hold,dut.hidx,dut.start_ptr);
endtask
initial begin
rst=1; req=0; lock=0; @(posedge clk); #1; rst=0;
$display("== dead-air test ==");
req=4'b0001; lock=1; step; // latch 0
req=4'b0001; lock=1; step; // stay 0
req=4'b0010; lock=1; step; // req0 dropped -> dead air expected
req=4'b0010; lock=1; step; // resume from 1, latch 1
req=4'b0010; lock=1; step; // stay 1
$finish;
end
endmodule
EOF
iverilog -g2012 -o sim2 dut.sv tb2.sv && vvp sim2== dead-air test == req=0001 lock=1 -> grant=0001 gv=1 [hold=1 hidx=0 start=1] req=0001 lock=1 -> grant=0001 gv=1 [hold=1 hidx=0 start=1] req=0010 lock=1 -> grant=0010 gv=1 [hold=0 hidx=0 start=1] req=0010 lock=1 -> grant=0010 gv=1 [hold=1 hidx=1 start=2] req=0010 lock=1 -> grant=0010 gv=1 [hold=1 hidx=1 start=2] tb2.sv:18: $finish called at 56 (1s) [stdout] == dead-air test == req=0001 lock=1 -> grant=0001 gv=1 [hold=1 hidx=0 start=1] req=0001 lock=1 -> grant=0001 gv=1 [hold=1 hidx=0 start=1] req=0010 lock=1 -> grant=0010 gv=1 [hold=0 hidx=0 start=1] req=0010 lock=1 -> grant=0010 gv=1 [hold=1 hidx=1 start=2] req=0010 lock=1 -> grant=0010 gv=1 [hold=1 hidx=1 start=2] tb2.sv:18: $finish called at 56 (1s)
cat > tb3.sv <<'EOF'
module tb;
logic clk, rst, lock;
logic [3:0] req; logic [3:0] grant; logic grant_valid;
TopModule dut(.clk(clk),.rst(rst),.req(req),.lock(lock),.grant(grant),.grant_valid(grant_valid));
initial clk=0; always #5 clk=~clk;
// Drive inputs for a cycle, sample output mid-cycle (before the consuming edge)
task cyc(input [3:0] r, input l, input [127:0] note);
req=r; lock=l;
@(negedge clk);
$display("%-28s req=%b lock=%b -> grant=%b gv=%b",note,req,lock,grant,grant_valid);
@(posedge clk);
endtask
task rstc;
rst=1; req=0; lock=0; @(negedge clk); @(posedge clk); rst=0;
endtask
initial begin
clk=0;
rstc;
$display("== all four forever: expect 0,1,2,3,0,1 ==");
cyc(4'b1111,0,"c0"); cyc(4'b1111,0,"c1"); cyc(4'b1111,0,"c2");
cyc(4'b1111,0,"c3"); cyc(4'b1111,0,"c4"); cyc(4'b1111,0,"c5");
$display("== lone req2 keeps winning ==");
cyc(4'b0100,0,"lone2"); cyc(4'b0100,0,"lone2");
$display("== idle keeps place, then all -> should be 3 (past 2) ==");
cyc(4'b0000,0,"idle"); cyc(4'b1111,0,"after idle");
rstc;
$display("== lock hold on 0, all ask ==");
cyc(4'b1111,1,"latch0"); cyc(4'b1111,1,"hold0"); cyc(4'b1111,1,"hold0");
$display("== drop lock: 0 owns cycle, then resume at 1 ==");
cyc(4'b1111,0,"lockdrop-owns0"); cyc(4'b1111,0,"resume->1");
rstc;
$display("== dead air: latch0, then req0 drops (lock still high) ==");
cyc(4'b0001,1,"latch0"); cyc(4'b0001,1,"hold0");
cyc(4'b0010,1,"deadair(expect g=0 gv=0)");
cyc(4'b0010,1,"resume->latch1"); cyc(4'b0010,1,"hold1");
rstc;
$display("== lock with no grant does nothing ==");
cyc(4'b0000,1,"nogrant"); cyc(4'b1111,0,"then0");
$finish;
end
endmodule
EOF
iverilog -g2012 -o sim3 dut.sv tb3.sv && vvp sim3== all four forever: expect 0,1,2,3,0,1 == c0 req=1111 lock=0 -> grant=0001 gv=1 c1 req=1111 lock=0 -> grant=0010 gv=1 c2 req=1111 lock=0 -> grant=0100 gv=1 c3 req=1111 lock=0 -> grant=1000 gv=1 c4 req=1111 lock=0 -> grant=0001 gv=1 c5 req=1111 lock=0 -> grant=0010 gv=1 == lone req2 keeps winning == lone2 req=0100 lock=0 -> grant=0100 gv=1 lone2 req=0100 lock=0 -> grant=0100 gv=1 == idle keeps place, then all -> should be 3 (past 2) == idle req=0000 lock=0 -> grant=0000 gv=0 after idle req=1111 lock=0 -> grant=1000 gv=1 == lock hold on 0, all ask == latch0 req=1111 lock=1 -> grant=0001 gv=1 hold0 req=1111 lock=1 -> grant=0001 gv=1 hold0 req=1111 lock=1 -> grant=0001 gv=1 == drop lock: 0 owns cycle, then resume at 1 == lockdrop-owns0 req=1111 lock=0 -> grant=0001 gv=1 resume->1 req=1111 lock=0 -> grant=0010 gv=1 == dead air: latch0, then req0 drops (lock still high) == latch0 req=0001 lock=1 -> grant=0001 gv=1 hold0 req=0001 lock=1 -> grant=0001 gv=1 expect g=0 gv=0) req=0010 lock=1 -> grant=0000 gv=0 resume->latch1 req=0010 lock=1 -> grant=0010 gv=1 hold1 req=0010 lock=1 -> grant=0010 gv=1 == lock with no grant does nothing == nogrant req=0000 lock=1 -> grant=0000 gv=0 then0 req=1111 lock=0 -> grant=0100 gv=1 tb3.sv:39: $finish called at 265 (1s) [stdout] == all four forever: expect 0,1,2,3,0,1 == c0 req=1111 lock=0 -> grant=0001 gv=1 c1 req=1111 lock=0 -> grant=0010 gv=1 c2 req=1111 lock=0 -> grant=0100 gv=1 c3 req=1111 lock=0 -> grant=1000 gv=1 c4 req=1111 lock=0 -> grant=0001 gv=1 c5 req=1111 lock=0 -> grant=0010 gv=1 == lone req2 keeps winning == lone2 req=0100 lock=0 -> grant=0100 gv=1 lone2 req=0100 lock=0 -> grant=0100 gv=1 == idle keeps place, then all -> should be 3 (past 2) == idle req=0000 lock=0 -> grant=0000 gv=0 after idle req=1111 lock=0 -> grant=1000 gv=1 == lock hold on 0, all ask == latch0 req=1111 lock=1 -> grant=0001 gv=1 hold0 req=1111 lock=1 -> grant=0001 gv=1 hold0 req=1111 lock=1 -> grant=0001 gv=1 == drop lock: 0 owns cycle, then resume at 1 == lockdrop-owns0 req=1111 lock=0 -> grant=0001 gv=1 resume->1 req=1111 lock=0 -> grant=0010 gv=1 == dead air: latch0, then req0 drops (lock still high) == latch0 req=0001 lock=1 -> grant=0001 gv=1 hold0 req=0001 lock=1 -> grant=0001 gv=1 expect g=0 gv=0) req=0010 lock=1 -> grant=0000 gv=0 resume->latch1 req=0010 lock=1 -> grant=0010 gv=1 hold1 req=0010 lock=1 -> grant=0010 gv=1 == lock with no grant does nothing == nogrant req=0000 lock=1 -> grant=0000 gv=0 then0 req=1111 lock=0 -> grant=0100 gv=1 tb3.sv:39: $finish called at 265 (1s)
cat > tb4.sv <<'EOF'
module tb;
logic clk, rst, lock;
logic [3:0] req; logic [3:0] grant; logic grant_valid;
TopModule dut(.clk(clk),.rst(rst),.req(req),.lock(lock),.grant(grant),.grant_valid(grant_valid));
initial clk=0; always #5 clk=~clk;
task cyc(input [3:0] r, input l, input [127:0] note);
req=r; lock=l; @(negedge clk);
$display("%-22s req=%b lock=%b -> g=%b gv=%b [hold=%b hidx=%0d start=%0d]",note,req,lock,grant,grant_valid,dut.hold,dut.hidx,dut.start_ptr);
@(posedge clk);
endtask
task rstc; rst=1; req=0; lock=0; @(negedge clk); @(posedge clk); rst=0; endtask
initial begin
clk=0;
// do a few cycles first to advance start, like the real sequence
rstc;
cyc(4'b0001,1,"latch0"); cyc(4'b0001,1,"hold0");
cyc(4'b0010,1,"deadair"); cyc(4'b0010,1,"latch1"); cyc(4'b0010,1,"hold1");
$display("-- now reset --");
rstc;
cyc(4'b0000,1,"nogrant"); cyc(4'b1111,0,"then-all expect 0001");
$finish;
end
endmodule
EOF
iverilog -g2012 -o sim4 dut.sv tb4.sv && vvp sim4latch0 req=0001 lock=1 -> g=0001 gv=1 [hold=0 hidx=0 start=0] hold0 req=0001 lock=1 -> g=0001 gv=1 [hold=1 hidx=0 start=1] deadair req=0010 lock=1 -> g=0000 gv=0 [hold=1 hidx=0 start=1] latch1 req=0010 lock=1 -> g=0010 gv=1 [hold=0 hidx=0 start=1] hold1 req=0010 lock=1 -> g=0010 gv=1 [hold=1 hidx=1 start=2] -- now reset -- nogrant req=0000 lock=1 -> g=0000 gv=0 [hold=0 hidx=1 start=2] -all expect 0001 req=1111 lock=0 -> g=0100 gv=1 [hold=0 hidx=1 start=2] tb4.sv:21: $finish called at 95 (1s) [stdout] latch0 req=0001 lock=1 -> g=0001 gv=1 [hold=0 hidx=0 start=0] hold0 req=0001 lock=1 -> g=0001 gv=1 [hold=1 hidx=0 start=1] deadair req=0010 lock=1 -> g=0000 gv=0 [hold=1 hidx=0 start=1] latch1 req=0010 lock=1 -> g=0010 gv=1 [hold=0 hidx=0 start=1] hold1 req=0010 lock=1 -> g=0010 gv=1 [hold=1 hidx=1 start=2] -- now reset -- nogrant req=0000 lock=1 -> g=0000 gv=0 [hold=0 hidx=1 start=2] -all expect 0001 req=1111 lock=0 -> g=0100 gv=1 [hold=0 hidx=1 start=2] tb4.sv:21: $finish called at 95 (1s)
cat > tb5.sv <<'EOF'
module tb;
logic clk, rst, lock; logic [3:0] req, grant; logic grant_valid;
TopModule dut(.clk(clk),.rst(rst),.req(req),.lock(lock),.grant(grant),.grant_valid(grant_valid));
initial clk=0; always #5 clk=~clk;
initial begin
// cycle A: reset high
rst=1; req=4'b1111; lock=0;
@(posedge clk); #1;
$display("after reset edge: start=%0d hold=%b",dut.start_ptr,dut.hold);
// advance a few with rst=0 to move pointer
rst=0; req=4'b1111; lock=0;
@(posedge clk); @(posedge clk); @(posedge clk); #1;
$display("advanced: start=%0d",dut.start_ptr);
// assert reset again
rst=1; req=4'b0000; lock=0;
@(posedge clk); #1;
$display("after 2nd reset: start=%0d hold=%b (expect 0,0)",dut.start_ptr,dut.hold);
$finish;
end
endmodule
EOF
iverilog -g2012 -o sim5 dut.sv tb5.sv && vvp sim5after reset edge: start=0 hold=0 advanced: start=3 after 2nd reset: start=0 hold=0 (expect 0,0) tb5.sv:18: $finish called at 46 (1s) [stdout] after reset edge: start=0 hold=0 advanced: start=3 after 2nd reset: start=0 hold=0 (expect 0,0) tb5.sv:18: $finish called at 46 (1s)
cat > tbf.sv <<'EOF'
module tb;
logic clk, rst, lock; logic [3:0] req, grant; logic grant_valid;
TopModule dut(.clk(clk),.rst(rst),.req(req),.lock(lock),.grant(grant),.grant_valid(grant_valid));
initial clk=0; always #5 clk=~clk;
integer errors=0;
// sample this cycle's output at negedge, then advance
task cyc(input [3:0] r, input l, input [3:0] eg, input egv, input [200:0] note);
req=r; lock=l; @(negedge clk);
if (grant!==eg || grant_valid!==egv) begin
$display("FAIL %-24s req=%b lock=%b -> g=%b gv=%b (exp g=%b gv=%b)",note,req,lock,grant,grant_valid,eg,egv);
errors=errors+1;
end else
$display("ok %-24s req=%b lock=%b -> g=%b gv=%b",note,req,lock,grant,grant_valid);
@(posedge clk);
endtask
// reset: hold rst across one posedge, sampled cleanly
task rstc; req=0; lock=0; rst=1; @(negedge clk); @(posedge clk); rst=0; @(negedge clk); @(posedge clk); endtask
initial begin
clk=0; rst=1; req=0; lock=0; @(posedge clk); rst=0; @(posedge clk);
$display("== reset then all-ask -> 0 ==");
cyc(4'b1111,0,4'b0001,1,"first-all->0");
cyc(4'b1111,0,4'b0010,1,"->1");
cyc(4'b1111,0,4'b0100,1,"->2");
cyc(4'b1111,0,4'b1000,1,"->3");
cyc(4'b1111,0,4'b0001,1,"->0 wrap");
$display("== lone req3 keeps winning ==");
cyc(4'b1000,0,4'b1000,1,"lone3"); cyc(4'b1000,0,4'b1000,1,"lone3");
$display("== idle keeps place then all -> 0 (past 3) ==");
cyc(4'b0000,0,4'b0000,0,"idle");
cyc(4'b1111,0,4'b0001,1,"after-idle->0");
rstc;
$display("== lock hold/drop ==");
cyc(4'b1111,1,4'b0001,1,"latch0");
cyc(4'b1111,1,4'b0001,1,"hold0-lockhi");
cyc(4'b1111,0,4'b0001,1,"lockdrop-0owns");
cyc(4'b1111,0,4'b0010,1,"resume->1");
rstc;
$display("== dead air + rearm ==");
cyc(4'b0001,1,4'b0001,1,"latch0");
cyc(4'b0000,1,4'b0000,0,"deadair req0 low");
cyc(4'b0010,1,4'b0010,1,"rearm latch1(start1)");
cyc(4'b0010,0,4'b0010,1,"drop lock 1 owns");
cyc(4'b0100,0,4'b0100,1,"resume->2");
rstc;
$display("== lock w/ no grant does nothing ==");
cyc(4'b0000,1,4'b0000,0,"nogrant lockhi");
cyc(4'b1111,0,4'b0001,1,"then all->0");
if (errors==0) $display("\nALL PASS"); else $display("\n%0d FAILURES",errors);
$finish;
end
endmodule
EOF
iverilog -g2012 -o simf dut.sv tbf.sv && vvp simf== reset then all-ask -> 0 == FAIL first-all->0 req=1111 lock=0 -> g=0000 gv=0 (exp g=0001 gv=1) FAIL ->1 req=1111 lock=0 -> g=0000 gv=0 (exp g=0010 gv=1) FAIL ->2 req=1111 lock=0 -> g=0000 gv=0 (exp g=0100 gv=1) FAIL ->3 req=1111 lock=0 -> g=0000 gv=0 (exp g=1000 gv=1) FAIL ->0 wrap req=1111 lock=0 -> g=0000 gv=0 (exp g=0001 gv=1) == lone req3 keeps winning == FAIL lone3 req=1000 lock=0 -> g=0000 gv=0 (exp g=1000 gv=1) FAIL lone3 req=1000 lock=0 -> g=0000 gv=0 (exp g=1000 gv=1) == idle keeps place then all -> 0 (past 3) == ok idle req=0000 lock=0 -> g=0000 gv=0 FAIL after-idle->0 req=1111 lock=0 -> g=0000 gv=0 (exp g=0001 gv=1) == lock hold/drop == FAIL latch0 req=1111 lock=1 -> g=0000 gv=0 (exp g=0001 gv=1) FAIL hold0-lockhi req=1111 lock=1 -> g=0000 gv=0 (exp g=0001 gv=1) FAIL lockdrop-0owns req=1111 lock=0 -> g=0000 gv=0 (exp g=0001 gv=1) FAIL resume->1 req=1111 lock=0 -> g=0000 gv=0 (exp g=0010 gv=1) == dead air + rearm == FAIL latch0 req=0001 lock=1 -> g=0000 gv=0 (exp g=0001 gv=1) ok deadair req0 low req=0000 lock=1 -> g=0000 gv=0 FAIL rearm latch1(start1) req=0010 lock=1 -> g=0000 gv=0 (exp g=0010 gv=1) FAIL drop lock 1 owns req=0010 lock=0 -> g=0000 gv=0 (exp g=0010 gv=1) FAIL resume->2 req=0100 lock=0 -> g=0000 gv=0 (exp g=0100 gv=1) == lock w/ no grant does nothing == ok nogrant lockhi req=0000 lock=1 -> g=0000 gv=0 FAIL then all->0 req=1111 lock=0 -> g=0000 gv=0 (exp g=0001 gv=1) 17 FAILURES tbf.sv:49: $finish called at 275 (1s) [stdout] == reset then all-ask -> 0 == FAIL first-all->0 req=1111 lock=0 -> g=0000 gv=0 (exp g=0001 gv=1) FAIL ->1 req=1111 lock=0 -> g=0000 gv=0 (exp g=0010 gv=1) FAIL ->2 req=1111 lock=0 -> g=0000 gv=0 (exp g=0100 gv=1) FAIL ->3 req=1111 lock=0 -> g=0000 gv=0 (exp g=1000 gv=1) FAIL ->0 wrap req=1111 lock=0 -> g=0000 gv=0 (exp g=0001 gv=1) == lone req3 keeps winning == FAIL lone3 req=1000 lock=0 -> g=0000 gv=0 (exp g=1000 gv=1) FAIL lone3 req=1000 lock=0 -> g=0000 gv=0 (exp g=1000 gv=1) == idle keeps place then all -> 0 (past 3) == ok idle req=0000 lock=0 -> g=0000 gv=0 FAIL after-idle->0 req=1111 lock=0 -> g=0000 gv=0 (exp g=0001 gv=1) == lock hold/drop == FAIL latch0 req=1111 lock=1 -> g=0000 gv=0 (exp g=0001 gv=1) FAIL hold0-lockhi req=1111 lock=1 -> g=0000 gv=0 (exp g=0001 gv=1) FAIL lockdrop-0owns req=1111 lock=0 -> g=0000 gv=0 (exp g=0001 gv=1) FAIL resume->1 req=1111 lock=0 -> g=0000 gv=0 (exp g=0010 gv=1) == dead air + rearm == FAIL latch0 req=0001 lock=1 -> g=0000 gv=0 (exp g=0001 gv=1) ok deadair req0 low req=0000 lock=1 -> g=0000 gv=0 FAIL rearm latch1(start1) req=0010 lock=1 -> g=0000 gv=0 (exp g=0010 gv=1) FAIL drop lock 1 owns req=0010 lock=0 -> g=0000 gv=0 (exp g=0010 gv=1) FAIL resume->2 req=0100 lock=0 -> g=0000 gv=0 (exp g=0100 gv=1) == lock w/ no grant does nothing == ok nogrant lockhi req=0000 lock=1 -> g=0000 gv=0 FAIL then all->0 req=1111 lock=0 -> g=0000 gv=0 (exp g=0001 gv=1) 17 FAILURES tbf.sv:49: $finish called at 275 (1s)
cat > tbg.sv <<'EOF'
module tb;
logic clk, rst, lock; logic [3:0] req, grant; logic grant_valid;
TopModule dut(.clk(clk),.rst(rst),.req(req),.lock(lock),.grant(grant),.grant_valid(grant_valid));
initial clk=0; always #5 clk=~clk;
initial begin
rst=1; req=0; lock=0; @(posedge clk); rst=0; @(posedge clk);
req=4'b1111; lock=0; @(negedge clk);
$display("state: start=%b hold=%b hidx=%b rot=%b arb_found=%b grant=%b",dut.start_ptr,dut.hold,dut.hidx,dut.rot,dut.arb_found,grant);
$finish;
end
endmodule
EOF
iverilog -g2012 -o simg dut.sv tbg.sv && vvp simgstate: start=xx hold=0 hidx=xx rot=xxxx arb_found=x grant=0000 tbg.sv:9: $finish called at 20 (1s) [stdout] state: start=xx hold=0 hidx=xx rot=xxxx arb_found=x grant=0000 tbg.sv:9: $finish called at 20 (1s)
cat > tbh.sv <<'EOF'
module tb;
logic clk, rst, lock; logic [3:0] req, grant; logic grant_valid;
TopModule dut(.clk(clk),.rst(rst),.req(req),.lock(lock),.grant(grant),.grant_valid(grant_valid));
initial clk=0; always #5 clk=~clk;
initial begin
rst=1; req=0; lock=0;
@(posedge clk); #1;
$display("t=%0t after 1st edge (rst=1): start=%b hold=%b",$time,dut.start_ptr,dut.hold);
rst=0;
@(posedge clk); #1;
$display("t=%0t after 2nd edge (rst=0,req=0): start=%b hold=%b",$time,dut.start_ptr,dut.hold);
$finish;
end
endmodule
EOF
iverilog -g2012 -o simh dut.sv tbh.sv && vvp simht=6 after 1st edge (rst=1): start=00 hold=0 t=16 after 2nd edge (rst=0,req=0): start=00 hold=0 tbh.sv:12: $finish called at 16 (1s) [stdout] t=6 after 1st edge (rst=1): start=00 hold=0 t=16 after 2nd edge (rst=0,req=0): start=00 hold=0 tbh.sv:12: $finish called at 16 (1s)
cat > tbz.sv <<'EOF'
module tb;
logic clk, rst, lock; logic [3:0] req, grant; logic grant_valid;
TopModule dut(.clk(clk),.rst(rst),.req(req),.lock(lock),.grant(grant),.grant_valid(grant_valid));
initial clk=0; always #5 clk=~clk;
integer errors=0;
// drive inputs just after posedge, sample well before next posedge (race-free)
task cyc(input [3:0] r, input l, input [3:0] eg, input egv, input [200:0] note);
@(posedge clk); #1; req=r; lock=l; #3;
if (grant!==eg || grant_valid!==egv) begin
$display("FAIL %-22s req=%b lock=%b -> g=%b gv=%b (exp g=%b gv=%b)",note,req,lock,grant,grant_valid,eg,egv);
errors=errors+1;
end else $display("ok %-22s req=%b lock=%b -> g=%b gv=%b",note,req,lock,grant,grant_valid);
endtask
task rstc; @(posedge clk); #1; rst=1; req=0; lock=0; @(posedge clk); #1; rst=0; endtask
initial begin
rst=1; req=0; lock=0; #1;
rstc;
$display("== reset then all-ask -> 0,1,2,3,0 ==");
cyc(4'b1111,0,4'b0001,1,"first-all->0"); cyc(4'b1111,0,4'b0010,1,"->1");
cyc(4'b1111,0,4'b0100,1,"->2"); cyc(4'b1111,0,4'b1000,1,"->3");
cyc(4'b1111,0,4'b0001,1,"->0 wrap");
$display("== lone req3 keeps winning ==");
cyc(4'b1000,0,4'b1000,1,"lone3"); cyc(4'b1000,0,4'b1000,1,"lone3");
$display("== idle keeps place then all -> 0 (past 3) ==");
cyc(4'b0000,0,4'b0000,0,"idle"); cyc(4'b1111,0,4'b0001,1,"after-idle->0");
rstc;
$display("== lock hold / drop ==");
cyc(4'b1111,1,4'b0001,1,"latch0"); cyc(4'b1111,1,4'b0001,1,"hold0-lockhi");
cyc(4'b1111,0,4'b0001,1,"lockdrop-0owns"); cyc(4'b1111,0,4'b0010,1,"resume->1");
rstc;
$display("== dead air + rearm (lock stays high) ==");
cyc(4'b0001,1,4'b0001,1,"latch0");
cyc(4'b0000,1,4'b0000,0,"deadair req0 low");
cyc(4'b0010,1,4'b0010,1,"rearm latch1 (start1)");
cyc(4'b0010,0,4'b0010,1,"drop lock, 1 owns");
cyc(4'b0100,0,4'b0100,1,"resume->2");
rstc;
$display("== lock w/ no grant does nothing ==");
cyc(4'b0000,1,4'b0000,0,"nogrant lockhi"); cyc(4'b1111,0,4'b0001,1,"then all->0");
if (errors==0) $display("\n=== ALL PASS ==="); else $display("\n=== %0d FAILURES ===",errors);
$finish;
end
endmodule
EOF
iverilog -g2012 -o simz dut.sv tbz.sv && vvp simz== reset then all-ask -> 0,1,2,3,0 == ok first-all->0 req=1111 lock=0 -> g=0001 gv=1 ok ->1 req=1111 lock=0 -> g=0010 gv=1 ok ->2 req=1111 lock=0 -> g=0100 gv=1 ok ->3 req=1111 lock=0 -> g=1000 gv=1 ok ->0 wrap req=1111 lock=0 -> g=0001 gv=1 == lone req3 keeps winning == ok lone3 req=1000 lock=0 -> g=1000 gv=1 ok lone3 req=1000 lock=0 -> g=1000 gv=1 == idle keeps place then all -> 0 (past 3) == ok idle req=0000 lock=0 -> g=0000 gv=0 ok after-idle->0 req=1111 lock=0 -> g=0001 gv=1 == lock hold / drop == ok latch0 req=1111 lock=1 -> g=0001 gv=1 ok hold0-lockhi req=1111 lock=1 -> g=0001 gv=1 ok lockdrop-0owns req=1111 lock=0 -> g=0001 gv=1 ok resume->1 req=1111 lock=0 -> g=0010 gv=1 == dead air + rearm (lock stays high) == ok latch0 req=0001 lock=1 -> g=0001 gv=1 ok deadair req0 low req=0000 lock=1 -> g=0000 gv=0 ok rearm latch1 (start1) req=0010 lock=1 -> g=0010 gv=1 ok drop lock, 1 owns req=0010 lock=0 -> g=0010 gv=1 ok resume->2 req=0100 lock=0 -> g=0100 gv=1 == lock w/ no grant does nothing == ok nogrant lockhi req=0000 lock=1 -> g=0000 gv=0 ok then all->0 req=1111 lock=0 -> g=0001 gv=1 === ALL PASS === tbz.sv:41: $finish called at 279 (1s) [stdout] == reset then all-ask -> 0,1,2,3,0 == ok first-all->0 req=1111 lock=0 -> g=0001 gv=1 ok ->1 req=1111 lock=0 -> g=0010 gv=1 ok ->2 req=1111 lock=0 -> g=0100 gv=1 ok ->3 req=1111 lock=0 -> g=1000 gv=1 ok ->0 wrap req=1111 lock=0 -> g=0001 gv=1 == lone req3 keeps winning == ok lone3 req=1000 lock=0 -> g=1000 gv=1 ok lone3 req=1000 lock=0 -> g=1000 gv=1 == idle keeps place then all -> 0 (past 3) == ok idle req=0000 lock=0 -> g=0000 gv=0 ok after-idle->0 req=1111 lock=0 -> g=0001 gv=1 == lock hold / drop == ok latch0 req=1111 lock=1 -> g=0001 gv=1 ok hold0-lockhi req=1111 lock=1 -> g=0001 gv=1 ok lockdrop-0owns req=1111 lock=0 -> g=0001 gv=1 ok resume->1 req=1111 lock=0 -> g=0010 gv=1 == dead air + rearm (lock stays high) == ok latch0 req=0001 lock=1 -> g=0001 gv=1 ok deadair req0 low req=0000 lock=1 -> g=0000 gv=0 ok rearm latch1 (start1) req=0010 lock=1 -> g=0010 gv=1 ok drop lock, 1 owns req=0010 lock=0 -> g=0010 gv=1 ok resume->2 req=0100 lock=0 -> g=0100 gv=1 == lock w/ no grant does nothing == ok nogrant lockhi req=0000 lock=1 -> g=0000 gv=0 ok then all->0 req=1111 lock=0 -> g=0001 gv=1 === ALL PASS === tbz.sv:41: $finish called at 279 (1s)
rm -f tb.sv tb2.sv tb3.sv tb4.sv tb5.sv tbf.sv tbg.sv tbh.sv tbz.sv sim sim2 sim3 sim4 sim5 simf simg simh simz && iverilog -g2012 -Wall -o /tmp/final_check dut.sv -s TopModule 2>&1; echo "compile exit: $?"; ls dut.sv
compile exit: 0 dut.sv [stdout] compile exit: 0 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.J5uvRL/runtime/cb_verifier_383-22369-24686-20126_383/results.jsonl"}Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_075e3b9ec63347af. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_075e3b9ec63347af · verifier authoritative; classifier explanatory.