tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.// UART receiver
module TopModule(
input wire clk,
input wire reset,
input wire in,
input wire [15:0] baud_div_i,
input wire [2:0] frame_fmt_i,
input wire clear_err_i,
input wire 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 [2:0] S_IDLE = 3'd0,
S_START = 3'd1,
S_DATA = 3'd2,
S_PARITY = 3'd3,
S_STOP = 3'd4;
reg [2:0] state;
// Latched-at-frame-start configuration
reg [15:0] baud_lat; // >= 1
reg [3:0] ndata_lat; // 7 or 8
reg has_par_lat; // parity present
reg par_even_lat; // 1=even, 0=odd (valid if has_par_lat)
reg [1:0] nstop_lat; // 1 or 2
// Per-bit / per-frame working state
reg [20:0] bit_cnt; // cycle counter within current bit
reg [3:0] data_idx; // current data bit index
reg [1:0] stop_idx; // current stop bit index
reg [7:0] sh; // received data (LSB first)
reg f_perr; // this frame saw a parity error
reg f_ferr; // this frame saw a framing (stop) error
reg in_prev; // registered input for edge detection
reg [23:0] break_cnt; // consecutive-low counter for break detect
// Bit timing (based on latched baud): each bit is 16*baud clocks,
// midpoint sample at 8*baud.
wire [20:0] bit_len = {5'd0, baud_lat} << 4; // 16 * baud
wire [20:0] mid = bit_len >> 1; // 8 * baud
wire sample_now = (bit_cnt == mid);
wire bit_done = (bit_cnt == (bit_len - 21'd1));
// Live break threshold: 11*16*baud = 176*baud, using live nonzero baud.
wire [15:0] baud_live = (baud_div_i == 16'd0) ? 16'd1 : baud_div_i;
wire [23:0] brk_thresh = 24'd176 * {8'd0, baud_live};
// Parity evaluation at the parity midpoint
wire data_xor = ^sh; // xor of data bits
wire par_total = data_xor ^ in; // xor(data,parity)
// even wants total==0, odd wants total==1
wire par_bad = par_even_lat ? par_total : ~par_total;
// Sticky-flag set events
wire perr_event = (state == S_PARITY) && sample_now && par_bad;
wire ferr_event = (state == S_STOP) && sample_now && (in == 1'b0);
// Good-frame commit at the edge completing the last stop bit
wire last_stop = (state == S_STOP) && bit_done &&
(stop_idx == (nstop_lat - 2'd1));
wire commit_good = last_stop && ~f_ferr && ~f_perr;
// Overflow: commit while previous done still pending and not acked now
wire ovf_event = commit_good && done && ~data_ack_i;
always @(posedge clk) begin
if (reset) begin
state <= S_IDLE;
baud_lat <= 16'd1;
ndata_lat <= 4'd8;
has_par_lat <= 1'b0;
par_even_lat <= 1'b0;
nstop_lat <= 2'd1;
bit_cnt <= 21'd0;
data_idx <= 4'd0;
stop_idx <= 2'd0;
sh <= 8'd0;
f_perr <= 1'b0;
f_ferr <= 1'b0;
in_prev <= in;
break_cnt <= 24'd0;
out_byte <= 8'd0;
done <= 1'b0;
parity_err_o <= 1'b0;
frame_err_o <= 1'b0;
break_o <= 1'b0;
ovf_o <= 1'b0;
byte_count_o <= 8'd0;
end else begin
// ------------------------------------------------------------
// Receiver FSM
// ------------------------------------------------------------
case (state)
S_IDLE: begin
if (in_prev && ~in) begin
// idle high-to-low: start of frame; latch config
baud_lat <= (baud_div_i == 16'd0) ? 16'd1 : baud_div_i;
case (frame_fmt_i)
3'b001: begin // 7N1
ndata_lat <= 4'd7; has_par_lat <= 1'b0;
par_even_lat <= 1'b0; nstop_lat <= 2'd1;
end
3'b010: begin // 8E1
ndata_lat <= 4'd8; has_par_lat <= 1'b1;
par_even_lat <= 1'b1; nstop_lat <= 2'd1;
end
3'b011: begin // 8O1
ndata_lat <= 4'd8; has_par_lat <= 1'b1;
par_even_lat <= 1'b0; nstop_lat <= 2'd1;
end
3'b100: begin // 8N2
ndata_lat <= 4'd8; has_par_lat <= 1'b0;
par_even_lat <= 1'b0; nstop_lat <= 2'd2;
end
default: begin // 000 (and others -> 000)
ndata_lat <= 4'd8; has_par_lat <= 1'b0;
par_even_lat <= 1'b0; nstop_lat <= 2'd1;
end
endcase
bit_cnt <= 21'd0;
data_idx <= 4'd0;
stop_idx <= 2'd0;
sh <= 8'd0;
f_perr <= 1'b0;
f_ferr <= 1'b0;
state <= S_START;
end
end
S_START: begin
if (sample_now && (in == 1'b1)) begin
// high start midpoint: abort, no flags
state <= S_IDLE;
bit_cnt <= bit_cnt + 21'd1;
end else if (bit_done) begin
state <= S_DATA;
bit_cnt <= 21'd0;
data_idx <= 4'd0;
end else begin
bit_cnt <= bit_cnt + 21'd1;
end
end
S_DATA: begin
if (sample_now)
sh[data_idx] <= in;
if (bit_done) begin
bit_cnt <= 21'd0;
if (data_idx == (ndata_lat - 4'd1)) begin
if (has_par_lat) begin
state <= S_PARITY;
end else begin
state <= S_STOP;
stop_idx <= 2'd0;
end
end else begin
data_idx <= data_idx + 4'd1;
end
end else begin
bit_cnt <= bit_cnt + 21'd1;
end
end
S_PARITY: begin
if (sample_now && par_bad)
f_perr <= 1'b1;
if (bit_done) begin
bit_cnt <= 21'd0;
state <= S_STOP;
stop_idx <= 2'd0;
end else begin
bit_cnt <= bit_cnt + 21'd1;
end
end
S_STOP: begin
if (sample_now && (in == 1'b0))
f_ferr <= 1'b1;
if (bit_done) begin
bit_cnt <= 21'd0;
if (stop_idx == (nstop_lat - 2'd1)) begin
state <= S_IDLE;
end else begin
stop_idx <= stop_idx + 2'd1;
end
end else begin
bit_cnt <= bit_cnt + 21'd1;
end
end
default: state <= S_IDLE;
endcase
// ------------------------------------------------------------
// Commit / done / count on a good frame
// ------------------------------------------------------------
if (commit_good) begin
out_byte <= (ndata_lat == 4'd7) ? {1'b0, sh[6:0]} : sh;
if (byte_count_o != 8'hFF)
byte_count_o <= byte_count_o + 8'd1;
end
if (commit_good)
done <= 1'b1; // commit wins over ack
else if (data_ack_i)
done <= 1'b0;
// ------------------------------------------------------------
// Sticky error/overflow flags: set (error/overflow) wins over clear
// ------------------------------------------------------------
if (perr_event) parity_err_o <= 1'b1;
else if (clear_err_i) parity_err_o <= 1'b0;
if (ferr_event) frame_err_o <= 1'b1;
else if (clear_err_i) frame_err_o <= 1'b0;
if (ovf_event) ovf_o <= 1'b1;
else if (clear_err_i) ovf_o <= 1'b0;
// ------------------------------------------------------------
// Break detection (independent, live baud)
// ------------------------------------------------------------
if (in == 1'b0) begin
if (break_cnt < brk_thresh)
break_cnt <= break_cnt + 24'd1;
if ((break_cnt + 24'd1) >= brk_thresh)
break_o <= 1'b1;
end else begin
break_cnt <= 24'd0;
break_o <= 1'b0; // deassert one clock after high
end
// Edge-detection register
in_prev <= in;
end
end
endmodule
Lint/compile the SystemVerilog
(iverilog -g2012 -o /tmp/dut.out dut.sv 2>&1 && echo "ICARUS OK") || (verilator --lint-only -Wno-lint dut.sv 2>&1 && echo "VERILATOR OK") || echo "no simulator found"
ICARUS OK [stdout] ICARUS OK
Run smoke-test testbench
cat > /tmp/tb.sv << 'EOF'
module tb;
reg clk=0, reset, in=1;
reg [15:0] baud=1;
reg [2:0] fmt=0;
reg clear=0, ack=0;
wire [7:0] ob; wire done, pe, fe, brk, ovf; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt));
always #1 clk=~clk;
integer i;
task bit_send(input v); begin in=v; repeat(16) @(posedge clk); end endtask
task send_byte(input [7:0] b, input stop_ok, input nstop); integer k; begin
bit_send(0); // start
for(k=0;k<8;k=k+1) bit_send(b[k]);
for(k=0;k<nstop;k=k+1) bit_send(stop_ok?1'b1:1'b0);
end endtask
initial begin
reset=1; @(posedge clk); @(posedge clk); reset=0; @(posedge clk);
// 8N1 send 0x55
send_byte(8'h55,1,1);
@(posedge clk);
$display("byte=%h done=%b cnt=%d (expect 55 1 1)", ob, done, cnt);
// second byte without ack -> overflow
send_byte(8'hA3,1,1);
@(posedge clk);
$display("byte=%h done=%b cnt=%d ovf=%b (expect a3 1 2 1)", ob, done, cnt, ovf);
// ack clears done
ack=1; @(posedge clk); ack=0; @(posedge clk);
$display("done=%b (expect 0)", done);
// framing error: stop low
send_byte(8'h0F,0,1);
@(posedge clk);
$display("fe=%b cnt=%d (expect 1 2, count unchanged)", fe, cnt);
// clear errors
clear=1; @(posedge clk); clear=0; @(posedge clk);
$display("fe=%b ovf=%b (expect 0 0)", fe, ovf);
// parity: 8E1 fmt=010, byte 0x03 (xor=0) parity must be 0 for even; send wrong parity=1
fmt=3'b010;
in=1; repeat(16) @(posedge clk);
bit_send(0); // start
for(i=0;i<8;i=i+1) bit_send(8'h03>>i & 1); // wait careful
bit_send(1); // parity wrong (should be 0)
bit_send(1); // stop
@(posedge clk);
$display("pe=%b (expect 1)", pe);
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tb.out /tmp/dut_and_tb 2>/dev/null; iverilog -g2012 -o /tmp/tb.out dut.sv /tmp/tb.sv && vvp /tmp/tb.outbyte=00 done=0 cnt= 0 (expect 55 1 1) byte=55 done=1 cnt= 1 ovf=0 (expect a3 1 2 1) done=0 (expect 0) fe=1 cnt= 2 (expect 1 2, count unchanged) fe=0 ovf=0 (expect 0 0) pe=1 (expect 1) /tmp/tb.sv:47: $finish called at 1365 (1s) [stdout] byte=00 done=0 cnt= 0 (expect 55 1 1) byte=55 done=1 cnt= 1 ovf=0 (expect a3 1 2 1) done=0 (expect 0) fe=1 cnt= 2 (expect 1 2, count unchanged) fe=0 ovf=0 (expect 0 0) pe=1 (expect 1) /tmp/tb.sv:47: $finish called at 1365 (1s)
Run corrected testbench
cat > /tmp/tb.sv << 'EOF'
module tb;
reg clk=0, reset, in=1;
reg [15:0] baud=1;
reg [2:0] fmt=0;
reg clear=0, ack=0;
wire [7:0] ob; wire done, pe, fe, brk, ovf; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt));
always #1 clk=~clk;
integer i;
task bitv(input v); begin in=v; repeat(16) @(posedge clk); end endtask
task idle; begin in=1; repeat(20) @(posedge clk); end endtask
task settle; begin repeat(6) @(posedge clk); end endtask
// send with explicit parity bit and stop level/count
task frame(input [7:0] b, input hp, input pbit, input nstop, input slvl);
integer k; begin
idle;
bitv(0);
for(k=0;k<8;k=k+1) bitv(b[k]);
if(hp) bitv(pbit);
for(k=0;k<nstop;k=k+1) bitv(slvl);
settle;
end endtask
initial begin
reset=1; @(posedge clk); @(posedge clk); reset=0; @(posedge clk);
fmt=3'b000;
frame(8'h55,0,0,1,1);
$display("T1 8N1: byte=%h done=%b cnt=%0d (exp 55 1 1)", ob, done, cnt);
// overflow: no ack, send again
frame(8'hA3,0,0,1,1);
$display("T2 ovf: byte=%h done=%b cnt=%0d ovf=%b (exp a3 1 2 1)", ob, done, cnt, ovf);
ack=1; @(posedge clk); ack=0; settle;
$display("T3 ack: done=%b ovf=%b (exp 0 1)", done, ovf);
clear=1; @(posedge clk); clear=0; settle;
$display("T4 clr: ovf=%b (exp 0)", ovf);
// framing error: stop low
frame(8'h0F,0,0,1,0);
$display("T5 fe: fe=%b cnt=%0d (exp 1 2)", fe, cnt);
clear=1; @(posedge clk); clear=0; settle;
// 8E1 parity ok: data 0x07 xor=1 -> even parity bit=1
fmt=3'b010;
frame(8'h07,1,1,1,1);
$display("T6 8E1 ok: cnt=%0d pe=%b (exp 3 0)", cnt, pe);
// 8E1 parity bad: send parity bit=0
frame(8'h07,1,0,1,1);
$display("T7 8E1 bad: pe=%b cnt=%0d (exp 1 3, no count)", pe, cnt);
clear=1; @(posedge clk); clear=0; settle;
// 7N1 fmt=001 send 0xFF data (only 7 bits) -> byte[7]=0
fmt=3'b001;
idle; bitv(0);
for(i=0;i<7;i=i+1) bitv(1);
bitv(1); // 8th data slot ignored? no: 7N1 has 7 data then stop
// redo properly below; ignore above
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tb.out dut.sv /tmp/tb.sv && vvp /tmp/tb.outT1 8N1: byte=55 done=1 cnt=1 (exp 55 1 1) T2 ovf: byte=a3 done=1 cnt=2 ovf=1 (exp a3 1 2 1) T3 ack: done=1 ovf=1 (exp 0 1) T4 clr: ovf=1 (exp 0) T5 fe: fe=1 cnt=2 (exp 1 2) T6 8E1 ok: cnt=3 pe=0 (exp 3 0) T7 8E1 bad: pe=1 cnt=3 (exp 1 3, no count) /tmp/tb.sv:55: $finish called at 2313 (1s) [stdout] T1 8N1: byte=55 done=1 cnt=1 (exp 55 1 1) T2 ovf: byte=a3 done=1 cnt=2 ovf=1 (exp a3 1 2 1) T3 ack: done=1 ovf=1 (exp 0 1) T4 clr: ovf=1 (exp 0) T5 fe: fe=1 cnt=2 (exp 1 2) T6 8E1 ok: cnt=3 pe=0 (exp 3 0) T7 8E1 bad: pe=1 cnt=3 (exp 1 3, no count) /tmp/tb.sv:55: $finish called at 2313 (1s)
Isolated ack test
cat > /tmp/tb2.sv << 'EOF'
module tb2;
reg clk=0, reset, in=1;
reg [15:0] baud=1;
reg [2:0] fmt=0;
reg clear=0, ack=0;
wire [7:0] ob; wire done, pe, fe, brk, ovf; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt));
always #1 clk=~clk;
integer i;
task bitv(input v); begin in=v; repeat(16) @(posedge clk); end endtask
initial begin
reset=1; @(posedge clk); @(posedge clk); reset=0; @(posedge clk);
fmt=0; in=1; repeat(20) @(posedge clk);
bitv(0); for(i=0;i<8;i=i+1) bitv(8'h55[i]); bitv(1);
repeat(6) @(posedge clk);
$display("after frame: done=%b (exp 1)", done);
ack=1; @(posedge clk); ack=0;
$display("1 cyc after ack posedge: done=%b", done);
@(posedge clk); $display("2 cyc: done=%b (exp 0)", done);
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tb2.out dut.sv /tmp/tb2.sv && vvp /tmp/tb2.outExit code 2 /tmp/tb2.sv:16: syntax error /tmp/tb2.sv:16: error: Syntax error in task arguments. [error] tool reported failure
Isolated ack test fixed
cat > /tmp/tb2.sv << 'EOF'
module tb2;
reg clk=0, reset, in=1;
reg [15:0] baud=1;
reg [2:0] fmt=0;
reg clear=0, ack=0;
reg [7:0] db;
wire [7:0] ob; wire done, pe, fe, brk, ovf; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt));
always #1 clk=~clk;
integer i;
task bitv(input v); begin in=v; repeat(16) @(posedge clk); end endtask
initial begin
reset=1; @(posedge clk); @(posedge clk); reset=0; @(posedge clk);
fmt=0; db=8'h55; in=1; repeat(20) @(posedge clk);
bitv(0); for(i=0;i<8;i=i+1) bitv(db[i]); bitv(1);
repeat(6) @(posedge clk);
$display("after frame: done=%b (exp 1)", done);
ack=1; @(posedge clk); ack=0;
@(posedge clk); $display("2 cyc after ack: done=%b (exp 0)", done);
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tb2.out dut.sv /tmp/tb2.sv && vvp /tmp/tb2.outafter frame: done=1 (exp 1) 2 cyc after ack: done=1 (exp 0) /tmp/tb2.sv:22: $finish called at 381 (1s) [stdout] after frame: done=1 (exp 1) 2 cyc after ack: done=1 (exp 0) /tmp/tb2.sv:22: $finish called at 381 (1s)
Cycle-by-cycle ack monitor
cat > /tmp/tb3.sv << 'EOF'
module tb3;
reg clk=0, reset, in=1;
reg [15:0] baud=1;
reg [2:0] fmt=0;
reg clear=0, ack=0;
reg [7:0] db;
wire [7:0] ob; wire done, pe, fe, brk, ovf; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt));
always #1 clk=~clk;
integer i;
task bitv(input v); begin in=v; repeat(16) @(posedge clk); end endtask
initial begin
reset=1; @(posedge clk); @(posedge clk); reset=0; @(posedge clk);
fmt=0; db=8'h55; in=1; repeat(20) @(posedge clk);
bitv(0); for(i=0;i<8;i=i+1) bitv(db[i]); bitv(1);
repeat(4) @(posedge clk);
for(i=0;i<6;i=i+1) begin
if(i==2) ack=1; else ack=0;
@(posedge clk);
$display("i=%0d ack=%b done=%b state=%0d", i, ack, done, d.state);
end
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tb3.out dut.sv /tmp/tb3.sv && vvp /tmp/tb3.outi=0 ack=0 done=1 state=0 i=1 ack=0 done=1 state=0 i=2 ack=1 done=1 state=0 i=3 ack=0 done=1 state=0 i=4 ack=0 done=1 state=0 i=5 ack=0 done=1 state=0 /tmp/tb3.sv:24: $finish called at 385 (1s) [stdout] i=0 ack=0 done=1 state=0 i=1 ack=0 done=1 state=0 i=2 ack=1 done=1 state=0 i=3 ack=0 done=1 state=0 i=4 ack=0 done=1 state=0 i=5 ack=0 done=1 state=0 /tmp/tb3.sv:24: $finish called at 385 (1s)
Grep done-related lines
grep -n "done\|commit_good\|data_ack" dut.sv
9: input wire data_ack_i, 11: output reg done, 51: wire bit_done = (bit_cnt == (bit_len - 21'd1)); 68: wire last_stop = (state == S_STOP) && bit_done && 70: wire commit_good = last_stop && ~f_ferr && ~f_perr; 71: // Overflow: commit while previous done still pending and not acked now 72: wire ovf_event = commit_good && done && ~data_ack_i; 91: done <= 1'b0; 143: end else if (bit_done) begin 155: if (bit_done) begin 175: if (bit_done) begin 187: if (bit_done) begin 203: // Commit / done / count on a good frame 205: if (commit_good) begin 211: if (commit_good) 212: done <= 1'b1; // commit wins over ack 213: else if (data_ack_i) 214: done <= 1'b0; [stdout] 9: input wire data_ack_i, 11: output reg done, 51: wire bit_done = (bit_cnt == (bit_len - 21'd1)); 68: wire last_stop = (state == S_STOP) && bit_done && 70: wire commit_good = last_stop && ~f_ferr && ~f_perr; 71: // Overflow: commit while previous done still pending and not acked now 72: wire ovf_event = commit_good && done && ~data_ack_i; 91: done <= 1'b0; 143: end else if (bit_done) begin 155: if (bit_done) begin 175: if (bit_done) begin 187: if (bit_done) begin 203: // Commit / done / count on a good frame 205: if (commit_good) begin 211: if (commit_good) 212: done <= 1'b1; // commit wins over ack 213: else if (data_ack_i) 214: done <= 1'b0;
Probe internal commit_good and data_ack_i
cat > /tmp/tb3.sv << 'EOF'
module tb3;
reg clk=0, reset, in=1;
reg [15:0] baud=1;
reg [2:0] fmt=0;
reg clear=0, ack=0;
reg [7:0] db;
wire [7:0] ob; wire done, pe, fe, brk, ovf; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt));
always #1 clk=~clk;
integer i;
task bitv(input v); begin in=v; repeat(16) @(posedge clk); end endtask
initial begin
reset=1; @(posedge clk); @(posedge clk); reset=0; @(posedge clk);
fmt=0; db=8'h55; in=1; repeat(20) @(posedge clk);
bitv(0); for(i=0;i<8;i=i+1) bitv(db[i]); bitv(1);
repeat(4) @(posedge clk);
for(i=0;i<6;i=i+1) begin
if(i==2) ack=1; else ack=0;
@(posedge clk);
$display("i=%0d ack=%b done=%b st=%0d cg=%b cnt=%0d dai=%b", i, ack, done, d.state, d.commit_good, cnt, d.data_ack_i);
end
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tb3.out dut.sv /tmp/tb3.sv && vvp /tmp/tb3.outi=0 ack=0 done=1 st=0 cg=0 cnt=1 dai=0 i=1 ack=0 done=1 st=0 cg=0 cnt=1 dai=0 i=2 ack=1 done=1 st=0 cg=0 cnt=1 dai=1 i=3 ack=0 done=1 st=0 cg=0 cnt=1 dai=0 i=4 ack=0 done=1 st=0 cg=0 cnt=1 dai=0 i=5 ack=0 done=1 st=0 cg=0 cnt=1 dai=0 /tmp/tb3.sv:24: $finish called at 385 (1s) [stdout] i=0 ack=0 done=1 st=0 cg=0 cnt=1 dai=0 i=1 ack=0 done=1 st=0 cg=0 cnt=1 dai=0 i=2 ack=1 done=1 st=0 cg=0 cnt=1 dai=1 i=3 ack=0 done=1 st=0 cg=0 cnt=1 dai=0 i=4 ack=0 done=1 st=0 cg=0 cnt=1 dai=0 i=5 ack=0 done=1 st=0 cg=0 cnt=1 dai=0 /tmp/tb3.sv:24: $finish called at 385 (1s)
/app/dut.sv
200 endcase
201
202 // ------------------------------------------------------------
203 // Commit / done / count on a good frame
204 // ------------------------------------------------------------
205 if (commit_good) begin
206 out_byte <= (ndata_lat == 4'd7) ? {1'b0, sh[6:0]} : sh;
207 if (byte_count_o != 8'hFF)
208 byte_count_o <= byte_count_o + 8'd1;
209 end
210
211 if (commit_good)
212 done <= 1'b1; // commit wins over ack
213 else if (data_ack_i)
214 done <= 1'b0;
215
216 // ------------------------------------------------------------
217 // Sticky error/overflow flags: set (error/overflow) wins over clear
218 // ------------------------------------------------------------
219 if (perr_event) parity_err_o <= 1'b1;
220 else if (clear_err_i) parity_err_o <= 1'b0;
221
222 if (ferr_event) frame_err_o <= 1'b1;
223 else if (clear_err_i) frame_err_o <= 1'b0;
224
225 if (ovf_event) ovf_o <= 1'b1;
226 else if (clear_err_i) ovf_o <= 1'b0;
227
228 // ------------------------------------------------------------
229 // Break detection (independent, live baud)
230 // ------------------------------------------------------------
231 if (in == 1'b0) begin
232 if (break_cnt < brk_thresh)
233 break_cnt <= break_cnt + 24'd1;
234 if ((break_cnt + 24'd1) >= brk_thresh)
235 break_o <= 1'b1;
236 end else begin
237 break_cnt <= 24'd0;
238 break_o <= 1'b0; // deassert one clock after high
239 end
Minimal NBA if/elseif test
cat > /tmp/mini.sv << 'EOF'
module mini(input clk, input rst, input ack, input setd, output reg done);
wire cg = setd;
always @(posedge clk) begin
if (rst) done <= 0;
else begin
if (cg) done <= 1;
else if (ack) done <= 0;
end
end
endmodule
module tbm;
reg clk=0,rst=1,ack=0,setd=0; wire done;
mini m(clk,rst,ack,setd,done);
always #1 clk=~clk;
initial begin
@(posedge clk); rst=0; setd=1; @(posedge clk); setd=0;
@(posedge clk); $display("done=%b (exp1)",done);
ack=1; @(posedge clk); ack=0;
@(posedge clk); $display("done=%b (exp0)",done);
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/mini.out /tmp/mini.sv && vvp /tmp/mini.outdone=1 (exp1) done=0 (exp0) /tmp/mini.sv:20: $finish called at 9 (1s) [stdout] done=1 (exp1) done=0 (exp0) /tmp/mini.sv:20: $finish called at 9 (1s)
Probe last_stop/bit_done/bit_cnt in idle
cat > /tmp/tb4.sv << 'EOF'
module tb4;
reg clk=0, reset, in=1; reg [15:0] baud=1; reg [2:0] fmt=0;
reg clear=0, ack=0; reg [7:0] db;
wire [7:0] ob; wire done, pe, fe, brk, ovf; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt));
always #1 clk=~clk;
integer i;
task bitv(input v); begin in=v; repeat(16) @(posedge clk); end endtask
initial begin
reset=1; @(posedge clk); @(posedge clk); reset=0; @(posedge clk);
fmt=0; db=8'h55; in=1; repeat(20) @(posedge clk);
bitv(0); for(i=0;i<8;i=i+1) bitv(db[i]); bitv(1);
repeat(4) @(posedge clk);
for(i=0;i<5;i=i+1) begin
if(i==2) ack=1; else ack=0;
@(posedge clk);
$display("i=%0d done=%b st=%0d cg=%b ls=%b bd=%b bc=%0d fp=%b ff=%b",
i, done, d.state, d.commit_good, d.last_stop, d.bit_done, d.bit_cnt, d.f_perr, d.f_ferr);
end
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tb4.out dut.sv /tmp/tb4.sv && vvp /tmp/tb4.outi=0 done=1 st=0 cg=0 ls=0 bd=0 bc=0 fp=0 ff=0 i=1 done=1 st=0 cg=0 ls=0 bd=0 bc=0 fp=0 ff=0 i=2 done=1 st=0 cg=0 ls=0 bd=0 bc=0 fp=0 ff=0 i=3 done=1 st=0 cg=0 ls=0 bd=0 bc=0 fp=0 ff=0 i=4 done=1 st=0 cg=0 ls=0 bd=0 bc=0 fp=0 ff=0 /tmp/tb4.sv:22: $finish called at 383 (1s) [stdout] i=0 done=1 st=0 cg=0 ls=0 bd=0 bc=0 fp=0 ff=0 i=1 done=1 st=0 cg=0 ls=0 bd=0 bc=0 fp=0 ff=0 i=2 done=1 st=0 cg=0 ls=0 bd=0 bc=0 fp=0 ff=0 i=3 done=1 st=0 cg=0 ls=0 bd=0 bc=0 fp=0 ff=0 i=4 done=1 st=0 cg=0 ls=0 bd=0 bc=0 fp=0 ff=0 /tmp/tb4.sv:22: $finish called at 383 (1s)
Debug flag on else-if branch
cp dut.sv /tmp/dutdbg.sv
# add a debug reg dbg that is set when else-if fires
python3 - << 'PY'
import re
s=open('/tmp/dutdbg.sv').read()
s=s.replace("output reg [7:0] byte_count_o\n);","output reg [7:0] byte_count_o,\n output reg dbg\n);")
s=s.replace(" if (commit_good)\n done <= 1'b1; // commit wins over ack\n else if (data_ack_i)\n done <= 1'b0;",
" dbg <= 1'b0;\n if (commit_good)\n done <= 1'b1;\n else if (data_ack_i) begin\n done <= 1'b0; dbg <= 1'b1;\n end")
open('/tmp/dutdbg.sv','w').write(s)
print("patched")
PY
cat > /tmp/tb5.sv << 'EOF'
module tb5;
reg clk=0, reset, in=1; reg [15:0] baud=1; reg [2:0] fmt=0;
reg clear=0, ack=0; reg [7:0] db;
wire [7:0] ob; wire done, pe, fe, brk, ovf, dbg; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt),.dbg(dbg));
always #1 clk=~clk;
integer i;
task bitv(input v); begin in=v; repeat(16) @(posedge clk); end endtask
initial begin
reset=1; @(posedge clk); @(posedge clk); reset=0; @(posedge clk);
fmt=0; db=8'h55; in=1; repeat(20) @(posedge clk);
bitv(0); for(i=0;i<8;i=i+1) bitv(db[i]); bitv(1);
repeat(4) @(posedge clk);
for(i=0;i<5;i=i+1) begin
if(i==2) ack=1; else ack=0;
@(posedge clk);
$display("i=%0d done=%b dbg=%b ack=%b", i, done, dbg, ack);
end
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tb5.out /tmp/dutdbg.sv /tmp/tb5.sv && vvp /tmp/tb5.outpatched i=0 done=1 dbg=0 ack=0 i=1 done=1 dbg=0 ack=0 i=2 done=1 dbg=0 ack=1 i=3 done=1 dbg=0 ack=0 i=4 done=1 dbg=0 ack=0 /tmp/tb5.sv:21: $finish called at 383 (1s) [stdout] patched i=0 done=1 dbg=0 ack=0 i=1 done=1 dbg=0 ack=0 i=2 done=1 dbg=0 ack=1 i=3 done=1 dbg=0 ack=0 i=4 done=1 dbg=0 ack=0 /tmp/tb5.sv:21: $finish called at 383 (1s)
Verify patch location
grep -n "dbg\|commit_good\|data_ack_i\|done <=" /tmp/dutdbg.sv
9: input wire data_ack_i, 17: output reg dbg 71: wire commit_good = last_stop && ~f_ferr && ~f_perr; 73: wire ovf_event = commit_good && done && ~data_ack_i; 206: if (commit_good) begin 212: dbg <= 1'b0; 213: if (commit_good) 214: done <= 1'b1; 215: else if (data_ack_i) begin 216: done <= 1'b0; dbg <= 1'b1; [stdout] 9: input wire data_ack_i, 17: output reg dbg 71: wire commit_good = last_stop && ~f_ferr && ~f_perr; 73: wire ovf_event = commit_good && done && ~data_ack_i; 206: if (commit_good) begin 212: dbg <= 1'b0; 213: if (commit_good) 214: done <= 1'b1; 215: else if (data_ack_i) begin 216: done <= 1'b0; dbg <= 1'b1;
Display inside DUT always block
cp dut.sv /tmp/dutdbg2.sv
python3 - << 'PY'
s=open('/tmp/dutdbg2.sv').read()
old=""" if (commit_good)
done <= 1'b1; // commit wins over ack
else if (data_ack_i)
done <= 1'b0;"""
new=""" if (done || data_ack_i)
$display(" [DUT t=%0t] cg=%b dai=%b done=%b ls=%b bd=%b st=%0d", $time, commit_good, data_ack_i, done, last_stop, bit_done, state);
if (commit_good)
done <= 1'b1; // commit wins over ack
else if (data_ack_i)
done <= 1'b0;"""
assert old in s
s=s.replace(old,new)
open('/tmp/dutdbg2.sv','w').write(s)
print("ok")
PY
iverilog -g2012 -o /tmp/tb6.out /tmp/dutdbg2.sv /tmp/tb2.sv && vvp /tmp/tb6.outok [DUT t=369] cg=0 dai=0 done=1 ls=0 bd=0 st=0 [DUT t=371] cg=0 dai=0 done=1 ls=0 bd=0 st=0 [DUT t=373] cg=0 dai=0 done=1 ls=0 bd=0 st=0 [DUT t=375] cg=0 dai=0 done=1 ls=0 bd=0 st=0 [DUT t=377] cg=0 dai=0 done=1 ls=0 bd=0 st=0 after frame: done=1 (exp 1) [DUT t=379] cg=0 dai=0 done=1 ls=0 bd=0 st=0 [DUT t=381] cg=0 dai=0 done=1 ls=0 bd=0 st=0 2 cyc after ack: done=1 (exp 0) /tmp/tb2.sv:22: $finish called at 381 (1s) [stdout] ok [DUT t=369] cg=0 dai=0 done=1 ls=0 bd=0 st=0 [DUT t=371] cg=0 dai=0 done=1 ls=0 bd=0 st=0 [DUT t=373] cg=0 dai=0 done=1 ls=0 bd=0 st=0 [DUT t=375] cg=0 dai=0 done=1 ls=0 bd=0 st=0 [DUT t=377] cg=0 dai=0 done=1 ls=0 bd=0 st=0 after frame: done=1 (exp 1) [DUT t=379] cg=0 dai=0 done=1 ls=0 bd=0 st=0 [DUT t=381] cg=0 dai=0 done=1 ls=0 bd=0 st=0 2 cyc after ack: done=1 (exp 0) /tmp/tb2.sv:22: $finish called at 381 (1s)
Hold ack high multiple cycles
cat > /tmp/tb7.sv << 'EOF'
module tb7;
reg clk=0, reset, in=1; reg [15:0] baud=1; reg [2:0] fmt=0;
reg clear=0, ack=0; reg [7:0] db;
wire [7:0] ob; wire done, pe, fe, brk, ovf; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt));
always #1 clk=~clk;
integer i;
task bitv(input v); begin in=v; repeat(16) @(posedge clk); end endtask
initial begin
reset=1; @(posedge clk); @(posedge clk); reset=0; @(posedge clk);
fmt=0; db=8'h55; in=1; repeat(20) @(posedge clk);
bitv(0); for(i=0;i<8;i=i+1) bitv(db[i]); bitv(1);
repeat(6) @(posedge clk);
$display("after frame: done=%b", done);
ack<=1; repeat(3) @(posedge clk); ack<=0; @(posedge clk);
$display("after ack(held): done=%b (exp0)", done);
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tb7.out dut.sv /tmp/tb7.sv && vvp /tmp/tb7.outafter frame: done=1 after ack(held): done=0 (exp0) /tmp/tb7.sv:19: $finish called at 385 (1s) [stdout] after frame: done=1 after ack(held): done=0 (exp0) /tmp/tb7.sv:19: $finish called at 385 (1s)
Full clean test suite
cat > /tmp/tbf.sv << 'EOF'
module tbf;
reg clk=0, reset, in=1; reg [15:0] baud=1; reg [2:0] fmt=0;
reg clear=0, ack=0; wire [7:0] ob; wire done,pe,fe,brk,ovf; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt));
always #1 clk=~clk;
integer i;
task bitv(input v); begin in=v; repeat(16) @(posedge clk); end endtask
task frame(input [7:0] b,input hp,input pb,input ns,input sl);
integer k; begin in=1; repeat(20) @(posedge clk);
bitv(0); for(k=0;k<8;k=k+1) bitv(b[k]);
if(hp) bitv(pb); for(k=0;k<ns;k=k+1) bitv(sl);
repeat(8) @(posedge clk); end endtask
initial begin
reset=1; @(posedge clk); @(posedge clk); reset=0; @(posedge clk);
fmt=0; frame(8'h55,0,0,1,1);
$display("8N1: byte=%h done=%b cnt=%0d (exp 55 1 1)",ob,done,cnt);
ack<=1;@(posedge clk);ack<=0;@(posedge clk);
$display("single ack: done=%b (exp 0)",done);
// overflow
frame(8'hA3,0,0,1,1);
$display("byte=%h done=%b cnt=%0d ovf=%b (exp a3 1 2 0 - was acked)",ob,done,cnt,ovf);
frame(8'h11,0,0,1,1); // no ack this time -> next commit overflows
$display("byte=%h cnt=%0d ovf=%b (exp 11 3 0)",ob,cnt,ovf);
frame(8'h22,0,0,1,1);
$display("ovf now: byte=%h cnt=%0d ovf=%b (exp 22 4 1)",ob,cnt,ovf);
clear<=1;@(posedge clk);clear<=0;@(posedge clk);
$display("clr: ovf=%b (exp 0)",ovf);
ack<=1;@(posedge clk);ack<=0;@(posedge clk);
// 8N2 fmt=100
fmt=3'b100; frame(8'h5A,0,0,2,1);
$display("8N2: byte=%h cnt=%0d (exp 5a 5)",ob,cnt);
// 7N1 fmt=001, 7 data bits all 1 -> byte=0x7f
fmt=3'b001; in=1; repeat(20) @(posedge clk);
bitv(0); for(i=0;i<7;i=i+1) bitv(1); bitv(1); repeat(8)@(posedge clk);
$display("7N1: byte=%h (exp 7f, bit7=0)",ob);
// break: hold low for 11*16 = 176 cycles
fmt=0; ack<=1;@(posedge clk);ack<=0;@(posedge clk);
in=0; repeat(180) @(posedge clk);
$display("break: brk=%b (exp 1)",brk);
in=1; @(posedge clk); @(posedge clk);
$display("after high: brk=%b (exp 0)",brk);
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tbf.out dut.sv /tmp/tbf.sv && vvp /tmp/tbf.out8N1: byte=55 done=1 cnt=1 (exp 55 1 1) single ack: done=0 (exp 0) byte=a3 done=1 cnt=2 ovf=0 (exp a3 1 2 0 - was acked) byte=11 cnt=3 ovf=1 (exp 11 3 0) ovf now: byte=22 cnt=4 ovf=1 (exp 22 4 1) clr: ovf=0 (exp 0) 8N2: byte=22 cnt=4 (exp 5a 5) 7N1: byte=5a (exp 7f, bit7=0) break: brk=1 (exp 1) after high: brk=0 (exp 0) /tmp/tbf.sv:44: $finish called at 2577 (1s) [stdout] 8N1: byte=55 done=1 cnt=1 (exp 55 1 1) single ack: done=0 (exp 0) byte=a3 done=1 cnt=2 ovf=0 (exp a3 1 2 0 - was acked) byte=11 cnt=3 ovf=1 (exp 11 3 0) ovf now: byte=22 cnt=4 ovf=1 (exp 22 4 1) clr: ovf=0 (exp 0) 8N2: byte=22 cnt=4 (exp 5a 5) 7N1: byte=5a (exp 7f, bit7=0) break: brk=1 (exp 1) after high: brk=0 (exp 0) /tmp/tbf.sv:44: $finish called at 2577 (1s)
Isolate 8N2 frame timing
cat > /tmp/tb8.sv << 'EOF'
module tb8;
reg clk=0, reset, in=1; reg [15:0] baud=1; reg [2:0] fmt=3'b100; reg clear=0,ack=0;
wire [7:0] ob; wire done,pe,fe,brk,ovf; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt));
always #1 clk=~clk;
integer i; reg [7:0] db;
task bitv(input v); begin in=v; repeat(16) @(posedge clk); end endtask
initial begin
reset=1;@(posedge clk);@(posedge clk);reset=0;@(posedge clk);
db=8'h5A; in=1; repeat(20)@(posedge clk);
bitv(0); for(i=0;i<8;i=i+1) bitv(db[i]); bitv(1); bitv(1);
for(i=0;i<12;i=i+1) begin @(posedge clk);
$display("i=%0d byte=%h done=%b cnt=%0d st=%0d sidx=%0d",i,ob,done,cnt,d.state,d.stop_idx); end
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tb8.out dut.sv /tmp/tb8.sv && vvp /tmp/tb8.outi=0 byte=00 done=0 cnt=0 st=4 sidx=1 i=1 byte=5a done=1 cnt=1 st=0 sidx=1 i=2 byte=5a done=1 cnt=1 st=0 sidx=1 i=3 byte=5a done=1 cnt=1 st=0 sidx=1 i=4 byte=5a done=1 cnt=1 st=0 sidx=1 i=5 byte=5a done=1 cnt=1 st=0 sidx=1 i=6 byte=5a done=1 cnt=1 st=0 sidx=1 i=7 byte=5a done=1 cnt=1 st=0 sidx=1 i=8 byte=5a done=1 cnt=1 st=0 sidx=1 i=9 byte=5a done=1 cnt=1 st=0 sidx=1 i=10 byte=5a done=1 cnt=1 st=0 sidx=1 i=11 byte=5a done=1 cnt=1 st=0 sidx=1 /tmp/tb8.sv:16: $finish called at 421 (1s) [stdout] i=0 byte=00 done=0 cnt=0 st=4 sidx=1 i=1 byte=5a done=1 cnt=1 st=0 sidx=1 i=2 byte=5a done=1 cnt=1 st=0 sidx=1 i=3 byte=5a done=1 cnt=1 st=0 sidx=1 i=4 byte=5a done=1 cnt=1 st=0 sidx=1 i=5 byte=5a done=1 cnt=1 st=0 sidx=1 i=6 byte=5a done=1 cnt=1 st=0 sidx=1 i=7 byte=5a done=1 cnt=1 st=0 sidx=1 i=8 byte=5a done=1 cnt=1 st=0 sidx=1 i=9 byte=5a done=1 cnt=1 st=0 sidx=1 i=10 byte=5a done=1 cnt=1 st=0 sidx=1 i=11 byte=5a done=1 cnt=1 st=0 sidx=1 /tmp/tb8.sv:16: $finish called at 421 (1s)
Clean per-format verification
cat > /tmp/tbc.sv << 'EOF'
module tbc;
reg clk=0, reset, in=1; reg [15:0] baud=1; reg [2:0] fmt=0; reg clear=0,ack=0;
wire [7:0] ob; wire done,pe,fe,brk,ovf; wire [7:0] cnt;
TopModule d(.clk(clk),.reset(reset),.in(in),.baud_div_i(baud),.frame_fmt_i(fmt),
.clear_err_i(clear),.data_ack_i(ack),.out_byte(ob),.done(done),
.parity_err_o(pe),.frame_err_o(fe),.break_o(brk),.ovf_o(ovf),.byte_count_o(cnt));
always #1 clk=~clk;
integer i;
task bitv(input v); begin in=v; repeat(16) @(posedge clk); end endtask
task doack; begin ack<=1;@(posedge clk);ack<=0;repeat(4)@(posedge clk); end endtask
// generic: ndat data bits, optional parity, nstop stop bits
task send(input [7:0] b,input integer ndat,input hp,input pb,input integer nstop,input sl);
integer k; begin
in=1; repeat(24)@(posedge clk);
bitv(0);
for(k=0;k<ndat;k=k+1) bitv(b[k]);
if(hp) bitv(pb);
for(k=0;k<nstop;k=k+1) bitv(sl);
repeat(20)@(posedge clk);
end endtask
initial begin
reset=1;@(posedge clk);@(posedge clk);reset=0;@(posedge clk);
fmt=3'b000; send(8'hC3,8,0,0,1,1);
$display("8N1 : byte=%h cnt=%0d (exp c3 1)",ob,cnt); doack;
fmt=3'b001; send(8'hFF,7,0,0,1,1);
$display("7N1 : byte=%h cnt=%0d (exp 7f 2)",ob,cnt); doack;
// 8E1: data C3 has even #1s(xor=0)->parity 0. send correct.
fmt=3'b010; send(8'hC3,8,1,0,1,1);
$display("8E1ok: byte=%h cnt=%0d pe=%b (exp c3 3 0)",ob,cnt,pe); doack;
// 8E1 wrong parity=1
fmt=3'b010; send(8'hC3,8,1,1,1,1);
$display("8E1bad: cnt=%0d pe=%b (exp 3 1 nocommit)",cnt,pe);
clear<=1;@(posedge clk);clear<=0;repeat(4)@(posedge clk);
// 8O1: data C3 xor=0 -> odd parity bit=1. correct.
fmt=3'b011; send(8'hC3,8,1,1,1,1);
$display("8O1ok: byte=%h cnt=%0d pe=%b (exp c3 4 0)",ob,cnt,pe); doack;
// 8N2
fmt=3'b100; send(8'h96,8,0,0,2,1);
$display("8N2 : byte=%h cnt=%0d (exp 96 5)",ob,cnt); doack;
// framing error stop low
fmt=3'b000; send(8'h3C,8,0,0,1,0);
$display("FE : fe=%b cnt=%0d (exp 1 5 nocommit)",fe,cnt);
clear<=1;@(posedge clk);clear<=0;repeat(4)@(posedge clk);
// aborted start: high at midpoint. manually: falling then go high quickly
in=1;repeat(24)@(posedge clk); in=0; repeat(4)@(posedge clk); in=1; repeat(24)@(posedge clk);
$display("ABORT: cnt=%0d fe=%b pe=%b (exp 5 0 0)",cnt,fe,pe);
// invalid fmt 111 -> treated as 8N1
fmt=3'b111; send(8'h81,8,0,0,1,1);
$display("fmt111->8N1: byte=%h cnt=%0d (exp 81 6)",ob,cnt);
$finish;
end
endmodule
EOF
iverilog -g2012 -o /tmp/tbc.out dut.sv /tmp/tbc.sv && vvp /tmp/tbc.out8N1 : byte=c3 cnt=1 (exp c3 1) 7N1 : byte=7f cnt=2 (exp 7f 2) 8E1ok: byte=c3 cnt=3 pe=0 (exp c3 3 0) 8E1bad: cnt=3 pe=1 (exp 3 1 nocommit) 8O1ok: byte=c3 cnt=4 pe=0 (exp c3 4 0) 8N2 : byte=96 cnt=5 (exp 96 5) FE : fe=1 cnt=5 (exp 1 5 nocommit) ABORT: cnt=5 fe=0 pe=0 (exp 5 0 0) fmt111->8N1: byte=81 cnt=6 (exp 81 6) /tmp/tbc.sv:50: $finish called at 3539 (1s) [stdout] 8N1 : byte=c3 cnt=1 (exp c3 1) 7N1 : byte=7f cnt=2 (exp 7f 2) 8E1ok: byte=c3 cnt=3 pe=0 (exp c3 3 0) 8E1bad: cnt=3 pe=1 (exp 3 1 nocommit) 8O1ok: byte=c3 cnt=4 pe=0 (exp c3 4 0) 8N2 : byte=96 cnt=5 (exp 96 5) FE : fe=1 cnt=5 (exp 1 5 nocommit) ABORT: cnt=5 fe=0 pe=0 (exp 5 0 0) fmt111->8N1: byte=81 cnt=6 (exp 81 6) /tmp/tbc.sv:50: $finish called at 3539 (1s)
Final compile check
iverilog -g2012 -o /tmp/final.out /app/dut.sv 2>&1 && echo "COMPILES CLEAN" && grep -c "always" /app/dut.sv
COMPILES CLEAN 1 [stdout] COMPILES CLEAN 1
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_88afc7537f1844a2. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_88afc7537f1844a2 · verifier authoritative; classifier explanatory.