tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.// TopModule: split byte stream across 4 lanes, pad each lane (MD-style with a
// 16-bit big-endian bit-length), frame into 64-bit big-endian blocks, and emit
// blocks in round-robin-by-index order. All outputs registered.
module TopModule (
input wire clk,
input wire rst,
input wire start_i,
input wire [7:0] byte_i,
input wire byte_valid_i,
input wire last_i,
input wire block_ready_i,
output reg [63:0] block_o,
output reg block_valid_o,
output reg byte_ready_o,
output reg done_o,
output reg busy_o
);
localparam ST_INPUT = 2'd0;
localparam ST_LOAD = 2'd1;
localparam ST_EMIT = 2'd2;
// Byte storage, arrival order. Max message length 8191.
reg [7:0] mem [0:8190];
reg [1:0] st;
reg [13:0] Ncnt; // accepted byte count
reg [13:0] cur_i; // current block index
reg [1:0] cur_j; // current lane
// combinational scratch (assigned before use in the clocked block)
reg [13:0] e0, e1, e2, e3;
reg [13:0] s_ifin, s_ni;
reg [1:0] s_jfin, s_nj;
reg s_found;
// Length in bytes routed to lane j given total N.
function automatic [13:0] f_len(input [13:0] N, input [1:0] j);
reg [13:0] base;
reg [1:0] rem;
begin
base = N >> 2;
rem = N[1:0];
f_len = base + ((rem > j) ? 14'd1 : 14'd0);
end
endfunction
// Number of 8-byte blocks lane j emits.
function automatic [13:0] f_blocks(input [13:0] N, input [1:0] j);
reg [13:0] L;
reg [13:0] full;
reg [2:0] r;
begin
L = f_len(N, j);
full = L >> 3;
r = L[2:0];
f_blocks = full + 14'd1 + ((r >= 3'd6) ? 14'd1 : 14'd0);
end
endfunction
// Build block bi of lane j.
function automatic [63:0] f_block(input [1:0] j, input [13:0] bi, input [13:0] N);
reg [13:0] L, blocks, finalBlk;
reg [15:0] lenbits;
integer p;
reg [16:0] m;
reg [18:0] idx;
reg [7:0] b;
begin
L = f_len(N, j);
blocks = f_blocks(N, j);
finalBlk = blocks - 14'd1;
lenbits = {2'b00, L} << 3; // length in bits, 16-bit
f_block = 64'd0;
for (p = 0; p < 8; p = p + 1) begin
m = ({3'b000, bi} << 3) + p[16:0]; // lane byte index
if ((bi == finalBlk) && (p == 6 || p == 7)) begin
b = (p == 6) ? lenbits[15:8] : lenbits[7:0];
end else if (m < {3'b000, L}) begin
idx = (m << 2) + {17'b0, j}; // arrival index = j + 4*m
b = mem[idx];
end else if (m == {3'b000, L}) begin
b = 8'h80; // padding marker
end else begin
b = 8'h00;
end
f_block[63 - 8*p -: 8] = b;
end
end
endfunction
always @(posedge clk) begin
if (rst) begin
st <= ST_INPUT;
Ncnt <= 14'd0;
cur_i <= 14'd0;
cur_j <= 2'd0;
block_o <= 64'd0;
block_valid_o <= 1'b0;
byte_ready_o <= 1'b1;
done_o <= 1'b0;
busy_o <= 1'b0;
end else begin
case (st)
ST_INPUT: begin
if (byte_valid_i && byte_ready_o) begin
mem[Ncnt] <= byte_i;
Ncnt <= Ncnt + 14'd1;
busy_o <= 1'b1;
if (last_i) begin
byte_ready_o <= 1'b0;
st <= ST_LOAD;
end
end
end
ST_LOAD: begin
// Ncnt is final and mem is fully written; present block (0,0).
block_o <= f_block(2'd0, 14'd0, Ncnt);
block_valid_o <= 1'b1;
cur_i <= 14'd0;
cur_j <= 2'd0;
done_o <= 1'b0; // (0,0) is never the final block
st <= ST_EMIT;
end
ST_EMIT: begin
if (block_valid_o && block_ready_i) begin
e0 = f_blocks(Ncnt, 2'd0);
e1 = f_blocks(Ncnt, 2'd1);
e2 = f_blocks(Ncnt, 2'd2);
e3 = f_blocks(Ncnt, 2'd3);
s_ifin = e0 - 14'd1;
s_jfin = (e3 == e0) ? 2'd3 :
(e2 == e0) ? 2'd2 :
(e1 == e0) ? 2'd1 : 2'd0;
if ((cur_i == s_ifin) && (cur_j == s_jfin)) begin
// final block accepted -> back to accepting bytes
st <= ST_INPUT;
byte_ready_o <= 1'b1;
block_valid_o <= 1'b0;
busy_o <= 1'b0;
done_o <= 1'b0;
Ncnt <= 14'd0;
end else begin
s_found = 1'b0;
s_ni = cur_i;
s_nj = 2'd0;
if (!s_found && (cur_j < 2'd1) && (e1 > cur_i)) begin
s_nj = 2'd1; s_ni = cur_i; s_found = 1'b1;
end
if (!s_found && (cur_j < 2'd2) && (e2 > cur_i)) begin
s_nj = 2'd2; s_ni = cur_i; s_found = 1'b1;
end
if (!s_found && (cur_j < 2'd3) && (e3 > cur_i)) begin
s_nj = 2'd3; s_ni = cur_i; s_found = 1'b1;
end
if (!s_found) begin
s_ni = cur_i + 14'd1; s_nj = 2'd0;
end
cur_i <= s_ni;
cur_j <= s_nj;
block_o <= f_block(s_nj, s_ni, Ncnt);
block_valid_o <= 1'b1;
done_o <= ((s_ni == s_ifin) && (s_nj == s_jfin)) ? 1'b1 : 1'b0;
end
end
end
default: st <= ST_INPUT;
endcase
end
end
endmodule
Compile dut.sv with iverilog
iverilog -g2012 -o /tmp/dut_compile dut.sv 2>&1 && echo "COMPILE OK"
COMPILE OK [stdout] COMPILE OK
`timescale 1ns/1ps
module tb;
reg clk=0, rst=1, start_i=0, byte_valid_i=0, last_i=0, block_ready_i=0;
reg [7:0] byte_i=0;
wire [63:0] block_o;
wire block_valid_o, byte_ready_o, done_o, busy_o;
TopModule dut(.clk(clk), .rst(rst), .start_i(start_i), .byte_i(byte_i),
.byte_valid_i(byte_valid_i), .last_i(last_i), .block_ready_i(block_ready_i),
.block_o(block_o), .block_valid_o(block_valid_o), .byte_ready_o(byte_ready_o),
.done_o(done_o), .busy_o(busy_o));
always #5 clk = ~clk;
// ---- independent golden model ----
integer N;
reg [7:0] msg [0:8191];
// expected block stream
reg [63:0] exp_blk [0:70000];
integer exp_done [0:70000]; // 1 if this emitted block is the final block
integer exp_cnt;
integer laneL [0:3];
integer laneBlocks [0:3];
function integer blocks_of(input integer L);
integer full; integer r;
begin
full = L/8; r = L%8;
blocks_of = full + 1 + ((r>=6)?1:0);
end
endfunction
// build expected block for lane j, block index bi
function [63:0] mkblk(input integer j, input integer bi);
integer L, blk, finalBlk, lenbits, p, m, idx;
reg [7:0] b; reg [63:0] r;
begin
L = laneL[j]; blk = laneBlocks[j]; finalBlk = blk-1; lenbits = 8*L;
r = 0;
for (p=0;p<8;p=p+1) begin
m = 8*bi + p;
if (bi==finalBlk && (p==6||p==7)) b = (p==6)? lenbits[15:8] : lenbits[7:0];
else if (m < L) begin idx = j + 4*m; b = msg[idx]; end
else if (m == L) b = 8'h80;
else b = 8'h00;
r[63 - 8*p -: 8] = b;
end
mkblk = r;
end
endfunction
task build_expected;
integer j, i, maxB, ifin, jfin;
begin
for (j=0;j<4;j=j+1) begin
laneL[j] = (N/4) + (((N%4) > j)?1:0);
laneBlocks[j] = blocks_of(laneL[j]);
end
maxB = laneBlocks[0];
ifin = maxB-1;
jfin = (laneBlocks[3]==maxB)?3:(laneBlocks[2]==maxB)?2:(laneBlocks[1]==maxB)?1:0;
exp_cnt = 0;
for (i=0;i<maxB;i=i+1)
for (j=0;j<4;j=j+1)
if (i < laneBlocks[j]) begin
exp_blk[exp_cnt] = mkblk(j,i);
exp_done[exp_cnt] = ((i==ifin)&&(j==jfin))?1:0;
exp_cnt = exp_cnt+1;
end
end
endtask
integer got_cnt;
integer errors;
integer trial;
integer k;
integer r;
// drive one message, collect blocks, compare
task run_msg(input integer len, input integer seed);
integer bi;
begin
N = len;
for (k=0;k<len;k=k+1) msg[k] = $random;
build_expected;
got_cnt = 0;
// ---- input phase ----
bi = 0;
while (bi < len) begin
// randomly present a byte
@(negedge clk);
if (($random % 3) != 0) begin
byte_valid_i = 1;
byte_i = msg[bi];
start_i = (bi==0);
last_i = (bi==len-1);
end else begin
byte_valid_i = 0; start_i=0; last_i=0;
end
@(posedge clk);
#1;
if (byte_valid_i && byte_ready_o) bi = bi + 1;
end
@(negedge clk); byte_valid_i=0; start_i=0; last_i=0;
// ---- output phase: randomly stall, collect blocks ----
block_ready_i = 0;
while (got_cnt < exp_cnt) begin
@(negedge clk);
block_ready_i = (($random % 3) != 0);
@(posedge clk);
#1;
if (block_valid_o && block_ready_i) begin
if (block_o !== exp_blk[got_cnt]) begin
errors = errors+1;
$display("MISMATCH len=%0d blk#%0d got=%h exp=%h", len, got_cnt, block_o, exp_blk[got_cnt]);
end
if (done_o !== (exp_done[got_cnt]?1'b1:1'b0)) begin
errors = errors+1;
$display("DONE mismatch len=%0d blk#%0d got_done=%b exp=%0d", len, got_cnt, done_o, exp_done[got_cnt]);
end
// busy must be high while presenting/accepting blocks
if (busy_o !== 1'b1) begin
errors=errors+1; $display("BUSY low during block accept len=%0d blk#%0d", len, got_cnt);
end
got_cnt = got_cnt + 1;
end
end
@(negedge clk); block_ready_i=0;
// after final accept, expect busy low, ready high eventually
@(posedge clk); #1;
if (busy_o !== 1'b0) begin errors=errors+1; $display("BUSY not cleared len=%0d", len); end
if (byte_ready_o !== 1'b1) begin errors=errors+1; $display("READY not restored len=%0d", len); end
end
endtask
initial begin
errors = 0;
block_ready_i=0; byte_valid_i=0;
@(negedge clk); rst=1; @(negedge clk); @(negedge clk); rst=0;
@(negedge clk);
// directed small lengths
for (trial=1; trial<=40; trial=trial+1) run_msg(trial, trial);
// some multiples of 32 and boundaries
run_msg(32, 100); run_msg(31,101); run_msg(33,102);
run_msg(64,103); run_msg(63,104); run_msg(48,105);
// random larger
for (trial=0; trial<30; trial=trial+1) begin
r = ($random % 4000); if (r<1) r=1; if(r<0) r=-r; if(r<1)r=1;
run_msg((r%8191)+1, trial+200);
end
run_msg(8191, 999);
if (errors==0) $display("ALL TESTS PASSED (%0d checks)", got_cnt);
else $display("FAILED with %0d errors", errors);
$finish;
end
endmodule
Compile and run self-checking testbench
cd /tmp && iverilog -g2012 -o /tmp/sim /app/dut.sv /tmp/tb.sv 2>&1 && vvp /tmp/sim 2>&1 | tail -40
No file changes, the agent left the workspace untouched.
FAIL: tampered GRADER_HOME/runtime detected -> failing closed (score 0)
Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_98c0bddd44a746c4. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_98c0bddd44a746c4 · verifier authoritative; classifier explanatory.