tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.// UART receiver with break detection and framing-error carry-over.
//
// Frame: idle-high line, one low start bit, 8 data bits LSB-first, one high
// stop bit; each bit is BITLEN clock cycles.
module TopModule #(
parameter BITLEN = 8
)(
input wire clk,
input wire rst,
input wire rx_i,
output reg [7:0] data_o,
output reg valid_o,
output reg frame_err_o,
output reg break_o
);
// Half a bit period (floored) and six full bit periods.
localparam integer HALF = BITLEN/2;
localparam integer SIXBIT = 6*BITLEN;
localparam integer CW = $clog2(6*BITLEN+2) + 1;
localparam [1:0] IDLE = 2'd0, RECV = 2'd1, BRK = 2'd2, RECOVER = 2'd3;
// Two-flop synchronizer.
reg rx_meta, rx_sync;
reg [1:0] state;
reg [CW-1:0] low_cnt; // consecutive low cycles (saturates at SIXBIT)
reg [CW-1:0] high_cnt; // consecutive high cycles (saturates at SIXBIT)
reg [CW-1:0] bit_timer; // cycles within the current bit
reg [3:0] bit_num; // next bit to sample: 0..7 data, 8 = stop
reg [7:0] shreg; // assembled data bits
reg [3:0] forced_count; // pending bytes that must report frame error
// Combinational temporaries (assigned before use each cycle).
reg [CW-1:0] lc, hc, bt;
always @(posedge clk) begin
if (rst) begin
rx_meta <= 1'b1;
rx_sync <= 1'b1;
state <= IDLE;
low_cnt <= {CW{1'b0}};
high_cnt <= {CW{1'b0}};
bit_timer <= {CW{1'b0}};
bit_num <= 4'd0;
shreg <= 8'd0;
forced_count <= 4'd0;
data_o <= 8'd0;
valid_o <= 1'b0;
frame_err_o <= 1'b0;
break_o <= 1'b0;
end else begin
// Synchronize rx_i.
rx_meta <= rx_i;
rx_sync <= rx_meta;
// Pulsed outputs default low each cycle.
valid_o <= 1'b0;
frame_err_o <= 1'b0;
// Saturating run-length counters on the synchronized line.
if (rx_sync == 1'b0)
lc = (low_cnt == SIXBIT[CW-1:0]) ? low_cnt : (low_cnt + 1'b1);
else
lc = {CW{1'b0}};
if (rx_sync == 1'b1)
hc = (high_cnt == SIXBIT[CW-1:0]) ? high_cnt : (high_cnt + 1'b1);
else
hc = {CW{1'b0}};
low_cnt <= lc;
high_cnt <= hc;
// ---- Break detection: preempts any in-progress frame. ----
// Suppressed while in BRK/RECOVER (line low during recovery just
// restarts the high count).
if ((state == IDLE || state == RECV) && (lc == SIXBIT[CW-1:0])) begin
break_o <= 1'b1;
// d = data bits the interrupted byte sampled (0 if none).
forced_count <= (state == RECV) ? bit_num : 4'd0;
state <= BRK;
end else begin
case (state)
IDLE: begin
// Accept start when a fresh low reaches half a bit period.
if (rx_sync == 1'b0 && lc == HALF[CW-1:0]) begin
state <= RECV;
bit_timer <= {CW{1'b0}};
bit_num <= 4'd0;
shreg <= 8'd0;
end
end
RECV: begin
bt = bit_timer + 1'b1;
if (bt == BITLEN[CW-1:0]) begin
bit_timer <= {CW{1'b0}};
if (bit_num < 4'd8) begin
// Sample a data bit at its center, LSB first.
shreg[bit_num] <= rx_sync;
bit_num <= bit_num + 1'b1;
end else begin
// Sample the stop bit: deliver the byte.
valid_o <= 1'b1;
data_o <= shreg;
frame_err_o <= (rx_sync == 1'b0) ||
(forced_count != 4'd0);
if (forced_count != 4'd0)
forced_count <= forced_count - 1'b1;
bit_num <= 4'd0;
state <= IDLE;
end
end else begin
bit_timer <= bt;
end
end
BRK: begin
// break_o stays high until the line returns high.
if (rx_sync == 1'b1) begin
break_o <= 1'b0;
state <= RECOVER;
end
end
RECOVER: begin
// No start accepted until the line holds high six bit
// periods; any low restarts (break_o stays low).
if (hc == SIXBIT[CW-1:0])
state <= IDLE;
end
default: state <= IDLE;
endcase
end
end
end
endmodule
Compile the module with iverilog
(iverilog -g2012 -o /tmp/dut_test dut.sv 2>&1 && echo "COMPILE OK") || echo "iverilog not available or error"
COMPILE OK [stdout] COMPILE OK
Run sanity testbench
cat > /tmp/tb.sv <<'EOF'
`timescale 1ns/1ps
module tb;
localparam BITLEN=8;
reg clk=0, rst=1, rx=1;
wire [7:0] data; wire valid, ferr, brk;
TopModule #(.BITLEN(BITLEN)) dut(.clk(clk),.rst(rst),.rx_i(rx),
.data_o(data),.valid_o(valid),.frame_err_o(ferr),.break_o(brk));
always #5 clk=~clk;
task send_byte(input [7:0] b, input stopbit);
integer i;
begin
rx=0; repeat(BITLEN) @(posedge clk); // start
for(i=0;i<8;i=i+1) begin rx=b[i]; repeat(BITLEN) @(posedge clk); end
rx=stopbit; repeat(BITLEN) @(posedge clk); // stop
rx=1;
end
endtask
always @(posedge clk) if(valid) $display("T=%0t VALID data=%02x ferr=%b",$time,data,ferr);
always @(posedge clk) if(brk) $display("T=%0t BREAK high",$time);
initial begin
repeat(3) @(posedge clk); rst=0; @(posedge clk);
// idle a bit
repeat(10) @(posedge clk);
send_byte(8'hA5,1); // clean byte, good stop
repeat(20) @(posedge clk);
send_byte(8'h3C,0); // framing error (low stop)
repeat(20) @(posedge clk);
// break: drive low long (>6 bit periods) then high & recover
rx=0; repeat(8*BITLEN) @(posedge clk); rx=1;
repeat(8*BITLEN) @(posedge clk); // recovery
send_byte(8'h5A,1); // should be forced frame_err due to break carryover
repeat(20) @(posedge clk);
send_byte(8'h55,1);
repeat(20) @(posedge clk);
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/sim /tmp/tb.sv dut.sv && vvp /tmp/simT=925000 VALID data=a5 ferr=0 T=1925000 VALID data=3c ferr=1 T=2645000 BREAK high T=2655000 BREAK high T=2665000 BREAK high T=2675000 BREAK high T=2685000 BREAK high T=2695000 BREAK high T=2705000 BREAK high T=2715000 BREAK high T=2725000 BREAK high T=2735000 BREAK high T=2745000 BREAK high T=2755000 BREAK high T=2765000 BREAK high T=2775000 BREAK high T=2785000 BREAK high T=2795000 BREAK high T=2805000 BREAK high T=4205000 VALID data=5a ferr=1 T=5205000 VALID data=55 ferr=1 /tmp/tb.sv:35: $finish called at 5415000 (1ps) [stdout] T=925000 VALID data=a5 ferr=0 T=1925000 VALID data=3c ferr=1 T=2645000 BREAK high T=2655000 BREAK high T=2665000 BREAK high T=2675000 BREAK high T=2685000 BREAK high T=2695000 BREAK high T=2705000 BREAK high T=2715000 BREAK high T=2725000 BREAK high T=2735000 BREAK high T=2745000 BREAK high T=2755000 BREAK high T=2765000 BREAK high T=2775000 BREAK high T=2785000 BREAK high T=2795000 BREAK high T=2805000 BREAK high T=4205000 VALID data=5a ferr=1 T=5205000 VALID data=55 ferr=1 /tmp/tb.sv:35: $finish called at 5415000 (1ps)
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.4P4H7V/runtime/cb_verifier_319-10832-21778-18623_319/results.jsonl"}Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_d926a03a364d4bb9. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_d926a03a364d4bb9 · verifier authoritative; classifier explanatory.