tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.// UART receiver with break detection and error-propagation.
//
// Timing model (per spec):
// * rx_i is passed through a two-flop synchronizer; that line drives all logic.
// * A start is accepted the exact cycle a fresh low (from the high-to-low edge)
// reaches HALF = floor(BITLEN/2) low cycles. That cycle is the start-bit
// center; data-bit and stop-bit centers follow every BITLEN cycles.
// * All outputs are registered.
module TopModule #(
parameter BITLEN = 16
) (
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
);
localparam integer HALF = BITLEN/2; // floored half bit period
localparam integer BREAKCYC = 6*BITLEN; // six continuous bit periods
localparam [1:0] S_IDLE = 2'd0, // ready to accept a start
S_DATA = 2'd1, // sampling data + stop
S_BREAK = 2'd2, // break asserted, line still low
S_RECOVER = 2'd3; // waiting for 6 high bit periods
reg sync0, sync1; // two-flop synchronizer
reg [31:0] lowcnt, highcnt; // consecutive low / high cycles
reg [31:0] cyc; // cycle counter within a bit
reg [3:0] bitidx; // data bits sampled so far (0..8)
reg [7:0] shreg; // LSB-first data shift register
reg [3:0] pending; // future bytes forced to frame_err
reg [1:0] state;
reg line;
reg [31:0] low_now, high_now;
always @(posedge clk) begin
if (rst) begin
sync0 <= 1'b1;
sync1 <= 1'b1;
lowcnt <= 32'd0;
highcnt <= 32'd0;
cyc <= 32'd0;
bitidx <= 4'd0;
shreg <= 8'd0;
pending <= 4'd0;
state <= S_IDLE;
data_o <= 8'd0;
valid_o <= 1'b0;
frame_err_o <= 1'b0;
break_o <= 1'b0;
end else begin
// two-flop synchronizer; `line` is the synchronized rx used below
sync0 <= rx_i;
sync1 <= sync0;
line = sync1;
// consecutive low / high run lengths (including this cycle),
// saturating just past BREAKCYC so thresholds fire exactly once.
if (line == 1'b0) begin
low_now = (lowcnt > BREAKCYC) ? lowcnt : lowcnt + 32'd1;
high_now = 32'd0;
end else begin
low_now = 32'd0;
high_now = (highcnt > BREAKCYC) ? highcnt : highcnt + 32'd1;
end
lowcnt <= low_now;
highcnt <= high_now;
// one-cycle pulses default low; data_o / break_o hold their level
valid_o <= 1'b0;
frame_err_o <= 1'b0;
if (line == 1'b0 && low_now == BREAKCYC) begin
// Break: six continuous low bit periods. Preempts any frame;
// d = data bits the interrupted byte sampled (0 if none), and
// this replaces any pending forced-error count.
break_o <= 1'b1;
pending <= (state == S_DATA) ? bitidx : 4'd0;
bitidx <= 4'd0;
cyc <= 32'd0;
state <= S_BREAK;
end else begin
case (state)
S_IDLE: begin
// accept start once a fresh low reaches half a bit period
if (line == 1'b0 && low_now == HALF) begin
state <= S_DATA;
cyc <= 32'd0;
bitidx <= 4'd0;
shreg <= 8'd0;
end
end
S_DATA: begin
if (cyc == BITLEN-1) begin
cyc <= 32'd0;
if (bitidx < 4'd8) begin
// sample a data bit at its center, LSB first
shreg <= {line, shreg[7:1]};
bitidx <= bitidx + 4'd1;
end else begin
// stop-bit sample: deliver the byte
valid_o <= 1'b1;
data_o <= shreg;
if (line == 1'b0 || pending != 4'd0)
frame_err_o <= 1'b1;
if (pending != 4'd0)
pending <= pending - 4'd1;
state <= S_IDLE;
end
end else begin
cyc <= cyc + 32'd1;
end
end
S_BREAK: begin
// break is a level held until the line is high again
if (line == 1'b1) begin
break_o <= 1'b0;
state <= S_RECOVER;
end
end
S_RECOVER: begin
// no start accepted until the line holds high six
// bit periods; any low restarts the high count.
if (line == 1'b1 && high_now == BREAKCYC)
state <= S_IDLE;
end
default: state <= S_IDLE;
endcase
end
end
end
endmodule
Compile-check the module
(iverilog -g2012 -o /tmp/dut_test dut.sv -s TopModule 2>&1 && echo "COMPILE OK") || echo "iverilog not available or error"
COMPILE OK [stdout] COMPILE OK
Run sanity simulation
cat > /tmp/tb.sv <<'EOF'
module tb;
localparam BITLEN=8;
reg clk=0, rst=1, rx=1;
wire [7:0] data; wire valid, ferr, brk;
TopModule #(.BITLEN(BITLEN)) d(.clk(clk),.rst(rst),.rx_i(rx),.data_o(data),.valid_o(valid),.frame_err_o(ferr),.break_o(brk));
always #1 clk=~clk;
task send_bit(input b); begin rx=b; repeat(BITLEN) @(posedge clk); end endtask
integer i; reg [7:0] byteval;
initial begin
@(posedge clk); rst=0; repeat(4) @(posedge clk);
// send 0xA5 = 10100101, LSB first
byteval=8'hA5;
send_bit(0); // start
for(i=0;i<8;i=i+1) send_bit(byteval[i]);
send_bit(1); // stop
repeat(4) @(posedge clk);
// send a break: hold low long enough (>6 bit periods) then high
rx=0; repeat(BITLEN*7) @(posedge clk);
rx=1; repeat(BITLEN*7) @(posedge clk);
$finish;
end
// monitor
always @(posedge clk) begin
if(valid) $display("t=%0t VALID data=%h ferr=%b",$time,data,ferr);
if(brk) $display("t=%0t BREAK high",$time);
end
endmodule
EOF
iverilog -g2012 -o /tmp/sim /app/dut.sv /tmp/tb.sv && vvp /tmp/sim 2>&1 | head -40t=167 VALID data=a5 ferr=0 t=279 BREAK high t=281 BREAK high t=283 BREAK high t=285 BREAK high t=287 BREAK high t=289 BREAK high t=291 BREAK high t=293 BREAK high t=295 BREAK high /tmp/tb.sv:20: $finish called at 401 (1s) [stdout] t=167 VALID data=a5 ferr=0 t=279 BREAK high t=281 BREAK high t=283 BREAK high t=285 BREAK high t=287 BREAK high t=289 BREAK high t=291 BREAK high t=293 BREAK high t=295 BREAK high /tmp/tb.sv:20: $finish called at 401 (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.H6nxo5/runtime/cb_verifier_312-2639-23284-29446_312/results.jsonl"}Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_39fa9d47f984492a. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_39fa9d47f984492a · verifier authoritative; classifier explanatory.