tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.// UART receiver: recovers bytes from a line idling high.
// Frame: 1 low start bit, 8 data bits LSB-first, 1 high stop bit,
// each BITLEN clock cycles. All outputs are registered.
module TopModule #(
parameter BITLEN = 4
) (
input logic clk,
input logic rst,
input logic rx_i,
output logic [7:0] data_o,
output logic valid_o,
output logic frame_err_o,
output logic break_o
);
// Derived timing constants.
localparam int HALF = BITLEN/2; // floored half bit period
localparam int STARTAT = (HALF == 0) ? 1 : HALF; // low cycles to accept a start
localparam int BREAKLEN = 6*BITLEN; // six continuous low bit periods
localparam int RECHIGH = 6*BITLEN; // high needed to leave recovery
localparam int CW = $clog2(6*BITLEN + 2) + 2; // counter width
// ----- two-flop synchronizer (idle high) -----
logic sync0, rx;
always_ff @(posedge clk) begin
if (rst) begin
sync0 <= 1'b1;
rx <= 1'b1;
end else begin
sync0 <= rx_i;
rx <= sync0;
end
end
// Continuous low / high run lengths of the synchronized line (saturating).
logic [CW-1:0] low_run, high_run;
wire [CW-1:0] lrn = (rx == 1'b0)
? ((low_run >= BREAKLEN[CW-1:0]) ? BREAKLEN[CW-1:0] : low_run + 1'b1)
: '0;
wire [CW-1:0] hrn = (rx == 1'b1)
? ((high_run >= RECHIGH[CW-1:0]) ? RECHIGH[CW-1:0] : high_run + 1'b1)
: '0;
// FSM.
typedef enum logic [1:0] {IDLE, DATA, BRK, RECOVER} state_t;
state_t state;
logic [CW-1:0] frame_cnt; // cycles since last sample point within a frame
logic [3:0] data_bits; // data bits sampled so far in the current frame (0..8)
logic [7:0] shiftreg; // assembled byte
logic [3:0] pend; // pending forced-frame-error byte count (d)
always_ff @(posedge clk) begin
if (rst) begin
state <= IDLE;
low_run <= '0;
high_run <= '0;
frame_cnt <= '0;
data_bits <= '0;
shiftreg <= '0;
pend <= '0;
data_o <= '0;
valid_o <= 1'b0;
frame_err_o <= 1'b0;
break_o <= 1'b0;
end else begin
// Global run counters and one-cycle output defaults.
low_run <= lrn;
high_run <= hrn;
valid_o <= 1'b0;
frame_err_o <= 1'b0;
// break_o and data_o retain their value unless updated below.
// Break preempts any in-progress frame (only in normal operation).
if ((state == IDLE || state == DATA) && lrn == BREAKLEN[CW-1:0]) begin
break_o <= 1'b1;
pend <= (state == DATA) ? data_bits : 4'd0; // d = data bits sampled
state <= BRK;
frame_cnt <= '0;
data_bits <= '0; // drop the byte
end else begin
case (state)
IDLE: begin
// Accept a start once a fresh low reaches half a bit period.
if (lrn == STARTAT[CW-1:0]) begin
state <= DATA;
frame_cnt <= '0;
data_bits <= '0;
shiftreg <= '0;
end
end
DATA: begin
if (frame_cnt == (BITLEN-1)) begin
frame_cnt <= '0;
if (data_bits < 8) begin
// Sample a data bit at its center (LSB first).
shiftreg[data_bits[2:0]] <= rx;
data_bits <= data_bits + 1'b1;
end else begin
// Sample the stop bit: deliver the byte.
valid_o <= 1'b1;
data_o <= shiftreg;
frame_err_o <= (~rx) | (pend != 0);
if (pend != 0) pend <= pend - 1'b1;
data_bits <= '0;
state <= IDLE;
end
end else begin
frame_cnt <= frame_cnt + 1'b1;
end
end
BRK: begin
// Hold break high until the line returns high.
if (rx) begin
break_o <= 1'b0;
state <= RECOVER;
end
end
RECOVER: begin
// Require six continuous high bit periods before rearming.
if (hrn == RECHIGH[CW-1:0])
state <= IDLE;
end
default: state <= IDLE;
endcase
end
end
end
endmodule
Compile-check the module
(iverilog -g2012 -o /tmp/dut_test dut.sv 2>&1 && echo "iverilog OK") || (verilator --lint-only -Wall dut.sv 2>&1 && echo "verilator OK") || echo "no simulator available"
iverilog OK [stdout] iverilog OK
Run testbench for normal bytes and break
cat > /tmp/tb.sv <<'EOF'
module tb;
localparam BITLEN=8;
logic clk=0, rst, rx;
logic [7:0] data_o; logic valid_o, frame_err_o, break_o;
TopModule #(.BITLEN(BITLEN)) dut(.clk,.rst,.rx_i(rx),.data_o,.valid_o,.frame_err_o,.break_o);
always #5 clk=~clk;
task sendbit(input logic b); repeat(BITLEN) @(posedge clk) rx<=b; endtask
initial begin
rst=1; rx=1; repeat(4) @(posedge clk); rst<=0;
repeat(4) @(posedge clk);
// send byte 0xA5 = 1010_0101, LSB first: 1,0,1,0,0,1,0,1
rx<=1; repeat(4)@(posedge clk); // idle
sendbit(0); // start
sendbit(1);sendbit(0);sendbit(1);sendbit(0);sendbit(0);sendbit(1);sendbit(0);sendbit(1);
sendbit(1); // stop
repeat(3)@(posedge clk);
// send byte 0x3C = 0011_1100 LSB: 0,0,1,1,1,1,0,0
sendbit(0);
sendbit(0);sendbit(0);sendbit(1);sendbit(1);sendbit(1);sendbit(1);sendbit(0);sendbit(0);
sendbit(1);
repeat(3)@(posedge clk);
// break: hold low 6 bit periods then high
rx<=0; repeat(6*BITLEN+5)@(posedge clk);
rx<=1; repeat(6*BITLEN+8)@(posedge clk); // recover
repeat(5)@(posedge clk);
$finish;
end
always @(posedge clk) begin
if (valid_o) $display("t=%0t VALID data=%02x ferr=%b", $time, data_o, frame_err_o);
if (break_o) $display("t=%0t BREAK high", $time);
end
endmodule
EOF
iverilog -g2012 -o /tmp/sim /tmp/tb.sv /app/dut.sv && vvp /tmp/sim | sort -u -t= -k2 -n | head -40/tmp/tb.sv:28: $finish called at 2915 (1s) t=915 VALID data=a5 ferr=0 t=1745 VALID data=3c ferr=0 t=2285 BREAK high t=2295 BREAK high t=2305 BREAK high t=2315 BREAK high t=2325 BREAK high t=2335 BREAK high [stdout] /tmp/tb.sv:28: $finish called at 2915 (1s) t=915 VALID data=a5 ferr=0 t=1745 VALID data=3c ferr=0 t=2285 BREAK high t=2295 BREAK high t=2305 BREAK high t=2315 BREAK high t=2325 BREAK high t=2335 BREAK high
Test forced frame errors after break
cat > /tmp/tb2.sv <<'EOF'
module tb;
localparam BITLEN=8;
logic clk=0, rst, rx;
logic [7:0] data_o; logic valid_o, frame_err_o, break_o;
TopModule #(.BITLEN(BITLEN)) dut(.clk,.rst,.rx_i(rx),.data_o,.valid_o,.frame_err_o,.break_o);
always #5 clk=~clk;
task sendbit(input logic b); repeat(BITLEN) @(posedge clk) rx<=b; endtask
task sendbyte(input logic[7:0] d, input logic stop);
integer i;
sendbit(0);
for(i=0;i<8;i=i+1) sendbit(d[i]);
sendbit(stop);
endtask
integer k;
initial begin
rst=1; rx=1; repeat(4) @(posedge clk); rst<=0; repeat(4) @(posedge clk);
// self-break: start then long low (6+ bit periods)
rx<=0; repeat(6*BITLEN+10)@(posedge clk);
rx<=1; repeat(6*BITLEN+10)@(posedge clk); // recover to idle
// now send 7 good bytes (stop=1). first d=5 should be forced ferr=1
for(k=0;k<7;k=k+1) begin sendbyte(8'h55, 1'b1); repeat(2)@(posedge clk); end
repeat(5)@(posedge clk); $finish;
end
always @(posedge clk) begin
if (valid_o) $display("t=%0t VALID data=%02x ferr=%b", $time, data_o, frame_err_o);
end
endmodule
EOF
iverilog -g2012 -o /tmp/sim2 /tmp/tb2.sv /app/dut.sv && vvp /tmp/sim2t=2035 VALID data=55 ferr=1 t=2855 VALID data=55 ferr=1 t=3675 VALID data=55 ferr=1 t=4495 VALID data=55 ferr=1 t=5315 VALID data=55 ferr=1 t=6135 VALID data=55 ferr=0 t=6955 VALID data=55 ferr=0 /tmp/tb2.sv:22: $finish called at 7025 (1s) [stdout] t=2035 VALID data=55 ferr=1 t=2855 VALID data=55 ferr=1 t=3675 VALID data=55 ferr=1 t=4495 VALID data=55 ferr=1 t=5315 VALID data=55 ferr=1 t=6135 VALID data=55 ferr=0 t=6955 VALID data=55 ferr=0 /tmp/tb2.sv:22: $finish called at 7025 (1s)
Test framing error on low stop bit
cat > /tmp/tb3.sv <<'EOF'
module tb;
localparam BITLEN=8;
logic clk=0, rst, rx;
logic [7:0] data_o; logic valid_o, frame_err_o, break_o;
TopModule #(.BITLEN(BITLEN)) dut(.clk,.rst,.rx_i(rx),.data_o,.valid_o,.frame_err_o,.break_o);
always #5 clk=~clk;
task sendbit(input logic b); repeat(BITLEN) @(posedge clk) rx<=b; endtask
task sendbyte(input logic[7:0] d, input logic stop);
integer i; sendbit(0);
for(i=0;i<8;i=i+1) sendbit(d[i]);
sendbit(stop);
endtask
initial begin
rst=1; rx=1; repeat(4) @(posedge clk); rst<=0; repeat(6) @(posedge clk);
sendbyte(8'h81, 1'b0); // stop bit low -> framing error, data 0x81
repeat(2)@(posedge clk);
sendbyte(8'h81, 1'b1); // good stop
repeat(6)@(posedge clk); $finish;
end
always @(posedge clk) if (valid_o) $display("VALID data=%02x ferr=%b", data_o, frame_err_o);
endmodule
EOF
iverilog -g2012 -o /tmp/sim3 /tmp/tb3.sv /app/dut.sv && vvp /tmp/sim3/tmp/tb3.sv:18: $finish called at 1775 (1s) [stdout] /tmp/tb3.sv:18: $finish called at 1775 (1s)
Rerun framing error test with 0x55
sed -i 's/8.h81/8'"'"'h55/g' /tmp/tb3.sv iverilog -g2012 -o /tmp/sim3 /tmp/tb3.sv /app/dut.sv && vvp /tmp/sim3
VALID data=55 ferr=1 /tmp/tb3.sv:18: $finish called at 1775 (1s) [stdout] VALID data=55 ferr=1 /tmp/tb3.sv:18: $finish called at 1775 (1s)
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_compiles: PASS (compiled with held-back reference/testbench)
TEST simulation_completed: PASS (Mismatches: 292 in 8633 samples)
TEST reference_equivalence: FAIL (292 mismatches in 8633 samples)
{"score": 0.000000, "results_file": "/tmp/h2t-grader-home.wJvd5q/runtime/cb_verifier_341-12906-750-11954_341/results.jsonl"}Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_71c93b1858bb4feb. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_71c93b1858bb4feb · verifier authoritative; classifier explanatory.