tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.// Synthesizable UART-style receiver with configurable frame format,
// parity/framing/overflow error reporting, and break detection.
module TopModule(
input clk,
input reset,
input in,
input [15:0] baud_div_i,
input [2:0] frame_fmt_i,
input clear_err_i,
input data_ack_i,
output reg [7:0] out_byte,
output reg done,
output reg parity_err_o,
output reg frame_err_o,
output reg break_o,
output reg ovf_o,
output reg [7:0] byte_count_o
);
// ---- states ----
localparam IDLE = 3'd0,
START = 3'd1,
DATA = 3'd2,
PARITY = 3'd3,
STOP = 3'd4;
reg [2:0] state;
// latched-per-frame configuration
reg [15:0] lbaud; // latched baud divisor (>=1)
reg [3:0] ndata; // number of data bits (7 or 8)
reg pen; // parity enable
reg podd; // 1 = odd parity, 0 = even
reg [1:0] nstop; // number of stop bits (1 or 2)
// running frame state
reg [20:0] clk_cnt; // clock counter within current bit
reg [3:0] bit_idx; // data-bit / stop-slot index
reg [7:0] data_reg; // received data bits (LSB first)
reg parity_bit; // sampled parity bit
reg frame_bad; // this frame has a parity/framing error
reg in_prev; // previous serial line value (edge detect)
// break detection
reg [31:0] low_cnt; // consecutive-low clock counter
// per-bit timing (based on latched baud)
wire [20:0] bit_len = {1'b0, lbaud, 4'b0000}; // 16 * lbaud
wire [20:0] mid = {2'b00, lbaud, 3'b000}; // 8 * lbaud
wire sample = (clk_cnt == mid);
wire bit_end = (clk_cnt == bit_len - 21'd1);
// live break threshold: 11 * 16 * baud_div_i = 176 * baud_div_i
wire [31:0] brk_thresh = 32'd176 * baud_div_i;
always @(posedge clk) begin
// serial line edge-detect register always tracks the input,
// so a line that is already low out of reset is NOT a start edge.
in_prev <= in;
if (reset) begin
state <= IDLE;
clk_cnt <= 21'd0;
bit_idx <= 4'd0;
data_reg <= 8'd0;
parity_bit <= 1'b0;
frame_bad <= 1'b0;
lbaud <= 16'd0;
ndata <= 4'd8;
pen <= 1'b0;
podd <= 1'b0;
nstop <= 2'd1;
out_byte <= 8'd0;
done <= 1'b0;
parity_err_o <= 1'b0;
frame_err_o <= 1'b0;
ovf_o <= 1'b0;
byte_count_o <= 8'd0;
break_o <= 1'b0;
low_cnt <= 32'd0;
end else begin
// ---------------- break detection (independent) ----------------
if (in == 1'b0) begin
low_cnt <= low_cnt + 32'd1;
if (baud_div_i != 16'd0 && (low_cnt + 32'd1) >= brk_thresh)
break_o <= 1'b1;
end else begin
low_cnt <= 32'd0;
break_o <= 1'b0; // deassert one clock after line goes high
end
// ---- sticky error clear (may be overridden below: error wins) --
if (clear_err_i) begin
parity_err_o <= 1'b0;
frame_err_o <= 1'b0;
ovf_o <= 1'b0;
end
// ---- ack clears done (commit below overrides: new done wins) ---
if (data_ack_i)
done <= 1'b0;
// ------------------------- frame FSM ---------------------------
case (state)
IDLE: begin
// only an idle high-to-low transition starts a frame
if (in_prev && !in) begin
lbaud <= (baud_div_i == 16'd0) ? 16'd1 : baud_div_i;
case (frame_fmt_i)
3'b000: begin ndata<=4'd8; pen<=1'b0; podd<=1'b0; nstop<=2'd1; end // 8N1
3'b001: begin ndata<=4'd7; pen<=1'b0; podd<=1'b0; nstop<=2'd1; end // 7N1
3'b010: begin ndata<=4'd8; pen<=1'b1; podd<=1'b0; nstop<=2'd1; end // 8E1
3'b011: begin ndata<=4'd8; pen<=1'b1; podd<=1'b1; nstop<=2'd1; end // 8O1
3'b100: begin ndata<=4'd8; pen<=1'b0; podd<=1'b0; nstop<=2'd2; end // 8N2
default:begin ndata<=4'd8; pen<=1'b0; podd<=1'b0; nstop<=2'd1; end // -> 8N1
endcase
state <= START;
clk_cnt <= 21'd0;
bit_idx <= 4'd0;
data_reg <= 8'd0;
frame_bad <= 1'b0;
end
end
START: begin
if (sample && in) begin
// high start midpoint -> abort, no flags
state <= IDLE;
clk_cnt <= 21'd0;
end else if (bit_end) begin
clk_cnt <= 21'd0;
bit_idx <= 4'd0;
state <= DATA;
end else begin
clk_cnt <= clk_cnt + 21'd1;
end
end
DATA: begin
if (sample)
data_reg[bit_idx] <= in;
if (bit_end) begin
clk_cnt <= 21'd0;
if (bit_idx == ndata - 4'd1) begin
if (pen)
state <= PARITY;
else begin
state <= STOP;
bit_idx <= 4'd0;
end
end else begin
bit_idx <= bit_idx + 4'd1;
end
end else begin
clk_cnt <= clk_cnt + 21'd1;
end
end
PARITY: begin
if (sample) begin
parity_bit <= in;
// even: XOR(data,parity)=0 ; odd: XOR(data,parity)=1
if ((^data_reg ^ in) != podd) begin
parity_err_o <= 1'b1; // asserts on failing midpoint
frame_bad <= 1'b1;
end
end
if (bit_end) begin
clk_cnt <= 21'd0;
bit_idx <= 4'd0;
state <= STOP;
end else begin
clk_cnt <= clk_cnt + 21'd1;
end
end
STOP: begin
if (sample) begin
if (!in) begin
frame_err_o <= 1'b1; // any low stop midpoint
frame_bad <= 1'b1;
end
end
if (bit_end) begin
clk_cnt <= 21'd0;
if (bit_idx == nstop - 2'd1) begin
// final stop slot: return to idle; commit if good
state <= IDLE;
if (!frame_bad) begin
out_byte <= (ndata == 4'd7) ? {1'b0, data_reg[6:0]}
: data_reg;
done <= 1'b1; // new done wins over ack
byte_count_o <= (byte_count_o == 8'hFF) ? 8'hFF
: byte_count_o + 8'd1;
if (done && !data_ack_i)
ovf_o <= 1'b1; // overflow wins over clear
end
frame_bad <= 1'b0;
end else begin
bit_idx <= bit_idx + 4'd1;
end
end else begin
clk_cnt <= clk_cnt + 21'd1;
end
end
default: state <= IDLE;
endcase
end
end
endmodule
Check for Verilog compiler and compile
(which iverilog verilator 2>/dev/null); iverilog -g2012 -o /tmp/dut.out dut.sv 2>&1 | head -40 || echo "iverilog not present"
/usr/bin/iverilog [stdout] /usr/bin/iverilog
Smoke test 8N1 reception
cat > /tmp/tb.sv <<'EOF'
module tb;
reg clk=0, reset=1, in=1, clear_err_i=0, data_ack_i=0;
reg [15:0] baud=1; reg [2:0] fmt=0;
wire [7:0] out_byte, byte_count_o; wire done,parity_err_o,frame_err_o,break_o,ovf_o;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear_err_i),.data_ack_i(data_ack_i),.out_byte(out_byte),.done(done),
.parity_err_o(parity_err_o),.frame_err_o(frame_err_o),.break_o(break_o),.ovf_o(ovf_o),
.byte_count_o(byte_count_o));
always #5 clk=~clk;
integer i; reg [7:0] data = 8'hA5;
task send_bit(input b); begin in=b; repeat(16) @(posedge clk); end endtask
initial begin
@(posedge clk); reset=0; repeat(4) @(posedge clk);
send_bit(0); // start
for(i=0;i<8;i=i+1) send_bit(data[i]); // LSB first
send_bit(1); // stop
repeat(4) @(posedge clk);
$display("out_byte=%h done=%b count=%d perr=%b ferr=%b ovf=%b",out_byte,done,byte_count_o,parity_err_o,frame_err_o,ovf_o);
if(out_byte==8'hA5 && done && byte_count_o==1) $display("PASS 8N1"); else $display("FAIL");
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/t.out dut.sv /tmp/tb.sv && vvp /tmp/t.outout_byte=a5 done=1 count= x perr=x ferr=x ovf=x FAIL /tmp/tb.sv:20: $finish called at 1685 (1s) [stdout] out_byte=a5 done=1 count= x perr=x ferr=x ovf=x FAIL /tmp/tb.sv:20: $finish called at 1685 (1s)
Fix reset race and rerun
cd /tmp sed -i 's/@(posedge clk); reset=0;/repeat(3) @(negedge clk); reset=0;/' tb.sv iverilog -g2012 -o /tmp/t.out /app/dut.sv tb.sv && vvp /tmp/t.out
out_byte=a5 done=1 count= 1 perr=0 ferr=0 ovf=0 PASS 8N1 tb.sv:20: $finish called at 1705 (1s) Shell cwd was reset to /app [stdout] out_byte=a5 done=1 count= 1 perr=0 ferr=0 ovf=0 PASS 8N1 tb.sv:20: $finish called at 1705 (1s) [stderr] Shell cwd was reset to /app
Test parity, frame error, overflow, break
cat > /tmp/tb2.sv <<'EOF'
module tb;
reg clk=0, reset=1, in=1, clear_err_i=0, data_ack_i=0;
reg [15:0] baud=1; reg [2:0] fmt=0;
wire [7:0] out_byte, byte_count_o; wire done,parity_err_o,frame_err_o,break_o,ovf_o;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear_err_i),.data_ack_i(data_ack_i),.out_byte(out_byte),.done(done),
.parity_err_o(parity_err_o),.frame_err_o(frame_err_o),.break_o(break_o),.ovf_o(ovf_o),
.byte_count_o(byte_count_o));
always #5 clk=~clk;
integer i;
task sb(input b); begin in=b; repeat(16) @(posedge clk); end endtask
task frame8(input [7:0] dat, input pbit, input use_par, input stopok);
begin sb(0); for(i=0;i<8;i=i+1) sb(dat[i]); if(use_par) sb(pbit); sb(stopok?1'b1:1'b0); end
endtask
initial begin
repeat(3) @(negedge clk); reset=0; repeat(4) @(posedge clk);
// 8E1 correct parity (0xA5 has 4 ones -> even parity bit=0)
fmt=3'b010; frame8(8'hA5,1'b0,1,1); repeat(3)@(posedge clk);
$display("8E1 good: byte=%h done=%b perr=%b cnt=%d",out_byte,done,parity_err_o,byte_count_o);
// 8O1 wrong parity to force error (odd wants total odd; give even -> error)
data_ack_i=1;@(posedge clk);data_ack_i=0; // clear done
fmt=3'b011; frame8(8'hA5,1'b0,1,1); repeat(3)@(posedge clk); // A5 even+pbit0 -> XOR=0, odd expects1 => err
$display("8O1 perr: perr=%b done=%b cnt=%d",parity_err_o,done,byte_count_o);
clear_err_i=1;@(posedge clk);clear_err_i=0;
$display("after clear perr=%b",parity_err_o);
// frame error: 8N1 with low stop
fmt=3'b000; frame8(8'h3C,1'b0,0,0); repeat(3)@(posedge clk);
$display("8N1 ferr: ferr=%b done=%b",frame_err_o,done);
clear_err_i=1;@(posedge clk);clear_err_i=0;
// overflow: two good frames without ack (done already high)
fmt=3'b000; frame8(8'h11,0,0,1); repeat(3)@(posedge clk);
fmt=3'b000; frame8(8'h22,0,0,1); repeat(3)@(posedge clk);
$display("ovf: ovf=%b byte=%h done=%b cnt=%d",ovf_o,out_byte,done,byte_count_o);
// break: hold low for 11*16*baud=176 clocks
reset=1; repeat(2)@(negedge clk); reset=0;
in=0; repeat(200) @(posedge clk);
$display("break asserted=%b",break_o);
in=1; @(posedge clk); @(posedge clk);
$display("break after high=%b",break_o);
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/t2.out /app/dut.sv /tmp/tb2.sv && vvp /tmp/t2.out8E1 good: byte=a5 done=1 perr=0 cnt= 1 8O1 perr: perr=1 done=0 cnt= 1 after clear perr=0 8N1 ferr: ferr=1 done=0 ovf: ovf=0 byte=a5 done=0 cnt= 1 break asserted=1 break after high=0 /tmp/tb2.sv:45: $finish called at 10595 (1s) [stdout] 8E1 good: byte=a5 done=1 perr=0 cnt= 1 8O1 perr: perr=1 done=0 cnt= 1 after clear perr=0 8N1 ferr: ferr=1 done=0 ovf: ovf=0 byte=a5 done=0 cnt= 1 break asserted=1 break after high=0 /tmp/tb2.sv:45: $finish called at 10595 (1s)
Test overflow, 7N1, start-abort
cat > /tmp/tb3.sv <<'EOF'
module tb;
reg clk=0, reset=1, in=1, clear_err_i=0, data_ack_i=0;
reg [15:0] baud=1; reg [2:0] fmt=0;
wire [7:0] out_byte, byte_count_o; wire done,parity_err_o,frame_err_o,break_o,ovf_o;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear_err_i),.data_ack_i(data_ack_i),.out_byte(out_byte),.done(done),
.parity_err_o(parity_err_o),.frame_err_o(frame_err_o),.break_o(break_o),.ovf_o(ovf_o),
.byte_count_o(byte_count_o));
always #5 clk=~clk;
integer i;
task sb(input b); begin in=b; repeat(16) @(posedge clk); end endtask
task idle; begin in=1; repeat(20) @(posedge clk); end endtask
task f8(input [7:0] dat); begin sb(0); for(i=0;i<8;i=i+1) sb(dat[i]); sb(1); end endtask
initial begin
repeat(3) @(negedge clk); reset=0; idle;
f8(8'h11); idle;
$display("f1: byte=%h done=%b cnt=%d ovf=%b",out_byte,done,byte_count_o,ovf_o);
f8(8'h22); idle; // done still high, no ack -> overflow, byte replaced
$display("f2: byte=%h done=%b cnt=%d ovf=%b",out_byte,done,byte_count_o,ovf_o);
if(out_byte==8'h22 && ovf_o && done && byte_count_o==2) $display("PASS overflow");
else $display("FAIL overflow");
// 7N1 test: out_byte[7] forced 0
data_ack_i=1;@(posedge clk);data_ack_i=0; clear_err_i=1;@(posedge clk);clear_err_i=0;
fmt=3'b001; sb(0); for(i=0;i<7;i=i+1) sb(1'b1); sb(1); idle; // 7 ones =0x7F
$display("7N1: byte=%h (expect 7f) done=%b",out_byte,done);
// high start midpoint abort: start goes low then high before midpoint
fmt=0; in=0; repeat(4)@(posedge clk); in=1; idle;
$display("abort: done=%b perr=%b ferr=%b (expect no change)",done,parity_err_o,frame_err_o);
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/t3.out /app/dut.sv /tmp/tb3.sv && vvp /tmp/t3.outf1: byte=11 done=1 cnt= 1 ovf=0 f2: byte=22 done=1 cnt= 2 ovf=1 PASS overflow 7N1: byte=7f (expect 7f) done=1 abort: done=1 perr=0 ferr=0 (expect no change) /tmp/tb3.sv:29: $finish called at 5725 (1s) [stdout] f1: byte=11 done=1 cnt= 1 ovf=0 f2: byte=22 done=1 cnt= 2 ovf=1 PASS overflow 7N1: byte=7f (expect 7f) done=1 abort: done=1 perr=0 ferr=0 (expect no change) /tmp/tb3.sv:29: $finish called at 5725 (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 harness_prepare: PASS (harness names nonce-renamed) TEST dut_compiles: PASS (compiled with held-back reference/testbench) TEST simulation_completed: PASS (Mismatches: 10 in 155243 samples) TEST reference_equivalence: FAIL (10 mismatches in 155243 samples)
Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_972070858d08454a. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_972070858d08454a · verifier authoritative; classifier explanatory.