tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.// UART-style receiver with break detection and post-break frame-error tagging.
//
// Frame: 1 low start bit, 8 data bits LSB first, 1 high stop bit; each bit is
// BITLEN clock cycles. rx_i is idle-high and is double-flop synchronized.
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; // half a bit period, floored
localparam integer BREAKC = 6 * BITLEN; // six continuous low bit periods
localparam integer LW = $clog2(BREAKC + 1);
localparam integer PW = $clog2(BITLEN + 1);
// FSM states
localparam [1:0] S_IDLE = 2'd0, // idle high, waiting for a valid start
S_DATA = 2'd1, // sampling 8 data bits then the stop bit
S_BREAK = 2'd2, // break asserted, line still low
S_RECOVER = 2'd3; // waiting for 6 high bit periods after break
reg [1:0] state;
// Two-flop synchronizer for rx_i.
reg rx_meta, rx_sync;
// Continuous-low / continuous-high run counters (on the synchronized line).
reg [LW-1:0] low_run, high_run;
// Within-frame sample spacing and progress.
reg [PW-1:0] phase_cnt; // cycles since last sample point
reg [3:0] data_idx; // number of data bits sampled so far (0..8)
reg [7:0] shifter; // data accumulator (LSB first)
// Number of upcoming delivered bytes whose frame_err_o must be forced high.
reg [3:0] fe_pending;
// Combinational "current" run values including this cycle.
reg [LW-1:0] cur_low, cur_high;
always @(posedge clk) begin
if (rst) begin
rx_meta <= 1'b1;
rx_sync <= 1'b1;
state <= S_IDLE;
low_run <= '0;
high_run <= '0;
phase_cnt <= '0;
data_idx <= '0;
shifter <= '0;
fe_pending <= '0;
data_o <= 8'd0;
valid_o <= 1'b0;
frame_err_o <= 1'b0;
break_o <= 1'b0;
end else begin
// Synchronizer.
rx_meta <= rx_i;
rx_sync <= rx_meta;
// valid_o / frame_err_o are single-cycle pulses.
valid_o <= 1'b0;
frame_err_o <= 1'b0;
// Update continuous-run counters (saturating), using the value of the
// synchronized line this cycle.
cur_low = (~rx_sync) ? ((low_run == BREAKC) ? BREAKC : (low_run + 1'b1)) : '0;
cur_high = ( rx_sync) ? ((high_run == BREAKC) ? BREAKC : (high_run + 1'b1)) : '0;
low_run <= cur_low;
high_run <= cur_high;
case (state)
S_IDLE: begin
break_o <= 1'b0;
// A fresh low that reaches half a bit period accepts the start.
if ((HALF != 0) && (cur_low == HALF[LW-1:0])) begin
state <= S_DATA;
phase_cnt <= '0;
data_idx <= '0;
shifter <= '0;
end
end
S_DATA: begin
if (cur_low == BREAKC[LW-1:0]) begin
// Six continuous low bit periods: break preempts this frame.
break_o <= 1'b1;
fe_pending <= data_idx; // d = data bits sampled so far
state <= S_BREAK;
end else if (phase_cnt == (BITLEN-1)) begin
phase_cnt <= '0;
if (data_idx != 4'd8) begin
// Sample a data bit at its bit-period center (LSB first).
shifter <= {rx_sync, shifter[7:1]};
data_idx <= data_idx + 1'b1;
end else begin
// Sample the stop bit: deliver the byte.
data_o <= shifter;
valid_o <= 1'b1;
frame_err_o <= (~rx_sync) | (fe_pending != 4'd0);
if (fe_pending != 4'd0)
fe_pending <= fe_pending - 1'b1;
state <= S_IDLE;
end
end else begin
phase_cnt <= phase_cnt + 1'b1;
end
end
S_BREAK: begin
// Break is a level: high while the line stays low, falls on high.
if (rx_sync) begin
break_o <= 1'b0;
state <= S_RECOVER; // now require 6 high bit periods
end else begin
break_o <= 1'b1;
end
end
S_RECOVER: begin
// No start accepted, break stays low; any low restarts the count.
break_o <= 1'b0;
if (cur_high == BREAKC[LW-1:0])
state <= S_IDLE;
end
default: state <= S_IDLE;
endcase
end
end
endmodule
Compile with iverilog
(iverilog -g2012 -o /tmp/dut.out dut.sv 2>&1 && echo "COMPILE OK") || echo "iverilog not available or error"
COMPILE OK [stdout] COMPILE OK
Run self-test simulation
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 bit_period(input v); integer i; begin
for(i=0;i<BITLEN;i=i+1) @(posedge clk) rx<=v;
end endtask
// send a byte with given data and stop-bit level
task send(input [7:0] b, input stop); integer i; begin
bit_period(0); // start
for(i=0;i<8;i=i+1) bit_period(b[i]); // LSB first
bit_period(stop); // stop
end endtask
// monitor deliveries
always @(posedge clk) if(valid && !rst)
$display("T=%0t VALID data=%02x ferr=%b brk=%b", $time, data, ferr, brk);
always @(posedge clk) if(brk && !rst) $display("T=%0t BREAK asserted", $time);
integer k;
initial begin
repeat(4) @(posedge clk); rst<=0; @(posedge clk);
bit_period(1); bit_period(1); // idle
$display("-- normal 0xA5 stop=1");
send(8'hA5,1'b1);
bit_period(1); bit_period(1);
$display("-- framing err 0x3C stop=0");
send(8'h3C,1'b0);
bit_period(1); bit_period(1);
$display("-- all-low byte (self break), d=5 expected");
// start low + 8 data low = continuous low -> break
bit_period(0); for(k=0;k<8;k=k+1) bit_period(0);
// now line still low a bit then go high to recover
bit_period(0);
// recovery: need 6 high bit periods
for(k=0;k<7;k=k+1) bit_period(1);
$display("-- after recovery, next 5 bytes should have ferr forced");
send(8'h11,1'b1);
bit_period(1);
send(8'h22,1'b1);
bit_period(1);
send(8'h33,1'b1);
bit_period(1);
send(8'h44,1'b1);
bit_period(1);
send(8'h55,1'b1);
bit_period(1);
$display("-- 6th byte should be clean ferr=0");
send(8'h66,1'b1);
bit_period(1); bit_period(1);
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tb.out /tmp/tb.sv /app/dut.sv && vvp /tmp/tb.out-- normal 0xA5 stop=1 T=1005000 VALID data=a5 ferr=0 brk=0 -- framing err 0x3C stop=0 T=1965000 VALID data=3c ferr=1 brk=0 -- all-low byte (self break), d=5 expected T=2645000 BREAK asserted T=2655000 BREAK asserted T=2665000 BREAK asserted T=2675000 BREAK asserted T=2685000 BREAK asserted T=2695000 BREAK asserted T=2705000 BREAK asserted T=2715000 BREAK asserted T=2725000 BREAK asserted T=2735000 BREAK asserted T=2745000 BREAK asserted T=2755000 BREAK asserted T=2765000 BREAK asserted T=2775000 BREAK asserted T=2785000 BREAK asserted T=2795000 BREAK asserted T=2805000 BREAK asserted T=2815000 BREAK asserted T=2825000 BREAK asserted T=2835000 BREAK asserted T=2845000 BREAK asserted T=2855000 BREAK asserted T=2865000 BREAK asserted T=2875000 BREAK asserted T=2885000 BREAK asserted T=2895000 BREAK asserted T=2905000 BREAK asserted T=2915000 BREAK asserted T=2925000 BREAK asserted T=2935000 BREAK asserted T=2945000 BREAK asserted T=2955000 BREAK asserted T=2965000 BREAK asserted -- after recovery, next 5 bytes should have ferr forced T=4285000 VALID data=11 ferr=1 brk=0 T=5165000 VALID data=22 ferr=1 brk=0 T=6045000 VALID data=33 ferr=1 brk=0 T=6925000 VALID data=44 ferr=1 brk=0 T=7805000 VALID data=55 ferr=1 brk=0 -- 6th byte should be clean ferr=0 T=8685000 VALID data=66 ferr=0 brk=0 /tmp/tb.sv:57: $finish called at 8845000 (1ps) [stdout] -- normal 0xA5 stop=1 T=1005000 VALID data=a5 ferr=0 brk=0 -- framing err 0x3C stop=0 T=1965000 VALID data=3c ferr=1 brk=0 -- all-low byte (self break), d=5 expected T=2645000 BREAK asserted T=2655000 BREAK asserted T=2665000 BREAK asserted T=2675000 BREAK asserted T=2685000 BREAK asserted T=2695000 BREAK asserted T=2705000 BREAK asserted T=2715000 BREAK asserted T=2725000 BREAK asserted T=2735000 BREAK asserted T=2745000 BREAK asserted T=2755000 BREAK asserted T=2765000 BREAK asserted T=2775000 BREAK asserted T=2785000 BREAK asserted T=2795000 BREAK asserted T=2805000 BREAK asserted T=2815000 BREAK asserted T=2825000 BREAK asserted T=2835000 BREAK asserted T=2845000 BREAK asserted T=2855000 BREAK asserted T=2865000 BREAK asserted T=2875000 BREAK asserted T=2885000 BREAK asserted T=2895000 BREAK asserted T=2905000 BREAK asserted T=2915000 BREAK asserted T=2925000 BREAK asserted T=2935000 BREAK asserted T=2945000 BREAK asserted T=2955000 BREAK asserted T=2965000 BREAK asserted -- after recovery, next 5 bytes should have ferr forced T=4285000 VALID data=11 ferr=1 brk=0 T=5165000 VALID data=22 ferr=1 brk=0 T=6045000 VALID data=33 ferr=1 brk=0 T=6925000 VALID data=44 ferr=1 brk=0 T=7805000 VALID data=55 ferr=1 brk=0 -- 6th byte should be clean ferr=0 T=8685000 VALID data=66 ferr=0 brk=0 /tmp/tb.sv:57: $finish called at 8845000 (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: 314 in 8633 samples)
TEST reference_equivalence: FAIL (314 mismatches in 8633 samples)
{"score": 0.000000, "results_file": "/tmp/h2t-grader-home.YlovA2/runtime/cb_verifier_314-11431-19723-30702_314/results.jsonl"}Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_e553926c486e4594. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_e553926c486e4594 · verifier authoritative; classifier explanatory.