tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.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 [1:0] IDLE = 2'd0, RECV = 2'd1, EMIT = 2'd2;
reg [1:0] state;
reg [12:0] n; // accepted byte count (0..8191)
reg [1:0] cur_lane; // currently presented block's lane
reg [9:0] cur_idx; // currently presented block's index
reg [12:0] nres; // temp for f_next result
reg [7:0] mem [0:8191]; // bytes in arrival order
// ---- combinational helpers (functions of n) ----
// number of bytes routed to lane L
function automatic [11:0] f_laneLen(input [1:0] L);
reg [11:0] base; reg extra;
begin
base = {1'b0, n[12:2]}; // n / 4
case (L)
2'd0: extra = (n[1:0] > 2'd0);
2'd1: extra = (n[1:0] > 2'd1);
2'd2: extra = (n[1:0] > 2'd2);
default: extra = 1'b0;
endcase
f_laneLen = base + {11'b0, extra};
end
endfunction
// number of emitted blocks for a lane of Lj bytes
function automatic [9:0] f_blocks(input [11:0] Lj);
reg [8:0] q; reg [2:0] rem; reg [9:0] extra;
begin
q = Lj[11:3]; // Lj / 8
rem = Lj[2:0]; // Lj % 8
extra = (rem >= 3'd6) ? 10'd1 : 10'd0;
f_blocks = {1'b0, q} + 10'd1 + extra;
end
endfunction
// build 64-bit block content for lane L, block index I
function automatic [63:0] f_block(input [1:0] L, input [9:0] I);
reg [11:0] Lj; reg [9:0] Bj; reg [15:0] lenb;
integer p; reg [15:0] m; reg [15:0] addr; reg [7:0] cur;
reg [63:0] acc;
begin
Lj = f_laneLen(L);
Bj = f_blocks(Lj);
lenb = {1'b0, Lj, 3'b000}; // length in bits = 8 * Lj
acc = 64'd0;
for (p = 0; p < 8; p = p + 1) begin
m = I*8 + p; // lane byte position
addr = I*32 + p*4 + L; // arrival index (valid when m < Lj)
if (m < Lj) cur = mem[addr];
else if ((I == Bj - 10'd1) && (p==6)) cur = lenb[15:8];
else if ((I == Bj - 10'd1) && (p==7)) cur = lenb[7:0];
else if (m == Lj) cur = 8'h80;
else cur = 8'h00;
acc = (acc << 8) | {56'b0, cur};
end
f_block = acc; // earliest byte in [63:56]
end
endfunction
// next block in emission order; returns {done, lane[1:0], idx[9:0]}
function automatic [12:0] f_next(input [1:0] L, input [9:0] I, input [9:0] maxB);
reg found; reg [1:0] nl; reg [9:0] ni; integer j; reg [9:0] bj;
begin
found = 1'b0; nl = 2'd0; ni = 10'd0;
// same index, a higher lane
for (j = 0; j < 4; j = j + 1) begin
bj = f_blocks(f_laneLen(j[1:0]));
if (!found && (j > L) && (bj > I)) begin
found = 1'b1; nl = j[1:0]; ni = I;
end
end
// otherwise advance to next index, lowest qualifying lane
if (!found && ((I + 10'd1) < maxB)) begin
for (j = 0; j < 4; j = j + 1) begin
bj = f_blocks(f_laneLen(j[1:0]));
if (!found && (bj > (I + 10'd1))) begin
found = 1'b1; nl = j[1:0]; ni = I + 10'd1;
end
end
end
f_next = {~found, nl, ni};
end
endfunction
// per-lane block counts and the global maxima
wire [11:0] llen0 = f_laneLen(2'd0);
wire [11:0] llen1 = f_laneLen(2'd1);
wire [11:0] llen2 = f_laneLen(2'd2);
wire [11:0] llen3 = f_laneLen(2'd3);
wire [9:0] blk0 = f_blocks(llen0);
wire [9:0] blk1 = f_blocks(llen1);
wire [9:0] blk2 = f_blocks(llen2);
wire [9:0] blk3 = f_blocks(llen3);
wire [9:0] mx01 = (blk0 > blk1) ? blk0 : blk1;
wire [9:0] mx23 = (blk2 > blk3) ? blk2 : blk3;
wire [9:0] w_maxB = (mx01 > mx23) ? mx01 : mx23;
wire [1:0] w_finalLane = (blk3 == w_maxB) ? 2'd3 :
(blk2 == w_maxB) ? 2'd2 :
(blk1 == w_maxB) ? 2'd1 : 2'd0;
always @(posedge clk) begin
if (rst) begin
state <= IDLE;
n <= 13'd0;
cur_lane <= 2'd0;
cur_idx <= 10'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 (state)
IDLE: begin
if (byte_valid_i && byte_ready_o) begin
mem[0] <= byte_i;
n <= 13'd1;
busy_o <= 1'b1;
if (last_i) begin
state <= EMIT;
byte_ready_o <= 1'b0; // block_valid_o stays 0 -> load next cycle
end else begin
state <= RECV;
end
end
end
RECV: begin
if (byte_valid_i && byte_ready_o) begin
mem[n] <= byte_i;
n <= n + 13'd1;
if (last_i) begin
state <= EMIT;
byte_ready_o <= 1'b0;
end
end
end
EMIT: begin
if (block_valid_o) begin
if (block_ready_i) begin
if ((cur_idx == w_maxB - 10'd1) && (cur_lane == w_finalLane)) begin
// final block accepted
state <= IDLE;
block_valid_o <= 1'b0;
done_o <= 1'b0;
busy_o <= 1'b0;
byte_ready_o <= 1'b1;
end else begin
nres = f_next(cur_lane, cur_idx, w_maxB);
cur_lane <= nres[11:10];
cur_idx <= nres[9:0];
block_o <= f_block(nres[11:10], nres[9:0]);
done_o <= (nres[9:0] == w_maxB - 10'd1) &&
(nres[11:10] == w_finalLane);
end
end
end else begin
// load the very first block (lane 0, index 0)
cur_lane <= 2'd0;
cur_idx <= 10'd0;
block_o <= f_block(2'd0, 10'd0);
block_valid_o <= 1'b1;
done_o <= (10'd0 == w_maxB - 10'd1) && (2'd0 == w_finalLane);
end
end
default: state <= IDLE;
endcase
end
end
endmodule
Compile dut.sv standalone
iverilog -g2012 -o /tmp/dut_only.out dut.sv 2>&1 && echo "COMPILE_OK" || echo "COMPILE_FAIL"
COMPILE_OK [stdout] COMPILE_OK
module tb;
reg clk=0, rst=0, 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;
// storage for one message
integer N;
reg [7:0] msg [0:8191];
// golden emitted blocks
reg [63:0] gexp [0:5000];
integer gcount;
integer errors;
integer seed;
// compute lane length
function integer laneLen(input integer NN, input integer L);
laneLen = (NN/4) + (((NN%4) > L) ? 1 : 0);
endfunction
function integer laneBlocks(input integer Lj);
integer q, rem;
begin
q = Lj/8; rem = Lj%8;
laneBlocks = q + 1 + ((rem>=6)?1:0);
end
endfunction
// build golden block for lane L idx I
function [63:0] goldBlock(input integer L, input integer I);
integer Lj, Bj, p, m, addr, lenb; reg [7:0] cur; reg [63:0] acc;
begin
Lj = laneLen(N,L); Bj = laneBlocks(Lj); lenb = 8*Lj; acc=0;
for (p=0;p<8;p=p+1) begin
m = I*8+p; addr = I*32+p*4+L;
if (m < Lj) cur = msg[addr];
else if ((I==Bj-1)&&(p==6)) cur = (lenb>>8)&8'hFF;
else if ((I==Bj-1)&&(p==7)) cur = lenb&8'hFF;
else if (m==Lj) cur = 8'h80;
else cur = 8'h00;
acc = (acc<<8)|cur;
end
goldBlock = acc;
end
endfunction
// build the golden emission sequence
task buildGolden;
integer b0,b1,b2,b3,maxB,I,L,bj;
begin
b0=laneBlocks(laneLen(N,0)); b1=laneBlocks(laneLen(N,1));
b2=laneBlocks(laneLen(N,2)); b3=laneBlocks(laneLen(N,3));
maxB=b0; if(b1>maxB)maxB=b1; if(b2>maxB)maxB=b2; if(b3>maxB)maxB=b3;
gcount=0;
for (I=0;I<maxB;I=I+1)
for (L=0;L<4;L=L+1) begin
bj=laneBlocks(laneLen(N,L));
if (I<bj) begin gexp[gcount]=goldBlock(L,I); gcount=gcount+1; end
end
end
endtask
integer collected;
integer i, msglen;
integer trial;
integer gap;
integer busy_seen_hi;
// send one message and collect emitted blocks, checking on the fly
task runMessage(input integer L);
integer sent;
begin
N = L;
for (i=0;i<N;i=i+1) msg[i] = $random(seed) & 8'hFF;
buildGolden;
collected = 0;
sent = 0;
// drive bytes with random gaps while randomly allowing blocks
// (blocks won't appear until reception done, but keep ready random)
while (sent < N || collected < gcount) begin
@(negedge clk);
// byte side
if (sent < N && byte_ready_o) begin
if (($random(seed)%3)!=0) begin
byte_valid_i = 1;
byte_i = msg[sent];
start_i = (sent==0);
last_i = (sent==N-1);
end else begin
byte_valid_i = 0; start_i=0; last_i=0;
end
end else begin
byte_valid_i = 0; start_i=0; last_i=0;
end
// block side ready random
block_ready_i = ($random(seed)%2);
@(posedge clk);
// observe acceptances that just happened at this edge
if (byte_valid_i && byte_ready_o) sent = sent + 1;
if (block_valid_o && block_ready_i) begin
if (collected < gcount) begin
if (block_o !== gexp[collected]) begin
errors = errors + 1;
$display("MISMATCH msglen=%0d block#%0d got=%h exp=%h", N, collected, block_o, gexp[collected]);
end
// done_o must be high exactly on the final block accept
if ((collected==gcount-1) !== done_o) begin
errors=errors+1;
$display("DONE mismatch msglen=%0d block#%0d done=%b", N, collected, done_o);
end
end else begin
errors=errors+1; $display("EXTRA block msglen=%0d", N);
end
collected = collected + 1;
end
end
// small idle gap
byte_valid_i=0; start_i=0; last_i=0; block_ready_i=0;
repeat (($random(seed)%4)) @(negedge clk);
if (collected != gcount) begin
errors=errors+1; $display("COUNT mismatch msglen=%0d got=%0d exp=%0d", N, collected, gcount);
end
end
endtask
initial begin
seed = 32'hDEAD1234;
errors = 0;
rst = 1; @(negedge clk); @(negedge clk); rst = 0;
@(negedge clk);
// directed small lengths
for (trial=1; trial<=40; trial=trial+1) runMessage(trial);
// multiples of 8 and boundaries per lane
runMessage(32); runMessage(24); runMessage(23); runMessage(48);
runMessage(1); runMessage(2); runMessage(3); runMessage(4);
runMessage(5); runMessage(6); runMessage(7); runMessage(8);
// random larger
for (trial=0; trial<60; trial=trial+1) begin
msglen = 1 + ($random(seed) % 2000);
if (msglen<1) msglen = 1;
runMessage(msglen);
end
// max
runMessage(8191);
if (errors==0) $display("ALL_TESTS_PASSED");
else $display("FAILED with %0d errors", errors);
$finish;
end
// watchdog
initial begin
#50000000 $display("TIMEOUT"); $finish;
end
endmodule
Compile and run testbench
cd /tmp && iverilog -g2012 -o /tmp/sim.out /app/dut.sv /tmp/tb.sv 2>&1 && vvp /tmp/sim.out 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_8c90b5677d734c75. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_8c90b5677d734c75 · verifier authoritative; classifier explanatory.