Combinatorial loop fails to converge
This may not be a bug, but a failure by me to understand the limitations of cycle accurate modeling. The following code is intended to increment register
y1 every time the clock changes:
module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cnt = 0; reg [1:0] y1; `ifndef VERILATOR initial begin $dumpfile("obj_dir/iv_t_eval_problem6/iv_t_eval_problem6.vcd"); $dumpvars; end `endif initial begin y1 = 0; end always @(clk) begin y1 = y1 + 1; end always @(posedge clk) begin cnt = cnt + 1; end always @(clk) begin `ifdef TEST_VERBOSE $display("clk = %x, y1 = %x", clk, y1); `endif if (cnt > 4) begin $write("*-* All Finished *-*\n"); $finish; end end endmoduleIt works just fine with Icarus Verilog, producing the expected VCD, with y1 incrementing on each clock edge. However with Verilator, the code fails to compile
%Warning-UNOPTFLAT: t/t_eval_problem6.v:17: Signal unoptimizable: Feedback to clock or circular logic: v.y1 %Warning-UNOPTFLAT: Use "/* verilator lint_off UNOPTFLAT */" and lint_on around source to disable this message. %Warning-UNOPTFLAT: Example path: t/t_eval_problem6.v:17: v.y1 %Warning-UNOPTFLAT: Example path: t/t_eval_problem6.v:30: ALWAYS %Warning-UNOPTFLAT: Example path: t/t_eval_problem6.v:17: v.y1I don't understand this. Sure
y1is assigned from an expression involving itself. But this is in a combinatorial
alwaysblock sensitive to
y1, so there is no circularity.
BTW, if I disable UNOPTFLAT, I just get a Verilator program which fails to converge.
#3 Updated by Jeremy Bennett over 1 year ago
Thanks for the explanation.
This came out of my efforts to get combinatorial always blocks with non-blocking assignments working. It was a test case of my own creation, but as you point out it probably won't synthesize (I'll check), so it isn't a good test case. I'm only looking at synthesizable use of non-blocking assignment in combinatorial always blocks.